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