]> 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 c3a729eabfb8d3a9c13b6f901d3fc9319318f2c2..0d0f926f82660a4fa498480094fce1a32b294fe6 100644 (file)
@@ -1,20 +1,22 @@
 /** @file\r
-  \r
+\r
   Vfr common library functions.\r
 \r
-Copyright (c) 2004 - 2011, 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
+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
@@ -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, (UINT16) 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
@@ -530,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
@@ -578,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
@@ -643,7 +725,7 @@ CVfrVarDataTypeDB::GetTypeField (
 {\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
@@ -675,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
@@ -696,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
@@ -707,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
@@ -727,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
@@ -735,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
@@ -752,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
@@ -766,18 +859,21 @@ CVfrVarDataTypeDB::InternalTypesListInit (
         pYearField->mOffset      = 0;\r
         pYearField->mNext        = pMonthField;\r
         pYearField->mArrayNum    = 0;\r
+        pYearField->mIsBitField = FALSE;\r
 \r
         strcpy (pMonthField->mFieldName, "Month");\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 ((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
@@ -790,18 +886,21 @@ CVfrVarDataTypeDB::InternalTypesListInit (
         pHoursField->mOffset     = 0;\r
         pHoursField->mNext       = pMinutesField;\r
         pHoursField->mArrayNum   = 0;\r
+        pHoursField->mIsBitField = FALSE;\r
 \r
         strcpy (pMinutesField->mFieldName, "Minutes");\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 ((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
@@ -815,24 +914,28 @@ CVfrVarDataTypeDB::InternalTypesListInit (
         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
@@ -855,6 +958,7 @@ CVfrVarDataTypeDB::CVfrVarDataTypeDB (
   mPackAlign     = DEFAULT_PACK_ALIGN;\r
   mPackStack     = NULL;\r
   mFirstNewDataTypeName = NULL;\r
+  mCurrDataType  = NULL;\r
 \r
   InternalTypesListInit ();\r
 }\r
@@ -879,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
@@ -956,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
@@ -983,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
@@ -991,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
@@ -1016,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
@@ -1035,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
@@ -1150,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
@@ -1172,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 = (UINT16) (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
@@ -1257,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
@@ -1288,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
@@ -1306,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
@@ -1327,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
@@ -1343,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
@@ -1353,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
@@ -1364,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
@@ -1371,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
@@ -1397,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
@@ -1431,7 +1688,7 @@ 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
@@ -1450,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
@@ -1495,21 +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
-  if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {\r
+  if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {\r
     return VFR_RETURN_REDEFINED;\r
   }\r
 \r
-  VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);\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
   if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {\r
     return VFR_RETURN_UNDEFINED;\r
   }\r
@@ -1558,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
@@ -1578,7 +1848,7 @@ CVfrDataStorage::DeclareEfiVarStore (
     return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;\r
   }\r
 \r
-  if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {\r
+  if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
     return VFR_RETURN_REDEFINED;\r
   }\r
 \r
@@ -1593,13 +1863,14 @@ 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
@@ -1611,7 +1882,7 @@ CVfrDataStorage::DeclareBufferVarStore (
     return VFR_RETURN_FATAL_ERROR;\r
   }\r
 \r
-  if (GetVarStoreId (StoreName, &TempVarStoreId) == VFR_RETURN_SUCCESS) {\r
+  if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {\r
     return VFR_RETURN_REDEFINED;\r
   }\r
 \r
@@ -1626,29 +1897,30 @@ 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
+EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::GetVarStoreByDataType (\r
   IN  CHAR8              *DataTypeName,\r
-  OUT SVfrVarStorageNode **VarNode\r
+  OUT SVfrVarStorageNode **VarNode,\r
+  IN  EFI_GUID           *VarGuid\r
   )\r
 {\r
   SVfrVarStorageNode    *pNode;\r
   SVfrVarStorageNode    *MatchNode;\r
-  \r
+\r
   //\r
   // Framework VFR uses Data type name as varstore name, so don't need check again.\r
   //\r
@@ -1658,7 +1930,16 @@ CVfrDataStorage::GetVarStoreByDataType (
 \r
   MatchNode = NULL;\r
   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) == 0) {\r
+    if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {\r
+      continue;\r
+    }\r
+\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
@@ -1669,7 +1950,7 @@ CVfrDataStorage::GetVarStoreByDataType (
       }\r
     }\r
   }\r
-  \r
+\r
   if (MatchNode == NULL) {\r
     return VFR_RETURN_UNDEFINED;\r
   }\r
@@ -1678,181 +1959,217 @@ CVfrDataStorage::GetVarStoreByDataType (
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
-EFI_VFR_RETURN_CODE \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
+      *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
+  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::GetVarStoreId (\r
   IN  CHAR8           *StoreName,\r
-  OUT EFI_VARSTORE_ID *VarStoreId\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
+  mCurrVarStorageNode = NULL;\r
 \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 (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+        *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+        return ReturnCode;\r
+      }\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 (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+        *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+        return ReturnCode;\r
+      }\r
     }\r
   }\r
 \r
   for (pNode = mNameVarStoreList; 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 (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {\r
+        *VarStoreId = mCurrVarStorageNode->mVarStoreId;\r
+        return ReturnCode;\r
+      }\r
     }\r
   }\r
 \r
-  mCurrVarStorageNode = NULL;\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 strucutre name is used as StoreName, and check again. \r
+  // Assume that Data structure name is used as StoreName, and check again.\r
   //\r
-  ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
+  ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);\r
   if (pNode != NULL) {\r
     mCurrVarStorageNode = pNode;\r
     *VarStoreId = pNode->mVarStoreId;\r
   }\r
-  \r
+\r
   return ReturnCode;\r
 }\r
 \r
 EFI_VFR_RETURN_CODE\r
 CVfrDataStorage::GetBufferVarStoreDataTypeName (\r
-  IN  CHAR8                  *StoreName,\r
+  IN  EFI_VARSTORE_ID        VarStoreId,\r
   OUT CHAR8                  **DataTypeName\r
   )\r
 {\r
   SVfrVarStorageNode    *pNode;\r
-  EFI_VFR_RETURN_CODE   ReturnCode;\r
 \r
-  if ((StoreName == NULL) || (DataTypeName == 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
-      break;\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
+      *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
+      return VFR_RETURN_SUCCESS;\r
     }\r
   }\r
 \r
-  ReturnCode = VFR_RETURN_UNDEFINED;\r
-  //\r
-  // Assume that Data strucutre name is used as StoreName, and check again. \r
-  //\r
-  if (pNode == NULL) {\r
-    ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
-  }\r
-\r
-  if (pNode == NULL) {\r
-    return ReturnCode;\r
-  }\r
-\r
-  if (pNode->mStorageInfo.mDataType == NULL) {\r
-    return VFR_RETURN_FATAL_ERROR;\r
-  }\r
-\r
-  *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;\r
-  return VFR_RETURN_SUCCESS;\r
+  return VFR_RETURN_UNDEFINED;\r
 }\r
 \r
-EFI_VFR_RETURN_CODE\r
+EFI_VFR_VARSTORE_TYPE\r
 CVfrDataStorage::GetVarStoreType (\r
-  IN  CHAR8                  *StoreName,\r
-  OUT EFI_VFR_VARSTORE_TYPE  &VarStoreType\r
+  IN  EFI_VARSTORE_ID        VarStoreId\r
   )\r
 {\r
   SVfrVarStorageNode    *pNode;\r
-  EFI_VFR_RETURN_CODE   ReturnCode;\r
+  EFI_VFR_VARSTORE_TYPE VarStoreType;\r
 \r
-  if (StoreName == NULL) {\r
-    return VFR_RETURN_FATAL_ERROR;\r
+  VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
+\r
+  if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
+    return VarStoreType;\r
   }\r
 \r
   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
       VarStoreType = pNode->mVarStoreType;\r
-      return VFR_RETURN_SUCCESS;\r
+      return VarStoreType;\r
     }\r
   }\r
 \r
   for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
       VarStoreType = pNode->mVarStoreType;\r
-      return VFR_RETURN_SUCCESS;\r
+      return VarStoreType;\r
     }\r
   }\r
 \r
   for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
+    if (pNode->mVarStoreId == VarStoreId) {\r
       VarStoreType = pNode->mVarStoreType;\r
-      return VFR_RETURN_SUCCESS;\r
+      return VarStoreType;\r
     }\r
   }\r
 \r
-  VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
-\r
-  //\r
-  // Assume that Data strucutre name is used as StoreName, and check again. \r
-  //\r
-  ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
-  if (pNode != NULL) {\r
-    VarStoreType = pNode->mVarStoreType;\r
-  }\r
-  \r
-  return ReturnCode;\r
+  return VarStoreType;\r
 }\r
 \r
-EFI_VFR_VARSTORE_TYPE\r
-CVfrDataStorage::GetVarStoreType (\r
+EFI_GUID *\r
+CVfrDataStorage::GetVarStoreGuid (\r
   IN  EFI_VARSTORE_ID        VarStoreId\r
   )\r
 {\r
   SVfrVarStorageNode    *pNode;\r
-  EFI_VFR_VARSTORE_TYPE VarStoreType;\r
+  EFI_GUID              *VarGuid;\r
 \r
-  VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
+  VarGuid = NULL;\r
 \r
   if (VarStoreId == EFI_VARSTORE_ID_INVALID) {\r
-    return VarStoreType;\r
+    return VarGuid;\r
   }\r
 \r
   for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
     if (pNode->mVarStoreId == VarStoreId) {\r
-      VarStoreType = pNode->mVarStoreType;\r
-      return VarStoreType;\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
-      VarStoreType = pNode->mVarStoreType;\r
-      return VarStoreType;\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
-      VarStoreType = pNode->mVarStoreType;\r
-      return VarStoreType;\r
+      VarGuid = &pNode->mGuid;\r
+      return VarGuid;\r
     }\r
   }\r
 \r
-  return VarStoreType;\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
@@ -1922,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
@@ -1935,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
@@ -1951,48 +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
-  SVfrVarStorageNode    *pNode = NULL;\r
-  EFI_IFR_TYPE_VALUE    Value = gZeroEfiIfrTypeValue;\r
-  EFI_VFR_RETURN_CODE   ReturnCode;\r
-\r
-  for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {\r
-    if (strcmp (pNode->mVarStoreName, StoreName) == 0) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  ReturnCode = VFR_RETURN_UNDEFINED;\r
-  //\r
-  // Assume that Data strucutre name is used as StoreName, and check again. \r
-  //\r
-  if (pNode == NULL) {\r
-    ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
-  }\r
-\r
-  if (pNode == NULL) {\r
-    return ReturnCode;\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
@@ -2015,7 +2336,7 @@ SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
   )\r
 {\r
   if (mRefName != NULL) {\r
-    delete mRefName;\r
+    delete[] mRefName;\r
   }\r
 }\r
 \r
@@ -2070,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
@@ -2155,6 +2476,7 @@ CVfrDefaultStore::BufferVarStoreAltConfigAdd (
   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
@@ -2180,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
@@ -2216,7 +2538,7 @@ SVfrRuleNode::~SVfrRuleNode (
   )\r
 {\r
   if (mRuleName != NULL) {\r
-    delete mRuleName;\r
+    delete[] mRuleName;\r
   }\r
 }\r
 \r
@@ -2289,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
@@ -2300,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
@@ -2308,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
@@ -2333,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
@@ -2411,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
@@ -2466,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
@@ -2477,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
@@ -2592,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
@@ -2646,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
@@ -2663,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
@@ -2740,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
@@ -2794,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
@@ -2811,12 +3236,13 @@ Err:
     }\r
 \r
     if (VarIdStr[Index] != NULL) {\r
-      delete VarIdStr[Index];\r
+      delete[] VarIdStr[Index];\r
+      VarIdStr[Index] = NULL;\r
     }\r
   }\r
 }\r
 \r
-VOID \r
+VOID\r
 CVfrQuestionDB::RegisterRefQuestion (\r
   IN     CHAR8           *Name,\r
   IN     CHAR8           *BaseVarId,\r
@@ -2828,31 +3254,56 @@ CVfrQuestionDB::RegisterRefQuestion (
   CHAR8                *VarIdStr[4] = {NULL, };\r
   CHAR8                 Index;\r
 \r
-  if (BaseVarId == NULL) {\r
+  if (BaseVarId == NULL && Name == NULL) {\r
     return;\r
   }\r
 \r
-  Len = strlen (BaseVarId);\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
+    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
@@ -2880,15 +3331,15 @@ CVfrQuestionDB::RegisterRefQuestion (
   pNode[0]->mQuestionId = QuestionId;\r
   pNode[1]->mQuestionId = QuestionId;\r
   pNode[2]->mQuestionId = QuestionId;\r
-  pNode[3]->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[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
+  pNode[3]->mNext       = mQuestionList;\r
   mQuestionList         = pNode[0];\r
 \r
   gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));\r
@@ -2917,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
@@ -2981,7 +3432,7 @@ CVfrQuestionDB::GetQuestionId (
       if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {\r
         continue;\r
       }\r
-       }\r
+    }\r
 \r
     QuestionId = pNode->mQuestionId;\r
     BitMask    = pNode->mBitMask;\r
@@ -3042,13 +3493,13 @@ CVfrStringDB::CVfrStringDB ()
 CVfrStringDB::~CVfrStringDB ()\r
 {\r
   if (mStringFileName != NULL) {\r
-    delete mStringFileName;\r
+    delete[] mStringFileName;\r
   }\r
   mStringFileName = NULL;\r
 }\r
 \r
 \r
-VOID \r
+VOID\r
 CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)\r
 {\r
   UINT32 FileLen = 0;\r
@@ -3057,6 +3508,10 @@ CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
     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
@@ -3067,6 +3522,83 @@ CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
   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
@@ -3085,12 +3617,12 @@ CVfrStringDB::GetVarStoreNameFormStringId (
   CHAR8       LineBuf[EFI_IFR_MAX_LENGTH];\r
   UINT8       BlockType;\r
   EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
-  \r
-  if (mStringFileName == '\0' ) {\r
+\r
+  if (mStringFileName == NULL) {\r
     return NULL;\r
   }\r
 \r
-  if ((pInFile = fopen (mStringFileName, "rb")) == NULL) {\r
+  if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {\r
     return NULL;\r
   }\r
 \r
@@ -3117,22 +3649,23 @@ CVfrStringDB::GetVarStoreNameFormStringId (
   // Check the String package.\r
   //\r
   if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {\r
-    delete StringPtr;\r
+    delete[] StringPtr;\r
     return NULL;\r
   }\r
 \r
   //\r
-  // Search the language, only search the "en-US".\r
+  // Search the language, get best language base on RFC 4647 matching algorithm.\r
   //\r
   Current = StringPtr;\r
-  while (strcmp (PkgHeader->Language, "en-US") != 0) {\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 "en-US" string package, just return the first string package.\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
@@ -3143,7 +3676,7 @@ CVfrStringDB::GetVarStoreNameFormStringId (
   //\r
   Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);\r
   if (Status != EFI_SUCCESS) {\r
-    delete StringPtr;\r
+    delete[] StringPtr;\r
     return NULL;\r
   }\r
 \r
@@ -3176,7 +3709,7 @@ CVfrStringDB::GetVarStoreNameFormStringId (
     break;\r
   }\r
 \r
-  delete StringPtr;\r
+  delete[] StringPtr;\r
 \r
   return VarStoreName;\r
 }\r
@@ -3433,5 +3966,7 @@ CVfrStringDB::GetUnicodeStringTextSize (
 BOOLEAN  VfrCompatibleMode = FALSE;\r
 \r
 CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
+CVfrDefaultStore  gCVfrDefaultStore;\r
+CVfrDataStorage  gCVfrDataStorage;\r
 \r
 \r