]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
BaseTools/VfrCompile: Add check to avoid using NULL pointer
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrUtilityLib.cpp
index c3a729eabfb8d3a9c13b6f901d3fc9319318f2c2..0fe14b0d29215213c48ee38b27e9a0c3efa40130 100644 (file)
@@ -2,7 +2,7 @@
   \r
   Vfr common library functions.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2017, 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
@@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "stdio.h"\r
 #include "stdlib.h"\r
+#include "CommonLib.h"\r
 #include "VfrUtilityLib.h"\r
 #include "VfrFormPkg.h"\r
 \r
@@ -109,6 +110,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 +123,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 +144,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 +159,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 +168,7 @@ SConfigItem::SConfigItem (
   )\r
 {\r
   mName        = NULL;\r
+  mGuid        = NULL;\r
   mId          = NULL;\r
   mInfoStrList = NULL;\r
   mNext        = NULL;\r
@@ -164,6 +179,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 +200,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 +214,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 +258,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 +294,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 +306,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 +328,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
@@ -578,6 +600,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 +724,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,7 +756,8 @@ 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
@@ -707,8 +789,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 +812,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 +821,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
@@ -766,18 +856,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 +883,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 +911,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
@@ -956,6 +1056,7 @@ CVfrVarDataTypeDB::DeclareDataTypeBegin (
   pNewType->mTotalSize   = 0;\r
   pNewType->mMembers     = NULL;\r
   pNewType->mNext        = NULL;\r
+  pNewType->mHasBitField = FALSE;\r
 \r
   mNewDataType           = pNewType;\r
 }\r
@@ -987,19 +1088,141 @@ CVfrVarDataTypeDB::SetNewTypeName (
   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
+    strcpy (pNewField->mFieldName, FieldName);\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 fileds 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
 EFI_VFR_RETURN_CODE\r
 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
@@ -1019,6 +1242,7 @@ CVfrVarDataTypeDB::DataTypeAddField (
   strcpy (pNewField->mFieldName, FieldName);\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 +1259,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 +1382,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 +1409,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
@@ -1306,7 +1547,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 +1568,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 +1585,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
@@ -1371,7 +1617,7 @@ SVfrVarStorageNode::~SVfrVarStorageNode (
   )\r
 {\r
   if (mVarStoreName != NULL) {\r
-    delete mVarStoreName;\r
+    delete[] mVarStoreName;\r
   }\r
 \r
   if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {\r
@@ -1397,6 +1643,8 @@ CVfrDataStorage::CVfrDataStorage (
   mNameVarStoreList        = NULL;\r
   mCurrVarStorageNode      = NULL;\r
   mNewVarStorageNode       = NULL;\r
+  mBufferFieldInfoListHead = NULL;\r
+  mBufferFieldInfoListTail = NULL;\r
 }\r
 \r
 CVfrDataStorage::~CVfrDataStorage (\r
@@ -1450,6 +1698,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 +1747,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
+  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
@@ -1578,7 +1839,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
@@ -1600,6 +1861,7 @@ CVfrDataStorage::DeclareBufferVarStore (
   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 +1873,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,14 +1888,14 @@ 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
@@ -1643,7 +1905,8 @@ CVfrDataStorage::DeclareBufferVarStore (
 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
@@ -1658,7 +1921,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
@@ -1678,46 +1950,108 @@ CVfrDataStorage::GetVarStoreByDataType (
   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
+      *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
   //\r
-  ReturnCode = GetVarStoreByDataType (StoreName, &pNode);\r
+  ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);\r
   if (pNode != NULL) {\r
     mCurrVarStorageNode = pNode;\r
     *VarStoreId = pNode->mVarStoreId;\r
@@ -1728,126 +2062,100 @@ CVfrDataStorage::GetVarStoreId (
 \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
@@ -1922,6 +2230,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
@@ -1951,44 +2301,6 @@ 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
@@ -2015,7 +2327,7 @@ SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
   )\r
 {\r
   if (mRefName != NULL) {\r
-    delete mRefName;\r
+    delete[] mRefName;\r
   }\r
 }\r
 \r
@@ -2155,6 +2467,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,8 +2493,8 @@ 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
@@ -2216,7 +2529,7 @@ SVfrRuleNode::~SVfrRuleNode (
   )\r
 {\r
   if (mRuleName != NULL) {\r
-    delete mRuleName;\r
+    delete[] mRuleName;\r
   }\r
 }\r
 \r
@@ -2289,6 +2602,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 +2614,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
@@ -2311,13 +2643,34 @@ EFI_VARSTORE_INFO::operator == (
          (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 +2686,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 +2768,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
@@ -2592,26 +2949,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
@@ -2740,26 +3125,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
@@ -2828,31 +3241,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
@@ -3067,6 +3505,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
@@ -3086,11 +3601,11 @@ CVfrStringDB::GetVarStoreNameFormStringId (
   UINT8       BlockType;\r
   EFI_HII_STRING_PACKAGE_HDR *PkgHeader;\r
   \r
-  if (mStringFileName == '\0' ) {\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 +3632,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 +3659,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 +3692,7 @@ CVfrStringDB::GetVarStoreNameFormStringId (
     break;\r
   }\r
 \r
-  delete StringPtr;\r
+  delete[] StringPtr;\r
 \r
   return VarStoreName;\r
 }\r
@@ -3433,5 +3949,7 @@ CVfrStringDB::GetUnicodeStringTextSize (
 BOOLEAN  VfrCompatibleMode = FALSE;\r
 \r
 CVfrVarDataTypeDB gCVfrVarDataTypeDB;\r
+CVfrDefaultStore  gCVfrDefaultStore;\r
+CVfrDataStorage  gCVfrDataStorage;\r
 \r
 \r