Home | History | Annotate | Download | only in VfrCompile
      1 /** @file
      2 
      3   Vfr common library functions.
      4 
      5 Copyright (c) 2004 - 2016, 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   ARRAY_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   ARRAY_SAFE_FREE (mName);
    204   ARRAY_SAFE_FREE (mGuid);
    205   ARRAY_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 (&mGuid, 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 (&mGuid, 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   mBufferFieldInfoListHead = NULL;
   1423   mBufferFieldInfoListTail = NULL;
   1424 }
   1425 
   1426 CVfrDataStorage::~CVfrDataStorage (
   1427   VOID
   1428   )
   1429 {
   1430   SVfrVarStorageNode *pNode;
   1431 
   1432   while (mBufferVarStoreList != NULL) {
   1433     pNode = mBufferVarStoreList;
   1434     mBufferVarStoreList = mBufferVarStoreList->mNext;
   1435     delete pNode;
   1436   }
   1437   while (mEfiVarStoreList != NULL) {
   1438     pNode = mEfiVarStoreList;
   1439     mEfiVarStoreList = mEfiVarStoreList->mNext;
   1440     delete pNode;
   1441   }
   1442   while (mNameVarStoreList != NULL) {
   1443     pNode = mNameVarStoreList;
   1444     mNameVarStoreList = mNameVarStoreList->mNext;
   1445     delete pNode;
   1446   }
   1447   if (mNewVarStorageNode != NULL) {
   1448     delete mNewVarStorageNode;
   1449   }
   1450 }
   1451 
   1452 EFI_VARSTORE_ID
   1453 CVfrDataStorage::GetFreeVarStoreId (
   1454   EFI_VFR_VARSTORE_TYPE VarType
   1455   )
   1456 {
   1457   UINT32  Index, Mask, Offset;
   1458 
   1459   //
   1460   // Assign the different ID range for the different type VarStore to support Framework Vfr
   1461   //
   1462   Index = 0;
   1463   if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
   1464     Index = 0;
   1465   } else if (VarType == EFI_VFR_VARSTORE_EFI) {
   1466     Index = 1;
   1467   } else if (VarType == EFI_VFR_VARSTORE_NAME) {
   1468     Index = 2;
   1469   }
   1470 
   1471   for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
   1472     if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
   1473       break;
   1474     }
   1475   }
   1476 
   1477   if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {
   1478     return EFI_VARSTORE_ID_INVALID;
   1479   }
   1480 
   1481   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
   1482     if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
   1483       mFreeVarStoreIdBitMap[Index] |= Mask;
   1484       return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
   1485     }
   1486   }
   1487 
   1488   return EFI_VARSTORE_ID_INVALID;
   1489 }
   1490 
   1491 BOOLEAN
   1492 CVfrDataStorage::ChekVarStoreIdFree (
   1493   IN EFI_VARSTORE_ID VarStoreId
   1494   )
   1495 {
   1496   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
   1497   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
   1498 
   1499   return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
   1500 }
   1501 
   1502 VOID
   1503 CVfrDataStorage::MarkVarStoreIdUsed (
   1504   IN EFI_VARSTORE_ID VarStoreId
   1505   )
   1506 {
   1507   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
   1508   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
   1509 
   1510   mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
   1511 }
   1512 
   1513 VOID
   1514 CVfrDataStorage::MarkVarStoreIdUnused (
   1515   IN EFI_VARSTORE_ID VarStoreId
   1516   )
   1517 {
   1518   UINT32 Index  = (VarStoreId / EFI_BITS_PER_UINT32);
   1519   UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
   1520 
   1521   mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
   1522 }
   1523 
   1524 EFI_VFR_RETURN_CODE
   1525 CVfrDataStorage::DeclareNameVarStoreBegin (
   1526   IN CHAR8           *StoreName,
   1527   IN EFI_VARSTORE_ID VarStoreId
   1528   )
   1529 {
   1530   SVfrVarStorageNode *pNode = NULL;
   1531   EFI_VARSTORE_ID    TmpVarStoreId;
   1532 
   1533   if (StoreName == NULL) {
   1534     return VFR_RETURN_FATAL_ERROR;
   1535   }
   1536 
   1537   if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
   1538     return VFR_RETURN_REDEFINED;
   1539   }
   1540 
   1541   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1542     VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
   1543   } else {
   1544     if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
   1545       return VFR_RETURN_VARSTOREID_REDEFINED;
   1546     }
   1547     MarkVarStoreIdUsed (VarStoreId);
   1548   }
   1549 
   1550   if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
   1551     return VFR_RETURN_UNDEFINED;
   1552   }
   1553 
   1554   mNewVarStorageNode = pNode;
   1555 
   1556   return VFR_RETURN_SUCCESS;
   1557 }
   1558 
   1559 EFI_VFR_RETURN_CODE
   1560 CVfrDataStorage::NameTableAddItem (
   1561   IN EFI_STRING_ID  Item
   1562   )
   1563 {
   1564   EFI_VARSTORE_ID *NewTable, *OldTable;
   1565   UINT32          TableSize;
   1566 
   1567   OldTable  = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
   1568   TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
   1569 
   1570   if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
   1571     if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
   1572       return VFR_RETURN_OUT_FOR_RESOURCES;
   1573     }
   1574     memcpy (NewTable, OldTable, TableSize);
   1575     mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
   1576   }
   1577 
   1578   mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
   1579   mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
   1580 
   1581   return VFR_RETURN_SUCCESS;
   1582 }
   1583 
   1584 EFI_VFR_RETURN_CODE
   1585 CVfrDataStorage::DeclareNameVarStoreEnd (
   1586   IN EFI_GUID *Guid
   1587   )
   1588 {
   1589   mNewVarStorageNode->mGuid = *Guid;
   1590   mNewVarStorageNode->mNext = mNameVarStoreList;
   1591   mNameVarStoreList         = mNewVarStorageNode;
   1592 
   1593   mNewVarStorageNode        = NULL;
   1594 
   1595   return VFR_RETURN_SUCCESS;
   1596 }
   1597 
   1598 EFI_VFR_RETURN_CODE
   1599 CVfrDataStorage::DeclareEfiVarStore (
   1600   IN CHAR8          *StoreName,
   1601   IN EFI_GUID       *Guid,
   1602   IN EFI_STRING_ID  NameStrId,
   1603   IN UINT32         VarSize,
   1604   IN BOOLEAN        Flag
   1605   )
   1606 {
   1607   SVfrVarStorageNode *pNode;
   1608   EFI_VARSTORE_ID    VarStoreId;
   1609 
   1610   if ((StoreName == NULL) || (Guid == NULL)) {
   1611     return VFR_RETURN_FATAL_ERROR;
   1612   }
   1613 
   1614   if (VarSize > sizeof (UINT64)) {
   1615     return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
   1616   }
   1617 
   1618   if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
   1619     return VFR_RETURN_REDEFINED;
   1620   }
   1621 
   1622   VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
   1623   if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
   1624     return VFR_RETURN_OUT_FOR_RESOURCES;
   1625   }
   1626 
   1627   pNode->mNext       = mEfiVarStoreList;
   1628   mEfiVarStoreList   = pNode;
   1629 
   1630   return VFR_RETURN_SUCCESS;
   1631 }
   1632 
   1633 EFI_VFR_RETURN_CODE
   1634 CVfrDataStorage::DeclareBufferVarStore (
   1635   IN CHAR8             *StoreName,
   1636   IN EFI_GUID          *Guid,
   1637   IN CVfrVarDataTypeDB *DataTypeDB,
   1638   IN CHAR8             *TypeName,
   1639   IN EFI_VARSTORE_ID   VarStoreId,
   1640   IN BOOLEAN           Flag
   1641   )
   1642 {
   1643   SVfrVarStorageNode   *pNew = NULL;
   1644   SVfrDataType         *pDataType = NULL;
   1645   EFI_VARSTORE_ID      TempVarStoreId;
   1646 
   1647   if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
   1648     return VFR_RETURN_FATAL_ERROR;
   1649   }
   1650 
   1651   if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
   1652     return VFR_RETURN_REDEFINED;
   1653   }
   1654 
   1655   CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
   1656 
   1657   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1658     VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
   1659   } else {
   1660     if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
   1661       return VFR_RETURN_VARSTOREID_REDEFINED;
   1662     }
   1663     MarkVarStoreIdUsed (VarStoreId);
   1664   }
   1665 
   1666   if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {
   1667     return VFR_RETURN_OUT_FOR_RESOURCES;
   1668   }
   1669 
   1670   pNew->mNext         = mBufferVarStoreList;
   1671   mBufferVarStoreList = pNew;
   1672 
   1673   if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
   1674     return VFR_RETURN_FATAL_ERROR;
   1675   }
   1676 
   1677   return VFR_RETURN_SUCCESS;
   1678 }
   1679 
   1680 EFI_VFR_RETURN_CODE
   1681 CVfrDataStorage::GetVarStoreByDataType (
   1682   IN  CHAR8              *DataTypeName,
   1683   OUT SVfrVarStorageNode **VarNode,
   1684   IN  EFI_GUID           *VarGuid
   1685   )
   1686 {
   1687   SVfrVarStorageNode    *pNode;
   1688   SVfrVarStorageNode    *MatchNode;
   1689 
   1690   //
   1691   // Framework VFR uses Data type name as varstore name, so don't need check again.
   1692   //
   1693   if (VfrCompatibleMode) {
   1694     return VFR_RETURN_UNDEFINED;
   1695   }
   1696 
   1697   MatchNode = NULL;
   1698   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1699     if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
   1700       continue;
   1701     }
   1702 
   1703     if ((VarGuid != NULL)) {
   1704       if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
   1705         *VarNode = pNode;
   1706         return VFR_RETURN_SUCCESS;
   1707       }
   1708     } else {
   1709       if (MatchNode == NULL) {
   1710         MatchNode = pNode;
   1711       } else {
   1712         //
   1713         // More than one varstores referred the same data structures.
   1714         //
   1715         return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
   1716       }
   1717     }
   1718   }
   1719 
   1720   if (MatchNode == NULL) {
   1721     return VFR_RETURN_UNDEFINED;
   1722   }
   1723 
   1724   *VarNode = MatchNode;
   1725   return VFR_RETURN_SUCCESS;
   1726 }
   1727 
   1728 EFI_VARSTORE_ID
   1729 CVfrDataStorage::CheckGuidField (
   1730   IN  SVfrVarStorageNode   *pNode,
   1731   IN  EFI_GUID             *StoreGuid,
   1732   IN  BOOLEAN              *HasFoundOne,
   1733   OUT EFI_VFR_RETURN_CODE  *ReturnCode
   1734   )
   1735 {
   1736   if (StoreGuid != NULL) {
   1737     //
   1738     // If has guid info, compare the guid filed.
   1739     //
   1740     if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
   1741       //
   1742       // Both name and guid are same, this this varstore.
   1743       //
   1744       mCurrVarStorageNode = pNode;
   1745       *ReturnCode = VFR_RETURN_SUCCESS;
   1746       return TRUE;
   1747     }
   1748   } else {
   1749     //
   1750     // Not has Guid field, check whether this name is the only one.
   1751     //
   1752     if (*HasFoundOne) {
   1753       //
   1754       // The name has conflict, return name redefined.
   1755       //
   1756       *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
   1757       return TRUE;
   1758     }
   1759 
   1760     *HasFoundOne = TRUE;
   1761     mCurrVarStorageNode = pNode;
   1762   }
   1763 
   1764   return FALSE;
   1765 }
   1766 
   1767 /**
   1768   Base on the input store name and guid to find the varstore id.
   1769 
   1770   If both name and guid are inputed, base on the name and guid to
   1771   found the varstore. If only name inputed, base on the name to
   1772   found the varstore and go on to check whether more than one varstore
   1773   has the same name. If only has found one varstore, return this
   1774   varstore; if more than one varstore has same name, return varstore
   1775   name redefined error. If no varstore found by varstore name, call
   1776   function GetVarStoreByDataType and use inputed varstore name as
   1777   data type name to search.
   1778 **/
   1779 EFI_VFR_RETURN_CODE
   1780 CVfrDataStorage::GetVarStoreId (
   1781   IN  CHAR8           *StoreName,
   1782   OUT EFI_VARSTORE_ID *VarStoreId,
   1783   IN  EFI_GUID        *StoreGuid
   1784   )
   1785 {
   1786   EFI_VFR_RETURN_CODE   ReturnCode;
   1787   SVfrVarStorageNode    *pNode;
   1788   BOOLEAN               HasFoundOne = FALSE;
   1789 
   1790   mCurrVarStorageNode = NULL;
   1791 
   1792   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1793     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
   1794       if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
   1795         *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1796         return ReturnCode;
   1797       }
   1798     }
   1799   }
   1800 
   1801   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1802     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
   1803       if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
   1804         *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1805         return ReturnCode;
   1806       }
   1807     }
   1808   }
   1809 
   1810   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1811     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
   1812       if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
   1813         *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1814         return ReturnCode;
   1815       }
   1816     }
   1817   }
   1818 
   1819   if (HasFoundOne) {
   1820     *VarStoreId = mCurrVarStorageNode->mVarStoreId;
   1821     return VFR_RETURN_SUCCESS;
   1822   }
   1823 
   1824   *VarStoreId         = EFI_VARSTORE_ID_INVALID;
   1825 
   1826   //
   1827   // Assume that Data strucutre name is used as StoreName, and check again.
   1828   //
   1829   ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
   1830   if (pNode != NULL) {
   1831     mCurrVarStorageNode = pNode;
   1832     *VarStoreId = pNode->mVarStoreId;
   1833   }
   1834 
   1835   return ReturnCode;
   1836 }
   1837 
   1838 EFI_VFR_RETURN_CODE
   1839 CVfrDataStorage::GetBufferVarStoreDataTypeName (
   1840   IN  EFI_VARSTORE_ID        VarStoreId,
   1841   OUT CHAR8                  **DataTypeName
   1842   )
   1843 {
   1844   SVfrVarStorageNode    *pNode;
   1845 
   1846   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1847     return VFR_RETURN_FATAL_ERROR;
   1848   }
   1849 
   1850   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1851     if (pNode->mVarStoreId == VarStoreId) {
   1852       *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
   1853       return VFR_RETURN_SUCCESS;
   1854     }
   1855   }
   1856 
   1857   return VFR_RETURN_UNDEFINED;
   1858 }
   1859 
   1860 EFI_VFR_VARSTORE_TYPE
   1861 CVfrDataStorage::GetVarStoreType (
   1862   IN  EFI_VARSTORE_ID        VarStoreId
   1863   )
   1864 {
   1865   SVfrVarStorageNode    *pNode;
   1866   EFI_VFR_VARSTORE_TYPE VarStoreType;
   1867 
   1868   VarStoreType = EFI_VFR_VARSTORE_INVALID;
   1869 
   1870   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1871     return VarStoreType;
   1872   }
   1873 
   1874   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1875     if (pNode->mVarStoreId == VarStoreId) {
   1876       VarStoreType = pNode->mVarStoreType;
   1877       return VarStoreType;
   1878     }
   1879   }
   1880 
   1881   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1882     if (pNode->mVarStoreId == VarStoreId) {
   1883       VarStoreType = pNode->mVarStoreType;
   1884       return VarStoreType;
   1885     }
   1886   }
   1887 
   1888   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1889     if (pNode->mVarStoreId == VarStoreId) {
   1890       VarStoreType = pNode->mVarStoreType;
   1891       return VarStoreType;
   1892     }
   1893   }
   1894 
   1895   return VarStoreType;
   1896 }
   1897 
   1898 EFI_GUID *
   1899 CVfrDataStorage::GetVarStoreGuid (
   1900   IN  EFI_VARSTORE_ID        VarStoreId
   1901   )
   1902 {
   1903   SVfrVarStorageNode    *pNode;
   1904   EFI_GUID              *VarGuid;
   1905 
   1906   VarGuid = NULL;
   1907 
   1908   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
   1909     return VarGuid;
   1910   }
   1911 
   1912   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1913     if (pNode->mVarStoreId == VarStoreId) {
   1914       VarGuid = &pNode->mGuid;
   1915       return VarGuid;
   1916     }
   1917   }
   1918 
   1919   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1920     if (pNode->mVarStoreId == VarStoreId) {
   1921       VarGuid = &pNode->mGuid;
   1922       return VarGuid;
   1923     }
   1924   }
   1925 
   1926   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1927     if (pNode->mVarStoreId == VarStoreId) {
   1928       VarGuid = &pNode->mGuid;
   1929       return VarGuid;
   1930     }
   1931   }
   1932 
   1933   return VarGuid;
   1934 }
   1935 
   1936 EFI_VFR_RETURN_CODE
   1937 CVfrDataStorage::GetVarStoreName (
   1938   IN  EFI_VARSTORE_ID VarStoreId,
   1939   OUT CHAR8           **VarStoreName
   1940   )
   1941 {
   1942   SVfrVarStorageNode    *pNode;
   1943 
   1944   if (VarStoreName == NULL) {
   1945     return VFR_RETURN_FATAL_ERROR;
   1946   }
   1947 
   1948   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1949     if (pNode->mVarStoreId == VarStoreId) {
   1950       *VarStoreName = pNode->mVarStoreName;
   1951       return VFR_RETURN_SUCCESS;
   1952     }
   1953   }
   1954 
   1955   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1956     if (pNode->mVarStoreId == VarStoreId) {
   1957       *VarStoreName = pNode->mVarStoreName;
   1958       return VFR_RETURN_SUCCESS;
   1959     }
   1960   }
   1961 
   1962   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
   1963     if (pNode->mVarStoreId == VarStoreId) {
   1964       *VarStoreName = pNode->mVarStoreName;
   1965       return VFR_RETURN_SUCCESS;
   1966     }
   1967   }
   1968 
   1969   *VarStoreName = NULL;
   1970   return VFR_RETURN_UNDEFINED;
   1971 }
   1972 
   1973 EFI_VFR_RETURN_CODE
   1974 CVfrDataStorage::GetEfiVarStoreInfo (
   1975   IN OUT EFI_VARSTORE_INFO  *Info
   1976   )
   1977 {
   1978   if (Info == NULL) {
   1979     return VFR_RETURN_FATAL_ERROR;
   1980   }
   1981 
   1982   if (mCurrVarStorageNode == NULL) {
   1983     return VFR_RETURN_GET_EFIVARSTORE_ERROR;
   1984   }
   1985 
   1986   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
   1987   Info->mVarTotalSize  = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
   1988   switch (Info->mVarTotalSize) {
   1989   case 1:
   1990     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
   1991     break;
   1992   case 2:
   1993     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
   1994     break;
   1995   case 4:
   1996     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
   1997     break;
   1998   case 8:
   1999     Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
   2000     break;
   2001   default :
   2002     return VFR_RETURN_FATAL_ERROR;
   2003   }
   2004 
   2005   return VFR_RETURN_SUCCESS;
   2006 }
   2007 
   2008 EFI_VFR_RETURN_CODE
   2009 CVfrDataStorage::AddBufferVarStoreFieldInfo (
   2010   IN EFI_VARSTORE_INFO  *Info
   2011   )
   2012 {
   2013   BufferVarStoreFieldInfoNode *pNew;
   2014 
   2015   if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
   2016     return VFR_RETURN_FATAL_ERROR;
   2017   }
   2018 
   2019   if (mBufferFieldInfoListHead == NULL) {
   2020     mBufferFieldInfoListHead = pNew;
   2021     mBufferFieldInfoListTail= pNew;
   2022   } else {
   2023     mBufferFieldInfoListTail->mNext = pNew;
   2024     mBufferFieldInfoListTail = pNew;
   2025   }
   2026 
   2027   return VFR_RETURN_SUCCESS;
   2028 }
   2029 
   2030 EFI_VFR_RETURN_CODE
   2031 CVfrDataStorage::GetBufferVarStoreFieldInfo (
   2032   IN OUT EFI_VARSTORE_INFO  *Info
   2033   )
   2034 {
   2035   BufferVarStoreFieldInfoNode *pNode;
   2036 
   2037   pNode = mBufferFieldInfoListHead;
   2038   while (pNode != NULL) {
   2039     if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
   2040       Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
   2041       Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
   2042       Info->mVarType      = pNode->mVarStoreInfo.mVarType;
   2043       return VFR_RETURN_SUCCESS;
   2044     }
   2045     pNode = pNode->mNext;
   2046   }
   2047   return VFR_RETURN_FATAL_ERROR;
   2048 }
   2049 
   2050 EFI_VFR_RETURN_CODE
   2051 CVfrDataStorage::GetNameVarStoreInfo (
   2052   OUT EFI_VARSTORE_INFO  *Info,
   2053   IN  UINT32             Index
   2054   )
   2055 {
   2056   if (Info == NULL) {
   2057     return VFR_RETURN_FATAL_ERROR;
   2058   }
   2059 
   2060   if (mCurrVarStorageNode == NULL) {
   2061     return VFR_RETURN_GET_NVVARSTORE_ERROR;
   2062   }
   2063 
   2064   //
   2065   // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
   2066   //
   2067   if (VfrCompatibleMode) {
   2068     if (Index == 0) {
   2069       return VFR_RETURN_ERROR_ARRARY_NUM;
   2070     }
   2071     Index --;
   2072   }
   2073 
   2074   Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
   2075 
   2076   return VFR_RETURN_SUCCESS;
   2077 }
   2078 
   2079 SVfrDefaultStoreNode::SVfrDefaultStoreNode (
   2080   IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
   2081   IN CHAR8                *RefName,
   2082   IN EFI_STRING_ID        DefaultStoreNameId,
   2083   IN UINT16               DefaultId
   2084   )
   2085 {
   2086   mObjBinAddr = ObjBinAddr;
   2087 
   2088   if (RefName != NULL) {
   2089     mRefName          = new CHAR8[strlen (RefName) + 1];
   2090     strcpy (mRefName, RefName);
   2091   } else {
   2092     mRefName          = NULL;
   2093   }
   2094 
   2095   mNext               = NULL;
   2096   mDefaultId          = DefaultId;
   2097   mDefaultStoreNameId = DefaultStoreNameId;
   2098 }
   2099 
   2100 SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
   2101   VOID
   2102   )
   2103 {
   2104   if (mRefName != NULL) {
   2105     delete[] mRefName;
   2106   }
   2107 }
   2108 
   2109 CVfrDefaultStore::CVfrDefaultStore (
   2110   VOID
   2111   )
   2112 {
   2113   mDefaultStoreList = NULL;
   2114 }
   2115 
   2116 CVfrDefaultStore::~CVfrDefaultStore (
   2117   VOID
   2118   )
   2119 {
   2120   SVfrDefaultStoreNode *pTmp = NULL;
   2121 
   2122   while (mDefaultStoreList != NULL) {
   2123     pTmp = mDefaultStoreList;
   2124     mDefaultStoreList = mDefaultStoreList->mNext;
   2125     delete pTmp;
   2126   }
   2127 }
   2128 
   2129 EFI_VFR_RETURN_CODE
   2130 CVfrDefaultStore::RegisterDefaultStore (
   2131   IN CHAR8                *ObjBinAddr,
   2132   IN CHAR8                *RefName,
   2133   IN EFI_STRING_ID        DefaultStoreNameId,
   2134   IN UINT16               DefaultId
   2135   )
   2136 {
   2137   SVfrDefaultStoreNode *pNode = NULL;
   2138 
   2139   if (RefName == NULL) {
   2140     return VFR_RETURN_FATAL_ERROR;
   2141   }
   2142 
   2143   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2144     if (strcmp (pNode->mRefName, RefName) == 0) {
   2145       return VFR_RETURN_REDEFINED;
   2146     }
   2147   }
   2148 
   2149   if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
   2150     return VFR_RETURN_OUT_FOR_RESOURCES;
   2151   }
   2152 
   2153   pNode->mNext               = mDefaultStoreList;
   2154   mDefaultStoreList          = pNode;
   2155 
   2156   return VFR_RETURN_SUCCESS;
   2157 }
   2158 
   2159 /*
   2160  * assign new reference name or new default store name id only if
   2161  * the original is invalid
   2162  */
   2163 EFI_VFR_RETURN_CODE
   2164 CVfrDefaultStore::ReRegisterDefaultStoreById (
   2165   IN UINT16          DefaultId,
   2166   IN CHAR8           *RefName,
   2167   IN EFI_STRING_ID   DefaultStoreNameId
   2168   )
   2169 {
   2170   SVfrDefaultStoreNode *pNode = NULL;
   2171 
   2172   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2173     if (pNode->mDefaultId == DefaultId) {
   2174       break;
   2175     }
   2176   }
   2177 
   2178   if (pNode == NULL) {
   2179     return VFR_RETURN_UNDEFINED;
   2180   } else {
   2181     if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
   2182       pNode->mDefaultStoreNameId  = DefaultStoreNameId;
   2183       if (pNode->mObjBinAddr != NULL) {
   2184         pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
   2185       }
   2186     } else {
   2187       return VFR_RETURN_REDEFINED;
   2188     }
   2189 
   2190     if (RefName != NULL) {
   2191       delete pNode->mRefName;
   2192       pNode->mRefName = new CHAR8[strlen (RefName) + 1];
   2193       if (pNode->mRefName != NULL) {
   2194         strcpy (pNode->mRefName, RefName);
   2195       }
   2196     }
   2197   }
   2198 
   2199   return VFR_RETURN_SUCCESS;
   2200 }
   2201 
   2202 BOOLEAN
   2203 CVfrDefaultStore::DefaultIdRegistered (
   2204   IN UINT16          DefaultId
   2205   )
   2206 {
   2207   SVfrDefaultStoreNode *pNode = NULL;
   2208 
   2209   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2210     if (pNode->mDefaultId == DefaultId) {
   2211       return TRUE;
   2212     }
   2213   }
   2214 
   2215   return FALSE;
   2216 }
   2217 
   2218 EFI_VFR_RETURN_CODE
   2219 CVfrDefaultStore::GetDefaultId (
   2220   IN  CHAR8           *RefName,
   2221   OUT UINT16          *DefaultId
   2222   )
   2223 {
   2224   SVfrDefaultStoreNode *pTmp = NULL;
   2225 
   2226   if (DefaultId == NULL) {
   2227     return VFR_RETURN_FATAL_ERROR;
   2228   }
   2229 
   2230   for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
   2231     if (strcmp (pTmp->mRefName, RefName) == 0) {
   2232       *DefaultId = pTmp->mDefaultId;
   2233       return VFR_RETURN_SUCCESS;
   2234     }
   2235   }
   2236 
   2237   return VFR_RETURN_UNDEFINED;
   2238 }
   2239 
   2240 EFI_VFR_RETURN_CODE
   2241 CVfrDefaultStore::BufferVarStoreAltConfigAdd (
   2242   IN EFI_VARSTORE_ID    DefaultId,
   2243   IN EFI_VARSTORE_INFO  &Info,
   2244   IN CHAR8              *VarStoreName,
   2245   IN EFI_GUID           *VarStoreGuid,
   2246   IN UINT8              Type,
   2247   IN EFI_IFR_TYPE_VALUE Value
   2248   )
   2249 {
   2250   SVfrDefaultStoreNode  *pNode = NULL;
   2251   CHAR8                 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
   2252   INTN                  Returnvalue = 0;
   2253 
   2254   if (VarStoreName == NULL) {
   2255     return VFR_RETURN_FATAL_ERROR;
   2256   }
   2257 
   2258   for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
   2259     if (pNode->mDefaultId == DefaultId) {
   2260       break;
   2261     }
   2262   }
   2263 
   2264   if (pNode == NULL) {
   2265     return VFR_RETURN_UNDEFINED;
   2266   }
   2267 
   2268   gCVfrBufferConfig.Open ();
   2269 
   2270   sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
   2271   if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
   2272     if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
   2273       goto WriteError;
   2274     }
   2275   }
   2276 
   2277   gCVfrBufferConfig.Close ();
   2278 
   2279   return VFR_RETURN_SUCCESS;
   2280 
   2281 WriteError:
   2282   gCVfrBufferConfig.Close ();
   2283   return (EFI_VFR_RETURN_CODE)Returnvalue;
   2284 }
   2285 
   2286 SVfrRuleNode::SVfrRuleNode (
   2287   IN CHAR8        *RuleName,
   2288   IN UINT8       RuleId
   2289   )
   2290 {
   2291   if (RuleName != NULL) {
   2292     mRuleName = new CHAR8[strlen (RuleName) + 1];
   2293     strcpy (mRuleName, RuleName);
   2294   } else {
   2295     mRuleName = NULL;
   2296   }
   2297 
   2298   mNext       = NULL;
   2299   mRuleId     = RuleId;
   2300 }
   2301 
   2302 SVfrRuleNode::~SVfrRuleNode (
   2303   VOID
   2304   )
   2305 {
   2306   if (mRuleName != NULL) {
   2307     delete[] mRuleName;
   2308   }
   2309 }
   2310 
   2311 CVfrRulesDB::CVfrRulesDB ()
   2312 {
   2313   mRuleList   = NULL;
   2314   mFreeRuleId = EFI_VARSTORE_ID_START;
   2315 }
   2316 
   2317 CVfrRulesDB::~CVfrRulesDB ()
   2318 {
   2319   SVfrRuleNode *pNode;
   2320 
   2321   while(mRuleList != NULL) {
   2322     pNode = mRuleList;
   2323     mRuleList = mRuleList->mNext;
   2324     delete pNode;
   2325   }
   2326 }
   2327 
   2328 VOID
   2329 CVfrRulesDB::RegisterRule (
   2330   IN CHAR8  *RuleName
   2331   )
   2332 {
   2333   SVfrRuleNode *pNew;
   2334 
   2335   if (RuleName == NULL) {
   2336     return ;
   2337   }
   2338 
   2339   if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
   2340     return ;
   2341   }
   2342 
   2343   mFreeRuleId++;
   2344 
   2345   pNew->mNext = mRuleList;
   2346   mRuleList   = pNew;
   2347 }
   2348 
   2349 UINT8
   2350 CVfrRulesDB::GetRuleId (
   2351   IN CHAR8  *RuleName
   2352   )
   2353 {
   2354   SVfrRuleNode *pNode;
   2355 
   2356   if (RuleName == NULL) {
   2357     return EFI_RULE_ID_INVALID;
   2358   }
   2359 
   2360   for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
   2361     if (strcmp (pNode->mRuleName, RuleName) == 0) {
   2362       return pNode->mRuleId;
   2363     }
   2364   }
   2365 
   2366   return EFI_RULE_ID_INVALID;
   2367 }
   2368 
   2369 CVfrRulesDB gCVfrRulesDB;
   2370 
   2371 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
   2372   VOID
   2373   )
   2374 {
   2375   mVarStoreId      = EFI_VARSTORE_ID_INVALID;
   2376   mInfo.mVarName   = EFI_STRING_ID_INVALID;
   2377   mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
   2378   mVarType         = EFI_IFR_TYPE_OTHER;
   2379   mVarTotalSize    = 0;
   2380 }
   2381 
   2382 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
   2383   IN EFI_VARSTORE_INFO &Info
   2384   )
   2385 {
   2386   mVarStoreId      = Info.mVarStoreId;
   2387   mInfo.mVarName   = Info.mInfo.mVarName;
   2388   mInfo.mVarOffset = Info.mInfo.mVarOffset;
   2389   mVarType         = Info.mVarType;
   2390   mVarTotalSize    = Info.mVarTotalSize;
   2391 }
   2392 
   2393 EFI_VARSTORE_INFO&
   2394 EFI_VARSTORE_INFO::operator= (
   2395   IN CONST EFI_VARSTORE_INFO &Info
   2396   )
   2397 {
   2398   if (this != &Info) {
   2399     mVarStoreId      = Info.mVarStoreId;
   2400     mInfo.mVarName   = Info.mInfo.mVarName;
   2401     mInfo.mVarOffset = Info.mInfo.mVarOffset;
   2402     mVarType         = Info.mVarType;
   2403     mVarTotalSize    = Info.mVarTotalSize;
   2404   }
   2405 
   2406   return *this;
   2407 }
   2408 
   2409 BOOLEAN
   2410 EFI_VARSTORE_INFO::operator == (
   2411   IN EFI_VARSTORE_INFO  *Info
   2412   )
   2413 {
   2414   if ((mVarStoreId == Info->mVarStoreId) &&
   2415   	  (mInfo.mVarName == Info->mInfo.mVarName) &&
   2416       (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
   2417       (mVarType == Info->mVarType) &&
   2418       (mVarTotalSize == Info->mVarTotalSize)) {
   2419     return TRUE;
   2420   }
   2421 
   2422   return FALSE;
   2423 }
   2424 
   2425 BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
   2426   IN EFI_VARSTORE_INFO  *Info
   2427   )
   2428 {
   2429   mVarStoreInfo.mVarType               = Info->mVarType;
   2430   mVarStoreInfo.mVarTotalSize          = Info->mVarTotalSize;
   2431   mVarStoreInfo.mInfo.mVarOffset       = Info->mInfo.mVarOffset;
   2432   mVarStoreInfo.mVarStoreId            = Info->mVarStoreId;
   2433   mNext = NULL;
   2434 }
   2435 
   2436 BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
   2437 {
   2438   mVarStoreInfo.mVarType               = EFI_IFR_TYPE_OTHER;
   2439   mVarStoreInfo.mVarTotalSize          = 0;
   2440   mVarStoreInfo.mInfo.mVarOffset       = EFI_VAROFFSET_INVALID;
   2441   mVarStoreInfo.mVarStoreId            = EFI_VARSTORE_ID_INVALID;
   2442   mNext = NULL;
   2443 }
   2444 
   2445 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
   2446 
   2447 EFI_QUESTION_ID
   2448 CVfrQuestionDB::GetFreeQuestionId (
   2449   VOID
   2450   )
   2451 {
   2452   UINT32  Index, Mask, Offset;
   2453 
   2454   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
   2455     if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
   2456       break;
   2457     }
   2458   }
   2459 
   2460   if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {
   2461     return EFI_QUESTION_ID_INVALID;
   2462   }
   2463 
   2464   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
   2465     if ((mFreeQIdBitMap[Index] & Mask) == 0) {
   2466       mFreeQIdBitMap[Index] |= Mask;
   2467       return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
   2468     }
   2469   }
   2470 
   2471   return EFI_QUESTION_ID_INVALID;
   2472 }
   2473 
   2474 BOOLEAN
   2475 CVfrQuestionDB::ChekQuestionIdFree (
   2476   IN EFI_QUESTION_ID QId
   2477   )
   2478 {
   2479   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
   2480   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
   2481 
   2482   return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
   2483 }
   2484 
   2485 VOID
   2486 CVfrQuestionDB::MarkQuestionIdUsed (
   2487   IN EFI_QUESTION_ID QId
   2488   )
   2489 {
   2490   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
   2491   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
   2492 
   2493   mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
   2494 }
   2495 
   2496 VOID
   2497 CVfrQuestionDB::MarkQuestionIdUnused (
   2498   IN EFI_QUESTION_ID QId
   2499   )
   2500 {
   2501   UINT32 Index  = (QId / EFI_BITS_PER_UINT32);
   2502   UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
   2503 
   2504   mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
   2505 }
   2506 
   2507 SVfrQuestionNode::SVfrQuestionNode (
   2508   IN CHAR8  *Name,
   2509   IN CHAR8  *VarIdStr,
   2510   IN UINT32 BitMask
   2511   )
   2512 {
   2513   mName       = NULL;
   2514   mVarIdStr   = NULL;
   2515   mQuestionId = EFI_QUESTION_ID_INVALID;
   2516   mBitMask    = BitMask;
   2517   mNext       = NULL;
   2518   mQtype      = QUESTION_NORMAL;
   2519 
   2520   if (Name == NULL) {
   2521     mName = new CHAR8[strlen ("$DEFAULT") + 1];
   2522     strcpy (mName, "$DEFAULT");
   2523   } else {
   2524     mName = new CHAR8[strlen (Name) + 1];
   2525     strcpy (mName, Name);
   2526   }
   2527 
   2528   if (VarIdStr != NULL) {
   2529     mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
   2530     strcpy (mVarIdStr, VarIdStr);
   2531   } else {
   2532     mVarIdStr = new CHAR8[strlen ("$") + 1];
   2533     strcpy (mVarIdStr, "$");
   2534   }
   2535 }
   2536 
   2537 SVfrQuestionNode::~SVfrQuestionNode (
   2538   VOID
   2539   )
   2540 {
   2541   if (mName != NULL) {
   2542     delete[] mName;
   2543   }
   2544 
   2545   if (mVarIdStr != NULL) {
   2546     delete[] mVarIdStr;
   2547   }
   2548 }
   2549 
   2550 CVfrQuestionDB::CVfrQuestionDB ()
   2551 {
   2552   UINT32 Index;
   2553 
   2554   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
   2555     mFreeQIdBitMap[Index] = 0;
   2556   }
   2557 
   2558   // Question ID 0 is reserved.
   2559   mFreeQIdBitMap[0] = 0x80000000;
   2560   mQuestionList     = NULL;
   2561 }
   2562 
   2563 CVfrQuestionDB::~CVfrQuestionDB ()
   2564 {
   2565   SVfrQuestionNode     *pNode;
   2566 
   2567   while (mQuestionList != NULL) {
   2568     pNode = mQuestionList;
   2569     mQuestionList = mQuestionList->mNext;
   2570     delete pNode;
   2571   }
   2572 }
   2573 
   2574 //
   2575 // Reset to init state
   2576 //
   2577 VOID
   2578 CVfrQuestionDB::ResetInit(
   2579   IN VOID
   2580   )
   2581 {
   2582   UINT32               Index;
   2583   SVfrQuestionNode     *pNode;
   2584 
   2585   while (mQuestionList != NULL) {
   2586     pNode = mQuestionList;
   2587     mQuestionList = mQuestionList->mNext;
   2588     delete pNode;
   2589   }
   2590 
   2591   for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
   2592     mFreeQIdBitMap[Index] = 0;
   2593   }
   2594 
   2595   // Question ID 0 is reserved.
   2596   mFreeQIdBitMap[0] = 0x80000000;
   2597   mQuestionList     = NULL;
   2598 }
   2599 
   2600 VOID
   2601 CVfrQuestionDB::PrintAllQuestion (
   2602   VOID
   2603   )
   2604 {
   2605   SVfrQuestionNode *pNode = NULL;
   2606 
   2607   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   2608     printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
   2609   }
   2610 }
   2611 
   2612 EFI_VFR_RETURN_CODE
   2613 CVfrQuestionDB::RegisterQuestion (
   2614   IN     CHAR8             *Name,
   2615   IN     CHAR8             *VarIdStr,
   2616   IN OUT EFI_QUESTION_ID   &QuestionId
   2617   )
   2618 {
   2619   SVfrQuestionNode *pNode = NULL;
   2620 
   2621   if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
   2622     return VFR_RETURN_REDEFINED;
   2623   }
   2624 
   2625   if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
   2626     return VFR_RETURN_OUT_FOR_RESOURCES;
   2627   }
   2628 
   2629   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2630     QuestionId = GetFreeQuestionId ();
   2631   } else {
   2632     //
   2633     // For Framework Vfr, don't check question ID conflict.
   2634     //
   2635     if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
   2636       delete pNode;
   2637       return VFR_RETURN_QUESTIONID_REDEFINED;
   2638     }
   2639     MarkQuestionIdUsed (QuestionId);
   2640   }
   2641   pNode->mQuestionId = QuestionId;
   2642 
   2643   pNode->mNext       = mQuestionList;
   2644   mQuestionList      = pNode;
   2645 
   2646   gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2647 
   2648   return VFR_RETURN_SUCCESS;
   2649 }
   2650 
   2651 VOID
   2652 CVfrQuestionDB::RegisterOldDateQuestion (
   2653   IN     CHAR8            *YearVarId,
   2654   IN     CHAR8            *MonthVarId,
   2655   IN     CHAR8            *DayVarId,
   2656   IN OUT EFI_QUESTION_ID &QuestionId
   2657   )
   2658 {
   2659   SVfrQuestionNode *pNode[3] = {NULL, };
   2660   UINT32           Index;
   2661 
   2662   if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
   2663     return;
   2664   }
   2665 
   2666   if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
   2667     goto Err;
   2668   }
   2669   if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
   2670     goto Err;
   2671   }
   2672   if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
   2673     goto Err;
   2674   }
   2675 
   2676   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2677     QuestionId = GetFreeQuestionId ();
   2678   } else {
   2679     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2680       goto Err;
   2681     }
   2682     MarkQuestionIdUsed (QuestionId);
   2683   }
   2684 
   2685   pNode[0]->mQuestionId = QuestionId;
   2686   pNode[1]->mQuestionId = QuestionId;
   2687   pNode[2]->mQuestionId = QuestionId;
   2688   pNode[0]->mQtype      = QUESTION_DATE;
   2689   pNode[1]->mQtype      = QUESTION_DATE;
   2690   pNode[2]->mQtype      = QUESTION_DATE;
   2691   pNode[0]->mNext       = pNode[1];
   2692   pNode[1]->mNext       = pNode[2];
   2693   pNode[2]->mNext       = mQuestionList;
   2694   mQuestionList         = pNode[0];
   2695 
   2696   gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2697   gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2698   gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2699 
   2700   return;
   2701 
   2702 Err:
   2703   for (Index = 0; Index < 3; Index++) {
   2704     if (pNode[Index] != NULL) {
   2705       delete pNode[Index];
   2706     }
   2707   }
   2708   QuestionId = EFI_QUESTION_ID_INVALID;
   2709 }
   2710 
   2711 VOID
   2712 CVfrQuestionDB::RegisterNewDateQuestion (
   2713   IN     CHAR8            *Name,
   2714   IN     CHAR8            *BaseVarId,
   2715   IN OUT EFI_QUESTION_ID &QuestionId
   2716   )
   2717 {
   2718   SVfrQuestionNode     *pNode[3] = {NULL, };
   2719   UINT32               Len;
   2720   CHAR8                *VarIdStr[3] = {NULL, };
   2721   CHAR8                 Index;
   2722 
   2723   if (BaseVarId == NULL && Name == NULL) {
   2724     if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2725       QuestionId = GetFreeQuestionId ();
   2726     } else {
   2727       if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2728         goto Err;
   2729       }
   2730       MarkQuestionIdUsed (QuestionId);
   2731     }
   2732     return;
   2733   }
   2734 
   2735   if (BaseVarId != NULL) {
   2736     Len = strlen (BaseVarId);
   2737 
   2738     VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
   2739     if (VarIdStr[0] != NULL) {
   2740       strcpy (VarIdStr[0], BaseVarId);
   2741       strcat (VarIdStr[0], ".Year");
   2742     }
   2743     VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
   2744     if (VarIdStr[1] != NULL) {
   2745       strcpy (VarIdStr[1], BaseVarId);
   2746       strcat (VarIdStr[1], ".Month");
   2747     }
   2748     VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
   2749     if (VarIdStr[2] != NULL) {
   2750       strcpy (VarIdStr[2], BaseVarId);
   2751       strcat (VarIdStr[2], ".Day");
   2752     }
   2753   } else {
   2754     Len = strlen (Name);
   2755 
   2756     VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
   2757     if (VarIdStr[0] != NULL) {
   2758       strcpy (VarIdStr[0], Name);
   2759       strcat (VarIdStr[0], ".Year");
   2760     }
   2761     VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
   2762     if (VarIdStr[1] != NULL) {
   2763       strcpy (VarIdStr[1], Name);
   2764       strcat (VarIdStr[1], ".Month");
   2765     }
   2766     VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
   2767     if (VarIdStr[2] != NULL) {
   2768       strcpy (VarIdStr[2], Name);
   2769       strcat (VarIdStr[2], ".Day");
   2770     }
   2771   }
   2772 
   2773   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
   2774     goto Err;
   2775   }
   2776   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
   2777     goto Err;
   2778   }
   2779   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
   2780     goto Err;
   2781   }
   2782 
   2783   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2784     QuestionId = GetFreeQuestionId ();
   2785   } else {
   2786     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2787       goto Err;
   2788     }
   2789     MarkQuestionIdUsed (QuestionId);
   2790   }
   2791 
   2792   pNode[0]->mQuestionId = QuestionId;
   2793   pNode[1]->mQuestionId = QuestionId;
   2794   pNode[2]->mQuestionId = QuestionId;
   2795   pNode[0]->mQtype      = QUESTION_DATE;
   2796   pNode[1]->mQtype      = QUESTION_DATE;
   2797   pNode[2]->mQtype      = QUESTION_DATE;
   2798   pNode[0]->mNext       = pNode[1];
   2799   pNode[1]->mNext       = pNode[2];
   2800   pNode[2]->mNext       = mQuestionList;
   2801   mQuestionList         = pNode[0];
   2802 
   2803   for (Index = 0; Index < 3; Index++) {
   2804     if (VarIdStr[Index] != NULL) {
   2805       delete VarIdStr[Index];
   2806     }
   2807   }
   2808 
   2809   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2810   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2811   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2812 
   2813   return;
   2814 
   2815 Err:
   2816   for (Index = 0; Index < 3; Index++) {
   2817     if (pNode[Index] != NULL) {
   2818       delete pNode[Index];
   2819     }
   2820 
   2821     if (VarIdStr[Index] != NULL) {
   2822       delete VarIdStr[Index];
   2823     }
   2824   }
   2825 }
   2826 
   2827 VOID
   2828 CVfrQuestionDB::RegisterOldTimeQuestion (
   2829   IN     CHAR8            *HourVarId,
   2830   IN     CHAR8            *MinuteVarId,
   2831   IN     CHAR8            *SecondVarId,
   2832   IN OUT EFI_QUESTION_ID &QuestionId
   2833   )
   2834 {
   2835   SVfrQuestionNode *pNode[3] = {NULL, };
   2836   UINT32           Index;
   2837 
   2838   if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
   2839     return;
   2840   }
   2841 
   2842   if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
   2843     goto Err;
   2844   }
   2845   if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
   2846     goto Err;
   2847   }
   2848   if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
   2849     goto Err;
   2850   }
   2851 
   2852   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2853     QuestionId = GetFreeQuestionId ();
   2854   } else {
   2855     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2856       goto Err;
   2857     }
   2858     MarkQuestionIdUsed (QuestionId);
   2859   }
   2860 
   2861   pNode[0]->mQuestionId = QuestionId;
   2862   pNode[1]->mQuestionId = QuestionId;
   2863   pNode[2]->mQuestionId = QuestionId;
   2864   pNode[0]->mQtype      = QUESTION_TIME;
   2865   pNode[1]->mQtype      = QUESTION_TIME;
   2866   pNode[2]->mQtype      = QUESTION_TIME;
   2867   pNode[0]->mNext       = pNode[1];
   2868   pNode[1]->mNext       = pNode[2];
   2869   pNode[2]->mNext       = mQuestionList;
   2870   mQuestionList         = pNode[0];
   2871 
   2872   gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2873   gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2874   gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2875 
   2876   return;
   2877 
   2878 Err:
   2879   for (Index = 0; Index < 3; Index++) {
   2880     if (pNode[Index] != NULL) {
   2881       delete pNode[Index];
   2882     }
   2883   }
   2884   QuestionId = EFI_QUESTION_ID_INVALID;
   2885 }
   2886 
   2887 VOID
   2888 CVfrQuestionDB::RegisterNewTimeQuestion (
   2889   IN     CHAR8           *Name,
   2890   IN     CHAR8           *BaseVarId,
   2891   IN OUT EFI_QUESTION_ID &QuestionId
   2892   )
   2893 {
   2894   SVfrQuestionNode     *pNode[3] = {NULL, };
   2895   UINT32               Len;
   2896   CHAR8                *VarIdStr[3] = {NULL, };
   2897   CHAR8                 Index;
   2898 
   2899   if (BaseVarId == NULL && Name == NULL) {
   2900     if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2901       QuestionId = GetFreeQuestionId ();
   2902     } else {
   2903       if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2904         goto Err;
   2905       }
   2906       MarkQuestionIdUsed (QuestionId);
   2907     }
   2908     return;
   2909   }
   2910 
   2911   if (BaseVarId != NULL) {
   2912     Len = strlen (BaseVarId);
   2913 
   2914     VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
   2915     if (VarIdStr[0] != NULL) {
   2916       strcpy (VarIdStr[0], BaseVarId);
   2917       strcat (VarIdStr[0], ".Hour");
   2918     }
   2919     VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
   2920     if (VarIdStr[1] != NULL) {
   2921       strcpy (VarIdStr[1], BaseVarId);
   2922       strcat (VarIdStr[1], ".Minute");
   2923     }
   2924     VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
   2925     if (VarIdStr[2] != NULL) {
   2926       strcpy (VarIdStr[2], BaseVarId);
   2927       strcat (VarIdStr[2], ".Second");
   2928     }
   2929   } else {
   2930     Len = strlen (Name);
   2931 
   2932     VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
   2933     if (VarIdStr[0] != NULL) {
   2934       strcpy (VarIdStr[0], Name);
   2935       strcat (VarIdStr[0], ".Hour");
   2936     }
   2937     VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
   2938     if (VarIdStr[1] != NULL) {
   2939       strcpy (VarIdStr[1], Name);
   2940       strcat (VarIdStr[1], ".Minute");
   2941     }
   2942     VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
   2943     if (VarIdStr[2] != NULL) {
   2944       strcpy (VarIdStr[2], Name);
   2945       strcat (VarIdStr[2], ".Second");
   2946     }
   2947   }
   2948 
   2949   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
   2950     goto Err;
   2951   }
   2952   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
   2953     goto Err;
   2954   }
   2955   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
   2956     goto Err;
   2957   }
   2958 
   2959   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   2960     QuestionId = GetFreeQuestionId ();
   2961   } else {
   2962     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   2963       goto Err;
   2964     }
   2965     MarkQuestionIdUsed (QuestionId);
   2966   }
   2967 
   2968   pNode[0]->mQuestionId = QuestionId;
   2969   pNode[1]->mQuestionId = QuestionId;
   2970   pNode[2]->mQuestionId = QuestionId;
   2971   pNode[0]->mQtype      = QUESTION_TIME;
   2972   pNode[1]->mQtype      = QUESTION_TIME;
   2973   pNode[2]->mQtype      = QUESTION_TIME;
   2974   pNode[0]->mNext       = pNode[1];
   2975   pNode[1]->mNext       = pNode[2];
   2976   pNode[2]->mNext       = mQuestionList;
   2977   mQuestionList         = pNode[0];
   2978 
   2979   for (Index = 0; Index < 3; Index++) {
   2980     if (VarIdStr[Index] != NULL) {
   2981       delete VarIdStr[Index];
   2982     }
   2983   }
   2984 
   2985   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2986   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2987   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   2988 
   2989   return;
   2990 
   2991 Err:
   2992   for (Index = 0; Index < 3; Index++) {
   2993     if (pNode[Index] != NULL) {
   2994       delete pNode[Index];
   2995     }
   2996 
   2997     if (VarIdStr[Index] != NULL) {
   2998       delete VarIdStr[Index];
   2999     }
   3000   }
   3001 }
   3002 
   3003 VOID
   3004 CVfrQuestionDB::RegisterRefQuestion (
   3005   IN     CHAR8           *Name,
   3006   IN     CHAR8           *BaseVarId,
   3007   IN OUT EFI_QUESTION_ID &QuestionId
   3008   )
   3009 {
   3010   SVfrQuestionNode     *pNode[4] = {NULL, };
   3011   UINT32               Len;
   3012   CHAR8                *VarIdStr[4] = {NULL, };
   3013   CHAR8                 Index;
   3014 
   3015   if (BaseVarId == NULL && Name == NULL) {
   3016     return;
   3017   }
   3018 
   3019   if (BaseVarId != NULL) {
   3020     Len = strlen (BaseVarId);
   3021 
   3022     VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
   3023     if (VarIdStr[0] != NULL) {
   3024       strcpy (VarIdStr[0], BaseVarId);
   3025       strcat (VarIdStr[0], ".QuestionId");
   3026     }
   3027     VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
   3028     if (VarIdStr[1] != NULL) {
   3029       strcpy (VarIdStr[1], BaseVarId);
   3030       strcat (VarIdStr[1], ".FormId");
   3031     }
   3032     VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
   3033     if (VarIdStr[2] != NULL) {
   3034       strcpy (VarIdStr[2], BaseVarId);
   3035       strcat (VarIdStr[2], ".FormSetGuid");
   3036     }
   3037     VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
   3038     if (VarIdStr[3] != NULL) {
   3039       strcpy (VarIdStr[3], BaseVarId);
   3040       strcat (VarIdStr[3], ".DevicePath");
   3041     }
   3042   } else {
   3043     Len = strlen (Name);
   3044 
   3045     VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
   3046     if (VarIdStr[0] != NULL) {
   3047       strcpy (VarIdStr[0], Name);
   3048       strcat (VarIdStr[0], ".QuestionId");
   3049     }
   3050     VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
   3051     if (VarIdStr[1] != NULL) {
   3052       strcpy (VarIdStr[1], Name);
   3053       strcat (VarIdStr[1], ".FormId");
   3054     }
   3055     VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
   3056     if (VarIdStr[2] != NULL) {
   3057       strcpy (VarIdStr[2], Name);
   3058       strcat (VarIdStr[2], ".FormSetGuid");
   3059     }
   3060     VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
   3061     if (VarIdStr[3] != NULL) {
   3062       strcpy (VarIdStr[3], Name);
   3063       strcat (VarIdStr[3], ".DevicePath");
   3064     }
   3065   }
   3066 
   3067   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
   3068     goto Err;
   3069   }
   3070   if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
   3071     goto Err;
   3072   }
   3073   if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
   3074     goto Err;
   3075   }
   3076   if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
   3077     goto Err;
   3078   }
   3079 
   3080   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   3081     QuestionId = GetFreeQuestionId ();
   3082   } else {
   3083     if (ChekQuestionIdFree (QuestionId) == FALSE) {
   3084       goto Err;
   3085     }
   3086     MarkQuestionIdUsed (QuestionId);
   3087   }
   3088 
   3089   pNode[0]->mQuestionId = QuestionId;
   3090   pNode[1]->mQuestionId = QuestionId;
   3091   pNode[2]->mQuestionId = QuestionId;
   3092   pNode[3]->mQuestionId = QuestionId;
   3093   pNode[0]->mQtype      = QUESTION_REF;
   3094   pNode[1]->mQtype      = QUESTION_REF;
   3095   pNode[2]->mQtype      = QUESTION_REF;
   3096   pNode[3]->mQtype      = QUESTION_REF;
   3097   pNode[0]->mNext       = pNode[1];
   3098   pNode[1]->mNext       = pNode[2];
   3099   pNode[2]->mNext       = pNode[3];
   3100   pNode[3]->mNext       = mQuestionList;
   3101   mQuestionList         = pNode[0];
   3102 
   3103   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3104   gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3105   gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3106   gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
   3107 
   3108   return;
   3109 
   3110   Err:
   3111   for (Index = 0; Index < 4; Index++) {
   3112     if (pNode[Index] != NULL) {
   3113       delete pNode[Index];
   3114     }
   3115 
   3116     if (VarIdStr[Index] != NULL) {
   3117       delete VarIdStr[Index];
   3118     }
   3119   }
   3120 }
   3121 
   3122 EFI_VFR_RETURN_CODE
   3123 CVfrQuestionDB::UpdateQuestionId (
   3124   IN EFI_QUESTION_ID   QId,
   3125   IN EFI_QUESTION_ID   NewQId
   3126   )
   3127 {
   3128   SVfrQuestionNode *pNode = NULL;
   3129 
   3130   if (QId == NewQId) {
   3131     // don't update
   3132     return VFR_RETURN_SUCCESS;
   3133   }
   3134 
   3135   //
   3136   // For Framework Vfr, don't check question ID conflict.
   3137   //
   3138   if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
   3139     return VFR_RETURN_REDEFINED;
   3140   }
   3141 
   3142   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3143     if (pNode->mQuestionId == QId) {
   3144       break;
   3145     }
   3146   }
   3147 
   3148   if (pNode == NULL) {
   3149     return VFR_RETURN_UNDEFINED;
   3150   }
   3151 
   3152   MarkQuestionIdUnused (QId);
   3153   pNode->mQuestionId = NewQId;
   3154   MarkQuestionIdUsed (NewQId);
   3155 
   3156   gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
   3157 
   3158   return VFR_RETURN_SUCCESS;
   3159 }
   3160 
   3161 VOID
   3162 CVfrQuestionDB::GetQuestionId (
   3163   IN  CHAR8             *Name,
   3164   IN  CHAR8             *VarIdStr,
   3165   OUT EFI_QUESTION_ID   &QuestionId,
   3166   OUT UINT32            &BitMask,
   3167   OUT EFI_QUESION_TYPE  *QType
   3168   )
   3169 {
   3170   SVfrQuestionNode *pNode;
   3171 
   3172   QuestionId = EFI_QUESTION_ID_INVALID;
   3173   BitMask    = 0x00000000;
   3174   if (QType != NULL) {
   3175     *QType = QUESTION_NORMAL;
   3176   }
   3177 
   3178   if ((Name == NULL) && (VarIdStr == NULL)) {
   3179     return ;
   3180   }
   3181 
   3182   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3183     if (Name != NULL) {
   3184       if (strcmp (pNode->mName, Name) != 0) {
   3185         continue;
   3186       }
   3187     }
   3188 
   3189     if (VarIdStr != NULL) {
   3190       if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
   3191         continue;
   3192       }
   3193   	}
   3194 
   3195     QuestionId = pNode->mQuestionId;
   3196     BitMask    = pNode->mBitMask;
   3197     if (QType != NULL) {
   3198       *QType     = pNode->mQtype;
   3199     }
   3200     break;
   3201   }
   3202 
   3203   return ;
   3204 }
   3205 
   3206 EFI_VFR_RETURN_CODE
   3207 CVfrQuestionDB::FindQuestion (
   3208   IN EFI_QUESTION_ID QuestionId
   3209   )
   3210 {
   3211   SVfrQuestionNode *pNode;
   3212 
   3213   if (QuestionId == EFI_QUESTION_ID_INVALID) {
   3214     return VFR_RETURN_INVALID_PARAMETER;
   3215   }
   3216 
   3217   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3218     if (pNode->mQuestionId == QuestionId) {
   3219       return VFR_RETURN_SUCCESS;
   3220     }
   3221   }
   3222 
   3223   return VFR_RETURN_UNDEFINED;
   3224 }
   3225 
   3226 EFI_VFR_RETURN_CODE
   3227 CVfrQuestionDB::FindQuestion (
   3228   IN CHAR8 *Name
   3229   )
   3230 {
   3231   SVfrQuestionNode *pNode;
   3232 
   3233   if (Name == NULL) {
   3234     return VFR_RETURN_FATAL_ERROR;
   3235   }
   3236 
   3237   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
   3238     if (strcmp (pNode->mName, Name) == 0) {
   3239       return VFR_RETURN_SUCCESS;
   3240     }
   3241   }
   3242 
   3243   return VFR_RETURN_UNDEFINED;
   3244 }
   3245 
   3246 CVfrStringDB::CVfrStringDB ()
   3247 {
   3248   mStringFileName = NULL;
   3249 }
   3250 
   3251 CVfrStringDB::~CVfrStringDB ()
   3252 {
   3253   if (mStringFileName != NULL) {
   3254     delete mStringFileName;
   3255   }
   3256   mStringFileName = NULL;
   3257 }
   3258 
   3259 
   3260 VOID
   3261 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
   3262 {
   3263   UINT32 FileLen = 0;
   3264 
   3265   if (StringFileName == NULL) {
   3266     return;
   3267   }
   3268 
   3269   FileLen = strlen (StringFileName) + 1;
   3270   mStringFileName = new CHAR8[FileLen];
   3271   if (mStringFileName == NULL) {
   3272     return;
   3273   }
   3274 
   3275   strcpy (mStringFileName, StringFileName);
   3276   mStringFileName[FileLen - 1] = '\0';
   3277 }
   3278 
   3279 
   3280 /**
   3281   Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
   3282   from a set of supported languages.
   3283 
   3284   @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string that
   3285                                   contains a set of language codes.
   3286   @param[in]  Language            A variable that contains pointers to Null-terminated
   3287                                   ASCII strings that contain one language codes.
   3288 
   3289   @retval FALSE   The best matching language could not be found in SupportedLanguages.
   3290   @retval TRUE    The best matching language could be found in SupportedLanguages.
   3291 
   3292 **/
   3293 BOOLEAN
   3294 CVfrStringDB::GetBestLanguage (
   3295   IN CONST CHAR8  *SupportedLanguages,
   3296   IN CHAR8        *Language
   3297   )
   3298 {
   3299   UINTN        CompareLength;
   3300   UINTN        LanguageLength;
   3301   CONST CHAR8  *Supported;
   3302 
   3303   if (SupportedLanguages == NULL || Language == NULL){
   3304     return FALSE;
   3305   }
   3306 
   3307   //
   3308   // Determine the length of the first RFC 4646 language code in Language
   3309   //
   3310   for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
   3311 
   3312   //
   3313   // Trim back the length of Language used until it is empty
   3314   //
   3315   while (LanguageLength > 0) {
   3316     //
   3317     // Loop through all language codes in SupportedLanguages
   3318     //
   3319     for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
   3320       //
   3321       // Skip ';' characters in Supported
   3322       //
   3323       for (; *Supported != '\0' && *Supported == ';'; Supported++);
   3324       //
   3325       // Determine the length of the next language code in Supported
   3326       //
   3327       for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
   3328       //
   3329       // If Language is longer than the Supported, then skip to the next language
   3330       //
   3331       if (LanguageLength > CompareLength) {
   3332         continue;
   3333       }
   3334 
   3335       //
   3336       // See if the first LanguageLength characters in Supported match Language
   3337       //
   3338       if (strncmp (Supported, Language, LanguageLength) == 0) {
   3339         return TRUE;
   3340       }
   3341     }
   3342 
   3343     //
   3344     // Trim Language from the right to the next '-' character
   3345     //
   3346     for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
   3347   }
   3348 
   3349   //
   3350   // No matches were found
   3351   //
   3352   return FALSE;
   3353 }
   3354 
   3355 
   3356 CHAR8 *
   3357 CVfrStringDB::GetVarStoreNameFormStringId (
   3358   IN EFI_STRING_ID StringId
   3359   )
   3360 {
   3361   FILE        *pInFile    = NULL;
   3362   UINT32      NameOffset;
   3363   UINT32      Length;
   3364   UINT8       *StringPtr;
   3365   CHAR8       *StringName;
   3366   CHAR16      *UnicodeString;
   3367   CHAR8       *VarStoreName = NULL;
   3368   CHAR8       *DestTmp;
   3369   UINT8       *Current;
   3370   EFI_STATUS  Status;
   3371   CHAR8       LineBuf[EFI_IFR_MAX_LENGTH];
   3372   UINT8       BlockType;
   3373   EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
   3374 
   3375   if (mStringFileName == NULL) {
   3376     return NULL;
   3377   }
   3378 
   3379   if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
   3380     return NULL;
   3381   }
   3382 
   3383   //
   3384   // Get file length.
   3385   //
   3386   fseek (pInFile, 0, SEEK_END);
   3387   Length = ftell (pInFile);
   3388   fseek (pInFile, 0, SEEK_SET);
   3389 
   3390   //
   3391   // Get file data.
   3392   //
   3393   StringPtr = new UINT8[Length];
   3394   if (StringPtr == NULL) {
   3395     fclose (pInFile);
   3396     return NULL;
   3397   }
   3398   fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
   3399   fclose (pInFile);
   3400 
   3401   PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
   3402   //
   3403   // Check the String package.
   3404   //
   3405   if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
   3406     delete[] StringPtr;
   3407     return NULL;
   3408   }
   3409 
   3410   //
   3411   // Search the language, get best language base on RFC 4647 matching algorithm.
   3412   //
   3413   Current = StringPtr;
   3414   while (!GetBestLanguage ("en", PkgHeader->Language)) {
   3415     Current += PkgHeader->Header.Length;
   3416     PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
   3417     //
   3418     // If can't find string package base on language, just return the first string package.
   3419     //
   3420     if (Current - StringPtr >= Length) {
   3421       Current = StringPtr;
   3422       PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
   3423       break;
   3424     }
   3425   }
   3426 
   3427   Current += PkgHeader->HdrSize;
   3428   //
   3429   // Find the string block according the stringId.
   3430   //
   3431   Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
   3432   if (Status != EFI_SUCCESS) {
   3433     delete[] StringPtr;
   3434     return NULL;
   3435   }
   3436 
   3437   //
   3438   // Get varstore name according the string type.
   3439   //
   3440   switch (BlockType) {
   3441   case EFI_HII_SIBT_STRING_SCSU:
   3442   case EFI_HII_SIBT_STRING_SCSU_FONT:
   3443   case EFI_HII_SIBT_STRINGS_SCSU:
   3444   case EFI_HII_SIBT_STRINGS_SCSU_FONT:
   3445     StringName = (CHAR8*)(Current + NameOffset);
   3446     VarStoreName = new CHAR8[strlen(StringName) + 1];
   3447     strcpy (VarStoreName, StringName);
   3448     break;
   3449   case EFI_HII_SIBT_STRING_UCS2:
   3450   case EFI_HII_SIBT_STRING_UCS2_FONT:
   3451   case EFI_HII_SIBT_STRINGS_UCS2:
   3452   case EFI_HII_SIBT_STRINGS_UCS2_FONT:
   3453     UnicodeString = (CHAR16*)(Current + NameOffset);
   3454     Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
   3455     DestTmp = new CHAR8[Length / 2 + 1];
   3456     VarStoreName = DestTmp;
   3457     while (*UnicodeString != '\0') {
   3458       *(DestTmp++) = (CHAR8) *(UnicodeString++);
   3459     }
   3460     *DestTmp = '\0';
   3461     break;
   3462   default:
   3463     break;
   3464   }
   3465 
   3466   delete[] StringPtr;
   3467 
   3468   return VarStoreName;
   3469 }
   3470 
   3471 EFI_STATUS
   3472 CVfrStringDB::FindStringBlock (
   3473   IN  UINT8                           *StringData,
   3474   IN  EFI_STRING_ID                   StringId,
   3475   OUT UINT32                          *StringTextOffset,
   3476   OUT UINT8                           *BlockType
   3477   )
   3478 {
   3479   UINT8                                *BlockHdr;
   3480   EFI_STRING_ID                        CurrentStringId;
   3481   UINT32                               BlockSize;
   3482   UINT32                               Index;
   3483   UINT8                                *StringTextPtr;
   3484   UINT32                               Offset;
   3485   UINT16                               StringCount;
   3486   UINT16                               SkipCount;
   3487   UINT8                                Length8;
   3488   EFI_HII_SIBT_EXT2_BLOCK              Ext2;
   3489   UINT32                               Length32;
   3490   UINT32                               StringSize;
   3491 
   3492   CurrentStringId = 1;
   3493 
   3494   //
   3495   // Parse the string blocks to get the string text and font.
   3496   //
   3497   BlockHdr  = StringData;
   3498   BlockSize = 0;
   3499   Offset    = 0;
   3500   while (*BlockHdr != EFI_HII_SIBT_END) {
   3501     switch (*BlockHdr) {
   3502     case EFI_HII_SIBT_STRING_SCSU:
   3503       Offset = sizeof (EFI_HII_STRING_BLOCK);
   3504       StringTextPtr = BlockHdr + Offset;
   3505       BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
   3506       CurrentStringId++;
   3507       break;
   3508 
   3509     case EFI_HII_SIBT_STRING_SCSU_FONT:
   3510       Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
   3511       StringTextPtr = BlockHdr + Offset;
   3512       BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
   3513       CurrentStringId++;
   3514       break;
   3515 
   3516     case EFI_HII_SIBT_STRINGS_SCSU:
   3517       memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
   3518       StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
   3519       BlockSize += StringTextPtr - BlockHdr;
   3520 
   3521       for (Index = 0; Index < StringCount; Index++) {
   3522         BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
   3523         if (CurrentStringId == StringId) {
   3524           *BlockType        = *BlockHdr;
   3525           *StringTextOffset = StringTextPtr - StringData;
   3526           return EFI_SUCCESS;
   3527         }
   3528         StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
   3529         CurrentStringId++;
   3530       }
   3531       break;
   3532 
   3533     case EFI_HII_SIBT_STRINGS_SCSU_FONT:
   3534       memcpy (
   3535         &StringCount,
   3536         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3537         sizeof (UINT16)
   3538         );
   3539       StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
   3540       BlockSize += StringTextPtr - BlockHdr;
   3541 
   3542       for (Index = 0; Index < StringCount; Index++) {
   3543         BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
   3544         if (CurrentStringId == StringId) {
   3545           *BlockType        = *BlockHdr;
   3546           *StringTextOffset = StringTextPtr - StringData;
   3547           return EFI_SUCCESS;
   3548         }
   3549         StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
   3550         CurrentStringId++;
   3551       }
   3552       break;
   3553 
   3554     case EFI_HII_SIBT_STRING_UCS2:
   3555       Offset        = sizeof (EFI_HII_STRING_BLOCK);
   3556       StringTextPtr = BlockHdr + Offset;
   3557       //
   3558       // Use StringSize to store the size of the specified string, including the NULL
   3559       // terminator.
   3560       //
   3561       StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3562       BlockSize += Offset + StringSize;
   3563       CurrentStringId++;
   3564       break;
   3565 
   3566     case EFI_HII_SIBT_STRING_UCS2_FONT:
   3567       Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
   3568       StringTextPtr = BlockHdr + Offset;
   3569       //
   3570       // Use StrSize to store the size of the specified string, including the NULL
   3571       // terminator.
   3572       //
   3573       StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3574       BlockSize += Offset + StringSize;
   3575       CurrentStringId++;
   3576       break;
   3577 
   3578     case EFI_HII_SIBT_STRINGS_UCS2:
   3579       Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
   3580       StringTextPtr = BlockHdr + Offset;
   3581       BlockSize += Offset;
   3582       memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
   3583       for (Index = 0; Index < StringCount; Index++) {
   3584         StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3585         BlockSize += StringSize;
   3586         if (CurrentStringId == StringId) {
   3587           *BlockType        = *BlockHdr;
   3588           *StringTextOffset = StringTextPtr - StringData;
   3589           return EFI_SUCCESS;
   3590         }
   3591         StringTextPtr = StringTextPtr + StringSize;
   3592         CurrentStringId++;
   3593       }
   3594       break;
   3595 
   3596     case EFI_HII_SIBT_STRINGS_UCS2_FONT:
   3597       Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
   3598       StringTextPtr = BlockHdr + Offset;
   3599       BlockSize += Offset;
   3600       memcpy (
   3601         &StringCount,
   3602         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3603         sizeof (UINT16)
   3604         );
   3605       for (Index = 0; Index < StringCount; Index++) {
   3606         StringSize = GetUnicodeStringTextSize (StringTextPtr);
   3607         BlockSize += StringSize;
   3608         if (CurrentStringId == StringId) {
   3609           *BlockType        = *BlockHdr;
   3610           *StringTextOffset = StringTextPtr - StringData;
   3611           return EFI_SUCCESS;
   3612         }
   3613         StringTextPtr = StringTextPtr + StringSize;
   3614         CurrentStringId++;
   3615       }
   3616       break;
   3617 
   3618     case EFI_HII_SIBT_DUPLICATE:
   3619       if (CurrentStringId == StringId) {
   3620         //
   3621         // Incoming StringId is an id of a duplicate string block.
   3622         // Update the StringId to be the previous string block.
   3623         // Go back to the header of string block to search.
   3624         //
   3625         memcpy (
   3626           &StringId,
   3627           BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
   3628           sizeof (EFI_STRING_ID)
   3629           );
   3630         CurrentStringId = 1;
   3631         BlockSize       = 0;
   3632       } else {
   3633         BlockSize       += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
   3634         CurrentStringId++;
   3635       }
   3636       break;
   3637 
   3638     case EFI_HII_SIBT_SKIP1:
   3639       SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
   3640       CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
   3641       BlockSize       +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
   3642       break;
   3643 
   3644     case EFI_HII_SIBT_SKIP2:
   3645       memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
   3646       CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
   3647       BlockSize       +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
   3648       break;
   3649 
   3650     case EFI_HII_SIBT_EXT1:
   3651       memcpy (
   3652         &Length8,
   3653         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3654         sizeof (UINT8)
   3655         );
   3656       BlockSize += Length8;
   3657       break;
   3658 
   3659     case EFI_HII_SIBT_EXT2:
   3660       memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
   3661       BlockSize += Ext2.Length;
   3662       break;
   3663 
   3664     case EFI_HII_SIBT_EXT4:
   3665       memcpy (
   3666         &Length32,
   3667         BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
   3668         sizeof (UINT32)
   3669         );
   3670 
   3671       BlockSize += Length32;
   3672       break;
   3673 
   3674     default:
   3675       break;
   3676     }
   3677 
   3678     if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
   3679       *StringTextOffset = BlockHdr - StringData + Offset;
   3680       *BlockType        = *BlockHdr;
   3681 
   3682       if (StringId == CurrentStringId - 1) {
   3683         //
   3684         // if only one skip item, return EFI_NOT_FOUND.
   3685         //
   3686         if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
   3687           return EFI_NOT_FOUND;
   3688         } else {
   3689           return EFI_SUCCESS;
   3690         }
   3691       }
   3692 
   3693       if (StringId < CurrentStringId - 1) {
   3694         return EFI_NOT_FOUND;
   3695       }
   3696     }
   3697     BlockHdr  = StringData + BlockSize;
   3698   }
   3699 
   3700   return EFI_NOT_FOUND;
   3701 }
   3702 
   3703 UINT32
   3704 CVfrStringDB::GetUnicodeStringTextSize (
   3705   IN  UINT8            *StringSrc
   3706   )
   3707 {
   3708   UINT32 StringSize;
   3709   CHAR16 *StringPtr;
   3710 
   3711   StringSize = sizeof (CHAR16);
   3712   StringPtr  = (UINT16*)StringSrc;
   3713   while (*StringPtr++ != L'\0') {
   3714     StringSize += sizeof (CHAR16);
   3715   }
   3716 
   3717   return StringSize;
   3718 }
   3719 
   3720 BOOLEAN  VfrCompatibleMode = FALSE;
   3721 
   3722 CVfrVarDataTypeDB gCVfrVarDataTypeDB;
   3723 CVfrDefaultStore  gCVfrDefaultStore;
   3724 CVfrDataStorage  gCVfrDataStorage;
   3725 
   3726 
   3727