73889508ddbff9b19eca44b27e46639d9747c983
[people/mcb30/basetools.git] / Source / C / VfrCompile / VfrUtilityLib.cpp
1 /** @file\r
2   \r
3   Vfr common library functions.\r
4 \r
5 Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
6 All rights reserved. This program and the accompanying materials                          \r
7 are licensed and made available under the terms and conditions of the BSD License         \r
8 which accompanies this distribution.  The full text of the license may be found at        \r
9 http://opensource.org/licenses/bsd-license.php                                            \r
10                                                                                           \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
13 \r
14 **/\r
15 \r
16 #include "stdio.h"\r
17 #include "stdlib.h"\r
18 #include "VfrUtilityLib.h"\r
19 #include "VfrFormPkg.h"\r
20 \r
21 VOID\r
22 CVfrBinaryOutput::WriteLine (\r
23   IN FILE   *pFile,\r
24   IN UINT32 LineBytes,\r
25   IN CHAR8  *LineHeader,\r
26   IN CHAR8  *BlkBuf,\r
27   IN UINT32 BlkSize\r
28   )\r
29 {\r
30   UINT32    Index;\r
31 \r
32   if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
33     return;\r
34   }\r
35 \r
36   for (Index = 0; Index < BlkSize; Index++) {\r
37     if ((Index % LineBytes) == 0) {\r
38       fprintf (pFile, "\n%s", LineHeader);\r
39     }\r
40     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
41   }\r
42 }\r
43 \r
44 VOID\r
45 CVfrBinaryOutput::WriteEnd (\r
46   IN FILE   *pFile,\r
47   IN UINT32 LineBytes,\r
48   IN CHAR8  *LineHeader,\r
49   IN CHAR8  *BlkBuf,\r
50   IN UINT32 BlkSize\r
51   )\r
52 {\r
53   UINT32    Index;\r
54 \r
55   if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
56     return;\r
57   }\r
58 \r
59   for (Index = 0; Index < BlkSize - 1; Index++) {\r
60     if ((Index % LineBytes) == 0) {\r
61       fprintf (pFile, "\n%s", LineHeader);\r
62     }\r
63     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);\r
64   }\r
65 \r
66   if ((Index % LineBytes) == 0) {\r
67     fprintf (pFile, "\n%s", LineHeader);\r
68   }\r
69   fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
70 }\r
71 \r
72 SConfigInfo::SConfigInfo (\r
73   IN UINT8              Type, \r
74   IN UINT16             Offset, \r
75   IN UINT32             Width, \r
76   IN EFI_IFR_TYPE_VALUE Value\r
77   )\r
78 {\r
79   mNext   = NULL;\r
80   mOffset = Offset;\r
81   mWidth  = (UINT16)Width;\r
82   mValue  = new UINT8[mWidth];\r
83   if (mValue == NULL) {\r
84     return;\r
85   }\r
86 \r
87   switch (Type) {\r
88   case EFI_IFR_TYPE_NUM_SIZE_8 :\r
89     memcpy (mValue, &Value.u8, mWidth);\r
90     break;\r
91   case EFI_IFR_TYPE_NUM_SIZE_16 :\r
92     memcpy (mValue, &Value.u16, mWidth);\r
93     break;\r
94   case EFI_IFR_TYPE_NUM_SIZE_32 :\r
95     memcpy (mValue, &Value.u32, mWidth);\r
96     break;\r
97   case EFI_IFR_TYPE_NUM_SIZE_64 :\r
98     memcpy (mValue, &Value.u64, mWidth);\r
99     break;\r
100   case EFI_IFR_TYPE_BOOLEAN :\r
101     memcpy (mValue, &Value.b, mWidth);\r
102     break;\r
103   case EFI_IFR_TYPE_TIME :\r
104     memcpy (mValue, &Value.time, mWidth);\r
105     break;\r
106   case EFI_IFR_TYPE_DATE :\r
107     memcpy (mValue, &Value.date, mWidth);\r
108     break;\r
109   case EFI_IFR_TYPE_STRING :\r
110     memcpy (mValue, &Value.string, mWidth);\r
111     break;\r
112   case EFI_IFR_TYPE_OTHER :\r
113     return;\r
114   }\r
115 }\r
116 \r
117 SConfigInfo::~SConfigInfo (\r
118   VOID\r
119   )\r
120 {\r
121   BUFFER_SAFE_FREE (mValue);\r
122 }\r
123 \r
124 SConfigItem::SConfigItem (\r
125   IN CHAR8               *Name,\r
126   IN CHAR8               *Id\r
127   )\r
128 {\r
129   mName          = NULL;\r
130   mId            = 0;\r
131   mInfoStrList = NULL;\r
132   mNext        = NULL;\r
133 \r
134   if (Name != NULL) {\r
135     if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {\r
136       strcpy (mName, Name);\r
137     }\r
138   }\r
139 \r
140   if (Id != NULL) {\r
141     if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
142       strcpy (mId, Id);\r
143     }\r
144   }\r
145 }\r
146 \r
147 SConfigItem::SConfigItem (\r
148   IN CHAR8               *Name,\r
149   IN CHAR8               *Id,\r
150   IN UINT8               Type,\r
151   IN UINT16              Offset,\r
152   IN UINT16              Width,\r
153   IN EFI_IFR_TYPE_VALUE  Value\r
154   )\r
155 {\r
156   mName        = NULL;\r
157   mId          = NULL;\r
158   mInfoStrList = NULL;\r
159   mNext        = NULL;\r
160 \r
161   if (Name != NULL) {\r
162     if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {\r
163       strcpy (mName, Name);\r
164     }\r
165   }\r
166 \r
167   if (Id != NULL) {\r
168     if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
169       strcpy (mId, Id);\r
170     }\r
171   }\r
172 \r
173   mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);\r
174 }\r
175 \r
176 SConfigItem::~SConfigItem (\r
177   VOID\r
178   )\r
179 {\r
180   SConfigInfo  *Info;\r
181 \r
182   BUFFER_SAFE_FREE (mName);\r
183   BUFFER_SAFE_FREE (mId);\r
184   while (mInfoStrList != NULL) {\r
185     Info = mInfoStrList;\r
186     mInfoStrList = mInfoStrList->mNext;\r
187 \r
188     BUFFER_SAFE_FREE (Info);\r
189   }\r
190 }\r
191 \r
192 UINT8\r
193 CVfrBufferConfig::Register (\r
194   IN CHAR8               *Name,\r
195   IN CHAR8               *Id\r
196   )\r
197 {\r
198   SConfigItem *pNew;\r
199 \r
200   if (Select (Name) == 0) {\r
201     return 1;\r
202   }\r
203 \r
204   if ((pNew = new SConfigItem (Name, Id)) == NULL) {\r
205     return 2;\r
206   }\r
207   if (mItemListHead == NULL) {\r
208     mItemListHead = pNew;\r
209     mItemListTail = pNew;\r
210   } else {\r
211     mItemListTail->mNext = pNew;\r
212     mItemListTail = pNew;\r
213   }\r
214   mItemListPos    = pNew;\r
215 \r
216   return 0;\r
217 }\r
218 \r
219 VOID\r
220 CVfrBufferConfig::Open (\r
221   VOID\r
222   )\r
223 {\r
224   mItemListPos = mItemListHead;\r
225 }\r
226 \r
227 BOOLEAN\r
228 CVfrBufferConfig::Eof(\r
229   VOID\r
230   )\r
231 {\r
232   return (mItemListPos == NULL) ? TRUE : FALSE;\r
233 }\r
234 \r
235 UINT8\r
236 CVfrBufferConfig::Select (\r
237   IN CHAR8 *Name,\r
238   IN CHAR8 *Id\r
239   )\r
240 {\r
241   SConfigItem *p;\r
242 \r
243   if (Name == NULL) {\r
244     mItemListPos = mItemListHead;\r
245     return 0;\r
246   } else {\r
247     for (p = mItemListHead; p != NULL; p = p->mNext) {\r
248       if (strcmp (p->mName, Name) != 0) {\r
249         continue;\r
250       }\r
251 \r
252       if (Id != NULL) {\r
253         if (p->mId == NULL || strcmp (p->mId, Id) != 0) {\r
254           continue;\r
255         }\r
256       }\r
257 \r
258       mItemListPos = p;\r
259       return 0;\r
260     }\r
261   }\r
262 \r
263   return 1;\r
264 }\r
265 \r
266 UINT8\r
267 CVfrBufferConfig::Write (\r
268   IN CONST CHAR8         Mode,\r
269   IN CHAR8               *Name,\r
270   IN CHAR8               *Id,\r
271   IN UINT8               Type,\r
272   IN UINT16              Offset,\r
273   IN UINT32              Width,\r
274   IN EFI_IFR_TYPE_VALUE  Value\r
275   )\r
276 {\r
277   UINT8         Ret;\r
278   SConfigItem   *pItem;\r
279   SConfigInfo   *pInfo;\r
280 \r
281   switch (Mode) {\r
282   case 'a' : // add\r
283     if (Select (Name, Id) != 0) {\r
284       if ((pItem = new SConfigItem (Name, Id, Type, Offset, Width, Value)) == NULL) {\r
285         return 2;\r
286       }\r
287       if (mItemListHead == NULL) {\r
288         mItemListHead = pItem;\r
289         mItemListTail = pItem;\r
290       } else {\r
291         mItemListTail->mNext = pItem;\r
292         mItemListTail = pItem;\r
293       }\r
294       mItemListPos = pItem;\r
295     } else {\r
296       // tranverse the list to find out if there's already the value for the same offset\r
297       for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {\r
298         if (pInfo->mOffset == Offset) {\r
299           // check if the value and width are the same; return error if not\r
300           if (pInfo->mWidth != Width || memcmp(pInfo->mValue, &Value, Width) != 0) {\r
301             return VFR_RETURN_DEFAULT_VALUE_REDEFINED;\r
302           }\r
303           return 0;\r
304         }\r
305       }\r
306       if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {\r
307         return 2;\r
308       }\r
309       pInfo->mNext = mItemListPos->mInfoStrList;\r
310       mItemListPos->mInfoStrList = pInfo;\r
311     }\r
312     break;\r
313 \r
314   case 'd' : // delete\r
315     if ((Ret = Select (Name, Id)) != 0) {\r
316       return Ret;\r
317     }\r
318 \r
319     if (mItemListHead == mItemListPos) {\r
320       mItemListHead = mItemListPos->mNext;\r
321       delete mItemListPos;\r
322       break;\r
323     }\r
324 \r
325     for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)\r
326       ;\r
327 \r
328     pItem->mNext = mItemListPos->mNext;\r
329     if (mItemListTail == mItemListPos) {\r
330       mItemListTail = pItem;\r
331     }\r
332     delete mItemListPos;\r
333     mItemListPos = pItem->mNext;\r
334     break;\r
335 \r
336   case 'i' : // set info\r
337     if ((Ret = Select (Name, Id)) != 0) {\r
338       return Ret;\r
339     }\r
340 \r
341     if (mItemListPos->mId != NULL) {\r
342       delete mItemListPos->mId;\r
343     }\r
344     mItemListPos->mId = NULL;\r
345     if (Id != NULL) {\r
346       if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {\r
347         return 2;\r
348       }\r
349       strcpy (mItemListPos->mId, Id);\r
350     }\r
351     break;\r
352 \r
353   default :\r
354     return 1;\r
355   }\r
356 \r
357   return 0;\r
358 }\r
359 \r
360 \r
361 VOID\r
362 CVfrBufferConfig::Close (\r
363   VOID\r
364   )\r
365 {\r
366   mItemListPos = NULL;\r
367 }\r
368 \r
369 #define BYTES_PRE_LINE 0x10\r
370 \r
371 VOID\r
372 CVfrBufferConfig::OutputCFile (\r
373   IN FILE  *pFile,\r
374   IN CHAR8 *BaseName\r
375   )\r
376 {\r
377   CVfrBinaryOutput Output;\r
378   SConfigItem      *Item;\r
379   SConfigInfo      *Info;\r
380   UINT32           TotalLen;\r
381 \r
382   if (pFile == NULL) {\r
383     return;\r
384   }\r
385 \r
386   for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {\r
387     if (Item->mId != NULL && Item->mInfoStrList != NULL) {\r
388       fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);\r
389 \r
390       TotalLen = sizeof (UINT32);\r
391       for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
392         TotalLen += Info->mWidth + sizeof (UINT16) * 2;\r
393       }\r
394       Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&TotalLen, sizeof (UINT32));\r
395 \r
396       for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {\r
397         Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));\r
398         Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));\r
399         if (Info->mNext == NULL) {\r
400           Output.WriteEnd (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)Info->mValue, Info->mWidth);\r
401         } else {\r
402           Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)Info->mValue, Info->mWidth);\r
403         }\r
404         fprintf (pFile, "\n"); \r
405       }\r
406       fprintf (pFile, "};\n"); \r
407     }\r
408   }\r
409 }\r
410 \r
411 CVfrBufferConfig::CVfrBufferConfig (\r
412   VOID\r
413   )\r
414 {\r
415   mItemListHead = NULL;\r
416   mItemListTail = NULL;\r
417   mItemListPos  = NULL;\r
418 }\r
419 \r
420 CVfrBufferConfig::~CVfrBufferConfig (\r
421   VOID\r
422   )\r
423 {\r
424   SConfigItem *p;\r
425 \r
426   while (mItemListHead != NULL) {\r
427     p = mItemListHead;\r
428     mItemListHead = mItemListHead->mNext;\r
429     delete p;\r
430   }\r
431 \r
432   mItemListHead = NULL;\r
433   mItemListTail = NULL;\r
434   mItemListPos  = NULL;\r
435 }\r
436 \r
437 CVfrBufferConfig gCVfrBufferConfig;\r
438 \r
439 static struct {\r
440   CHAR8  *mTypeName;\r
441   UINT8  mType;\r
442   UINT32 mSize;\r
443   UINT32 mAlign;\r
444 } gInternalTypesTable [] = {\r
445   {"UINT64",        EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64),       sizeof (UINT64)},\r
446   {"UINT32",        EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32),       sizeof (UINT32)},\r
447   {"UINT16",        EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16),       sizeof (UINT16)},\r
448   {"UINT8",         EFI_IFR_TYPE_NUM_SIZE_8,  sizeof (UINT8),        sizeof (UINT8)},\r
449   {"BOOLEAN",       EFI_IFR_TYPE_BOOLEAN,     sizeof (BOOLEAN),      sizeof (BOOLEAN)},\r
450   {"EFI_HII_DATE",  EFI_IFR_TYPE_DATE,        sizeof (EFI_HII_DATE), sizeof (UINT16)},\r
451   {"EFI_STRING_ID", EFI_IFR_TYPE_STRING,      sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},\r
452   {"EFI_HII_TIME",  EFI_IFR_TYPE_TIME,        sizeof (EFI_HII_TIME), sizeof (UINT8)},\r
453   {NULL,            EFI_IFR_TYPE_OTHER,       0,                     0}\r
454 };\r
455 \r
456 STATIC\r
457 BOOLEAN\r
458 _IS_INTERNAL_TYPE (\r
459   IN CHAR8 *TypeName\r
460   )\r
461 {\r
462   UINT32  Index;\r
463 \r
464   if (TypeName == NULL) {\r
465     return FALSE;\r
466   }\r
467 \r
468   for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
469     if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {\r
470       return TRUE;\r
471     }\r
472   }\r
473 \r
474   return FALSE;\r
475 }\r
476 \r
477 STATIC\r
478 CHAR8 *\r
479 TrimHex (\r
480   IN  CHAR8   *Str,\r
481   OUT bool    *IsHex\r
482   )\r
483 {\r
484   *IsHex = FALSE;\r
485 \r
486   while (*Str && *Str == ' ') {\r
487     Str++;\r
488   }\r
489   while (*Str && *Str == '0') {\r
490     Str++;\r
491   }\r
492   if (*Str && (*Str == 'x' || *Str == 'X')) {\r
493     Str++;\r
494     *IsHex = TRUE;\r
495   }\r
496 \r
497   return Str;\r
498 }\r
499 \r
500 UINT32\r
501 _STR2U32 (\r
502   IN CHAR8 *Str\r
503   )\r
504 {\r
505   bool    IsHex;\r
506   UINT32  Value;\r
507   CHAR8    c;\r
508 \r
509   Str = TrimHex (Str, &IsHex);\r
510   for (Value = 0; (c = *Str) != '\0'; Str++) {\r
511     //\r
512     // BUG: does not handle overflow here\r
513     //\r
514         (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
515 \r
516     if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
517       Value += (c - 'a' + 10);\r
518     }\r
519     if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {\r
520       Value += (c - 'A' + 10);\r
521     }\r
522     if (c >= '0' && c <= '9') {\r
523       Value += (c - '0');\r
524     } \r
525   }\r
526 \r
527   return Value;\r
528 }\r
529 \r
530 VOID\r
531 CVfrVarDataTypeDB::RegisterNewType (\r
532   IN SVfrDataType  *New\r
533   )\r
534 {\r
535   New->mNext               = mDataTypeList;\r
536   mDataTypeList            = New;\r
537 }\r
538 \r
539 EFI_VFR_RETURN_CODE\r
540 CVfrVarDataTypeDB::ExtractStructTypeName (\r
541   IN  CHAR8 *&VarStr, \r
542   OUT CHAR8 *TName\r
543   )\r
544 {\r
545   if (TName == NULL) {\r
546     return VFR_RETURN_FATAL_ERROR;\r
547   }\r
548 \r
549   while((*VarStr != '\0') && (*VarStr != '.')) {\r
550     *TName = *VarStr;\r
551     VarStr++;\r
552     TName++;\r
553   }\r
554   *TName = '\0';\r
555   if (*VarStr == '.') {\r
556     VarStr++;\r
557   }\r
558 \r
559   return VFR_RETURN_SUCCESS;\r
560 }\r
561 \r
562 EFI_VFR_RETURN_CODE\r
563 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (\r
564   IN  CHAR8   *&VarStr, \r
565   IN  CHAR8   *FName,\r
566   OUT UINT32 &ArrayIdx\r
567   )\r
568 {\r
569   UINT32 Idx;\r
570   CHAR8   ArrayStr[MAX_NAME_LEN + 1];\r
571 \r
572   ArrayIdx = INVALID_ARRAY_INDEX; \r
573 \r
574   if (FName == NULL) {\r
575     return VFR_RETURN_FATAL_ERROR;\r
576   }\r
577 \r
578   while((*VarStr != '\0') &&\r
579         (*VarStr != '.') && \r
580         (*VarStr != '[') && \r
581         (*VarStr != ']')) {\r
582     *FName = *VarStr;\r
583     VarStr++;\r
584     FName++;\r
585   }\r
586   *FName = '\0';\r
587 \r
588   switch (*VarStr) {\r
589   case '.' :\r
590     VarStr++;\r
591   case '\0':\r
592     return VFR_RETURN_SUCCESS;\r
593   case '[' :\r
594     VarStr++;\r
595     for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {\r
596       ArrayStr[Idx] = *VarStr;\r
597     }\r
598     ArrayStr[Idx] = '\0';\r
599 \r
600     if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {\r
601       return VFR_RETURN_DATA_STRING_ERROR;\r
602     }\r
603     ArrayIdx = _STR2U32 (ArrayStr);\r
604     if (*VarStr == ']') {\r
605       VarStr++;\r
606     }\r
607     return VFR_RETURN_SUCCESS;\r
608   case ']':\r
609     return VFR_RETURN_DATA_STRING_ERROR;\r
610   }\r
611 \r
612   return VFR_RETURN_SUCCESS;\r
613 }\r
614 \r
615 EFI_VFR_RETURN_CODE\r
616 CVfrVarDataTypeDB::GetTypeField (\r
617   IN  CHAR8          *FName, \r
618   IN  SVfrDataType  *Type, \r
619   OUT SVfrDataField *&Field\r
620   )\r
621 {\r
622   SVfrDataField  *pField = NULL;\r
623 \r
624   if ((FName == NULL) && (Type == NULL)) {\r
625     return VFR_RETURN_FATAL_ERROR;\r
626   }\r
627 \r
628   for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {\r
629     if (strcmp (pField->mFieldName, FName) == 0) {\r
630       Field = pField;\r
631       return VFR_RETURN_SUCCESS;\r
632     }\r
633   }\r
634 \r
635   return VFR_RETURN_UNDEFINED;\r
636 }\r
637 \r
638 EFI_VFR_RETURN_CODE\r
639 CVfrVarDataTypeDB::GetFieldOffset (\r
640   IN  SVfrDataField *Field, \r
641   IN  UINT32        ArrayIdx,\r
642   OUT UINT32        &Offset\r
643   )\r
644 {\r
645   if (Field == NULL) {\r
646     return VFR_RETURN_FATAL_ERROR;\r
647   }\r
648   \r
649   //\r
650   // Framework Vfr file Array Index is from 1.\r
651   // But Uefi Vfr file Array Index is from 0.\r
652   //\r
653   if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {\r
654     if (ArrayIdx == 0) {\r
655       return VFR_RETURN_ERROR_ARRARY_NUM;\r
656     }\r
657     ArrayIdx = ArrayIdx - 1;\r
658   }\r
659 \r
660   if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {\r
661     return VFR_RETURN_ERROR_ARRARY_NUM;\r
662   }\r
663   \r
664   //\r
665   // Be compatible with the current usage\r
666   // If ArraryIdx is not specified, the first one is used.\r
667   //\r
668   // if ArrayNum is larger than zero, ArraryIdx must be specified.\r
669   //\r
670   // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {\r
671   //   return VFR_RETURN_ERROR_ARRARY_NUM;\r
672   // }\r
673   //\r
674 \r
675   Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
676   return VFR_RETURN_SUCCESS;\r
677 }\r
678 \r
679 UINT8\r
680 CVfrVarDataTypeDB::GetFieldWidth (\r
681   IN SVfrDataField *Field\r
682   )\r
683 {\r
684   if (Field == NULL) {\r
685     return 0;\r
686   }\r
687 \r
688   return Field->mFieldType->mType;\r
689 }\r
690 \r
691 UINT32\r
692 CVfrVarDataTypeDB::GetFieldSize (\r
693   IN SVfrDataField *Field,\r
694   IN UINT32       ArrayIdx\r
695   )\r
696 {\r
697   if (Field == NULL) {\r
698     return VFR_RETURN_FATAL_ERROR;\r
699   }\r
700 \r
701   if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
702     return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
703   } else {\r
704     return Field->mFieldType->mTotalSize;\r
705   }\r
706 }\r
707 \r
708 VOID\r
709 CVfrVarDataTypeDB::InternalTypesListInit (\r
710   VOID\r
711   )\r
712 {\r
713   SVfrDataType *New   = NULL;\r
714   UINT32       Index;\r
715 \r
716   for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
717     New                 = new SVfrDataType;\r
718     if (New != NULL) {\r
719       strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);\r
720       New->mType        = gInternalTypesTable[Index].mType;\r
721       New->mAlign       = gInternalTypesTable[Index].mAlign;\r
722       New->mTotalSize   = gInternalTypesTable[Index].mSize;\r
723       if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {\r
724         SVfrDataField *pYearField  = new SVfrDataField;\r
725         SVfrDataField *pMonthField = new SVfrDataField;\r
726         SVfrDataField *pDayField   = new SVfrDataField;\r
727 \r
728         strcpy (pYearField->mFieldName, "Year");\r
729         GetDataType ("UINT8", &pYearField->mFieldType);\r
730         pYearField->mOffset      = 0;\r
731         pYearField->mNext        = pMonthField;\r
732         pYearField->mArrayNum    = 0;\r
733 \r
734         strcpy (pMonthField->mFieldName, "Month");\r
735         GetDataType ("UINT8", &pMonthField->mFieldType);\r
736         pMonthField->mOffset     = 1;\r
737         pMonthField->mNext       = pDayField;\r
738         pMonthField->mArrayNum   = 0;\r
739 \r
740         strcpy (pDayField->mFieldName, "Day");\r
741         GetDataType ("UINT8", &pDayField->mFieldType);\r
742         pDayField->mOffset       = 2;\r
743         pDayField->mNext         = NULL;\r
744         pDayField->mArrayNum     = 0;\r
745 \r
746         New->mMembers            = pYearField;\r
747       } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
748         SVfrDataField *pHoursField   = new SVfrDataField;\r
749         SVfrDataField *pMinutesField = new SVfrDataField;\r
750         SVfrDataField *pSecondsField = new SVfrDataField;\r
751 \r
752         strcpy (pHoursField->mFieldName, "Hours");\r
753         GetDataType ("UINT8", &pHoursField->mFieldType);\r
754         pHoursField->mOffset     = 0;\r
755         pHoursField->mNext       = pMinutesField;\r
756         pHoursField->mArrayNum   = 0;\r
757 \r
758         strcpy (pMinutesField->mFieldName, "Minutes");\r
759         GetDataType ("UINT8", &pMinutesField->mFieldType);\r
760         pMinutesField->mOffset   = 1;\r
761         pMinutesField->mNext     = pSecondsField;\r
762         pMinutesField->mArrayNum = 0;\r
763 \r
764         strcpy (pSecondsField->mFieldName, "Seconds");\r
765         GetDataType ("UINT8", &pSecondsField->mFieldType);\r
766         pSecondsField->mOffset   = 2;\r
767         pSecondsField->mNext     = NULL;\r
768         pSecondsField->mArrayNum = 0;\r
769 \r
770         New->mMembers            = pHoursField;      \r
771       } else {\r
772         New->mMembers            = NULL;\r
773       }\r
774       New->mNext                 = NULL;\r
775       RegisterNewType (New);\r
776       New                        = NULL;\r
777     }\r
778   }\r
779 }\r
780 \r
781 CVfrVarDataTypeDB::CVfrVarDataTypeDB (\r
782   VOID\r
783   )\r
784 {\r
785   mDataTypeList  = NULL;\r
786   mNewDataType   = NULL;\r
787   mCurrDataField = NULL;\r
788   mPackAlign     = DEFAULT_PACK_ALIGN;\r
789   mPackStack     = NULL;\r
790   mFirstNewDataTypeName = NULL;\r
791 \r
792   InternalTypesListInit ();\r
793 }\r
794 \r
795 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (\r
796   VOID\r
797   )\r
798 {\r
799   SVfrDataType      *pType;\r
800   SVfrDataField     *pField;\r
801   SVfrPackStackNode *pPack;\r
802 \r
803   if (mNewDataType != NULL) {\r
804     delete mNewDataType;\r
805   }\r
806 \r
807   while (mDataTypeList != NULL) {\r
808     pType = mDataTypeList;\r
809     mDataTypeList = mDataTypeList->mNext;\r
810     while(pType->mMembers != NULL) {\r
811       pField = pType->mMembers;\r
812       pType->mMembers = pType->mMembers->mNext;\r
813       delete pField;\r
814     }\r
815         delete pType;\r
816   }\r
817 \r
818   while (mPackStack != NULL) {\r
819     pPack = mPackStack;\r
820     mPackStack = mPackStack->mNext;\r
821     delete pPack;\r
822   }\r
823 }\r
824 \r
825 EFI_VFR_RETURN_CODE\r
826 CVfrVarDataTypeDB::Pack (\r
827   IN UINT32         LineNum,\r
828   IN UINT8          Action, \r
829   IN CHAR8          *Identifier, \r
830   IN UINT32         Number\r
831   )\r
832 {\r
833   UINT32            PackAlign;\r
834   CHAR8             Msg[MAX_STRING_LEN] = {0, };\r
835 \r
836   if (Action & VFR_PACK_SHOW) {\r
837     sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);\r
838     gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", Msg);\r
839   }\r
840 \r
841   if (Action & VFR_PACK_PUSH) {\r
842     SVfrPackStackNode *pNew = NULL;\r
843 \r
844     if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {\r
845       return VFR_RETURN_FATAL_ERROR;\r
846     }\r
847     pNew->mNext = mPackStack;\r
848     mPackStack  = pNew;\r
849   }\r
850 \r
851   if (Action & VFR_PACK_POP) {\r
852     SVfrPackStackNode *pNode = NULL;\r
853 \r
854     if (mPackStack == NULL) {\r
855       gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "#pragma pack(pop...) : more pops than pushes");\r
856     }\r
857 \r
858     for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {\r
859       if (pNode->Match (Identifier) == TRUE) {\r
860         mPackAlign = pNode->mNumber;\r
861         mPackStack = pNode->mNext;\r
862       }\r
863     }\r
864   }\r
865 \r
866   if (Action & VFR_PACK_ASSIGN) {\r
867     PackAlign = (Number > 1) ? Number + Number % 2 : Number;\r
868     if ((PackAlign == 0) || (PackAlign > 16)) {\r
869       gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
870     } else {\r
871       mPackAlign = PackAlign;\r
872     }\r
873   }\r
874 \r
875   return VFR_RETURN_SUCCESS;\r
876 }\r
877 \r
878 VOID\r
879 CVfrVarDataTypeDB::DeclareDataTypeBegin (\r
880   VOID\r
881   )\r
882 {\r
883   SVfrDataType *pNewType = NULL;\r
884 \r
885   pNewType               = new SVfrDataType;\r
886   pNewType->mTypeName[0] = '\0';\r
887   pNewType->mType        = EFI_IFR_TYPE_OTHER;\r
888   pNewType->mAlign       = DEFAULT_ALIGN;\r
889   pNewType->mTotalSize   = 0;\r
890   pNewType->mMembers     = NULL;\r
891   pNewType->mNext        = NULL;\r
892 \r
893   mNewDataType           = pNewType;\r
894 }\r
895 \r
896 EFI_VFR_RETURN_CODE\r
897 CVfrVarDataTypeDB::SetNewTypeName (\r
898   IN CHAR8   *TypeName\r
899   )\r
900 {\r
901   SVfrDataType *pType;\r
902 \r
903   if (mNewDataType == NULL) {\r
904     return VFR_RETURN_ERROR_SKIPED;\r
905   }\r
906   if (TypeName == NULL) {\r
907     return VFR_RETURN_FATAL_ERROR;\r
908   }\r
909   if (strlen(TypeName) >= MAX_NAME_LEN) {\r
910     return VFR_RETURN_INVALID_PARAMETER;\r
911   }\r
912 \r
913   for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
914     if (strcmp(pType->mTypeName, TypeName) == 0) {\r
915       return VFR_RETURN_REDEFINED;\r
916     }\r
917   }\r
918 \r
919   strcpy(mNewDataType->mTypeName, TypeName);\r
920   return VFR_RETURN_SUCCESS;\r
921 }\r
922 \r
923 EFI_VFR_RETURN_CODE\r
924 CVfrVarDataTypeDB::DataTypeAddField (\r
925   IN CHAR8   *FieldName, \r
926   IN CHAR8   *TypeName, \r
927   IN UINT32 ArrayNum\r
928   )\r
929 {\r
930   SVfrDataField       *pNewField  = NULL;\r
931   SVfrDataType        *pFieldType = NULL;\r
932   SVfrDataField       *pTmp;\r
933   UINT32              Align;\r
934 \r
935   CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
936 \r
937   if (strlen (FieldName) >= MAX_NAME_LEN) {\r
938    return VFR_RETURN_INVALID_PARAMETER;\r
939   }\r
940 \r
941   for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
942     if (strcmp (pTmp->mFieldName, FieldName) == 0) {\r
943       return VFR_RETURN_REDEFINED;\r
944     }\r
945   }\r
946 \r
947   Align = MIN (mPackAlign, pFieldType->mAlign);\r
948 \r
949   if ((pNewField = new SVfrDataField) == NULL) {\r
950     return VFR_RETURN_OUT_FOR_RESOURCES;\r
951   }\r
952   strcpy (pNewField->mFieldName, FieldName);\r
953   pNewField->mFieldType    = pFieldType;\r
954   pNewField->mArrayNum     = ArrayNum;\r
955   if ((mNewDataType->mTotalSize % Align) == 0) {\r
956     pNewField->mOffset     = mNewDataType->mTotalSize;\r
957   } else {\r
958     pNewField->mOffset     = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
959   }\r
960   if (mNewDataType->mMembers == NULL) {\r
961     mNewDataType->mMembers = pNewField;\r
962     pNewField->mNext       = NULL;\r
963   } else {\r
964     for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext) \r
965       ;\r
966     pTmp->mNext            = pNewField;\r
967     pNewField->mNext       = NULL;\r
968   }\r
969 \r
970   mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
971   mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
972 \r
973   return VFR_RETURN_SUCCESS;\r
974 }\r
975 \r
976 VOID\r
977 CVfrVarDataTypeDB::DeclareDataTypeEnd (\r
978   VOID\r
979   )\r
980 {\r
981   if (mNewDataType->mTypeName[0] == '\0') {\r
982     return;\r
983   }\r
984 \r
985   if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {\r
986     mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);\r
987   }\r
988 \r
989   RegisterNewType (mNewDataType);\r
990   if (mFirstNewDataTypeName == NULL) {\r
991     mFirstNewDataTypeName = mNewDataType->mTypeName;\r
992   }\r
993 \r
994   mNewDataType             = NULL;\r
995 }\r
996 \r
997 EFI_VFR_RETURN_CODE\r
998 CVfrVarDataTypeDB::GetDataType (\r
999   IN  CHAR8         *TypeName,\r
1000   OUT SVfrDataType **DataType\r
1001   )\r
1002 {\r
1003   SVfrDataType *pDataType = NULL;\r
1004 \r
1005   if (TypeName == NULL) {\r
1006     return VFR_RETURN_ERROR_SKIPED;\r
1007   }\r
1008 \r
1009   if (DataType == NULL) {\r
1010     return VFR_RETURN_FATAL_ERROR;\r
1011   }\r
1012 \r
1013   *DataType = NULL;\r
1014 \r
1015   for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1016     if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1017       *DataType = pDataType;\r
1018       return VFR_RETURN_SUCCESS;\r
1019     }\r
1020   }\r
1021 \r
1022   return VFR_RETURN_UNDEFINED;\r
1023 }\r
1024 \r
1025 EFI_VFR_RETURN_CODE\r
1026 CVfrVarDataTypeDB::GetDataTypeSize (\r
1027   IN  UINT8   DataType,\r
1028   OUT UINT32 *Size\r
1029   )\r
1030 {\r
1031   SVfrDataType *pDataType = NULL;\r
1032 \r
1033   if (Size == NULL) {\r
1034     return VFR_RETURN_FATAL_ERROR;\r
1035   }\r
1036 \r
1037   *Size    = 0;\r
1038   DataType = DataType & 0x0F;\r
1039 \r
1040   //\r
1041   // For user defined data type, the size can't be got by this function.\r
1042   //\r
1043   if (DataType == EFI_IFR_TYPE_OTHER) {\r
1044     return VFR_RETURN_SUCCESS;\r
1045   }\r
1046 \r
1047   for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1048     if (DataType == pDataType->mType) {\r
1049       *Size = pDataType->mTotalSize;\r
1050       return VFR_RETURN_SUCCESS;\r
1051     }\r
1052   }\r
1053 \r
1054   return VFR_RETURN_UNDEFINED;\r
1055 }\r
1056 \r
1057 EFI_VFR_RETURN_CODE\r
1058 CVfrVarDataTypeDB::GetDataTypeSize (\r
1059   IN  CHAR8   *TypeName,\r
1060   OUT UINT32 *Size\r
1061   )\r
1062 {\r
1063   SVfrDataType *pDataType = NULL;\r
1064 \r
1065   if (Size == NULL) {\r
1066     return VFR_RETURN_FATAL_ERROR;\r
1067   }\r
1068 \r
1069   *Size = 0;\r
1070 \r
1071   for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {\r
1072     if (strcmp (TypeName, pDataType->mTypeName) == 0) {\r
1073       *Size = pDataType->mTotalSize;\r
1074       return VFR_RETURN_SUCCESS;\r
1075     }\r
1076   }\r
1077 \r
1078   return VFR_RETURN_UNDEFINED;\r
1079 }\r
1080 \r
1081 EFI_VFR_RETURN_CODE\r
1082 CVfrVarDataTypeDB::GetDataFieldInfo (\r
1083   IN  CHAR8     *VarStr, \r
1084   OUT UINT16   &Offset, \r
1085   OUT UINT8    &Type, \r
1086   OUT UINT32   &Size\r
1087   )\r
1088 {\r
1089   CHAR8               TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
1090   UINT32              ArrayIdx, Tmp;\r
1091   SVfrDataType        *pType  = NULL;\r
1092   SVfrDataField       *pField = NULL;\r
1093 \r
1094   Offset = 0;\r
1095   Type   = EFI_IFR_TYPE_OTHER;\r
1096   Size   = 0;\r
1097 \r
1098   CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
1099   CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
1100 \r
1101   //\r
1102   // if it is not struct data type\r
1103   //\r
1104   Type  = pType->mType;\r
1105   Size  = pType->mTotalSize;\r
1106 \r
1107   while (*VarStr != '\0') {\r
1108         CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
1109     CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
1110     pType  = pField->mFieldType;\r
1111     CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
1112     Offset += Tmp;\r
1113     Type   = GetFieldWidth (pField);\r
1114     Size   = GetFieldSize (pField, ArrayIdx);\r
1115   }\r
1116   return VFR_RETURN_SUCCESS;\r
1117 }\r
1118 \r
1119 EFI_VFR_RETURN_CODE\r
1120 CVfrVarDataTypeDB::GetUserDefinedTypeNameList  (\r
1121   OUT CHAR8     ***NameList, \r
1122   OUT UINT32    *ListSize\r
1123   )\r
1124 {\r
1125   UINT32       Index;\r
1126   SVfrDataType *pType;\r
1127 \r
1128   if ((NameList == NULL) || (ListSize == NULL)) {\r
1129     return VFR_RETURN_FATAL_ERROR;\r
1130   }\r
1131 \r
1132   *NameList = NULL;\r
1133   *ListSize = 0;\r
1134 \r
1135   for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1136     if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1137       (*ListSize)++;\r
1138     }\r
1139   }\r
1140 \r
1141   if (*ListSize == 0) {\r
1142     return VFR_RETURN_SUCCESS;\r
1143   }\r
1144 \r
1145   if ((*NameList = new CHAR8*[*ListSize]) == NULL) {\r
1146     *ListSize = 0;\r
1147     return VFR_RETURN_OUT_FOR_RESOURCES;\r
1148   }\r
1149 \r
1150   for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {\r
1151     if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {\r
1152       (*NameList)[Index] = pType->mTypeName;\r
1153     }\r
1154   }\r
1155   return VFR_RETURN_SUCCESS;\r
1156 }\r
1157 \r
1158 BOOLEAN\r
1159 CVfrVarDataTypeDB::IsTypeNameDefined (\r
1160   IN CHAR8 *TypeName\r
1161   )\r
1162 {\r
1163   SVfrDataType *pType;\r
1164 \r
1165   if (TypeName == NULL) {\r
1166     return FALSE;\r
1167   }\r
1168 \r
1169   for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {\r
1170     if (strcmp (pType->mTypeName, TypeName) == 0) {\r
1171       return TRUE;\r
1172     }\r
1173   }\r
1174 \r
1175   return FALSE;\r
1176 }\r
1177 \r
1178 #ifdef CVFR_VARDATATYPEDB_DEBUG\r
1179 VOID\r
1180 CVfrVarDataTypeDB::ParserDB (\r
1181   VOID\r
1182   )\r
1183 {\r
1184   SVfrDataType  *pTNode;\r
1185   SVfrDataField *pFNode;\r
1186 \r
1187   printf ("***************************************************************\n");\r
1188   printf ("\t\tmPackAlign = %x\n", mPackAlign);\r
1189   for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {\r
1190     printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);\r
1191     printf ("\t\tstruct %s {\n", pTNode->mTypeName);\r
1192     for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
1193       printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
1194     }\r
1195     printf ("\t\t};\n");\r
1196         printf ("---------------------------------------------------------------\n");\r
1197   }\r
1198   printf ("***************************************************************\n");\r
1199 }\r
1200 #endif\r
1201 \r
1202 SVfrVarStorageNode::SVfrVarStorageNode (\r
1203   IN EFI_GUID              *Guid,\r
1204   IN CHAR8                 *StoreName,\r
1205   IN EFI_VARSTORE_ID       VarStoreId,\r
1206   IN EFI_STRING_ID         VarName,\r
1207   IN UINT32                VarSize,\r
1208   IN BOOLEAN               Flag\r
1209   )\r
1210 {\r
1211   if (Guid != NULL) {\r
1212     mGuid = *Guid;\r
1213   } else {\r
1214     memset (&Guid, 0, sizeof (EFI_GUID));\r
1215   }\r
1216   if (StoreName != NULL) {\r
1217     mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1218     strcpy (mVarStoreName, StoreName);\r
1219   } else {\r
1220     mVarStoreName = NULL;\r
1221   }\r
1222   mNext                            = NULL;\r
1223   mVarStoreId                      = VarStoreId;\r
1224   mVarStoreType                    = EFI_VFR_VARSTORE_EFI;\r
1225   mStorageInfo.mEfiVar.mEfiVarName = VarName;\r
1226   mStorageInfo.mEfiVar.mEfiVarSize = VarSize;\r
1227   mAssignedFlag                    = Flag;\r
1228 }\r
1229 \r
1230 SVfrVarStorageNode::SVfrVarStorageNode (\r
1231   IN EFI_GUID              *Guid,\r
1232   IN CHAR8                 *StoreName,\r
1233   IN EFI_VARSTORE_ID       VarStoreId,\r
1234   IN SVfrDataType          *DataType,\r
1235   IN BOOLEAN               Flag\r
1236   )\r
1237 {\r
1238   if (Guid != NULL) {\r
1239     mGuid = *Guid;\r
1240   } else {\r
1241     memset (&Guid, 0, sizeof (EFI_GUID));\r
1242   }\r
1243   if (StoreName != NULL) {\r
1244     mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1245     strcpy (mVarStoreName, StoreName);\r
1246   } else {\r
1247     mVarStoreName = NULL;\r
1248   }\r
1249   mNext                    = NULL;\r
1250   mVarStoreId              = VarStoreId;\r
1251   mVarStoreType            = EFI_VFR_VARSTORE_BUFFER;\r
1252   mStorageInfo.mDataType   = DataType;\r
1253   mAssignedFlag            = Flag;\r
1254 }\r
1255 \r
1256 SVfrVarStorageNode::SVfrVarStorageNode (\r
1257   IN CHAR8                 *StoreName,\r
1258   IN EFI_VARSTORE_ID       VarStoreId\r
1259   )\r
1260 {\r
1261   if (StoreName != NULL) {\r
1262     mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
1263     strcpy (mVarStoreName, StoreName);\r
1264   } else {\r
1265     mVarStoreName = NULL;\r
1266   }\r
1267   mNext                              = NULL;\r
1268   mVarStoreId                        = VarStoreId;\r
1269   mVarStoreType                      = EFI_VFR_VARSTORE_NAME;\r
1270   mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
1271   mStorageInfo.mNameSpace.mTableSize = 0;\r
1272 }\r
1273 \r
1274 SVfrVarStorageNode::~SVfrVarStorageNode (\r
1275   VOID\r
1276   )\r
1277 {\r
1278   if (mVarStoreName != NULL) {\r
1279     delete mVarStoreName;\r
1280   }\r
1281 \r
1282   if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
1283     delete mStorageInfo.mNameSpace.mNameTable;\r
1284   }\r
1285 }\r
1286 \r
1287 CVfrDataStorage::CVfrDataStorage (\r
1288   VOID\r
1289   )\r
1290 {\r
1291   UINT32 Index;\r
1292 \r
1293   for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1294     mFreeVarStoreIdBitMap[Index] = 0;\r
1295   }\r
1296 \r
1297   // Question ID 0 is reserved.\r
1298   mFreeVarStoreIdBitMap[0] = 0x80000000;\r
1299 \r
1300   mBufferVarStoreList      = NULL;\r
1301   mEfiVarStoreList         = NULL;\r
1302   mNameVarStoreList        = NULL;\r
1303   mCurrVarStorageNode      = NULL;\r
1304   mNewVarStorageNode       = NULL;\r
1305 }\r
1306 \r
1307 CVfrDataStorage::~CVfrDataStorage (\r
1308   VOID\r
1309   )\r
1310 {\r
1311   SVfrVarStorageNode *pNode;\r
1312 \r
1313   while (mBufferVarStoreList != NULL) {\r
1314     pNode = mBufferVarStoreList;\r
1315     mBufferVarStoreList = mBufferVarStoreList->mNext;\r
1316     delete pNode;\r
1317   }\r
1318   while (mEfiVarStoreList != NULL) {\r
1319     pNode = mEfiVarStoreList;\r
1320     mEfiVarStoreList = mEfiVarStoreList->mNext;\r
1321     delete pNode;\r
1322   }\r
1323   while (mNameVarStoreList != NULL) {\r
1324     pNode = mNameVarStoreList;\r
1325     mNameVarStoreList = mNameVarStoreList->mNext;\r
1326     delete pNode;\r
1327   }\r
1328   if (mNewVarStorageNode != NULL) {\r
1329     delete mNewVarStorageNode;\r
1330   }\r
1331 }\r
1332 \r
1333 EFI_VARSTORE_ID\r
1334 CVfrDataStorage::GetFreeVarStoreId (\r
1335   EFI_VFR_VARSTORE_TYPE VarType\r
1336   )\r
1337 {\r
1338   UINT32  Index, Mask, Offset;\r
1339   \r
1340   //\r
1341   // Assign the different ID range for the different type VarStore to support Framework Vfr\r
1342   //\r
1343   if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {\r
1344     Index = 0;\r
1345   } else if (VarType == EFI_VFR_VARSTORE_EFI) {\r
1346     Index = 1;\r
1347   } else if (VarType == EFI_VFR_VARSTORE_NAME) {\r
1348     Index = 2;\r
1349   }\r
1350 \r
1351   for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {\r
1352     if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {\r
1353       break;\r
1354     }\r
1355   }\r
1356 \r
1357   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
1358     if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
1359       mFreeVarStoreIdBitMap[Index] |= Mask;\r
1360       return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
1361     }\r
1362   }\r
1363 \r
1364   return EFI_VARSTORE_ID_INVALID;\r
1365 }\r
1366 \r
1367 BOOLEAN\r
1368 CVfrDataStorage::ChekVarStoreIdFree (\r
1369   IN EFI_VARSTORE_ID VarStoreId\r
1370   )\r
1371 {\r
1372   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);\r
1373   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1374 \r
1375   return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
1376 }\r
1377 \r
1378 VOID\r
1379 CVfrDataStorage::MarkVarStoreIdUsed (\r
1380   IN EFI_VARSTORE_ID VarStoreId\r
1381   )\r
1382 {\r
1383   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);\r
1384   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1385 \r
1386   mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);\r
1387 }\r
1388 \r
1389 VOID\r
1390 CVfrDataStorage::MarkVarStoreIdUnused (\r
1391   IN EFI_VARSTORE_ID VarStoreId\r
1392   )\r
1393 {\r
1394   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);\r
1395   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);\r
1396 \r
1397   mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
1398 }\r
1399 \r
1400 EFI_VFR_RETURN_CODE\r
1401 CVfrDataStorage::DeclareNameVarStoreBegin (\r
1402   IN CHAR8    *StoreName\r
1403   )\r
1404 {\r
1405   SVfrVarStorageNode *pNode = NULL;\r
1406   EFI_VARSTORE_ID    VarStoreId;\r
1407 \r
1408   if (StoreName == NULL) {\r
1409     return VFR_RETURN_FATAL_ERROR;\r
1410   }\r
1411 \r
1412   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1413     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1414       return VFR_RETURN_REDEFINED;\r
1415     }\r
1416   }\r
1417 \r
1418   VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
1419   if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
1420     return VFR_RETURN_UNDEFINED;\r
1421   }\r
1422 \r
1423   mNewVarStorageNode = pNode;\r
1424 \r
1425   return VFR_RETURN_SUCCESS;\r
1426 }\r
1427 \r
1428 EFI_VFR_RETURN_CODE\r
1429 CVfrDataStorage::NameTableAddItem (\r
1430   IN EFI_STRING_ID  Item\r
1431   )\r
1432 {\r
1433   EFI_VARSTORE_ID *NewTable, *OldTable;\r
1434   UINT32          TableSize;\r
1435 \r
1436   OldTable  = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;\r
1437   TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;\r
1438 \r
1439   if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {\r
1440     if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {\r
1441       return VFR_RETURN_OUT_FOR_RESOURCES;\r
1442     }\r
1443     memcpy (NewTable, OldTable, TableSize);\r
1444     mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;\r
1445   }\r
1446 \r
1447   mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;\r
1448   mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;\r
1449 \r
1450   return VFR_RETURN_SUCCESS;\r
1451 }\r
1452 \r
1453 EFI_VFR_RETURN_CODE\r
1454 CVfrDataStorage::DeclareNameVarStoreEnd (\r
1455   IN EFI_GUID *Guid\r
1456   )\r
1457 {\r
1458   mNewVarStorageNode->mGuid = *Guid;\r
1459   mNewVarStorageNode->mNext = mNameVarStoreList;\r
1460   mNameVarStoreList         = mNewVarStorageNode;\r
1461 \r
1462   mNewVarStorageNode        = NULL;\r
1463 \r
1464   return VFR_RETURN_SUCCESS;\r
1465 }\r
1466 \r
1467 EFI_VFR_RETURN_CODE \r
1468 CVfrDataStorage::DeclareEfiVarStore (\r
1469   IN CHAR8          *StoreName, \r
1470   IN EFI_GUID       *Guid, \r
1471   IN EFI_STRING_ID  NameStrId,\r
1472   IN UINT32         VarSize,\r
1473   IN BOOLEAN        Flag\r
1474   )\r
1475 {\r
1476   SVfrVarStorageNode *pNode;\r
1477   EFI_VARSTORE_ID    VarStoreId;\r
1478 \r
1479   if ((StoreName == NULL) || (Guid == NULL)) {\r
1480     return VFR_RETURN_FATAL_ERROR;\r
1481   }\r
1482 \r
1483   if (VarSize > sizeof (UINT64)) {\r
1484     return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
1485   }\r
1486 \r
1487   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1488     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1489       return VFR_RETURN_REDEFINED;\r
1490     }\r
1491   }\r
1492 \r
1493   VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);\r
1494   if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {\r
1495     return VFR_RETURN_OUT_FOR_RESOURCES;\r
1496   }\r
1497 \r
1498   pNode->mNext       = mEfiVarStoreList;\r
1499   mEfiVarStoreList   = pNode;\r
1500 \r
1501   return VFR_RETURN_SUCCESS;\r
1502 }\r
1503 \r
1504 EFI_VFR_RETURN_CODE \r
1505 CVfrDataStorage::DeclareBufferVarStore (\r
1506   IN CHAR8             *StoreName, \r
1507   IN EFI_GUID          *Guid, \r
1508   IN CVfrVarDataTypeDB *DataTypeDB,\r
1509   IN CHAR8             *TypeName,\r
1510   IN EFI_VARSTORE_ID   VarStoreId,\r
1511   IN BOOLEAN           Flag\r
1512   )\r
1513 {\r
1514   SVfrVarStorageNode   *pNew = NULL;\r
1515   SVfrDataType         *pDataType = NULL;\r
1516 \r
1517   if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
1518     return VFR_RETURN_FATAL_ERROR;\r
1519   }\r
1520 \r
1521   CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
1522 \r
1523   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1524     VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);\r
1525   } else {\r
1526     if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
1527       return VFR_RETURN_VARSTOREID_REDEFINED;\r
1528     }\r
1529     MarkVarStoreIdUsed (VarStoreId);\r
1530   }\r
1531 \r
1532   if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
1533     return VFR_RETURN_OUT_FOR_RESOURCES;\r
1534   }\r
1535 \r
1536   pNew->mNext         = mBufferVarStoreList;\r
1537   mBufferVarStoreList = pNew;\r
1538 \r
1539   if (gCVfrBufferConfig.Register(StoreName) != 0) {\r
1540     return VFR_RETURN_FATAL_ERROR;\r
1541   }\r
1542 \r
1543   return VFR_RETURN_SUCCESS;\r
1544 }\r
1545 \r
1546 EFI_VFR_RETURN_CODE \r
1547 CVfrDataStorage::GetVarStoreId (\r
1548   IN  CHAR8           *StoreName,\r
1549   OUT EFI_VARSTORE_ID *VarStoreId\r
1550   )\r
1551 {\r
1552   SVfrVarStorageNode    *pNode;\r
1553 \r
1554   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1555     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1556       mCurrVarStorageNode = pNode;\r
1557       *VarStoreId = pNode->mVarStoreId;\r
1558       return VFR_RETURN_SUCCESS;\r
1559     }\r
1560   }\r
1561 \r
1562   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1563     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1564       mCurrVarStorageNode = pNode;\r
1565       *VarStoreId = pNode->mVarStoreId;\r
1566       return VFR_RETURN_SUCCESS;\r
1567     }\r
1568   }\r
1569 \r
1570   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1571     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1572       mCurrVarStorageNode = pNode;\r
1573       *VarStoreId = pNode->mVarStoreId;\r
1574       return VFR_RETURN_SUCCESS;\r
1575     }\r
1576   }\r
1577 \r
1578   mCurrVarStorageNode = NULL;\r
1579   *VarStoreId        = EFI_VARSTORE_ID_INVALID;\r
1580   return VFR_RETURN_UNDEFINED;\r
1581 }\r
1582 \r
1583 EFI_VFR_RETURN_CODE\r
1584 CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
1585   IN  CHAR8                  *StoreName,\r
1586   OUT CHAR8                  **DataTypeName\r
1587   )\r
1588 {\r
1589   SVfrVarStorageNode    *pNode;\r
1590 \r
1591   if ((StoreName == NULL) || (DataTypeName == NULL)) {\r
1592     return VFR_RETURN_FATAL_ERROR;\r
1593   }\r
1594 \r
1595   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1596     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
1597       break;\r
1598     }\r
1599   }\r
1600 \r
1601   if (pNode == NULL) {\r
1602     return VFR_RETURN_UNDEFINED;\r
1603   }\r
1604 \r
1605   if (pNode->mStorageInfo.mDataType == NULL) {\r
1606     return VFR_RETURN_FATAL_ERROR;\r
1607   }\r
1608 \r
1609   *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
1610   return VFR_RETURN_SUCCESS;\r
1611 }\r
1612 \r
1613 EFI_VFR_RETURN_CODE\r
1614 CVfrDataStorage::GetVarStoreType (\r
1615   IN  CHAR8                  *StoreName,\r
1616   OUT EFI_VFR_VARSTORE_TYPE  &VarStoreType\r
1617   )\r
1618 {\r
1619   SVfrVarStorageNode    *pNode;\r
1620 \r
1621   if (StoreName == NULL) {\r
1622     return VFR_RETURN_FATAL_ERROR;\r
1623   }\r
1624 \r
1625   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1626     if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
1627       VarStoreType = pNode->mVarStoreType;\r
1628       return VFR_RETURN_SUCCESS;\r
1629     }\r
1630   }\r
1631 \r
1632   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1633     if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
1634       VarStoreType = pNode->mVarStoreType;\r
1635       return VFR_RETURN_SUCCESS;\r
1636     }\r
1637   }\r
1638 \r
1639   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1640     if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
1641       VarStoreType = pNode->mVarStoreType;\r
1642       return VFR_RETURN_SUCCESS;\r
1643     }\r
1644   }\r
1645 \r
1646   VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1647   return VFR_RETURN_UNDEFINED;\r
1648 }\r
1649 \r
1650 EFI_VFR_RETURN_CODE\r
1651 CVfrDataStorage::GetVarStoreName (\r
1652   IN  EFI_VARSTORE_ID VarStoreId, \r
1653   OUT CHAR8           **VarStoreName\r
1654   )\r
1655 {\r
1656   SVfrVarStorageNode    *pNode;\r
1657 \r
1658   if (VarStoreName == NULL) {\r
1659     return VFR_RETURN_FATAL_ERROR;\r
1660   }\r
1661 \r
1662   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1663     if (pNode->mVarStoreId == VarStoreId) {\r
1664       *VarStoreName = pNode->mVarStoreName;\r
1665       return VFR_RETURN_SUCCESS;\r
1666     }\r
1667   }\r
1668 \r
1669   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1670     if (pNode->mVarStoreId == VarStoreId) {\r
1671       *VarStoreName = pNode->mVarStoreName;\r
1672       return VFR_RETURN_SUCCESS;\r
1673     }\r
1674   }\r
1675 \r
1676   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1677     if (pNode->mVarStoreId == VarStoreId) {\r
1678       *VarStoreName = pNode->mVarStoreName;\r
1679       return VFR_RETURN_SUCCESS;\r
1680     }\r
1681   }\r
1682 \r
1683   *VarStoreName = NULL;\r
1684   return VFR_RETURN_UNDEFINED;\r
1685 }\r
1686 \r
1687 EFI_VFR_RETURN_CODE\r
1688 CVfrDataStorage::GetEfiVarStoreInfo (\r
1689   IN OUT EFI_VARSTORE_INFO  *Info\r
1690   )\r
1691 {\r
1692   if (Info == NULL) {\r
1693     return VFR_RETURN_FATAL_ERROR;\r
1694   }\r
1695 \r
1696   if (mCurrVarStorageNode == NULL) {\r
1697     return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
1698   }\r
1699 \r
1700   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
1701   Info->mVarTotalSize  = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
1702   switch (Info->mVarTotalSize) {\r
1703   case 1:\r
1704     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
1705     break;\r
1706   case 2:\r
1707     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
1708     break;\r
1709   case 4:\r
1710     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
1711     break;\r
1712   case 8:\r
1713     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
1714     break;\r
1715   default :\r
1716     return VFR_RETURN_FATAL_ERROR;\r
1717   }\r
1718 \r
1719   return VFR_RETURN_SUCCESS;\r
1720 }\r
1721 \r
1722 EFI_VFR_RETURN_CODE\r
1723 CVfrDataStorage::GetNameVarStoreInfo (\r
1724   OUT EFI_VARSTORE_INFO  *Info,\r
1725   IN  UINT32             Index\r
1726   )\r
1727 {\r
1728   if (Info == NULL) {\r
1729     return VFR_RETURN_FATAL_ERROR;\r
1730   }\r
1731 \r
1732   if (mCurrVarStorageNode == NULL) {\r
1733     return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
1734   }\r
1735   \r
1736   //\r
1737   // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
1738   //\r
1739   if (VfrCompatibleMode) {\r
1740     if (Index == 0) {\r
1741       return VFR_RETURN_ERROR_ARRARY_NUM;\r
1742     }\r
1743     Index --;\r
1744   }\r
1745 \r
1746   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
1747 \r
1748   return VFR_RETURN_SUCCESS;\r
1749 }\r
1750 \r
1751 EFI_VFR_RETURN_CODE\r
1752 CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
1753   IN CHAR8             *StoreName,\r
1754   IN EFI_VARSTORE_INFO &Info\r
1755   )\r
1756 {\r
1757   CHAR8                 NewReqElt[128] = {'\0',};\r
1758   CHAR8                 *OldReqElt = NULL;\r
1759   SVfrVarStorageNode    *pNode = NULL;\r
1760   EFI_IFR_TYPE_VALUE    Value;\r
1761 \r
1762   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1763     if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
1764       break;\r
1765     }\r
1766   }\r
1767 \r
1768   if (pNode == NULL) {\r
1769     return VFR_RETURN_UNDEFINED;\r
1770   }\r
1771 \r
1772   gCVfrBufferConfig.Open ();\r
1773   Value.u8 = 0;\r
1774   if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
1775     return VFR_RETURN_FATAL_ERROR;\r
1776   }\r
1777   gCVfrBufferConfig.Close ();\r
1778 \r
1779   return VFR_RETURN_SUCCESS;\r
1780 }\r
1781 \r
1782 SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
1783   IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
1784   IN CHAR8                *RefName, \r
1785   IN EFI_STRING_ID        DefaultStoreNameId, \r
1786   IN UINT16               DefaultId\r
1787   )\r
1788 {\r
1789   mObjBinAddr = ObjBinAddr;\r
1790 \r
1791   if (RefName != NULL) {\r
1792     mRefName          = new CHAR8[strlen (RefName) + 1];\r
1793     strcpy (mRefName, RefName);\r
1794   } else {\r
1795     mRefName          = NULL;\r
1796   }\r
1797 \r
1798   mNext               = NULL;\r
1799   mDefaultId          = DefaultId;\r
1800   mDefaultStoreNameId = DefaultStoreNameId;\r
1801 }\r
1802 \r
1803 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
1804   VOID\r
1805   )\r
1806 {\r
1807   if (mRefName != NULL) {\r
1808     delete mRefName;\r
1809   }\r
1810 }\r
1811 \r
1812 CVfrDefaultStore::CVfrDefaultStore (\r
1813   VOID\r
1814   )\r
1815 {\r
1816   mDefaultStoreList = NULL;\r
1817 }\r
1818 \r
1819 CVfrDefaultStore::~CVfrDefaultStore (\r
1820   VOID\r
1821   )\r
1822 {\r
1823   SVfrDefaultStoreNode *pTmp = NULL;\r
1824 \r
1825   while (mDefaultStoreList != NULL) {\r
1826     pTmp = mDefaultStoreList;\r
1827     mDefaultStoreList = mDefaultStoreList->mNext;\r
1828     delete pTmp;\r
1829   }\r
1830 }\r
1831 \r
1832 EFI_VFR_RETURN_CODE\r
1833 CVfrDefaultStore::RegisterDefaultStore (\r
1834   IN CHAR8                *ObjBinAddr,\r
1835   IN CHAR8                *RefName,\r
1836   IN EFI_STRING_ID        DefaultStoreNameId,\r
1837   IN UINT16               DefaultId\r
1838   )\r
1839 {\r
1840   SVfrDefaultStoreNode *pNode = NULL;\r
1841 \r
1842   if (RefName == NULL) {\r
1843     return VFR_RETURN_FATAL_ERROR;\r
1844   }\r
1845 \r
1846   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1847     if (strcmp (pNode->mRefName, RefName) == 0) {\r
1848       return VFR_RETURN_REDEFINED;\r
1849     }\r
1850   }\r
1851 \r
1852   if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
1853     return VFR_RETURN_OUT_FOR_RESOURCES;\r
1854   }\r
1855 \r
1856   pNode->mNext               = mDefaultStoreList;\r
1857   mDefaultStoreList          = pNode;\r
1858 \r
1859   return VFR_RETURN_SUCCESS;\r
1860 }\r
1861 \r
1862 /*\r
1863  * assign new reference name or new default store name id only if \r
1864  * the original is invalid\r
1865  */\r
1866 EFI_VFR_RETURN_CODE\r
1867 CVfrDefaultStore::ReRegisterDefaultStoreById (\r
1868   IN UINT16          DefaultId,\r
1869   IN CHAR8           *RefName,\r
1870   IN EFI_STRING_ID   DefaultStoreNameId\r
1871   )\r
1872 {\r
1873   SVfrDefaultStoreNode *pNode = NULL;\r
1874 \r
1875   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1876     if (pNode->mDefaultId == DefaultId) {\r
1877       break;\r
1878     }\r
1879   }\r
1880 \r
1881   if (pNode == NULL) {\r
1882     return VFR_RETURN_UNDEFINED;\r
1883   } else {\r
1884     if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
1885       pNode->mDefaultStoreNameId  = DefaultStoreNameId;\r
1886       if (pNode->mObjBinAddr != NULL) {\r
1887         pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
1888       }\r
1889     } else {\r
1890       return VFR_RETURN_REDEFINED;\r
1891     }\r
1892 \r
1893     if (RefName != NULL) {\r
1894       delete pNode->mRefName;\r
1895       pNode->mRefName = new CHAR8[strlen (RefName) + 1];\r
1896       if (pNode->mRefName != NULL) {\r
1897         strcpy (pNode->mRefName, RefName);\r
1898       }\r
1899     }\r
1900   }\r
1901 \r
1902   return VFR_RETURN_SUCCESS;\r
1903 }\r
1904 \r
1905 BOOLEAN\r
1906 CVfrDefaultStore::DefaultIdRegistered (\r
1907   IN UINT16          DefaultId\r
1908   )\r
1909 {\r
1910   SVfrDefaultStoreNode *pNode = NULL;\r
1911 \r
1912   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1913     if (pNode->mDefaultId == DefaultId) {\r
1914       return TRUE;\r
1915     }\r
1916   }\r
1917 \r
1918   return FALSE;\r
1919 }\r
1920 \r
1921 EFI_VFR_RETURN_CODE\r
1922 CVfrDefaultStore::GetDefaultId (\r
1923   IN  CHAR8           *RefName,\r
1924   OUT UINT16          *DefaultId\r
1925   )\r
1926 {\r
1927   SVfrDefaultStoreNode *pTmp = NULL;\r
1928 \r
1929   if (DefaultId == NULL) {\r
1930     return VFR_RETURN_FATAL_ERROR;\r
1931   }\r
1932 \r
1933   for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
1934     if (strcmp (pTmp->mRefName, RefName) == 0) {\r
1935       *DefaultId = pTmp->mDefaultId;\r
1936       return VFR_RETURN_SUCCESS;\r
1937     }\r
1938   }\r
1939 \r
1940   return VFR_RETURN_UNDEFINED;\r
1941 }\r
1942 \r
1943 STATIC\r
1944 EFI_VFR_RETURN_CODE\r
1945 AltCfgItemPrintToBuffer (\r
1946   IN CHAR8              *NewAltCfg, \r
1947   IN EFI_VARSTORE_INFO  Info, \r
1948   IN UINT8              Type,\r
1949   IN EFI_IFR_TYPE_VALUE Value\r
1950   )\r
1951 {\r
1952   UINT32 Index;\r
1953   UINT8  *BufChar = NULL;\r
1954   UINT32 Count    = 0;\r
1955 \r
1956   if (NewAltCfg != NULL) {\r
1957     Count = sprintf (\r
1958               NewAltCfg, \r
1959               "&OFFSET=%x&WIDTH=%x&VALUE=", \r
1960               Info.mInfo.mVarOffset, \r
1961               Info.mVarTotalSize\r
1962               );\r
1963     NewAltCfg += Count;\r
1964 \r
1965     switch (Type) {\r
1966     case EFI_IFR_TYPE_NUM_SIZE_8 :\r
1967       Count = sprintf (NewAltCfg, "%x", Value.u8);\r
1968       NewAltCfg += Count;\r
1969       break;\r
1970     case EFI_IFR_TYPE_NUM_SIZE_16 :\r
1971       Count = sprintf (NewAltCfg, "%x", Value.u16);\r
1972       NewAltCfg += Count;\r
1973       break;\r
1974     case EFI_IFR_TYPE_NUM_SIZE_32 :\r
1975       Count = sprintf (NewAltCfg, "%x", Value.u32);\r
1976       NewAltCfg += Count;\r
1977       break;\r
1978     case EFI_IFR_TYPE_NUM_SIZE_64 :\r
1979       Count = sprintf (NewAltCfg, "%x", Value.u64);\r
1980       NewAltCfg += Count;\r
1981       break;\r
1982     case EFI_IFR_TYPE_BOOLEAN :\r
1983       Count = sprintf (NewAltCfg, "%x", Value.b);\r
1984       NewAltCfg += Count;\r
1985       break;\r
1986     case EFI_IFR_TYPE_TIME :\r
1987 #if 1\r
1988       Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));\r
1989       NewAltCfg += Count;\r
1990 #else\r
1991       BufChar = (UINT8 *)&Value.time;\r
1992       for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {\r
1993         Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
1994         NewAltCfg += Count;\r
1995       }\r
1996 #endif\r
1997       break;\r
1998     case EFI_IFR_TYPE_DATE :\r
1999 #if 1\r
2000       Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));\r
2001       NewAltCfg += Count;\r
2002 #else\r
2003       BufChar = (UINT8 *)&Value.date;\r
2004       for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {\r
2005         Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
2006         NewAltCfg += Count;\r
2007       }\r
2008 #endif\r
2009       break;\r
2010     case EFI_IFR_TYPE_STRING :\r
2011       Count = sprintf (NewAltCfg, "%x", Value.string);\r
2012       NewAltCfg += Count;\r
2013       break;\r
2014     case EFI_IFR_TYPE_OTHER :\r
2015       return VFR_RETURN_UNSUPPORTED;\r
2016         }\r
2017   }\r
2018 \r
2019   return VFR_RETURN_FATAL_ERROR;    \r
2020 }\r
2021 \r
2022 EFI_VFR_RETURN_CODE\r
2023 CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
2024   IN EFI_VARSTORE_ID    DefaultId,\r
2025   IN EFI_VARSTORE_INFO  &Info,\r
2026   IN CHAR8              *VarStoreName,\r
2027   IN UINT8              Type,\r
2028   IN EFI_IFR_TYPE_VALUE Value\r
2029   )\r
2030 {\r
2031   SVfrDefaultStoreNode  *pNode = NULL;\r
2032   CHAR8                 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
2033   INTN                  Returnvalue = 0;\r
2034 \r
2035   if (VarStoreName == NULL) {\r
2036     return VFR_RETURN_FATAL_ERROR;\r
2037   }\r
2038 \r
2039   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2040     if (pNode->mDefaultId == DefaultId) {\r
2041       break;\r
2042     }\r
2043   }\r
2044 \r
2045   if (pNode == NULL) {\r
2046     return VFR_RETURN_UNDEFINED;\r
2047   }\r
2048 \r
2049   gCVfrBufferConfig.Open ();\r
2050 \r
2051   sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
2052   if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {\r
2053     if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
2054       goto WriteError;\r
2055     }\r
2056   }\r
2057   \r
2058   gCVfrBufferConfig.Close ();\r
2059 \r
2060   return VFR_RETURN_SUCCESS;\r
2061 \r
2062 WriteError:\r
2063   gCVfrBufferConfig.Close ();\r
2064   return (EFI_VFR_RETURN_CODE)Returnvalue;\r
2065 }\r
2066 \r
2067 SVfrRuleNode::SVfrRuleNode (\r
2068   IN CHAR8       *RuleName, \r
2069   IN UINT8       RuleId\r
2070   )\r
2071 {\r
2072   if (RuleName != NULL) {\r
2073     mRuleName = new CHAR8[strlen (RuleName) + 1];\r
2074     strcpy (mRuleName, RuleName);\r
2075   } else {\r
2076     mRuleName = NULL;\r
2077   }\r
2078 \r
2079   mNext       = NULL;\r
2080   mRuleId     = RuleId;\r
2081 }\r
2082 \r
2083 SVfrRuleNode::~SVfrRuleNode (\r
2084   VOID\r
2085   )\r
2086 {\r
2087   if (mRuleName != NULL) {\r
2088     delete mRuleName;\r
2089   }\r
2090 }\r
2091 \r
2092 CVfrRulesDB::CVfrRulesDB ()\r
2093 {\r
2094   mRuleList   = NULL;\r
2095   mFreeRuleId = EFI_VARSTORE_ID_START;\r
2096 }\r
2097 \r
2098 CVfrRulesDB::~CVfrRulesDB ()\r
2099 {\r
2100   SVfrRuleNode *pNode;\r
2101 \r
2102   while(mRuleList != NULL) {\r
2103     pNode = mRuleList;\r
2104     mRuleList = mRuleList->mNext;\r
2105     delete pNode;\r
2106   }\r
2107 }\r
2108 \r
2109 VOID\r
2110 CVfrRulesDB::RegisterRule (\r
2111   IN CHAR8  *RuleName\r
2112   )\r
2113 {\r
2114   SVfrRuleNode *pNew;\r
2115 \r
2116   if (RuleName == NULL) {\r
2117     return ;\r
2118   }\r
2119 \r
2120   if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
2121     return ;\r
2122   }\r
2123 \r
2124   mFreeRuleId++;\r
2125 \r
2126   pNew->mNext = mRuleList;\r
2127   mRuleList   = pNew;\r
2128 }\r
2129 \r
2130 UINT8\r
2131 CVfrRulesDB::GetRuleId (\r
2132   IN CHAR8  *RuleName\r
2133   )\r
2134 {\r
2135   SVfrRuleNode *pNode;\r
2136 \r
2137   if (RuleName == NULL) {\r
2138     return EFI_RULE_ID_INVALID;\r
2139   }\r
2140 \r
2141   for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
2142     if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
2143       return pNode->mRuleId;\r
2144     }\r
2145   }\r
2146 \r
2147   return EFI_RULE_ID_INVALID;\r
2148 }\r
2149 \r
2150 CVfrRulesDB gCVfrRulesDB;\r
2151 \r
2152 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2153   VOID\r
2154   )\r
2155 {\r
2156   mVarStoreId      = EFI_VARSTORE_ID_INVALID;\r
2157   mInfo.mVarName   = EFI_STRING_ID_INVALID;\r
2158   mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2159   mVarType         = EFI_IFR_TYPE_OTHER;\r
2160   mVarTotalSize    = 0;\r
2161 }\r
2162 \r
2163 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2164   IN EFI_VARSTORE_INFO &Info\r
2165   )\r
2166 {\r
2167   mVarStoreId      = Info.mVarStoreId;\r
2168   mInfo.mVarName   = Info.mInfo.mVarName;\r
2169   mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2170   mVarType         = Info.mVarType;\r
2171   mVarTotalSize    = Info.mVarTotalSize;\r
2172 }\r
2173 \r
2174 BOOLEAN \r
2175 EFI_VARSTORE_INFO::operator == (\r
2176   IN EFI_VARSTORE_INFO  *Info\r
2177   )\r
2178 {\r
2179   if ((mVarStoreId == Info->mVarStoreId) &&\r
2180           (mInfo.mVarName == Info->mInfo.mVarName) &&\r
2181       (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
2182       (mVarType == Info->mVarType) &&\r
2183       (mVarTotalSize == Info->mVarTotalSize)) {\r
2184     return TRUE;\r
2185   }\r
2186 \r
2187   return FALSE;\r
2188 }\r
2189 \r
2190 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
2191 \r
2192 EFI_QUESTION_ID\r
2193 CVfrQuestionDB::GetFreeQuestionId (\r
2194   VOID\r
2195   )\r
2196 {\r
2197   UINT32  Index, Mask, Offset;\r
2198 \r
2199   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2200     if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
2201       break;\r
2202     }\r
2203   }\r
2204 \r
2205   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
2206     if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
2207       mFreeQIdBitMap[Index] |= Mask;\r
2208       return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
2209     }\r
2210   }\r
2211 \r
2212   return EFI_QUESTION_ID_INVALID;\r
2213 }\r
2214 \r
2215 BOOLEAN\r
2216 CVfrQuestionDB::ChekQuestionIdFree (\r
2217   IN EFI_QUESTION_ID QId\r
2218   )\r
2219 {\r
2220   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
2221   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2222 \r
2223   return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
2224 }\r
2225 \r
2226 VOID \r
2227 CVfrQuestionDB::MarkQuestionIdUsed (\r
2228   IN EFI_QUESTION_ID QId\r
2229   )\r
2230 {\r
2231   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
2232   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2233 \r
2234   mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
2235 }\r
2236 \r
2237 VOID \r
2238 CVfrQuestionDB::MarkQuestionIdUnused (\r
2239   IN EFI_QUESTION_ID QId\r
2240   )\r
2241 {\r
2242   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
2243   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2244 \r
2245   mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
2246 }\r
2247 \r
2248 SVfrQuestionNode::SVfrQuestionNode (\r
2249   IN CHAR8  *Name,\r
2250   IN CHAR8  *VarIdStr,\r
2251   IN UINT32 BitMask\r
2252   )\r
2253 {\r
2254   mName       = NULL;\r
2255   mVarIdStr   = NULL;\r
2256   mQuestionId = EFI_QUESTION_ID_INVALID;\r
2257   mBitMask    = BitMask;\r
2258   mNext       = NULL;\r
2259 \r
2260   if (Name == NULL) {\r
2261     mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
2262     strcpy (mName, "$DEFAULT");\r
2263   } else {\r
2264     mName = new CHAR8[strlen (Name) + 1];\r
2265     strcpy (mName, Name);\r
2266   }\r
2267 \r
2268   if (VarIdStr != NULL) {\r
2269     mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];\r
2270     strcpy (mVarIdStr, VarIdStr);\r
2271   } else {\r
2272     mVarIdStr = new CHAR8[strlen ("$") + 1];\r
2273     strcpy (mVarIdStr, "$");\r
2274   }\r
2275 }\r
2276 \r
2277 SVfrQuestionNode::~SVfrQuestionNode (\r
2278   VOID\r
2279   )\r
2280 {\r
2281   if (mName != NULL) {\r
2282     delete mName;\r
2283   }\r
2284 \r
2285   if (mVarIdStr != NULL) {\r
2286     delete mVarIdStr;\r
2287   }\r
2288 }\r
2289 \r
2290 CVfrQuestionDB::CVfrQuestionDB ()\r
2291 {\r
2292   UINT32 Index;\r
2293 \r
2294   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2295     mFreeQIdBitMap[Index] = 0;\r
2296   }\r
2297 \r
2298   // Question ID 0 is reserved.\r
2299   mFreeQIdBitMap[0] = 0x80000000;\r
2300   mQuestionList     = NULL;\r
2301\r
2302 \r
2303 CVfrQuestionDB::~CVfrQuestionDB ()\r
2304 {\r
2305   SVfrQuestionNode     *pNode;\r
2306 \r
2307   while (mQuestionList != NULL) {\r
2308     pNode = mQuestionList;\r
2309     mQuestionList = mQuestionList->mNext;\r
2310     delete pNode;\r
2311   }\r
2312 }\r
2313 \r
2314 //\r
2315 // Reset to init state\r
2316 //\r
2317 VOID\r
2318 CVfrQuestionDB::ResetInit(\r
2319   IN VOID\r
2320   )\r
2321 {\r
2322   UINT32               Index;\r
2323   SVfrQuestionNode     *pNode;\r
2324 \r
2325   while (mQuestionList != NULL) {\r
2326     pNode = mQuestionList;\r
2327     mQuestionList = mQuestionList->mNext;\r
2328     delete pNode;\r
2329   }\r
2330 \r
2331   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2332     mFreeQIdBitMap[Index] = 0;\r
2333   }\r
2334 \r
2335   // Question ID 0 is reserved.\r
2336   mFreeQIdBitMap[0] = 0x80000000;\r
2337   mQuestionList     = NULL;   \r
2338 }\r
2339 \r
2340 VOID\r
2341 CVfrQuestionDB::PrintAllQuestion (\r
2342   VOID\r
2343   )\r
2344 {\r
2345   SVfrQuestionNode *pNode = NULL;\r
2346 \r
2347   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2348     printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
2349   }\r
2350 }\r
2351 \r
2352 EFI_VFR_RETURN_CODE\r
2353 CVfrQuestionDB::RegisterQuestion (\r
2354   IN     CHAR8             *Name,\r
2355   IN     CHAR8             *VarIdStr,\r
2356   IN OUT EFI_QUESTION_ID   &QuestionId\r
2357   )\r
2358 {\r
2359   SVfrQuestionNode *pNode = NULL;\r
2360 \r
2361   if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
2362     return VFR_RETURN_REDEFINED;\r
2363   }\r
2364 \r
2365   if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
2366     return VFR_RETURN_OUT_FOR_RESOURCES;\r
2367   }\r
2368 \r
2369   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2370     QuestionId = GetFreeQuestionId ();\r
2371   } else {\r
2372     //\r
2373     // For Framework Vfr, don't check question ID conflict.\r
2374     //\r
2375     if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {\r
2376       delete pNode;\r
2377       return VFR_RETURN_QUESTIONID_REDEFINED;\r
2378     }\r
2379     MarkQuestionIdUsed (QuestionId);\r
2380   }\r
2381   pNode->mQuestionId = QuestionId;\r
2382 \r
2383   pNode->mNext       = mQuestionList;\r
2384   mQuestionList      = pNode;\r
2385 \r
2386   gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2387 \r
2388   return VFR_RETURN_SUCCESS;\r
2389 }\r
2390 \r
2391 VOID\r
2392 CVfrQuestionDB::RegisterOldDateQuestion (\r
2393   IN     CHAR8           *YearVarId, \r
2394   IN     CHAR8           *MonthVarId, \r
2395   IN     CHAR8           *DayVarId, \r
2396   IN OUT EFI_QUESTION_ID &QuestionId\r
2397   )\r
2398 {\r
2399   SVfrQuestionNode *pNode[3] = {NULL, };\r
2400   UINT32           Index;\r
2401 \r
2402   if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
2403     return;\r
2404   }\r
2405 \r
2406   if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
2407     goto Err;\r
2408   }\r
2409   if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
2410     goto Err;\r
2411   }\r
2412   if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
2413     goto Err;\r
2414   }\r
2415 \r
2416   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2417     QuestionId = GetFreeQuestionId ();\r
2418   } else {\r
2419     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2420       goto Err;\r
2421     }\r
2422     MarkQuestionIdUsed (QuestionId);\r
2423   }\r
2424 \r
2425   pNode[0]->mQuestionId = QuestionId;\r
2426   pNode[1]->mQuestionId = QuestionId;\r
2427   pNode[2]->mQuestionId = QuestionId;\r
2428   pNode[0]->mNext       = pNode[1];\r
2429   pNode[1]->mNext       = pNode[2];\r
2430   pNode[2]->mNext       = mQuestionList;\r
2431   mQuestionList         = pNode[0];\r
2432 \r
2433   gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2434   gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2435   gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2436 \r
2437   return;\r
2438 \r
2439 Err:\r
2440   for (Index = 0; Index < 3; Index++) {\r
2441     if (pNode[Index] != NULL) {\r
2442       delete pNode[Index];\r
2443     }\r
2444   }\r
2445   QuestionId = EFI_QUESTION_ID_INVALID;\r
2446 }\r
2447 \r
2448 VOID\r
2449 CVfrQuestionDB::RegisterNewDateQuestion (\r
2450   IN     CHAR8           *Name,\r
2451   IN     CHAR8           *BaseVarId, \r
2452   IN OUT EFI_QUESTION_ID &QuestionId\r
2453   )\r
2454 {\r
2455   SVfrQuestionNode     *pNode[3] = {NULL, };\r
2456   UINT32               Len;\r
2457   CHAR8                *VarIdStr[3] = {NULL, };\r
2458   INT8                 Index;\r
2459 \r
2460   if (BaseVarId == NULL) {\r
2461     return;\r
2462   }\r
2463 \r
2464   Len = strlen (BaseVarId);\r
2465 \r
2466   VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2467   if (VarIdStr[0] != NULL) {\r
2468     strcpy (VarIdStr[0], BaseVarId);\r
2469     strcat (VarIdStr[0], ".Year");\r
2470   }\r
2471   VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2472   if (VarIdStr[1] != NULL) {\r
2473     strcpy (VarIdStr[1], BaseVarId);\r
2474     strcat (VarIdStr[1], ".Month");\r
2475   }\r
2476   VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2477   if (VarIdStr[2] != NULL) {\r
2478     strcpy (VarIdStr[2], BaseVarId);\r
2479     strcat (VarIdStr[2], ".Day");\r
2480   }\r
2481 \r
2482   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
2483     goto Err;\r
2484   }\r
2485   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
2486     goto Err;\r
2487   }\r
2488   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
2489     goto Err;\r
2490   }\r
2491 \r
2492   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2493     QuestionId = GetFreeQuestionId ();\r
2494   } else {\r
2495     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2496       goto Err;\r
2497     }\r
2498     MarkQuestionIdUsed (QuestionId);\r
2499   }\r
2500 \r
2501   pNode[0]->mQuestionId = QuestionId;\r
2502   pNode[1]->mQuestionId = QuestionId;\r
2503   pNode[2]->mQuestionId = QuestionId;\r
2504   pNode[0]->mNext       = pNode[1];\r
2505   pNode[1]->mNext       = pNode[2];\r
2506   pNode[2]->mNext       = mQuestionList;\r
2507   mQuestionList         = pNode[0];\r
2508 \r
2509   for (Index = 0; Index < 3; Index++) {\r
2510     if (VarIdStr[Index] != NULL) {\r
2511       delete VarIdStr[Index];\r
2512     }\r
2513   }\r
2514 \r
2515   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2516   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2517   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2518 \r
2519   return;\r
2520 \r
2521 Err:\r
2522   for (Index = 0; Index < 3; Index++) {\r
2523     if (pNode[Index] != NULL) {\r
2524       delete pNode[Index];\r
2525     }\r
2526 \r
2527     if (VarIdStr[Index] != NULL) {\r
2528       delete VarIdStr[Index];\r
2529     }\r
2530   }\r
2531 }\r
2532 \r
2533 VOID\r
2534 CVfrQuestionDB::RegisterOldTimeQuestion (\r
2535   IN     CHAR8           *HourVarId, \r
2536   IN     CHAR8           *MinuteVarId, \r
2537   IN     CHAR8           *SecondVarId, \r
2538   IN OUT EFI_QUESTION_ID &QuestionId\r
2539   )\r
2540 {\r
2541   SVfrQuestionNode *pNode[3] = {NULL, };\r
2542   UINT32           Index;\r
2543 \r
2544   if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
2545     return;\r
2546   }\r
2547 \r
2548   if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
2549     goto Err;\r
2550   }\r
2551   if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
2552     goto Err;\r
2553   }\r
2554   if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
2555     goto Err;\r
2556   }\r
2557 \r
2558   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2559     QuestionId = GetFreeQuestionId ();\r
2560   } else {\r
2561     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2562       goto Err;\r
2563     }\r
2564     MarkQuestionIdUsed (QuestionId);\r
2565   }\r
2566 \r
2567   pNode[0]->mQuestionId = QuestionId;\r
2568   pNode[1]->mQuestionId = QuestionId;\r
2569   pNode[2]->mQuestionId = QuestionId;\r
2570   pNode[0]->mNext       = pNode[1];\r
2571   pNode[1]->mNext       = pNode[2];\r
2572   pNode[2]->mNext       = mQuestionList;\r
2573   mQuestionList         = pNode[0];\r
2574 \r
2575   gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2576   gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2577   gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2578 \r
2579   return;\r
2580 \r
2581 Err:\r
2582   for (Index = 0; Index < 3; Index++) {\r
2583     if (pNode[Index] != NULL) {\r
2584       delete pNode[Index];\r
2585     }\r
2586   }\r
2587   QuestionId = EFI_QUESTION_ID_INVALID;\r
2588 }\r
2589 \r
2590 VOID\r
2591 CVfrQuestionDB::RegisterNewTimeQuestion (\r
2592   IN     CHAR8           *Name,\r
2593   IN     CHAR8           *BaseVarId,\r
2594   IN OUT EFI_QUESTION_ID &QuestionId\r
2595   )\r
2596 {\r
2597   SVfrQuestionNode     *pNode[3] = {NULL, };\r
2598   UINT32               Len;\r
2599   CHAR8                *VarIdStr[3] = {NULL, };\r
2600   INT8                 Index;\r
2601 \r
2602   if (BaseVarId == NULL) {\r
2603     return;\r
2604   }\r
2605 \r
2606   Len = strlen (BaseVarId);\r
2607 \r
2608   VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
2609   if (VarIdStr[0] != NULL) {\r
2610     strcpy (VarIdStr[0], BaseVarId);\r
2611     strcat (VarIdStr[0], ".Hour");\r
2612   }\r
2613   VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
2614   if (VarIdStr[1] != NULL) {\r
2615     strcpy (VarIdStr[1], BaseVarId);\r
2616     strcat (VarIdStr[1], ".Minute");\r
2617   }\r
2618   VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
2619   if (VarIdStr[2] != NULL) {\r
2620     strcpy (VarIdStr[2], BaseVarId);\r
2621     strcat (VarIdStr[2], ".Second");\r
2622   }\r
2623 \r
2624   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
2625     goto Err;\r
2626   }\r
2627   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
2628     goto Err;\r
2629   }\r
2630   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
2631     goto Err;\r
2632   }\r
2633 \r
2634   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2635     QuestionId = GetFreeQuestionId ();\r
2636   } else {\r
2637     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2638       goto Err;\r
2639     }\r
2640     MarkQuestionIdUsed (QuestionId);\r
2641   }\r
2642 \r
2643   pNode[0]->mQuestionId = QuestionId;\r
2644   pNode[1]->mQuestionId = QuestionId;\r
2645   pNode[2]->mQuestionId = QuestionId;\r
2646   pNode[0]->mNext       = pNode[1];\r
2647   pNode[1]->mNext       = pNode[2];\r
2648   pNode[2]->mNext       = mQuestionList;\r
2649   mQuestionList         = pNode[0];\r
2650 \r
2651   for (Index = 0; Index < 3; Index++) {\r
2652     if (VarIdStr[Index] != NULL) {\r
2653       delete VarIdStr[Index];\r
2654     }\r
2655   }\r
2656 \r
2657   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2658   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2659   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2660 \r
2661   return;\r
2662 \r
2663 Err:\r
2664   for (Index = 0; Index < 3; Index++) {\r
2665     if (pNode[Index] != NULL) {\r
2666       delete pNode[Index];\r
2667     }\r
2668 \r
2669     if (VarIdStr[Index] != NULL) {\r
2670       delete VarIdStr[Index];\r
2671     }\r
2672   }\r
2673 }\r
2674 \r
2675 EFI_VFR_RETURN_CODE\r
2676 CVfrQuestionDB::UpdateQuestionId (\r
2677   IN EFI_QUESTION_ID   QId,\r
2678   IN EFI_QUESTION_ID   NewQId\r
2679   )\r
2680 {\r
2681   SVfrQuestionNode *pNode = NULL;\r
2682   \r
2683   if (QId == NewQId) {\r
2684     // don't update\r
2685     return VFR_RETURN_SUCCESS;\r
2686   }\r
2687   \r
2688   //\r
2689   // For Framework Vfr, don't check question ID conflict.\r
2690   //  \r
2691   if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
2692     return VFR_RETURN_REDEFINED;\r
2693   }\r
2694 \r
2695   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2696     if (pNode->mQuestionId == QId) {\r
2697       break;\r
2698     }\r
2699   }\r
2700 \r
2701   if (pNode == NULL) {\r
2702     return VFR_RETURN_UNDEFINED;\r
2703   }\r
2704 \r
2705   MarkQuestionIdUnused (QId);\r
2706   pNode->mQuestionId = NewQId;\r
2707   MarkQuestionIdUsed (NewQId);\r
2708 \r
2709   gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
2710 \r
2711   return VFR_RETURN_SUCCESS;\r
2712 }\r
2713 \r
2714 VOID \r
2715 CVfrQuestionDB::GetQuestionId (\r
2716   IN  CHAR8             *Name,\r
2717   IN  CHAR8             *VarIdStr,\r
2718   OUT EFI_QUESTION_ID   &QuestionId,\r
2719   OUT UINT32            &BitMask\r
2720   )\r
2721 {\r
2722   SVfrQuestionNode *pNode;\r
2723 \r
2724   QuestionId = EFI_QUESTION_ID_INVALID;\r
2725   BitMask    = 0x00000000;\r
2726 \r
2727   if ((Name == NULL) && (VarIdStr == NULL)) {\r
2728     return ;\r
2729   }\r
2730 \r
2731   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2732     if (Name != NULL) {\r
2733       if (strcmp (pNode->mName, Name) != 0) {\r
2734         continue;\r
2735       }\r
2736     }\r
2737 \r
2738     if (VarIdStr != NULL) {\r
2739       if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
2740         continue;\r
2741       }\r
2742         }\r
2743 \r
2744     QuestionId = pNode->mQuestionId;\r
2745     BitMask    = pNode->mBitMask;\r
2746     break;\r
2747   }\r
2748 \r
2749   return ;\r
2750 }\r
2751 \r
2752 EFI_VFR_RETURN_CODE \r
2753 CVfrQuestionDB::FindQuestion (\r
2754   IN EFI_QUESTION_ID QuestionId\r
2755   )\r
2756 {\r
2757   SVfrQuestionNode *pNode;\r
2758 \r
2759   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2760     return VFR_RETURN_INVALID_PARAMETER;\r
2761   }\r
2762 \r
2763   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2764     if (pNode->mQuestionId == QuestionId) {\r
2765       return VFR_RETURN_SUCCESS;\r
2766     }\r
2767   }\r
2768 \r
2769   return VFR_RETURN_UNDEFINED;\r
2770 }\r
2771 \r
2772 EFI_VFR_RETURN_CODE \r
2773 CVfrQuestionDB::FindQuestion (\r
2774   IN CHAR8 *Name\r
2775   )\r
2776 {\r
2777   SVfrQuestionNode *pNode;\r
2778 \r
2779   if (Name == NULL) {\r
2780     return VFR_RETURN_FATAL_ERROR;\r
2781   }\r
2782 \r
2783   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2784     if (strcmp (pNode->mName, Name) == 0) {\r
2785       return VFR_RETURN_SUCCESS;\r
2786     }\r
2787   }\r
2788 \r
2789   return VFR_RETURN_UNDEFINED;\r
2790 }\r
2791 \r
2792 BOOLEAN  VfrCompatibleMode = FALSE;\r