Only Check the buffer var store CheckBox question to the boolean type according to...
[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_VARSTORE_TYPE\r
1651 CVfrDataStorage::GetVarStoreType (\r
1652   IN  EFI_VARSTORE_ID        VarStoreId\r
1653   )\r
1654 {\r
1655   SVfrVarStorageNode    *pNode;\r
1656   EFI_VFR_VARSTORE_TYPE VarStoreType;\r
1657 \r
1658   VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
1659 \r
1660   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
1661     return VarStoreType;\r
1662   }\r
1663 \r
1664   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1665     if (pNode->mVarStoreId == VarStoreId) {\r
1666       VarStoreType = pNode->mVarStoreType;\r
1667       return VarStoreType;\r
1668     }\r
1669   }\r
1670 \r
1671   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1672     if (pNode->mVarStoreId == VarStoreId) {\r
1673       VarStoreType = pNode->mVarStoreType;\r
1674       return VarStoreType;\r
1675     }\r
1676   }\r
1677 \r
1678   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1679     if (pNode->mVarStoreId == VarStoreId) {\r
1680       VarStoreType = pNode->mVarStoreType;\r
1681       return VarStoreType;\r
1682     }\r
1683   }\r
1684 \r
1685   return VarStoreType;\r
1686 }\r
1687 \r
1688 EFI_VFR_RETURN_CODE\r
1689 CVfrDataStorage::GetVarStoreName (\r
1690   IN  EFI_VARSTORE_ID VarStoreId, \r
1691   OUT CHAR8           **VarStoreName\r
1692   )\r
1693 {\r
1694   SVfrVarStorageNode    *pNode;\r
1695 \r
1696   if (VarStoreName == NULL) {\r
1697     return VFR_RETURN_FATAL_ERROR;\r
1698   }\r
1699 \r
1700   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1701     if (pNode->mVarStoreId == VarStoreId) {\r
1702       *VarStoreName = pNode->mVarStoreName;\r
1703       return VFR_RETURN_SUCCESS;\r
1704     }\r
1705   }\r
1706 \r
1707   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1708     if (pNode->mVarStoreId == VarStoreId) {\r
1709       *VarStoreName = pNode->mVarStoreName;\r
1710       return VFR_RETURN_SUCCESS;\r
1711     }\r
1712   }\r
1713 \r
1714   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1715     if (pNode->mVarStoreId == VarStoreId) {\r
1716       *VarStoreName = pNode->mVarStoreName;\r
1717       return VFR_RETURN_SUCCESS;\r
1718     }\r
1719   }\r
1720 \r
1721   *VarStoreName = NULL;\r
1722   return VFR_RETURN_UNDEFINED;\r
1723 }\r
1724 \r
1725 EFI_VFR_RETURN_CODE\r
1726 CVfrDataStorage::GetEfiVarStoreInfo (\r
1727   IN OUT EFI_VARSTORE_INFO  *Info\r
1728   )\r
1729 {\r
1730   if (Info == NULL) {\r
1731     return VFR_RETURN_FATAL_ERROR;\r
1732   }\r
1733 \r
1734   if (mCurrVarStorageNode == NULL) {\r
1735     return VFR_RETURN_GET_EFIVARSTORE_ERROR;\r
1736   }\r
1737 \r
1738   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;\r
1739   Info->mVarTotalSize  = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;\r
1740   switch (Info->mVarTotalSize) {\r
1741   case 1:\r
1742     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
1743     break;\r
1744   case 2:\r
1745     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;\r
1746     break;\r
1747   case 4:\r
1748     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;\r
1749     break;\r
1750   case 8:\r
1751     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;\r
1752     break;\r
1753   default :\r
1754     return VFR_RETURN_FATAL_ERROR;\r
1755   }\r
1756 \r
1757   return VFR_RETURN_SUCCESS;\r
1758 }\r
1759 \r
1760 EFI_VFR_RETURN_CODE\r
1761 CVfrDataStorage::GetNameVarStoreInfo (\r
1762   OUT EFI_VARSTORE_INFO  *Info,\r
1763   IN  UINT32             Index\r
1764   )\r
1765 {\r
1766   if (Info == NULL) {\r
1767     return VFR_RETURN_FATAL_ERROR;\r
1768   }\r
1769 \r
1770   if (mCurrVarStorageNode == NULL) {\r
1771     return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
1772   }\r
1773   \r
1774   //\r
1775   // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
1776   //\r
1777   if (VfrCompatibleMode) {\r
1778     if (Index == 0) {\r
1779       return VFR_RETURN_ERROR_ARRARY_NUM;\r
1780     }\r
1781     Index --;\r
1782   }\r
1783 \r
1784   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];\r
1785 \r
1786   return VFR_RETURN_SUCCESS;\r
1787 }\r
1788 \r
1789 EFI_VFR_RETURN_CODE\r
1790 CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
1791   IN CHAR8             *StoreName,\r
1792   IN EFI_VARSTORE_INFO &Info\r
1793   )\r
1794 {\r
1795   CHAR8                 NewReqElt[128] = {'\0',};\r
1796   CHAR8                 *OldReqElt = NULL;\r
1797   SVfrVarStorageNode    *pNode = NULL;\r
1798   EFI_IFR_TYPE_VALUE    Value;\r
1799 \r
1800   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1801     if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
1802       break;\r
1803     }\r
1804   }\r
1805 \r
1806   if (pNode == NULL) {\r
1807     return VFR_RETURN_UNDEFINED;\r
1808   }\r
1809 \r
1810   gCVfrBufferConfig.Open ();\r
1811   Value.u8 = 0;\r
1812   if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
1813     return VFR_RETURN_FATAL_ERROR;\r
1814   }\r
1815   gCVfrBufferConfig.Close ();\r
1816 \r
1817   return VFR_RETURN_SUCCESS;\r
1818 }\r
1819 \r
1820 SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
1821   IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
1822   IN CHAR8                *RefName, \r
1823   IN EFI_STRING_ID        DefaultStoreNameId, \r
1824   IN UINT16               DefaultId\r
1825   )\r
1826 {\r
1827   mObjBinAddr = ObjBinAddr;\r
1828 \r
1829   if (RefName != NULL) {\r
1830     mRefName          = new CHAR8[strlen (RefName) + 1];\r
1831     strcpy (mRefName, RefName);\r
1832   } else {\r
1833     mRefName          = NULL;\r
1834   }\r
1835 \r
1836   mNext               = NULL;\r
1837   mDefaultId          = DefaultId;\r
1838   mDefaultStoreNameId = DefaultStoreNameId;\r
1839 }\r
1840 \r
1841 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (\r
1842   VOID\r
1843   )\r
1844 {\r
1845   if (mRefName != NULL) {\r
1846     delete mRefName;\r
1847   }\r
1848 }\r
1849 \r
1850 CVfrDefaultStore::CVfrDefaultStore (\r
1851   VOID\r
1852   )\r
1853 {\r
1854   mDefaultStoreList = NULL;\r
1855 }\r
1856 \r
1857 CVfrDefaultStore::~CVfrDefaultStore (\r
1858   VOID\r
1859   )\r
1860 {\r
1861   SVfrDefaultStoreNode *pTmp = NULL;\r
1862 \r
1863   while (mDefaultStoreList != NULL) {\r
1864     pTmp = mDefaultStoreList;\r
1865     mDefaultStoreList = mDefaultStoreList->mNext;\r
1866     delete pTmp;\r
1867   }\r
1868 }\r
1869 \r
1870 EFI_VFR_RETURN_CODE\r
1871 CVfrDefaultStore::RegisterDefaultStore (\r
1872   IN CHAR8                *ObjBinAddr,\r
1873   IN CHAR8                *RefName,\r
1874   IN EFI_STRING_ID        DefaultStoreNameId,\r
1875   IN UINT16               DefaultId\r
1876   )\r
1877 {\r
1878   SVfrDefaultStoreNode *pNode = NULL;\r
1879 \r
1880   if (RefName == NULL) {\r
1881     return VFR_RETURN_FATAL_ERROR;\r
1882   }\r
1883 \r
1884   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1885     if (strcmp (pNode->mRefName, RefName) == 0) {\r
1886       return VFR_RETURN_REDEFINED;\r
1887     }\r
1888   }\r
1889 \r
1890   if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {\r
1891     return VFR_RETURN_OUT_FOR_RESOURCES;\r
1892   }\r
1893 \r
1894   pNode->mNext               = mDefaultStoreList;\r
1895   mDefaultStoreList          = pNode;\r
1896 \r
1897   return VFR_RETURN_SUCCESS;\r
1898 }\r
1899 \r
1900 /*\r
1901  * assign new reference name or new default store name id only if \r
1902  * the original is invalid\r
1903  */\r
1904 EFI_VFR_RETURN_CODE\r
1905 CVfrDefaultStore::ReRegisterDefaultStoreById (\r
1906   IN UINT16          DefaultId,\r
1907   IN CHAR8           *RefName,\r
1908   IN EFI_STRING_ID   DefaultStoreNameId\r
1909   )\r
1910 {\r
1911   SVfrDefaultStoreNode *pNode = NULL;\r
1912 \r
1913   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1914     if (pNode->mDefaultId == DefaultId) {\r
1915       break;\r
1916     }\r
1917   }\r
1918 \r
1919   if (pNode == NULL) {\r
1920     return VFR_RETURN_UNDEFINED;\r
1921   } else {\r
1922     if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {\r
1923       pNode->mDefaultStoreNameId  = DefaultStoreNameId;\r
1924       if (pNode->mObjBinAddr != NULL) {\r
1925         pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;\r
1926       }\r
1927     } else {\r
1928       return VFR_RETURN_REDEFINED;\r
1929     }\r
1930 \r
1931     if (RefName != NULL) {\r
1932       delete pNode->mRefName;\r
1933       pNode->mRefName = new CHAR8[strlen (RefName) + 1];\r
1934       if (pNode->mRefName != NULL) {\r
1935         strcpy (pNode->mRefName, RefName);\r
1936       }\r
1937     }\r
1938   }\r
1939 \r
1940   return VFR_RETURN_SUCCESS;\r
1941 }\r
1942 \r
1943 BOOLEAN\r
1944 CVfrDefaultStore::DefaultIdRegistered (\r
1945   IN UINT16          DefaultId\r
1946   )\r
1947 {\r
1948   SVfrDefaultStoreNode *pNode = NULL;\r
1949 \r
1950   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
1951     if (pNode->mDefaultId == DefaultId) {\r
1952       return TRUE;\r
1953     }\r
1954   }\r
1955 \r
1956   return FALSE;\r
1957 }\r
1958 \r
1959 EFI_VFR_RETURN_CODE\r
1960 CVfrDefaultStore::GetDefaultId (\r
1961   IN  CHAR8           *RefName,\r
1962   OUT UINT16          *DefaultId\r
1963   )\r
1964 {\r
1965   SVfrDefaultStoreNode *pTmp = NULL;\r
1966 \r
1967   if (DefaultId == NULL) {\r
1968     return VFR_RETURN_FATAL_ERROR;\r
1969   }\r
1970 \r
1971   for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {\r
1972     if (strcmp (pTmp->mRefName, RefName) == 0) {\r
1973       *DefaultId = pTmp->mDefaultId;\r
1974       return VFR_RETURN_SUCCESS;\r
1975     }\r
1976   }\r
1977 \r
1978   return VFR_RETURN_UNDEFINED;\r
1979 }\r
1980 \r
1981 STATIC\r
1982 EFI_VFR_RETURN_CODE\r
1983 AltCfgItemPrintToBuffer (\r
1984   IN CHAR8              *NewAltCfg, \r
1985   IN EFI_VARSTORE_INFO  Info, \r
1986   IN UINT8              Type,\r
1987   IN EFI_IFR_TYPE_VALUE Value\r
1988   )\r
1989 {\r
1990   UINT32 Index;\r
1991   UINT8  *BufChar = NULL;\r
1992   UINT32 Count    = 0;\r
1993 \r
1994   if (NewAltCfg != NULL) {\r
1995     Count = sprintf (\r
1996               NewAltCfg, \r
1997               "&OFFSET=%x&WIDTH=%x&VALUE=", \r
1998               Info.mInfo.mVarOffset, \r
1999               Info.mVarTotalSize\r
2000               );\r
2001     NewAltCfg += Count;\r
2002 \r
2003     switch (Type) {\r
2004     case EFI_IFR_TYPE_NUM_SIZE_8 :\r
2005       Count = sprintf (NewAltCfg, "%x", Value.u8);\r
2006       NewAltCfg += Count;\r
2007       break;\r
2008     case EFI_IFR_TYPE_NUM_SIZE_16 :\r
2009       Count = sprintf (NewAltCfg, "%x", Value.u16);\r
2010       NewAltCfg += Count;\r
2011       break;\r
2012     case EFI_IFR_TYPE_NUM_SIZE_32 :\r
2013       Count = sprintf (NewAltCfg, "%x", Value.u32);\r
2014       NewAltCfg += Count;\r
2015       break;\r
2016     case EFI_IFR_TYPE_NUM_SIZE_64 :\r
2017       Count = sprintf (NewAltCfg, "%x", Value.u64);\r
2018       NewAltCfg += Count;\r
2019       break;\r
2020     case EFI_IFR_TYPE_BOOLEAN :\r
2021       Count = sprintf (NewAltCfg, "%x", Value.b);\r
2022       NewAltCfg += Count;\r
2023       break;\r
2024     case EFI_IFR_TYPE_TIME :\r
2025 #if 1\r
2026       Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));\r
2027       NewAltCfg += Count;\r
2028 #else\r
2029       BufChar = (UINT8 *)&Value.time;\r
2030       for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {\r
2031         Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
2032         NewAltCfg += Count;\r
2033       }\r
2034 #endif\r
2035       break;\r
2036     case EFI_IFR_TYPE_DATE :\r
2037 #if 1\r
2038       Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));\r
2039       NewAltCfg += Count;\r
2040 #else\r
2041       BufChar = (UINT8 *)&Value.date;\r
2042       for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {\r
2043         Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
2044         NewAltCfg += Count;\r
2045       }\r
2046 #endif\r
2047       break;\r
2048     case EFI_IFR_TYPE_STRING :\r
2049       Count = sprintf (NewAltCfg, "%x", Value.string);\r
2050       NewAltCfg += Count;\r
2051       break;\r
2052     case EFI_IFR_TYPE_OTHER :\r
2053       return VFR_RETURN_UNSUPPORTED;\r
2054         }\r
2055   }\r
2056 \r
2057   return VFR_RETURN_FATAL_ERROR;    \r
2058 }\r
2059 \r
2060 EFI_VFR_RETURN_CODE\r
2061 CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
2062   IN EFI_VARSTORE_ID    DefaultId,\r
2063   IN EFI_VARSTORE_INFO  &Info,\r
2064   IN CHAR8              *VarStoreName,\r
2065   IN UINT8              Type,\r
2066   IN EFI_IFR_TYPE_VALUE Value\r
2067   )\r
2068 {\r
2069   SVfrDefaultStoreNode  *pNode = NULL;\r
2070   CHAR8                 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};\r
2071   INTN                  Returnvalue = 0;\r
2072 \r
2073   if (VarStoreName == NULL) {\r
2074     return VFR_RETURN_FATAL_ERROR;\r
2075   }\r
2076 \r
2077   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {\r
2078     if (pNode->mDefaultId == DefaultId) {\r
2079       break;\r
2080     }\r
2081   }\r
2082 \r
2083   if (pNode == NULL) {\r
2084     return VFR_RETURN_UNDEFINED;\r
2085   }\r
2086 \r
2087   gCVfrBufferConfig.Open ();\r
2088 \r
2089   sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
2090   if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {\r
2091     if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
2092       goto WriteError;\r
2093     }\r
2094   }\r
2095   \r
2096   gCVfrBufferConfig.Close ();\r
2097 \r
2098   return VFR_RETURN_SUCCESS;\r
2099 \r
2100 WriteError:\r
2101   gCVfrBufferConfig.Close ();\r
2102   return (EFI_VFR_RETURN_CODE)Returnvalue;\r
2103 }\r
2104 \r
2105 SVfrRuleNode::SVfrRuleNode (\r
2106   IN CHAR8       *RuleName, \r
2107   IN UINT8       RuleId\r
2108   )\r
2109 {\r
2110   if (RuleName != NULL) {\r
2111     mRuleName = new CHAR8[strlen (RuleName) + 1];\r
2112     strcpy (mRuleName, RuleName);\r
2113   } else {\r
2114     mRuleName = NULL;\r
2115   }\r
2116 \r
2117   mNext       = NULL;\r
2118   mRuleId     = RuleId;\r
2119 }\r
2120 \r
2121 SVfrRuleNode::~SVfrRuleNode (\r
2122   VOID\r
2123   )\r
2124 {\r
2125   if (mRuleName != NULL) {\r
2126     delete mRuleName;\r
2127   }\r
2128 }\r
2129 \r
2130 CVfrRulesDB::CVfrRulesDB ()\r
2131 {\r
2132   mRuleList   = NULL;\r
2133   mFreeRuleId = EFI_VARSTORE_ID_START;\r
2134 }\r
2135 \r
2136 CVfrRulesDB::~CVfrRulesDB ()\r
2137 {\r
2138   SVfrRuleNode *pNode;\r
2139 \r
2140   while(mRuleList != NULL) {\r
2141     pNode = mRuleList;\r
2142     mRuleList = mRuleList->mNext;\r
2143     delete pNode;\r
2144   }\r
2145 }\r
2146 \r
2147 VOID\r
2148 CVfrRulesDB::RegisterRule (\r
2149   IN CHAR8  *RuleName\r
2150   )\r
2151 {\r
2152   SVfrRuleNode *pNew;\r
2153 \r
2154   if (RuleName == NULL) {\r
2155     return ;\r
2156   }\r
2157 \r
2158   if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {\r
2159     return ;\r
2160   }\r
2161 \r
2162   mFreeRuleId++;\r
2163 \r
2164   pNew->mNext = mRuleList;\r
2165   mRuleList   = pNew;\r
2166 }\r
2167 \r
2168 UINT8\r
2169 CVfrRulesDB::GetRuleId (\r
2170   IN CHAR8  *RuleName\r
2171   )\r
2172 {\r
2173   SVfrRuleNode *pNode;\r
2174 \r
2175   if (RuleName == NULL) {\r
2176     return EFI_RULE_ID_INVALID;\r
2177   }\r
2178 \r
2179   for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {\r
2180     if (strcmp (pNode->mRuleName, RuleName) == 0) {\r
2181       return pNode->mRuleId;\r
2182     }\r
2183   }\r
2184 \r
2185   return EFI_RULE_ID_INVALID;\r
2186 }\r
2187 \r
2188 CVfrRulesDB gCVfrRulesDB;\r
2189 \r
2190 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2191   VOID\r
2192   )\r
2193 {\r
2194   mVarStoreId      = EFI_VARSTORE_ID_INVALID;\r
2195   mInfo.mVarName   = EFI_STRING_ID_INVALID;\r
2196   mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
2197   mVarType         = EFI_IFR_TYPE_OTHER;\r
2198   mVarTotalSize    = 0;\r
2199 }\r
2200 \r
2201 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
2202   IN EFI_VARSTORE_INFO &Info\r
2203   )\r
2204 {\r
2205   mVarStoreId      = Info.mVarStoreId;\r
2206   mInfo.mVarName   = Info.mInfo.mVarName;\r
2207   mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
2208   mVarType         = Info.mVarType;\r
2209   mVarTotalSize    = Info.mVarTotalSize;\r
2210 }\r
2211 \r
2212 BOOLEAN \r
2213 EFI_VARSTORE_INFO::operator == (\r
2214   IN EFI_VARSTORE_INFO  *Info\r
2215   )\r
2216 {\r
2217   if ((mVarStoreId == Info->mVarStoreId) &&\r
2218           (mInfo.mVarName == Info->mInfo.mVarName) &&\r
2219       (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
2220       (mVarType == Info->mVarType) &&\r
2221       (mVarTotalSize == Info->mVarTotalSize)) {\r
2222     return TRUE;\r
2223   }\r
2224 \r
2225   return FALSE;\r
2226 }\r
2227 \r
2228 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
2229 \r
2230 EFI_QUESTION_ID\r
2231 CVfrQuestionDB::GetFreeQuestionId (\r
2232   VOID\r
2233   )\r
2234 {\r
2235   UINT32  Index, Mask, Offset;\r
2236 \r
2237   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2238     if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {\r
2239       break;\r
2240     }\r
2241   }\r
2242 \r
2243   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
2244     if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
2245       mFreeQIdBitMap[Index] |= Mask;\r
2246       return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);\r
2247     }\r
2248   }\r
2249 \r
2250   return EFI_QUESTION_ID_INVALID;\r
2251 }\r
2252 \r
2253 BOOLEAN\r
2254 CVfrQuestionDB::ChekQuestionIdFree (\r
2255   IN EFI_QUESTION_ID QId\r
2256   )\r
2257 {\r
2258   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
2259   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2260 \r
2261   return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;\r
2262 }\r
2263 \r
2264 VOID \r
2265 CVfrQuestionDB::MarkQuestionIdUsed (\r
2266   IN EFI_QUESTION_ID QId\r
2267   )\r
2268 {\r
2269   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
2270   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2271 \r
2272   mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);\r
2273 }\r
2274 \r
2275 VOID \r
2276 CVfrQuestionDB::MarkQuestionIdUnused (\r
2277   IN EFI_QUESTION_ID QId\r
2278   )\r
2279 {\r
2280   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);\r
2281   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);\r
2282 \r
2283   mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);\r
2284 }\r
2285 \r
2286 SVfrQuestionNode::SVfrQuestionNode (\r
2287   IN CHAR8  *Name,\r
2288   IN CHAR8  *VarIdStr,\r
2289   IN UINT32 BitMask\r
2290   )\r
2291 {\r
2292   mName       = NULL;\r
2293   mVarIdStr   = NULL;\r
2294   mQuestionId = EFI_QUESTION_ID_INVALID;\r
2295   mBitMask    = BitMask;\r
2296   mNext       = NULL;\r
2297 \r
2298   if (Name == NULL) {\r
2299     mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
2300     strcpy (mName, "$DEFAULT");\r
2301   } else {\r
2302     mName = new CHAR8[strlen (Name) + 1];\r
2303     strcpy (mName, Name);\r
2304   }\r
2305 \r
2306   if (VarIdStr != NULL) {\r
2307     mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];\r
2308     strcpy (mVarIdStr, VarIdStr);\r
2309   } else {\r
2310     mVarIdStr = new CHAR8[strlen ("$") + 1];\r
2311     strcpy (mVarIdStr, "$");\r
2312   }\r
2313 }\r
2314 \r
2315 SVfrQuestionNode::~SVfrQuestionNode (\r
2316   VOID\r
2317   )\r
2318 {\r
2319   if (mName != NULL) {\r
2320     delete mName;\r
2321   }\r
2322 \r
2323   if (mVarIdStr != NULL) {\r
2324     delete mVarIdStr;\r
2325   }\r
2326 }\r
2327 \r
2328 CVfrQuestionDB::CVfrQuestionDB ()\r
2329 {\r
2330   UINT32 Index;\r
2331 \r
2332   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2333     mFreeQIdBitMap[Index] = 0;\r
2334   }\r
2335 \r
2336   // Question ID 0 is reserved.\r
2337   mFreeQIdBitMap[0] = 0x80000000;\r
2338   mQuestionList     = NULL;\r
2339\r
2340 \r
2341 CVfrQuestionDB::~CVfrQuestionDB ()\r
2342 {\r
2343   SVfrQuestionNode     *pNode;\r
2344 \r
2345   while (mQuestionList != NULL) {\r
2346     pNode = mQuestionList;\r
2347     mQuestionList = mQuestionList->mNext;\r
2348     delete pNode;\r
2349   }\r
2350 }\r
2351 \r
2352 //\r
2353 // Reset to init state\r
2354 //\r
2355 VOID\r
2356 CVfrQuestionDB::ResetInit(\r
2357   IN VOID\r
2358   )\r
2359 {\r
2360   UINT32               Index;\r
2361   SVfrQuestionNode     *pNode;\r
2362 \r
2363   while (mQuestionList != NULL) {\r
2364     pNode = mQuestionList;\r
2365     mQuestionList = mQuestionList->mNext;\r
2366     delete pNode;\r
2367   }\r
2368 \r
2369   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {\r
2370     mFreeQIdBitMap[Index] = 0;\r
2371   }\r
2372 \r
2373   // Question ID 0 is reserved.\r
2374   mFreeQIdBitMap[0] = 0x80000000;\r
2375   mQuestionList     = NULL;   \r
2376 }\r
2377 \r
2378 VOID\r
2379 CVfrQuestionDB::PrintAllQuestion (\r
2380   VOID\r
2381   )\r
2382 {\r
2383   SVfrQuestionNode *pNode = NULL;\r
2384 \r
2385   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2386     printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
2387   }\r
2388 }\r
2389 \r
2390 EFI_VFR_RETURN_CODE\r
2391 CVfrQuestionDB::RegisterQuestion (\r
2392   IN     CHAR8             *Name,\r
2393   IN     CHAR8             *VarIdStr,\r
2394   IN OUT EFI_QUESTION_ID   &QuestionId\r
2395   )\r
2396 {\r
2397   SVfrQuestionNode *pNode = NULL;\r
2398 \r
2399   if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {\r
2400     return VFR_RETURN_REDEFINED;\r
2401   }\r
2402 \r
2403   if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {\r
2404     return VFR_RETURN_OUT_FOR_RESOURCES;\r
2405   }\r
2406 \r
2407   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2408     QuestionId = GetFreeQuestionId ();\r
2409   } else {\r
2410     //\r
2411     // For Framework Vfr, don't check question ID conflict.\r
2412     //\r
2413     if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {\r
2414       delete pNode;\r
2415       return VFR_RETURN_QUESTIONID_REDEFINED;\r
2416     }\r
2417     MarkQuestionIdUsed (QuestionId);\r
2418   }\r
2419   pNode->mQuestionId = QuestionId;\r
2420 \r
2421   pNode->mNext       = mQuestionList;\r
2422   mQuestionList      = pNode;\r
2423 \r
2424   gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2425 \r
2426   return VFR_RETURN_SUCCESS;\r
2427 }\r
2428 \r
2429 VOID\r
2430 CVfrQuestionDB::RegisterOldDateQuestion (\r
2431   IN     CHAR8           *YearVarId, \r
2432   IN     CHAR8           *MonthVarId, \r
2433   IN     CHAR8           *DayVarId, \r
2434   IN OUT EFI_QUESTION_ID &QuestionId\r
2435   )\r
2436 {\r
2437   SVfrQuestionNode *pNode[3] = {NULL, };\r
2438   UINT32           Index;\r
2439 \r
2440   if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {\r
2441     return;\r
2442   }\r
2443 \r
2444   if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {\r
2445     goto Err;\r
2446   }\r
2447   if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {\r
2448     goto Err;\r
2449   }\r
2450   if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {\r
2451     goto Err;\r
2452   }\r
2453 \r
2454   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2455     QuestionId = GetFreeQuestionId ();\r
2456   } else {\r
2457     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2458       goto Err;\r
2459     }\r
2460     MarkQuestionIdUsed (QuestionId);\r
2461   }\r
2462 \r
2463   pNode[0]->mQuestionId = QuestionId;\r
2464   pNode[1]->mQuestionId = QuestionId;\r
2465   pNode[2]->mQuestionId = QuestionId;\r
2466   pNode[0]->mNext       = pNode[1];\r
2467   pNode[1]->mNext       = pNode[2];\r
2468   pNode[2]->mNext       = mQuestionList;\r
2469   mQuestionList         = pNode[0];\r
2470 \r
2471   gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2472   gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2473   gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2474 \r
2475   return;\r
2476 \r
2477 Err:\r
2478   for (Index = 0; Index < 3; Index++) {\r
2479     if (pNode[Index] != NULL) {\r
2480       delete pNode[Index];\r
2481     }\r
2482   }\r
2483   QuestionId = EFI_QUESTION_ID_INVALID;\r
2484 }\r
2485 \r
2486 VOID\r
2487 CVfrQuestionDB::RegisterNewDateQuestion (\r
2488   IN     CHAR8           *Name,\r
2489   IN     CHAR8           *BaseVarId, \r
2490   IN OUT EFI_QUESTION_ID &QuestionId\r
2491   )\r
2492 {\r
2493   SVfrQuestionNode     *pNode[3] = {NULL, };\r
2494   UINT32               Len;\r
2495   CHAR8                *VarIdStr[3] = {NULL, };\r
2496   INT8                 Index;\r
2497 \r
2498   if (BaseVarId == NULL) {\r
2499     return;\r
2500   }\r
2501 \r
2502   Len = strlen (BaseVarId);\r
2503 \r
2504   VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
2505   if (VarIdStr[0] != NULL) {\r
2506     strcpy (VarIdStr[0], BaseVarId);\r
2507     strcat (VarIdStr[0], ".Year");\r
2508   }\r
2509   VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
2510   if (VarIdStr[1] != NULL) {\r
2511     strcpy (VarIdStr[1], BaseVarId);\r
2512     strcat (VarIdStr[1], ".Month");\r
2513   }\r
2514   VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
2515   if (VarIdStr[2] != NULL) {\r
2516     strcpy (VarIdStr[2], BaseVarId);\r
2517     strcat (VarIdStr[2], ".Day");\r
2518   }\r
2519 \r
2520   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
2521     goto Err;\r
2522   }\r
2523   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {\r
2524     goto Err;\r
2525   }\r
2526   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {\r
2527     goto Err;\r
2528   }\r
2529 \r
2530   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2531     QuestionId = GetFreeQuestionId ();\r
2532   } else {\r
2533     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2534       goto Err;\r
2535     }\r
2536     MarkQuestionIdUsed (QuestionId);\r
2537   }\r
2538 \r
2539   pNode[0]->mQuestionId = QuestionId;\r
2540   pNode[1]->mQuestionId = QuestionId;\r
2541   pNode[2]->mQuestionId = QuestionId;\r
2542   pNode[0]->mNext       = pNode[1];\r
2543   pNode[1]->mNext       = pNode[2];\r
2544   pNode[2]->mNext       = mQuestionList;\r
2545   mQuestionList         = pNode[0];\r
2546 \r
2547   for (Index = 0; Index < 3; Index++) {\r
2548     if (VarIdStr[Index] != NULL) {\r
2549       delete VarIdStr[Index];\r
2550     }\r
2551   }\r
2552 \r
2553   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2554   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2555   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2556 \r
2557   return;\r
2558 \r
2559 Err:\r
2560   for (Index = 0; Index < 3; Index++) {\r
2561     if (pNode[Index] != NULL) {\r
2562       delete pNode[Index];\r
2563     }\r
2564 \r
2565     if (VarIdStr[Index] != NULL) {\r
2566       delete VarIdStr[Index];\r
2567     }\r
2568   }\r
2569 }\r
2570 \r
2571 VOID\r
2572 CVfrQuestionDB::RegisterOldTimeQuestion (\r
2573   IN     CHAR8           *HourVarId, \r
2574   IN     CHAR8           *MinuteVarId, \r
2575   IN     CHAR8           *SecondVarId, \r
2576   IN OUT EFI_QUESTION_ID &QuestionId\r
2577   )\r
2578 {\r
2579   SVfrQuestionNode *pNode[3] = {NULL, };\r
2580   UINT32           Index;\r
2581 \r
2582   if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {\r
2583     return;\r
2584   }\r
2585 \r
2586   if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {\r
2587     goto Err;\r
2588   }\r
2589   if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {\r
2590     goto Err;\r
2591   }\r
2592   if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {\r
2593     goto Err;\r
2594   }\r
2595 \r
2596   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2597     QuestionId = GetFreeQuestionId ();\r
2598   } else {\r
2599     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2600       goto Err;\r
2601     }\r
2602     MarkQuestionIdUsed (QuestionId);\r
2603   }\r
2604 \r
2605   pNode[0]->mQuestionId = QuestionId;\r
2606   pNode[1]->mQuestionId = QuestionId;\r
2607   pNode[2]->mQuestionId = QuestionId;\r
2608   pNode[0]->mNext       = pNode[1];\r
2609   pNode[1]->mNext       = pNode[2];\r
2610   pNode[2]->mNext       = mQuestionList;\r
2611   mQuestionList         = pNode[0];\r
2612 \r
2613   gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2614   gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2615   gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2616 \r
2617   return;\r
2618 \r
2619 Err:\r
2620   for (Index = 0; Index < 3; Index++) {\r
2621     if (pNode[Index] != NULL) {\r
2622       delete pNode[Index];\r
2623     }\r
2624   }\r
2625   QuestionId = EFI_QUESTION_ID_INVALID;\r
2626 }\r
2627 \r
2628 VOID\r
2629 CVfrQuestionDB::RegisterNewTimeQuestion (\r
2630   IN     CHAR8           *Name,\r
2631   IN     CHAR8           *BaseVarId,\r
2632   IN OUT EFI_QUESTION_ID &QuestionId\r
2633   )\r
2634 {\r
2635   SVfrQuestionNode     *pNode[3] = {NULL, };\r
2636   UINT32               Len;\r
2637   CHAR8                *VarIdStr[3] = {NULL, };\r
2638   INT8                 Index;\r
2639 \r
2640   if (BaseVarId == NULL) {\r
2641     return;\r
2642   }\r
2643 \r
2644   Len = strlen (BaseVarId);\r
2645 \r
2646   VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
2647   if (VarIdStr[0] != NULL) {\r
2648     strcpy (VarIdStr[0], BaseVarId);\r
2649     strcat (VarIdStr[0], ".Hour");\r
2650   }\r
2651   VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
2652   if (VarIdStr[1] != NULL) {\r
2653     strcpy (VarIdStr[1], BaseVarId);\r
2654     strcat (VarIdStr[1], ".Minute");\r
2655   }\r
2656   VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
2657   if (VarIdStr[2] != NULL) {\r
2658     strcpy (VarIdStr[2], BaseVarId);\r
2659     strcat (VarIdStr[2], ".Second");\r
2660   }\r
2661 \r
2662   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
2663     goto Err;\r
2664   }\r
2665   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {\r
2666     goto Err;\r
2667   }\r
2668   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {\r
2669     goto Err;\r
2670   }\r
2671 \r
2672   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2673     QuestionId = GetFreeQuestionId ();\r
2674   } else {\r
2675     if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
2676       goto Err;\r
2677     }\r
2678     MarkQuestionIdUsed (QuestionId);\r
2679   }\r
2680 \r
2681   pNode[0]->mQuestionId = QuestionId;\r
2682   pNode[1]->mQuestionId = QuestionId;\r
2683   pNode[2]->mQuestionId = QuestionId;\r
2684   pNode[0]->mNext       = pNode[1];\r
2685   pNode[1]->mNext       = pNode[2];\r
2686   pNode[2]->mNext       = mQuestionList;\r
2687   mQuestionList         = pNode[0];\r
2688 \r
2689   for (Index = 0; Index < 3; Index++) {\r
2690     if (VarIdStr[Index] != NULL) {\r
2691       delete VarIdStr[Index];\r
2692     }\r
2693   }\r
2694 \r
2695   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2696   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2697   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
2698 \r
2699   return;\r
2700 \r
2701 Err:\r
2702   for (Index = 0; Index < 3; Index++) {\r
2703     if (pNode[Index] != NULL) {\r
2704       delete pNode[Index];\r
2705     }\r
2706 \r
2707     if (VarIdStr[Index] != NULL) {\r
2708       delete VarIdStr[Index];\r
2709     }\r
2710   }\r
2711 }\r
2712 \r
2713 EFI_VFR_RETURN_CODE\r
2714 CVfrQuestionDB::UpdateQuestionId (\r
2715   IN EFI_QUESTION_ID   QId,\r
2716   IN EFI_QUESTION_ID   NewQId\r
2717   )\r
2718 {\r
2719   SVfrQuestionNode *pNode = NULL;\r
2720   \r
2721   if (QId == NewQId) {\r
2722     // don't update\r
2723     return VFR_RETURN_SUCCESS;\r
2724   }\r
2725   \r
2726   //\r
2727   // For Framework Vfr, don't check question ID conflict.\r
2728   //  \r
2729   if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
2730     return VFR_RETURN_REDEFINED;\r
2731   }\r
2732 \r
2733   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2734     if (pNode->mQuestionId == QId) {\r
2735       break;\r
2736     }\r
2737   }\r
2738 \r
2739   if (pNode == NULL) {\r
2740     return VFR_RETURN_UNDEFINED;\r
2741   }\r
2742 \r
2743   MarkQuestionIdUnused (QId);\r
2744   pNode->mQuestionId = NewQId;\r
2745   MarkQuestionIdUsed (NewQId);\r
2746 \r
2747   gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));\r
2748 \r
2749   return VFR_RETURN_SUCCESS;\r
2750 }\r
2751 \r
2752 VOID \r
2753 CVfrQuestionDB::GetQuestionId (\r
2754   IN  CHAR8             *Name,\r
2755   IN  CHAR8             *VarIdStr,\r
2756   OUT EFI_QUESTION_ID   &QuestionId,\r
2757   OUT UINT32            &BitMask\r
2758   )\r
2759 {\r
2760   SVfrQuestionNode *pNode;\r
2761 \r
2762   QuestionId = EFI_QUESTION_ID_INVALID;\r
2763   BitMask    = 0x00000000;\r
2764 \r
2765   if ((Name == NULL) && (VarIdStr == NULL)) {\r
2766     return ;\r
2767   }\r
2768 \r
2769   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2770     if (Name != NULL) {\r
2771       if (strcmp (pNode->mName, Name) != 0) {\r
2772         continue;\r
2773       }\r
2774     }\r
2775 \r
2776     if (VarIdStr != NULL) {\r
2777       if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
2778         continue;\r
2779       }\r
2780         }\r
2781 \r
2782     QuestionId = pNode->mQuestionId;\r
2783     BitMask    = pNode->mBitMask;\r
2784     break;\r
2785   }\r
2786 \r
2787   return ;\r
2788 }\r
2789 \r
2790 EFI_VFR_RETURN_CODE \r
2791 CVfrQuestionDB::FindQuestion (\r
2792   IN EFI_QUESTION_ID QuestionId\r
2793   )\r
2794 {\r
2795   SVfrQuestionNode *pNode;\r
2796 \r
2797   if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
2798     return VFR_RETURN_INVALID_PARAMETER;\r
2799   }\r
2800 \r
2801   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2802     if (pNode->mQuestionId == QuestionId) {\r
2803       return VFR_RETURN_SUCCESS;\r
2804     }\r
2805   }\r
2806 \r
2807   return VFR_RETURN_UNDEFINED;\r
2808 }\r
2809 \r
2810 EFI_VFR_RETURN_CODE \r
2811 CVfrQuestionDB::FindQuestion (\r
2812   IN CHAR8 *Name\r
2813   )\r
2814 {\r
2815   SVfrQuestionNode *pNode;\r
2816 \r
2817   if (Name == NULL) {\r
2818     return VFR_RETURN_FATAL_ERROR;\r
2819   }\r
2820 \r
2821   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
2822     if (strcmp (pNode->mName, Name) == 0) {\r
2823       return VFR_RETURN_SUCCESS;\r
2824     }\r
2825   }\r
2826 \r
2827   return VFR_RETURN_UNDEFINED;\r
2828 }\r
2829 \r
2830 BOOLEAN  VfrCompatibleMode = FALSE;\r