]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools: Various typo
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
index f047b2c471905ed5494c6eefb389f4bb067b6c31..0d0f926f82660a4fa498480094fce1a32b294fe6 100644 (file)
@@ -1,30 +1,32 @@
 /** @file\r
-  \r
+\r
   Vfr common library functions.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
 #include "stdio.h"\r
 #include "stdlib.h"\r
+#include "assert.h"\r
+#include "CommonLib.h"\r
 #include "VfrUtilityLib.h"\r
 #include "VfrFormPkg.h"\r
 \r
 VOID\r
 CVfrBinaryOutput::WriteLine (\r
-  IN FILE   *pFile,\r
-  IN UINT32 LineBytes,\r
-  IN CHAR8  *LineHeader,\r
-  IN CHAR8  *BlkBuf,\r
-  IN UINT32 BlkSize\r
+  IN FILE         *pFile,\r
+  IN UINT32       LineBytes,\r
+  IN CONST CHAR8  *LineHeader,\r
+  IN CHAR8        *BlkBuf,\r
+  IN UINT32       BlkSize\r
   )\r
 {\r
   UINT32    Index;\r
@@ -43,11 +45,11 @@ CVfrBinaryOutput::WriteLine (
 \r
 VOID\r
 CVfrBinaryOutput::WriteEnd (\r
-  IN FILE   *pFile,\r
-  IN UINT32 LineBytes,\r
-  IN CHAR8  *LineHeader,\r
-  IN CHAR8  *BlkBuf,\r
-  IN UINT32 BlkSize\r
+  IN FILE         *pFile,\r
+  IN UINT32       LineBytes,\r
+  IN CONST CHAR8  *LineHeader,\r
+  IN CHAR8        *BlkBuf,\r
+  IN UINT32       BlkSize\r
   )\r
 {\r
   UINT32    Index;\r
@@ -70,9 +72,9 @@ CVfrBinaryOutput::WriteEnd (
 }\r
 \r
 SConfigInfo::SConfigInfo (\r
-  IN UINT8              Type, \r
-  IN UINT16             Offset, \r
-  IN UINT32             Width, \r
+  IN UINT8              Type,\r
+  IN UINT16             Offset,\r
+  IN UINT32             Width,\r
   IN EFI_IFR_TYPE_VALUE Value\r
   )\r
 {\r
@@ -109,6 +111,10 @@ SConfigInfo::SConfigInfo (
   case EFI_IFR_TYPE_STRING :\r
     memcpy (mValue, &Value.string, mWidth);\r
     break;\r
+  case EFI_IFR_TYPE_BUFFER :\r
+    memcpy (mValue, &Value.u8, mWidth);\r
+    break;\r
+\r
   case EFI_IFR_TYPE_OTHER :\r
     return;\r
   }\r
@@ -118,16 +124,18 @@ SConfigInfo::~SConfigInfo (
   VOID\r
   )\r
 {\r
-  BUFFER_SAFE_FREE (mValue);\r
+  ARRAY_SAFE_FREE (mValue);\r
 }\r
 \r
 SConfigItem::SConfigItem (\r
   IN CHAR8               *Name,\r
+  IN EFI_GUID            *Guid,\r
   IN CHAR8               *Id\r
   )\r
 {\r
   mName          = NULL;\r
-  mId            = 0;\r
+  mGuid          = NULL;\r
+  mId            = NULL;\r
   mInfoStrList = NULL;\r
   mNext        = NULL;\r
 \r
@@ -137,6 +145,12 @@ SConfigItem::SConfigItem (
     }\r
   }\r
 \r
+  if (Guid != NULL) {\r
+    if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {\r
+      memcpy (mGuid, Guid, sizeof (EFI_GUID));\r
+    }\r
+  }\r
+\r
   if (Id != NULL) {\r
     if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
       strcpy (mId, Id);\r
@@ -146,6 +160,7 @@ SConfigItem::SConfigItem (
 \r
 SConfigItem::SConfigItem (\r
   IN CHAR8               *Name,\r
+  IN EFI_GUID            *Guid,\r
   IN CHAR8               *Id,\r
   IN UINT8               Type,\r
   IN UINT16              Offset,\r
@@ -154,6 +169,7 @@ SConfigItem::SConfigItem (
   )\r
 {\r
   mName        = NULL;\r
+  mGuid        = NULL;\r
   mId          = NULL;\r
   mInfoStrList = NULL;\r
   mNext        = NULL;\r
@@ -164,6 +180,12 @@ SConfigItem::SConfigItem (
     }\r
   }\r
 \r
+  if (Guid != NULL) {\r
+    if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {\r
+      memcpy (mGuid, Guid, sizeof (EFI_GUID));\r
+    }\r
+  }\r
+\r
   if (Id != NULL) {\r
     if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {\r
       strcpy (mId, Id);\r
@@ -179,8 +201,9 @@ SConfigItem::~SConfigItem (
 {\r
   SConfigInfo  *Info;\r
 \r
-  BUFFER_SAFE_FREE (mName);\r
-  BUFFER_SAFE_FREE (mId);\r
+  ARRAY_SAFE_FREE (mName);\r
+  ARRAY_SAFE_FREE (mGuid);\r
+  ARRAY_SAFE_FREE (mId);\r
   while (mInfoStrList != NULL) {\r
     Info = mInfoStrList;\r
     mInfoStrList = mInfoStrList->mNext;\r
@@ -192,18 +215,20 @@ SConfigItem::~SConfigItem (
 UINT8\r
 CVfrBufferConfig::Register (\r
   IN CHAR8               *Name,\r
+  IN EFI_GUID            *Guid,\r
   IN CHAR8               *Id\r
   )\r
 {\r
   SConfigItem *pNew;\r
 \r
-  if (Select (Name) == 0) {\r
+  if (Select (Name, Guid) == 0) {\r
     return 1;\r
   }\r
 \r
-  if ((pNew = new SConfigItem (Name, Id)) == NULL) {\r
+  if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {\r
     return 2;\r
   }\r
+\r
   if (mItemListHead == NULL) {\r
     mItemListHead = pNew;\r
     mItemListTail = pNew;\r
@@ -234,18 +259,19 @@ CVfrBufferConfig::Eof(
 \r
 UINT8\r
 CVfrBufferConfig::Select (\r
-  IN CHAR8 *Name,\r
-  IN CHAR8 *Id\r
+  IN CHAR8    *Name,\r
+  IN EFI_GUID *Guid,\r
+  IN CHAR8    *Id\r
   )\r
 {\r
   SConfigItem *p;\r
 \r
-  if (Name == NULL) {\r
+  if (Name == NULL || Guid == NULL) {\r
     mItemListPos = mItemListHead;\r
     return 0;\r
   } else {\r
     for (p = mItemListHead; p != NULL; p = p->mNext) {\r
-      if (strcmp (p->mName, Name) != 0) {\r
+      if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {\r
         continue;\r
       }\r
 \r
@@ -269,6 +295,7 @@ UINT8
 CVfrBufferConfig::Write (\r
   IN CONST CHAR8         Mode,\r
   IN CHAR8               *Name,\r
+  IN EFI_GUID            *Guid,\r
   IN CHAR8               *Id,\r
   IN UINT8               Type,\r
   IN UINT16              Offset,\r
@@ -280,14 +307,14 @@ CVfrBufferConfig::Write (
   SConfigItem   *pItem;\r
   SConfigInfo   *pInfo;\r
 \r
-  if ((Ret = Select (Name)) != 0) {\r
+  if ((Ret = Select (Name, Guid)) != 0) {\r
     return Ret;\r
   }\r
 \r
   switch (Mode) {\r
   case 'a' : // add\r
-    if (Select (Name, Id) != 0) {\r
-      if ((pItem = new SConfigItem (Name, Id, Type, Offset, Width, Value)) == NULL) {\r
+    if (Select (Name, Guid, Id) != 0) {\r
+      if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {\r
         return 2;\r
       }\r
       if (mItemListHead == NULL) {\r
@@ -302,10 +329,6 @@ CVfrBufferConfig::Write (
       // tranverse the list to find out if there's already the value for the same offset\r
       for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {\r
         if (pInfo->mOffset == Offset) {\r
-          // check if the value and width are the same; return error if not\r
-          if ((Id != NULL) && (pInfo->mWidth != Width || memcmp(pInfo->mValue, &Value, Width) != 0)) {\r
-            return VFR_RETURN_DEFAULT_VALUE_REDEFINED;\r
-          }\r
           return 0;\r
         }\r
       }\r
@@ -337,7 +360,7 @@ CVfrBufferConfig::Write (
 \r
   case 'i' : // set info\r
     if (mItemListPos->mId != NULL) {\r
-      delete mItemListPos->mId;\r
+      delete[] mItemListPos->mId;\r
     }\r
     mItemListPos->mId = NULL;\r
     if (Id != NULL) {\r
@@ -455,7 +478,7 @@ CVfrBufferConfig::~CVfrBufferConfig (
 CVfrBufferConfig gCVfrBufferConfig;\r
 \r
 static struct {\r
-  CHAR8  *mTypeName;\r
+  CONST CHAR8  *mTypeName;\r
   UINT8  mType;\r
   UINT32 mSize;\r
   UINT32 mAlign;\r
@@ -468,6 +491,7 @@ static struct {
   {"EFI_HII_DATE",  EFI_IFR_TYPE_DATE,        sizeof (EFI_HII_DATE), sizeof (UINT16)},\r
   {"EFI_STRING_ID", EFI_IFR_TYPE_STRING,      sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},\r
   {"EFI_HII_TIME",  EFI_IFR_TYPE_TIME,        sizeof (EFI_HII_TIME), sizeof (UINT8)},\r
+  {"EFI_HII_REF",   EFI_IFR_TYPE_REF,         sizeof (EFI_HII_REF),  sizeof (EFI_GUID)},\r
   {NULL,            EFI_IFR_TYPE_OTHER,       0,                     0}\r
 };\r
 \r
@@ -529,7 +553,7 @@ _STR2U32 (
     //\r
     // BUG: does not handle overflow here\r
     //\r
-       (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
+  (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);\r
 \r
     if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {\r
       Value += (c - 'a' + 10);\r
@@ -577,6 +601,65 @@ CVfrVarDataTypeDB::ExtractStructTypeName (
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
+/**\r
+  Check whether the DataType contain bit field.\r
+\r
+  @param  TypeName     The name of the type.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrVarDataTypeDB::DataTypeHasBitField (\r
+  IN  CHAR8         *TypeName\r
+  )\r
+{\r
+  SVfrDataType        *pType  = NULL;\r
+  SVfrDataField       *pTmp;\r
+\r
+  GetDataType (TypeName, &pType);\r
+\r
+  if (pType == NULL){\r
+    return FALSE;\r
+  }\r
+  for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {\r
+    if (pTmp->mIsBitField) {\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Check whether the field is bit field or not.\r
+\r
+  @param  VarStr     Point to the field name which may contain the structure name.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrVarDataTypeDB::IsThisBitField (\r
+  IN  CHAR8   *VarStr\r
+  )\r
+{\r
+  CHAR8             FName[MAX_NAME_LEN];\r
+  CHAR8             TName[MAX_NAME_LEN];\r
+  UINT32            ArrayIdx;\r
+  SVfrDataType      *pType  = NULL;\r
+  SVfrDataField     *pField = NULL;\r
+\r
+  CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
+  CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
+\r
+  while (*VarStr != '\0') {\r
+    CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+    CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
+    pType  = pField->mFieldType;\r
+  }\r
+  if (pField != NULL && pField->mIsBitField) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
 EFI_VFR_RETURN_CODE\r
 CVfrVarDataTypeDB::ExtractFieldNameAndArrary (\r
   IN  CHAR8   *&VarStr,\r
@@ -622,6 +705,9 @@ CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
     if (*VarStr == ']') {\r
       VarStr++;\r
     }\r
+    if (*VarStr == '.') {\r
+      VarStr++;\r
+    }\r
     return VFR_RETURN_SUCCESS;\r
   case ']':\r
     return VFR_RETURN_DATA_STRING_ERROR;\r
@@ -632,18 +718,32 @@ CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
 \r
 EFI_VFR_RETURN_CODE\r
 CVfrVarDataTypeDB::GetTypeField (\r
-  IN  CHAR8          *FName,\r
+  IN  CONST CHAR8   *FName,\r
   IN  SVfrDataType  *Type,\r
   OUT SVfrDataField *&Field\r
   )\r
 {\r
   SVfrDataField  *pField = NULL;\r
 \r
-  if ((FName == NULL) && (Type == NULL)) {\r
+  if ((FName == NULL) || (Type == NULL)) {\r
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
 \r
   for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {\r
+    //\r
+    // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,\r
+    // add code to adjust it.\r
+    //\r
+    if (Type->mType == EFI_IFR_TYPE_TIME) {\r
+      if (strcmp (FName, "Hour") == 0) {\r
+        FName = "Hours";\r
+      } else if (strcmp (FName, "Minute") == 0) {\r
+        FName = "Minuts";\r
+      } else if (strcmp (FName, "Second") == 0) {\r
+        FName = "Seconds";\r
+      }\r
+    }\r
+\r
     if (strcmp (pField->mFieldName, FName) == 0) {\r
       Field = pField;\r
       return VFR_RETURN_SUCCESS;\r
@@ -657,13 +757,14 @@ EFI_VFR_RETURN_CODE
 CVfrVarDataTypeDB::GetFieldOffset (\r
   IN  SVfrDataField *Field,\r
   IN  UINT32        ArrayIdx,\r
-  OUT UINT32        &Offset\r
+  OUT UINT32        &Offset,\r
+  IN  BOOLEAN       IsBitField\r
   )\r
 {\r
   if (Field == NULL) {\r
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
-  \r
+\r
   //\r
   // Framework Vfr file Array Index is from 1.\r
   // But Uefi Vfr file Array Index is from 0.\r
@@ -678,7 +779,7 @@ CVfrVarDataTypeDB::GetFieldOffset (
   if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {\r
     return VFR_RETURN_ERROR_ARRARY_NUM;\r
   }\r
-  \r
+\r
   //\r
   // Be compatible with the current usage\r
   // If ArraryIdx is not specified, the first one is used.\r
@@ -689,8 +790,11 @@ CVfrVarDataTypeDB::GetFieldOffset (
   //   return VFR_RETURN_ERROR_ARRARY_NUM;\r
   // }\r
   //\r
-\r
-  Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+  if (IsBitField) {\r
+    Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;\r
+  } else {\r
+    Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);\r
+  }\r
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
@@ -709,7 +813,8 @@ CVfrVarDataTypeDB::GetFieldWidth (
 UINT32\r
 CVfrVarDataTypeDB::GetFieldSize (\r
   IN SVfrDataField *Field,\r
-  IN UINT32       ArrayIdx\r
+  IN UINT32       ArrayIdx,\r
+  IN BOOLEAN      BitField\r
   )\r
 {\r
   if (Field == NULL) {\r
@@ -717,9 +822,13 @@ CVfrVarDataTypeDB::GetFieldSize (
   }\r
 \r
   if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {\r
-    return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
+      return Field->mFieldType->mTotalSize * Field->mArrayNum;\r
   } else {\r
-    return Field->mFieldType->mTotalSize;\r
+    if (BitField) {\r
+      return Field->mBitWidth;\r
+    } else {\r
+      return Field->mFieldType->mTotalSize;\r
+    }\r
   }\r
 }\r
 \r
@@ -734,7 +843,9 @@ CVfrVarDataTypeDB::InternalTypesListInit (
   for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {\r
     New                 = new SVfrDataType;\r
     if (New != NULL) {\r
-      strcpy (New->mTypeName, gInternalTypesTable[Index].mTypeName);\r
+      assert (strlen (gInternalTypesTable[Index].mTypeName) < MAX_NAME_LEN);\r
+      strncpy (New->mTypeName, gInternalTypesTable[Index].mTypeName, MAX_NAME_LEN - 1);\r
+      New->mTypeName[MAX_NAME_LEN - 1] = 0;\r
       New->mType        = gInternalTypesTable[Index].mType;\r
       New->mAlign       = gInternalTypesTable[Index].mAlign;\r
       New->mTotalSize   = gInternalTypesTable[Index].mSize;\r
@@ -744,22 +855,25 @@ CVfrVarDataTypeDB::InternalTypesListInit (
         SVfrDataField *pDayField   = new SVfrDataField;\r
 \r
         strcpy (pYearField->mFieldName, "Year");\r
-        GetDataType ("UINT8", &pYearField->mFieldType);\r
+        GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);\r
         pYearField->mOffset      = 0;\r
         pYearField->mNext        = pMonthField;\r
         pYearField->mArrayNum    = 0;\r
+        pYearField->mIsBitField = FALSE;\r
 \r
         strcpy (pMonthField->mFieldName, "Month");\r
-        GetDataType ("UINT8", &pMonthField->mFieldType);\r
-        pMonthField->mOffset     = 1;\r
+        GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);\r
+        pMonthField->mOffset     = 2;\r
         pMonthField->mNext       = pDayField;\r
         pMonthField->mArrayNum   = 0;\r
+        pMonthField->mIsBitField = FALSE;\r
 \r
         strcpy (pDayField->mFieldName, "Day");\r
-        GetDataType ("UINT8", &pDayField->mFieldType);\r
-        pDayField->mOffset       = 2;\r
+        GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);\r
+        pDayField->mOffset       = 3;\r
         pDayField->mNext         = NULL;\r
         pDayField->mArrayNum     = 0;\r
+        pDayField->mIsBitField = FALSE;\r
 \r
         New->mMembers            = pYearField;\r
       } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {\r
@@ -768,24 +882,62 @@ CVfrVarDataTypeDB::InternalTypesListInit (
         SVfrDataField *pSecondsField = new SVfrDataField;\r
 \r
         strcpy (pHoursField->mFieldName, "Hours");\r
-        GetDataType ("UINT8", &pHoursField->mFieldType);\r
+        GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);\r
         pHoursField->mOffset     = 0;\r
         pHoursField->mNext       = pMinutesField;\r
         pHoursField->mArrayNum   = 0;\r
+        pHoursField->mIsBitField = FALSE;\r
 \r
         strcpy (pMinutesField->mFieldName, "Minutes");\r
-        GetDataType ("UINT8", &pMinutesField->mFieldType);\r
+        GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);\r
         pMinutesField->mOffset   = 1;\r
         pMinutesField->mNext     = pSecondsField;\r
         pMinutesField->mArrayNum = 0;\r
+        pMinutesField->mIsBitField = FALSE;\r
 \r
         strcpy (pSecondsField->mFieldName, "Seconds");\r
-        GetDataType ("UINT8", &pSecondsField->mFieldType);\r
+        GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);\r
         pSecondsField->mOffset   = 2;\r
         pSecondsField->mNext     = NULL;\r
         pSecondsField->mArrayNum = 0;\r
+        pSecondsField->mIsBitField = FALSE;\r
 \r
         New->mMembers            = pHoursField;\r
+      } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {\r
+        SVfrDataField *pQuestionIdField   = new SVfrDataField;\r
+        SVfrDataField *pFormIdField       = new SVfrDataField;\r
+        SVfrDataField *pFormSetGuidField  = new SVfrDataField;\r
+        SVfrDataField *pDevicePathField   = new SVfrDataField;\r
+\r
+        strcpy (pQuestionIdField->mFieldName, "QuestionId");\r
+        GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);\r
+        pQuestionIdField->mOffset     = 0;\r
+        pQuestionIdField->mNext       = pFormIdField;\r
+        pQuestionIdField->mArrayNum   = 0;\r
+        pQuestionIdField->mIsBitField = FALSE;\r
+\r
+        strcpy (pFormIdField->mFieldName, "FormId");\r
+        GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);\r
+        pFormIdField->mOffset   = 2;\r
+        pFormIdField->mNext     = pFormSetGuidField;\r
+        pFormIdField->mArrayNum = 0;\r
+        pFormIdField->mIsBitField = FALSE;\r
+\r
+        strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");\r
+        GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);\r
+        pFormSetGuidField->mOffset   = 4;\r
+        pFormSetGuidField->mNext     = pDevicePathField;\r
+        pFormSetGuidField->mArrayNum = 0;\r
+        pFormSetGuidField->mIsBitField = FALSE;\r
+\r
+        strcpy (pDevicePathField->mFieldName, "DevicePath");\r
+        GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);\r
+        pDevicePathField->mOffset   = 20;\r
+        pDevicePathField->mNext     = NULL;\r
+        pDevicePathField->mArrayNum = 0;\r
+        pDevicePathField->mIsBitField = FALSE;\r
+\r
+        New->mMembers            = pQuestionIdField;\r
       } else {\r
         New->mMembers            = NULL;\r
       }\r
@@ -806,6 +958,7 @@ CVfrVarDataTypeDB::CVfrVarDataTypeDB (
   mPackAlign     = DEFAULT_PACK_ALIGN;\r
   mPackStack     = NULL;\r
   mFirstNewDataTypeName = NULL;\r
+  mCurrDataType  = NULL;\r
 \r
   InternalTypesListInit ();\r
 }\r
@@ -830,7 +983,7 @@ CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
       pType->mMembers = pType->mMembers->mNext;\r
       delete pField;\r
     }\r
-       delete pType;\r
+  delete pType;\r
   }\r
 \r
   while (mPackStack != NULL) {\r
@@ -853,7 +1006,7 @@ CVfrVarDataTypeDB::Pack (
 \r
   if (Action & VFR_PACK_SHOW) {\r
     sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);\r
-    gCVfrErrorHandle.PrintMsg (LineNum, "", "Warning", Msg);\r
+    gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);\r
   }\r
 \r
   if (Action & VFR_PACK_PUSH) {\r
@@ -870,7 +1023,7 @@ CVfrVarDataTypeDB::Pack (
     SVfrPackStackNode *pNode = NULL;\r
 \r
     if (mPackStack == NULL) {\r
-      gCVfrErrorHandle.PrintMsg (LineNum, "", "Error", "#pragma pack(pop...) : more pops than pushes");\r
+      gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");\r
     }\r
 \r
     for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {\r
@@ -884,7 +1037,7 @@ CVfrVarDataTypeDB::Pack (
   if (Action & VFR_PACK_ASSIGN) {\r
     PackAlign = (Number > 1) ? Number + Number % 2 : Number;\r
     if ((PackAlign == 0) || (PackAlign > 16)) {\r
-      gCVfrErrorHandle.PrintMsg (LineNum, "", "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
+      gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");\r
     } else {\r
       mPackAlign = PackAlign;\r
     }\r
@@ -907,6 +1060,7 @@ CVfrVarDataTypeDB::DeclareDataTypeBegin (
   pNewType->mTotalSize   = 0;\r
   pNewType->mMembers     = NULL;\r
   pNewType->mNext        = NULL;\r
+  pNewType->mHasBitField = FALSE;\r
 \r
   mNewDataType           = pNewType;\r
 }\r
@@ -934,7 +1088,128 @@ CVfrVarDataTypeDB::SetNewTypeName (
     }\r
   }\r
 \r
-  strcpy(mNewDataType->mTypeName, TypeName);\r
+  strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1);\r
+  mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0;\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Record the bit field info in the data type.\r
+\r
+  @param  FieldName     Point to the field name.\r
+  @param  TypeName      Point to the type name.\r
+  @param  Width         The bit width.\r
+  @param  FieldInUnion  The filed is in Union type or Structure type.\r
+\r
+**/\r
+EFI_VFR_RETURN_CODE\r
+CVfrVarDataTypeDB::DataTypeAddBitField (\r
+  IN CHAR8   *FieldName,\r
+  IN CHAR8   *TypeName,\r
+  IN UINT32   Width,\r
+  IN BOOLEAN FieldInUnion\r
+  )\r
+{\r
+  SVfrDataField       *pNewField  = NULL;\r
+  SVfrDataType        *pFieldType = NULL;\r
+  SVfrDataField       *pTmp;\r
+  UINT32              Align;\r
+  UINT32              MaxDataTypeSize;\r
+  BOOLEAN             UpdateTotalSize;\r
+\r
+  CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
+\r
+  if (Width > MAX_BIT_WIDTH) {\r
+    return VFR_RETURN_BIT_WIDTH_ERROR;\r
+  }\r
+\r
+  if (Width > pFieldType->mTotalSize * 8) {\r
+    return VFR_RETURN_BIT_WIDTH_ERROR;\r
+  }\r
+\r
+  if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {\r
+   return VFR_RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 && FieldName != NULL) {\r
+    return VFR_RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {\r
+    if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {\r
+      return VFR_RETURN_REDEFINED;\r
+    }\r
+  }\r
+\r
+  Align = MIN (mPackAlign, pFieldType->mAlign);\r
+  UpdateTotalSize = FALSE;\r
+\r
+  if ((pNewField = new SVfrDataField) == NULL) {\r
+    return VFR_RETURN_OUT_FOR_RESOURCES;\r
+  }\r
+\r
+  MaxDataTypeSize = mNewDataType->mTotalSize;\r
+  if (FieldName != NULL) {\r
+    strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);\r
+    pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;\r
+  }\r
+  pNewField->mFieldType    = pFieldType;\r
+  pNewField->mIsBitField   = TRUE;\r
+  pNewField->mBitWidth     = Width;\r
+  pNewField->mArrayNum     = 0;\r
+  pNewField->mBitOffset    = 0;\r
+  pNewField->mOffset       = 0;\r
+\r
+  if (mNewDataType->mMembers == NULL) {\r
+    mNewDataType->mMembers = pNewField;\r
+    pNewField->mNext       = NULL;\r
+  } else {\r
+    for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)\r
+      ;\r
+    pTmp->mNext            = pNewField;\r
+    pNewField->mNext       = NULL;\r
+  }\r
+\r
+  if (FieldInUnion) {\r
+    pNewField->mOffset = 0;\r
+    if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
+      mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
+    }\r
+  } else {\r
+    //\r
+    // Check whether the bit fields can be contained within one FieldType.\r
+    //\r
+    if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&\r
+       (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {\r
+      pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;\r
+      pNewField->mOffset = pTmp->mOffset;\r
+      //\r
+      // If BitWidth=0,used to force alignment at the next word boundary.\r
+      // So make this bit field occupy the remaing bit width of current field type.\r
+      //\r
+      if (pNewField->mBitWidth == 0) {\r
+        pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);\r
+      }\r
+    } else {\r
+      //\r
+      // The bit filed start a new memory\r
+      //\r
+      pNewField->mBitOffset = mNewDataType->mTotalSize * 8;\r
+      UpdateTotalSize = TRUE;\r
+    }\r
+  }\r
+\r
+  if (UpdateTotalSize){\r
+    if ((mNewDataType->mTotalSize % Align) == 0) {\r
+      pNewField->mOffset     = mNewDataType->mTotalSize;\r
+    } else {\r
+      pNewField->mOffset     = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);\r
+    }\r
+    mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);\r
+  }\r
+\r
+  mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
+  mNewDataType->mHasBitField = TRUE;\r
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
@@ -942,15 +1217,18 @@ EFI_VFR_RETURN_CODE
 CVfrVarDataTypeDB::DataTypeAddField (\r
   IN CHAR8   *FieldName,\r
   IN CHAR8   *TypeName,\r
-  IN UINT32 ArrayNum\r
+  IN UINT32 ArrayNum,\r
+  IN BOOLEAN FieldInUnion\r
   )\r
 {\r
   SVfrDataField       *pNewField  = NULL;\r
   SVfrDataType        *pFieldType = NULL;\r
   SVfrDataField       *pTmp;\r
   UINT32              Align;\r
+  UINT32              MaxDataTypeSize;\r
 \r
   CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);\r
+  MaxDataTypeSize = mNewDataType->mTotalSize;\r
 \r
   if (strlen (FieldName) >= MAX_NAME_LEN) {\r
    return VFR_RETURN_INVALID_PARAMETER;\r
@@ -967,9 +1245,11 @@ CVfrVarDataTypeDB::DataTypeAddField (
   if ((pNewField = new SVfrDataField) == NULL) {\r
     return VFR_RETURN_OUT_FOR_RESOURCES;\r
   }\r
-  strcpy (pNewField->mFieldName, FieldName);\r
+  strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);\r
+  pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;\r
   pNewField->mFieldType    = pFieldType;\r
   pNewField->mArrayNum     = ArrayNum;\r
+  pNewField->mIsBitField   = FALSE;\r
   if ((mNewDataType->mTotalSize % Align) == 0) {\r
     pNewField->mOffset     = mNewDataType->mTotalSize;\r
   } else {\r
@@ -986,7 +1266,15 @@ CVfrVarDataTypeDB::DataTypeAddField (
   }\r
 \r
   mNewDataType->mAlign     = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));\r
-  mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
+\r
+  if (FieldInUnion) {\r
+    if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {\r
+      mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;\r
+    }\r
+    pNewField->mOffset = 0;\r
+  } else {\r
+    mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);\r
+  }\r
 \r
   return VFR_RETURN_SUCCESS;\r
 }\r
@@ -1101,21 +1389,26 @@ CVfrVarDataTypeDB::GetDataFieldInfo (
   IN  CHAR8     *VarStr,\r
   OUT UINT16   &Offset,\r
   OUT UINT8    &Type,\r
-  OUT UINT32   &Size\r
+  OUT UINT32   &Size,\r
+  OUT BOOLEAN  &BitField\r
   )\r
 {\r
   CHAR8               TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];\r
   UINT32              ArrayIdx, Tmp;\r
   SVfrDataType        *pType  = NULL;\r
   SVfrDataField       *pField = NULL;\r
+  CHAR8               *VarStrName;\r
 \r
   Offset = 0;\r
   Type   = EFI_IFR_TYPE_OTHER;\r
   Size   = 0;\r
+  VarStrName = VarStr;\r
 \r
   CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);\r
   CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);\r
 \r
+  BitField = IsThisBitField (VarStrName);\r
+\r
   //\r
   // if it is not struct data type\r
   //\r
@@ -1123,13 +1416,17 @@ CVfrVarDataTypeDB::GetDataFieldInfo (
   Size  = pType->mTotalSize;\r
 \r
   while (*VarStr != '\0') {\r
-       CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
+    CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);\r
     CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);\r
     pType  = pField->mFieldType;\r
-    CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp), VFR_RETURN_SUCCESS);\r
-    Offset += Tmp;\r
+    CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);\r
+    if (BitField && !pField->mIsBitField) {\r
+      Offset = (UINT16) (Offset + Tmp * 8);\r
+    } else {\r
+      Offset = (UINT16) (Offset + Tmp);\r
+    }\r
     Type   = GetFieldWidth (pField);\r
-    Size   = GetFieldSize (pField, ArrayIdx);\r
+    Size   = GetFieldSize (pField, ArrayIdx, BitField);\r
   }\r
   return VFR_RETURN_SUCCESS;\r
 }\r
@@ -1208,10 +1505,10 @@ CVfrVarDataTypeDB::Dump (
     fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);\r
     for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {\r
       if (pFNode->mArrayNum > 0) {\r
-        fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
+        fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,\r
                   pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);\r
       } else {\r
-        fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset, \r
+        fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,\r
                   pFNode->mFieldName, pFNode->mFieldType->mTypeName);\r
       }\r
     }\r
@@ -1239,7 +1536,7 @@ CVfrVarDataTypeDB::ParserDB (
       printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);\r
     }\r
     printf ("\t\t};\n");\r
-       printf ("---------------------------------------------------------------\n");\r
+  printf ("---------------------------------------------------------------\n");\r
   }\r
   printf ("***************************************************************\n");\r
 }\r
@@ -1257,7 +1554,7 @@ SVfrVarStorageNode::SVfrVarStorageNode (
   if (Guid != NULL) {\r
     mGuid = *Guid;\r
   } else {\r
-    memset (&Guid, 0, sizeof (EFI_GUID));\r
+    memset (&mGuid, 0, sizeof (EFI_GUID));\r
   }\r
   if (StoreName != NULL) {\r
     mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
@@ -1278,13 +1575,14 @@ SVfrVarStorageNode::SVfrVarStorageNode (
   IN CHAR8                 *StoreName,\r
   IN EFI_VARSTORE_ID       VarStoreId,\r
   IN SVfrDataType          *DataType,\r
+  IN BOOLEAN               BitsVarstore,\r
   IN BOOLEAN               Flag\r
   )\r
 {\r
   if (Guid != NULL) {\r
     mGuid = *Guid;\r
   } else {\r
-    memset (&Guid, 0, sizeof (EFI_GUID));\r
+    memset (&mGuid, 0, sizeof (EFI_GUID));\r
   }\r
   if (StoreName != NULL) {\r
     mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
@@ -1294,7 +1592,11 @@ SVfrVarStorageNode::SVfrVarStorageNode (
   }\r
   mNext                    = NULL;\r
   mVarStoreId              = VarStoreId;\r
-  mVarStoreType            = EFI_VFR_VARSTORE_BUFFER;\r
+  if (BitsVarstore) {\r
+    mVarStoreType            = EFI_VFR_VARSTORE_BUFFER_BITS;\r
+  } else {\r
+    mVarStoreType            = EFI_VFR_VARSTORE_BUFFER;\r
+  }\r
   mStorageInfo.mDataType   = DataType;\r
   mAssignedFlag            = Flag;\r
 }\r
@@ -1304,6 +1606,7 @@ SVfrVarStorageNode::SVfrVarStorageNode (
   IN EFI_VARSTORE_ID       VarStoreId\r
   )\r
 {\r
+  memset (&mGuid, 0, sizeof (EFI_GUID));\r
   if (StoreName != NULL) {\r
     mVarStoreName = new CHAR8[strlen(StoreName) + 1];\r
     strcpy (mVarStoreName, StoreName);\r
@@ -1315,6 +1618,7 @@ SVfrVarStorageNode::SVfrVarStorageNode (
   mVarStoreType                      = EFI_VFR_VARSTORE_NAME;\r
   mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];\r
   mStorageInfo.mNameSpace.mTableSize = 0;\r
+  mAssignedFlag                      = FALSE;\r
 }\r
 \r
 SVfrVarStorageNode::~SVfrVarStorageNode (\r
@@ -1322,11 +1626,11 @@ SVfrVarStorageNode::~SVfrVarStorageNode (
   )\r
 {\r
   if (mVarStoreName != NULL) {\r
-    delete mVarStoreName;\r
+    delete[] mVarStoreName;\r
   }\r
 \r
   if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
-    delete mStorageInfo.mNameSpace.mNameTable;\r
+    delete[] mStorageInfo.mNameSpace.mNameTable;\r
   }\r
 }\r
 \r
@@ -1348,6 +1652,8 @@ CVfrDataStorage::CVfrDataStorage (
   mNameVarStoreList        = NULL;\r
   mCurrVarStorageNode      = NULL;\r
   mNewVarStorageNode       = NULL;\r
+  mBufferFieldInfoListHead = NULL;\r
+  mBufferFieldInfoListTail = NULL;\r
 }\r
 \r
 CVfrDataStorage::~CVfrDataStorage (\r
@@ -1382,10 +1688,11 @@ CVfrDataStorage::GetFreeVarStoreId (
   )\r
 {\r
   UINT32  Index, Mask, Offset;\r
-  \r
+\r
   //\r
   // Assign the different ID range for the different type VarStore to support Framework Vfr\r
   //\r
+  Index = 0;\r
   if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {\r
     Index = 0;\r
   } else if (VarType == EFI_VFR_VARSTORE_EFI) {\r
@@ -1400,6 +1707,10 @@ CVfrDataStorage::GetFreeVarStoreId (
     }\r
   }\r
 \r
+  if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {\r
+    return EFI_VARSTORE_ID_INVALID;\r
+  }\r
+\r
   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
     if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {\r
       mFreeVarStoreIdBitMap[Index] |= Mask;\r
@@ -1445,23 +1756,30 @@ CVfrDataStorage::MarkVarStoreIdUnused (
 \r
 EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::DeclareNameVarStoreBegin (\r
-  IN CHAR8    *StoreName\r
+  IN CHAR8           *StoreName,\r
+  IN EFI_VARSTORE_ID VarStoreId\r
   )\r
 {\r
   SVfrVarStorageNode *pNode = NULL;\r
-  EFI_VARSTORE_ID    VarStoreId;\r
+  EFI_VARSTORE_ID    TmpVarStoreId;\r
 \r
   if (StoreName == NULL) {\r
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
 \r
-  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      return VFR_RETURN_REDEFINED;\r
+  if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {\r
+    return VFR_RETURN_REDEFINED;\r
+  }\r
+\r
+  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
+    VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
+  } else {\r
+    if (ChekVarStoreIdFree (VarStoreId) == FALSE) {\r
+      return VFR_RETURN_VARSTOREID_REDEFINED;\r
     }\r
+    MarkVarStoreIdUsed (VarStoreId);\r
   }\r
 \r
-  VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\r
   if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
     return VFR_RETURN_UNDEFINED;\r
   }\r
@@ -1510,10 +1828,10 @@ CVfrDataStorage::DeclareNameVarStoreEnd (
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
-EFI_VFR_RETURN_CODE \r
+EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::DeclareEfiVarStore (\r
-  IN CHAR8          *StoreName, \r
-  IN EFI_GUID       *Guid, \r
+  IN CHAR8          *StoreName,\r
+  IN EFI_GUID       *Guid,\r
   IN EFI_STRING_ID  NameStrId,\r
   IN UINT32         VarSize,\r
   IN BOOLEAN        Flag\r
@@ -1530,10 +1848,8 @@ CVfrDataStorage::DeclareEfiVarStore (
     return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
   }\r
 \r
-  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      return VFR_RETURN_REDEFINED;\r
-    }\r
+  if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
+    return VFR_RETURN_REDEFINED;\r
   }\r
 \r
   VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);\r
@@ -1547,23 +1863,29 @@ CVfrDataStorage::DeclareEfiVarStore (
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
-EFI_VFR_RETURN_CODE \r
+EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::DeclareBufferVarStore (\r
-  IN CHAR8             *StoreName, \r
-  IN EFI_GUID          *Guid, \r
+  IN CHAR8             *StoreName,\r
+  IN EFI_GUID          *Guid,\r
   IN CVfrVarDataTypeDB *DataTypeDB,\r
   IN CHAR8             *TypeName,\r
   IN EFI_VARSTORE_ID   VarStoreId,\r
+  IN BOOLEAN           IsBitVarStore,\r
   IN BOOLEAN           Flag\r
   )\r
 {\r
   SVfrVarStorageNode   *pNew = NULL;\r
   SVfrDataType         *pDataType = NULL;\r
+  EFI_VARSTORE_ID      TempVarStoreId;\r
 \r
   if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {\r
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
 \r
+  if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
+    return VFR_RETURN_REDEFINED;\r
+  }\r
+\r
   CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);\r
 \r
   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
@@ -1575,121 +1897,197 @@ CVfrDataStorage::DeclareBufferVarStore (
     MarkVarStoreIdUsed (VarStoreId);\r
   }\r
 \r
-  if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, Flag)) == NULL) {\r
+  if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {\r
     return VFR_RETURN_OUT_FOR_RESOURCES;\r
   }\r
 \r
   pNew->mNext         = mBufferVarStoreList;\r
   mBufferVarStoreList = pNew;\r
 \r
-  if (gCVfrBufferConfig.Register(StoreName) != 0) {\r
+  if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {\r
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
 \r
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
-EFI_VFR_RETURN_CODE \r
-CVfrDataStorage::GetVarStoreId (\r
-  IN  CHAR8           *StoreName,\r
-  OUT EFI_VARSTORE_ID *VarStoreId\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetVarStoreByDataType (\r
+  IN  CHAR8              *DataTypeName,\r
+  OUT SVfrVarStorageNode **VarNode,\r
+  IN  EFI_GUID           *VarGuid\r
   )\r
 {\r
   SVfrVarStorageNode    *pNode;\r
+  SVfrVarStorageNode    *MatchNode;\r
+\r
+  //\r
+  // Framework VFR uses Data type name as varstore name, so don't need check again.\r
+  //\r
+  if (VfrCompatibleMode) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
 \r
+  MatchNode = NULL;\r
   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      mCurrVarStorageNode = pNode;\r
-      *VarStoreId = pNode->mVarStoreId;\r
-      return VFR_RETURN_SUCCESS;\r
+    if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {\r
+      continue;\r
     }\r
-  }\r
 \r
-  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      mCurrVarStorageNode = pNode;\r
-      *VarStoreId = pNode->mVarStoreId;\r
-      return VFR_RETURN_SUCCESS;\r
+    if ((VarGuid != NULL)) {\r
+      if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
+        *VarNode = pNode;\r
+        return VFR_RETURN_SUCCESS;\r
+      }\r
+    } else {\r
+      if (MatchNode == NULL) {\r
+        MatchNode = pNode;\r
+      } else {\r
+        //\r
+        // More than one varstores referred the same data structures.\r
+        //\r
+        return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;\r
+      }\r
     }\r
   }\r
 \r
-  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+  if (MatchNode == NULL) {\r
+    return VFR_RETURN_UNDEFINED;\r
+  }\r
+\r
+  *VarNode = MatchNode;\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VARSTORE_ID\r
+CVfrDataStorage::CheckGuidField (\r
+  IN  SVfrVarStorageNode   *pNode,\r
+  IN  EFI_GUID             *StoreGuid,\r
+  IN  BOOLEAN              *HasFoundOne,\r
+  OUT EFI_VFR_RETURN_CODE  *ReturnCode\r
+  )\r
+{\r
+  if (StoreGuid != NULL) {\r
+    //\r
+    // If has guid info, compare the guid filed.\r
+    //\r
+    if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {\r
+      //\r
+      // Both name and guid are same, this this varstore.\r
+      //\r
       mCurrVarStorageNode = pNode;\r
-      *VarStoreId = pNode->mVarStoreId;\r
-      return VFR_RETURN_SUCCESS;\r
+      *ReturnCode = VFR_RETURN_SUCCESS;\r
+      return TRUE;\r
+    }\r
+  } else {\r
+    //\r
+    // Not has Guid field, check whether this name is the only one.\r
+    //\r
+    if (*HasFoundOne) {\r
+      //\r
+      // The name has conflict, return name redefined.\r
+      //\r
+      *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;\r
+      return TRUE;\r
     }\r
+\r
+    *HasFoundOne = TRUE;\r
+    mCurrVarStorageNode = pNode;\r
   }\r
 \r
-  mCurrVarStorageNode = NULL;\r
-  *VarStoreId        = EFI_VARSTORE_ID_INVALID;\r
-  return VFR_RETURN_UNDEFINED;\r
+  return FALSE;\r
 }\r
 \r
+/**\r
+  Base on the input store name and guid to find the varstore id.\r
+\r
+  If both name and guid are inputed, base on the name and guid to\r
+  found the varstore. If only name inputed, base on the name to\r
+  found the varstore and go on to check whether more than one varstore\r
+  has the same name. If only has found one varstore, return this\r
+  varstore; if more than one varstore has same name, return varstore\r
+  name redefined error. If no varstore found by varstore name, call\r
+  function GetVarStoreByDataType and use inputed varstore name as\r
+  data type name to search.\r
+**/\r
 EFI_VFR_RETURN_CODE\r
-CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
-  IN  CHAR8                  *StoreName,\r
-  OUT CHAR8                  **DataTypeName\r
+CVfrDataStorage::GetVarStoreId (\r
+  IN  CHAR8           *StoreName,\r
+  OUT EFI_VARSTORE_ID *VarStoreId,\r
+  IN  EFI_GUID        *StoreGuid\r
   )\r
 {\r
+  EFI_VFR_RETURN_CODE   ReturnCode;\r
   SVfrVarStorageNode    *pNode;\r
+  BOOLEAN               HasFoundOne = FALSE;\r
 \r
-  if ((StoreName == NULL) || (DataTypeName == NULL)) {\r
-    return VFR_RETURN_FATAL_ERROR;\r
-  }\r
+  mCurrVarStorageNode = NULL;\r
 \r
   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
     if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      break;\r
+      if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+        *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+        return ReturnCode;\r
+      }\r
     }\r
   }\r
 \r
-  if (pNode == NULL) {\r
-    return VFR_RETURN_UNDEFINED;\r
+  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+        *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+        return ReturnCode;\r
+      }\r
+    }\r
   }\r
 \r
-  if (pNode->mStorageInfo.mDataType == NULL) {\r
-    return VFR_RETURN_FATAL_ERROR;\r
+  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+      if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+        *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+        return ReturnCode;\r
+      }\r
+    }\r
   }\r
 \r
-  *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
-  return VFR_RETURN_SUCCESS;\r
+  if (HasFoundOne) {\r
+    *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+    return VFR_RETURN_SUCCESS;\r
+  }\r
+\r
+  *VarStoreId         = EFI_VARSTORE_ID_INVALID;\r
+\r
+  //\r
+  // Assume that Data structure name is used as StoreName, and check again.\r
+  //\r
+  ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);\r
+  if (pNode != NULL) {\r
+    mCurrVarStorageNode = pNode;\r
+    *VarStoreId = pNode->mVarStoreId;\r
+  }\r
+\r
+  return ReturnCode;\r
 }\r
 \r
 EFI_VFR_RETURN_CODE\r
-CVfrDataStorage::GetVarStoreType (\r
-  IN  CHAR8                  *StoreName,\r
-  OUT EFI_VFR_VARSTORE_TYPE  &VarStoreType\r
+CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
+  IN  EFI_VARSTORE_ID        VarStoreId,\r
+  OUT CHAR8                  **DataTypeName\r
   )\r
 {\r
   SVfrVarStorageNode    *pNode;\r
 \r
-  if (StoreName == NULL) {\r
+  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
 \r
   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      VarStoreType = pNode->mVarStoreType;\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
       return VFR_RETURN_SUCCESS;\r
     }\r
   }\r
 \r
-  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      VarStoreType = pNode->mVarStoreType;\r
-      return VFR_RETURN_SUCCESS;\r
-    }\r
-  }\r
-\r
-  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      VarStoreType = pNode->mVarStoreType;\r
-      return VFR_RETURN_SUCCESS;\r
-    }\r
-  }\r
-\r
-  VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
   return VFR_RETURN_UNDEFINED;\r
 }\r
 \r
@@ -1731,9 +2129,47 @@ CVfrDataStorage::GetVarStoreType (
   return VarStoreType;\r
 }\r
 \r
+EFI_GUID *\r
+CVfrDataStorage::GetVarStoreGuid (\r
+  IN  EFI_VARSTORE_ID        VarStoreId\r
+  )\r
+{\r
+  SVfrVarStorageNode    *pNode;\r
+  EFI_GUID              *VarGuid;\r
+\r
+  VarGuid = NULL;\r
+\r
+  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
+    return VarGuid;\r
+  }\r
+\r
+  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      VarGuid = &pNode->mGuid;\r
+      return VarGuid;\r
+    }\r
+  }\r
+\r
+  for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      VarGuid = &pNode->mGuid;\r
+      return VarGuid;\r
+    }\r
+  }\r
+\r
+  for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      VarGuid = &pNode->mGuid;\r
+      return VarGuid;\r
+    }\r
+  }\r
+\r
+  return VarGuid;\r
+}\r
+\r
 EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::GetVarStoreName (\r
-  IN  EFI_VARSTORE_ID VarStoreId, \r
+  IN  EFI_VARSTORE_ID VarStoreId,\r
   OUT CHAR8           **VarStoreName\r
   )\r
 {\r
@@ -1803,6 +2239,48 @@ CVfrDataStorage::GetEfiVarStoreInfo (
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::AddBufferVarStoreFieldInfo (\r
+  IN EFI_VARSTORE_INFO  *Info\r
+  )\r
+{\r
+  BufferVarStoreFieldInfoNode *pNew;\r
+\r
+  if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {\r
+    return VFR_RETURN_FATAL_ERROR;\r
+  }\r
+\r
+  if (mBufferFieldInfoListHead == NULL) {\r
+    mBufferFieldInfoListHead = pNew;\r
+    mBufferFieldInfoListTail= pNew;\r
+  } else {\r
+    mBufferFieldInfoListTail->mNext = pNew;\r
+    mBufferFieldInfoListTail = pNew;\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CVfrDataStorage::GetBufferVarStoreFieldInfo (\r
+  IN OUT EFI_VARSTORE_INFO  *Info\r
+  )\r
+{\r
+  BufferVarStoreFieldInfoNode *pNode;\r
+\r
+  pNode = mBufferFieldInfoListHead;\r
+  while (pNode != NULL) {\r
+    if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&\r
+      Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {\r
+      Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;\r
+      Info->mVarType      = pNode->mVarStoreInfo.mVarType;\r
+      return VFR_RETURN_SUCCESS;\r
+    }\r
+    pNode = pNode->mNext;\r
+  }\r
+  return VFR_RETURN_FATAL_ERROR;\r
+}\r
+\r
 EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::GetNameVarStoreInfo (\r
   OUT EFI_VARSTORE_INFO  *Info,\r
@@ -1816,7 +2294,7 @@ CVfrDataStorage::GetNameVarStoreInfo (
   if (mCurrVarStorageNode == NULL) {\r
     return VFR_RETURN_GET_NVVARSTORE_ERROR;\r
   }\r
-  \r
+\r
   //\r
   // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.\r
   //\r
@@ -1832,41 +2310,10 @@ CVfrDataStorage::GetNameVarStoreInfo (
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
-EFI_VFR_RETURN_CODE\r
-CVfrDataStorage::BufferVarStoreRequestElementAdd (\r
-  IN CHAR8             *StoreName,\r
-  IN EFI_VARSTORE_INFO &Info\r
-  )\r
-{\r
-  CHAR8                 NewReqElt[128] = {'\0',};\r
-  CHAR8                 *OldReqElt = NULL;\r
-  SVfrVarStorageNode    *pNode = NULL;\r
-  EFI_IFR_TYPE_VALUE    Value = gZeroEfiIfrTypeValue;\r
-\r
-  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == NULL) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (pNode == NULL) {\r
-    return VFR_RETURN_UNDEFINED;\r
-  }\r
-\r
-  gCVfrBufferConfig.Open ();\r
-  Value.u8 = 0;\r
-  if (gCVfrBufferConfig.Write ('a', StoreName, NULL, EFI_IFR_TYPE_NUM_SIZE_8, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value) != 0) {\r
-    return VFR_RETURN_FATAL_ERROR;\r
-  }\r
-  gCVfrBufferConfig.Close ();\r
-\r
-  return VFR_RETURN_SUCCESS;\r
-}\r
-\r
 SVfrDefaultStoreNode::SVfrDefaultStoreNode (\r
   IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,\r
-  IN CHAR8                *RefName, \r
-  IN EFI_STRING_ID        DefaultStoreNameId, \r
+  IN CHAR8                *RefName,\r
+  IN EFI_STRING_ID        DefaultStoreNameId,\r
   IN UINT16               DefaultId\r
   )\r
 {\r
@@ -1889,7 +2336,7 @@ SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
   )\r
 {\r
   if (mRefName != NULL) {\r
-    delete mRefName;\r
+    delete[] mRefName;\r
   }\r
 }\r
 \r
@@ -1944,7 +2391,7 @@ CVfrDefaultStore::RegisterDefaultStore (
 }\r
 \r
 /*\r
- * assign new reference name or new default store name id only if \r
+ * assign new reference name or new default store name id only if\r
  * the original is invalid\r
  */\r
 EFI_VFR_RETURN_CODE\r
@@ -2024,90 +2471,12 @@ CVfrDefaultStore::GetDefaultId (
   return VFR_RETURN_UNDEFINED;\r
 }\r
 \r
-STATIC\r
-EFI_VFR_RETURN_CODE\r
-AltCfgItemPrintToBuffer (\r
-  IN CHAR8              *NewAltCfg, \r
-  IN EFI_VARSTORE_INFO  Info, \r
-  IN UINT8              Type,\r
-  IN EFI_IFR_TYPE_VALUE Value\r
-  )\r
-{\r
-  UINT32 Index;\r
-  UINT8  *BufChar = NULL;\r
-  UINT32 Count    = 0;\r
-\r
-  if (NewAltCfg != NULL) {\r
-    Count = sprintf (\r
-              NewAltCfg,\r
-              "&OFFSET=%x&WIDTH=%x&VALUE=",\r
-              Info.mInfo.mVarOffset,\r
-              Info.mVarTotalSize\r
-              );\r
-    NewAltCfg += Count;\r
-\r
-    switch (Type) {\r
-    case EFI_IFR_TYPE_NUM_SIZE_8 :\r
-      Count = sprintf (NewAltCfg, "%x", Value.u8);\r
-      NewAltCfg += Count;\r
-      break;\r
-    case EFI_IFR_TYPE_NUM_SIZE_16 :\r
-      Count = sprintf (NewAltCfg, "%x", Value.u16);\r
-      NewAltCfg += Count;\r
-      break;\r
-    case EFI_IFR_TYPE_NUM_SIZE_32 :\r
-      Count = sprintf (NewAltCfg, "%x", Value.u32);\r
-      NewAltCfg += Count;\r
-      break;\r
-    case EFI_IFR_TYPE_NUM_SIZE_64 :\r
-      Count = sprintf (NewAltCfg, "%x", Value.u64);\r
-      NewAltCfg += Count;\r
-      break;\r
-    case EFI_IFR_TYPE_BOOLEAN :\r
-      Count = sprintf (NewAltCfg, "%x", Value.b);\r
-      NewAltCfg += Count;\r
-      break;\r
-    case EFI_IFR_TYPE_TIME :\r
-#if 1\r
-      Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.time)));\r
-      NewAltCfg += Count;\r
-#else\r
-      BufChar = (UINT8 *)&Value.time;\r
-      for (Index = 0; Index < sizeof(EFI_HII_TIME); Index++) {\r
-        Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
-        NewAltCfg += Count;\r
-      }\r
-#endif\r
-      break;\r
-    case EFI_IFR_TYPE_DATE :\r
-#if 1\r
-      Count = sprintf (NewAltCfg, "%x", *((UINT32 *)(&Value.date)));\r
-      NewAltCfg += Count;\r
-#else\r
-      BufChar = (UINT8 *)&Value.date;\r
-      for (Index = 0; Index < sizeof(EFI_HII_DATE); Index++) {\r
-        Count = sprintf (NewAltCfg, "%02x", (UINT8)BufChar[Index]);\r
-        NewAltCfg += Count;\r
-      }\r
-#endif\r
-      break;\r
-    case EFI_IFR_TYPE_STRING :\r
-      Count = sprintf (NewAltCfg, "%x", Value.string);\r
-      NewAltCfg += Count;\r
-      break;\r
-    case EFI_IFR_TYPE_OTHER :\r
-      return VFR_RETURN_UNSUPPORTED;\r
-       }\r
-  }\r
-\r
-  return VFR_RETURN_FATAL_ERROR;\r
-}\r
-\r
 EFI_VFR_RETURN_CODE\r
 CVfrDefaultStore::BufferVarStoreAltConfigAdd (\r
   IN EFI_VARSTORE_ID    DefaultId,\r
   IN EFI_VARSTORE_INFO  &Info,\r
   IN CHAR8              *VarStoreName,\r
+  IN EFI_GUID           *VarStoreGuid,\r
   IN UINT8              Type,\r
   IN EFI_IFR_TYPE_VALUE Value\r
   )\r
@@ -2133,12 +2502,12 @@ CVfrDefaultStore::BufferVarStoreAltConfigAdd (
   gCVfrBufferConfig.Open ();\r
 \r
   sprintf (NewAltCfg, "%04x", pNode->mDefaultId);\r
-  if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName)) == 0) {\r
-    if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
+  if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {\r
+    if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {\r
       goto WriteError;\r
     }\r
   }\r
-  \r
+\r
   gCVfrBufferConfig.Close ();\r
 \r
   return VFR_RETURN_SUCCESS;\r
@@ -2169,7 +2538,7 @@ SVfrRuleNode::~SVfrRuleNode (
   )\r
 {\r
   if (mRuleName != NULL) {\r
-    delete mRuleName;\r
+    delete[] mRuleName;\r
   }\r
 }\r
 \r
@@ -2242,6 +2611,7 @@ EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
   mInfo.mVarOffset = EFI_VAROFFSET_INVALID;\r
   mVarType         = EFI_IFR_TYPE_OTHER;\r
   mVarTotalSize    = 0;\r
+  mIsBitVar        = FALSE;\r
 }\r
 \r
 EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (\r
@@ -2253,6 +2623,24 @@ EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
   mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
   mVarType         = Info.mVarType;\r
   mVarTotalSize    = Info.mVarTotalSize;\r
+  mIsBitVar        = Info.mIsBitVar;\r
+}\r
+\r
+EFI_VARSTORE_INFO&\r
+EFI_VARSTORE_INFO::operator= (\r
+  IN CONST EFI_VARSTORE_INFO &Info\r
+  )\r
+{\r
+  if (this != &Info) {\r
+    mVarStoreId      = Info.mVarStoreId;\r
+    mInfo.mVarName   = Info.mInfo.mVarName;\r
+    mInfo.mVarOffset = Info.mInfo.mVarOffset;\r
+    mVarType         = Info.mVarType;\r
+    mVarTotalSize    = Info.mVarTotalSize;\r
+    mIsBitVar        = Info.mIsBitVar;\r
+  }\r
+\r
+  return *this;\r
 }\r
 \r
 BOOLEAN\r
@@ -2261,16 +2649,37 @@ EFI_VARSTORE_INFO::operator == (
   )\r
 {\r
   if ((mVarStoreId == Info->mVarStoreId) &&\r
-         (mInfo.mVarName == Info->mInfo.mVarName) &&\r
+      (mInfo.mVarName == Info->mInfo.mVarName) &&\r
       (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&\r
       (mVarType == Info->mVarType) &&\r
-      (mVarTotalSize == Info->mVarTotalSize)) {\r
+      (mVarTotalSize == Info->mVarTotalSize) &&\r
+      (mIsBitVar == Info->mIsBitVar)) {\r
     return TRUE;\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
+BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(\r
+  IN EFI_VARSTORE_INFO  *Info\r
+  )\r
+{\r
+  mVarStoreInfo.mVarType               = Info->mVarType;\r
+  mVarStoreInfo.mVarTotalSize          = Info->mVarTotalSize;\r
+  mVarStoreInfo.mInfo.mVarOffset       = Info->mInfo.mVarOffset;\r
+  mVarStoreInfo.mVarStoreId            = Info->mVarStoreId;\r
+  mNext = NULL;\r
+}\r
+\r
+BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()\r
+{\r
+  mVarStoreInfo.mVarType               = EFI_IFR_TYPE_OTHER;\r
+  mVarStoreInfo.mVarTotalSize          = 0;\r
+  mVarStoreInfo.mInfo.mVarOffset       = EFI_VAROFFSET_INVALID;\r
+  mVarStoreInfo.mVarStoreId            = EFI_VARSTORE_ID_INVALID;\r
+  mNext = NULL;\r
+}\r
+\r
 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;\r
 \r
 EFI_QUESTION_ID\r
@@ -2286,6 +2695,10 @@ CVfrQuestionDB::GetFreeQuestionId (
     }\r
   }\r
 \r
+  if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {\r
+    return EFI_QUESTION_ID_INVALID;\r
+  }\r
+\r
   for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {\r
     if ((mFreeQIdBitMap[Index] & Mask) == 0) {\r
       mFreeQIdBitMap[Index] |= Mask;\r
@@ -2340,6 +2753,7 @@ SVfrQuestionNode::SVfrQuestionNode (
   mQuestionId = EFI_QUESTION_ID_INVALID;\r
   mBitMask    = BitMask;\r
   mNext       = NULL;\r
+  mQtype      = QUESTION_NORMAL;\r
 \r
   if (Name == NULL) {\r
     mName = new CHAR8[strlen ("$DEFAULT") + 1];\r
@@ -2363,11 +2777,11 @@ SVfrQuestionNode::~SVfrQuestionNode (
   )\r
 {\r
   if (mName != NULL) {\r
-    delete mName;\r
+    delete[] mName;\r
   }\r
 \r
   if (mVarIdStr != NULL) {\r
-    delete mVarIdStr;\r
+    delete[] mVarIdStr;\r
   }\r
 }\r
 \r
@@ -2418,7 +2832,7 @@ CVfrQuestionDB::ResetInit(
 \r
   // Question ID 0 is reserved.\r
   mFreeQIdBitMap[0] = 0x80000000;\r
-  mQuestionList     = NULL;   \r
+  mQuestionList     = NULL;\r
 }\r
 \r
 VOID\r
@@ -2429,7 +2843,7 @@ CVfrQuestionDB::PrintAllQuestion (
   SVfrQuestionNode *pNode = NULL;\r
 \r
   for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {\r
-    printf ("Question VarId is %s and QuesitonId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
+    printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);\r
   }\r
 }\r
 \r
@@ -2509,6 +2923,9 @@ CVfrQuestionDB::RegisterOldDateQuestion (
   pNode[0]->mQuestionId = QuestionId;\r
   pNode[1]->mQuestionId = QuestionId;\r
   pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mQtype      = QUESTION_DATE;\r
+  pNode[1]->mQtype      = QUESTION_DATE;\r
+  pNode[2]->mQtype      = QUESTION_DATE;\r
   pNode[0]->mNext       = pNode[1];\r
   pNode[1]->mNext       = pNode[2];\r
   pNode[2]->mNext       = mQuestionList;\r
@@ -2541,26 +2958,54 @@ CVfrQuestionDB::RegisterNewDateQuestion (
   CHAR8                *VarIdStr[3] = {NULL, };\r
   CHAR8                 Index;\r
 \r
-  if (BaseVarId == NULL) {\r
+  if (BaseVarId == NULL && Name == NULL) {\r
+    if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+      QuestionId = GetFreeQuestionId ();\r
+    } else {\r
+      if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+        goto Err;\r
+      }\r
+      MarkQuestionIdUsed (QuestionId);\r
+    }\r
     return;\r
   }\r
 \r
-  Len = strlen (BaseVarId);\r
+  if (BaseVarId != NULL) {\r
+    Len = strlen (BaseVarId);\r
 \r
-  VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
-  if (VarIdStr[0] != NULL) {\r
-    strcpy (VarIdStr[0], BaseVarId);\r
-    strcat (VarIdStr[0], ".Year");\r
-  }\r
-  VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
-  if (VarIdStr[1] != NULL) {\r
-    strcpy (VarIdStr[1], BaseVarId);\r
-    strcat (VarIdStr[1], ".Month");\r
-  }\r
-  VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
-  if (VarIdStr[2] != NULL) {\r
-    strcpy (VarIdStr[2], BaseVarId);\r
-    strcat (VarIdStr[2], ".Day");\r
+    VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
+    if (VarIdStr[0] != NULL) {\r
+      strcpy (VarIdStr[0], BaseVarId);\r
+      strcat (VarIdStr[0], ".Year");\r
+    }\r
+    VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
+    if (VarIdStr[1] != NULL) {\r
+      strcpy (VarIdStr[1], BaseVarId);\r
+      strcat (VarIdStr[1], ".Month");\r
+    }\r
+    VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
+    if (VarIdStr[2] != NULL) {\r
+      strcpy (VarIdStr[2], BaseVarId);\r
+      strcat (VarIdStr[2], ".Day");\r
+    }\r
+  } else {\r
+    Len = strlen (Name);\r
+\r
+    VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];\r
+    if (VarIdStr[0] != NULL) {\r
+      strcpy (VarIdStr[0], Name);\r
+      strcat (VarIdStr[0], ".Year");\r
+    }\r
+    VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];\r
+    if (VarIdStr[1] != NULL) {\r
+      strcpy (VarIdStr[1], Name);\r
+      strcat (VarIdStr[1], ".Month");\r
+    }\r
+    VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];\r
+    if (VarIdStr[2] != NULL) {\r
+      strcpy (VarIdStr[2], Name);\r
+      strcat (VarIdStr[2], ".Day");\r
+    }\r
   }\r
 \r
   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {\r
@@ -2585,6 +3030,9 @@ CVfrQuestionDB::RegisterNewDateQuestion (
   pNode[0]->mQuestionId = QuestionId;\r
   pNode[1]->mQuestionId = QuestionId;\r
   pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mQtype      = QUESTION_DATE;\r
+  pNode[1]->mQtype      = QUESTION_DATE;\r
+  pNode[2]->mQtype      = QUESTION_DATE;\r
   pNode[0]->mNext       = pNode[1];\r
   pNode[1]->mNext       = pNode[2];\r
   pNode[2]->mNext       = mQuestionList;\r
@@ -2592,7 +3040,8 @@ CVfrQuestionDB::RegisterNewDateQuestion (
 \r
   for (Index = 0; Index < 3; Index++) {\r
     if (VarIdStr[Index] != NULL) {\r
-      delete VarIdStr[Index];\r
+      delete[] VarIdStr[Index];\r
+      VarIdStr[Index] = NULL;\r
     }\r
   }\r
 \r
@@ -2609,7 +3058,8 @@ Err:
     }\r
 \r
     if (VarIdStr[Index] != NULL) {\r
-      delete VarIdStr[Index];\r
+      delete[] VarIdStr [Index];\r
+      VarIdStr [Index] = NULL;\r
     }\r
   }\r
 }\r
@@ -2651,6 +3101,9 @@ CVfrQuestionDB::RegisterOldTimeQuestion (
   pNode[0]->mQuestionId = QuestionId;\r
   pNode[1]->mQuestionId = QuestionId;\r
   pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mQtype      = QUESTION_TIME;\r
+  pNode[1]->mQtype      = QUESTION_TIME;\r
+  pNode[2]->mQtype      = QUESTION_TIME;\r
   pNode[0]->mNext       = pNode[1];\r
   pNode[1]->mNext       = pNode[2];\r
   pNode[2]->mNext       = mQuestionList;\r
@@ -2683,26 +3136,54 @@ CVfrQuestionDB::RegisterNewTimeQuestion (
   CHAR8                *VarIdStr[3] = {NULL, };\r
   CHAR8                 Index;\r
 \r
-  if (BaseVarId == NULL) {\r
+  if (BaseVarId == NULL && Name == NULL) {\r
+    if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+      QuestionId = GetFreeQuestionId ();\r
+    } else {\r
+      if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+        goto Err;\r
+      }\r
+      MarkQuestionIdUsed (QuestionId);\r
+    }\r
     return;\r
   }\r
 \r
-  Len = strlen (BaseVarId);\r
+  if (BaseVarId != NULL) {\r
+    Len = strlen (BaseVarId);\r
 \r
-  VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
-  if (VarIdStr[0] != NULL) {\r
-    strcpy (VarIdStr[0], BaseVarId);\r
-    strcat (VarIdStr[0], ".Hour");\r
-  }\r
-  VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
-  if (VarIdStr[1] != NULL) {\r
-    strcpy (VarIdStr[1], BaseVarId);\r
-    strcat (VarIdStr[1], ".Minute");\r
-  }\r
-  VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
-  if (VarIdStr[2] != NULL) {\r
-    strcpy (VarIdStr[2], BaseVarId);\r
-    strcat (VarIdStr[2], ".Second");\r
+    VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
+    if (VarIdStr[0] != NULL) {\r
+      strcpy (VarIdStr[0], BaseVarId);\r
+      strcat (VarIdStr[0], ".Hour");\r
+    }\r
+    VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
+    if (VarIdStr[1] != NULL) {\r
+      strcpy (VarIdStr[1], BaseVarId);\r
+      strcat (VarIdStr[1], ".Minute");\r
+    }\r
+    VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
+    if (VarIdStr[2] != NULL) {\r
+      strcpy (VarIdStr[2], BaseVarId);\r
+      strcat (VarIdStr[2], ".Second");\r
+    }\r
+  } else {\r
+    Len = strlen (Name);\r
+\r
+    VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];\r
+    if (VarIdStr[0] != NULL) {\r
+      strcpy (VarIdStr[0], Name);\r
+      strcat (VarIdStr[0], ".Hour");\r
+    }\r
+    VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];\r
+    if (VarIdStr[1] != NULL) {\r
+      strcpy (VarIdStr[1], Name);\r
+      strcat (VarIdStr[1], ".Minute");\r
+    }\r
+    VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];\r
+    if (VarIdStr[2] != NULL) {\r
+      strcpy (VarIdStr[2], Name);\r
+      strcat (VarIdStr[2], ".Second");\r
+    }\r
   }\r
 \r
   if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {\r
@@ -2727,6 +3208,9 @@ CVfrQuestionDB::RegisterNewTimeQuestion (
   pNode[0]->mQuestionId = QuestionId;\r
   pNode[1]->mQuestionId = QuestionId;\r
   pNode[2]->mQuestionId = QuestionId;\r
+  pNode[0]->mQtype      = QUESTION_TIME;\r
+  pNode[1]->mQtype      = QUESTION_TIME;\r
+  pNode[2]->mQtype      = QUESTION_TIME;\r
   pNode[0]->mNext       = pNode[1];\r
   pNode[1]->mNext       = pNode[2];\r
   pNode[2]->mNext       = mQuestionList;\r
@@ -2734,7 +3218,8 @@ CVfrQuestionDB::RegisterNewTimeQuestion (
 \r
   for (Index = 0; Index < 3; Index++) {\r
     if (VarIdStr[Index] != NULL) {\r
-      delete VarIdStr[Index];\r
+      delete[] VarIdStr[Index];\r
+      VarIdStr[Index] = NULL;\r
     }\r
   }\r
 \r
@@ -2750,6 +3235,126 @@ Err:
       delete pNode[Index];\r
     }\r
 \r
+    if (VarIdStr[Index] != NULL) {\r
+      delete[] VarIdStr[Index];\r
+      VarIdStr[Index] = NULL;\r
+    }\r
+  }\r
+}\r
+\r
+VOID\r
+CVfrQuestionDB::RegisterRefQuestion (\r
+  IN     CHAR8           *Name,\r
+  IN     CHAR8           *BaseVarId,\r
+  IN OUT EFI_QUESTION_ID &QuestionId\r
+  )\r
+{\r
+  SVfrQuestionNode     *pNode[4] = {NULL, };\r
+  UINT32               Len;\r
+  CHAR8                *VarIdStr[4] = {NULL, };\r
+  CHAR8                 Index;\r
+\r
+  if (BaseVarId == NULL && Name == NULL) {\r
+    return;\r
+  }\r
+\r
+  if (BaseVarId != NULL) {\r
+    Len = strlen (BaseVarId);\r
+\r
+    VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
+    if (VarIdStr[0] != NULL) {\r
+      strcpy (VarIdStr[0], BaseVarId);\r
+      strcat (VarIdStr[0], ".QuestionId");\r
+    }\r
+    VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
+    if (VarIdStr[1] != NULL) {\r
+      strcpy (VarIdStr[1], BaseVarId);\r
+      strcat (VarIdStr[1], ".FormId");\r
+    }\r
+    VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
+    if (VarIdStr[2] != NULL) {\r
+      strcpy (VarIdStr[2], BaseVarId);\r
+      strcat (VarIdStr[2], ".FormSetGuid");\r
+    }\r
+    VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
+    if (VarIdStr[3] != NULL) {\r
+      strcpy (VarIdStr[3], BaseVarId);\r
+      strcat (VarIdStr[3], ".DevicePath");\r
+    }\r
+  } else {\r
+    Len = strlen (Name);\r
+\r
+    VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];\r
+    if (VarIdStr[0] != NULL) {\r
+      strcpy (VarIdStr[0], Name);\r
+      strcat (VarIdStr[0], ".QuestionId");\r
+    }\r
+    VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];\r
+    if (VarIdStr[1] != NULL) {\r
+      strcpy (VarIdStr[1], Name);\r
+      strcat (VarIdStr[1], ".FormId");\r
+    }\r
+    VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];\r
+    if (VarIdStr[2] != NULL) {\r
+      strcpy (VarIdStr[2], Name);\r
+      strcat (VarIdStr[2], ".FormSetGuid");\r
+    }\r
+    VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];\r
+    if (VarIdStr[3] != NULL) {\r
+      strcpy (VarIdStr[3], Name);\r
+      strcat (VarIdStr[3], ".DevicePath");\r
+    }\r
+  }\r
+\r
+  if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {\r
+    goto Err;\r
+  }\r
+  if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {\r
+    goto Err;\r
+  }\r
+\r
+  if (QuestionId == EFI_QUESTION_ID_INVALID) {\r
+    QuestionId = GetFreeQuestionId ();\r
+  } else {\r
+    if (ChekQuestionIdFree (QuestionId) == FALSE) {\r
+      goto Err;\r
+    }\r
+    MarkQuestionIdUsed (QuestionId);\r
+  }\r
+\r
+  pNode[0]->mQuestionId = QuestionId;\r
+  pNode[1]->mQuestionId = QuestionId;\r
+  pNode[2]->mQuestionId = QuestionId;\r
+  pNode[3]->mQuestionId = QuestionId;\r
+  pNode[0]->mQtype      = QUESTION_REF;\r
+  pNode[1]->mQtype      = QUESTION_REF;\r
+  pNode[2]->mQtype      = QUESTION_REF;\r
+  pNode[3]->mQtype      = QUESTION_REF;\r
+  pNode[0]->mNext       = pNode[1];\r
+  pNode[1]->mNext       = pNode[2];\r
+  pNode[2]->mNext       = pNode[3];\r
+  pNode[3]->mNext       = mQuestionList;\r
+  mQuestionList         = pNode[0];\r
+\r
+  gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+  gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
+\r
+  return;\r
+\r
+  Err:\r
+  for (Index = 0; Index < 4; Index++) {\r
+    if (pNode[Index] != NULL) {\r
+      delete pNode[Index];\r
+    }\r
+\r
     if (VarIdStr[Index] != NULL) {\r
       delete VarIdStr[Index];\r
     }\r
@@ -2763,15 +3368,15 @@ CVfrQuestionDB::UpdateQuestionId (
   )\r
 {\r
   SVfrQuestionNode *pNode = NULL;\r
-  \r
+\r
   if (QId == NewQId) {\r
     // don't update\r
     return VFR_RETURN_SUCCESS;\r
   }\r
-  \r
+\r
   //\r
   // For Framework Vfr, don't check question ID conflict.\r
-  //  \r
+  //\r
   if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {\r
     return VFR_RETURN_REDEFINED;\r
   }\r
@@ -2800,13 +3405,17 @@ CVfrQuestionDB::GetQuestionId (
   IN  CHAR8             *Name,\r
   IN  CHAR8             *VarIdStr,\r
   OUT EFI_QUESTION_ID   &QuestionId,\r
-  OUT UINT32            &BitMask\r
+  OUT UINT32            &BitMask,\r
+  OUT EFI_QUESION_TYPE  *QType\r
   )\r
 {\r
   SVfrQuestionNode *pNode;\r
 \r
   QuestionId = EFI_QUESTION_ID_INVALID;\r
   BitMask    = 0x00000000;\r
+  if (QType != NULL) {\r
+    *QType = QUESTION_NORMAL;\r
+  }\r
 \r
   if ((Name == NULL) && (VarIdStr == NULL)) {\r
     return ;\r
@@ -2823,10 +3432,13 @@ CVfrQuestionDB::GetQuestionId (
       if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
         continue;\r
       }\r
-       }\r
+    }\r
 \r
     QuestionId = pNode->mQuestionId;\r
     BitMask    = pNode->mBitMask;\r
+    if (QType != NULL) {\r
+      *QType     = pNode->mQtype;\r
+    }\r
     break;\r
   }\r
 \r
@@ -2873,7 +3485,488 @@ CVfrQuestionDB::FindQuestion (
   return VFR_RETURN_UNDEFINED;\r
 }\r
 \r
+CVfrStringDB::CVfrStringDB ()\r
+{\r
+  mStringFileName = NULL;\r
+}\r
+\r
+CVfrStringDB::~CVfrStringDB ()\r
+{\r
+  if (mStringFileName != NULL) {\r
+    delete[] mStringFileName;\r
+  }\r
+  mStringFileName = NULL;\r
+}\r
+\r
+\r
+VOID\r
+CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)\r
+{\r
+  UINT32 FileLen = 0;\r
+\r
+  if (StringFileName == NULL) {\r
+    return;\r
+  }\r
+\r
+  if (mStringFileName != NULL) {\r
+    delete[] mStringFileName;\r
+  }\r
+\r
+  FileLen = strlen (StringFileName) + 1;\r
+  mStringFileName = new CHAR8[FileLen];\r
+  if (mStringFileName == NULL) {\r
+    return;\r
+  }\r
+\r
+  strcpy (mStringFileName, StringFileName);\r
+  mStringFileName[FileLen - 1] = '\0';\r
+}\r
+\r
+\r
+/**\r
+  Returns TRUE or FALSE whether SupportedLanguages contains the best matching language\r
+  from a set of supported languages.\r
+\r
+  @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string that\r
+                                  contains a set of language codes.\r
+  @param[in]  Language            A variable that contains pointers to Null-terminated\r
+                                  ASCII strings that contain one language codes.\r
+\r
+  @retval FALSE   The best matching language could not be found in SupportedLanguages.\r
+  @retval TRUE    The best matching language could be found in SupportedLanguages.\r
+\r
+**/\r
+BOOLEAN\r
+CVfrStringDB::GetBestLanguage (\r
+  IN CONST CHAR8  *SupportedLanguages,\r
+  IN CHAR8        *Language\r
+  )\r
+{\r
+  UINTN        CompareLength;\r
+  UINTN        LanguageLength;\r
+  CONST CHAR8  *Supported;\r
+\r
+  if (SupportedLanguages == NULL || Language == NULL){\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Determine the length of the first RFC 4646 language code in Language\r
+  //\r
+  for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);\r
+\r
+  //\r
+  // Trim back the length of Language used until it is empty\r
+  //\r
+  while (LanguageLength > 0) {\r
+    //\r
+    // Loop through all language codes in SupportedLanguages\r
+    //\r
+    for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {\r
+      //\r
+      // Skip ';' characters in Supported\r
+      //\r
+      for (; *Supported != '\0' && *Supported == ';'; Supported++);\r
+      //\r
+      // Determine the length of the next language code in Supported\r
+      //\r
+      for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);\r
+      //\r
+      // If Language is longer than the Supported, then skip to the next language\r
+      //\r
+      if (LanguageLength > CompareLength) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // See if the first LanguageLength characters in Supported match Language\r
+      //\r
+      if (strncmp (Supported, Language, LanguageLength) == 0) {\r
+        return TRUE;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Trim Language from the right to the next '-' character\r
+    //\r
+    for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);\r
+  }\r
+\r
+  //\r
+  // No matches were found\r
+  //\r
+  return FALSE;\r
+}\r
+\r
+\r
+CHAR8 *\r
+CVfrStringDB::GetVarStoreNameFormStringId (\r
+  IN EFI_STRING_ID StringId\r
+  )\r
+{\r
+  FILE        *pInFile    = NULL;\r
+  UINT32      NameOffset;\r
+  UINT32      Length;\r
+  UINT8       *StringPtr;\r
+  CHAR8       *StringName;\r
+  CHAR16      *UnicodeString;\r
+  CHAR8       *VarStoreName = NULL;\r
+  CHAR8       *DestTmp;\r
+  UINT8       *Current;\r
+  EFI_STATUS  Status;\r
+  CHAR8       LineBuf[EFI_IFR_MAX_LENGTH];\r
+  UINT8       BlockType;\r
+  EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
+\r
+  if (mStringFileName == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Get file length.\r
+  //\r
+  fseek (pInFile, 0, SEEK_END);\r
+  Length = ftell (pInFile);\r
+  fseek (pInFile, 0, SEEK_SET);\r
+\r
+  //\r
+  // Get file data.\r
+  //\r
+  StringPtr = new UINT8[Length];\r
+  if (StringPtr == NULL) {\r
+    fclose (pInFile);\r
+    return NULL;\r
+  }\r
+  fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);\r
+  fclose (pInFile);\r
+\r
+  PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
+  //\r
+  // Check the String package.\r
+  //\r
+  if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
+    delete[] StringPtr;\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Search the language, get best language base on RFC 4647 matching algorithm.\r
+  //\r
+  Current = StringPtr;\r
+  while (!GetBestLanguage ("en", PkgHeader->Language)) {\r
+    Current += PkgHeader->Header.Length;\r
+    PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;\r
+    //\r
+    // If can't find string package base on language, just return the first string package.\r
+    //\r
+    if (Current - StringPtr >= Length) {\r
+      Current = StringPtr;\r
+      PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;\r
+      break;\r
+    }\r
+  }\r
+\r
+  Current += PkgHeader->HdrSize;\r
+  //\r
+  // Find the string block according the stringId.\r
+  //\r
+  Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
+  if (Status != EFI_SUCCESS) {\r
+    delete[] StringPtr;\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Get varstore name according the string type.\r
+  //\r
+  switch (BlockType) {\r
+  case EFI_HII_SIBT_STRING_SCSU:\r
+  case EFI_HII_SIBT_STRING_SCSU_FONT:\r
+  case EFI_HII_SIBT_STRINGS_SCSU:\r
+  case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
+    StringName = (CHAR8*)(Current + NameOffset);\r
+    VarStoreName = new CHAR8[strlen(StringName) + 1];\r
+    strcpy (VarStoreName, StringName);\r
+    break;\r
+  case EFI_HII_SIBT_STRING_UCS2:\r
+  case EFI_HII_SIBT_STRING_UCS2_FONT:\r
+  case EFI_HII_SIBT_STRINGS_UCS2:\r
+  case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
+    UnicodeString = (CHAR16*)(Current + NameOffset);\r
+    Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;\r
+    DestTmp = new CHAR8[Length / 2 + 1];\r
+    VarStoreName = DestTmp;\r
+    while (*UnicodeString != '\0') {\r
+      *(DestTmp++) = (CHAR8) *(UnicodeString++);\r
+    }\r
+    *DestTmp = '\0';\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
+\r
+  delete[] StringPtr;\r
+\r
+  return VarStoreName;\r
+}\r
+\r
+EFI_STATUS\r
+CVfrStringDB::FindStringBlock (\r
+  IN  UINT8                           *StringData,\r
+  IN  EFI_STRING_ID                   StringId,\r
+  OUT UINT32                          *StringTextOffset,\r
+  OUT UINT8                           *BlockType\r
+  )\r
+{\r
+  UINT8                                *BlockHdr;\r
+  EFI_STRING_ID                        CurrentStringId;\r
+  UINT32                               BlockSize;\r
+  UINT32                               Index;\r
+  UINT8                                *StringTextPtr;\r
+  UINT32                               Offset;\r
+  UINT16                               StringCount;\r
+  UINT16                               SkipCount;\r
+  UINT8                                Length8;\r
+  EFI_HII_SIBT_EXT2_BLOCK              Ext2;\r
+  UINT32                               Length32;\r
+  UINT32                               StringSize;\r
+\r
+  CurrentStringId = 1;\r
+\r
+  //\r
+  // Parse the string blocks to get the string text and font.\r
+  //\r
+  BlockHdr  = StringData;\r
+  BlockSize = 0;\r
+  Offset    = 0;\r
+  while (*BlockHdr != EFI_HII_SIBT_END) {\r
+    switch (*BlockHdr) {\r
+    case EFI_HII_SIBT_STRING_SCSU:\r
+      Offset = sizeof (EFI_HII_STRING_BLOCK);\r
+      StringTextPtr = BlockHdr + Offset;\r
+      BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+      CurrentStringId++;\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRING_SCSU_FONT:\r
+      Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
+      StringTextPtr = BlockHdr + Offset;\r
+      BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+      CurrentStringId++;\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRINGS_SCSU:\r
+      memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
+      StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
+      BlockSize += StringTextPtr - BlockHdr;\r
+\r
+      for (Index = 0; Index < StringCount; Index++) {\r
+        BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
+        if (CurrentStringId == StringId) {\r
+          *BlockType        = *BlockHdr;\r
+          *StringTextOffset = StringTextPtr - StringData;\r
+          return EFI_SUCCESS;\r
+        }\r
+        StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+        CurrentStringId++;\r
+      }\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
+      memcpy (\r
+        &StringCount,\r
+        BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+        sizeof (UINT16)\r
+        );\r
+      StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
+      BlockSize += StringTextPtr - BlockHdr;\r
+\r
+      for (Index = 0; Index < StringCount; Index++) {\r
+        BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;\r
+        if (CurrentStringId == StringId) {\r
+          *BlockType        = *BlockHdr;\r
+          *StringTextOffset = StringTextPtr - StringData;\r
+          return EFI_SUCCESS;\r
+        }\r
+        StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;\r
+        CurrentStringId++;\r
+      }\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRING_UCS2:\r
+      Offset        = sizeof (EFI_HII_STRING_BLOCK);\r
+      StringTextPtr = BlockHdr + Offset;\r
+      //\r
+      // Use StringSize to store the size of the specified string, including the NULL\r
+      // terminator.\r
+      //\r
+      StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+      BlockSize += Offset + StringSize;\r
+      CurrentStringId++;\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRING_UCS2_FONT:\r
+      Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);\r
+      StringTextPtr = BlockHdr + Offset;\r
+      //\r
+      // Use StrSize to store the size of the specified string, including the NULL\r
+      // terminator.\r
+      //\r
+      StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+      BlockSize += Offset + StringSize;\r
+      CurrentStringId++;\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRINGS_UCS2:\r
+      Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);\r
+      StringTextPtr = BlockHdr + Offset;\r
+      BlockSize += Offset;\r
+      memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
+      for (Index = 0; Index < StringCount; Index++) {\r
+        StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+        BlockSize += StringSize;\r
+        if (CurrentStringId == StringId) {\r
+          *BlockType        = *BlockHdr;\r
+          *StringTextOffset = StringTextPtr - StringData;\r
+          return EFI_SUCCESS;\r
+        }\r
+        StringTextPtr = StringTextPtr + StringSize;\r
+        CurrentStringId++;\r
+      }\r
+      break;\r
+\r
+    case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
+      Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);\r
+      StringTextPtr = BlockHdr + Offset;\r
+      BlockSize += Offset;\r
+      memcpy (\r
+        &StringCount,\r
+        BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+        sizeof (UINT16)\r
+        );\r
+      for (Index = 0; Index < StringCount; Index++) {\r
+        StringSize = GetUnicodeStringTextSize (StringTextPtr);\r
+        BlockSize += StringSize;\r
+        if (CurrentStringId == StringId) {\r
+          *BlockType        = *BlockHdr;\r
+          *StringTextOffset = StringTextPtr - StringData;\r
+          return EFI_SUCCESS;\r
+        }\r
+        StringTextPtr = StringTextPtr + StringSize;\r
+        CurrentStringId++;\r
+      }\r
+      break;\r
+\r
+    case EFI_HII_SIBT_DUPLICATE:\r
+      if (CurrentStringId == StringId) {\r
+        //\r
+        // Incoming StringId is an id of a duplicate string block.\r
+        // Update the StringId to be the previous string block.\r
+        // Go back to the header of string block to search.\r
+        //\r
+        memcpy (\r
+          &StringId,\r
+          BlockHdr + sizeof (EFI_HII_STRING_BLOCK),\r
+          sizeof (EFI_STRING_ID)\r
+          );\r
+        CurrentStringId = 1;\r
+        BlockSize       = 0;\r
+      } else {\r
+        BlockSize       += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);\r
+        CurrentStringId++;\r
+      }\r
+      break;\r
+\r
+    case EFI_HII_SIBT_SKIP1:\r
+      SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
+      CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
+      BlockSize       +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
+      break;\r
+\r
+    case EFI_HII_SIBT_SKIP2:\r
+      memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
+      CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
+      BlockSize       +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+      break;\r
+\r
+    case EFI_HII_SIBT_EXT1:\r
+      memcpy (\r
+        &Length8,\r
+        BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+        sizeof (UINT8)\r
+        );\r
+      BlockSize += Length8;\r
+      break;\r
+\r
+    case EFI_HII_SIBT_EXT2:\r
+      memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));\r
+      BlockSize += Ext2.Length;\r
+      break;\r
+\r
+    case EFI_HII_SIBT_EXT4:\r
+      memcpy (\r
+        &Length32,\r
+        BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+        sizeof (UINT32)\r
+        );\r
+\r
+      BlockSize += Length32;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+\r
+    if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {\r
+      *StringTextOffset = BlockHdr - StringData + Offset;\r
+      *BlockType        = *BlockHdr;\r
+\r
+      if (StringId == CurrentStringId - 1) {\r
+        //\r
+        // if only one skip item, return EFI_NOT_FOUND.\r
+        //\r
+        if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {\r
+          return EFI_NOT_FOUND;\r
+        } else {\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+\r
+      if (StringId < CurrentStringId - 1) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+    }\r
+    BlockHdr  = StringData + BlockSize;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+UINT32\r
+CVfrStringDB::GetUnicodeStringTextSize (\r
+  IN  UINT8            *StringSrc\r
+  )\r
+{\r
+  UINT32 StringSize;\r
+  CHAR16 *StringPtr;\r
+\r
+  StringSize = sizeof (CHAR16);\r
+  StringPtr  = (UINT16*)StringSrc;\r
+  while (*StringPtr++ != L'\0') {\r
+    StringSize += sizeof (CHAR16);\r
+  }\r
+\r
+  return StringSize;\r
+}\r
+\r
 BOOLEAN  VfrCompatibleMode = FALSE;\r
 \r
 CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
+CVfrDefaultStore  gCVfrDefaultStore;\r
+CVfrDataStorage  gCVfrDataStorage;\r
+\r
 \r