Home | History | Annotate | Download | only in VfrCompile
      1 /** @file
      2 
      3   Vfr common library functions.
      4 
      5 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "stdio.h"
     17 #include "stdlib.h"
     18 #include "CommonLib.h"
     19 #include "VfrUtilityLib.h"
     20 #include "VfrFormPkg.h"
     21 
     22 VOID
     23 CVfrBinaryOutput::WriteLine (
     24   IN FILE         *pFile,
     25   IN UINT32       LineBytes,
     26   IN CONST CHAR8  *LineHeader,
     27   IN CHAR8        *BlkBuf,
     28   IN UINT32       BlkSize
     29   )
     30 {
     31   UINT32    Index;
     32 
     33   if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
     34     return;
     35   }
     36 
     37   for (Index = 0; Index < BlkSize; Index++) {
     38     if ((Index % LineBytes) == 0) {
     39       fprintf (pFile, "\n%s", LineHeader);
     40     }
     41     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
     42   }
     43 }
     44 
     45 VOID
     46 CVfrBinaryOutput::WriteEnd (
     47   IN FILE         *pFile,
     48   IN UINT32       LineBytes,
     49   IN CONST CHAR8  *LineHeader,
     50   IN CHAR8        *BlkBuf,
     51   IN UINT32       BlkSize
     52   )
     53 {
     54   UINT32    Index;
     55 
     56   if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
     57     return;
     58   }
     59 
     60   for (Index = 0; Index < BlkSize - 1; Index++) {
     61     if ((Index % LineBytes) == 0) {
     62       fprintf (pFile, "\n%s", LineHeader);
     63     }
     64     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
     65   }
     66 
     67   if ((Index % LineBytes) == 0) {
     68     fprintf (pFile, "\n%s", LineHeader);
     69   }
     70   fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
     71 }
     72 
     73 SConfigInfo::SConfigInfo (
     74   IN UINT8              Type,
     75   IN UINT16             Offset,
     76   IN UINT32             Width,
     77   IN EFI_IFR_TYPE_VALUE Value
     78   )
     79 {
     80   mNext   = NULL;
     81   mOffset = Offset;
     82   mWidth  = (UINT16)Width;
     83   mValue  = new UINT8[mWidth];
     84   if (mValue == NULL) {
     85     return;
     86   }
     87 
     88   switch (Type) {
     89   case EFI_IFR_TYPE_NUM_SIZE_8 :
     90     memcpy (mValue, &Value.u8, mWidth);
     91     break;
     92   case EFI_IFR_TYPE_NUM_SIZE_16 :
     93     memcpy (mValue, &Value.u16, mWidth);
     94     break;
     95   case EFI_IFR_TYPE_NUM_SIZE_32 :
     96     memcpy (mValue, &Value.u32, mWidth);
     97     break;
     98   case EFI_IFR_TYPE_NUM_SIZE_64 :
     99     memcpy (mValue, &Value.u64, mWidth);
    100     break;
    101   case EFI_IFR_TYPE_BOOLEAN :
    102     memcpy (mValue, &Value.b, mWidth);
    103     break;
    104   case EFI_IFR_TYPE_TIME :
    105     memcpy (mValue, &Value.time, mWidth);
    106     break;
    107   case EFI_IFR_TYPE_DATE :
    108     memcpy (mValue, &Value.date, mWidth);
    109     break;
    110   case EFI_IFR_TYPE_STRING :
    111     memcpy (mValue, &Value.string, mWidth);
    112     break;
    113   case EFI_IFR_TYPE_BUFFER :
    114     memcpy (mValue, &Value.u8, mWidth);
    115     break;
    116 
    117   case EFI_IFR_TYPE_OTHER :
    118     return;
    119   }
    120 }
    121 
    122 SConfigInfo::~SConfigInfo (
    123   VOID
    124   )
    125 {
    126   BUFFER_SAFE_FREE (mValue);
    127 }
    128 
    129 SConfigItem::SConfigItem (
    130   IN CHAR8               *Name,
    131   IN EFI_GUID            *Guid,
    132   IN CHAR8               *Id
    133   )
    134 {
    135   mName          = NULL;
    136   mGuid          = NULL;
    137   mId            = NULL;
    138   mInfoStrList = NULL;
    139   mNext        = NULL;
    140 
    141   if (Name != NULL) {
    142     if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
    143       strcpy (mName, Name);
    144     }
    145   }
    146 
    147   if (Guid != NULL) {
    148     if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
    149       memcpy (mGuid, Guid, sizeof (EFI_GUID));
    150     }
    151   }
    152 
    153   if (Id != NULL) {
    154     if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
    155       strcpy (mId, Id);
    156     }
    157   }
    158 }
    159 
    160 SConfigItem::SConfigItem (
    161   IN CHAR8               *Name,
    162   IN EFI_GUID            *Guid,
    163   IN CHAR8               *Id,
    164   IN UINT8               Type,
    165   IN UINT16              Offset,
    166   IN UINT16              Width,
    167   IN EFI_IFR_TYPE_VALUE  Value
    168   )
    169 {
    170   mName        = NULL;
    171   mGuid        = NULL;
    172   mId          = NULL;
    173   mInfoStrList = NULL;
    174   mNext        = NULL;
    175 
    176   if (Name != NULL) {
    177     if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
    178       strcpy (mName, Name);
    179     }
    180   }
    181 
    182   if (Guid != NULL) {
    183     if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
    184       memcpy (mGuid, Guid, sizeof (EFI_GUID));
    185     }
    186   }
    187 
    188   if (Id != NULL) {
    189     if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
    190       strcpy (mId, Id);
    191     }
    192   }
    193 
    194   mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
    195 }
    196 
    197 SConfigItem::~SConfigItem (
    198   VOID
    199   )
    200 {
    201   SConfigInfo  *Info;
    202 
    203   BUFFER_SAFE_FREE (mName);
    204   BUFFER_SAFE_FREE (mGuid);
    205   BUFFER_SAFE_FREE (mId);
    206   while (mInfoStrList != NULL) {
    207     Info = mInfoStrList;
    208     mInfoStrList = mInfoStrList->mNext;
    209 
    210     BUFFER_SAFE_FREE (Info);
    211   }
    212 }
    213 
    214 UINT8
    215 CVfrBufferConfig::Register (
    216   IN CHAR8               *Name,
    217   IN EFI_GUID            *Guid,
    218   IN CHAR8               *Id
    219   )
    220 {
    221   SConfigItem *pNew;
    222 
    223   if (Select (Name, Guid) == 0) {
    224     return 1;
    225   }
    226 
    227   if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {
    228     return 2;
    229   }
    230 
    231   if (mItemListHead == NULL) {
    232     mItemListHead = pNew;
    233     mItemListTail = pNew;
    234   } else {
    235     mItemListTail->mNext = pNew;
    236     mItemListTail = pNew;
    237   }
    238   mItemListPos    = pNew;
    239 
    240   return 0;
    241 }
    242 
    243 VOID
    244 CVfrBufferConfig::Open (
    245   VOID
    246   )
    247 {
    248   mItemListPos = mItemListHead;
    249 }
    250 
    251 BOOLEAN
    252 CVfrBufferConfig::Eof(
    253   VOID
    254   )
    255 {
    256   return (mItemListPos == NULL) ? TRUE : FALSE;
    257 }
    258 
    259 UINT8
    260 CVfrBufferConfig::Select (
    261   IN CHAR8    *Name,
    262   IN EFI_GUID *Guid,
    263   IN CHAR8    *Id
    264   )
    265 {
    266   SConfigItem *p;
    267 
    268   if (Name == NULL || Guid == NULL) {
    269     mItemListPos = mItemListHead;
    270     return 0;
    271   } else {
    272     for (p = mItemListHead; p != NULL; p = p->mNext) {
    273       if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {
    274         continue;
    275       }
    276 
    277       if (Id != NULL) {
    278         if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
    279           continue;
    280         }
    281       } else if (p->mId != NULL) {
    282         continue;
    283       }
    284 
    285       mItemListPos = p;
    286       return 0;
    287     }
    288   }
    289 
    290   return 1;
    291 }
    292 
    293 UINT8
    294 CVfrBufferConfig::Write (
    295   IN CONST CHAR8         Mode,
    296   IN CHAR8               *Name,
    297   IN EFI_GUID            *Guid,
    298   IN CHAR8               *Id,
    299   IN UINT8               Type,
    300   IN UINT16              Offset,
    301   IN UINT32              Width,
    302   IN EFI_IFR_TYPE_VALUE  Value
    303   )
    304 {
    305   UINT8         Ret;
    306   SConfigItem   *pItem;
    307   SConfigInfo   *pInfo;
    308 
    309   if ((Ret = Select (Name, Guid)) != 0) {
    310     return Ret;
    311   }
    312 
    313   switch (Mode) {
    314   case 'a' : // add
    315     if (Select (Name, Guid, Id) != 0) {
    316       if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {
    317         return 2;
    318       }
    319       if (mItemListHead == NULL) {
    320         mItemListHead = pItem;
    321         mItemListTail = pItem;
    322       } else {
    323         mItemListTail->mNext = pItem;
    324         mItemListTail = pItem;
    325       }
    326       mItemListPos = pItem;
    327     } else {
    328       // tranverse the list to find out if there's already the value for the same offset
    329       for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {
    330         if (pInfo->mOffset == Offset) {
    331           return 0;
    332         }
    333       }
    334       if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
    335         return 2;
    336       }
    337       pInfo->mNext = mItemListPos->mInfoStrList;
    338       mItemListPos->mInfoStrList = pInfo;
    339     }
    340     break;
    341 
    342   case 'd' : // delete
    343     if (mItemListHead == mItemListPos) {
    344       mItemListHead = mItemListPos->mNext;
    345       delete mItemListPos;
    346       break;
    347     }
    348 
    349     for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
    350       ;
    351 
    352     pItem->mNext = mItemListPos->mNext;
    353     if (mItemListTail == mItemListPos) {
    354       mItemListTail = pItem;
    355     }
    356     delete mItemListPos;
    357     mItemListPos = pItem->mNext;
    358     break;
    359 
    360   case 'i' : // set info
    361     if (mItemListPos->mId != NULL) {
    362       delete mItemListPos->mId;
    363     }
    364     mItemListPos->mId = NULL;
    365     if (Id != NULL) {
    366       if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
    367         return 2;
    368       }
    369       strcpy (mItemListPos->mId, Id);
    370     }
    371     break;
    372 
    373   default :
    374     return 1;
    375   }
    376 
    377   return 0;
    378 }
    379 
    380 
    381 VOID
    382 CVfrBufferConfig::Close (
    383   VOID
    384   )
    385 {
    386   mItemListPos = NULL;
    387 }
    388 
    389 #define BYTES_PRE_LINE 0x10
    390 
    391 VOID
    392 CVfrBufferConfig::OutputCFile (
    393   IN FILE  *pFile,
    394   IN CHAR8 *BaseName
    395   )
    396 {
    397   CVfrBinaryOutput Output;
    398   SConfigItem      *Item;
    399   SConfigInfo      *Info;
    400   UINT32           TotalLen;
    401 
    402   if (pFile == NULL) {
    403     return;
    404   }
    405 
    406   for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
    407     if (Item->mId != NULL || Item->mInfoStrList == NULL) {
    408       continue;
    409     }
    410     fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
    411 
    412     TotalLen = sizeof (UINT32);
    413     for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
    414       TotalLen += sizeof (UINT16) * 2;
    415     }
    416     Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&TotalLen, sizeof (UINT32));
    417 
    418     for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
    419       fprintf (pFile, "\n");
    420       Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
    421       Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
    422     }
    423     fprintf (pFile, "\n};\n");
    424   }
    425 
    426   for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
    427     if (Item->mId != NULL && Item->mInfoStrList != NULL) {
    428       fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);
    429 
    430       TotalLen = sizeof (UINT32);
    431       for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
    432         TotalLen += Info->mWidth + sizeof (UINT16) * 2;
    433       }
    434       Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&TotalLen, sizeof (UINT32));
    435 
    436       for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
    437         fprintf (pFile, "\n");
    438         Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
    439         Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
    440         if (Info->mNext == NULL) {
    441           Output.WriteEnd (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)Info->mValue, Info->mWidth);
    442         } else {
    443           Output.WriteLine (pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)Info->mValue, Info->mWidth);
    444         }
    445       }
    446       fprintf (pFile, "\n};\n");
    447     }
    448   }
    449 }
    450 
    451 CVfrBufferConfig::CVfrBufferConfig (
    452   VOID
    453   )
    454 {
    455   mItemListHead = NULL;
    456   mItemListTail = NULL;
    457   mItemListPos  = NULL;
    458 }
    459 
    460 CVfrBufferConfig::~CVfrBufferConfig (
    461   VOID
    462   )
    463 {
    464   SConfigItem *p;
    465 
    466   while (mItemListHead != NULL) {
    467     p = mItemListHead;
    468     mItemListHead = mItemListHead->mNext;
    469     delete p;
    470   }
    471 
    472   mItemListHead = NULL;
    473   mItemListTail = NULL;
    474   mItemListPos  = NULL;
    475 }
    476 
    477 CVfrBufferConfig gCVfrBufferConfig;
    478 
    479 static struct {
    480   CONST CHAR8  *mTypeName;
    481   UINT8  mType;
    482   UINT32 mSize;
    483   UINT32 mAlign;
    484 } gInternalTypesTable [] = {
    485   {"UINT64",        EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64),       sizeof (UINT64)},
    486   {"UINT32",        EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32),       sizeof (UINT32)},
    487   {"UINT16",        EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16),       sizeof (UINT16)},
    488   {"UINT8",         EFI_IFR_TYPE_NUM_SIZE_8,  sizeof (UINT8),        sizeof (UINT8)},
    489   {"BOOLEAN",       EFI_IFR_TYPE_BOOLEAN,     sizeof (BOOLEAN),      sizeof (BOOLEAN)},
    490   {"EFI_HII_DATE",  EFI_IFR_TYPE_DATE,        sizeof (EFI_HII_DATE), sizeof (UINT16)},
    491   {"EFI_STRING_ID", EFI_IFR_TYPE_STRING,      sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
    492   {"EFI_HII_TIME",  EFI_IFR_TYPE_TIME,        sizeof (EFI_HII_TIME), sizeof (UINT8)},
    493   {"EFI_HII_REF",   EFI_IFR_TYPE_REF,         sizeof (EFI_HII_REF),  sizeof (EFI_GUID)},
    494   {NULL,            EFI_IFR_TYPE_OTHER,       0,                     0}
    495 };
    496 
    497 STATIC
    498 BOOLEAN
    499 _IS_INTERNAL_TYPE (
    500   IN CHAR8 *TypeName
    501   )
    502 {
    503   UINT32  Index;
    504 
    505   if (TypeName == NULL) {
    506     return FALSE;
    507   }
    508 
    509   for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
    510     if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
    511       return TRUE;
    512     }
    513   }
    514 
    515   return FALSE;
    516 }
    517 
    518 STATIC
    519 CHAR8 *
    520 TrimHex (
    521   IN  CHAR8   *Str,
    522   OUT bool    *IsHex
    523   )
    524 {
    525   *IsHex = FALSE;
    526 
    527   while (*Str && *Str == ' ') {
    528     Str++;
    529   }
    530   while (*Str && *Str == '0') {
    531     Str++;
    532   }
    533   if (*Str && (*Str == 'x' || *Str == 'X')) {
    534     Str++;
    535     *IsHex = TRUE;
    536   }
    537 
    538   return Str;
    539 }
    540 
    541 UINT32
    542 _STR2U32 (
    543   IN CHAR8 *Str
    544   )
    545 {
    546   bool    IsHex;
    547   UINT32  Value;
    548   CHAR8    c;
    549 
    550   Str = TrimHex (Str, &IsHex);
    551   for (Value = 0; (c = *Str) != '\0'; Str++) {
    552     //
    553     // BUG: does not handle overflow here
    554     //
    555 	(IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
    556 
    557     if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
    558       Value += (c - 'a' + 10);
    559     }
    560     if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
    561       Value += (c - 'A' + 10);
    562     }
    563     if (c >= '0' && c <= '9') {
    564       Value += (c - '0');
    565     }
    566   }
    567 
    568   return Value;
    569 }
    570 
    571 VOID
    572 CVfrVarDataTypeDB::RegisterNewType (
    573   IN SVfrDataType  *New
    574   )
    575 {
    576   New->mNext               = mDataTypeList;
    577   mDataTypeList            = New;
    578 }
    579 
    580 EFI_VFR_RETURN_CODE
    581 CVfrVarDataTypeDB::ExtractStructTypeName (
    582   IN  CHAR8 *&VarStr,
    583   OUT CHAR8 *TName
    584   )
    585 {
    586   if (TName == NULL) {
    587     return VFR_RETURN_FATAL_ERROR;
    588   }
    589 
    590   while((*VarStr != '\0') && (*VarStr != '.')) {
    591     *TName = *VarStr;
    592     VarStr++;
    593     TName++;
    594   }
    595   *TName = '\0';
    596   if (*VarStr == '.') {
    597     VarStr++;
    598   }
    599 
    600   return VFR_RETURN_SUCCESS;
    601 }
    602 
    603 EFI_VFR_RETURN_CODE
    604 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
    605   IN  CHAR8   *&VarStr,
    606   IN  CHAR8   *FName,
    607   OUT UINT32 &ArrayIdx
    608   )
    609 {
    610   UINT32 Idx;
    611   CHAR8   ArrayStr[MAX_NAME_LEN + 1];
    612 
    613   ArrayIdx = INVALID_ARRAY_INDEX;
    614 
    615   if (FName == NULL) {
    616     return VFR_RETURN_FATAL_ERROR;
    617   }
    618 
    619   while((*VarStr != '\0') &&
    620         (*VarStr != '.') &&
    621         (*VarStr != '[') &&
    622         (*VarStr != ']')) {
    623     *FName = *VarStr;
    624     VarStr++;
    625     FName++;
    626   }
    627   *FName = '\0';
    628 
    629   switch (*VarStr) {
    630   case '.' :
    631     VarStr++;
    632   case '\0':
    633     return VFR_RETURN_SUCCESS;
    634   case '[' :
    635     VarStr++;
    636     for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
    637       ArrayStr[Idx] = *VarStr;
    638     }
    639     ArrayStr[Idx] = '\0';
    640 
    641     if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
    642       return VFR_RETURN_DATA_STRING_ERROR;
    643     }
    644     ArrayIdx = _STR2U32 (ArrayStr);
    645     if (*VarStr == ']') {
    646       VarStr++;
    647     }
    648     if (*VarStr == '.') {
    649       VarStr++;
    650     }
    651     return VFR_RETURN_SUCCESS;
    652   case ']':
    653     return VFR_RETURN_DATA_STRING_ERROR;
    654   }
    655 
    656   return VFR_RETURN_SUCCESS;
    657 }
    658 
    659 EFI_VFR_RETURN_CODE
    660 CVfrVarDataTypeDB::GetTypeField (
    661   IN  CONST CHAR8   *FName,
    662   IN  SVfrDataType  *Type,
    663   OUT SVfrDataField *&Field
    664   )
    665 {
    666   SVfrDataField  *pField = NULL;
    667 
    668   if ((FName == NULL) && (Type == NULL)) {
    669     return VFR_RETURN_FATAL_ERROR;
    670   }
    671 
    672   for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
    673     //
    674     // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
    675     // add code to adjust it.
    676     //
    677     if (Type->mType == EFI_IFR_TYPE_TIME) {
    678       if (strcmp (FName, "Hour") == 0) {
    679         FName = "Hours";
    680       } else if (strcmp (FName, "Minute") == 0) {
    681         FName = "Minuts";
    682       } else if (strcmp (FName, "Second") == 0) {
    683         FName = "Seconds";
    684       }
    685     }
    686 
    687     if (strcmp (pField->mFieldName, FName) == 0) {
    688       Field = pField;
    689       return VFR_RETURN_SUCCESS;
    690     }
    691   }
    692 
    693   return VFR_RETURN_UNDEFINED;
    694 }
    695 
    696 EFI_VFR_RETURN_CODE
    697 CVfrVarDataTypeDB::GetFieldOffset (
    698   IN  SVfrDataField *Field,
    699   IN  UINT32        ArrayIdx,
    700   OUT UINT32        &Offset
    701   )
    702 {
    703   if (Field == NULL) {
    704     return VFR_RETURN_FATAL_ERROR;
    705   }
    706 
    707   //
    708   // Framework Vfr file Array Index is from 1.
    709   // But Uefi Vfr file Array Index is from 0.
    710   //
    711   if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
    712     if (ArrayIdx == 0) {
    713       return VFR_RETURN_ERROR_ARRARY_NUM;
    714     }
    715     ArrayIdx = ArrayIdx - 1;
    716   }
    717 
    718   if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
    719     return VFR_RETURN_ERROR_ARRARY_NUM;
    720   }
    721 
    722   //
    723   // Be compatible with the current usage
    724   // If ArraryIdx is not specified, the first one is used.
    725   //
    726   // if ArrayNum is larger than zero, ArraryIdx must be specified.
    727   //
    728   // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
    729   //   return VFR_RETURN_ERROR_ARRARY_NUM;
    730   // }
    731   //
    732 
    733   Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
    734   return VFR_RETURN_SUCCESS;
    735 }
    736 
    737 UINT8
    738 CVfrVarDataTypeDB::GetFieldWidth (
    739   IN SVfrDataField *Field
    740   )
    741 {
    742   if (Field == NULL) {
    743     return 0;
    744   }
    745 
    746   return Field->mFieldType->mType;
    747 }
    748 
    749 UINT32
    750 CVfrVarDataTypeDB::GetFieldSize (
    751   IN SVfrDataField *Field,
    752   IN UINT32       ArrayIdx
    753   )
    754 {
    755   if (Field == NULL) {
    756     return VFR_RETURN_FATAL_ERROR;
    757   }
    758 
    759   if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
    760     return Field->mFieldType->mTotalSize * Field->mArrayNum;
    761   } else {
    762     return Field->mFieldType->mTotalSize;
    763   }
    764 }
    765 
    766 VOID
    767 CVfrVarDataTypeDB::InternalTypesListInit (
    768   VOID
    769   )
    770 {
    771   SVfrDataType *New   = NULL;
    772   UINT32       Index;
    773 
    774   for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
    775     New                 = new SVfrDataType;
    776     if (New != NULL) {
    777       strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);
    778       New->mType        = gInternalTypesTable[Index].mType;
    779       New->mAlign       = gInternalTypesTable[Index].mAlign;
    780       New->mTotalSize   = gInternalTypesTable[Index].mSize;
    781       if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
    782         SVfrDataField *pYearField  = new SVfrDataField;
    783         SVfrDataField *pMonthField = new SVfrDataField;
    784         SVfrDataField *pDayField   = new SVfrDataField;
    785 
    786         strcpy (pYearField->mFieldName, "Year");
    787         GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);
    788         pYearField->mOffset      = 0;
    789         pYearField->mNext        = pMonthField;
    790         pYearField->mArrayNum    = 0;
    791 
    792         strcpy (pMonthField->mFieldName, "Month");
    793         GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
    794         pMonthField->mOffset     = 2;
    795         pMonthField->mNext       = pDayField;
    796         pMonthField->mArrayNum   = 0;
    797 
    798         strcpy (pDayField->mFieldName, "Day");
    799         GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
    800         pDayField->mOffset       = 3;
    801         pDayField->mNext         = NULL;
    802         pDayField->mArrayNum     = 0;
    803 
    804         New->mMembers            = pYearField;
    805       } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
    806         SVfrDataField *pHoursField   = new SVfrDataField;
    807         SVfrDataField *pMinutesField = new SVfrDataField;
    808         SVfrDataField *pSecondsField = new SVfrDataField;
    809 
    810         strcpy (pHoursField->mFieldName, "Hours");
    811         GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);
    812         pHoursField->mOffset     = 0;
    813         pHoursField->mNext       = pMinutesField;
    814         pHoursField->mArrayNum   = 0;
    815 
    816         strcpy (pMinutesField->mFieldName, "Minutes");
    817         GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
    818         pMinutesField->mOffset   = 1;
    819         pMinutesField->mNext     = pSecondsField;
    820         pMinutesField->mArrayNum = 0;
    821 
    822         strcpy (pSecondsField->mFieldName, "Seconds");
    823         GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
    824         pSecondsField->mOffset   = 2;
    825         pSecondsField->mNext     = NULL;
    826         pSecondsField->mArrayNum = 0;
    827 
    828         New->mMembers            = pHoursField;
    829       } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
    830         SVfrDataField *pQuestionIdField   = new SVfrDataField;
    831         SVfrDataField *pFormIdField       = new SVfrDataField;
    832         SVfrDataField *pFormSetGuidField  = new SVfrDataField;
    833         SVfrDataField *pDevicePathField   = new SVfrDataField;
    834 
    835         strcpy (pQuestionIdField->mFieldName, "QuestionId");
    836         GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);
    837         pQuestionIdField->mOffset     = 0;
    838         pQuestionIdField->mNext       = pFormIdField;
    839         pQuestionIdField->mArrayNum   = 0;
    840 
    841         strcpy (pFormIdField->mFieldName, "FormId");
    842         GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
    843         pFormIdField->mOffset   = 2;
    844         pFormIdField->mNext     = pFormSetGuidField;
    845         pFormIdField->mArrayNum = 0;
    846 
    847         strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
    848         GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
    849         pFormSetGuidField->mOffset   = 4;
    850         pFormSetGuidField->mNext     = pDevicePathField;
    851         pFormSetGuidField->mArrayNum = 0;
    852 
    853         strcpy (pDevicePathField->mFieldName, "DevicePath");
    854         GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
    855         pDevicePathField->mOffset   = 20;
    856         pDevicePathField->mNext     = NULL;
    857         pDevicePathField->mArrayNum = 0;
    858 
    859         New->mMembers            = pQuestionIdField;
    860       } else {
    861         New->mMembers            = NULL;
    862       }
    863       New->mNext                 = NULL;
    864       RegisterNewType (New);
    865       New                        = NULL;
    866     }
    867   }
    868 }
    869 
    870 CVfrVarDataTypeDB::CVfrVarDataTypeDB (
    871   VOID
    872   )
    873 {
    874   mDataTypeList  = NULL;
    875   mNewDataType   = NULL;
    876   mCurrDataField = NULL;
    877   mPackAlign     = DEFAULT_PACK_ALIGN;
    878   mPackStack     = NULL;
    879   mFirstNewDataTypeName = NULL;
    880 
    881   InternalTypesListInit ();
    882 }
    883 
    884 CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
    885   VOID
    886   )
    887 {
    888   SVfrDataType      *pType;
    889   SVfrDataField     *pField;
    890   SVfrPackStackNode *pPack;
    891 
    892   if (mNewDataType != NULL) {
    893     delete mNewDataType;
    894   }
    895 
    896   while (mDataTypeList != NULL) {
    897     pType = mDataTypeList;
    898     mDataTypeList = mDataTypeList->mNext;
    899     while(pType->mMembers != NULL) {
    900       pField = pType->mMembers;
    901       pType->mMembers = pType->mMembers->mNext;
    902       delete pField;
    903     }
    904 	delete pType;
    905   }
    906 
    907   while (mPackStack != NULL) {
    908     pPack = mPackStack;
    909     mPackStack = mPackStack->mNext;
    910     delete pPack;
    911   }
    912 }
    913 
    914 EFI_VFR_RETURN_CODE
    915 CVfrVarDataTypeDB::Pack (
    916   IN UINT32         LineNum,
    917   IN UINT8          Action,
    918   IN CHAR8           *Identifier,
    919   IN UINT32         Number
    920   )
    921 {
    922   UINT32            PackAlign;
    923   CHAR8             Msg[MAX_STRING_LEN] = {0, };
    924 
    925   if (Action & VFR_PACK_SHOW) {
    926     sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
    927     gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);
    928   }
    929 
    930   if (Action & VFR_PACK_PUSH) {
    931     SVfrPackStackNode *pNew = NULL;
    932 
    933     if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
    934       return VFR_RETURN_FATAL_ERROR;
    935     }
    936     pNew->mNext = mPackStack;
    937     mPackStack  = pNew;
    938   }
    939 
    940   if (Action & VFR_PACK_POP) {
    941     SVfrPackStackNode *pNode = NULL;
    942 
    943     if (mPackStack == NULL) {
    944       gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");
    945     }
    946 
    947     for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
    948       if (pNode->Match (Identifier) == TRUE) {
    949         mPackAlign = pNode->mNumber;
    950         mPackStack = pNode->mNext;
    951       }
    952     }
    953   }
    954 
    955   if (Action & VFR_PACK_ASSIGN) {
    956     PackAlign = (Number > 1) ? Number + Number % 2 : Number;
    957     if ((PackAlign == 0) || (PackAlign > 16)) {
    958       gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
    959     } else {
    960       mPackAlign = PackAlign;
    961     }
    962   }
    963 
    964   return VFR_RETURN_SUCCESS;
    965 }
    966 
    967 VOID
    968 CVfrVarDataTypeDB::DeclareDataTypeBegin (
    969   VOID
    970   )
    971 {
    972   SVfrDataType *pNewType = NULL;
    973 
    974   pNewType               = new SVfrDataType;
    975   pNewType->mTypeName[0] = '\0';
    976   pNewType->mType        = EFI_IFR_TYPE_OTHER;
    977   pNewType->mAlign       = DEFAULT_ALIGN;
    978   pNewType->mTotalSize   = 0;
    979   pNewType->mMembers     = NULL;
    980   pNewType->mNext        = NULL;
    981 
    982   mNewDataType           = pNewType;
    983 }
    984 
    985 EFI_VFR_RETURN_CODE
    986 CVfrVarDataTypeDB::SetNewTypeName (
    987   IN CHAR8   *TypeName
    988   )
    989 {
    990   SVfrDataType *pType;
    991 
    992   if (mNewDataType == NULL) {
    993     return VFR_RETURN_ERROR_SKIPED;
    994   }
    995   if (TypeName == NULL) {
    996     return VFR_RETURN_FATAL_ERROR;
    997   }
    998   if (strlen(TypeName) >= MAX_NAME_LEN) {
    999     return VFR_RETURN_INVALID_PARAMETER;
   1000   }
   1001 
   1002   for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
   1003     if (strcmp(pType->mTypeName, TypeName) == 0) {
   1004       return VFR_RETURN_REDEFINED;
   1005     }
   1006   }
   1007 
   1008   strcpy(mNewDataType->mTypeName, TypeName);
   1009   return VFR_RETURN_SUCCESS;
   1010 }
   1011 
   1012 EFI_VFR_RETURN_CODE
   1013 CVfrVarDataTypeDB::DataTypeAddField (
   1014   IN CHAR8   *FieldName,
   1015   IN CHAR8   *TypeName,
   1016   IN UINT32 ArrayNum
   1017   )
   1018 {
   1019   SVfrDataField       *pNewField  = NULL;
   1020   SVfrDataType        *pFieldType = NULL;
   1021   SVfrDataField       *pTmp;
   1022   UINT32              Align;
   1023 
   1024   CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
   1025 
   1026   if (strlen (FieldName) >= MAX_NAME_LEN) {
   1027    return VFR_RETURN_INVALID_PARAMETER;
   1028   }
   1029 
   1030   for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
   1031     if (strcmp (pTmp->mFieldName, FieldName) == 0) {
   1032       return VFR_RETURN_REDEFINED;
   1033     }
   1034   }
   1035 
   1036   Align = MIN (mPackAlign, pFieldType->mAlign);
   1037 
   1038   if ((pNewField = new SVfrDataField) == NULL) {
   1039     return VFR_RETURN_OUT_FOR_RESOURCES;
   1040   }
   1041   strcpy (pNewField->mFieldName, FieldName);
   1042   pNewField->mFieldType    = pFieldType;
   1043   pNewField->mArrayNum     = ArrayNum;
   1044   if ((mNewDataType->mTotalSize % Align) == 0) {
   1045     pNewField->mOffset     = mNewDataType->mTotalSize;
   1046   } else {
   1047     pNewField->mOffset     = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
   1048   }
   1049   if (mNewDataType->mMembers == NULL) {
   1050     mNewDataType->mMembers = pNewField;
   1051     pNewField->mNext       = NULL;
   1052   } else {
   1053     for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
   1054       ;
   1055     pTmp->mNext            = pNewField;
   1056     pNewField->mNext       = NULL;
   1057   }
   1058 
   1059   mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
   1060   mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
   1061 
   1062   return VFR_RETURN_SUCCESS;
   1063 }
   1064 
   1065 VOID
   1066 CVfrVarDataTypeDB::DeclareDataTypeEnd (
   1067   VOID
   1068   )
   1069 {
   1070   if (mNewDataType->mTypeName[0] == '\0') {
   1071     return;
   1072   }
   1073 
   1074   if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
   1075     mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
   1076   }
   1077 
   1078   RegisterNewType (mNewDataType);
   1079   if (mFirstNewDataTypeName == NULL) {
   1080     mFirstNewDataTypeName = mNewDataType->mTypeName;
   1081   }
   1082 
   1083   mNewDataType             = NULL;
   1084 }
   1085 
   1086 EFI_VFR_RETURN_CODE
   1087 CVfrVarDataTypeDB::GetDataType (
   1088   IN  CHAR8         *TypeName,
   1089   OUT SVfrDataType **DataType
   1090   )
   1091 {
   1092   SVfrDataType *pDataType = NULL;
   1093 
   1094   if (TypeName == NULL) {
   1095     return VFR_RETURN_ERROR_SKIPED;
   1096   }
   1097 
   1098   if (DataType == NULL) {
   1099     return VFR_RETURN_FATAL_ERROR;
   1100   }
   1101 
   1102   *DataType = NULL;
   1103 
   1104   for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
   1105     if (strcmp (TypeName, pDataType->mTypeName) == 0) {
   1106       *DataType = pDataType;
   1107       return VFR_RETURN_SUCCESS;
   1108     }
   1109   }
   1110 
   1111   return VFR_RETURN_UNDEFINED;
   1112 }
   1113 
   1114 EFI_VFR_RETURN_CODE
   1115 CVfrVarDataTypeDB::GetDataTypeSize (
   1116   IN  UINT8   DataType,
   1117   OUT UINT32 *Size
   1118   )
   1119 {
   1120   SVfrDataType *pDataType = NULL;
   1121 
   1122   if (Size == NULL) {
   1123     return VFR_RETURN_FATAL_ERROR;
   1124   }
   1125 
   1126   *Size    = 0;
   1127   DataType = DataType & 0x0F;
   1128 
   1129   //
   1130   // For user defined data type, the size can't be got by this function.
   1131   //
   1132   if (DataType == EFI_IFR_TYPE_OTHER) {
   1133     return VFR_RETURN_SUCCESS;
   1134   }
   1135 
   1136   for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
   1137     if (DataType == pDataType->mType) {
   1138       *Size = pDataType->mTotalSize;
   1139       return VFR_RETURN_SUCCESS;
   1140     }
   1141   }
   1142 
   1143   return VFR_RETURN_UNDEFINED;
   1144 }
   1145 
   1146 EFI_VFR_RETURN_CODE
   1147 CVfrVarDataTypeDB::GetDataTypeSize (
   1148   IN  CHAR8   *TypeName,
   1149   OUT UINT32 *Size
   1150   )
   1151 {
   1152   SVfrDataType *pDataType = NULL;
   1153 
   1154   if (Size == NULL) {
   1155     return VFR_RETURN_FATAL_ERROR;
   1156   }
   1157 
   1158   *Size = 0;
   1159 
   1160   for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
   1161     if (strcmp (TypeName, pDataType->mTypeName) == 0) {
   1162       *Size = pDataType->mTotalSize;
   1163       return VFR_RETURN_SUCCESS;
   1164     }
   1165   }
   1166 
   1167   return VFR_RETURN_UNDEFINED;
   1168 }
   1169 
   1170 EFI_VFR_RETURN_CODE
   1171 CVfrVarDataTypeDB::GetDataFieldInfo (
   1172   IN  CHAR8     *VarStr,
   1173   OUT UINT16   &Offset,
   1174   OUT UINT8    &Type,
   1175   OUT UINT32   &Size
   1176   )
   1177 {
   1178   CHAR8               TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
   1179   UINT32              ArrayIdx, Tmp;
   1180   SVfrDataType        *pType  = NULL;
   1181   SVfrDataField       *pField = NULL;
   1182 
   1183   Offset = 0;
   1184   Type   = EFI_IFR_TYPE_OTHER;
   1185   Size   = 0;
   1186 
   1187   CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
   1188   CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
   1189 
   1190   //
   1191   // if it is not struct data type
   1192   //
   1193   Type  = pType->mType;
   1194   Size  = pType->mTotalSize;
   1195 
   1196   while (*VarStr != '\0') {
   1197   	CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
   1198     CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
   1199     pType  = pField->mFieldType;
   1200     CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);
   1201     Offset = (UINT16) (Offset + Tmp);
   1202     Type   = GetFieldWidth (pField);
   1203     Size   = GetFieldSize (pField, ArrayIdx);
   1204   }
   1205   return VFR_RETURN_SUCCESS;
   1206 }
   1207 
   1208 EFI_VFR_RETURN_CODE
   1209 CVfrVarDataTypeDB::GetUserDefinedTypeNameList  (
   1210   OUT CHAR8      ***NameList,
   1211   OUT UINT32    *ListSize
   1212   )
   1213 {
   1214   UINT32       Index;
   1215   SVfrDataType *pType;
   1216 
   1217   if ((NameList == NULL) || (ListSize == NULL)) {
   1218     return VFR_RETURN_FATAL_ERROR;
   1219   }
   1220 
   1221   *NameList = NULL;
   1222   *ListSize = 0;
   1223 
   1224   for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
   1225     if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
   1226       (*ListSize)++;
   1227     }
   1228   }
   1229 
   1230   if (*ListSize == 0) {
   1231     return VFR_RETURN_SUCCESS;
   1232   }
   1233 
   1234   if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
   1235     *ListSize = 0;
   1236     return VFR_RETURN_OUT_FOR_RESOURCES;
   1237   }
   1238 
   1239   for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
   1240     if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
   1241       (*NameList)[Index] = pType->mTypeName;
   1242     }
   1243   }
   1244   return VFR_RETURN_SUCCESS;
   1245 }
   1246 
   1247 BOOLEAN
   1248 CVfrVarDataTypeDB::IsTypeNameDefined (
   1249   IN CHAR8 *TypeName
   1250   )
   1251 {
   1252   SVfrDataType *pType;
   1253 
   1254   if (TypeName == NULL) {
   1255     return FALSE;
   1256   }
   1257 
   1258   for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
   1259     if (strcmp (pType->mTypeName, TypeName) == 0) {
   1260       return TRUE;
   1261     }
   1262   }
   1263 
   1264   return FALSE;
   1265 }
   1266 
   1267 VOID
   1268 CVfrVarDataTypeDB::Dump (
   1269   IN FILE         *File
   1270   )
   1271 {
   1272   SVfrDataType  *pTNode;
   1273   SVfrDataField *pFNode;
   1274 
   1275   fprintf (File, "\n\n***************************************************************\n");
   1276   fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
   1277   for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
   1278     fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
   1279     fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
   1280     for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
   1281       if (pFNode->mArrayNum > 0) {
   1282         fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
   1283                   pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
   1284       } else {
   1285         fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
   1286                   pFNode->mFieldName, pFNode->mFieldType->mTypeName);
   1287       }
   1288     }
   1289     fprintf (File, "\t\t};\n");
   1290   fprintf (File, "---------------------------------------------------------------\n");
   1291   }
   1292   fprintf (File, "***************************************************************\n");
   1293 }
   1294 
   1295 #ifdef CVFR_VARDATATYPEDB_DEBUG
   1296 VOID
   1297 CVfrVarDataTypeDB::ParserDB (
   1298   VOID
   1299   )
   1300 {
   1301   SVfrDataType  *pTNode;
   1302   SVfrDataField *pFNode;
   1303 
   1304   printf ("***************************************************************\n");
   1305   printf ("\t\tmPackAlign = %x\n", mPackAlign);
   1306   for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
   1307     printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
   1308     printf ("\t\tstruct %s {\n", pTNode->mTypeName);
   1309     for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
   1310       printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
   1311     }
   1312     printf ("\t\t};\n");
   1313 	printf ("---------------------------------------------------------------\n");
   1314   }
   1315   printf ("***************************************************************\n");
   1316 }
   1317 #endif
   1318 
   1319 SVfrVarStorageNode::SVfrVarStorageNode (
   1320   IN EFI_GUID              *Guid,
   1321   IN CHAR8                 *StoreName,
   1322   IN EFI_VARSTORE_ID       VarStoreId,
   1323   IN EFI_STRING_ID         VarName,
   1324   IN UINT32                VarSize,
   1325   IN BOOLEAN               Flag
   1326   )
   1327 {
   1328   if (Guid != NULL) {
   1329     mGuid = *Guid;
   1330   } else {
   1331     memset (&Guid, 0, sizeof (EFI_GUID));
   1332   }
   1333   if (StoreName != NULL) {
   1334     mVarStoreName = new CHAR8[strlen(StoreName) + 1];
   1335     strcpy (mVarStoreName, StoreName);
   1336   } else {
   1337     mVarStoreName = NULL;
   1338   }
   1339   mNext                            = NULL;
   1340   mVarStoreId                      = VarStoreId;
   1341   mVarStoreType                    = EFI_VFR_VARSTORE_EFI;
   1342   mStorageInfo.mEfiVar.mEfiVarName = VarName;
   1343   mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
   1344   mAssignedFlag                    = Flag;
   1345 }
   1346 
   1347 SVfrVarStorageNode::SVfrVarStorageNode (
   1348   IN EFI_GUID              *Guid,
   1349   IN CHAR8                 *StoreName,
   1350   IN EFI_VARSTORE_ID       VarStoreId,
   1351   IN SVfrDataType          *DataType,
   1352   IN BOOLEAN               Flag
   1353   )
   1354 {
   1355   if (Guid != NULL) {
   1356     mGuid = *Guid;
   1357   } else {
   1358     memset (&Guid, 0, sizeof (EFI_GUID));
   1359   }
   1360   if (StoreName != NULL) {
   1361     mVarStoreName = new CHAR8[strlen(StoreName) + 1];
   1362     strcpy (mVarStoreName, StoreName);
   1363   } else {
   1364     mVarStoreName = NULL;
   1365   }
   1366   mNext                    = NULL;
   1367   mVarStoreId              = VarStoreId;
   1368   mVarStoreType            = EFI_VFR_VARSTORE_BUFFER;
   1369   mStorageInfo.mDataType   = DataType;
   1370   mAssignedFlag            = Flag;
   1371 }
   1372 
   1373 SVfrVarStorageNode::SVfrVarStorageNode (
   1374   IN CHAR8                 *StoreName,
   1375   IN EFI_VARSTORE_ID       VarStoreId
   1376   )
   1377 {
   1378   if (StoreName != NULL) {
   1379     mVarStoreName = new CHAR8[strlen(StoreName) + 1];
   1380     strcpy (mVarStoreName, StoreName);
   1381   } else {
   1382     mVarStoreName = NULL;
   1383   }
   1384   mNext                              = NULL;
   1385   mVarStoreId                        = VarStoreId;
   1386   mVarStoreType                      = EFI_VFR_VARSTORE_NAME;
   1387   mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
   1388   mStorageInfo.mNameSpace.mTableSize = 0;
   1389 }
   1390 
   1391 SVfrVarStorageNode::~SVfrVarStorageNode (
   1392   VOID
   1393   )
   1394 {
   1395   if (mVarStoreName != NULL) {
   1396     delete mVarStoreName;
   1397   }
   1398 
   1399   if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
   1400     delete mStorageInfo.mNameSpace.mNameTable;
   1401   }
   1402 }
   1403 
   1404 CVfrDataStorage::CVfrDataStorage (
   1405   VOID
   1406   )
   1407 {
   1408   UINT32 Index;
   1409 
   1410   for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
   1411     mFreeVarStoreIdBitMap[Index] = 0;
   1412   }
   1413 
   1414   // Question ID 0 is reserved.
   1415   mFreeVarStoreIdBitMap[0] = 0x80000000;
   1416 
   1417   mBufferVarStoreList      = NULL;
   1418   mEfiVarStoreList         = NULL;
   1419   mNameVarStoreList        = NULL;
   1420   mCurrVarStorageNode      = NULL;
   1421   mNewVarStorageNode       = NULL;
   1422 }
   1423 
   1424 CVfrDataStorage::~CVfrDataStorage (
   1425   VOID
   1426   )
   1427 {
   1428   SVfrVarStorageNode *pNode;
   1429 
   1430   while (mBufferVarStoreList != NULL) {
   1431     pNode = mBufferVarStoreList;
   1432     mBufferVarStoreList = mBufferVarStoreList->mNext;
   1433     delete pNode;
   1434   }
   1435   while (mEfiVarStoreList != NULL) {
   1436     pNode = mEfiVarStoreList;
   1437     mEfiVarStoreList = mEfiVarStoreList->mNext;
   1438     delete pNode;
   1439   }
   1440   while (mNameVarStoreList != NULL) {
   1441     pNode = mNameVarStoreList;
   1442     mNameVarStoreList = mNameVarStoreList->mNext;
   1443     delete pNode;
   1444   }
   1445   if (mNewVarStorageNode != NULL) {
   1446     delete mNewVarStorageNode;
   1447   }
   1448 }
   1449 
   1450 EFI_VARSTORE_ID
   1451 CVfrDataStorage::GetFreeVarStoreId (
   1452   EFI_VFR_VARSTORE_TYPE VarType
   1453   )
   1454 {
   1455   UINT32  Index, Mask, Offset;
   1456 
   1457   //
   1458   // Assign the different ID range for the different type VarStore to support Framework Vfr
   1459   //
   1460   Index = 0;
   1461   if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
   1462     Index = 0;
   1463   } else if (VarType == EFI_VFR_VARSTORE_EFI) {
   1464     Index = 1;
   1465   } else if (VarType == EFI_VFR_VARSTORE_NAME) {
   1466     Index = 2;
   1467   }
   1468 
   1469   for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
   1470     if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
   1471       break;
   1472     }
   1473   }
   1474 
   1475   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
   1476     if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
   1477       mFreeVarStoreIdBitMap[Index] |= Mask;
   1478       return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
   1479     }
   1480   }
   1481 
   1482   return EFI_VARSTORE_ID_INVALID;
   1483 }
   1484 
   1485 BOOLEAN
   1486 CVfrDataStorage::ChekVarStoreIdFree (
   1487   IN EFI_VARSTORE_ID VarStoreId
   1488   )
   1489 {
   1490   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
   1491   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
   1492 
   1493   return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
   1494 }
   1495 
   1496 VOID
   1497 CVfrDataStorage::MarkVarStoreIdUsed (
   1498   IN EFI_VARSTORE_ID VarStoreId
   1499   )
   1500 {
   1501   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
   1502   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
   1503 
   1504   mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
   1505 }
   1506 
   1507 VOID
   1508 CVfrDataStorage::MarkVarStoreIdUnused (
   1509   IN EFI_VARSTORE_ID VarStoreId
   1510   )
   1511 {
   1512   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
   1513   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
   1514 
   1515   mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
   1516 }
   1517 
   1518 EFI_VFR_RETURN_CODE
   1519 CVfrDataStorage::DeclareNameVarStoreBegin (
   1520   IN CHAR8           *StoreName,
   1521   IN EFI_VARSTORE_ID VarStoreId
   1522   )
   1523 {
   1524   SVfrVarStorageNode *pNode = NULL;
   1525   EFI_VARSTORE_ID    TmpVarStoreId;
   1526 
   1527   if (StoreName == NULL) {
   1528     return VFR_RETURN_FATAL_ERROR;
   1529   }
   1530 
   1531   if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
   1532     return VFR_RETURN_REDEFINED;
   1533   }
   1534 
   1535   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1536     VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
   1537   } else {
   1538     if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
   1539       return VFR_RETURN_VARSTOREID_REDEFINED;
   1540     }
   1541     MarkVarStoreIdUsed (VarStoreId);
   1542   }
   1543 
   1544   if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
   1545     return VFR_RETURN_UNDEFINED;
   1546   }
   1547 
   1548   mNewVarStorageNode = pNode;
   1549 
   1550   return VFR_RETURN_SUCCESS;
   1551 }
   1552 
   1553 EFI_VFR_RETURN_CODE
   1554 CVfrDataStorage::NameTableAddItem (
   1555   IN EFI_STRING_ID  Item
   1556   )
   1557 {
   1558   EFI_VARSTORE_ID *NewTable, *OldTable;
   1559   UINT32          TableSize;
   1560 
   1561   OldTable  = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
   1562   TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
   1563 
   1564   if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
   1565     if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
   1566       return VFR_RETURN_OUT_FOR_RESOURCES;
   1567     }
   1568     memcpy (NewTable, OldTable, TableSize);
   1569     mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
   1570   }
   1571 
   1572   mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
   1573   mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
   1574 
   1575   return VFR_RETURN_SUCCESS;
   1576 }
   1577 
   1578 EFI_VFR_RETURN_CODE
   1579 CVfrDataStorage::DeclareNameVarStoreEnd (
   1580   IN EFI_GUID *Guid
   1581   )
   1582 {
   1583   mNewVarStorageNode->mGuid = *Guid;
   1584   mNewVarStorageNode->mNext = mNameVarStoreList;
   1585   mNameVarStoreList         = mNewVarStorageNode;
   1586 
   1587   mNewVarStorageNode        = NULL;
   1588 
   1589   return VFR_RETURN_SUCCESS;
   1590 }
   1591 
   1592 EFI_VFR_RETURN_CODE
   1593 CVfrDataStorage::DeclareEfiVarStore (
   1594   IN CHAR8          *StoreName,
   1595   IN EFI_GUID       *Guid,
   1596   IN EFI_STRING_ID  NameStrId,
   1597   IN UINT32         VarSize,
   1598   IN BOOLEAN        Flag
   1599   )
   1600 {
   1601   SVfrVarStorageNode *pNode;
   1602   EFI_VARSTORE_ID    VarStoreId;
   1603 
   1604   if ((StoreName == NULL) || (Guid == NULL)) {
   1605     return VFR_RETURN_FATAL_ERROR;
   1606   }
   1607 
   1608   if (VarSize > sizeof (UINT64)) {
   1609     return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
   1610   }
   1611 
   1612   if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
   1613     return VFR_RETURN_REDEFINED;
   1614   }
   1615 
   1616   VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
   1617   if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
   1618     return VFR_RETURN_OUT_FOR_RESOURCES;
   1619   }
   1620 
   1621   pNode->mNext       = mEfiVarStoreList;
   1622   mEfiVarStoreList   = pNode;
   1623 
   1624   return VFR_RETURN_SUCCESS;
   1625 }
   1626 
   1627 EFI_VFR_RETURN_CODE
   1628 CVfrDataStorage::DeclareBufferVarStore (
   1629   IN CHAR8             *StoreName,
   1630   IN EFI_GUID          *Guid,
   1631   IN CVfrVarDataTypeDB *DataTypeDB,
   1632   IN CHAR8             *TypeName,
   1633   IN EFI_VARSTORE_ID   VarStoreId,
   1634   IN BOOLEAN           Flag
   1635   )
   1636 {
   1637   SVfrVarStorageNode   *pNew = NULL;
   1638   SVfrDataType         *pDataType = NULL;
   1639   EFI_VARSTORE_ID      TempVarStoreId;
   1640 
   1641   if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
   1642     return VFR_RETURN_FATAL_ERROR;
   1643   }
   1644 
   1645   if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
   1646     return VFR_RETURN_REDEFINED;
   1647   }
   1648 
   1649   CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
   1650 
   1651   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1652     VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
   1653   } else {
   1654     if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
   1655       return VFR_RETURN_VARSTOREID_REDEFINED;
   1656     }
   1657     MarkVarStoreIdUsed (VarStoreId);
   1658   }
   1659 
   1660   if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
   1661     return VFR_RETURN_OUT_FOR_RESOURCES;
   1662   }
   1663 
   1664   pNew->mNext         = mBufferVarStoreList;
   1665   mBufferVarStoreList = pNew;
   1666 
   1667   if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
   1668     return VFR_RETURN_FATAL_ERROR;
   1669   }
   1670 
   1671   return VFR_RETURN_SUCCESS;
   1672 }
   1673 
   1674 EFI_VFR_RETURN_CODE
   1675 CVfrDataStorage::GetVarStoreByDataType (
   1676   IN  CHAR8              *DataTypeName,
   1677   OUT SVfrVarStorageNode **VarNode,
   1678   IN  EFI_GUID           *VarGuid
   1679   )
   1680 {
   1681   SVfrVarStorageNode    *pNode;
   1682   SVfrVarStorageNode    *MatchNode;
   1683 
   1684   //
   1685   // Framework VFR uses Data type name as varstore name, so don't need check again.
   1686   //
   1687   if (VfrCompatibleMode) {
   1688     return VFR_RETURN_UNDEFINED;
   1689   }
   1690 
   1691   MatchNode = NULL;
   1692   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1693     if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
   1694       continue;
   1695     }
   1696 
   1697     if ((VarGuid != NULL)) {
   1698       if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
   1699         *VarNode = pNode;
   1700         return VFR_RETURN_SUCCESS;
   1701       }
   1702     } else {
   1703       if (MatchNode == NULL) {
   1704         MatchNode = pNode;
   1705       } else {
   1706         //
   1707         // More than one varstores referred the same data structures.
   1708         //
   1709         return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
   1710       }
   1711     }
   1712   }
   1713 
   1714   if (MatchNode == NULL) {
   1715     return VFR_RETURN_UNDEFINED;
   1716   }
   1717 
   1718   *VarNode = MatchNode;
   1719   return VFR_RETURN_SUCCESS;
   1720 }
   1721 
   1722 EFI_VARSTORE_ID
   1723 CVfrDataStorage::CheckGuidField (
   1724   IN  SVfrVarStorageNode   *pNode,
   1725   IN  EFI_GUID             *StoreGuid,
   1726   IN  BOOLEAN              *HasFoundOne,
   1727   OUT EFI_VFR_RETURN_CODE  *ReturnCode
   1728   )
   1729 {
   1730   if (StoreGuid != NULL) {
   1731     //
   1732     // If has guid info, compare the guid filed.
   1733     //
   1734     if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
   1735       //
   1736       // Both name and guid are same, this this varstore.
   1737       //
   1738       mCurrVarStorageNode = pNode;
   1739       *ReturnCode = VFR_RETURN_SUCCESS;
   1740       return TRUE;
   1741     }
   1742   } else {
   1743     //
   1744     // Not has Guid field, check whether this name is the only one.
   1745     //
   1746     if (*HasFoundOne) {
   1747       //
   1748       // The name has conflict, return name redefined.
   1749       //
   1750       *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
   1751       return TRUE;
   1752     }
   1753 
   1754     *HasFoundOne = TRUE;
   1755     mCurrVarStorageNode = pNode;
   1756   }
   1757 
   1758   return FALSE;
   1759 }
   1760 
   1761 /**
   1762   Base on the input store name and guid to find the varstore id.
   1763 
   1764   If both name and guid are inputed, base on the name and guid to
   1765   found the varstore. If only name inputed, base on the name to
   1766   found the varstore and go on to check whether more than one varstore
   1767   has the same name. If only has found one varstore, return this
   1768   varstore; if more than one varstore has same name, return varstore
   1769   name redefined error. If no varstore found by varstore name, call
   1770   function GetVarStoreByDataType and use inputed varstore name as
   1771   data type name to search.
   1772 **/
   1773 EFI_VFR_RETURN_CODE
   1774 CVfrDataStorage::GetVarStoreId (
   1775   IN  CHAR8           *StoreName,
   1776   OUT EFI_VARSTORE_ID *VarStoreId,
   1777   IN  EFI_GUID        *StoreGuid
   1778   )
   1779 {
   1780   EFI_VFR_RETURN_CODE   ReturnCode;
   1781   SVfrVarStorageNode    *pNode;
   1782   BOOLEAN               HasFoundOne = FALSE;
   1783 
   1784   mCurrVarStorageNode = NULL;
   1785 
   1786   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1787     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
   1788       if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
   1789         *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1790         return ReturnCode;
   1791       }
   1792     }
   1793   }
   1794 
   1795   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1796     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
   1797       if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
   1798         *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1799         return ReturnCode;
   1800       }
   1801     }
   1802   }
   1803 
   1804   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1805     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
   1806       if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
   1807         *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1808         return ReturnCode;
   1809       }
   1810     }
   1811   }
   1812 
   1813   if (HasFoundOne) {
   1814     *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1815     return VFR_RETURN_SUCCESS;
   1816   }
   1817 
   1818   *VarStoreId         = EFI_VARSTORE_ID_INVALID;
   1819 
   1820   //
   1821   // Assume that Data strucutre name is used as StoreName, and check again.
   1822   //
   1823   ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
   1824   if (pNode != NULL) {
   1825     mCurrVarStorageNode = pNode;
   1826     *VarStoreId = pNode->mVarStoreId;
   1827   }
   1828 
   1829   return ReturnCode;
   1830 }
   1831 
   1832 EFI_VFR_RETURN_CODE
   1833 CVfrDataStorage::GetBufferVarStoreDataTypeName (
   1834   IN  EFI_VARSTORE_ID        VarStoreId,
   1835   OUT CHAR8                  **DataTypeName
   1836   )
   1837 {
   1838   SVfrVarStorageNode    *pNode;
   1839 
   1840   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1841     return VFR_RETURN_FATAL_ERROR;
   1842   }
   1843 
   1844   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1845     if (pNode->mVarStoreId == VarStoreId) {
   1846       *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
   1847       return VFR_RETURN_SUCCESS;
   1848     }
   1849   }
   1850 
   1851   return VFR_RETURN_UNDEFINED;
   1852 }
   1853 
   1854 EFI_VFR_VARSTORE_TYPE
   1855 CVfrDataStorage::GetVarStoreType (
   1856   IN  EFI_VARSTORE_ID        VarStoreId
   1857   )
   1858 {
   1859   SVfrVarStorageNode    *pNode;
   1860   EFI_VFR_VARSTORE_TYPE VarStoreType;
   1861 
   1862   VarStoreType = EFI_VFR_VARSTORE_INVALID;
   1863 
   1864   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1865     return VarStoreType;
   1866   }
   1867 
   1868   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1869     if (pNode->mVarStoreId == VarStoreId) {
   1870       VarStoreType = pNode->mVarStoreType;
   1871       return VarStoreType;
   1872     }
   1873   }
   1874 
   1875   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1876     if (pNode->mVarStoreId == VarStoreId) {
   1877       VarStoreType = pNode->mVarStoreType;
   1878       return VarStoreType;
   1879     }
   1880   }
   1881 
   1882   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1883     if (pNode->mVarStoreId == VarStoreId) {
   1884       VarStoreType = pNode->mVarStoreType;
   1885       return VarStoreType;
   1886     }
   1887   }
   1888 
   1889   return VarStoreType;
   1890 }
   1891 
   1892 EFI_GUID *
   1893 CVfrDataStorage::GetVarStoreGuid (
   1894   IN  EFI_VARSTORE_ID        VarStoreId
   1895   )
   1896 {
   1897   SVfrVarStorageNode    *pNode;
   1898   EFI_GUID              *VarGuid;
   1899 
   1900   VarGuid = NULL;
   1901 
   1902   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1903     return VarGuid;
   1904   }
   1905 
   1906   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1907     if (pNode->mVarStoreId == VarStoreId) {
   1908       VarGuid = &pNode->mGuid;
   1909       return VarGuid;
   1910     }
   1911   }
   1912 
   1913   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1914     if (pNode->mVarStoreId == VarStoreId) {
   1915       VarGuid = &pNode->mGuid;
   1916       return VarGuid;
   1917     }
   1918   }
   1919 
   1920   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1921     if (pNode->mVarStoreId == VarStoreId) {
   1922       VarGuid = &pNode->mGuid;
   1923       return VarGuid;
   1924     }
   1925   }
   1926 
   1927   return VarGuid;
   1928 }
   1929 
   1930 EFI_VFR_RETURN_CODE
   1931 CVfrDataStorage::GetVarStoreName (
   1932   IN  EFI_VARSTORE_ID VarStoreId,
   1933   OUT CHAR8           **VarStoreName
   1934   )
   1935 {
   1936   SVfrVarStorageNode    *pNode;
   1937 
   1938   if (VarStoreName == NULL) {
   1939     return VFR_RETURN_FATAL_ERROR;
   1940   }
   1941 
   1942   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1943     if (pNode->mVarStoreId == VarStoreId) {
   1944       *VarStoreName = pNode->mVarStoreName;
   1945       return VFR_RETURN_SUCCESS;
   1946     }
   1947   }
   1948 
   1949   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1950     if (pNode->mVarStoreId == VarStoreId) {
   1951       *VarStoreName = pNode->mVarStoreName;
   1952       return VFR_RETURN_SUCCESS;
   1953     }
   1954   }
   1955 
   1956   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1957     if (pNode->mVarStoreId == VarStoreId) {
   1958       *VarStoreName = pNode->mVarStoreName;
   1959       return VFR_RETURN_SUCCESS;
   1960     }
   1961   }
   1962 
   1963   *VarStoreName = NULL;
   1964   return VFR_RETURN_UNDEFINED;
   1965 }
   1966 
   1967 EFI_VFR_RETURN_CODE
   1968 CVfrDataStorage::GetEfiVarStoreInfo (
   1969   IN OUT EFI_VARSTORE_INFO  *Info
   1970   )
   1971 {
   1972   if (Info == NULL) {
   1973     return VFR_RETURN_FATAL_ERROR;
   1974   }
   1975 
   1976   if (mCurrVarStorageNode == NULL) {
   1977     return VFR_RETURN_GET_EFIVARSTORE_ERROR;
   1978   }
   1979 
   1980   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
   1981   Info->mVarTotalSize  = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
   1982   switch (Info->mVarTotalSize) {
   1983   case 1:
   1984     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
   1985     break;
   1986   case 2:
   1987     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
   1988     break;
   1989   case 4:
   1990     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
   1991     break;
   1992   case 8:
   1993     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
   1994     break;
   1995   default :
   1996     return VFR_RETURN_FATAL_ERROR;
   1997   }
   1998 
   1999   return VFR_RETURN_SUCCESS;
   2000 }
   2001 
   2002 EFI_VFR_RETURN_CODE
   2003 CVfrDataStorage::GetNameVarStoreInfo (
   2004   OUT EFI_VARSTORE_INFO  *Info,
   2005   IN  UINT32             Index
   2006   )
   2007 {
   2008   if (Info == NULL) {
   2009     return VFR_RETURN_FATAL_ERROR;
   2010   }
   2011 
   2012   if (mCurrVarStorageNode == NULL) {
   2013     return VFR_RETURN_GET_NVVARSTORE_ERROR;
   2014   }
   2015 
   2016   //
   2017   // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
   2018   //
   2019   if (VfrCompatibleMode) {
   2020     if (Index == 0) {
   2021       return VFR_RETURN_ERROR_ARRARY_NUM;
   2022     }
   2023     Index --;
   2024   }
   2025 
   2026   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
   2027 
   2028   return VFR_RETURN_SUCCESS;
   2029 }
   2030 
   2031 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
   2032   IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
   2033   IN CHAR8                *RefName,
   2034   IN EFI_STRING_ID        DefaultStoreNameId,
   2035   IN UINT16               DefaultId
   2036   )
   2037 {
   2038   mObjBinAddr = ObjBinAddr;
   2039 
   2040   if (RefName != NULL) {
   2041     mRefName          = new CHAR8[strlen (RefName) + 1];
   2042     strcpy (mRefName, RefName);
   2043   } else {
   2044     mRefName          = NULL;
   2045   }
   2046 
   2047   mNext               = NULL;
   2048   mDefaultId          = DefaultId;
   2049   mDefaultStoreNameId = DefaultStoreNameId;
   2050 }
   2051 
   2052 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
   2053   VOID
   2054   )
   2055 {
   2056   if (mRefName != NULL) {
   2057     delete mRefName;
   2058   }
   2059 }
   2060 
   2061 CVfrDefaultStore::CVfrDefaultStore (
   2062   VOID
   2063   )
   2064 {
   2065   mDefaultStoreList = NULL;
   2066 }
   2067 
   2068 CVfrDefaultStore::~CVfrDefaultStore (
   2069   VOID
   2070   )
   2071 {
   2072   SVfrDefaultStoreNode *pTmp = NULL;
   2073 
   2074   while (mDefaultStoreList != NULL) {
   2075     pTmp = mDefaultStoreList;
   2076     mDefaultStoreList = mDefaultStoreList->mNext;
   2077     delete pTmp;
   2078   }
   2079 }
   2080 
   2081 EFI_VFR_RETURN_CODE
   2082 CVfrDefaultStore::RegisterDefaultStore (
   2083   IN CHAR8                *ObjBinAddr,
   2084   IN CHAR8                *RefName,
   2085   IN EFI_STRING_ID        DefaultStoreNameId,
   2086   IN UINT16               DefaultId
   2087   )
   2088 {
   2089   SVfrDefaultStoreNode *pNode = NULL;
   2090 
   2091   if (RefName == NULL) {
   2092     return VFR_RETURN_FATAL_ERROR;
   2093   }
   2094 
   2095   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2096     if (strcmp (pNode->mRefName, RefName) == 0) {
   2097       return VFR_RETURN_REDEFINED;
   2098     }
   2099   }
   2100 
   2101   if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
   2102     return VFR_RETURN_OUT_FOR_RESOURCES;
   2103   }
   2104 
   2105   pNode->mNext               = mDefaultStoreList;
   2106   mDefaultStoreList          = pNode;
   2107 
   2108   return VFR_RETURN_SUCCESS;
   2109 }
   2110 
   2111 /*
   2112  * assign new reference name or new default store name id only if
   2113  * the original is invalid
   2114  */
   2115 EFI_VFR_RETURN_CODE
   2116 CVfrDefaultStore::ReRegisterDefaultStoreById (
   2117   IN UINT16          DefaultId,
   2118   IN CHAR8           *RefName,
   2119   IN EFI_STRING_ID   DefaultStoreNameId
   2120   )
   2121 {
   2122   SVfrDefaultStoreNode *pNode = NULL;
   2123 
   2124   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2125     if (pNode->mDefaultId == DefaultId) {
   2126       break;
   2127     }
   2128   }
   2129 
   2130   if (pNode == NULL) {
   2131     return VFR_RETURN_UNDEFINED;
   2132   } else {
   2133     if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
   2134       pNode->mDefaultStoreNameId  = DefaultStoreNameId;
   2135       if (pNode->mObjBinAddr != NULL) {
   2136         pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
   2137       }
   2138     } else {
   2139       return VFR_RETURN_REDEFINED;
   2140     }
   2141 
   2142     if (RefName != NULL) {
   2143       delete pNode->mRefName;
   2144       pNode->mRefName = new CHAR8[strlen (RefName) + 1];
   2145       if (pNode->mRefName != NULL) {
   2146         strcpy (pNode->mRefName, RefName);
   2147       }
   2148     }
   2149   }
   2150 
   2151   return VFR_RETURN_SUCCESS;
   2152 }
   2153 
   2154 BOOLEAN
   2155 CVfrDefaultStore::DefaultIdRegistered (
   2156   IN UINT16          DefaultId
   2157   )
   2158 {
   2159   SVfrDefaultStoreNode *pNode = NULL;
   2160 
   2161   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2162     if (pNode->mDefaultId == DefaultId) {
   2163       return TRUE;
   2164     }
   2165   }
   2166 
   2167   return FALSE;
   2168 }
   2169 
   2170 EFI_VFR_RETURN_CODE
   2171 CVfrDefaultStore::GetDefaultId (
   2172   IN  CHAR8           *RefName,
   2173   OUT UINT16          *DefaultId
   2174   )
   2175 {
   2176   SVfrDefaultStoreNode *pTmp = NULL;
   2177 
   2178   if (DefaultId == NULL) {
   2179     return VFR_RETURN_FATAL_ERROR;
   2180   }
   2181 
   2182   for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
   2183     if (strcmp (pTmp->mRefName, RefName) == 0) {
   2184       *DefaultId = pTmp->mDefaultId;
   2185       return VFR_RETURN_SUCCESS;
   2186     }
   2187   }
   2188 
   2189   return VFR_RETURN_UNDEFINED;
   2190 }
   2191 
   2192 EFI_VFR_RETURN_CODE
   2193 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
   2194   IN EFI_VARSTORE_ID    DefaultId,
   2195   IN EFI_VARSTORE_INFO  &Info,
   2196   IN CHAR8              *VarStoreName,
   2197   IN EFI_GUID           *VarStoreGuid,
   2198   IN UINT8              Type,
   2199   IN EFI_IFR_TYPE_VALUE Value
   2200   )
   2201 {
   2202   SVfrDefaultStoreNode  *pNode = NULL;
   2203   CHAR8                 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
   2204   INTN                  Returnvalue = 0;
   2205 
   2206   if (VarStoreName == NULL) {
   2207     return VFR_RETURN_FATAL_ERROR;
   2208   }
   2209 
   2210   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2211     if (pNode->mDefaultId == DefaultId) {
   2212       break;
   2213     }
   2214   }
   2215 
   2216   if (pNode == NULL) {
   2217     return VFR_RETURN_UNDEFINED;
   2218   }
   2219 
   2220   gCVfrBufferConfig.Open ();
   2221 
   2222   sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
   2223   if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
   2224     if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
   2225       goto WriteError;
   2226     }
   2227   }
   2228 
   2229   gCVfrBufferConfig.Close ();
   2230 
   2231   return VFR_RETURN_SUCCESS;
   2232 
   2233 WriteError:
   2234   gCVfrBufferConfig.Close ();
   2235   return (EFI_VFR_RETURN_CODE)Returnvalue;
   2236 }
   2237 
   2238 SVfrRuleNode::SVfrRuleNode (
   2239   IN CHAR8        *RuleName,
   2240   IN UINT8       RuleId
   2241   )
   2242 {
   2243   if (RuleName != NULL) {
   2244     mRuleName = new CHAR8[strlen (RuleName) + 1];
   2245     strcpy (mRuleName, RuleName);
   2246   } else {
   2247     mRuleName = NULL;
   2248   }
   2249 
   2250   mNext       = NULL;
   2251   mRuleId     = RuleId;
   2252 }
   2253 
   2254 SVfrRuleNode::~SVfrRuleNode (
   2255   VOID
   2256   )
   2257 {
   2258   if (mRuleName != NULL) {
   2259     delete mRuleName;
   2260   }
   2261 }
   2262 
   2263 CVfrRulesDB::CVfrRulesDB ()
   2264 {
   2265   mRuleList   = NULL;
   2266   mFreeRuleId = EFI_VARSTORE_ID_START;
   2267 }
   2268 
   2269 CVfrRulesDB::~CVfrRulesDB ()
   2270 {
   2271   SVfrRuleNode *pNode;
   2272 
   2273   while(mRuleList != NULL) {
   2274     pNode = mRuleList;
   2275     mRuleList = mRuleList->mNext;
   2276     delete pNode;
   2277   }
   2278 }
   2279 
   2280 VOID
   2281 CVfrRulesDB::RegisterRule (
   2282   IN CHAR8  *RuleName
   2283   )
   2284 {
   2285   SVfrRuleNode *pNew;
   2286 
   2287   if (RuleName == NULL) {
   2288     return ;
   2289   }
   2290 
   2291   if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
   2292     return ;
   2293   }
   2294 
   2295   mFreeRuleId++;
   2296 
   2297   pNew->mNext = mRuleList;
   2298   mRuleList   = pNew;
   2299 }
   2300 
   2301 UINT8
   2302 CVfrRulesDB::GetRuleId (
   2303   IN CHAR8  *RuleName
   2304   )
   2305 {
   2306   SVfrRuleNode *pNode;
   2307 
   2308   if (RuleName == NULL) {
   2309     return EFI_RULE_ID_INVALID;
   2310   }
   2311 
   2312   for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
   2313     if (strcmp (pNode->mRuleName, RuleName) == 0) {
   2314       return pNode->mRuleId;
   2315     }
   2316   }
   2317 
   2318   return EFI_RULE_ID_INVALID;
   2319 }
   2320 
   2321 CVfrRulesDB gCVfrRulesDB;
   2322 
   2323 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
   2324   VOID
   2325   )
   2326 {
   2327   mVarStoreId      = EFI_VARSTORE_ID_INVALID;
   2328   mInfo.mVarName   = EFI_STRING_ID_INVALID;
   2329   mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
   2330   mVarType         = EFI_IFR_TYPE_OTHER;
   2331   mVarTotalSize    = 0;
   2332 }
   2333 
   2334 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
   2335   IN EFI_VARSTORE_INFO &Info
   2336   )
   2337 {
   2338   mVarStoreId      = Info.mVarStoreId;
   2339   mInfo.mVarName   = Info.mInfo.mVarName;
   2340   mInfo.mVarOffset = Info.mInfo.mVarOffset;
   2341   mVarType         = Info.mVarType;
   2342   mVarTotalSize    = Info.mVarTotalSize;
   2343 }
   2344 
   2345 BOOLEAN
   2346 EFI_VARSTORE_INFO::operator == (
   2347   IN EFI_VARSTORE_INFO  *Info
   2348   )
   2349 {
   2350   if ((mVarStoreId == Info->mVarStoreId) &&
   2351   	  (mInfo.mVarName == Info->mInfo.mVarName) &&
   2352       (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
   2353       (mVarType == Info->mVarType) &&
   2354       (mVarTotalSize == Info->mVarTotalSize)) {
   2355     return TRUE;
   2356   }
   2357 
   2358   return FALSE;
   2359 }
   2360 
   2361 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
   2362 
   2363 EFI_QUESTION_ID
   2364 CVfrQuestionDB::GetFreeQuestionId (
   2365   VOID
   2366   )
   2367 {
   2368   UINT32  Index, Mask, Offset;
   2369 
   2370   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
   2371     if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
   2372       break;
   2373     }
   2374   }
   2375 
   2376   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
   2377     if ((mFreeQIdBitMap[Index] & Mask) == 0) {
   2378       mFreeQIdBitMap[Index] |= Mask;
   2379       return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
   2380     }
   2381   }
   2382 
   2383   return EFI_QUESTION_ID_INVALID;
   2384 }
   2385 
   2386 BOOLEAN
   2387 CVfrQuestionDB::ChekQuestionIdFree (
   2388   IN EFI_QUESTION_ID QId
   2389   )
   2390 {
   2391   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
   2392   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
   2393 
   2394   return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
   2395 }
   2396 
   2397 VOID
   2398 CVfrQuestionDB::MarkQuestionIdUsed (
   2399   IN EFI_QUESTION_ID QId
   2400   )
   2401 {
   2402   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
   2403   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
   2404 
   2405   mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
   2406 }
   2407 
   2408 VOID
   2409 CVfrQuestionDB::MarkQuestionIdUnused (
   2410   IN EFI_QUESTION_ID QId
   2411   )
   2412 {
   2413   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
   2414   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
   2415 
   2416   mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
   2417 }
   2418 
   2419 SVfrQuestionNode::SVfrQuestionNode (
   2420   IN CHAR8  *Name,
   2421   IN CHAR8  *VarIdStr,
   2422   IN UINT32 BitMask
   2423   )
   2424 {
   2425   mName       = NULL;
   2426   mVarIdStr   = NULL;
   2427   mQuestionId = EFI_QUESTION_ID_INVALID;
   2428   mBitMask    = BitMask;
   2429   mNext       = NULL;
   2430   mQtype      = QUESTION_NORMAL;
   2431 
   2432   if (Name == NULL) {
   2433     mName = new CHAR8[strlen ("$DEFAULT") + 1];
   2434     strcpy (mName, "$DEFAULT");
   2435   } else {
   2436     mName = new CHAR8[strlen (Name) + 1];
   2437     strcpy (mName, Name);
   2438   }
   2439 
   2440   if (VarIdStr != NULL) {
   2441     mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
   2442     strcpy (mVarIdStr, VarIdStr);
   2443   } else {
   2444     mVarIdStr = new CHAR8[strlen ("$") + 1];
   2445     strcpy (mVarIdStr, "$");
   2446   }
   2447 }
   2448 
   2449 SVfrQuestionNode::~SVfrQuestionNode (
   2450   VOID
   2451   )
   2452 {
   2453   if (mName != NULL) {
   2454     delete mName;
   2455   }
   2456 
   2457   if (mVarIdStr != NULL) {
   2458     delete mVarIdStr;
   2459   }
   2460 }
   2461 
   2462 CVfrQuestionDB::CVfrQuestionDB ()
   2463 {
   2464   UINT32 Index;
   2465 
   2466   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
   2467     mFreeQIdBitMap[Index] = 0;
   2468   }
   2469 
   2470   // Question ID 0 is reserved.
   2471   mFreeQIdBitMap[0] = 0x80000000;
   2472   mQuestionList     = NULL;
   2473 }
   2474 
   2475 CVfrQuestionDB::~CVfrQuestionDB ()
   2476 {
   2477   SVfrQuestionNode     *pNode;
   2478 
   2479   while (mQuestionList != NULL) {
   2480     pNode = mQuestionList;
   2481     mQuestionList = mQuestionList->mNext;
   2482     delete pNode;
   2483   }
   2484 }
   2485 
   2486 //
   2487 // Reset to init state
   2488 //
   2489 VOID
   2490 CVfrQuestionDB::ResetInit(
   2491   IN VOID
   2492   )
   2493 {
   2494   UINT32               Index;
   2495   SVfrQuestionNode     *pNode;
   2496 
   2497   while (mQuestionList != NULL) {
   2498     pNode = mQuestionList;
   2499     mQuestionList = mQuestionList->mNext;
   2500     delete pNode;
   2501   }
   2502 
   2503   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
   2504     mFreeQIdBitMap[Index] = 0;
   2505   }
   2506 
   2507   // Question ID 0 is reserved.
   2508   mFreeQIdBitMap[0] = 0x80000000;
   2509   mQuestionList     = NULL;
   2510 }
   2511 
   2512 VOID
   2513 CVfrQuestionDB::PrintAllQuestion (
   2514   VOID
   2515   )
   2516 {
   2517   SVfrQuestionNode *pNode = NULL;
   2518 
   2519   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   2520     printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
   2521   }
   2522 }
   2523 
   2524 EFI_VFR_RETURN_CODE
   2525 CVfrQuestionDB::RegisterQuestion (
   2526   IN     CHAR8             *Name,
   2527   IN     CHAR8             *VarIdStr,
   2528   IN OUT EFI_QUESTION_ID   &QuestionId
   2529   )
   2530 {
   2531   SVfrQuestionNode *pNode = NULL;
   2532 
   2533   if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
   2534     return VFR_RETURN_REDEFINED;
   2535   }
   2536 
   2537   if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
   2538     return VFR_RETURN_OUT_FOR_RESOURCES;
   2539   }
   2540 
   2541   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2542     QuestionId = GetFreeQuestionId ();
   2543   } else {
   2544     //
   2545     // For Framework Vfr, don't check question ID conflict.
   2546     //
   2547     if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
   2548       delete pNode;
   2549       return VFR_RETURN_QUESTIONID_REDEFINED;
   2550     }
   2551     MarkQuestionIdUsed (QuestionId);
   2552   }
   2553   pNode->mQuestionId = QuestionId;
   2554 
   2555   pNode->mNext       = mQuestionList;
   2556   mQuestionList      = pNode;
   2557 
   2558   gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2559 
   2560   return VFR_RETURN_SUCCESS;
   2561 }
   2562 
   2563 VOID
   2564 CVfrQuestionDB::RegisterOldDateQuestion (
   2565   IN     CHAR8            *YearVarId,
   2566   IN     CHAR8            *MonthVarId,
   2567   IN     CHAR8            *DayVarId,
   2568   IN OUT EFI_QUESTION_ID &QuestionId
   2569   )
   2570 {
   2571   SVfrQuestionNode *pNode[3] = {NULL, };
   2572   UINT32           Index;
   2573 
   2574   if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
   2575     return;
   2576   }
   2577 
   2578   if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
   2579     goto Err;
   2580   }
   2581   if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
   2582     goto Err;
   2583   }
   2584   if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
   2585     goto Err;
   2586   }
   2587 
   2588   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2589     QuestionId = GetFreeQuestionId ();
   2590   } else {
   2591     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2592       goto Err;
   2593     }
   2594     MarkQuestionIdUsed (QuestionId);
   2595   }
   2596 
   2597   pNode[0]->mQuestionId = QuestionId;
   2598   pNode[1]->mQuestionId = QuestionId;
   2599   pNode[2]->mQuestionId = QuestionId;
   2600   pNode[0]->mQtype      = QUESTION_DATE;
   2601   pNode[1]->mQtype      = QUESTION_DATE;
   2602   pNode[2]->mQtype      = QUESTION_DATE;
   2603   pNode[0]->mNext       = pNode[1];
   2604   pNode[1]->mNext       = pNode[2];
   2605   pNode[2]->mNext       = mQuestionList;
   2606   mQuestionList         = pNode[0];
   2607 
   2608   gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2609   gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2610   gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2611 
   2612   return;
   2613 
   2614 Err:
   2615   for (Index = 0; Index < 3; Index++) {
   2616     if (pNode[Index] != NULL) {
   2617       delete pNode[Index];
   2618     }
   2619   }
   2620   QuestionId = EFI_QUESTION_ID_INVALID;
   2621 }
   2622 
   2623 VOID
   2624 CVfrQuestionDB::RegisterNewDateQuestion (
   2625   IN     CHAR8            *Name,
   2626   IN     CHAR8            *BaseVarId,
   2627   IN OUT EFI_QUESTION_ID &QuestionId
   2628   )
   2629 {
   2630   SVfrQuestionNode     *pNode[3] = {NULL, };
   2631   UINT32               Len;
   2632   CHAR8                *VarIdStr[3] = {NULL, };
   2633   CHAR8                 Index;
   2634 
   2635   if (BaseVarId == NULL && Name == NULL) {
   2636     if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2637       QuestionId = GetFreeQuestionId ();
   2638     } else {
   2639       if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2640         goto Err;
   2641       }
   2642       MarkQuestionIdUsed (QuestionId);
   2643     }
   2644     return;
   2645   }
   2646 
   2647   if (BaseVarId != NULL) {
   2648     Len = strlen (BaseVarId);
   2649 
   2650     VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
   2651     if (VarIdStr[0] != NULL) {
   2652       strcpy (VarIdStr[0], BaseVarId);
   2653       strcat (VarIdStr[0], ".Year");
   2654     }
   2655     VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
   2656     if (VarIdStr[1] != NULL) {
   2657       strcpy (VarIdStr[1], BaseVarId);
   2658       strcat (VarIdStr[1], ".Month");
   2659     }
   2660     VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
   2661     if (VarIdStr[2] != NULL) {
   2662       strcpy (VarIdStr[2], BaseVarId);
   2663       strcat (VarIdStr[2], ".Day");
   2664     }
   2665   } else {
   2666     Len = strlen (Name);
   2667 
   2668     VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
   2669     if (VarIdStr[0] != NULL) {
   2670       strcpy (VarIdStr[0], Name);
   2671       strcat (VarIdStr[0], ".Year");
   2672     }
   2673     VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
   2674     if (VarIdStr[1] != NULL) {
   2675       strcpy (VarIdStr[1], Name);
   2676       strcat (VarIdStr[1], ".Month");
   2677     }
   2678     VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
   2679     if (VarIdStr[2] != NULL) {
   2680       strcpy (VarIdStr[2], Name);
   2681       strcat (VarIdStr[2], ".Day");
   2682     }
   2683   }
   2684 
   2685   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
   2686     goto Err;
   2687   }
   2688   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
   2689     goto Err;
   2690   }
   2691   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
   2692     goto Err;
   2693   }
   2694 
   2695   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2696     QuestionId = GetFreeQuestionId ();
   2697   } else {
   2698     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2699       goto Err;
   2700     }
   2701     MarkQuestionIdUsed (QuestionId);
   2702   }
   2703 
   2704   pNode[0]->mQuestionId = QuestionId;
   2705   pNode[1]->mQuestionId = QuestionId;
   2706   pNode[2]->mQuestionId = QuestionId;
   2707   pNode[0]->mQtype      = QUESTION_DATE;
   2708   pNode[1]->mQtype      = QUESTION_DATE;
   2709   pNode[2]->mQtype      = QUESTION_DATE;
   2710   pNode[0]->mNext       = pNode[1];
   2711   pNode[1]->mNext       = pNode[2];
   2712   pNode[2]->mNext       = mQuestionList;
   2713   mQuestionList         = pNode[0];
   2714 
   2715   for (Index = 0; Index < 3; Index++) {
   2716     if (VarIdStr[Index] != NULL) {
   2717       delete VarIdStr[Index];
   2718     }
   2719   }
   2720 
   2721   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2722   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2723   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2724 
   2725   return;
   2726 
   2727 Err:
   2728   for (Index = 0; Index < 3; Index++) {
   2729     if (pNode[Index] != NULL) {
   2730       delete pNode[Index];
   2731     }
   2732 
   2733     if (VarIdStr[Index] != NULL) {
   2734       delete VarIdStr[Index];
   2735     }
   2736   }
   2737 }
   2738 
   2739 VOID
   2740 CVfrQuestionDB::RegisterOldTimeQuestion (
   2741   IN     CHAR8            *HourVarId,
   2742   IN     CHAR8            *MinuteVarId,
   2743   IN     CHAR8            *SecondVarId,
   2744   IN OUT EFI_QUESTION_ID &QuestionId
   2745   )
   2746 {
   2747   SVfrQuestionNode *pNode[3] = {NULL, };
   2748   UINT32           Index;
   2749 
   2750   if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
   2751     return;
   2752   }
   2753 
   2754   if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
   2755     goto Err;
   2756   }
   2757   if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
   2758     goto Err;
   2759   }
   2760   if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
   2761     goto Err;
   2762   }
   2763 
   2764   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2765     QuestionId = GetFreeQuestionId ();
   2766   } else {
   2767     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2768       goto Err;
   2769     }
   2770     MarkQuestionIdUsed (QuestionId);
   2771   }
   2772 
   2773   pNode[0]->mQuestionId = QuestionId;
   2774   pNode[1]->mQuestionId = QuestionId;
   2775   pNode[2]->mQuestionId = QuestionId;
   2776   pNode[0]->mQtype      = QUESTION_TIME;
   2777   pNode[1]->mQtype      = QUESTION_TIME;
   2778   pNode[2]->mQtype      = QUESTION_TIME;
   2779   pNode[0]->mNext       = pNode[1];
   2780   pNode[1]->mNext       = pNode[2];
   2781   pNode[2]->mNext       = mQuestionList;
   2782   mQuestionList         = pNode[0];
   2783 
   2784   gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2785   gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2786   gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2787 
   2788   return;
   2789 
   2790 Err:
   2791   for (Index = 0; Index < 3; Index++) {
   2792     if (pNode[Index] != NULL) {
   2793       delete pNode[Index];
   2794     }
   2795   }
   2796   QuestionId = EFI_QUESTION_ID_INVALID;
   2797 }
   2798 
   2799 VOID
   2800 CVfrQuestionDB::RegisterNewTimeQuestion (
   2801   IN     CHAR8           *Name,
   2802   IN     CHAR8           *BaseVarId,
   2803   IN OUT EFI_QUESTION_ID &QuestionId
   2804   )
   2805 {
   2806   SVfrQuestionNode     *pNode[3] = {NULL, };
   2807   UINT32               Len;
   2808   CHAR8                *VarIdStr[3] = {NULL, };
   2809   CHAR8                 Index;
   2810 
   2811   if (BaseVarId == NULL && Name == NULL) {
   2812     if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2813       QuestionId = GetFreeQuestionId ();
   2814     } else {
   2815       if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2816         goto Err;
   2817       }
   2818       MarkQuestionIdUsed (QuestionId);
   2819     }
   2820     return;
   2821   }
   2822 
   2823   if (BaseVarId != NULL) {
   2824     Len = strlen (BaseVarId);
   2825 
   2826     VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
   2827     if (VarIdStr[0] != NULL) {
   2828       strcpy (VarIdStr[0], BaseVarId);
   2829       strcat (VarIdStr[0], ".Hour");
   2830     }
   2831     VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
   2832     if (VarIdStr[1] != NULL) {
   2833       strcpy (VarIdStr[1], BaseVarId);
   2834       strcat (VarIdStr[1], ".Minute");
   2835     }
   2836     VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
   2837     if (VarIdStr[2] != NULL) {
   2838       strcpy (VarIdStr[2], BaseVarId);
   2839       strcat (VarIdStr[2], ".Second");
   2840     }
   2841   } else {
   2842     Len = strlen (Name);
   2843 
   2844     VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
   2845     if (VarIdStr[0] != NULL) {
   2846       strcpy (VarIdStr[0], Name);
   2847       strcat (VarIdStr[0], ".Hour");
   2848     }
   2849     VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
   2850     if (VarIdStr[1] != NULL) {
   2851       strcpy (VarIdStr[1], Name);
   2852       strcat (VarIdStr[1], ".Minute");
   2853     }
   2854     VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
   2855     if (VarIdStr[2] != NULL) {
   2856       strcpy (VarIdStr[2], Name);
   2857       strcat (VarIdStr[2], ".Second");
   2858     }
   2859   }
   2860 
   2861   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
   2862     goto Err;
   2863   }
   2864   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
   2865     goto Err;
   2866   }
   2867   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
   2868     goto Err;
   2869   }
   2870 
   2871   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2872     QuestionId = GetFreeQuestionId ();
   2873   } else {
   2874     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2875       goto Err;
   2876     }
   2877     MarkQuestionIdUsed (QuestionId);
   2878   }
   2879 
   2880   pNode[0]->mQuestionId = QuestionId;
   2881   pNode[1]->mQuestionId = QuestionId;
   2882   pNode[2]->mQuestionId = QuestionId;
   2883   pNode[0]->mQtype      = QUESTION_TIME;
   2884   pNode[1]->mQtype      = QUESTION_TIME;
   2885   pNode[2]->mQtype      = QUESTION_TIME;
   2886   pNode[0]->mNext       = pNode[1];
   2887   pNode[1]->mNext       = pNode[2];
   2888   pNode[2]->mNext       = mQuestionList;
   2889   mQuestionList         = pNode[0];
   2890 
   2891   for (Index = 0; Index < 3; Index++) {
   2892     if (VarIdStr[Index] != NULL) {
   2893       delete VarIdStr[Index];
   2894     }
   2895   }
   2896 
   2897   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2898   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2899   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2900 
   2901   return;
   2902 
   2903 Err:
   2904   for (Index = 0; Index < 3; Index++) {
   2905     if (pNode[Index] != NULL) {
   2906       delete pNode[Index];
   2907     }
   2908 
   2909     if (VarIdStr[Index] != NULL) {
   2910       delete VarIdStr[Index];
   2911     }
   2912   }
   2913 }
   2914 
   2915 VOID
   2916 CVfrQuestionDB::RegisterRefQuestion (
   2917   IN     CHAR8           *Name,
   2918   IN     CHAR8           *BaseVarId,
   2919   IN OUT EFI_QUESTION_ID &QuestionId
   2920   )
   2921 {
   2922   SVfrQuestionNode     *pNode[4] = {NULL, };
   2923   UINT32               Len;
   2924   CHAR8                *VarIdStr[4] = {NULL, };
   2925   CHAR8                 Index;
   2926 
   2927   if (BaseVarId == NULL && Name == NULL) {
   2928     return;
   2929   }
   2930 
   2931   if (BaseVarId != NULL) {
   2932     Len = strlen (BaseVarId);
   2933 
   2934     VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
   2935     if (VarIdStr[0] != NULL) {
   2936       strcpy (VarIdStr[0], BaseVarId);
   2937       strcat (VarIdStr[0], ".QuestionId");
   2938     }
   2939     VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
   2940     if (VarIdStr[1] != NULL) {
   2941       strcpy (VarIdStr[1], BaseVarId);
   2942       strcat (VarIdStr[1], ".FormId");
   2943     }
   2944     VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
   2945     if (VarIdStr[2] != NULL) {
   2946       strcpy (VarIdStr[2], BaseVarId);
   2947       strcat (VarIdStr[2], ".FormSetGuid");
   2948     }
   2949     VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
   2950     if (VarIdStr[3] != NULL) {
   2951       strcpy (VarIdStr[3], BaseVarId);
   2952       strcat (VarIdStr[3], ".DevicePath");
   2953     }
   2954   } else {
   2955     Len = strlen (Name);
   2956 
   2957     VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
   2958     if (VarIdStr[0] != NULL) {
   2959       strcpy (VarIdStr[0], Name);
   2960       strcat (VarIdStr[0], ".QuestionId");
   2961     }
   2962     VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
   2963     if (VarIdStr[1] != NULL) {
   2964       strcpy (VarIdStr[1], Name);
   2965       strcat (VarIdStr[1], ".FormId");
   2966     }
   2967     VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
   2968     if (VarIdStr[2] != NULL) {
   2969       strcpy (VarIdStr[2], Name);
   2970       strcat (VarIdStr[2], ".FormSetGuid");
   2971     }
   2972     VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
   2973     if (VarIdStr[3] != NULL) {
   2974       strcpy (VarIdStr[3], Name);
   2975       strcat (VarIdStr[3], ".DevicePath");
   2976     }
   2977   }
   2978 
   2979   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
   2980     goto Err;
   2981   }
   2982   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
   2983     goto Err;
   2984   }
   2985   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
   2986     goto Err;
   2987   }
   2988   if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
   2989     goto Err;
   2990   }
   2991 
   2992   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2993     QuestionId = GetFreeQuestionId ();
   2994   } else {
   2995     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2996       goto Err;
   2997     }
   2998     MarkQuestionIdUsed (QuestionId);
   2999   }
   3000 
   3001   pNode[0]->mQuestionId = QuestionId;
   3002   pNode[1]->mQuestionId = QuestionId;
   3003   pNode[2]->mQuestionId = QuestionId;
   3004   pNode[3]->mQuestionId = QuestionId;
   3005   pNode[0]->mQtype      = QUESTION_REF;
   3006   pNode[1]->mQtype      = QUESTION_REF;
   3007   pNode[2]->mQtype      = QUESTION_REF;
   3008   pNode[3]->mQtype      = QUESTION_REF;
   3009   pNode[0]->mNext       = pNode[1];
   3010   pNode[1]->mNext       = pNode[2];
   3011   pNode[2]->mNext       = pNode[3];
   3012   pNode[3]->mNext       = mQuestionList;
   3013   mQuestionList         = pNode[0];
   3014 
   3015   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3016   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3017   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3018   gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3019 
   3020   return;
   3021 
   3022   Err:
   3023   for (Index = 0; Index < 4; Index++) {
   3024     if (pNode[Index] != NULL) {
   3025       delete pNode[Index];
   3026     }
   3027 
   3028     if (VarIdStr[Index] != NULL) {
   3029       delete VarIdStr[Index];
   3030     }
   3031   }
   3032 }
   3033 
   3034 EFI_VFR_RETURN_CODE
   3035 CVfrQuestionDB::UpdateQuestionId (
   3036   IN EFI_QUESTION_ID   QId,
   3037   IN EFI_QUESTION_ID   NewQId
   3038   )
   3039 {
   3040   SVfrQuestionNode *pNode = NULL;
   3041 
   3042   if (QId == NewQId) {
   3043     // don't update
   3044     return VFR_RETURN_SUCCESS;
   3045   }
   3046 
   3047   //
   3048   // For Framework Vfr, don't check question ID conflict.
   3049   //
   3050   if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
   3051     return VFR_RETURN_REDEFINED;
   3052   }
   3053 
   3054   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3055     if (pNode->mQuestionId == QId) {
   3056       break;
   3057     }
   3058   }
   3059 
   3060   if (pNode == NULL) {
   3061     return VFR_RETURN_UNDEFINED;
   3062   }
   3063 
   3064   MarkQuestionIdUnused (QId);
   3065   pNode->mQuestionId = NewQId;
   3066   MarkQuestionIdUsed (NewQId);
   3067 
   3068   gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
   3069 
   3070   return VFR_RETURN_SUCCESS;
   3071 }
   3072 
   3073 VOID
   3074 CVfrQuestionDB::GetQuestionId (
   3075   IN  CHAR8             *Name,
   3076   IN  CHAR8             *VarIdStr,
   3077   OUT EFI_QUESTION_ID   &QuestionId,
   3078   OUT UINT32            &BitMask,
   3079   OUT EFI_QUESION_TYPE  *QType
   3080   )
   3081 {
   3082   SVfrQuestionNode *pNode;
   3083 
   3084   QuestionId = EFI_QUESTION_ID_INVALID;
   3085   BitMask    = 0x00000000;
   3086   if (QType != NULL) {
   3087     *QType = QUESTION_NORMAL;
   3088   }
   3089 
   3090   if ((Name == NULL) && (VarIdStr == NULL)) {
   3091     return ;
   3092   }
   3093 
   3094   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3095     if (Name != NULL) {
   3096       if (strcmp (pNode->mName, Name) != 0) {
   3097         continue;
   3098       }
   3099     }
   3100 
   3101     if (VarIdStr != NULL) {
   3102       if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
   3103         continue;
   3104       }
   3105   	}
   3106 
   3107     QuestionId = pNode->mQuestionId;
   3108     BitMask    = pNode->mBitMask;
   3109     if (QType != NULL) {
   3110       *QType     = pNode->mQtype;
   3111     }
   3112     break;
   3113   }
   3114 
   3115   return ;
   3116 }
   3117 
   3118 EFI_VFR_RETURN_CODE
   3119 CVfrQuestionDB::FindQuestion (
   3120   IN EFI_QUESTION_ID QuestionId
   3121   )
   3122 {
   3123   SVfrQuestionNode *pNode;
   3124 
   3125   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   3126     return VFR_RETURN_INVALID_PARAMETER;
   3127   }
   3128 
   3129   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3130     if (pNode->mQuestionId == QuestionId) {
   3131       return VFR_RETURN_SUCCESS;
   3132     }
   3133   }
   3134 
   3135   return VFR_RETURN_UNDEFINED;
   3136 }
   3137 
   3138 EFI_VFR_RETURN_CODE
   3139 CVfrQuestionDB::FindQuestion (
   3140   IN CHAR8 *Name
   3141   )
   3142 {
   3143   SVfrQuestionNode *pNode;
   3144 
   3145   if (Name == NULL) {
   3146     return VFR_RETURN_FATAL_ERROR;
   3147   }
   3148 
   3149   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3150     if (strcmp (pNode->mName, Name) == 0) {
   3151       return VFR_RETURN_SUCCESS;
   3152     }
   3153   }
   3154 
   3155   return VFR_RETURN_UNDEFINED;
   3156 }
   3157 
   3158 CVfrStringDB::CVfrStringDB ()
   3159 {
   3160   mStringFileName = NULL;
   3161 }
   3162 
   3163 CVfrStringDB::~CVfrStringDB ()
   3164 {
   3165   if (mStringFileName != NULL) {
   3166     delete mStringFileName;
   3167   }
   3168   mStringFileName = NULL;
   3169 }
   3170 
   3171 
   3172 VOID
   3173 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
   3174 {
   3175   UINT32 FileLen = 0;
   3176 
   3177   if (StringFileName == NULL) {
   3178     return;
   3179   }
   3180 
   3181   FileLen = strlen (StringFileName) + 1;
   3182   mStringFileName = new CHAR8[FileLen];
   3183   if (mStringFileName == NULL) {
   3184     return;
   3185   }
   3186 
   3187   strcpy (mStringFileName, StringFileName);
   3188   mStringFileName[FileLen - 1] = '\0';
   3189 }
   3190 
   3191 
   3192 /**
   3193   Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
   3194   from a set of supported languages.
   3195 
   3196   @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string that
   3197                                   contains a set of language codes.
   3198   @param[in]  Language            A variable that contains pointers to Null-terminated
   3199                                   ASCII strings that contain one language codes.
   3200 
   3201   @retval FALSE   The best matching language could not be found in SupportedLanguages.
   3202   @retval TRUE    The best matching language could be found in SupportedLanguages.
   3203 
   3204 **/
   3205 BOOLEAN
   3206 CVfrStringDB::GetBestLanguage (
   3207   IN CONST CHAR8  *SupportedLanguages,
   3208   IN CHAR8        *Language
   3209   )
   3210 {
   3211   UINTN        CompareLength;
   3212   UINTN        LanguageLength;
   3213   CONST CHAR8  *Supported;
   3214 
   3215   if (SupportedLanguages == NULL || Language == NULL){
   3216     return FALSE;
   3217   }
   3218 
   3219   //
   3220   // Determine the length of the first RFC 4646 language code in Language
   3221   //
   3222   for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
   3223 
   3224   //
   3225   // Trim back the length of Language used until it is empty
   3226   //
   3227   while (LanguageLength > 0) {
   3228     //
   3229     // Loop through all language codes in SupportedLanguages
   3230     //
   3231     for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
   3232       //
   3233       // Skip ';' characters in Supported
   3234       //
   3235       for (; *Supported != '\0' && *Supported == ';'; Supported++);
   3236       //
   3237       // Determine the length of the next language code in Supported
   3238       //
   3239       for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
   3240       //
   3241       // If Language is longer than the Supported, then skip to the next language
   3242       //
   3243       if (LanguageLength > CompareLength) {
   3244         continue;
   3245       }
   3246 
   3247       //
   3248       // See if the first LanguageLength characters in Supported match Language
   3249       //
   3250       if (strncmp (Supported, Language, LanguageLength) == 0) {
   3251         return TRUE;
   3252       }
   3253     }
   3254 
   3255     //
   3256     // Trim Language from the right to the next '-' character
   3257     //
   3258     for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
   3259   }
   3260 
   3261   //
   3262   // No matches were found
   3263   //
   3264   return FALSE;
   3265 }
   3266 
   3267 
   3268 CHAR8 *
   3269 CVfrStringDB::GetVarStoreNameFormStringId (
   3270   IN EFI_STRING_ID StringId
   3271   )
   3272 {
   3273   FILE        *pInFile    = NULL;
   3274   UINT32      NameOffset;
   3275   UINT32      Length;
   3276   UINT8       *StringPtr;
   3277   CHAR8       *StringName;
   3278   CHAR16      *UnicodeString;
   3279   CHAR8       *VarStoreName = NULL;
   3280   CHAR8       *DestTmp;
   3281   UINT8       *Current;
   3282   EFI_STATUS  Status;
   3283   CHAR8       LineBuf[EFI_IFR_MAX_LENGTH];
   3284   UINT8       BlockType;
   3285   EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
   3286 
   3287   if (mStringFileName == '\0' ) {
   3288     return NULL;
   3289   }
   3290 
   3291   if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
   3292     return NULL;
   3293   }
   3294 
   3295   //
   3296   // Get file length.
   3297   //
   3298   fseek (pInFile, 0, SEEK_END);
   3299   Length = ftell (pInFile);
   3300   fseek (pInFile, 0, SEEK_SET);
   3301 
   3302   //
   3303   // Get file data.
   3304   //
   3305   StringPtr = new UINT8[Length];
   3306   if (StringPtr == NULL) {
   3307     fclose (pInFile);
   3308     return NULL;
   3309   }
   3310   fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
   3311   fclose (pInFile);
   3312 
   3313   PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
   3314   //
   3315   // Check the String package.
   3316   //
   3317   if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
   3318     delete StringPtr;
   3319     return NULL;
   3320   }
   3321 
   3322   //
   3323   // Search the language, get best language base on RFC 4647 matching algorithm.
   3324   //
   3325   Current = StringPtr;
   3326   while (!GetBestLanguage ("en", PkgHeader->Language)) {
   3327     Current += PkgHeader->Header.Length;
   3328     PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
   3329     //
   3330     // If can't find string package base on language, just return the first string package.
   3331     //
   3332     if (Current - StringPtr >= Length) {
   3333       Current = StringPtr;
   3334       PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
   3335       break;
   3336     }
   3337   }
   3338 
   3339   Current += PkgHeader->HdrSize;
   3340   //
   3341   // Find the string block according the stringId.
   3342   //
   3343   Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
   3344   if (Status != EFI_SUCCESS) {
   3345     delete StringPtr;
   3346     return NULL;
   3347   }
   3348 
   3349   //
   3350   // Get varstore name according the string type.
   3351   //
   3352   switch (BlockType) {
   3353   case EFI_HII_SIBT_STRING_SCSU:
   3354   case EFI_HII_SIBT_STRING_SCSU_FONT:
   3355   case EFI_HII_SIBT_STRINGS_SCSU:
   3356   case EFI_HII_SIBT_STRINGS_SCSU_FONT:
   3357     StringName = (CHAR8*)(Current + NameOffset);
   3358     VarStoreName = new CHAR8[strlen(StringName) + 1];
   3359     strcpy (VarStoreName, StringName);
   3360     break;
   3361   case EFI_HII_SIBT_STRING_UCS2:
   3362   case EFI_HII_SIBT_STRING_UCS2_FONT:
   3363   case EFI_HII_SIBT_STRINGS_UCS2:
   3364   case EFI_HII_SIBT_STRINGS_UCS2_FONT:
   3365     UnicodeString = (CHAR16*)(Current + NameOffset);
   3366     Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
   3367     DestTmp = new CHAR8[Length / 2 + 1];
   3368     VarStoreName = DestTmp;
   3369     while (*UnicodeString != '\0') {
   3370       *(DestTmp++) = (CHAR8) *(UnicodeString++);
   3371     }
   3372     *DestTmp = '\0';
   3373     break;
   3374   default:
   3375     break;
   3376   }
   3377 
   3378   delete StringPtr;
   3379 
   3380   return VarStoreName;
   3381 }
   3382 
   3383 EFI_STATUS
   3384 CVfrStringDB::FindStringBlock (
   3385   IN  UINT8                           *StringData,
   3386   IN  EFI_STRING_ID                   StringId,
   3387   OUT UINT32                          *StringTextOffset,
   3388   OUT UINT8                           *BlockType
   3389   )
   3390 {
   3391   UINT8                                *BlockHdr;
   3392   EFI_STRING_ID                        CurrentStringId;
   3393   UINT32                               BlockSize;
   3394   UINT32                               Index;
   3395   UINT8                                *StringTextPtr;
   3396   UINT32                               Offset;
   3397   UINT16                               StringCount;
   3398   UINT16                               SkipCount;
   3399   UINT8                                Length8;
   3400   EFI_HII_SIBT_EXT2_BLOCK              Ext2;
   3401   UINT32                               Length32;
   3402   UINT32                               StringSize;
   3403 
   3404   CurrentStringId = 1;
   3405 
   3406   //
   3407   // Parse the string blocks to get the string text and font.
   3408   //
   3409   BlockHdr  = StringData;
   3410   BlockSize = 0;
   3411   Offset    = 0;
   3412   while (*BlockHdr != EFI_HII_SIBT_END) {
   3413     switch (*BlockHdr) {
   3414     case EFI_HII_SIBT_STRING_SCSU:
   3415       Offset = sizeof (EFI_HII_STRING_BLOCK);
   3416       StringTextPtr = BlockHdr + Offset;
   3417       BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
   3418       CurrentStringId++;
   3419       break;
   3420 
   3421     case EFI_HII_SIBT_STRING_SCSU_FONT:
   3422       Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
   3423       StringTextPtr = BlockHdr + Offset;
   3424       BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
   3425       CurrentStringId++;
   3426       break;
   3427 
   3428     case EFI_HII_SIBT_STRINGS_SCSU:
   3429       memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
   3430       StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
   3431       BlockSize += StringTextPtr - BlockHdr;
   3432 
   3433       for (Index = 0; Index < StringCount; Index++) {
   3434         BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
   3435         if (CurrentStringId == StringId) {
   3436           *BlockType        = *BlockHdr;
   3437           *StringTextOffset = StringTextPtr - StringData;
   3438           return EFI_SUCCESS;
   3439         }
   3440         StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
   3441         CurrentStringId++;
   3442       }
   3443       break;
   3444 
   3445     case EFI_HII_SIBT_STRINGS_SCSU_FONT:
   3446       memcpy (
   3447         &StringCount,
   3448         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3449         sizeof (UINT16)
   3450         );
   3451       StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
   3452       BlockSize += StringTextPtr - BlockHdr;
   3453 
   3454       for (Index = 0; Index < StringCount; Index++) {
   3455         BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
   3456         if (CurrentStringId == StringId) {
   3457           *BlockType        = *BlockHdr;
   3458           *StringTextOffset = StringTextPtr - StringData;
   3459           return EFI_SUCCESS;
   3460         }
   3461         StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
   3462         CurrentStringId++;
   3463       }
   3464       break;
   3465 
   3466     case EFI_HII_SIBT_STRING_UCS2:
   3467       Offset        = sizeof (EFI_HII_STRING_BLOCK);
   3468       StringTextPtr = BlockHdr + Offset;
   3469       //
   3470       // Use StringSize to store the size of the specified string, including the NULL
   3471       // terminator.
   3472       //
   3473       StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3474       BlockSize += Offset + StringSize;
   3475       CurrentStringId++;
   3476       break;
   3477 
   3478     case EFI_HII_SIBT_STRING_UCS2_FONT:
   3479       Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
   3480       StringTextPtr = BlockHdr + Offset;
   3481       //
   3482       // Use StrSize to store the size of the specified string, including the NULL
   3483       // terminator.
   3484       //
   3485       StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3486       BlockSize += Offset + StringSize;
   3487       CurrentStringId++;
   3488       break;
   3489 
   3490     case EFI_HII_SIBT_STRINGS_UCS2:
   3491       Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
   3492       StringTextPtr = BlockHdr + Offset;
   3493       BlockSize += Offset;
   3494       memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
   3495       for (Index = 0; Index < StringCount; Index++) {
   3496         StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3497         BlockSize += StringSize;
   3498         if (CurrentStringId == StringId) {
   3499           *BlockType        = *BlockHdr;
   3500           *StringTextOffset = StringTextPtr - StringData;
   3501           return EFI_SUCCESS;
   3502         }
   3503         StringTextPtr = StringTextPtr + StringSize;
   3504         CurrentStringId++;
   3505       }
   3506       break;
   3507 
   3508     case EFI_HII_SIBT_STRINGS_UCS2_FONT:
   3509       Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
   3510       StringTextPtr = BlockHdr + Offset;
   3511       BlockSize += Offset;
   3512       memcpy (
   3513         &StringCount,
   3514         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3515         sizeof (UINT16)
   3516         );
   3517       for (Index = 0; Index < StringCount; Index++) {
   3518         StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3519         BlockSize += StringSize;
   3520         if (CurrentStringId == StringId) {
   3521           *BlockType        = *BlockHdr;
   3522           *StringTextOffset = StringTextPtr - StringData;
   3523           return EFI_SUCCESS;
   3524         }
   3525         StringTextPtr = StringTextPtr + StringSize;
   3526         CurrentStringId++;
   3527       }
   3528       break;
   3529 
   3530     case EFI_HII_SIBT_DUPLICATE:
   3531       if (CurrentStringId == StringId) {
   3532         //
   3533         // Incoming StringId is an id of a duplicate string block.
   3534         // Update the StringId to be the previous string block.
   3535         // Go back to the header of string block to search.
   3536         //
   3537         memcpy (
   3538           &StringId,
   3539           BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
   3540           sizeof (EFI_STRING_ID)
   3541           );
   3542         CurrentStringId = 1;
   3543         BlockSize       = 0;
   3544       } else {
   3545         BlockSize       += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
   3546         CurrentStringId++;
   3547       }
   3548       break;
   3549 
   3550     case EFI_HII_SIBT_SKIP1:
   3551       SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
   3552       CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
   3553       BlockSize       +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
   3554       break;
   3555 
   3556     case EFI_HII_SIBT_SKIP2:
   3557       memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
   3558       CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
   3559       BlockSize       +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
   3560       break;
   3561 
   3562     case EFI_HII_SIBT_EXT1:
   3563       memcpy (
   3564         &Length8,
   3565         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3566         sizeof (UINT8)
   3567         );
   3568       BlockSize += Length8;
   3569       break;
   3570 
   3571     case EFI_HII_SIBT_EXT2:
   3572       memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
   3573       BlockSize += Ext2.Length;
   3574       break;
   3575 
   3576     case EFI_HII_SIBT_EXT4:
   3577       memcpy (
   3578         &Length32,
   3579         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3580         sizeof (UINT32)
   3581         );
   3582 
   3583       BlockSize += Length32;
   3584       break;
   3585 
   3586     default:
   3587       break;
   3588     }
   3589 
   3590     if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
   3591       *StringTextOffset = BlockHdr - StringData + Offset;
   3592       *BlockType        = *BlockHdr;
   3593 
   3594       if (StringId == CurrentStringId - 1) {
   3595         //
   3596         // if only one skip item, return EFI_NOT_FOUND.
   3597         //
   3598         if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
   3599           return EFI_NOT_FOUND;
   3600         } else {
   3601           return EFI_SUCCESS;
   3602         }
   3603       }
   3604 
   3605       if (StringId < CurrentStringId - 1) {
   3606         return EFI_NOT_FOUND;
   3607       }
   3608     }
   3609     BlockHdr  = StringData + BlockSize;
   3610   }
   3611 
   3612   return EFI_NOT_FOUND;
   3613 }
   3614 
   3615 UINT32
   3616 CVfrStringDB::GetUnicodeStringTextSize (
   3617   IN  UINT8            *StringSrc
   3618   )
   3619 {
   3620   UINT32 StringSize;
   3621   CHAR16 *StringPtr;
   3622 
   3623   StringSize = sizeof (CHAR16);
   3624   StringPtr  = (UINT16*)StringSrc;
   3625   while (*StringPtr++ != L'\0') {
   3626     StringSize += sizeof (CHAR16);
   3627   }
   3628 
   3629   return StringSize;
   3630 }
   3631 
   3632 BOOLEAN  VfrCompatibleMode = FALSE;
   3633 
   3634 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
   3635 
   3636 
   3637