]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
MdeModulePkg/HiiDatabase: Fix Setup numeric default value incorrect issue
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigRouting.c
index 15a55d794ae68477691f8bda74cfbcc0f62c981e..5ae6189a2843ce6fa386cc05a0717c71433f2191 100644 (file)
 /** @file\r
+Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
 \r
-Copyright (c) 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
-    ConfigRouting.c\r
-\r
-Abstract:\r
-\r
-    Implementation for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
-\r
-Revision History\r
-\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include "HiiDatabase.h"\r
-\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
-STATIC\r
-CHAR16\r
-NibbleToHexCharPrivate (\r
-  IN UINT8                         Nibble\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Converts the low nibble of a byte to hex unicode character.\r
-\r
-  Arguments:\r
-    Nibble - lower nibble of a byte.\r
-\r
-  Returns:\r
-    Hex unicode character between L'0' to L'f'.\r
-\r
---*/\r
-{\r
-  Nibble &= 0x0F;\r
-\r
-  if (Nibble <= 0x9) {\r
-    return (CHAR16)(Nibble + L'0');\r
-  }\r
-\r
-  return (CHAR16)(Nibble - 0xA + L'a');\r
-}\r
-\r
-\r
-/**\r
-  Converts Unicode string to binary buffer.\r
-  The conversion may be partial.\r
-  The first character in the string that is not hex digit stops the conversion.\r
-  At a minimum, any blob of data could be represented as a hex string.\r
-\r
-  @param  Buf                    Pointer to buffer that receives the data.\r
-  @param  Len                    Length in bytes of the buffer to hold converted\r
-                                 data. If routine return with EFI_SUCCESS,\r
-                                 containing length of converted data. If routine\r
-                                 return with EFI_BUFFER_TOO_SMALL, containg length\r
-                                 of buffer desired.\r
-  @param  Str                    String to be converted from.\r
-  @param  ConvertedStrLen        Length of the Hex String consumed.\r
-\r
-  @retval EFI_SUCCESS            Routine Success.\r
-  @retval EFI_BUFFER_TOO_SMALL   The buffer is too small to hold converted data.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-HexStringToBufPrivate (\r
-  IN OUT UINT8                     *Buf,\r
-  IN OUT UINTN                     *Len,\r
-  IN     CHAR16                    *Str,\r
-  OUT    UINTN                     *ConvertedStrLen  OPTIONAL\r
-  )\r
-{\r
-  UINTN       HexCnt;\r
-  UINTN       Idx;\r
-  UINTN       BufferLength;\r
-  UINT8       Digit;\r
-  UINT8       Byte;\r
-\r
-  //\r
-  // Find out how many hex characters the string has.\r
-  //\r
-  for (Idx = 0, HexCnt = 0; R8_IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);\r
-\r
-  if (HexCnt == 0) {\r
-    *Len = 0;\r
-    return EFI_SUCCESS;\r
-  }\r
-  //\r
-  // Two Unicode characters make up 1 buffer byte. Round up.\r
-  //\r
-  BufferLength = (HexCnt + 1) / 2;\r
-\r
-  //\r
-  // Test if  buffer is passed enough.\r
-  //\r
-  if (BufferLength > (*Len)) {\r
-    *Len = BufferLength;\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  *Len = BufferLength;\r
-\r
-  for (Idx = 0; Idx < HexCnt; Idx++) {\r
-\r
-    R8_IsHexDigit (&Digit, Str[Idx]);\r
-\r
-    //\r
-    // For odd charaters, write the lower nibble for each buffer byte,\r
-    // and for even characters, the upper nibble.\r
-    //\r
-    if ((Idx & 1) == 0) {\r
-      Byte = (UINT8) (Digit << 4);\r
-    } else {\r
-      Byte = Buf[Idx / 2];\r
-      Byte &= 0xF0;\r
-      Byte = (UINT8) (Byte | Digit);\r
-    }\r
-\r
-    Buf[Idx / 2] = Byte;\r
-  }\r
-\r
-  if (ConvertedStrLen != NULL) {\r
-    *ConvertedStrLen = HexCnt;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Converts binary buffer to Unicode string.\r
-  At a minimum, any blob of data could be represented as a hex string.\r
-\r
-  @param  Str                    Pointer to the string.\r
-  @param  HexStringBufferLength  Length in bytes of buffer to hold the hex string.\r
-                                 Includes tailing '\0' character. If routine return\r
-                                 with EFI_SUCCESS, containing length of hex string\r
-                                 buffer. If routine return with\r
-                                 EFI_BUFFER_TOO_SMALL, containg length of hex\r
-                                 string buffer desired.\r
-  @param  Buf                    Buffer to be converted from.\r
-  @param  Len                    Length in bytes of the buffer to be converted.\r
-  @param  Flag                   If TRUE, encode the data in the same order as the\r
-                                 it  resides in the Buf. Else encode it in the\r
-                                 reverse direction.\r
-\r
-  @retval EFI_SUCCESS            Routine  success.\r
-  @retval EFI_BUFFER_TOO_SMALL   The hex string buffer is too small.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-BufToHexStringPrivate (\r
-  IN OUT CHAR16                    *Str,\r
-  IN OUT UINTN                     *HexStringBufferLength,\r
-  IN     UINT8                     *Buf,\r
-  IN     UINTN                     Len,\r
-  IN     BOOLEAN                   Flag\r
-  )\r
-{\r
-  UINTN       Idx;\r
-  UINT8       Byte;\r
-  UINTN       StrLen;\r
-\r
-  //\r
-  // Make sure string is either passed or allocate enough.\r
-  // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.\r
-  // Plus the Unicode termination character.\r
-  //\r
-  StrLen = Len * 2;\r
-  if ((*HexStringBufferLength) < (StrLen + 1) * sizeof (CHAR16)) {\r
-    *HexStringBufferLength = (StrLen + 1) * sizeof (CHAR16);\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  *HexStringBufferLength = (StrLen + 1) * sizeof (CHAR16);\r
-\r
-  //\r
-  // Ends the string.\r
-  //\r
-  Str[StrLen] = 0;\r
-\r
-  for (Idx = 0; Idx < Len; Idx++) {\r
-\r
-    Byte = Buf[Idx];\r
-    if (Flag) {\r
-      Str[Idx * 2]     = NibbleToHexCharPrivate ((UINT8)(Byte >> 4));\r
-      Str[Idx * 2 + 1] = NibbleToHexCharPrivate (Byte);\r
-    } else {\r
-      Str[StrLen - 1 - Idx * 2] = NibbleToHexCharPrivate (Byte);\r
-      Str[StrLen - 2 - Idx * 2] = NibbleToHexCharPrivate ((UINT8)(Byte >> 4));\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
+extern HII_DATABASE_PRIVATE_DATA  mPrivate;\r
 \r
 /**\r
   Calculate the number of Unicode characters of the incoming Configuration string,\r
   not including NULL terminator.\r
 \r
+  This is a internal function.\r
+\r
   @param  String                 String in <MultiConfigRequest> or\r
                                  <MultiConfigResp> format.\r
 \r
   @return The number of Unicode characters.\r
 \r
 **/\r
-STATIC\r
 UINTN\r
 CalculateConfigStringLen (\r
-  IN EFI_STRING                    String\r
+  IN EFI_STRING  String\r
   )\r
 {\r
-  UINTN Length;\r
+  EFI_STRING  TmpPtr;\r
 \r
   //\r
   // "GUID=" should be the first element of incoming string.\r
@@ -234,59 +34,70 @@ CalculateConfigStringLen (
   ASSERT (String != NULL);\r
   ASSERT (StrnCmp (String, L"GUID=", StrLen (L"GUID=")) == 0);\r
 \r
-  Length  = StrLen (L"GUID=");\r
-  String += Length;\r
-\r
   //\r
   // The beginning of next <ConfigRequest>/<ConfigResp> should be "&GUID=".\r
   // Will meet '\0' if there is only one <ConfigRequest>/<ConfigResp>.\r
   //\r
-  while (*String != 0 && StrnCmp (String, L"&GUID=", StrLen (L"&GUID=")) != 0) {\r
-    Length++;\r
-    String++;\r
+  TmpPtr = StrStr (String, L"&GUID=");\r
+  if (TmpPtr == NULL) {\r
+    return StrLen (String);\r
   }\r
 \r
-  return Length;\r
+  return (TmpPtr - String);\r
 }\r
 \r
-\r
 /**\r
   Convert the hex UNICODE %02x encoding of a UEFI device path to binary\r
   from <PathHdr> of <ConfigHdr>.\r
 \r
+  This is a internal function.\r
+\r
   @param  String                 UEFI configuration string\r
-  @param  DevicePath             binary of a UEFI device path.\r
+  @param  DevicePathData         Binary of a UEFI device path.\r
 \r
+  @retval EFI_NOT_FOUND          The device path is not invalid.\r
   @retval EFI_INVALID_PARAMETER  Any incoming parameter is invalid.\r
-  @retval EFI_OUT_OF_RESOURCES   Lake of resources to store neccesary structures.\r
+  @retval EFI_OUT_OF_RESOURCES   Lake of resources to store necessary structures.\r
   @retval EFI_SUCCESS            The device path is retrieved and translated to\r
                                  binary format.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetDevicePath (\r
-  IN  EFI_STRING                   String,\r
-  OUT UINT8                        **DevicePath\r
+  IN  EFI_STRING  String,\r
+  OUT UINT8       **DevicePathData\r
   )\r
 {\r
-  UINTN      Length;\r
-  EFI_STRING PathHdr;\r
-  EFI_STRING DevicePathString;\r
-\r
-  if (String == NULL || DevicePath == NULL) {\r
+  UINTN                     Length;\r
+  EFI_STRING                PathHdr;\r
+  UINT8                     *DevicePathBuffer;\r
+  CHAR16                    TemStr[2];\r
+  UINTN                     Index;\r
+  UINT8                     DigitUint8;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+\r
+  if ((String == NULL) || (DevicePathData == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
   // Find the 'PATH=' of <PathHdr> and skip it.\r
   //\r
-  for (; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++);\r
+  for ( ; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++) {\r
+  }\r
+\r
   if (*String == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // Check whether path data does exist.\r
+  //\r
   String += StrLen (L"PATH=");\r
+  if (*String == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   PathHdr = String;\r
 \r
   //\r
@@ -294,273 +105,230 @@ GetDevicePath (
   // or '\0' (end of configuration string) is the UNICODE %02x bytes encoding\r
   // of UEFI device path.\r
   //\r
-  for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);\r
-  DevicePathString = (EFI_STRING) AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
-  if (DevicePathString == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  for (Length = 0; *String != 0 && *String != L'&'; String++, Length++) {\r
+  }\r
+\r
+  //\r
+  // Check DevicePath Length\r
+  //\r
+  if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+    return EFI_NOT_FOUND;\r
   }\r
-  StrnCpy (DevicePathString, PathHdr, Length);\r
-  *(DevicePathString + Length) = 0;\r
 \r
   //\r
   // The data in <PathHdr> is encoded as hex UNICODE %02x bytes in the same order\r
   // as the device path resides in RAM memory.\r
   // Translate the data into binary.\r
-  // Two Unicode characters make up 1 buffer byte.\r
   //\r
-  Length /= 2;\r
-  *DevicePath = (UINT8 *) AllocateZeroPool (Length);\r
-  if (*DevicePath == NULL) {\r
-    SafeFreePool (DevicePathString);\r
+  DevicePathBuffer = (UINT8 *)AllocateZeroPool ((Length + 1) / 2);\r
+  if (DevicePathBuffer == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  HexStringToBufPrivate (*DevicePath, &Length, DevicePathString, NULL);\r
-\r
-  SafeFreePool (DevicePathString);\r
-\r
-  return EFI_SUCCESS;\r
-\r
-}\r
-\r
-\r
-/**\r
-  Extract Storage from all Form Packages in current hii database.\r
-\r
-  @param  HiiDatabase            EFI_HII_DATABASE_PROTOCOL instance.\r
-  @param  StorageListHead        Storage link List head.\r
-\r
-  @retval EFI_NOT_FOUND          There is no form package in current hii database.\r
-  @retval EFI_INVALID_PARAMETER  Any parameter is invalid.\r
-  @retval EFI_SUCCESS            All existing storage is exported.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-ExportAllStorage (\r
-  IN EFI_HII_DATABASE_PROTOCOL     *HiiDatabase,\r
-  IN OUT LIST_ENTRY                *StorageListHead\r
-)\r
-{\r
-  EFI_STATUS                   Status;\r
-  UINTN                        BufferSize;\r
-  UINTN                        HandleCount;\r
-  EFI_HII_HANDLE               *HandleBuffer;\r
-  UINTN                        Index;\r
-  UINTN                        Index2;\r
-  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
-  EFI_HII_PACKAGE_HEADER       *Package;\r
-  UINT8                        *OpCodeData;\r
-  UINT8                        Operand;\r
-  UINT32                       Offset;\r
-  HII_FORMSET_STORAGE          *Storage;\r
-  EFI_HII_HANDLE               HiiHandle;\r
-  EFI_HANDLE                   DriverHandle;\r
-  CHAR8                        *AsciiString;\r
-  UINT32                       PackageListLength;\r
-  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
-\r
-  //\r
-  // Find the package list which contains Form package.\r
   //\r
-  BufferSize   = 0;\r
-  HandleBuffer = NULL;\r
-  Status = HiiListPackageLists (\r
-             HiiDatabase,\r
-             EFI_HII_PACKAGE_FORM,\r
-             NULL,\r
-             &BufferSize,\r
-             HandleBuffer\r
-             );\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    HandleBuffer = AllocateZeroPool (BufferSize);\r
-    ASSERT (HandleBuffer != NULL);\r
-\r
-    Status = HiiListPackageLists (\r
-               HiiDatabase,\r
-               EFI_HII_PACKAGE_FORM,\r
-               NULL,\r
-               &BufferSize,\r
-               HandleBuffer\r
-               );\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    SafeFreePool (HandleBuffer);\r
-    return Status;\r
-  }\r
-\r
-  HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    HiiHandle = HandleBuffer[Index];\r
-\r
-    BufferSize     = 0;\r
-    HiiPackageList = NULL;\r
-    Status = HiiExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
-    if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      HiiPackageList = AllocateZeroPool (BufferSize);\r
-      ASSERT (HiiPackageList != NULL);\r
-      Status = HiiExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
-    }\r
-    if (EFI_ERROR (Status)) {\r
-      SafeFreePool (HandleBuffer);\r
-      SafeFreePool (HiiPackageList);\r
-      return Status;\r
+  // Convert DevicePath\r
+  //\r
+  ZeroMem (TemStr, sizeof (TemStr));\r
+  for (Index = 0; Index < Length; Index++) {\r
+    TemStr[0]  = PathHdr[Index];\r
+    DigitUint8 = (UINT8)StrHexToUint64 (TemStr);\r
+    if ((Index & 1) == 0) {\r
+      DevicePathBuffer[Index/2] = DigitUint8;\r
+    } else {\r
+      DevicePathBuffer[Index/2] = (UINT8)((DevicePathBuffer[Index/2] << 4) + DigitUint8);\r
     }\r
+  }\r
 \r
-    //\r
-    // Get Form package from this HII package List\r
-    //\r
-    Offset  = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-    CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
-    Package = NULL;\r
-    ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
-    while (Offset < PackageListLength) {\r
-      Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
-      CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
-      if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
-        break;\r
-      }\r
-      Offset += PackageHeader.Length;\r
-    }\r
-    if (Offset >= PackageListLength) {\r
+  //\r
+  // Validate DevicePath\r
+  //\r
+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathBuffer;\r
+  while (!IsDevicePathEnd (DevicePath)) {\r
+    if ((DevicePath->Type == 0) || (DevicePath->SubType == 0) || (DevicePathNodeLength (DevicePath) < sizeof (EFI_DEVICE_PATH_PROTOCOL))) {\r
       //\r
-      // Error here: No Form package found in this Package List\r
+      // Invalid device path\r
       //\r
-      ASSERT (FALSE);\r
+      FreePool (DevicePathBuffer);\r
+      return EFI_NOT_FOUND;\r
     }\r
 \r
-    //\r
-    // Search Storage definition in this Form package\r
-    //\r
-    Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
-    while (Offset < PackageHeader.Length) {\r
-      OpCodeData = ((UINT8 *) Package) + Offset;\r
-      Offset += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
-\r
-      Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
-\r
-      if ((Operand == EFI_IFR_VARSTORE_OP) ||\r
-          (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) ||\r
-          (Operand == EFI_IFR_VARSTORE_EFI_OP)) {\r
-\r
-        Storage = AllocateZeroPool (sizeof (HII_FORMSET_STORAGE));\r
-        ASSERT (Storage != NULL);\r
-        InsertTailList (StorageListHead, &Storage->Entry);\r
-\r
-        Storage->Signature = HII_FORMSET_STORAGE_SIGNATURE;\r
-        Storage->HiiHandle = HiiHandle;\r
+    DevicePath = NextDevicePathNode (DevicePath);\r
+  }\r
 \r
-        Status = HiiGetPackageListHandle (HiiDatabase, HiiHandle, &DriverHandle);\r
-        if (EFI_ERROR (Status)) {\r
-          SafeFreePool (HandleBuffer);\r
-          SafeFreePool (HiiPackageList);\r
-          SafeFreePool (Storage);\r
-          return Status;\r
-        }\r
-        Storage->DriverHandle = DriverHandle;\r
+  //\r
+  // return the device path\r
+  //\r
+  *DevicePathData = DevicePathBuffer;\r
+  return EFI_SUCCESS;\r
+}\r
 \r
-        if (Operand == EFI_IFR_VARSTORE_OP) {\r
-          Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
+/**\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\r
 \r
-          CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
-          CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
+  @param ConfigString  String to be converted\r
 \r
-          AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
-          Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
-          ASSERT (Storage->Name != NULL);\r
-          for (Index2 = 0; AsciiString[Index2] != 0; Index2++) {\r
-            Storage->Name[Index2] = (CHAR16) AsciiString[Index2];\r
-          }\r
-          //\r
-          // Append '\0' to the end of the unicode string.\r
-          //\r
-          Storage->Name[Index2] = 0;\r
-        } else if (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) {\r
-          Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+**/\r
+VOID\r
+EFIAPI\r
+HiiToLower (\r
+  IN EFI_STRING  ConfigString\r
+  )\r
+{\r
+  EFI_STRING  String;\r
+  BOOLEAN     Lower;\r
 \r
-          CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
-        } else if (Operand == EFI_IFR_VARSTORE_EFI_OP) {\r
-          Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
+  ASSERT (ConfigString != NULL);\r
 \r
-          CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
-        }\r
-      }\r
+  //\r
+  // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
+  //\r
+  for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {\r
+    if (*String == L'=') {\r
+      Lower = TRUE;\r
+    } else if (*String == L'&') {\r
+      Lower = FALSE;\r
+    } else if (Lower && (*String >= L'A') && (*String <= L'F')) {\r
+      *String = (CHAR16)(*String - L'A' + L'a');\r
     }\r
-\r
-    SafeFreePool (HiiPackageList);\r
   }\r
 \r
-  SafeFreePool (HandleBuffer);\r
-\r
-  return EFI_SUCCESS;\r
+  return;\r
 }\r
 \r
-\r
 /**\r
   Generate a sub string then output it.\r
 \r
+  This is a internal function.\r
+\r
   @param  String                 A constant string which is the prefix of the to be\r
                                  generated string, e.g. GUID=\r
+\r
   @param  BufferLen              The length of the Buffer in bytes.\r
-  @param  Buffer                 Points to a buffer which will be converted to hex\r
-                                 string and to be the content of the generated\r
-                                 string.\r
-  @param  Flag                   If TRUE, convert the buffer data in the same order\r
-                                 as the it  resides in the Buffer. Else convert it\r
-                                 in the reverse direction.\r
+\r
+  @param  Buffer                 Points to a buffer which will be converted to be the\r
+                                 content of the generated string.\r
+\r
+  @param  Flag                   If 1, the buffer contains data for the value of GUID or PATH stored in\r
+                                 UINT8 *; if 2, the buffer contains unicode string for the value of NAME;\r
+                                 if 3, the buffer contains other data.\r
+\r
   @param  SubStr                 Points to the output string. It's caller's\r
                                  responsibility to free this buffer.\r
 \r
 \r
 **/\r
-STATIC\r
 VOID\r
 GenerateSubStr (\r
-  IN CONST EFI_STRING              String,\r
-  IN  UINTN                        BufferLen,\r
-  IN  UINT8                        *Buffer,\r
-  IN  BOOLEAN                      Flag,\r
-  OUT EFI_STRING                   *SubStr\r
+  IN CONST EFI_STRING  String,\r
+  IN  UINTN            BufferLen,\r
+  IN  VOID             *Buffer,\r
+  IN  UINT8            Flag,\r
+  OUT EFI_STRING       *SubStr\r
   )\r
 {\r
   UINTN       Length;\r
   EFI_STRING  Str;\r
-  EFI_STATUS  Status;\r
+  EFI_STRING  StringHeader;\r
+  CHAR16      *TemString;\r
+  CHAR16      *TemName;\r
+  UINT8       *TemBuffer;\r
+  UINTN       Index;\r
 \r
   ASSERT (String != NULL && SubStr != NULL);\r
 \r
   if (Buffer == NULL) {\r
     *SubStr = AllocateCopyPool (StrSize (String), String);\r
     ASSERT (*SubStr != NULL);\r
-    return ;\r
+    return;\r
   }\r
 \r
-  Length = BufferLen * 2 + 1 + StrLen (String) + 1;\r
-  Str = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  //\r
+  // Header + Data + '&' + '\0'\r
+  //\r
+  Length = StrLen (String) + BufferLen * 2 + 1 + 1;\r
+  Str    = AllocateZeroPool (Length * sizeof (CHAR16));\r
   ASSERT (Str != NULL);\r
 \r
-  StrCpy (Str, String);\r
-  Length = (BufferLen * 2 + 1) * sizeof (CHAR16);\r
+  StrCpyS (Str, Length, String);\r
 \r
-  Status = BufToHexStringPrivate (\r
-             Str + StrLen (String),\r
-             &Length,\r
-             Buffer,\r
-             BufferLen,\r
-             Flag\r
-             );\r
+  StringHeader = Str + StrLen (String);\r
+  TemString    = (CHAR16 *)StringHeader;\r
+\r
+  switch (Flag) {\r
+    case 1:\r
+      //\r
+      // Convert Buffer to Hex String in reverse order\r
+      //\r
+      TemBuffer = ((UINT8 *)Buffer);\r
+      for (Index = 0; Index < BufferLen; Index++, TemBuffer++) {\r
+        UnicodeValueToStringS (\r
+          TemString,\r
+          sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+          PREFIX_ZERO | RADIX_HEX,\r
+          *TemBuffer,\r
+          2\r
+          );\r
+        TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
+      }\r
+\r
+      break;\r
+    case 2:\r
+      //\r
+      // Check buffer is enough\r
+      //\r
+      TemName = (CHAR16 *)Buffer;\r
+      ASSERT ((BufferLen * 2 + 1) >= (StrLen (TemName) * 4 + 1));\r
+      //\r
+      // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
+      //\r
+      for ( ; *TemName != L'\0'; TemName++) {\r
+        UnicodeValueToStringS (\r
+          TemString,\r
+          sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+          PREFIX_ZERO | RADIX_HEX,\r
+          *TemName,\r
+          4\r
+          );\r
+        TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
+      }\r
 \r
-  ASSERT_EFI_ERROR (Status);\r
-  StrCat (Str, L"&");\r
+      break;\r
+    case 3:\r
+      //\r
+      // Convert Buffer to Hex String\r
+      //\r
+      TemBuffer = ((UINT8 *)Buffer) + BufferLen - 1;\r
+      for (Index = 0; Index < BufferLen; Index++, TemBuffer--) {\r
+        UnicodeValueToStringS (\r
+          TemString,\r
+          sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+          PREFIX_ZERO | RADIX_HEX,\r
+          *TemBuffer,\r
+          2\r
+          );\r
+        TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
+      }\r
+\r
+      break;\r
+    default:\r
+      break;\r
+  }\r
+\r
+  //\r
+  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.\r
+  //\r
+  StrCatS (Str, Length, L"&");\r
+  HiiToLower (Str);\r
 \r
   *SubStr = Str;\r
 }\r
 \r
-\r
 /**\r
   Retrieve the <ConfigBody> from String then output it.\r
 \r
+  This is a internal function.\r
+\r
   @param  String                 A sub string of a configuration string in\r
                                  <MultiConfigAltResp> format.\r
   @param  ConfigBody             Points to the output string. It's caller's\r
@@ -571,18 +339,24 @@ GenerateSubStr (
   @retval EFI_SUCCESS            All existing storage is exported.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 OutputConfigBody (\r
-  IN  EFI_STRING                   String,\r
-  OUT EFI_STRING                   *ConfigBody\r
+  IN  EFI_STRING  String,\r
+  OUT EFI_STRING  *ConfigBody\r
   )\r
 {\r
   EFI_STRING  TmpPtr;\r
   EFI_STRING  Result;\r
   UINTN       Length;\r
 \r
-  if (String == NULL || ConfigBody == NULL) {\r
+  if ((String == NULL) || (ConfigBody == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // The setting information should start OFFSET, not ALTCFG.\r
+  //\r
+  if (StrnCmp (String, L"&ALTCFG=", StrLen (L"&ALTCFG=")) == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -601,63 +375,25 @@ OutputConfigBody (
   }\r
 \r
   Length = TmpPtr - String;\r
+  if (Length == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
   Result = AllocateCopyPool (Length * sizeof (CHAR16), String);\r
   if (Result == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   *(Result + Length - 1) = 0;\r
-  *ConfigBody = Result;\r
+  *ConfigBody            = Result;\r
   return EFI_SUCCESS;\r
-\r
-}\r
-\r
-\r
-#endif\r
-\r
-VOID *\r
-ReallocatePool (\r
-  IN VOID                          *OldPool,\r
-  IN UINTN                         OldSize,\r
-  IN UINTN                         NewSize\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-  Adjusts the size of a previously allocated buffer.\r
-\r
-Arguments:\r
-  OldPool               - A pointer to the buffer whose size is being adjusted.\r
-  OldSize               - The size of the current buffer.\r
-  NewSize               - The size of the new buffer.\r
-\r
-Returns:\r
-  Points to the new buffer\r
-\r
---*/\r
-{\r
-  VOID  *NewPool;\r
-\r
-  NewPool = NULL;\r
-  if (NewSize) {\r
-    NewPool = AllocateZeroPool (NewSize);\r
-  }\r
-\r
-  if (OldPool) {\r
-    if (NewPool) {\r
-      CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);\r
-    }\r
-\r
-    gBS->FreePool (OldPool);\r
-  }\r
-\r
-  return NewPool;\r
 }\r
 \r
-\r
 /**\r
   Append a string to a multi-string format.\r
 \r
+  This is a internal function.\r
+\r
   @param  MultiString            String in <MultiConfigRequest>,\r
                                  <MultiConfigAltResp>, or <MultiConfigResp>. On\r
                                  input, the buffer length of  this string is\r
@@ -669,125 +405,4394 @@ Returns:
   @retval EFI_SUCCESS            AppendString is append to the end of MultiString\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 AppendToMultiString (\r
-  IN OUT EFI_STRING                *MultiString,\r
-  IN EFI_STRING                    AppendString\r
+  IN OUT EFI_STRING  *MultiString,\r
+  IN EFI_STRING      AppendString\r
   )\r
 {\r
-  UINTN AppendStringSize;\r
-  UINTN MultiStringSize;\r
+  UINTN  AppendStringSize;\r
+  UINTN  MultiStringSize;\r
+  UINTN  MaxLen;\r
 \r
-  if (MultiString == NULL || *MultiString == NULL || AppendString == NULL) {\r
+  if ((MultiString == NULL) || (*MultiString == NULL) || (AppendString == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   AppendStringSize = StrSize (AppendString);\r
   MultiStringSize  = StrSize (*MultiString);\r
+  MaxLen           = MAX_STRING_LENGTH / sizeof (CHAR16);\r
 \r
   //\r
   // Enlarge the buffer each time when length exceeds MAX_STRING_LENGTH.\r
   //\r
-  if (MultiStringSize + AppendStringSize > MAX_STRING_LENGTH ||\r
-      MultiStringSize > MAX_STRING_LENGTH) {\r
-    *MultiString = (EFI_STRING) ReallocatePool (\r
-                                  (VOID *) (*MultiString),\r
-                                  MultiStringSize,\r
-                                  MultiStringSize + AppendStringSize\r
-                                  );\r
+  if ((MultiStringSize + AppendStringSize > MAX_STRING_LENGTH) ||\r
+      (MultiStringSize > MAX_STRING_LENGTH))\r
+  {\r
+    *MultiString = (EFI_STRING)ReallocatePool (\r
+                                 MultiStringSize,\r
+                                 MultiStringSize + AppendStringSize,\r
+                                 (VOID *)(*MultiString)\r
+                                 );\r
+    MaxLen = (MultiStringSize + AppendStringSize) / sizeof (CHAR16);\r
+    ASSERT (*MultiString != NULL);\r
   }\r
 \r
   //\r
   // Append the incoming string\r
   //\r
-  StrCat (*MultiString, AppendString);\r
+  StrCatS (*MultiString, MaxLen, AppendString);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET\r
   or WIDTH or VALUE.\r
   <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
 \r
+  This is a internal function.\r
+\r
   @param  StringPtr              String in <BlockConfig> format and points to the\r
                                  first character of <Number>.\r
   @param  Number                 The output value. Caller takes the responsibility\r
                                  to free memory.\r
   @param  Len                    Length of the <Number>, in characters.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary\r
                                  structures.\r
   @retval EFI_SUCCESS            Value of <Number> is outputted in Number\r
                                  successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetValueOfNumber (\r
-  IN EFI_STRING                    StringPtr,\r
-  OUT UINT8                        **Number,\r
-  OUT UINTN                        *Len\r
+  IN EFI_STRING  StringPtr,\r
+  OUT UINT8      **Number,\r
+  OUT UINTN      *Len\r
   )\r
 {\r
-  EFI_STRING               TmpPtr;\r
-  UINTN                    Length;\r
-  EFI_STRING               Str;\r
-  UINT8                    *Buf;\r
-  EFI_STATUS               Status;\r
+  EFI_STRING  TmpPtr;\r
+  UINTN       Length;\r
+  EFI_STRING  Str;\r
+  UINT8       *Buf;\r
+  EFI_STATUS  Status;\r
+  UINT8       DigitUint8;\r
+  UINTN       Index;\r
+  CHAR16      TemStr[2];\r
 \r
-  ASSERT (StringPtr != NULL && Number != NULL && Len != NULL);\r
-  ASSERT (*StringPtr != 0);\r
+  if ((StringPtr == NULL) || (*StringPtr == L'\0') || (Number == NULL) || (Len == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
   Buf = NULL;\r
 \r
   TmpPtr = StringPtr;\r
-  while (*StringPtr != 0 && *StringPtr != L'&') {\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
     StringPtr++;\r
   }\r
+\r
   *Len   = StringPtr - TmpPtr;\r
   Length = *Len + 1;\r
 \r
-  Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (EFI_STRING));\r
+  Str = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));\r
   if (Str == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
   }\r
+\r
   CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
-  *(Str + *Len) = 0;\r
+  *(Str + *Len) = L'\0';\r
 \r
   Length = (Length + 1) / 2;\r
-  Buf = (UINT8 *) AllocateZeroPool (Length);\r
+  Buf    = (UINT8 *)AllocateZeroPool (Length);\r
   if (Buf == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
   }\r
 \r
-  Status = R8_HexStringToBuf (Buf, &Length, Str, NULL);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
+  Length = *Len;\r
+  ZeroMem (TemStr, sizeof (TemStr));\r
+  for (Index = 0; Index < Length; Index++) {\r
+    TemStr[0]  = Str[Length - Index - 1];\r
+    DigitUint8 = (UINT8)StrHexToUint64 (TemStr);\r
+    if ((Index & 1) == 0) {\r
+      Buf[Index/2] = DigitUint8;\r
+    } else {\r
+      Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);\r
+    }\r
   }\r
 \r
   *Number = Buf;\r
   Status  = EFI_SUCCESS;\r
 \r
 Exit:\r
-  SafeFreePool (Str);\r
+  if (Str != NULL) {\r
+    FreePool (Str);\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  This function allows a caller to extract the current configuration\r
-  for one or more named elements from one or more drivers.\r
+ To find the BlockName in the string with same value.\r
 \r
-  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
-                                 instance.\r
-  @param  Request                A null-terminated Unicode string in\r
-                                 <MultiConfigRequest> format.\r
-  @param  Progress               On return, points to a character in the Request\r
+  @param  String                 Pointer to a Null-terminated Unicode string.\r
+  @param  BlockName              Pointer to a Null-terminated Unicode string to search for.\r
+  @param  Buffer                 Pointer to the value correspond to the BlockName.\r
+  @param  Found                  The Block whether has been found.\r
+  @param  BufferLen              The length of the buffer.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.\r
+  @retval EFI_SUCCESS            The function finishes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+FindSameBlockElement (\r
+  IN  EFI_STRING  String,\r
+  IN  EFI_STRING  BlockName,\r
+  IN  UINT8       *Buffer,\r
+  OUT BOOLEAN     *Found,\r
+  IN  UINTN       BufferLen\r
+  )\r
+{\r
+  EFI_STRING  BlockPtr;\r
+  UINTN       Length;\r
+  UINT8       *TempBuffer;\r
+  EFI_STATUS  Status;\r
+\r
+  TempBuffer = NULL;\r
+  *Found     = FALSE;\r
+  BlockPtr   = StrStr (String, BlockName);\r
+\r
+  while (BlockPtr != NULL) {\r
+    BlockPtr += StrLen (BlockName);\r
+    Status    = GetValueOfNumber (BlockPtr, &TempBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    ASSERT (TempBuffer != NULL);\r
+    if ((BufferLen == Length) && (0 == CompareMem (Buffer, TempBuffer, Length))) {\r
+      *Found = TRUE;\r
+      FreePool (TempBuffer);\r
+      TempBuffer = NULL;\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      FreePool (TempBuffer);\r
+      TempBuffer = NULL;\r
+      BlockPtr   = StrStr (BlockPtr + 1, BlockName);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Compare the <AltResp> in ConfigAltResp and DefaultAltCfgResp, if the <AltResp>\r
+  in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp.\r
+\r
+  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in\r
+                                 <MultiConfigAltResp> format. The default value\r
+                                 string may contain more than one ConfigAltResp\r
+                                 string for the different varstore buffer.\r
+  @param  ConfigAltResp          Pointer to a null-terminated Unicode string in\r
+                                 <ConfigAltResp> format.\r
+  @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.\r
+  @param  ConfigAltRespChanged   Whether the ConfigAltResp has been changed.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.\r
+  @retval EFI_SUCCESS            The function finishes  successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareBlockElementDefault (\r
+  IN      EFI_STRING  DefaultAltCfgResp,\r
+  IN OUT  EFI_STRING  *ConfigAltResp,\r
+  IN      EFI_STRING  AltConfigHdr,\r
+  IN OUT  BOOLEAN     *ConfigAltRespChanged\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_STRING  BlockPtr;\r
+  EFI_STRING  BlockPtrStart;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  AppendString;\r
+  EFI_STRING  AltConfigHdrPtr;\r
+  UINT8       *TempBuffer;\r
+  UINTN       OffsetLength;\r
+  UINTN       AppendSize;\r
+  UINTN       TotalSize;\r
+  BOOLEAN     FoundOffset;\r
+\r
+  AppendString = NULL;\r
+  TempBuffer   = NULL;\r
+  //\r
+  // Make BlockPtr point to the first <BlockConfig> with AltConfigHdr in DefaultAltCfgResp.\r
+  //\r
+  AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+  ASSERT (AltConfigHdrPtr != NULL);\r
+  BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");\r
+  //\r
+  // Make StringPtr point to the AltConfigHdr in ConfigAltResp.\r
+  //\r
+  StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);\r
+  ASSERT (StringPtr != NULL);\r
+\r
+  while (BlockPtr != NULL) {\r
+    //\r
+    // Find the "&OFFSET=<Number>" block and get the value of the Number with AltConfigHdr in DefaultAltCfgResp.\r
+    //\r
+    BlockPtrStart = BlockPtr;\r
+    BlockPtr     += StrLen (L"&OFFSET=");\r
+    Status        = GetValueOfNumber (BlockPtr, &TempBuffer, &OffsetLength);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
+\r
+    //\r
+    // To find the same "&OFFSET=<Number>" block in ConfigAltResp.\r
+    //\r
+    Status = FindSameBlockElement (StringPtr, L"&OFFSET=", TempBuffer, &FoundOffset, OffsetLength);\r
+    if (TempBuffer != NULL) {\r
+      FreePool (TempBuffer);\r
+      TempBuffer = NULL;\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
+\r
+    if (!FoundOffset) {\r
+      //\r
+      // Don't find the same "&OFFSET=<Number>" block in ConfigAltResp.\r
+      // Calculate the size of <BlockConfig>.\r
+      // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number>.\r
+      //\r
+      BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");\r
+      if (BlockPtr != NULL) {\r
+        AppendSize = (BlockPtr - BlockPtrStart) * sizeof (CHAR16);\r
+      } else {\r
+        AppendSize = StrSize (BlockPtrStart);\r
+      }\r
+\r
+      //\r
+      // Copy the <BlockConfig> to AppendString.\r
+      //\r
+      if (AppendString == NULL) {\r
+        AppendString = (EFI_STRING)AllocateZeroPool (AppendSize + sizeof (CHAR16));\r
+        StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, BlockPtrStart, AppendSize / sizeof (CHAR16));\r
+      } else {\r
+        TotalSize    = StrSize (AppendString) + AppendSize + sizeof (CHAR16);\r
+        AppendString = (EFI_STRING)ReallocatePool (\r
+                                     StrSize (AppendString),\r
+                                     TotalSize,\r
+                                     AppendString\r
+                                     );\r
+        if (AppendString == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Exit;\r
+        }\r
+\r
+        StrnCatS (AppendString, TotalSize / sizeof (CHAR16), BlockPtrStart, AppendSize / sizeof (CHAR16));\r
+      }\r
+    } else {\r
+      //\r
+      // To find next "&OFFSET=<Number>" block with AltConfigHdr in DefaultAltCfgResp.\r
+      //\r
+      BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");\r
+    }\r
+  }\r
+\r
+  if (AppendString != NULL) {\r
+    //\r
+    // Reallocate ConfigAltResp to copy the AppendString.\r
+    //\r
+    TotalSize      = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);\r
+    *ConfigAltResp = (EFI_STRING)ReallocatePool (\r
+                                   StrSize (*ConfigAltResp),\r
+                                   TotalSize,\r
+                                   *ConfigAltResp\r
+                                   );\r
+    if (*ConfigAltResp == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
+\r
+    StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);\r
+    *ConfigAltRespChanged = TRUE;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+  if (AppendString != NULL) {\r
+    FreePool (AppendString);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Compare the <AltResp> in ConfigAltResp and DefaultAltCfgResp, if the <AltResp>\r
+  in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp.\r
+\r
+  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in\r
+                                 <MultiConfigAltResp> format. The default value\r
+                                 string may contain more than one ConfigAltResp\r
+                                 string for the different varstore buffer.\r
+  @param  ConfigAltResp          Pointer to a null-terminated Unicode string in\r
+                                 <ConfigAltResp> format.\r
+  @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.\r
+  @param  ConfigAltRespChanged   Whether the ConfigAltResp has been changed.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.\r
+  @retval EFI_SUCCESS            The function finishes  successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareNameElementDefault (\r
+  IN     EFI_STRING  DefaultAltCfgResp,\r
+  IN OUT EFI_STRING  *ConfigAltResp,\r
+  IN     EFI_STRING  AltConfigHdr,\r
+  IN OUT BOOLEAN     *ConfigAltRespChanged\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_STRING  NvConfigPtr;\r
+  EFI_STRING  NvConfigStart;\r
+  EFI_STRING  NvConfigValuePtr;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  NvConfigExist;\r
+  EFI_STRING  AppendString;\r
+  CHAR16      TempChar;\r
+  UINTN       AppendSize;\r
+  UINTN       TotalSize;\r
+\r
+  AppendString  = NULL;\r
+  NvConfigExist = NULL;\r
+  //\r
+  // Make NvConfigPtr point to the first <NvConfig> with AltConfigHdr in DefaultAltCfgResp.\r
+  //\r
+  NvConfigPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+  ASSERT (NvConfigPtr != NULL);\r
+  NvConfigPtr = StrStr (NvConfigPtr + StrLen (AltConfigHdr), L"&");\r
+  //\r
+  // Make StringPtr point to the first <NvConfig> with AltConfigHdr in ConfigAltResp.\r
+  //\r
+  StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);\r
+  ASSERT (StringPtr != NULL);\r
+  StringPtr = StrStr (StringPtr + StrLen (AltConfigHdr), L"&");\r
+  ASSERT (StringPtr != NULL);\r
+\r
+  while (NvConfigPtr != NULL) {\r
+    //\r
+    // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number>.\r
+    // Get the <Label> with AltConfigHdr in DefaultAltCfgResp.\r
+    //\r
+    NvConfigStart    = NvConfigPtr;\r
+    NvConfigValuePtr = StrStr (NvConfigPtr + 1, L"=");\r
+    ASSERT (NvConfigValuePtr != NULL);\r
+    TempChar          = *NvConfigValuePtr;\r
+    *NvConfigValuePtr = L'\0';\r
+    //\r
+    // Get the <Label> with AltConfigHdr in ConfigAltResp.\r
+    //\r
+    NvConfigExist = StrStr (StringPtr, NvConfigPtr);\r
+    if (NvConfigExist == NULL) {\r
+      //\r
+      // Don't find same <Label> in ConfigAltResp.\r
+      // Calculate the size of <NvConfig>.\r
+      //\r
+      *NvConfigValuePtr = TempChar;\r
+      NvConfigPtr       = StrStr (NvConfigPtr + 1, L"&");\r
+      if (NvConfigPtr != NULL) {\r
+        AppendSize = (NvConfigPtr - NvConfigStart) * sizeof (CHAR16);\r
+      } else {\r
+        AppendSize = StrSize (NvConfigStart);\r
+      }\r
+\r
+      //\r
+      // Copy the <NvConfig> to AppendString.\r
+      //\r
+      if (AppendString == NULL) {\r
+        AppendString = (EFI_STRING)AllocateZeroPool (AppendSize + sizeof (CHAR16));\r
+        StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, NvConfigStart, AppendSize / sizeof (CHAR16));\r
+      } else {\r
+        TotalSize    = StrSize (AppendString) + AppendSize + sizeof (CHAR16);\r
+        AppendString = (EFI_STRING)ReallocatePool (\r
+                                     StrSize (AppendString),\r
+                                     TotalSize,\r
+                                     AppendString\r
+                                     );\r
+        if (AppendString == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Exit;\r
+        }\r
+\r
+        StrnCatS (AppendString, TotalSize / sizeof (CHAR16), NvConfigStart, AppendSize / sizeof (CHAR16));\r
+      }\r
+    } else {\r
+      //\r
+      // To find next <Label> in DefaultAltCfgResp.\r
+      //\r
+      *NvConfigValuePtr = TempChar;\r
+      NvConfigPtr       = StrStr (NvConfigPtr + 1, L"&");\r
+    }\r
+  }\r
+\r
+  if (AppendString != NULL) {\r
+    //\r
+    // Reallocate ConfigAltResp to copy the AppendString.\r
+    //\r
+    TotalSize      = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);\r
+    *ConfigAltResp = (EFI_STRING)ReallocatePool (\r
+                                   StrSize (*ConfigAltResp),\r
+                                   StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16),\r
+                                   *ConfigAltResp\r
+                                   );\r
+    if (*ConfigAltResp == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
+\r
+    StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);\r
+    *ConfigAltRespChanged = TRUE;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+  if (AppendString != NULL) {\r
+    FreePool (AppendString);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Compare the <AltResp> in AltCfgResp and DefaultAltCfgResp, if the <AltResp>\r
+  in DefaultAltCfgResp but not in AltCfgResp,add it to the AltCfgResp.\r
+\r
+  @param  AltCfgResp             Pointer to a null-terminated Unicode string in\r
+                                 <ConfigAltResp> format.\r
+  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in\r
+                                 <MultiConfigAltResp> format. The default value\r
+                                 string may contain more than one ConfigAltResp\r
+                                 string for the different varstore buffer.\r
+  @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary\r
+                                 structures.\r
+  @retval EFI_SUCCESS            The function finishes  successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareAndMergeDefaultString (\r
+  IN OUT EFI_STRING  *AltCfgResp,\r
+  IN     EFI_STRING  DefaultAltCfgResp,\r
+  IN     EFI_STRING  AltConfigHdr\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_STRING  AltCfgRespBackup;\r
+  EFI_STRING  AltConfigHdrPtr;\r
+  EFI_STRING  AltConfigHdrPtrNext;\r
+  EFI_STRING  ConfigAltResp;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  StringPtrNext;\r
+  EFI_STRING  BlockPtr;\r
+  UINTN       ReallocateSize;\r
+  CHAR16      TempChar;\r
+  CHAR16      TempCharA;\r
+  BOOLEAN     ConfigAltRespChanged;\r
+\r
+  Status               = EFI_OUT_OF_RESOURCES;\r
+  BlockPtr             = NULL;\r
+  AltConfigHdrPtrNext  = NULL;\r
+  StringPtrNext        = NULL;\r
+  ConfigAltResp        = NULL;\r
+  AltCfgRespBackup     = NULL;\r
+  TempChar             = L'\0';\r
+  TempCharA            = L'\0';\r
+  ConfigAltRespChanged = FALSE;\r
+\r
+  //\r
+  // To find the <AltResp> with AltConfigHdr in DefaultAltCfgResp, ignore other <AltResp> which follow it.\r
+  //\r
+  AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+  ASSERT (AltConfigHdrPtr != NULL);\r
+  AltConfigHdrPtrNext = StrStr (AltConfigHdrPtr + 1, L"&GUID");\r
+  if (AltConfigHdrPtrNext != NULL) {\r
+    TempChar             = *AltConfigHdrPtrNext;\r
+    *AltConfigHdrPtrNext = L'\0';\r
+  }\r
+\r
+  //\r
+  // To find the <AltResp> with AltConfigHdr in AltCfgResp, ignore other <AltResp> which follow it.\r
+  //\r
+  StringPtr = StrStr (*AltCfgResp, AltConfigHdr);\r
+  ASSERT (StringPtr != NULL);\r
+  StringPtrNext = StrStr (StringPtr + 1, L"&GUID");\r
+  if (StringPtrNext != NULL) {\r
+    TempCharA      = *StringPtrNext;\r
+    *StringPtrNext = L'\0';\r
+  }\r
+\r
+  //\r
+  // Copy the content of <ConfigAltResp> which contain current AltConfigHdr in AltCfgResp.\r
+  //\r
+  ConfigAltResp = AllocateCopyPool (StrSize (*AltCfgResp), *AltCfgResp);\r
+  if (ConfigAltResp == NULL) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // To find the <ConfigBody> with AltConfigHdr in DefaultAltCfgResp.\r
+  //\r
+  BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");\r
+  if (BlockPtr != NULL) {\r
+    //\r
+    // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number> style.\r
+    // Call function CompareBlockElementDefault to compare the <BlockConfig> in DefaultAltCfgResp and ConfigAltResp.\r
+    // The ConfigAltResp which may contain the new <BlockConfig> get from DefaultAltCfgResp.\r
+    //\r
+    Status = CompareBlockElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+  } else {\r
+    //\r
+    // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number> style.\r
+    // Call function CompareNameElementDefault to compare the <NvConfig> in DefaultAltCfgResp and ConfigAltResp.\r
+    // The ConfigAltResp which may contain the new <NvConfig> get from DefaultAltCfgResp.\r
+    //\r
+    Status = CompareNameElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Restore the AltCfgResp.\r
+  //\r
+  if (StringPtrNext != NULL) {\r
+    *StringPtrNext = TempCharA;\r
+  }\r
+\r
+  //\r
+  // If the ConfigAltResp has no change,no need to update the content in AltCfgResp.\r
+  //\r
+  if (!ConfigAltRespChanged) {\r
+    Status = EFI_SUCCESS;\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // ConfigAltResp has been changed, need to update the content in AltCfgResp.\r
+  //\r
+  if (StringPtrNext != NULL) {\r
+    ReallocateSize = StrSize (ConfigAltResp) + StrSize (StringPtrNext) + sizeof (CHAR16);\r
+  } else {\r
+    ReallocateSize = StrSize (ConfigAltResp) + sizeof (CHAR16);\r
+  }\r
+\r
+  AltCfgRespBackup = (EFI_STRING)AllocateZeroPool (ReallocateSize);\r
+  if (AltCfgRespBackup == NULL) {\r
+    goto Exit;\r
+  }\r
+\r
+  StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), ConfigAltResp);\r
+  if (StringPtrNext != NULL) {\r
+    StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), StringPtrNext);\r
+  }\r
+\r
+  FreePool (*AltCfgResp);\r
+  *AltCfgResp = AltCfgRespBackup;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+  if (ConfigAltResp != NULL) {\r
+    FreePool (ConfigAltResp);\r
+  }\r
+\r
+  //\r
+  // Restore the DefaultAltCfgResp.\r
+  //\r
+  if ( AltConfigHdrPtrNext != NULL) {\r
+    *AltConfigHdrPtrNext = TempChar;\r
+    AltConfigHdrPtrNext  = NULL;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function merges DefaultAltCfgResp string into AltCfgResp string for\r
+  the missing AltCfgId in AltCfgResq.\r
+\r
+  @param  AltCfgResp             Pointer to a null-terminated Unicode string in\r
+                                 <ConfigAltResp> format. The default value string\r
+                                 will be merged into it.\r
+  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in\r
+                                 <MultiConfigAltResp> format. The default value\r
+                                 string may contain more than one ConfigAltResp\r
+                                 string for the different varstore buffer.\r
+\r
+  @retval EFI_SUCCESS            The merged string returns.\r
+  @retval EFI_INVALID_PARAMETER  *AltCfgResp is to NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MergeDefaultString (\r
+  IN OUT EFI_STRING  *AltCfgResp,\r
+  IN     EFI_STRING  DefaultAltCfgResp\r
+  )\r
+{\r
+  EFI_STRING  StringPtrDefault;\r
+  EFI_STRING  StringPtrEnd;\r
+  CHAR16      TempChar;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  AltConfigHdr;\r
+  UINTN       HeaderLength;\r
+  UINTN       SizeAltCfgResp;\r
+  UINTN       MaxLen;\r
+  UINTN       TotalSize;\r
+\r
+  if (*AltCfgResp == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Get the request ConfigHdr\r
+  //\r
+  SizeAltCfgResp = 0;\r
+  StringPtr      = *AltCfgResp;\r
+\r
+  //\r
+  // Find <ConfigHdr> GUID=...&NAME=...&PATH=...\r
+  //\r
+  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+\r
+  if (*StringPtr == L'\0') {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  StringPtr += StrLen (L"&PATH=");\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+\r
+  HeaderLength = StringPtr - *AltCfgResp;\r
+\r
+  //\r
+  // Construct AltConfigHdr string  "&<ConfigHdr>&ALTCFG=XXXX\0"\r
+  //                                  |1| StrLen (ConfigHdr) | 8 | 4 | 1 |\r
+  //\r
+  MaxLen       = 1 + HeaderLength + 8 + 4 + 1;\r
+  AltConfigHdr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
+  if (AltConfigHdr == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  StrCpyS (AltConfigHdr, MaxLen, L"&");\r
+  StrnCatS (AltConfigHdr, MaxLen, *AltCfgResp, HeaderLength);\r
+  StrCatS (AltConfigHdr, MaxLen, L"&ALTCFG=");\r
+  HeaderLength = StrLen (AltConfigHdr);\r
+\r
+  StringPtrDefault = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+  while (StringPtrDefault != NULL) {\r
+    //\r
+    // Get AltCfg Name\r
+    //\r
+    StrnCatS (AltConfigHdr, MaxLen, StringPtrDefault + HeaderLength, 4);\r
+    StringPtr = StrStr (*AltCfgResp, AltConfigHdr);\r
+\r
+    //\r
+    // Append the found default value string to the input AltCfgResp\r
+    //\r
+    if (StringPtr == NULL) {\r
+      StringPtrEnd   = StrStr (StringPtrDefault + 1, L"&GUID");\r
+      SizeAltCfgResp = StrSize (*AltCfgResp);\r
+      if (StringPtrEnd == NULL) {\r
+        //\r
+        // No more default string is found.\r
+        //\r
+        TotalSize   = SizeAltCfgResp + StrSize (StringPtrDefault);\r
+        *AltCfgResp = (EFI_STRING)ReallocatePool (\r
+                                    SizeAltCfgResp,\r
+                                    TotalSize,\r
+                                    (VOID *)(*AltCfgResp)\r
+                                    );\r
+        if (*AltCfgResp == NULL) {\r
+          FreePool (AltConfigHdr);\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+\r
+        StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);\r
+        break;\r
+      } else {\r
+        TempChar      = *StringPtrEnd;\r
+        *StringPtrEnd = L'\0';\r
+        TotalSize     = SizeAltCfgResp + StrSize (StringPtrDefault);\r
+        *AltCfgResp   = (EFI_STRING)ReallocatePool (\r
+                                      SizeAltCfgResp,\r
+                                      TotalSize,\r
+                                      (VOID *)(*AltCfgResp)\r
+                                      );\r
+        if (*AltCfgResp == NULL) {\r
+          FreePool (AltConfigHdr);\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+\r
+        StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);\r
+        *StringPtrEnd = TempChar;\r
+      }\r
+    } else {\r
+      //\r
+      // The AltCfgResp contains <AltCfgResp>.\r
+      // If the <ConfigElement> in <AltCfgResp> in the DefaultAltCfgResp but not in the\r
+      // related <AltCfgResp> in AltCfgResp, merge it to AltCfgResp. else no need to merge.\r
+      //\r
+      CompareAndMergeDefaultString (AltCfgResp, DefaultAltCfgResp, AltConfigHdr);\r
+    }\r
+\r
+    //\r
+    // Find next AltCfg String\r
+    //\r
+    *(AltConfigHdr + HeaderLength) = L'\0';\r
+    StringPtrDefault               = StrStr (StringPtrDefault + 1, AltConfigHdr);\r
+  }\r
+\r
+  FreePool (AltConfigHdr);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function inserts new DefaultValueData into the BlockData DefaultValue array.\r
+\r
+  @param  BlockData         The BlockData is updated to add new default value.\r
+  @param  DefaultValueData  The DefaultValue is added.\r
+\r
+**/\r
+VOID\r
+InsertDefaultValue (\r
+  IN IFR_BLOCK_DATA    *BlockData,\r
+  IN IFR_DEFAULT_DATA  *DefaultValueData\r
+  )\r
+{\r
+  LIST_ENTRY        *Link;\r
+  IFR_DEFAULT_DATA  *DefaultValueArray;\r
+  LIST_ENTRY        *DefaultLink;\r
+\r
+  DefaultLink = &BlockData->DefaultValueEntry;\r
+\r
+  for (Link = DefaultLink->ForwardLink; Link != DefaultLink; Link = Link->ForwardLink) {\r
+    DefaultValueArray = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {\r
+      //\r
+      // DEFAULT_VALUE_FROM_OPCODE has high priority, DEFAULT_VALUE_FROM_DEFAULT has low priority.\r
+      // When default types are DEFAULT_VALUE_FROM_OTHER_DEFAULT, the default value can be overrode.\r
+      //\r
+      if ((DefaultValueData->Type > DefaultValueArray->Type) || ((DefaultValueData->Type == DefaultValueArray->Type) && (DefaultValueData->Type == DefaultValueFromOtherDefault))) {\r
+        //\r
+        // Update the default value array in BlockData.\r
+        //\r
+        CopyMem (&DefaultValueArray->Value, &DefaultValueData->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+        DefaultValueArray->Type    = DefaultValueData->Type;\r
+        DefaultValueArray->Cleaned = DefaultValueData->Cleaned;\r
+      }\r
+\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Insert new default value data in tail.\r
+  //\r
+  DefaultValueArray = AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+  ASSERT (DefaultValueArray != NULL);\r
+  CopyMem (DefaultValueArray, DefaultValueData, sizeof (IFR_DEFAULT_DATA));\r
+  InsertTailList (Link, &DefaultValueArray->Entry);\r
+}\r
+\r
+/**\r
+  This function inserts new BlockData into the block link\r
+\r
+  @param  BlockLink      The list entry points to block array.\r
+  @param  BlockData      The point to BlockData is added.\r
+\r
+**/\r
+VOID\r
+InsertBlockData (\r
+  IN LIST_ENTRY      *BlockLink,\r
+  IN IFR_BLOCK_DATA  **BlockData\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  IFR_BLOCK_DATA  *BlockArray;\r
+  IFR_BLOCK_DATA  *BlockSingleData;\r
+\r
+  BlockSingleData = *BlockData;\r
+\r
+  if (BlockSingleData->Name != NULL) {\r
+    InsertTailList (BlockLink, &BlockSingleData->Entry);\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Insert block data in its Offset and Width order.\r
+  //\r
+  for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
+    BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (BlockArray->Offset == BlockSingleData->Offset) {\r
+      if ((BlockArray->Width > BlockSingleData->Width) || (BlockSingleData->IsBitVar && (BlockArray->Width == BlockSingleData->Width))) {\r
+        //\r
+        // Insert this block data in the front of block array\r
+        //\r
+        InsertTailList (Link, &BlockSingleData->Entry);\r
+        return;\r
+      }\r
+\r
+      if ((!BlockSingleData->IsBitVar) && (BlockArray->Width == BlockSingleData->Width)) {\r
+        //\r
+        // The same block array has been added.\r
+        //\r
+        if (BlockSingleData != BlockArray) {\r
+          FreePool (BlockSingleData);\r
+          *BlockData = BlockArray;\r
+        }\r
+\r
+        return;\r
+      }\r
+    } else if (BlockArray->Offset > BlockSingleData->Offset) {\r
+      //\r
+      // Insert new block data in the front of block array\r
+      //\r
+      InsertTailList (Link, &BlockSingleData->Entry);\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Add new block data into the tail.\r
+  //\r
+  InsertTailList (Link, &BlockSingleData->Entry);\r
+}\r
+\r
+/**\r
+  Retrieves a pointer to the a Null-terminated ASCII string containing the list\r
+  of languages that an HII handle in the HII Database supports.  The returned\r
+  string is allocated using AllocatePool().  The caller is responsible for freeing\r
+  the returned string using FreePool().  The format of the returned string follows\r
+  the language format assumed the HII Database.\r
+\r
+  If HiiHandle is NULL, then ASSERT().\r
+\r
+  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.\r
+\r
+  @retval NULL   HiiHandle is not registered in the HII database\r
+  @retval NULL   There are not enough resources available to retrieve the supported\r
+                 languages.\r
+  @retval NULL   The list of supported languages could not be retrieved.\r
+  @retval Other  A pointer to the Null-terminated ASCII string of supported languages.\r
+\r
+**/\r
+CHAR8 *\r
+GetSupportedLanguages (\r
+  IN EFI_HII_HANDLE  HiiHandle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       LanguageSize;\r
+  CHAR8       TempSupportedLanguages;\r
+  CHAR8       *SupportedLanguages;\r
+\r
+  ASSERT (HiiHandle != NULL);\r
+\r
+  //\r
+  // Retrieve the size required for the supported languages buffer.\r
+  //\r
+  LanguageSize = 0;\r
+  Status       = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize);\r
+\r
+  //\r
+  // If GetLanguages() returns EFI_SUCCESS for a zero size,\r
+  // then there are no supported languages registered for HiiHandle.  If GetLanguages()\r
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+  // in the HII Database\r
+  //\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    //\r
+    // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database\r
+    //\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Allocate the supported languages buffer.\r
+  //\r
+  SupportedLanguages = AllocateZeroPool (LanguageSize);\r
+  if (SupportedLanguages == NULL) {\r
+    //\r
+    // Return NULL if allocation fails.\r
+    //\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Retrieve the supported languages string\r
+  //\r
+  Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, SupportedLanguages, &LanguageSize);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+    //\r
+    FreePool (SupportedLanguages);\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Return the Null-terminated ASCII string of supported languages\r
+  //\r
+  return SupportedLanguages;\r
+}\r
+\r
+/**\r
+  Retrieves a string from a string package.\r
+\r
+  If HiiHandle is NULL, then ASSERT().\r
+  If StringId is 0, then ASSET.\r
+\r
+  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.\r
+  @param[in]  StringId   The identifier of the string to retrieved from the string\r
+                         package associated with HiiHandle.\r
+\r
+  @retval NULL   The string specified by StringId is not present in the string package.\r
+  @retval Other  The string was returned.\r
+\r
+**/\r
+EFI_STRING\r
+InternalGetString (\r
+  IN EFI_HII_HANDLE  HiiHandle,\r
+  IN EFI_STRING_ID   StringId\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       StringSize;\r
+  CHAR16      TempString;\r
+  EFI_STRING  String;\r
+  CHAR8       *SupportedLanguages;\r
+  CHAR8       *PlatformLanguage;\r
+  CHAR8       *BestLanguage;\r
+  CHAR8       *Language;\r
+\r
+  ASSERT (HiiHandle != NULL);\r
+  ASSERT (StringId != 0);\r
+\r
+  //\r
+  // Initialize all allocated buffers to NULL\r
+  //\r
+  SupportedLanguages = NULL;\r
+  PlatformLanguage   = NULL;\r
+  BestLanguage       = NULL;\r
+  String             = NULL;\r
+  Language           = "";\r
+\r
+  //\r
+  // Get the languages that the package specified by HiiHandle supports\r
+  //\r
+  SupportedLanguages = GetSupportedLanguages (HiiHandle);\r
+  if (SupportedLanguages == NULL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Get the current platform language setting\r
+  //\r
+  GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL);\r
+\r
+  //\r
+  // Get the best matching language from SupportedLanguages\r
+  //\r
+  BestLanguage = GetBestLanguage (\r
+                   SupportedLanguages,\r
+                   FALSE,                                             // RFC 4646 mode\r
+                   Language,                                          // Highest priority\r
+                   PlatformLanguage != NULL ? PlatformLanguage : "",  // Next highest priority\r
+                   SupportedLanguages,                                // Lowest priority\r
+                   NULL\r
+                   );\r
+  if (BestLanguage == NULL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Retrieve the size of the string in the string package for the BestLanguage\r
+  //\r
+  StringSize = 0;\r
+  Status     = mPrivate.HiiString.GetString (\r
+                                    &mPrivate.HiiString,\r
+                                    BestLanguage,\r
+                                    HiiHandle,\r
+                                    StringId,\r
+                                    &TempString,\r
+                                    &StringSize,\r
+                                    NULL\r
+                                    );\r
+  //\r
+  // If GetString() returns EFI_SUCCESS for a zero size,\r
+  // then there are no supported languages registered for HiiHandle.  If GetString()\r
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+  // in the HII Database\r
+  //\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Allocate a buffer for the return string\r
+  //\r
+  String = AllocateZeroPool (StringSize);\r
+  if (String == NULL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Retrieve the string from the string package\r
+  //\r
+  Status = mPrivate.HiiString.GetString (\r
+                                &mPrivate.HiiString,\r
+                                BestLanguage,\r
+                                HiiHandle,\r
+                                StringId,\r
+                                String,\r
+                                &StringSize,\r
+                                NULL\r
+                                );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+    //\r
+    FreePool (String);\r
+    String = NULL;\r
+  }\r
+\r
+Error:\r
+  //\r
+  // Free allocated buffers\r
+  //\r
+  if (SupportedLanguages != NULL) {\r
+    FreePool (SupportedLanguages);\r
+  }\r
+\r
+  if (PlatformLanguage != NULL) {\r
+    FreePool (PlatformLanguage);\r
+  }\r
+\r
+  if (BestLanguage != NULL) {\r
+    FreePool (BestLanguage);\r
+  }\r
+\r
+  //\r
+  // Return the Null-terminated Unicode string\r
+  //\r
+  return String;\r
+}\r
+\r
+/**\r
+  This function checks VarOffset and VarWidth is in the block range.\r
+\r
+  @param  RequestBlockArray  The block array is to be checked.\r
+  @param  VarOffset          Offset of var to the structure\r
+  @param  VarWidth           Width of var.\r
+  @param  IsNameValueType    Whether this varstore is name/value varstore or not.\r
+  @param  HiiHandle          Hii handle for this hii package.\r
+\r
+  @retval TRUE   This Var is in the block range.\r
+  @retval FALSE  This Var is not in the block range.\r
+**/\r
+BOOLEAN\r
+BlockArrayCheck (\r
+  IN IFR_BLOCK_DATA  *RequestBlockArray,\r
+  IN UINT16          VarOffset,\r
+  IN UINT16          VarWidth,\r
+  IN BOOLEAN         IsNameValueType,\r
+  IN EFI_HII_HANDLE  HiiHandle\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  IFR_BLOCK_DATA  *BlockData;\r
+  EFI_STRING      Name;\r
+\r
+  //\r
+  // No Request Block array, all vars are got.\r
+  //\r
+  if (RequestBlockArray == NULL) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Check the input var is in the request block range.\r
+  //\r
+  for (Link = RequestBlockArray->Entry.ForwardLink; Link != &RequestBlockArray->Entry; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+\r
+    if (IsNameValueType) {\r
+      Name = InternalGetString (HiiHandle, VarOffset);\r
+      ASSERT (Name != NULL);\r
+\r
+      if (StrnCmp (BlockData->Name, Name, StrLen (Name)) == 0) {\r
+        FreePool (Name);\r
+        return TRUE;\r
+      }\r
+\r
+      FreePool (Name);\r
+    } else {\r
+      if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {\r
+        return TRUE;\r
+      }\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Get form package data from data base.\r
+\r
+  @param  DataBaseRecord         The DataBaseRecord instance contains the found Hii handle and package.\r
+  @param  HiiFormPackage         The buffer saves the package data.\r
+  @param  PackageSize            The buffer size of the package data.\r
+\r
+**/\r
+EFI_STATUS\r
+GetFormPackageData (\r
+  IN     HII_DATABASE_RECORD  *DataBaseRecord,\r
+  IN OUT UINT8                **HiiFormPackage,\r
+  OUT    UINTN                *PackageSize\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Size;\r
+  UINTN       ResultSize;\r
+\r
+  if ((DataBaseRecord == NULL) || (HiiFormPackage == NULL) || (PackageSize == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Size       = 0;\r
+  ResultSize = 0;\r
+  //\r
+  // 0. Get Hii Form Package by HiiHandle\r
+  //\r
+  Status = ExportFormPackages (\r
+             &mPrivate,\r
+             DataBaseRecord->Handle,\r
+             DataBaseRecord->PackageList,\r
+             0,\r
+             Size,\r
+             HiiFormPackage,\r
+             &ResultSize\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  (*HiiFormPackage) = AllocatePool (ResultSize);\r
+  if (*HiiFormPackage == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get HiiFormPackage by HiiHandle\r
+  //\r
+  Size       = ResultSize;\r
+  ResultSize = 0;\r
+  Status     = ExportFormPackages (\r
+                 &mPrivate,\r
+                 DataBaseRecord->Handle,\r
+                 DataBaseRecord->PackageList,\r
+                 0,\r
+                 Size,\r
+                 *HiiFormPackage,\r
+                 &ResultSize\r
+                 );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (*HiiFormPackage);\r
+  }\r
+\r
+  *PackageSize = Size;\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function parses Form Package to get the efi varstore info according to the request ConfigHdr.\r
+\r
+  @param  DataBaseRecord        The DataBaseRecord instance contains the found Hii handle and package.\r
+  @param  ConfigHdr             Request string ConfigHdr. If it is NULL,\r
+                                the first found varstore will be as ConfigHdr.\r
+  @param  IsEfiVarstore         Whether the request storage type is efi varstore type.\r
+  @param  EfiVarStore           The efi varstore info which will return.\r
+**/\r
+EFI_STATUS\r
+GetVarStoreType (\r
+  IN     HII_DATABASE_RECORD   *DataBaseRecord,\r
+  IN     EFI_STRING            ConfigHdr,\r
+  OUT    BOOLEAN               *IsEfiVarstore,\r
+  OUT    EFI_IFR_VARSTORE_EFI  **EfiVarStore\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  UINTN                   IfrOffset;\r
+  UINTN                   PackageOffset;\r
+  EFI_IFR_OP_HEADER       *IfrOpHdr;\r
+  CHAR16                  *VarStoreName;\r
+  UINTN                   NameSize;\r
+  EFI_STRING              GuidStr;\r
+  EFI_STRING              NameStr;\r
+  EFI_STRING              TempStr;\r
+  UINTN                   LengthString;\r
+  UINT8                   *HiiFormPackage;\r
+  UINTN                   PackageSize;\r
+  EFI_IFR_VARSTORE_EFI    *IfrEfiVarStore;\r
+  EFI_HII_PACKAGE_HEADER  *PackageHeader;\r
+\r
+  HiiFormPackage = NULL;\r
+  LengthString   = 0;\r
+  Status         = EFI_SUCCESS;\r
+  GuidStr        = NULL;\r
+  NameStr        = NULL;\r
+  TempStr        = NULL;\r
+  *IsEfiVarstore = FALSE;\r
+\r
+  Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  IfrOffset     = sizeof (EFI_HII_PACKAGE_HEADER);\r
+  PackageOffset = IfrOffset;\r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiFormPackage;\r
+\r
+  while (IfrOffset < PackageSize) {\r
+    //\r
+    // More than one form packages exist.\r
+    //\r
+    if (PackageOffset >= PackageHeader->Length) {\r
+      //\r
+      // Process the new form package.\r
+      //\r
+      PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+      IfrOffset    += PackageOffset;\r
+      PackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiFormPackage + IfrOffset);\r
+    }\r
+\r
+    IfrOpHdr       = (EFI_IFR_OP_HEADER *)(HiiFormPackage + IfrOffset);\r
+    IfrOffset     += IfrOpHdr->Length;\r
+    PackageOffset += IfrOpHdr->Length;\r
+\r
+    if (IfrOpHdr->OpCode == EFI_IFR_VARSTORE_EFI_OP ) {\r
+      IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;\r
+      //\r
+      // If the length is small than the structure, this is from old efi\r
+      // varstore definition. Old efi varstore get config directly from\r
+      // GetVariable function.\r
+      //\r
+      if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+        continue;\r
+      }\r
+\r
+      NameSize     = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);\r
+      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+      if (VarStoreName == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);\r
+\r
+      GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)&IfrEfiVarStore->Guid, 1, &GuidStr);\r
+      GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *)VarStoreName, 2, &NameStr);\r
+      LengthString = StrLen (GuidStr);\r
+      LengthString = LengthString + StrLen (NameStr) + 1;\r
+      TempStr      = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
+      if (TempStr == NULL) {\r
+        FreePool (GuidStr);\r
+        FreePool (NameStr);\r
+        FreePool (VarStoreName);\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      StrCpyS (TempStr, LengthString, GuidStr);\r
+      StrCatS (TempStr, LengthString, NameStr);\r
+      if ((ConfigHdr == NULL) || (StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0)) {\r
+        *EfiVarStore = (EFI_IFR_VARSTORE_EFI *)AllocateZeroPool (IfrOpHdr->Length);\r
+        if (*EfiVarStore == NULL) {\r
+          FreePool (VarStoreName);\r
+          FreePool (GuidStr);\r
+          FreePool (NameStr);\r
+          FreePool (TempStr);\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+\r
+        *IsEfiVarstore = TRUE;\r
+        CopyMem (*EfiVarStore, IfrEfiVarStore, IfrOpHdr->Length);\r
+      }\r
+\r
+      //\r
+      // Free allocated temp string.\r
+      //\r
+      FreePool (VarStoreName);\r
+      FreePool (GuidStr);\r
+      FreePool (NameStr);\r
+      FreePool (TempStr);\r
+\r
+      //\r
+      // Already found the varstore, break;\r
+      //\r
+      if (*IsEfiVarstore) {\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (HiiFormPackage != NULL) {\r
+    FreePool (HiiFormPackage);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Check whether the ConfigRequest string has the request elements.\r
+  For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.\r
+  For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.\r
+\r
+  @param  ConfigRequest      The input config request string.\r
+\r
+  @retval  TRUE              The input include config request elements.\r
+  @retval  FALSE             The input string not includes.\r
+\r
+**/\r
+BOOLEAN\r
+GetElementsFromRequest (\r
+  IN EFI_STRING  ConfigRequest\r
+  )\r
+{\r
+  EFI_STRING  TmpRequest;\r
+\r
+  TmpRequest = StrStr (ConfigRequest, L"PATH=");\r
+  ASSERT (TmpRequest != NULL);\r
+\r
+  if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Check whether the this varstore is the request varstore.\r
+\r
+  @param  VarstoreGuid      Varstore guid.\r
+  @param  Name              Varstore name.\r
+  @param  ConfigHdr         Current configRequest info.\r
+\r
+  @retval  TRUE              This varstore is the request one.\r
+  @retval  FALSE             This varstore is not the request one.\r
+\r
+**/\r
+BOOLEAN\r
+IsThisVarstore (\r
+  IN EFI_GUID  *VarstoreGuid,\r
+  IN CHAR16    *Name,\r
+  IN CHAR16    *ConfigHdr\r
+  )\r
+{\r
+  EFI_STRING  GuidStr;\r
+  EFI_STRING  NameStr;\r
+  EFI_STRING  TempStr;\r
+  UINTN       LengthString;\r
+  BOOLEAN     RetVal;\r
+\r
+  RetVal  = FALSE;\r
+  GuidStr = NULL;\r
+  TempStr = NULL;\r
+\r
+  //\r
+  // If ConfigHdr has name field and varstore not has name, return FALSE.\r
+  //\r
+  if ((Name == NULL) && (ConfigHdr != NULL) && (StrStr (ConfigHdr, L"NAME=&") == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);\r
+  if (Name != NULL) {\r
+    GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *)Name, 2, &NameStr);\r
+  } else {\r
+    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
+  }\r
+\r
+  LengthString = StrLen (GuidStr);\r
+  LengthString = LengthString + StrLen (NameStr) + 1;\r
+  TempStr      = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
+  if (TempStr == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  StrCpyS (TempStr, LengthString, GuidStr);\r
+  StrCatS (TempStr, LengthString, NameStr);\r
+\r
+  if ((ConfigHdr == NULL) || (StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0)) {\r
+    RetVal = TRUE;\r
+  }\r
+\r
+Done:\r
+  if (GuidStr != NULL) {\r
+    FreePool (GuidStr);\r
+  }\r
+\r
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
+\r
+  if (TempStr != NULL) {\r
+    FreePool (TempStr);\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  This function parses Form Package to get the efi varstore info according to the request ConfigHdr.\r
+\r
+  @param  DataBaseRecord        The DataBaseRecord instance contains the found Hii handle and package.\r
+  @param  ConfigHdr             Request string ConfigHdr. If it is NULL,\r
+                                the first found varstore will be as ConfigHdr.\r
+  @retval  TRUE                 This hii package is the request one.\r
+  @retval  FALSE                This hii package is not the request one.\r
+**/\r
+BOOLEAN\r
+IsThisPackageList (\r
+  IN     HII_DATABASE_RECORD  *DataBaseRecord,\r
+  IN     EFI_STRING           ConfigHdr\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        IfrOffset;\r
+  UINTN                        PackageOffset;\r
+  EFI_IFR_OP_HEADER            *IfrOpHdr;\r
+  CHAR16                       *VarStoreName;\r
+  UINTN                        NameSize;\r
+  UINT8                        *HiiFormPackage;\r
+  UINTN                        PackageSize;\r
+  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStore;\r
+  EFI_HII_PACKAGE_HEADER       *PackageHeader;\r
+  EFI_IFR_VARSTORE             *IfrVarStore;\r
+  EFI_IFR_VARSTORE_NAME_VALUE  *IfrNameValueVarStore;\r
+  BOOLEAN                      FindVarstore;\r
+\r
+  HiiFormPackage = NULL;\r
+  VarStoreName   = NULL;\r
+  Status         = EFI_SUCCESS;\r
+  FindVarstore   = FALSE;\r
+\r
+  Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);\r
+  if (EFI_ERROR (Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+  IfrOffset     = sizeof (EFI_HII_PACKAGE_HEADER);\r
+  PackageOffset = IfrOffset;\r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiFormPackage;\r
+\r
+  while (IfrOffset < PackageSize) {\r
+    //\r
+    // More than one form packages exist.\r
+    //\r
+    if (PackageOffset >= PackageHeader->Length) {\r
+      //\r
+      // Process the new form package.\r
+      //\r
+      PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+      IfrOffset    += PackageOffset;\r
+      PackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiFormPackage + IfrOffset);\r
+    }\r
+\r
+    IfrOpHdr       = (EFI_IFR_OP_HEADER *)(HiiFormPackage + IfrOffset);\r
+    IfrOffset     += IfrOpHdr->Length;\r
+    PackageOffset += IfrOpHdr->Length;\r
+\r
+    switch (IfrOpHdr->OpCode) {\r
+      case EFI_IFR_VARSTORE_OP:\r
+        IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;\r
+\r
+        NameSize     = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);\r
+        VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+        if (VarStoreName == NULL) {\r
+          goto Done;\r
+        }\r
+\r
+        AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);\r
+\r
+        if (IsThisVarstore ((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+          FindVarstore = TRUE;\r
+          goto Done;\r
+        } else {\r
+          FreePool (VarStoreName);\r
+          VarStoreName = NULL;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_VARSTORE_EFI_OP:\r
+        IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;\r
+        NameSize       = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);\r
+        VarStoreName   = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+        if (VarStoreName == NULL) {\r
+          goto Done;\r
+        }\r
+\r
+        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);\r
+\r
+        if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+          FindVarstore = TRUE;\r
+          goto Done;\r
+        } else {\r
+          FreePool (VarStoreName);\r
+          VarStoreName = NULL;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
+        IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;\r
+\r
+        if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {\r
+          FindVarstore = TRUE;\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
+        //\r
+        // No matched varstore is found and directly return.\r
+        //\r
+        goto Done;\r
+\r
+      default:\r
+        break;\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (HiiFormPackage != NULL) {\r
+    FreePool (HiiFormPackage);\r
+  }\r
+\r
+  if (VarStoreName != NULL) {\r
+    FreePool (VarStoreName);\r
+  }\r
+\r
+  return FindVarstore;\r
+}\r
+\r
+/**\r
+  Check whether the this op code is required.\r
+\r
+  @param  RequestBlockArray      The array includes all the request info or NULL.\r
+  @param  HiiHandle              The hii handle for this form package.\r
+  @param  VarStorageData         The varstore data structure.\r
+  @param  IfrOpHdr               Ifr opcode header for this opcode.\r
+  @param  VarWidth               The buffer width for this opcode.\r
+  @param  ReturnData             The data block added for this opcode.\r
+  @param  IsBitVar               Whether the the opcode refers to bit storage.\r
+\r
+  @retval  EFI_SUCCESS           This opcode is required.\r
+  @retval  EFI_NOT_FOUND         This opcode is not required.\r
+  @retval  Others                Contain some error.\r
+\r
+**/\r
+EFI_STATUS\r
+IsThisOpcodeRequired (\r
+  IN     IFR_BLOCK_DATA       *RequestBlockArray,\r
+  IN     EFI_HII_HANDLE       HiiHandle,\r
+  IN OUT IFR_VARSTORAGE_DATA  *VarStorageData,\r
+  IN     EFI_IFR_OP_HEADER    *IfrOpHdr,\r
+  IN     UINT16               VarWidth,\r
+  OUT    IFR_BLOCK_DATA       **ReturnData,\r
+  IN     BOOLEAN              IsBitVar\r
+  )\r
+{\r
+  IFR_BLOCK_DATA           *BlockData;\r
+  UINT16                   VarOffset;\r
+  EFI_STRING_ID            NameId;\r
+  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;\r
+  UINT16                   BitOffset;\r
+  UINT16                   BitWidth;\r
+  UINT16                   TotalBits;\r
+\r
+  NameId         = 0;\r
+  VarOffset      = 0;\r
+  BitOffset      = 0;\r
+  BitWidth       = 0;\r
+  IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER  *)((CHAR8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));\r
+\r
+  if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    NameId = IfrQuestionHdr->VarStoreInfo.VarName;\r
+\r
+    //\r
+    // Check whether this question is in requested block array.\r
+    //\r
+    if (!BlockArrayCheck (RequestBlockArray, NameId, 0, TRUE, HiiHandle)) {\r
+      //\r
+      // This question is not in the requested string. Skip it.\r
+      //\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  } else {\r
+    //\r
+    // Get the byte offset/with and bit offset/width\r
+    //\r
+    if (IsBitVar) {\r
+      BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+      BitWidth  = VarWidth;\r
+      VarOffset = BitOffset / 8;\r
+      //\r
+      // Use current bit width and the bit width before current bit (with same byte offset) to calculate the byte width.\r
+      //\r
+      TotalBits = BitOffset % 8 + BitWidth;\r
+      VarWidth  = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);\r
+    } else {\r
+      VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+      BitWidth  = VarWidth;\r
+      BitOffset = VarOffset * 8;\r
+    }\r
+\r
+    //\r
+    // Check whether this question is in requested block array.\r
+    //\r
+    if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth, FALSE, HiiHandle)) {\r
+      //\r
+      // This question is not in the requested string. Skip it.\r
+      //\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    //\r
+    // Check this var question is in the var storage\r
+    //\r
+    if (((VarOffset + VarWidth) > VarStorageData->Size)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (BlockData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    BlockData->Name = InternalGetString (HiiHandle, NameId);\r
+  } else {\r
+    BlockData->Offset = VarOffset;\r
+  }\r
+\r
+  BlockData->Width      = VarWidth;\r
+  BlockData->QuestionId = IfrQuestionHdr->QuestionId;\r
+  BlockData->OpCode     = IfrOpHdr->OpCode;\r
+  BlockData->Scope      = IfrOpHdr->Scope;\r
+  BlockData->IsBitVar   = IsBitVar;\r
+  BlockData->BitOffset  = BitOffset;\r
+  BlockData->BitWidth   = BitWidth;\r
+  InitializeListHead (&BlockData->DefaultValueEntry);\r
+  //\r
+  // Add Block Data into VarStorageData BlockEntry\r
+  //\r
+  InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+  *ReturnData = BlockData;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function parses Form Package to get the block array and the default\r
+  value array according to the request ConfigHdr.\r
+\r
+  @param  HiiHandle             Hii Handle for this hii package.\r
+  @param  Package               Pointer to the form package data.\r
+  @param  PackageLength         Length of the package.\r
+  @param  ConfigHdr             Request string ConfigHdr. If it is NULL,\r
+                                the first found varstore will be as ConfigHdr.\r
+  @param  RequestBlockArray     The block array is retrieved from the request string.\r
+  @param  VarStorageData        VarStorage structure contains the got block and default value.\r
+  @param  DefaultIdArray        Point to the got default id and default name array.\r
+\r
+  @retval EFI_SUCCESS           The block array and the default value array are got.\r
+  @retval EFI_INVALID_PARAMETER The varstore definition in the different form packages\r
+                                are conflicted.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ParseIfrData (\r
+  IN     EFI_HII_HANDLE       HiiHandle,\r
+  IN     UINT8                *Package,\r
+  IN     UINT32               PackageLength,\r
+  IN     EFI_STRING           ConfigHdr,\r
+  IN     IFR_BLOCK_DATA       *RequestBlockArray,\r
+  IN OUT IFR_VARSTORAGE_DATA  *VarStorageData,\r
+  OUT    IFR_DEFAULT_DATA     *DefaultIdArray\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        IfrOffset;\r
+  UINTN                        PackageOffset;\r
+  EFI_IFR_VARSTORE             *IfrVarStore;\r
+  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStore;\r
+  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStoreTmp;\r
+  EFI_IFR_OP_HEADER            *IfrOpHdr;\r
+  EFI_IFR_ONE_OF               *IfrOneOf;\r
+  EFI_IFR_REF4                 *IfrRef;\r
+  EFI_IFR_ONE_OF_OPTION        *IfrOneOfOption;\r
+  EFI_IFR_DEFAULT              *IfrDefault;\r
+  EFI_IFR_ORDERED_LIST         *IfrOrderedList;\r
+  EFI_IFR_CHECKBOX             *IfrCheckBox;\r
+  EFI_IFR_PASSWORD             *IfrPassword;\r
+  EFI_IFR_STRING               *IfrString;\r
+  EFI_IFR_DATE                 *IfrDate;\r
+  EFI_IFR_TIME                 *IfrTime;\r
+  IFR_DEFAULT_DATA             DefaultData;\r
+  IFR_DEFAULT_DATA             *DefaultDataPtr;\r
+  IFR_BLOCK_DATA               *BlockData;\r
+  CHAR16                       *VarStoreName;\r
+  UINTN                        NameSize;\r
+  UINTN                        NvDefaultStoreSize;\r
+  UINT16                       VarWidth;\r
+  UINT16                       VarDefaultId;\r
+  BOOLEAN                      FirstOneOfOption;\r
+  BOOLEAN                      FirstOrderedList;\r
+  LIST_ENTRY                   *LinkData;\r
+  LIST_ENTRY                   *LinkDefault;\r
+  EFI_IFR_VARSTORE_NAME_VALUE  *IfrNameValueVarStore;\r
+  EFI_HII_PACKAGE_HEADER       *PackageHeader;\r
+  EFI_VARSTORE_ID              VarStoreId;\r
+  UINT16                       SmallestDefaultId;\r
+  BOOLEAN                      SmallestIdFromFlag;\r
+  BOOLEAN                      FromOtherDefaultOpcode;\r
+  BOOLEAN                      QuestionReferBitField;\r
+\r
+  Status           = EFI_SUCCESS;\r
+  BlockData        = NULL;\r
+  DefaultDataPtr   = NULL;\r
+  FirstOneOfOption = FALSE;\r
+  VarStoreId       = 0;\r
+  FirstOrderedList = FALSE;\r
+  VarStoreName     = NULL;\r
+  ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));\r
+  SmallestDefaultId      = 0xFFFF;\r
+  FromOtherDefaultOpcode = FALSE;\r
+  QuestionReferBitField  = FALSE;\r
+  IfrEfiVarStoreTmp      = NULL;\r
+\r
+  //\r
+  // Go through the form package to parse OpCode one by one.\r
+  //\r
+  PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *)Package;\r
+  IfrOffset     = PackageOffset;\r
+  while (IfrOffset < PackageLength) {\r
+    //\r
+    // More than one form package found.\r
+    //\r
+    if (PackageOffset >= PackageHeader->Length) {\r
+      //\r
+      // Already found varstore for this request, break;\r
+      //\r
+      if (VarStoreId != 0) {\r
+        VarStoreId = 0;\r
+      }\r
+\r
+      //\r
+      // Get next package header info.\r
+      //\r
+      IfrOffset    += sizeof (EFI_HII_PACKAGE_HEADER);\r
+      PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+      PackageHeader = (EFI_HII_PACKAGE_HEADER *)(Package + IfrOffset);\r
+    }\r
+\r
+    IfrOpHdr = (EFI_IFR_OP_HEADER *)(Package + IfrOffset);\r
+    switch (IfrOpHdr->OpCode) {\r
+      case EFI_IFR_VARSTORE_OP:\r
+        //\r
+        // VarStore is found. Don't need to search any more.\r
+        //\r
+        if (VarStoreId != 0) {\r
+          break;\r
+        }\r
+\r
+        IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;\r
+\r
+        NameSize     = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);\r
+        VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+        if (VarStoreName == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+\r
+        AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);\r
+\r
+        if (IsThisVarstore ((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+          //\r
+          // Find the matched VarStore\r
+          //\r
+          CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrVarStore->Guid);\r
+          VarStorageData->Size = IfrVarStore->Size;\r
+          VarStorageData->Name = VarStoreName;\r
+          VarStorageData->Type = EFI_HII_VARSTORE_BUFFER;\r
+          VarStoreId           = IfrVarStore->VarStoreId;\r
+        } else {\r
+          FreePool (VarStoreName);\r
+          VarStoreName = NULL;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_VARSTORE_EFI_OP:\r
+        //\r
+        // VarStore is found. Don't need to search any more.\r
+        //\r
+        if (VarStoreId != 0) {\r
+          break;\r
+        }\r
+\r
+        IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;\r
+\r
+        //\r
+        // If the length is small than the structure, this is from old efi\r
+        // varstore definition. Old efi varstore get config directly from\r
+        // GetVariable function.\r
+        //\r
+        if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+          break;\r
+        }\r
+\r
+        NameSize     = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);\r
+        VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+        if (VarStoreName == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+\r
+        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);\r
+        if (IfrEfiVarStoreTmp != NULL) {\r
+          FreePool (IfrEfiVarStoreTmp);\r
+        }\r
+\r
+        IfrEfiVarStoreTmp = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));\r
+        if (IfrEfiVarStoreTmp == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+\r
+        CopyMem (IfrEfiVarStoreTmp, IfrEfiVarStore, IfrEfiVarStore->Header.Length);\r
+        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *)&(IfrEfiVarStoreTmp->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+\r
+        if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+          //\r
+          // Find the matched VarStore\r
+          //\r
+          CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrEfiVarStore->Guid);\r
+          VarStorageData->Size = IfrEfiVarStore->Size;\r
+          VarStorageData->Name = VarStoreName;\r
+          VarStorageData->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;\r
+          VarStoreId           = IfrEfiVarStore->VarStoreId;\r
+        } else {\r
+          FreePool (VarStoreName);\r
+          VarStoreName = NULL;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
+        //\r
+        // VarStore is found. Don't need to search any more.\r
+        //\r
+        if (VarStoreId != 0) {\r
+          break;\r
+        }\r
+\r
+        IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;\r
+\r
+        if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {\r
+          //\r
+          // Find the matched VarStore\r
+          //\r
+          CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrNameValueVarStore->Guid);\r
+          VarStorageData->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+          VarStoreId           = IfrNameValueVarStore->VarStoreId;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_DEFAULTSTORE_OP:\r
+        //\r
+        // Add new the map between default id and default name.\r
+        //\r
+        DefaultDataPtr = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+        if (DefaultDataPtr == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+\r
+        DefaultDataPtr->DefaultId = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;\r
+        InsertTailList (&DefaultIdArray->Entry, &DefaultDataPtr->Entry);\r
+        DefaultDataPtr = NULL;\r
+        break;\r
+\r
+      case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
+        //\r
+        // No matched varstore is found and directly return.\r
+        //\r
+        if ( VarStoreId == 0) {\r
+          Status = EFI_SUCCESS;\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_REF_OP:\r
+        //\r
+        // Ref question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if ( VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrRef = (EFI_IFR_REF4 *)IfrOpHdr;\r
+        if (IfrRef->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        VarWidth = (UINT16)(sizeof (EFI_HII_REF));\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_ONE_OF_OP:\r
+      case EFI_IFR_NUMERIC_OP:\r
+        //\r
+        // Numeric and OneOf has the same opcode structure.\r
+        //\r
+\r
+        //\r
+        // Numeric and OneOf question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpHdr;\r
+        if (IfrOneOf->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        if (QuestionReferBitField) {\r
+          VarWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+        } else {\r
+          VarWidth = (UINT16)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+        }\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // when go to there,BlockData can't be NULLL.\r
+        //\r
+        ASSERT (BlockData != NULL);\r
+\r
+        if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {\r
+          //\r
+          // Set this flag to TRUE for the first oneof option.\r
+          //\r
+          FirstOneOfOption = TRUE;\r
+        } else if (IfrOpHdr->OpCode == EFI_IFR_NUMERIC_OP) {\r
+          //\r
+          // Numeric minimum value will be used as default value when no default is specified.\r
+          //\r
+          DefaultData.Type = DefaultValueFromDefault;\r
+          if (QuestionReferBitField) {\r
+            //\r
+            // Since default value in bit field was stored as UINT32 type.\r
+            //\r
+            CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+          } else {\r
+            switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+              case EFI_IFR_NUMERIC_SIZE_1:\r
+                DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
+                break;\r
+\r
+              case EFI_IFR_NUMERIC_SIZE_2:\r
+                CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
+                break;\r
+\r
+              case EFI_IFR_NUMERIC_SIZE_4:\r
+                CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+                break;\r
+\r
+              case EFI_IFR_NUMERIC_SIZE_8:\r
+                CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));\r
+                break;\r
+\r
+              default:\r
+                Status = EFI_INVALID_PARAMETER;\r
+                goto Done;\r
+            }\r
+          }\r
+\r
+          //\r
+          // Set default value base on the DefaultId list get from IFR data.\r
+          //\r
+          NvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);\r
+          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+            DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+            if (NvDefaultStoreSize > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
+              FindQuestionDefaultSetting (DefaultData.DefaultId, IfrEfiVarStoreTmp, &(IfrOneOf->Question), &DefaultData.Value, VarWidth, QuestionReferBitField);\r
+            }\r
+\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+          }\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_ORDERED_LIST_OP:\r
+        //\r
+        // offset by question header\r
+        // width by EFI_IFR_ORDERED_LIST MaxContainers * OneofOption Type\r
+        //\r
+\r
+        FirstOrderedList = TRUE;\r
+        //\r
+        // OrderedList question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpHdr;\r
+        if (IfrOrderedList->Question.VarStoreId != VarStoreId) {\r
+          BlockData = NULL;\r
+          break;\r
+        }\r
+\r
+        VarWidth = IfrOrderedList->MaxContainers;\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_CHECKBOX_OP:\r
+        //\r
+        // EFI_IFR_DEFAULT_OP\r
+        // offset by question header\r
+        // width is 1 sizeof (BOOLEAN)\r
+        // default id by CheckBox Flags if CheckBox flags (Default or Mau) is set, the default value is 1 to be set.\r
+        // value by DefaultOption\r
+        // default id by DeaultOption DefaultId can override CheckBox Flags and Default value.\r
+        //\r
+\r
+        //\r
+        // CheckBox question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr;\r
+        if (IfrCheckBox->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        VarWidth = (UINT16)sizeof (BOOLEAN);\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        if (QuestionReferBitField) {\r
+          VarWidth = 1;\r
+        }\r
+\r
+        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // when go to there,BlockData can't be NULLL.\r
+        //\r
+        ASSERT (BlockData != NULL);\r
+\r
+        SmallestIdFromFlag = FALSE;\r
+\r
+        //\r
+        // Add default value for standard ID by CheckBox Flag\r
+        //\r
+        VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData.DefaultId = VarDefaultId;\r
+        if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {\r
+          //\r
+          // When flag is set, default value is TRUE.\r
+          //\r
+          DefaultData.Type = DefaultValueFromFlag;\r
+          if (QuestionReferBitField) {\r
+            DefaultData.Value.u32 = TRUE;\r
+          } else {\r
+            DefaultData.Value.b = TRUE;\r
+          }\r
+\r
+          InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+          if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+            //\r
+            // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+            //\r
+            SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+            SmallestIdFromFlag = TRUE;\r
+          }\r
+        }\r
+\r
+        //\r
+        // Add default value for Manufacture ID by CheckBox Flag\r
+        //\r
+        VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData.DefaultId = VarDefaultId;\r
+        if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {\r
+          //\r
+          // When flag is set, default value is TRUE.\r
+          //\r
+          DefaultData.Type = DefaultValueFromFlag;\r
+          if (QuestionReferBitField) {\r
+            DefaultData.Value.u32 = TRUE;\r
+          } else {\r
+            DefaultData.Value.b = TRUE;\r
+          }\r
+\r
+          InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+          if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+            //\r
+            // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+            //\r
+            SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+            SmallestIdFromFlag = TRUE;\r
+          }\r
+        }\r
+\r
+        if (SmallestIdFromFlag) {\r
+          //\r
+          // When smallest default Id is given by the  flag of CheckBox, set default value with TRUE for other default Id in the DefaultId list.\r
+          //\r
+          DefaultData.Type = DefaultValueFromOtherDefault;\r
+          if (QuestionReferBitField) {\r
+            DefaultData.Value.u32 = TRUE;\r
+          } else {\r
+            DefaultData.Value.b = TRUE;\r
+          }\r
+\r
+          //\r
+          // Set default value for all the default id in the DefaultId list.\r
+          //\r
+          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+            DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+          }\r
+        } else {\r
+          //\r
+          // When flag is not set, default value is FASLE.\r
+          //\r
+          DefaultData.Type = DefaultValueFromDefault;\r
+          if (QuestionReferBitField) {\r
+            DefaultData.Value.u32 = FALSE;\r
+          } else {\r
+            DefaultData.Value.b = FALSE;\r
+          }\r
+\r
+          //\r
+          // Set default value for all the default id in the DefaultId list.\r
+          //\r
+          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+            DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+          }\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_DATE_OP:\r
+        //\r
+        // offset by question header\r
+        // width MaxSize * sizeof (CHAR16)\r
+        // no default value, only block array\r
+        //\r
+\r
+        //\r
+        // Date question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrDate = (EFI_IFR_DATE *)IfrOpHdr;\r
+        if (IfrDate->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        VarWidth = (UINT16)sizeof (EFI_HII_DATE);\r
+        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_TIME_OP:\r
+        //\r
+        // offset by question header\r
+        // width MaxSize * sizeof (CHAR16)\r
+        // no default value, only block array\r
+        //\r
+\r
+        //\r
+        // Time question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrTime = (EFI_IFR_TIME *)IfrOpHdr;\r
+        if (IfrTime->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        VarWidth = (UINT16)sizeof (EFI_HII_TIME);\r
+        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_STRING_OP:\r
+        //\r
+        // offset by question header\r
+        // width MaxSize * sizeof (CHAR16)\r
+        // no default value, only block array\r
+        //\r
+\r
+        //\r
+        // String question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrString = (EFI_IFR_STRING *)IfrOpHdr;\r
+        if (IfrString->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        VarWidth = (UINT16)(IfrString->MaxSize * sizeof (UINT16));\r
+        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_PASSWORD_OP:\r
+        //\r
+        // offset by question header\r
+        // width MaxSize * sizeof (CHAR16)\r
+        // no default value, only block array\r
+        //\r
+\r
+        //\r
+        // Password question is not in IFR Form. This IFR form is not valid.\r
+        //\r
+        if (VarStoreId == 0) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // Check whether this question is for the requested varstore.\r
+        //\r
+        IfrPassword = (EFI_IFR_PASSWORD *)IfrOpHdr;\r
+        if (IfrPassword->Question.VarStoreId != VarStoreId) {\r
+          break;\r
+        }\r
+\r
+        //\r
+        // The BlockData may allocate by other opcode,need to clean.\r
+        //\r
+        if (BlockData != NULL) {\r
+          BlockData = NULL;\r
+        }\r
+\r
+        VarWidth = (UINT16)(IfrPassword->MaxSize * sizeof (UINT16));\r
+        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+        if (EFI_ERROR (Status)) {\r
+          if (Status == EFI_NOT_FOUND) {\r
+            //\r
+            // The opcode is not required,exit and parse other opcode.\r
+            //\r
+            break;\r
+          }\r
+\r
+          goto Done;\r
+        }\r
+\r
+        //\r
+        // No default value for string.\r
+        //\r
+        BlockData = NULL;\r
+        break;\r
+\r
+      case EFI_IFR_ONE_OF_OPTION_OP:\r
+        //\r
+        // No matched block data is ignored.\r
+        //\r
+        if ((BlockData == NULL) || (BlockData->Scope == 0)) {\r
+          break;\r
+        }\r
+\r
+        IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;\r
+        if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+          if (!FirstOrderedList) {\r
+            break;\r
+          }\r
+\r
+          //\r
+          // Get ordered list option data type.\r
+          //\r
+          if ((IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrOneOfOption->Type == EFI_IFR_TYPE_BOOLEAN)) {\r
+            VarWidth = 1;\r
+          } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_16) {\r
+            VarWidth = 2;\r
+          } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_32) {\r
+            VarWidth = 4;\r
+          } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_64) {\r
+            VarWidth = 8;\r
+          } else {\r
+            //\r
+            // Invalid ordered list option data type.\r
+            //\r
+            Status = EFI_INVALID_PARAMETER;\r
+            if (BlockData->Name != NULL) {\r
+              FreePool (BlockData->Name);\r
+            }\r
+\r
+            FreePool (BlockData);\r
+            goto Done;\r
+          }\r
+\r
+          //\r
+          // Calculate Ordered list QuestionId width.\r
+          //\r
+          BlockData->Width = (UINT16)(BlockData->Width * VarWidth);\r
+          //\r
+          // Check whether this question is in requested block array.\r
+          //\r
+          if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, (BOOLEAN)(BlockData->Name != NULL), HiiHandle)) {\r
+            //\r
+            // This question is not in the requested string. Skip it.\r
+            //\r
+            if (BlockData->Name != NULL) {\r
+              FreePool (BlockData->Name);\r
+            }\r
+\r
+            FreePool (BlockData);\r
+            BlockData = NULL;\r
+            break;\r
+          }\r
+\r
+          //\r
+          // Check this var question is in the var storage\r
+          //\r
+          if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {\r
+            Status = EFI_INVALID_PARAMETER;\r
+            FreePool (BlockData);\r
+            goto Done;\r
+          }\r
+\r
+          //\r
+          // Add Block Data into VarStorageData BlockEntry\r
+          //\r
+          InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+\r
+          FirstOrderedList = FALSE;\r
+\r
+          break;\r
+        }\r
+\r
+        //\r
+        // 1. Set default value for OneOf option when flag field has default attribute.\r
+        //    And set the default value with the smallest default id for other default id in the DefaultId list.\r
+        //\r
+        if (((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) ||\r
+            ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG))\r
+        {\r
+          //\r
+          // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.\r
+          // The first oneof option value will be used as default value when no default value is specified.\r
+          //\r
+          FirstOneOfOption = FALSE;\r
+\r
+          SmallestIdFromFlag = FALSE;\r
+\r
+          // Prepare new DefaultValue\r
+          //\r
+          DefaultData.Type = DefaultValueFromFlag;\r
+          CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+          if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {\r
+            DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+            if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+              //\r
+              // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+              //\r
+              SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+              SmallestIdFromFlag = TRUE;\r
+            }\r
+          }\r
+\r
+          if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {\r
+            DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+            if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+              //\r
+              // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+              //\r
+              SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+              SmallestIdFromFlag = TRUE;\r
+            }\r
+          }\r
+\r
+          if (SmallestIdFromFlag) {\r
+            //\r
+            // When smallest default Id is given by the flag of oneofOption, set this option value for other default Id in the DefaultId list.\r
+            //\r
+            DefaultData.Type = DefaultValueFromOtherDefault;\r
+            //\r
+            // Set default value for other default id in the DefaultId list.\r
+            //\r
+            for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+              DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+              DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+              InsertDefaultValue (BlockData, &DefaultData);\r
+            }\r
+          }\r
+        }\r
+\r
+        //\r
+        // 2. Set as the default value when this is the first option.\r
+        // The first oneof option value will be used as default value when no default value is specified.\r
+        //\r
+        if (FirstOneOfOption) {\r
+          // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.\r
+          FirstOneOfOption = FALSE;\r
+\r
+          //\r
+          // Prepare new DefaultValue\r
+          //\r
+          DefaultData.Type = DefaultValueFromDefault;\r
+          CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+            DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+          }\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_DEFAULT_OP:\r
+        //\r
+        // Update Current BlockData to the default value.\r
+        //\r
+        if ((BlockData == NULL) || (BlockData->Scope == 0)) {\r
+          //\r
+          // No matched block data is ignored.\r
+          //\r
+          break;\r
+        }\r
+\r
+        //\r
+        // Get the DefaultId\r
+        //\r
+        IfrDefault   = (EFI_IFR_DEFAULT *)IfrOpHdr;\r
+        VarDefaultId = IfrDefault->DefaultId;\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData.Type      = DefaultValueFromOpcode;\r
+        DefaultData.DefaultId = VarDefaultId;\r
+        if (QuestionReferBitField) {\r
+          CopyMem (&DefaultData.Value.u32, &IfrDefault->Value.u32, sizeof (UINT32));\r
+        } else {\r
+          CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+        }\r
+\r
+        // If the value field is expression, set the cleaned flag.\r
+        if (IfrDefault->Type ==  EFI_IFR_TYPE_OTHER) {\r
+          DefaultData.Cleaned = TRUE;\r
+        }\r
+\r
+        //\r
+        // Add DefaultValue into current BlockData\r
+        //\r
+        InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+        //\r
+        // Set default value for other default id in the DefaultId list.\r
+        // when SmallestDefaultId == VarDefaultId means there are two defaults with same default Id.\r
+        // If the two defaults are both from default opcode, use the first default as the default value of other default Id.\r
+        // If one from flag and the other form default opcode, use the default opcode value as the default value of other default Id.\r
+        //\r
+        if ((SmallestDefaultId > VarDefaultId) || ((SmallestDefaultId == VarDefaultId) && !FromOtherDefaultOpcode)) {\r
+          FromOtherDefaultOpcode = TRUE;\r
+          SmallestDefaultId      = VarDefaultId;\r
+          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+            DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+            if (DefaultDataPtr->DefaultId != DefaultData.DefaultId) {\r
+              DefaultData.Type      = DefaultValueFromOtherDefault;\r
+              DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+              InsertDefaultValue (BlockData, &DefaultData);\r
+            }\r
+          }\r
+        }\r
+\r
+        //\r
+        // After insert the default value, reset the cleaned value for next\r
+        // time used. If not set here, need to set the value before every time.\r
+        // use it.\r
+        //\r
+        DefaultData.Cleaned = FALSE;\r
+        break;\r
+\r
+      case EFI_IFR_END_OP:\r
+        //\r
+        // End Opcode is for Var question.\r
+        //\r
+        QuestionReferBitField = FALSE;\r
+        if (BlockData != NULL) {\r
+          if (BlockData->Scope > 0) {\r
+            BlockData->Scope--;\r
+          }\r
+\r
+          if (BlockData->Scope == 0) {\r
+            BlockData = NULL;\r
+            //\r
+            // when finishing parsing a question, clean the SmallestDefaultId and GetDefaultFromDefaultOpcode.\r
+            //\r
+            SmallestDefaultId      = 0xFFFF;\r
+            FromOtherDefaultOpcode = FALSE;\r
+          }\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_IFR_GUID_OP:\r
+        if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+          QuestionReferBitField = TRUE;\r
+        }\r
+\r
+        break;\r
+\r
+      default:\r
+        if (BlockData != NULL) {\r
+          if (BlockData->Scope > 0) {\r
+            BlockData->Scope = (UINT8)(BlockData->Scope + IfrOpHdr->Scope);\r
+          }\r
+\r
+          if (BlockData->Scope == 0) {\r
+            BlockData = NULL;\r
+          }\r
+        }\r
+\r
+        break;\r
+    }\r
+\r
+    IfrOffset     += IfrOpHdr->Length;\r
+    PackageOffset += IfrOpHdr->Length;\r
+  }\r
+\r
+  //\r
+  // if Status == EFI_NOT_FOUND, just means the opcode is not required,not contain any error,\r
+  // so set the Status to EFI_SUCCESS.\r
+  //\r
+  if (Status == EFI_NOT_FOUND) {\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+Done:\r
+  for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+    BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+    for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; ) {\r
+      DefaultDataPtr = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+      LinkDefault    = LinkDefault->ForwardLink;\r
+      if (DefaultDataPtr->Cleaned == TRUE) {\r
+        RemoveEntryList (&DefaultDataPtr->Entry);\r
+        FreePool (DefaultDataPtr);\r
+      }\r
+    }\r
+  }\r
+\r
+  if (IfrEfiVarStoreTmp != NULL) {\r
+    FreePool (IfrEfiVarStoreTmp);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  parse the configrequest string, get the elements.\r
+\r
+  @param      ConfigRequest         The input configrequest string.\r
+  @param      Progress              Return the progress data.\r
+\r
+  @retval     Block data pointer.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetBlockElement (\r
+  IN  EFI_STRING  ConfigRequest,\r
+  OUT EFI_STRING  *Progress\r
+  )\r
+{\r
+  EFI_STRING      StringPtr;\r
+  IFR_BLOCK_DATA  *BlockData;\r
+  IFR_BLOCK_DATA  *RequestBlockArray;\r
+  EFI_STATUS      Status;\r
+  UINT8           *TmpBuffer;\r
+  UINT16          Offset;\r
+  UINT16          Width;\r
+  LIST_ENTRY      *Link;\r
+  IFR_BLOCK_DATA  *NextBlockData;\r
+  UINTN           Length;\r
+\r
+  TmpBuffer = NULL;\r
+\r
+  //\r
+  // Init RequestBlockArray\r
+  //\r
+  RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (RequestBlockArray == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  InitializeListHead (&RequestBlockArray->Entry);\r
+\r
+  //\r
+  // Get the request Block array from the request string\r
+  // Offset and Width\r
+  //\r
+\r
+  //\r
+  // Parse each <RequestElement> if exists\r
+  // Only <BlockName> format is supported by this help function.\r
+  // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
+  //\r
+  StringPtr = ConfigRequest;\r
+  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
+    //\r
+    // Skip the OFFSET string\r
+    //\r
+    *Progress  = StringPtr;\r
+    StringPtr += StrLen (L"&OFFSET=");\r
+    //\r
+    // Get Offset\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    Offset = 0;\r
+    CopyMem (\r
+      &Offset,\r
+      TmpBuffer,\r
+      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+      );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      goto Done;\r
+    }\r
+\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    Width = 0;\r
+    CopyMem (\r
+      &Width,\r
+      TmpBuffer,\r
+      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+      );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if ((*StringPtr != 0) && (*StringPtr != L'&')) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Set Block Data\r
+    //\r
+    BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+    if (BlockData == NULL) {\r
+      goto Done;\r
+    }\r
+\r
+    BlockData->Offset = Offset;\r
+    BlockData->Width  = Width;\r
+    InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
+\r
+    //\r
+    // Skip &VALUE string if &VALUE does exists.\r
+    //\r
+    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) == 0) {\r
+      StringPtr += StrLen (L"&VALUE=");\r
+\r
+      //\r
+      // Get Value\r
+      //\r
+      Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      FreePool (TmpBuffer);\r
+      StringPtr += Length;\r
+      if ((*StringPtr != 0) && (*StringPtr != L'&')) {\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    //\r
+    // If '\0', parsing is finished.\r
+    //\r
+    if (*StringPtr == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Merge the requested block data.\r
+  //\r
+  Link = RequestBlockArray->Entry.ForwardLink;\r
+  while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {\r
+    BlockData     = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
+    if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
+      if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
+        BlockData->Width = (UINT16)(NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);\r
+      }\r
+\r
+      RemoveEntryList (Link->ForwardLink);\r
+      FreePool (NextBlockData);\r
+      continue;\r
+    }\r
+\r
+    Link = Link->ForwardLink;\r
+  }\r
+\r
+  return RequestBlockArray;\r
+\r
+Done:\r
+  if (RequestBlockArray != NULL) {\r
+    //\r
+    // Free Link Array RequestBlockArray\r
+    //\r
+    while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      FreePool (BlockData);\r
+    }\r
+\r
+    FreePool (RequestBlockArray);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  parse the configrequest string, get the elements.\r
+\r
+  @param      ConfigRequest         The input config request string.\r
+  @param      Progress              Return the progress data.\r
+\r
+  @retval     return data block array.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetNameElement (\r
+  IN  EFI_STRING  ConfigRequest,\r
+  OUT EFI_STRING  *Progress\r
+  )\r
+{\r
+  EFI_STRING      StringPtr;\r
+  EFI_STRING      NextTag;\r
+  IFR_BLOCK_DATA  *BlockData;\r
+  IFR_BLOCK_DATA  *RequestBlockArray;\r
+  BOOLEAN         HasValue;\r
+\r
+  StringPtr = ConfigRequest;\r
+\r
+  //\r
+  // Init RequestBlockArray\r
+  //\r
+  RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (RequestBlockArray == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  InitializeListHead (&RequestBlockArray->Entry);\r
+\r
+  //\r
+  // Get the request Block array from the request string\r
+  //\r
+\r
+  //\r
+  // Parse each <RequestElement> if exists\r
+  // Only <BlockName> format is supported by this help function.\r
+  // <BlockName> ::= &'Name***=***\r
+  //\r
+  while (StringPtr != NULL && *StringPtr == L'&') {\r
+    *Progress = StringPtr;\r
+    //\r
+    // Skip the L"&" string\r
+    //\r
+    StringPtr += 1;\r
+\r
+    HasValue = FALSE;\r
+    if ((NextTag = StrStr (StringPtr, L"=")) != NULL) {\r
+      *NextTag = L'\0';\r
+      HasValue = TRUE;\r
+    } else if ((NextTag = StrStr (StringPtr, L"&")) != NULL) {\r
+      *NextTag = L'\0';\r
+    }\r
+\r
+    //\r
+    // Set Block Data\r
+    //\r
+    BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+    if (BlockData == NULL) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Get Name\r
+    //\r
+    BlockData->Name = AllocateCopyPool (StrSize (StringPtr), StringPtr);\r
+    InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
+\r
+    if (HasValue) {\r
+      //\r
+      // If has value, skip the value.\r
+      //\r
+      StringPtr = NextTag + 1;\r
+      *NextTag  = L'=';\r
+      StringPtr = StrStr (StringPtr, L"&");\r
+    } else if (NextTag != NULL) {\r
+      //\r
+      // restore the '&' text.\r
+      //\r
+      StringPtr = NextTag;\r
+      *NextTag  = L'&';\r
+    }\r
+  }\r
+\r
+  return RequestBlockArray;\r
+\r
+Done:\r
+  if (RequestBlockArray != NULL) {\r
+    //\r
+    // Free Link Array RequestBlockArray\r
+    //\r
+    while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      if (BlockData->Name != NULL) {\r
+        FreePool (BlockData->Name);\r
+      }\r
+\r
+      FreePool (BlockData);\r
+    }\r
+\r
+    FreePool (RequestBlockArray);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Generate ConfigRequest string base on the varstore info.\r
+\r
+  @param      ConfigHdr             The config header for this varstore.\r
+  @param      VarStorageData        The varstore info.\r
+  @param      Status                Return Status.\r
+  @param      ConfigRequest         The ConfigRequest info may be return.\r
+\r
+  @retval     TRUE                  Need to continue\r
+  @retval     Others                NO need to continue or error occur.\r
+**/\r
+BOOLEAN\r
+GenerateConfigRequest (\r
+  IN  CHAR16               *ConfigHdr,\r
+  IN  IFR_VARSTORAGE_DATA  *VarStorageData,\r
+  OUT EFI_STATUS           *Status,\r
+  IN OUT EFI_STRING        *ConfigRequest\r
+  )\r
+{\r
+  BOOLEAN         DataExist;\r
+  UINTN           Length;\r
+  LIST_ENTRY      *Link;\r
+  CHAR16          *FullConfigRequest;\r
+  CHAR16          *StringPtr;\r
+  IFR_BLOCK_DATA  *BlockData;\r
+\r
+  //\r
+  // Append VarStorageData BlockEntry into *Request string\r
+  // Now support only one varstore in a form package.\r
+  //\r
+\r
+  //\r
+  // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package\r
+  // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig\r
+  //\r
+\r
+  //\r
+  // Compute the length of the entire request starting with <ConfigHdr> and a\r
+  // Null-terminator\r
+  //\r
+  DataExist = FALSE;\r
+  Length    = StrLen (ConfigHdr) + 1;\r
+\r
+  for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
+    DataExist = TRUE;\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+      //\r
+      // Add <BlockName> length for each Name\r
+      //\r
+      // <BlockName> ::= &Name1&Name2&...\r
+      //                 |1| StrLen(Name1)\r
+      //\r
+      Length = Length + (1 + StrLen (BlockData->Name));\r
+    } else {\r
+      //\r
+      // Add <BlockName> length for each Offset/Width pair\r
+      //\r
+      // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
+      //                 |  8   | 4 |   7  | 4 |\r
+      //\r
+      Length = Length + (8 + 4 + 7 + 4);\r
+    }\r
+  }\r
+\r
+  //\r
+  // No any request block data is found. The request string can't be constructed.\r
+  //\r
+  if (!DataExist) {\r
+    *Status = EFI_SUCCESS;\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Allocate buffer for the entire <ConfigRequest>\r
+  //\r
+  FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (FullConfigRequest == NULL) {\r
+    *Status = EFI_OUT_OF_RESOURCES;\r
+    return FALSE;\r
+  }\r
+\r
+  StringPtr = FullConfigRequest;\r
+\r
+  //\r
+  // Start with <ConfigHdr>\r
+  //\r
+  StrCpyS (StringPtr, Length, ConfigHdr);\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  //\r
+  // Loop through all the Offset/Width pairs and append them to ConfigRequest\r
+  //\r
+  for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+      //\r
+      // Append &Name1\0\r
+      //\r
+      UnicodeSPrint (\r
+        StringPtr,\r
+        (1 + StrLen (BlockData->Name) + 1) * sizeof (CHAR16),\r
+        L"&%s",\r
+        BlockData->Name\r
+        );\r
+    } else {\r
+      //\r
+      // Append &OFFSET=XXXX&WIDTH=YYYY\0\r
+      //\r
+      UnicodeSPrint (\r
+        StringPtr,\r
+        (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16),\r
+        L"&OFFSET=%04X&WIDTH=%04X",\r
+        BlockData->Offset,\r
+        BlockData->Width\r
+        );\r
+    }\r
+\r
+    StringPtr += StrLen (StringPtr);\r
+  }\r
+\r
+  //\r
+  // Set to the got full request string.\r
+  //\r
+  HiiToLower (FullConfigRequest);\r
+\r
+  if (*ConfigRequest != NULL) {\r
+    FreePool (*ConfigRequest);\r
+  }\r
+\r
+  *ConfigRequest = FullConfigRequest;\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Generate ConfigRequest Header base on the varstore info.\r
+\r
+  @param      VarStorageData        The varstore info.\r
+  @param      DevicePath            Device path for this varstore.\r
+  @param      ConfigHdr             The config header for this varstore.\r
+\r
+  @retval     EFI_SUCCESS           Generate the header success.\r
+  @retval     EFI_OUT_OF_RESOURCES  Allocate buffer fail.\r
+**/\r
+EFI_STATUS\r
+GenerateHdr (\r
+  IN   IFR_VARSTORAGE_DATA       *VarStorageData,\r
+  IN   EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
+  OUT  EFI_STRING                *ConfigHdr\r
+  )\r
+{\r
+  EFI_STRING  GuidStr;\r
+  EFI_STRING  NameStr;\r
+  EFI_STRING  PathStr;\r
+  UINTN       Length;\r
+  EFI_STATUS  Status;\r
+\r
+  Status  = EFI_SUCCESS;\r
+  NameStr = NULL;\r
+  GuidStr = NULL;\r
+  PathStr = NULL;\r
+\r
+  //\r
+  // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle\r
+  //\r
+  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)&VarStorageData->Guid, 1, &GuidStr);\r
+  if (VarStorageData->Name != NULL) {\r
+    GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *)VarStorageData->Name, 2, &NameStr);\r
+  } else {\r
+    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
+  }\r
+\r
+  GenerateSubStr (\r
+    L"PATH=",\r
+    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)DevicePath),\r
+    (VOID *)DevicePath,\r
+    1,\r
+    &PathStr\r
+    );\r
+  Length = StrLen (GuidStr) + StrLen (NameStr) + StrLen (PathStr) + 1;\r
+  if (VarStorageData->Name == NULL) {\r
+    Length += 1;\r
+  }\r
+\r
+  *ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (*ConfigHdr == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  StrCpyS (*ConfigHdr, Length, GuidStr);\r
+  StrCatS (*ConfigHdr, Length, NameStr);\r
+  if (VarStorageData->Name == NULL) {\r
+    StrCatS (*ConfigHdr, Length, L"&");\r
+  }\r
+\r
+  StrCatS (*ConfigHdr, Length, PathStr);\r
+\r
+  //\r
+  // Remove the last character L'&'\r
+  //\r
+  *(*ConfigHdr + StrLen (*ConfigHdr) - 1) = L'\0';\r
+\r
+Done:\r
+  if (GuidStr != NULL) {\r
+    FreePool (GuidStr);\r
+  }\r
+\r
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
+\r
+  if (PathStr != NULL) {\r
+    FreePool (PathStr);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Update the default value in the block data which is used as bit var store.\r
+\r
+  For example:\r
+  A question value saved in a bit fied: bitoffset = 1; bitwidth = 2;default value = 1.\r
+  And corresponding block data info: offset==0; width==1;currently the default value\r
+  is saved as 1.Actually the default value 1 need to be set to bit field 1, so the\r
+  default value of this block data shuold be:2.\r
+\r
+  typedef struct {\r
+    UINT8  Bit1 : 1; //\r
+    UINT8  Bit2 : 2; // Question saved in Bit2,so originalBlock info: offset = 0; width = 1;(byte level) defaul = 1.\r
+                     // (default value record for the bit field)\r
+    ......\r
+  }ExampleData;\r
+\r
+  After function UpdateDefaultValue,the Block info is: offset = 0; width = 1;(byte level) default = 2.\r
+                                                       (default value record for the Block)\r
+\r
+  UpdateDefaultValue function update default value of bit var block based on the bit field info in the block.\r
+\r
+  @param  BlockLink     The Link of the block data.\r
+\r
+**/\r
+VOID\r
+UpdateDefaultValue (\r
+  IN LIST_ENTRY  *BlockLink\r
+  )\r
+{\r
+  LIST_ENTRY        *Link;\r
+  LIST_ENTRY        *ListEntry;\r
+  LIST_ENTRY        *LinkDefault;\r
+  IFR_BLOCK_DATA    *BlockData;\r
+  IFR_DEFAULT_DATA  *DefaultValueData;\r
+  UINTN             StartBit;\r
+  UINTN             EndBit;\r
+  UINT32            BitFieldDefaultValue;\r
+\r
+  for ( Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (!BlockData->IsBitVar) {\r
+      continue;\r
+    }\r
+\r
+    ListEntry = &BlockData->DefaultValueEntry;\r
+    //\r
+    // Update the default value in the block data with all existing default id.\r
+    //\r
+    for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+      //\r
+      // Get the default data, and the value of the default data is for some field in the block.\r
+      // Note: Default value for bit field question is stored as UINT32.\r
+      //\r
+      DefaultValueData     = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+      BitFieldDefaultValue = DefaultValueData->Value.u32;\r
+\r
+      StartBit = BlockData->BitOffset % 8;\r
+      EndBit   = StartBit + BlockData->BitWidth - 1;\r
+\r
+      //\r
+      // Set the bit field default value to related bit filed, then we will got the new default vaule for the block data.\r
+      //\r
+      DefaultValueData->Value.u32 = BitFieldWrite32 (0, StartBit, EndBit, BitFieldDefaultValue);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+Merge the default value in two block datas which have overlap region.\r
+\r
+For bit fields, their related block data may have overlap region, such as:\r
+\r
+typedef struct {\r
+  UINT16  Bit1 : 6;  // Question1 refer Bit1, Block1: offset = 0; width = 1;(byte level) default = 1\r
+  UINT16  Bit2 : 5;  // Question2 refer Bit2, Block2: offset = 0; width = 2;(byte level) default = 5\r
+                     // (default value record for the bit field)\r
+  ......\r
+}ExampleData;\r
+\r
+After function UpdateDefaultValue:\r
+Block1: offset = 0; width = 1;(byte level) default = 1\r
+Block2: offset = 0; width = 2;(byte level) default = 320 (5 * (2 << 6))\r
+(default value record for block)\r
+\r
+After function MergeBlockDefaultValue:\r
+Block1: offset = 0; width = 1;(byte level) default = 65\r
+Block2: offset = 0; width = 2;(byte level) default = 321\r
+(Block1 and Block2 has overlap region, merge the overlap value to Block1 and Blcok2)\r
+\r
+Block1 and Block2 have overlap byte region, but currntly the default value of Block1 only contains\r
+value of Bit1 (low 6 bits),the default value of Block2 only contains the value of Bit2 (middle 5 bits).\r
+\r
+This fuction merge the default value of these two blocks, and make the default value of block1\r
+also contain the value of lower 2 bits of the Bit2. And make the default value of Block2 also\r
+contain the default value of Bit1.\r
+\r
+We can get the total value of the whole block that just cover these two blocks(in this case is:\r
+block: offset =0; width =2;) then the value of block2 is same as block, the value of block1 is\r
+the first byte value of block.\r
+\r
+@param  FirstBlock     Point to the block date whose default value need to be merged.\r
+@param  SecondBlock    Point to the block date whose default value need to be merged.\r
+\r
+**/\r
+VOID\r
+MergeBlockDefaultValue (\r
+  IN OUT IFR_BLOCK_DATA  *FirstBlock,\r
+  IN OUT IFR_BLOCK_DATA  *SecondBlock\r
+  )\r
+{\r
+  LIST_ENTRY        *FirstListEntry;\r
+  LIST_ENTRY        *SecondListEntry;\r
+  LIST_ENTRY        *FirstDefaultLink;\r
+  LIST_ENTRY        *SecondDefaultLink;\r
+  IFR_DEFAULT_DATA  *FirstDefaultValueData;\r
+  IFR_DEFAULT_DATA  *SecondDefaultValueData;\r
+  UINT32            *FirstDefaultValue;\r
+  UINT32            *SecondDefaultValue;\r
+  UINT64            TotalValue;\r
+  UINT64            ShiftedValue;\r
+  UINT16            OffsetShift;\r
+\r
+  FirstListEntry = &FirstBlock->DefaultValueEntry;\r
+  for (FirstDefaultLink = FirstListEntry->ForwardLink; FirstDefaultLink != FirstListEntry; FirstDefaultLink = FirstDefaultLink->ForwardLink) {\r
+    FirstDefaultValueData = BASE_CR (FirstDefaultLink, IFR_DEFAULT_DATA, Entry);\r
+    SecondListEntry       = &SecondBlock->DefaultValueEntry;\r
+    for (SecondDefaultLink = SecondListEntry->ForwardLink; SecondDefaultLink != SecondListEntry; SecondDefaultLink = SecondDefaultLink->ForwardLink) {\r
+      SecondDefaultValueData = BASE_CR (SecondDefaultLink, IFR_DEFAULT_DATA, Entry);\r
+      if (FirstDefaultValueData->DefaultId != SecondDefaultValueData->DefaultId) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Find default value with same default id in the two blocks.\r
+      // Note: Default value for bit field question is stored as UINT32 type.\r
+      //\r
+      FirstDefaultValue  = &FirstDefaultValueData->Value.u32;\r
+      SecondDefaultValue = &SecondDefaultValueData->Value.u32;\r
+      //\r
+      // 1. Get the default value of the whole blcok that can just cover FirstBlock and SecondBlock.\r
+      // 2. Get the default value of FirstBlock and SecondBlock form the value of whole block based\r
+      //    on the offset and width of FirstBlock and SecondBlock.\r
+      //\r
+      if (FirstBlock->Offset > SecondBlock->Offset) {\r
+        OffsetShift         = FirstBlock->Offset - SecondBlock->Offset;\r
+        ShiftedValue        = LShiftU64 ((UINT64)(*FirstDefaultValue), OffsetShift * 8);\r
+        TotalValue          = ShiftedValue | (UINT64)(*SecondDefaultValue);\r
+        *SecondDefaultValue = (UINT32)BitFieldRead64 (TotalValue, 0, SecondBlock->Width * 8 -1);\r
+        *FirstDefaultValue  = (UINT32)BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + FirstBlock->Width *8 -1);\r
+      } else {\r
+        OffsetShift         = SecondBlock->Offset -FirstBlock->Offset;\r
+        ShiftedValue        = LShiftU64 ((UINT64)(*SecondDefaultValue), OffsetShift * 8);\r
+        TotalValue          = ShiftedValue | (UINT64)(*FirstDefaultValue);\r
+        *FirstDefaultValue  = (UINT32)BitFieldRead64 (TotalValue, 0, FirstBlock->Width * 8 -1);\r
+        *SecondDefaultValue = (UINT32)BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + SecondBlock->Width *8 -1);\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+\r
+Update the default value in the block data which used as Bit VarStore\r
+\r
+@param  BlockLink     The Link of the block data.\r
+\r
+**/\r
+VOID\r
+UpdateBlockDataArray (\r
+  IN LIST_ENTRY  *BlockLink\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  LIST_ENTRY      *TempLink;\r
+  IFR_BLOCK_DATA  *BlockData;\r
+  IFR_BLOCK_DATA  *NextBlockData;\r
+\r
+  //\r
+  // 1. Update default value in BitVar block data.\r
+  // Sine some block datas are used as BitVarStore, then the default value recored in the block\r
+  // is for related bit field in the block. so we need to set the default value to the related bit\r
+  // fields in the block data if the block data is used as bit varstore, then the default value of\r
+  // the block will be updated.\r
+  //\r
+  UpdateDefaultValue (BlockLink);\r
+\r
+  //\r
+  // 2.Update default value for overlap BitVar blcok datas.\r
+  // For block datas have overlap region, we need to merge the default value in different blocks.\r
+  //\r
+  for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (!BlockData->IsBitVar) {\r
+      continue;\r
+    }\r
+\r
+    for (TempLink = Link->ForwardLink; TempLink != BlockLink; TempLink = TempLink->ForwardLink) {\r
+      NextBlockData = BASE_CR (TempLink, IFR_BLOCK_DATA, Entry);\r
+      if (!NextBlockData->IsBitVar || (NextBlockData->Offset >= BlockData->Offset + BlockData->Width) || (BlockData->Offset >= NextBlockData->Offset + NextBlockData->Width)) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Find two blocks are used as bit VarStore and have overlap region, so need to merge default value of these two blocks.\r
+      //\r
+      MergeBlockDefaultValue (BlockData, NextBlockData);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Generate ConfigAltResp string base on the varstore info.\r
+\r
+  @param      HiiHandle             Hii Handle for this hii package.\r
+  @param      ConfigHdr             The config header for this varstore.\r
+  @param      VarStorageData        The varstore info.\r
+  @param      DefaultIdArray        The Default id array.\r
+  @param      DefaultAltCfgResp     The DefaultAltCfgResp info may be return.\r
+\r
+  @retval     TRUE                  Need to continue\r
+  @retval     Others                NO need to continue or error occur.\r
+**/\r
+EFI_STATUS\r
+GenerateAltConfigResp (\r
+  IN  EFI_HII_HANDLE       HiiHandle,\r
+  IN  CHAR16               *ConfigHdr,\r
+  IN  IFR_VARSTORAGE_DATA  *VarStorageData,\r
+  IN  IFR_DEFAULT_DATA     *DefaultIdArray,\r
+  IN OUT EFI_STRING        *DefaultAltCfgResp\r
+  )\r
+{\r
+  BOOLEAN           DataExist;\r
+  UINTN             Length;\r
+  LIST_ENTRY        *Link;\r
+  LIST_ENTRY        *LinkData;\r
+  LIST_ENTRY        *LinkDefault;\r
+  LIST_ENTRY        *ListEntry;\r
+  CHAR16            *StringPtr;\r
+  IFR_BLOCK_DATA    *BlockData;\r
+  IFR_DEFAULT_DATA  *DefaultId;\r
+  IFR_DEFAULT_DATA  *DefaultValueData;\r
+  UINTN             Width;\r
+  UINT8             *TmpBuffer;\r
+  CHAR16            *DefaultString;\r
+  UINTN             StrSize;\r
+\r
+  BlockData     = NULL;\r
+  DataExist     = FALSE;\r
+  DefaultString = NULL;\r
+  //\r
+  // Add length for <ConfigHdr> + '\0'\r
+  //\r
+  Length = StrLen (ConfigHdr) + 1;\r
+\r
+  UpdateBlockDataArray (&VarStorageData->BlockEntry);\r
+\r
+  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    //\r
+    // Add length for "&<ConfigHdr>&ALTCFG=XXXX"\r
+    //                |1| StrLen (ConfigHdr) | 8 | 4 |\r
+    //\r
+    Length += (1 + StrLen (ConfigHdr) + 8 + 4);\r
+\r
+    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+      ListEntry = &BlockData->DefaultValueEntry;\r
+      for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+        if (DefaultValueData->DefaultId != DefaultId->DefaultId) {\r
+          continue;\r
+        }\r
+\r
+        if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+          //\r
+          // Add length for "&Name1=zzzzzzzzzzzz"\r
+          //                |1|Name|1|Value|\r
+          //\r
+          Length += (1 + StrLen (BlockData->Name) + 1 + BlockData->Width * 2);\r
+        } else {\r
+          //\r
+          // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"\r
+          //                |    8  | 4 |   7  | 4 |   7  | Width * 2 |\r
+          //\r
+          Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);\r
+        }\r
+\r
+        DataExist = TRUE;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // No default value is found. The default string doesn't exist.\r
+  //\r
+  if (!DataExist) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Allocate buffer for the entire <DefaultAltCfgResp>\r
+  //\r
+  *DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (*DefaultAltCfgResp == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  StringPtr = *DefaultAltCfgResp;\r
+\r
+  //\r
+  // Start with <ConfigHdr>\r
+  //\r
+  StrCpyS (StringPtr, Length, ConfigHdr);\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    //\r
+    // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"\r
+    //                                |1| StrLen (ConfigHdr) | 8 | 4 |\r
+    //\r
+    UnicodeSPrint (\r
+      StringPtr,\r
+      (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),\r
+      L"&%s&ALTCFG=%04X",\r
+      ConfigHdr,\r
+      DefaultId->DefaultId\r
+      );\r
+    StringPtr += StrLen (StringPtr);\r
+\r
+    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+      ListEntry = &BlockData->DefaultValueEntry;\r
+      for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+        if (DefaultValueData->DefaultId != DefaultId->DefaultId) {\r
+          continue;\r
+        }\r
+\r
+        if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+          UnicodeSPrint (\r
+            StringPtr,\r
+            (1 + StrLen (ConfigHdr) + 1) * sizeof (CHAR16),\r
+            L"&%s=",\r
+            BlockData->Name\r
+            );\r
+          StringPtr += StrLen (StringPtr);\r
+        } else {\r
+          //\r
+          // Add <BlockConfig>\r
+          // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
+          //\r
+          UnicodeSPrint (\r
+            StringPtr,\r
+            (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),\r
+            L"&OFFSET=%04X&WIDTH=%04X&VALUE=",\r
+            BlockData->Offset,\r
+            BlockData->Width\r
+            );\r
+          StringPtr += StrLen (StringPtr);\r
+        }\r
+\r
+        Width = BlockData->Width;\r
+        //\r
+        // Convert Value to a hex string in "%x" format\r
+        // NOTE: This is in the opposite byte that GUID and PATH use\r
+        //\r
+        if (BlockData->OpCode == EFI_IFR_STRING_OP) {\r
+          DefaultString = InternalGetString (HiiHandle, DefaultValueData->Value.string);\r
+          TmpBuffer     = AllocateZeroPool (Width);\r
+          ASSERT (TmpBuffer != NULL);\r
+          if (DefaultString != NULL) {\r
+            StrSize = StrLen (DefaultString)* sizeof (CHAR16);\r
+            if (StrSize > Width) {\r
+              StrSize = Width;\r
+            }\r
+\r
+            CopyMem (TmpBuffer, (UINT8 *)DefaultString, StrSize);\r
+          }\r
+        } else {\r
+          TmpBuffer = (UINT8 *)&(DefaultValueData->Value);\r
+        }\r
+\r
+        for ( ; Width > 0 && (TmpBuffer != NULL); Width--) {\r
+          UnicodeValueToStringS (\r
+            StringPtr,\r
+            Length * sizeof (CHAR16) - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp),\r
+            PREFIX_ZERO | RADIX_HEX,\r
+            TmpBuffer[Width - 1],\r
+            2\r
+            );\r
+          StringPtr += StrnLenS (StringPtr, Length - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp) / sizeof (CHAR16));\r
+        }\r
+\r
+        if (DefaultString != NULL) {\r
+          FreePool (DefaultString);\r
+          DefaultString = NULL;\r
+        }\r
+\r
+        if ((BlockData->OpCode == EFI_IFR_STRING_OP) && (TmpBuffer != NULL)) {\r
+          FreePool (TmpBuffer);\r
+          TmpBuffer = NULL;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  HiiToLower (*DefaultAltCfgResp);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function gets the full request string and full default value string by\r
+  parsing IFR data in HII form packages.\r
+\r
+  When Request points to NULL string, the request string and default value string\r
+  for each varstore in form package will return.\r
+\r
+  @param  DataBaseRecord         The DataBaseRecord instance contains the found Hii handle and package.\r
+  @param  DevicePath             Device Path which Hii Config Access Protocol is registered.\r
+  @param  Request                Pointer to a null-terminated Unicode string in\r
+                                 <ConfigRequest> format. When it doesn't contain\r
+                                 any RequestElement, it will be updated to return\r
+                                 the full RequestElement retrieved from IFR data.\r
+                                 If it points to NULL, the request string for the first\r
+                                 varstore in form package will be merged into a\r
+                                 <MultiConfigRequest> format string and return.\r
+  @param  AltCfgResp             Pointer to a null-terminated Unicode string in\r
+                                 <ConfigAltResp> format. When the pointer is to NULL,\r
+                                 the full default value string retrieved from IFR data\r
+                                 will return. When the pinter is to a string, the\r
+                                 full default value string retrieved from IFR data\r
+                                 will be merged into the input string and return.\r
+                                 When Request points to NULL, the default value string\r
+                                 for each varstore in form package will be merged into\r
+                                 a <MultiConfigAltResp> format string and return.\r
+  @param  PointerProgress        Optional parameter, it can be NULL.\r
+                                 When it is not NULL, if Request is NULL, it returns NULL.\r
+                                 On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 & before the first failing name / value pair (or\r
+                                 the beginning of the string if the failure is in\r
+                                 the first name / value pair) if the request was\r
+                                 not successful.\r
+  @retval EFI_SUCCESS            The Results string is set to the full request string.\r
+                                 And AltCfgResp contains all default value string.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory for the return string.\r
+  @retval EFI_NOT_FOUND          The varstore (Guid and Name) in Request string\r
+                                 can't be found in Form package.\r
+  @retval EFI_NOT_FOUND          HiiPackage can't be got on the input HiiHandle.\r
+  @retval EFI_INVALID_PARAMETER  Request points to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetFullStringFromHiiFormPackages (\r
+  IN     HII_DATABASE_RECORD       *DataBaseRecord,\r
+  IN     EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
+  IN OUT EFI_STRING                *Request,\r
+  IN OUT EFI_STRING                *AltCfgResp,\r
+  OUT    EFI_STRING                *PointerProgress OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  UINT8                *HiiFormPackage;\r
+  UINTN                PackageSize;\r
+  IFR_BLOCK_DATA       *RequestBlockArray;\r
+  IFR_BLOCK_DATA       *BlockData;\r
+  IFR_DEFAULT_DATA     *DefaultValueData;\r
+  IFR_DEFAULT_DATA     *DefaultId;\r
+  IFR_DEFAULT_DATA     *DefaultIdArray;\r
+  IFR_VARSTORAGE_DATA  *VarStorageData;\r
+  EFI_STRING           DefaultAltCfgResp;\r
+  EFI_STRING           ConfigHdr;\r
+  EFI_STRING           StringPtr;\r
+  EFI_STRING           Progress;\r
+\r
+  if ((DataBaseRecord == NULL) || (DevicePath == NULL) || (Request == NULL) || (AltCfgResp == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Initialize the local variables.\r
+  //\r
+  RequestBlockArray = NULL;\r
+  DefaultIdArray    = NULL;\r
+  VarStorageData    = NULL;\r
+  DefaultAltCfgResp = NULL;\r
+  ConfigHdr         = NULL;\r
+  HiiFormPackage    = NULL;\r
+  PackageSize       = 0;\r
+  Progress          = *Request;\r
+\r
+  Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // 1. Get the request block array by Request String when Request string contains the block array.\r
+  //\r
+  StringPtr = NULL;\r
+  if (*Request != NULL) {\r
+    StringPtr = *Request;\r
+    //\r
+    // Jump <ConfigHdr>\r
+    //\r
+    if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    StringPtr += StrLen (L"GUID=");\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+\r
+    if (*StringPtr == L'\0') {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    StringPtr += StrLen (L"&NAME=");\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+\r
+    if (*StringPtr == L'\0') {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    StringPtr += StrLen (L"&PATH=");\r
+    while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+      StringPtr++;\r
+    }\r
+\r
+    if (*StringPtr == L'\0') {\r
+      //\r
+      // No request block is found.\r
+      //\r
+      StringPtr = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  // If StringPtr != NULL, get the request elements.\r
+  //\r
+  if (StringPtr != NULL) {\r
+    if (StrStr (StringPtr, L"&OFFSET=") != NULL) {\r
+      RequestBlockArray = GetBlockElement (StringPtr, &Progress);\r
+    } else {\r
+      RequestBlockArray = GetNameElement (StringPtr, &Progress);\r
+    }\r
+\r
+    if (RequestBlockArray == NULL) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Initialize DefaultIdArray to store the map between DeaultId and DefaultName\r
+  //\r
+  DefaultIdArray = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+  if (DefaultIdArray == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  InitializeListHead (&DefaultIdArray->Entry);\r
+\r
+  //\r
+  // Initialize VarStorageData to store the var store Block and Default value information.\r
+  //\r
+  VarStorageData = (IFR_VARSTORAGE_DATA *)AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));\r
+  if (VarStorageData == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  InitializeListHead (&VarStorageData->Entry);\r
+  InitializeListHead (&VarStorageData->BlockEntry);\r
+\r
+  //\r
+  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
+  //\r
+\r
+  //\r
+  // Parse the opcode in form package to get the default setting.\r
+  //\r
+  Status = ParseIfrData (\r
+             DataBaseRecord->Handle,\r
+             HiiFormPackage,\r
+             (UINT32)PackageSize,\r
+             *Request,\r
+             RequestBlockArray,\r
+             VarStorageData,\r
+             DefaultIdArray\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // No requested varstore in IFR data and directly return\r
+  //\r
+  if ((VarStorageData->Type == 0) && (VarStorageData->Name == NULL)) {\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.\r
+  //\r
+  Status = GenerateHdr (VarStorageData, DevicePath, &ConfigHdr);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  if (RequestBlockArray == NULL) {\r
+    if (!GenerateConfigRequest (ConfigHdr, VarStorageData, &Status, Request)) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // 4. Construct Default Value string in AltResp according to request element.\r
+  // Go through all VarStorageData Entry and get the DefaultId array for each one\r
+  // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody\r
+  //\r
+  Status = GenerateAltConfigResp (DataBaseRecord->Handle, ConfigHdr, VarStorageData, DefaultIdArray, &DefaultAltCfgResp);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // 5. Merge string into the input AltCfgResp if the input *AltCfgResp is not NULL.\r
+  //\r
+  if ((*AltCfgResp != NULL) && (DefaultAltCfgResp != NULL)) {\r
+    Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);\r
+    FreePool (DefaultAltCfgResp);\r
+  } else if (*AltCfgResp == NULL) {\r
+    *AltCfgResp = DefaultAltCfgResp;\r
+  }\r
+\r
+Done:\r
+  if (RequestBlockArray != NULL) {\r
+    //\r
+    // Free Link Array RequestBlockArray\r
+    //\r
+    while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      if (BlockData->Name != NULL) {\r
+        FreePool (BlockData->Name);\r
+      }\r
+\r
+      FreePool (BlockData);\r
+    }\r
+\r
+    FreePool (RequestBlockArray);\r
+  }\r
+\r
+  if (VarStorageData != NULL) {\r
+    //\r
+    // Free link array VarStorageData\r
+    //\r
+    while (!IsListEmpty (&VarStorageData->BlockEntry)) {\r
+      BlockData = BASE_CR (VarStorageData->BlockEntry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      if (BlockData->Name != NULL) {\r
+        FreePool (BlockData->Name);\r
+      }\r
+\r
+      //\r
+      // Free default value link array\r
+      //\r
+      while (!IsListEmpty (&BlockData->DefaultValueEntry)) {\r
+        DefaultValueData = BASE_CR (BlockData->DefaultValueEntry.ForwardLink, IFR_DEFAULT_DATA, Entry);\r
+        RemoveEntryList (&DefaultValueData->Entry);\r
+        FreePool (DefaultValueData);\r
+      }\r
+\r
+      FreePool (BlockData);\r
+    }\r
+\r
+    if (VarStorageData->Name != NULL) {\r
+      FreePool (VarStorageData->Name);\r
+      VarStorageData->Name = NULL;\r
+    }\r
+\r
+    FreePool (VarStorageData);\r
+  }\r
+\r
+  if (DefaultIdArray != NULL) {\r
+    //\r
+    // Free DefaultId Array\r
+    //\r
+    while (!IsListEmpty (&DefaultIdArray->Entry)) {\r
+      DefaultId = BASE_CR (DefaultIdArray->Entry.ForwardLink, IFR_DEFAULT_DATA, Entry);\r
+      RemoveEntryList (&DefaultId->Entry);\r
+      FreePool (DefaultId);\r
+    }\r
+\r
+    FreePool (DefaultIdArray);\r
+  }\r
+\r
+  //\r
+  // Free the allocated string\r
+  //\r
+  if (ConfigHdr != NULL) {\r
+    FreePool (ConfigHdr);\r
+  }\r
+\r
+  //\r
+  // Free Package data\r
+  //\r
+  if (HiiFormPackage != NULL) {\r
+    FreePool (HiiFormPackage);\r
+  }\r
+\r
+  if (PointerProgress != NULL) {\r
+    if (*Request == NULL) {\r
+      *PointerProgress = NULL;\r
+    } else if (EFI_ERROR (Status)) {\r
+      *PointerProgress = *Request;\r
+    } else {\r
+      *PointerProgress = *Request + StrLen (*Request);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function gets the full request resp string by\r
+  parsing IFR data in HII form packages.\r
+\r
+  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
+                                 instance.\r
+  @param  EfiVarStoreInfo        The efi varstore info which is save in the EFI\r
+                                 varstore data structure.\r
+  @param  Request                Pointer to a null-terminated Unicode string in\r
+                                 <ConfigRequest> format.\r
+  @param  RequestResp            Pointer to a null-terminated Unicode string in\r
+                                 <ConfigResp> format.\r
+  @param  AccessProgress         On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 & before the first failing name / value pair (or\r
+                                 the beginning of the string if the failure is in\r
+                                 the first name / value pair) if the request was\r
+                                 not successful.\r
+\r
+  @retval EFI_SUCCESS            The Results string is set to the full request string.\r
+                                 And AltCfgResp contains all default value string.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory for the return string.\r
+  @retval EFI_INVALID_PARAMETER  Request points to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+GetConfigRespFromEfiVarStore (\r
+  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,\r
+  IN  EFI_IFR_VARSTORE_EFI                   *EfiVarStoreInfo,\r
+  IN  EFI_STRING                             Request,\r
+  OUT EFI_STRING                             *RequestResp,\r
+  OUT EFI_STRING                             *AccessProgress\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_STRING  VarStoreName;\r
+  UINTN       NameSize;\r
+  UINT8       *VarStore;\r
+  UINTN       BufferSize;\r
+\r
+  Status          = EFI_SUCCESS;\r
+  BufferSize      = 0;\r
+  VarStore        = NULL;\r
+  VarStoreName    = NULL;\r
+  *AccessProgress = Request;\r
+\r
+  NameSize     = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);\r
+  VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+  if (VarStoreName == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  AsciiStrToUnicodeStrS ((CHAR8 *)EfiVarStoreInfo->Name, VarStoreName, NameSize);\r
+\r
+  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    goto Done;\r
+  }\r
+\r
+  VarStore = AllocateZeroPool (BufferSize);\r
+  ASSERT (VarStore != NULL);\r
+  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = HiiBlockToConfig (This, Request, VarStore, BufferSize, RequestResp, AccessProgress);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  if (VarStoreName != NULL) {\r
+    FreePool (VarStoreName);\r
+  }\r
+\r
+  if (VarStore != NULL) {\r
+    FreePool (VarStore);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function route the full request resp string for efi varstore.\r
+\r
+  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
+                                 instance.\r
+  @param  EfiVarStoreInfo        The efi varstore info which is save in the EFI\r
+                                 varstore data structure.\r
+  @param  RequestResp            Pointer to a null-terminated Unicode string in\r
+                                 <ConfigResp> format.\r
+  @param  Result                 Pointer to a null-terminated Unicode string in\r
+                                 <ConfigResp> format.\r
+\r
+  @retval EFI_SUCCESS            The Results string is set to the full request string.\r
+                                 And AltCfgResp contains all default value string.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory for the return string.\r
+  @retval EFI_INVALID_PARAMETER  Request points to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+RouteConfigRespForEfiVarStore (\r
+  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,\r
+  IN  EFI_IFR_VARSTORE_EFI                   *EfiVarStoreInfo,\r
+  IN  EFI_STRING                             RequestResp,\r
+  OUT EFI_STRING                             *Result\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_STRING  VarStoreName;\r
+  UINTN       NameSize;\r
+  UINT8       *VarStore;\r
+  UINTN       BufferSize;\r
+  UINTN       BlockSize;\r
+\r
+  Status       = EFI_SUCCESS;\r
+  BufferSize   = 0;\r
+  VarStore     = NULL;\r
+  VarStoreName = NULL;\r
+  *Result      = RequestResp;\r
+\r
+  NameSize     = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);\r
+  VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
+  if (VarStoreName == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  AsciiStrToUnicodeStrS ((CHAR8 *)EfiVarStoreInfo->Name, VarStoreName, NameSize);\r
+\r
+  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    DEBUG ((DEBUG_ERROR, "The variable does not exist!"));\r
+    goto Done;\r
+  }\r
+\r
+  BlockSize = BufferSize;\r
+  VarStore  = AllocateZeroPool (BufferSize);\r
+  ASSERT (VarStore != NULL);\r
+  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = HiiConfigToBlock (This, RequestResp, VarStore, &BlockSize, Result);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = gRT->SetVariable (VarStoreName, &EfiVarStoreInfo->Guid, EfiVarStoreInfo->Attributes, BufferSize, VarStore);\r
+  if (EFI_ERROR (Status)) {\r
+    *Result = RequestResp;\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  if (VarStoreName != NULL) {\r
+    FreePool (VarStoreName);\r
+  }\r
+\r
+  if (VarStore != NULL) {\r
+    FreePool (VarStore);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Validate the config request elements.\r
+\r
+  @param  ConfigElements                A null-terminated Unicode string in <ConfigRequest> format,\r
+                                        without configHdr field.\r
+\r
+  @retval     CHAR16 *    THE first Name/value pair not correct.\r
+  @retval     NULL        Success parse the name/value pair\r
+**/\r
+CHAR16 *\r
+OffsetWidthValidate (\r
+  CHAR16  *ConfigElements\r
+  )\r
+{\r
+  CHAR16  *StringPtr;\r
+  CHAR16  *RetVal;\r
+\r
+  StringPtr = ConfigElements;\r
+\r
+  while (1) {\r
+    RetVal = StringPtr;\r
+    if (StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+      return RetVal;\r
+    }\r
+\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+\r
+    if (*StringPtr == L'\0') {\r
+      return RetVal;\r
+    }\r
+\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+\r
+    if (*StringPtr == L'\0') {\r
+      return NULL;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Validate the config request elements.\r
+\r
+  @param  ConfigElements                A null-terminated Unicode string in <ConfigRequest> format,\r
+                                        without configHdr field.\r
+\r
+  @retval     CHAR16 *    THE first Name/value pair not correct.\r
+  @retval     NULL        Success parse the name/value pair\r
+\r
+**/\r
+CHAR16 *\r
+NameValueValidate (\r
+  CHAR16  *ConfigElements\r
+  )\r
+{\r
+  CHAR16  *StringPtr;\r
+  CHAR16  *RetVal;\r
+\r
+  StringPtr = ConfigElements;\r
+\r
+  while (1) {\r
+    RetVal = StringPtr;\r
+    if (*StringPtr != L'&') {\r
+      return RetVal;\r
+    }\r
+\r
+    StringPtr += 1;\r
+\r
+    StringPtr = StrStr (StringPtr, L"&");\r
+\r
+    if (StringPtr == NULL) {\r
+      return NULL;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Validate the config request string.\r
+\r
+  @param  ConfigRequest                A null-terminated Unicode string in <ConfigRequest> format.\r
+\r
+  @retval     CHAR16 *    THE first element not correct.\r
+  @retval     NULL        Success parse the name/value pair\r
+\r
+**/\r
+CHAR16 *\r
+ConfigRequestValidate (\r
+  CHAR16  *ConfigRequest\r
+  )\r
+{\r
+  BOOLEAN  HasNameField;\r
+  CHAR16   *StringPtr;\r
+\r
+  HasNameField = TRUE;\r
+  StringPtr    = ConfigRequest;\r
+\r
+  //\r
+  // Check <ConfigHdr>\r
+  //\r
+  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+    return ConfigRequest;\r
+  }\r
+\r
+  StringPtr += StrLen (L"GUID=");\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+\r
+  if (*StringPtr == L'\0') {\r
+    return ConfigRequest;\r
+  }\r
+\r
+  StringPtr += StrLen (L"&NAME=");\r
+  if (*StringPtr == L'&') {\r
+    HasNameField = FALSE;\r
+  }\r
+\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+\r
+  if (*StringPtr == L'\0') {\r
+    return ConfigRequest;\r
+  }\r
+\r
+  StringPtr += StrLen (L"&PATH=");\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+\r
+  if (*StringPtr == L'\0') {\r
+    return NULL;\r
+  }\r
+\r
+  if (HasNameField) {\r
+    //\r
+    // Should be Buffer varstore, config request should be "OFFSET/Width" pairs.\r
+    //\r
+    return OffsetWidthValidate (StringPtr);\r
+  } else {\r
+    //\r
+    // Should be Name/Value varstore, config request should be "&name1&name2..." pairs.\r
+    //\r
+    return NameValueValidate (StringPtr);\r
+  }\r
+}\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration\r
+  for one or more named elements from one or more drivers.\r
+\r
+  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
+                                 instance.\r
+  @param  Request                A null-terminated Unicode string in\r
+                                 <MultiConfigRequest> format.\r
+  @param  Progress               On return, points to a character in the Request\r
                                  string. Points to the string's null terminator if\r
                                  request was successful. Points to the most recent\r
                                  & before the first failing name / value pair (or\r
@@ -814,8 +4819,10 @@ Exit:
                                  Progress parameter is set to NULL.\r
   @retval EFI_INVALID_PARAMETER  Illegal syntax. Progress set to most recent &\r
                                  before the error or the beginning of the string.\r
-  @retval EFI_INVALID_PARAMETER  Unknown name. Progress points to the & before the\r
-                                 name in question.\r
+  @retval EFI_INVALID_PARAMETER  The ExtractConfig function of the underlying HII\r
+                                 Configuration Access Protocol returned\r
+                                 EFI_INVALID_PARAMETER. Progress set to most recent\r
+                                 & before the error or the beginning of the string.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -827,25 +4834,36 @@ HiiConfigRoutingExtractConfig (
   OUT EFI_STRING                             *Results\r
   )\r
 {\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  EFI_STRING                          StringPtr;\r
-  EFI_STRING                          ConfigRequest;\r
-  UINTN                               Length;\r
-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
-  EFI_STATUS                          Status;\r
-  LIST_ENTRY                          *Link;\r
-  HII_DATABASE_RECORD                 *Database;\r
-  UINT8                               *CurrentDevicePath;\r
-  EFI_HANDLE                          DriverHandle;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
-  EFI_STRING                          AccessProgress;\r
-  EFI_STRING                          AccessResults;\r
-  UINTN                               RemainSize;\r
-  EFI_STRING                          TmpPtr;\r
-\r
-  if (This == NULL || Progress == NULL || Results == NULL) {\r
+  HII_DATABASE_PRIVATE_DATA       *Private;\r
+  EFI_STRING                      StringPtr;\r
+  EFI_STRING                      ConfigRequest;\r
+  UINTN                           Length;\r
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;\r
+  EFI_STATUS                      Status;\r
+  LIST_ENTRY                      *Link;\r
+  HII_DATABASE_RECORD             *Database;\r
+  UINT8                           *DevicePathPkg;\r
+  UINT8                           *CurrentDevicePath;\r
+  EFI_HANDLE                      DriverHandle;\r
+  EFI_HII_HANDLE                  HiiHandle;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_STRING                      AccessProgress;\r
+  EFI_STRING                      AccessResults;\r
+  EFI_STRING                      AccessProgressBackup;\r
+  EFI_STRING                      AccessResultsBackup;\r
+  EFI_STRING                      DefaultResults;\r
+  BOOLEAN                         FirstElement;\r
+  BOOLEAN                         IfrDataParsedFlag;\r
+  BOOLEAN                         IsEfiVarStore;\r
+  EFI_IFR_VARSTORE_EFI            *EfiVarStoreInfo;\r
+  EFI_STRING                      ErrorPtr;\r
+  UINTN                           DevicePathSize;\r
+  UINTN                           ConigStringSize;\r
+  UINTN                           ConigStringSizeNewsize;\r
+  EFI_STRING                      ConfigStringPtr;\r
+\r
+  if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -854,9 +4872,20 @@ HiiConfigRoutingExtractConfig (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Private   = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-  StringPtr = Request;\r
-  *Progress = StringPtr;\r
+  Private              = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  StringPtr            = Request;\r
+  *Progress            = StringPtr;\r
+  DefaultResults       = NULL;\r
+  ConfigRequest        = NULL;\r
+  Status               = EFI_SUCCESS;\r
+  AccessResults        = NULL;\r
+  AccessProgress       = NULL;\r
+  AccessResultsBackup  = NULL;\r
+  AccessProgressBackup = NULL;\r
+  DevicePath           = NULL;\r
+  IfrDataParsedFlag    = FALSE;\r
+  IsEfiVarStore        = FALSE;\r
+  EfiVarStoreInfo      = NULL;\r
 \r
   //\r
   // The first element of <MultiConfigRequest> should be\r
@@ -866,11 +4895,13 @@ HiiConfigRoutingExtractConfig (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  FirstElement = TRUE;\r
+\r
   //\r
   // Allocate a fix length of memory to store Results. Reallocate memory for\r
   // Results if this fix length is insufficient.\r
   //\r
-  *Results = (EFI_STRING) AllocateZeroPool (MAX_STRING_LENGTH);\r
+  *Results = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);\r
   if (*Results == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -889,94 +4920,246 @@ HiiConfigRoutingExtractConfig (
     //\r
     // Process each <ConfigRequest> of <MultiConfigRequest>\r
     //\r
-    Length = CalculateConfigStringLen (StringPtr);\r
+    Length        = CalculateConfigStringLen (StringPtr);\r
     ConfigRequest = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), StringPtr);\r
     if (ConfigRequest == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
     }\r
+\r
     *(ConfigRequest + Length) = 0;\r
 \r
     //\r
     // Get the UEFI device path\r
     //\r
-    Status = GetDevicePath (ConfigRequest, (UINT8 **) &DevicePath);\r
+    Status = GetDevicePath (ConfigRequest, (UINT8 **)&DevicePath);\r
     if (EFI_ERROR (Status)) {\r
-      SafeFreePool (ConfigRequest);\r
-      return Status;\r
+      goto Done;\r
     }\r
 \r
     //\r
     // Find driver which matches the routing data.\r
     //\r
     DriverHandle = NULL;\r
+    HiiHandle    = NULL;\r
+    Database     = NULL;\r
     for (Link = Private->DatabaseList.ForwardLink;\r
          Link != &Private->DatabaseList;\r
          Link = Link->ForwardLink\r
-        ) {\r
+         )\r
+    {\r
       Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
-      CurrentDevicePath = Database->PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
-      if (CurrentDevicePath != NULL) {\r
-        if (CompareMem (\r
-              DevicePath,\r
-              CurrentDevicePath,\r
-              GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
-              ) == 0) {\r
+      if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
+        CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
+        DevicePathSize    = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);\r
+        if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0) && IsThisPackageList (Database, ConfigRequest)) {\r
           DriverHandle = Database->DriverHandle;\r
+          HiiHandle    = Database->Handle;\r
           break;\r
         }\r
       }\r
     }\r
 \r
-    SafeFreePool (DevicePath);\r
-\r
+    //\r
+    // Try to find driver handle by device path.\r
+    //\r
     if (DriverHandle == NULL) {\r
+      TempDevicePath = DevicePath;\r
+      Status         = gBS->LocateDevicePath (\r
+                              &gEfiDevicePathProtocolGuid,\r
+                              &TempDevicePath,\r
+                              &DriverHandle\r
+                              );\r
+      if (EFI_ERROR (Status) || (DriverHandle == NULL)) {\r
+        //\r
+        // Routing data does not match any known driver.\r
+        // Set Progress to the 'G' in "GUID" of the routing header.\r
+        //\r
+        *Progress = StringPtr;\r
+        Status    = EFI_NOT_FOUND;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Validate ConfigRequest String.\r
+    //\r
+    ErrorPtr = ConfigRequestValidate (ConfigRequest);\r
+    if (ErrorPtr != NULL) {\r
+      *Progress = StrStr (StringPtr, ErrorPtr);\r
+      Status    = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Check whether ConfigRequest contains request string.\r
+    //\r
+    IfrDataParsedFlag = FALSE;\r
+    if ((HiiHandle != NULL) && !GetElementsFromRequest (ConfigRequest)) {\r
       //\r
-      // Routing data does not match any known driver.\r
-      // Set Progress to the 'G' in "GUID" of the routing header.\r
+      // Get the full request string from IFR when HiiPackage is registered to HiiHandle\r
       //\r
-      *Progress = StringPtr;\r
-      SafeFreePool (ConfigRequest);\r
-      return EFI_NOT_FOUND;\r
+      IfrDataParsedFlag = TRUE;\r
+      Status            = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, &AccessProgress);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // AccessProgress indicates the parsing progress on <ConfigRequest>.\r
+        // Map it to the progress on <MultiConfigRequest> then return it.\r
+        //\r
+        ASSERT (AccessProgress != NULL);\r
+        *Progress = StrStr (StringPtr, AccessProgress);\r
+        goto Done;\r
+      }\r
+\r
+      //\r
+      // Not any request block is found.\r
+      //\r
+      if (!GetElementsFromRequest (ConfigRequest)) {\r
+        AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
+        goto NextConfigString;\r
+      }\r
     }\r
 \r
     //\r
-    // Call corresponding ConfigAccess protocol to extract settings\r
+    // Check whether this ConfigRequest is search from Efi varstore type storage.\r
     //\r
-    Status = gBS->HandleProtocol (\r
-                    DriverHandle,\r
-                    &gEfiHiiConfigAccessProtocolGuid,\r
-                    (VOID **) &ConfigAccess\r
-                    );\r
-    ASSERT_EFI_ERROR (Status);\r
+    Status = GetVarStoreType (Database, ConfigRequest, &IsEfiVarStore, &EfiVarStoreInfo);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (IsEfiVarStore) {\r
+      //\r
+      // Call the GetVariable function to extract settings.\r
+      //\r
+      Status = GetConfigRespFromEfiVarStore (This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);\r
+      FreePool (EfiVarStoreInfo);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // AccessProgress indicates the parsing progress on <ConfigRequest>.\r
+        // Map it to the progress on <MultiConfigRequest> then return it.\r
+        //\r
+        *Progress = StrStr (StringPtr, AccessProgress);\r
+        goto Done;\r
+      }\r
+\r
+      //\r
+      // For EfiVarstore, call corresponding ConfigAccess protocol to get the AltCfgResp from driver.\r
+      //\r
+      Status = gBS->HandleProtocol (\r
+                      DriverHandle,\r
+                      &gEfiHiiConfigAccessProtocolGuid,\r
+                      (VOID **)&ConfigAccess\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // The driver has EfiVarStore, may not install ConfigAccess protocol.\r
+        // So ignore the error status in this case.\r
+        //\r
+        Status = EFI_SUCCESS;\r
+      } else {\r
+        Status = ConfigAccess->ExtractConfig (\r
+                                 ConfigAccess,\r
+                                 ConfigRequest,\r
+                                 &AccessProgressBackup,\r
+                                 &AccessResultsBackup\r
+                                 );\r
+        if (!EFI_ERROR (Status)) {\r
+          //\r
+          // Merge the AltCfgResp in AccessResultsBackup to AccessResults\r
+          //\r
+          if ((AccessResultsBackup != NULL) && (StrStr (AccessResultsBackup, L"&ALTCFG=") != NULL)) {\r
+            ConigStringSize        = StrSize (AccessResults);\r
+            ConfigStringPtr        = StrStr (AccessResultsBackup, L"&GUID=");\r
+            ConigStringSizeNewsize = StrSize (ConfigStringPtr) + ConigStringSize + sizeof (CHAR16);\r
+            AccessResults          = (EFI_STRING)ReallocatePool (\r
+                                                   ConigStringSize,\r
+                                                   ConigStringSizeNewsize,\r
+                                                   AccessResults\r
+                                                   );\r
+            StrCatS (AccessResults, ConigStringSizeNewsize / sizeof (CHAR16), ConfigStringPtr);\r
+          }\r
+        } else {\r
+          //\r
+          // In the ExtractConfig function of some driver may not support EfiVarStore,\r
+          // may return error status, just ignore the error status in this case.\r
+          //\r
+          Status = EFI_SUCCESS;\r
+        }\r
+\r
+        if (AccessResultsBackup != NULL) {\r
+          FreePool (AccessResultsBackup);\r
+          AccessResultsBackup = NULL;\r
+        }\r
+      }\r
+    } else {\r
+      //\r
+      // Call corresponding ConfigAccess protocol to extract settings\r
+      //\r
+      Status = gBS->HandleProtocol (\r
+                      DriverHandle,\r
+                      &gEfiHiiConfigAccessProtocolGuid,\r
+                      (VOID **)&ConfigAccess\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      Status = ConfigAccess->ExtractConfig (\r
+                               ConfigAccess,\r
+                               ConfigRequest,\r
+                               &AccessProgress,\r
+                               &AccessResults\r
+                               );\r
+    }\r
 \r
-    Status = ConfigAccess->ExtractConfig (\r
-                             ConfigAccess,\r
-                             ConfigRequest,\r
-                             &AccessProgress,\r
-                             &AccessResults\r
-                             );\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // AccessProgress indicates the parsing progress on <ConfigRequest>.\r
       // Map it to the progress on <MultiConfigRequest> then return it.\r
       //\r
-      RemainSize = StrSize (AccessProgress);\r
-      for (TmpPtr = StringPtr; CompareMem (TmpPtr, AccessProgress, RemainSize) != 0; TmpPtr++);\r
-      *Progress = TmpPtr;\r
-\r
-      SafeFreePool (ConfigRequest);\r
-      return Status;\r
+      *Progress = StrStr (StringPtr, AccessProgress);\r
+      goto Done;\r
     }\r
 \r
     //\r
-    // Attach this <ConfigAltResp> to a <MultiConfigAltResp>\r
+    // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
+    // which separates the first <ConfigAltResp> and the following ones.\r
     //\r
     ASSERT (*AccessProgress == 0);\r
+\r
+    //\r
+    // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle\r
+    //\r
+    if (!IfrDataParsedFlag && (HiiHandle != NULL)) {\r
+      Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+\r
+    FreePool (DevicePath);\r
+    DevicePath = NULL;\r
+\r
+    if (DefaultResults != NULL) {\r
+      Status = MergeDefaultString (&AccessResults, DefaultResults);\r
+      ASSERT_EFI_ERROR (Status);\r
+      FreePool (DefaultResults);\r
+      DefaultResults = NULL;\r
+    }\r
+\r
+NextConfigString:\r
+    if (!FirstElement) {\r
+      Status = AppendToMultiString (Results, L"&");\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
+\r
     Status = AppendToMultiString (Results, AccessResults);\r
     ASSERT_EFI_ERROR (Status);\r
-    SafeFreePool (AccessResults);\r
+\r
+    FirstElement = FALSE;\r
+\r
+    FreePool (AccessResults);\r
     AccessResults = NULL;\r
-    SafeFreePool (ConfigRequest);\r
+    FreePool (ConfigRequest);\r
     ConfigRequest = NULL;\r
 \r
     //\r
@@ -989,17 +5172,33 @@ HiiConfigRoutingExtractConfig (
     }\r
 \r
     StringPtr++;\r
+  }\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (*Results);\r
+    *Results = NULL;\r
+  }\r
+\r
+  if (ConfigRequest != NULL) {\r
+    FreePool (ConfigRequest);\r
+  }\r
+\r
+  if (AccessResults != NULL) {\r
+    FreePool (AccessResults);\r
+  }\r
 \r
+  if (DefaultResults != NULL) {\r
+    FreePool (DefaultResults);\r
   }\r
 \r
-  return EFI_SUCCESS;\r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
+  if (DevicePath != NULL) {\r
+    FreePool (DevicePath);\r
+  }\r
 \r
+  return Status;\r
 }\r
 \r
-\r
 /**\r
   This function allows the caller to request the current configuration for the\r
   entirety of the current HII database and returns the data in a\r
@@ -1009,9 +5208,9 @@ HiiConfigRoutingExtractConfig (
                                  instance.\r
   @param  Results                Null-terminated Unicode string in\r
                                  <MultiConfigAltResp> format which has all values\r
-                                 filled in for the names in the Request string.\r
-                                 String to be allocated by the  called function.\r
-                                 De-allocation is up to the caller.\r
+                                 filled in for the entirety of the current HII\r
+                                 database. String to be allocated by the  called\r
+                                 function. De-allocation is up to the caller.\r
 \r
   @retval EFI_SUCCESS            The Results string is filled with the values\r
                                  corresponding to all requested names.\r
@@ -1029,200 +5228,181 @@ HiiConfigRoutingExportConfig (
   OUT EFI_STRING                             *Results\r
   )\r
 {\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
-  EFI_STATUS                          Status;\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  LIST_ENTRY                          StorageListHdr;\r
-  HII_FORMSET_STORAGE                 *Storage;\r
-  LIST_ENTRY                          *Link;\r
-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
-  UINTN                               Length;\r
-  EFI_STRING                          PathHdr;\r
-  UINTN                               PathHdrSize;\r
-  EFI_STRING                          ConfigRequest;\r
-  UINTN                               RequestSize;\r
-  EFI_STRING                          StringPtr;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
-  EFI_STRING                          AccessProgress;\r
-  EFI_STRING                          AccessResults;\r
-  UINTN                               TmpSize;\r
-\r
-  if (This == NULL || Results == NULL) {\r
+  EFI_STATUS                      Status;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_STRING                      AccessResults;\r
+  EFI_STRING                      Progress;\r
+  EFI_STRING                      StringPtr;\r
+  EFI_STRING                      ConfigRequest;\r
+  UINTN                           Index;\r
+  EFI_HANDLE                      *ConfigAccessHandles;\r
+  UINTN                           NumberConfigAccessHandles;\r
+  BOOLEAN                         FirstElement;\r
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
+  EFI_HII_HANDLE                  HiiHandle;\r
+  EFI_STRING                      DefaultResults;\r
+  HII_DATABASE_PRIVATE_DATA       *Private;\r
+  LIST_ENTRY                      *Link;\r
+  HII_DATABASE_RECORD             *Database;\r
+  UINT8                           *DevicePathPkg;\r
+  UINT8                           *CurrentDevicePath;\r
+  BOOLEAN                         IfrDataParsedFlag;\r
+\r
+  if ((This == NULL) || (Results == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
 \r
-  InitializeListHead (&StorageListHdr);\r
-\r
-  Status = ExportAllStorage (&Private->HiiDatabase, &StorageListHdr);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
   //\r
   // Allocate a fix length of memory to store Results. Reallocate memory for\r
   // Results if this fix length is insufficient.\r
   //\r
-  *Results = (EFI_STRING) AllocateZeroPool (MAX_STRING_LENGTH);\r
+  *Results = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);\r
   if (*Results == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  //\r
-  // Parsing all formset storages.\r
-  //\r
-  for (Link = StorageListHdr.ForwardLink; Link != &StorageListHdr; Link = Link->ForwardLink) {\r
-    Storage = CR (Link, HII_FORMSET_STORAGE, Entry, HII_FORMSET_STORAGE_SIGNATURE);\r
-    //\r
-    // Find the corresponding device path instance\r
-    //\r
+  NumberConfigAccessHandles = 0;\r
+  Status                    = gBS->LocateHandleBuffer (\r
+                                     ByProtocol,\r
+                                     &gEfiHiiConfigAccessProtocolGuid,\r
+                                     NULL,\r
+                                     &NumberConfigAccessHandles,\r
+                                     &ConfigAccessHandles\r
+                                     );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  FirstElement = TRUE;\r
+\r
+  for (Index = 0; Index < NumberConfigAccessHandles; Index++) {\r
     Status = gBS->HandleProtocol (\r
-                    Storage->DriverHandle,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    (VOID **) &DevicePath\r
+                    ConfigAccessHandles[Index],\r
+                    &gEfiHiiConfigAccessProtocolGuid,\r
+                    (VOID **)&ConfigAccess\r
                     );\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      continue;\r
     }\r
+\r
     //\r
-    // Convert the device path binary to hex UNICODE %02x bytes in the same order\r
-    // as the device path resides in RAM memory.\r
+    // Get DevicePath and HiiHandle for this ConfigAccess driver handle\r
     //\r
-    Length      = GetDevicePathSize (DevicePath);\r
-    PathHdrSize = (Length * 2 + 1) * sizeof (CHAR16);\r
-    PathHdr     = (EFI_STRING) AllocateZeroPool (PathHdrSize);\r
-    if (PathHdr == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+    IfrDataParsedFlag = FALSE;\r
+    Progress          = NULL;\r
+    HiiHandle         = NULL;\r
+    DefaultResults    = NULL;\r
+    Database          = NULL;\r
+    ConfigRequest     = NULL;\r
+    DevicePath        = DevicePathFromHandle (ConfigAccessHandles[Index]);\r
+    if (DevicePath != NULL) {\r
+      for (Link = Private->DatabaseList.ForwardLink;\r
+           Link != &Private->DatabaseList;\r
+           Link = Link->ForwardLink\r
+           )\r
+      {\r
+        Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
+        if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
+          CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
+          if (CompareMem (\r
+                DevicePath,\r
+                CurrentDevicePath,\r
+                GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath)\r
+                ) == 0)\r
+          {\r
+            HiiHandle = Database->Handle;\r
+            break;\r
+          }\r
+        }\r
+      }\r
     }\r
-    Status = BufToHexStringPrivate (PathHdr, &PathHdrSize, (UINT8 *) DevicePath, Length, TRUE);\r
-    ASSERT_EFI_ERROR (Status);\r
 \r
-    //\r
-    // Generate a <ConfigRequest> with one <ConfigHdr> and zero <RequestElement>.\r
-    // It means extract all possible configurations from this specific driver.\r
-    //\r
-    TmpSize = StrLen (L"GUID=&NAME=&PATH=");\r
-    RequestSize   = (TmpSize + sizeof (EFI_GUID) * 2 +  StrLen (Storage->Name))\r
-                     * sizeof (CHAR16) + PathHdrSize;\r
-    ConfigRequest = (EFI_STRING) AllocateZeroPool (RequestSize);\r
-    if (ConfigRequest == NULL) {\r
-      SafeFreePool (PathHdr);\r
-      return EFI_OUT_OF_RESOURCES;\r
+    Status = ConfigAccess->ExtractConfig (\r
+                             ConfigAccess,\r
+                             NULL,\r
+                             &Progress,\r
+                             &AccessResults\r
+                             );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle\r
+      //\r
+      if ((HiiHandle != NULL) && (DevicePath != NULL)) {\r
+        IfrDataParsedFlag = TRUE;\r
+        Status            = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+        //\r
+        // Get the full request string to get the Current setting again.\r
+        //\r
+        if (!EFI_ERROR (Status) && (ConfigRequest != NULL)) {\r
+          Status = ConfigAccess->ExtractConfig (\r
+                                   ConfigAccess,\r
+                                   ConfigRequest,\r
+                                   &Progress,\r
+                                   &AccessResults\r
+                                   );\r
+          FreePool (ConfigRequest);\r
+        } else {\r
+          Status = EFI_NOT_FOUND;\r
+        }\r
+      }\r
     }\r
 \r
-    //\r
-    // Add <GuidHdr>\r
-    // <GuidHdr> ::= 'GUID='<Guid>\r
-    //\r
-    StringPtr = ConfigRequest;\r
-    StrnCpy (StringPtr, L"GUID=", StrLen (L"GUID="));\r
-    StringPtr += StrLen (L"GUID=");\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle\r
+      //\r
+      if (!IfrDataParsedFlag && (HiiHandle != NULL) && (DevicePath != NULL)) {\r
+        StringPtr = StrStr (AccessResults, L"&GUID=");\r
+        if (StringPtr != NULL) {\r
+          *StringPtr = 0;\r
+        }\r
 \r
-    Status = BufToHexStringPrivate (\r
-               StringPtr,\r
-               &RequestSize,\r
-               (UINT8 *) (&Storage->Guid),\r
-               sizeof (EFI_GUID),\r
-               FALSE\r
-               );\r
-    ASSERT_EFI_ERROR (Status);\r
-    StringPtr += RequestSize / 2 - 1;\r
-    ASSERT (*StringPtr == 0);\r
-    *StringPtr = L'&';\r
-    StringPtr++;\r
+        if (GetElementsFromRequest (AccessResults)) {\r
+          Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);\r
+          ASSERT_EFI_ERROR (Status);\r
+        }\r
 \r
-    //\r
-    // Add <NameHdr>\r
-    // <NameHdr> ::= 'NAME='<String>\r
-    //\r
-    StrnCpy (StringPtr, L"NAME=", StrLen (L"NAME="));\r
-    StringPtr += StrLen (L"NAME=");\r
-    StrnCpy (StringPtr, Storage->Name, StrLen (Storage->Name));\r
-    StringPtr += StrLen (Storage->Name);\r
-    *StringPtr = L'&';\r
-    StringPtr++;\r
+        if (StringPtr != NULL) {\r
+          *StringPtr = L'&';\r
+        }\r
+      }\r
 \r
-    //\r
-    // Add <PathHdr>\r
-    // <PathHdr> ::= '<PATH=>'<UEFI binary represented as hex UNICODE %02x>\r
-    //\r
-    StrnCpy (StringPtr, L"PATH=", StrLen (L"PATH="));\r
-    StringPtr += StrLen (L"PATH=");\r
-    StrCpy (StringPtr, PathHdr);\r
+      //\r
+      // Merge the default sting from IFR code into the got setting from driver.\r
+      //\r
+      if (DefaultResults != NULL) {\r
+        Status = MergeDefaultString (&AccessResults, DefaultResults);\r
+        ASSERT_EFI_ERROR (Status);\r
+        FreePool (DefaultResults);\r
+        DefaultResults = NULL;\r
+      }\r
 \r
-    SafeFreePool (PathHdr);\r
-    PathHdr = NULL;\r
+      //\r
+      // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
+      // which separates the first <ConfigAltResp> and the following ones.\r
+      //\r
+      if (!FirstElement) {\r
+        Status = AppendToMultiString (Results, L"&");\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
 \r
-    //\r
-    // BUGBUG: The "Implementation note" of ExportConfig() in UEFI spec makes the\r
-    // code somewhat complex. Let's TBD here whether a <ConfigRequest> or a <ConfigHdr>\r
-    // is required to call ConfigAccess.ExtractConfig().\r
-    //\r
-    // Here we use <ConfigHdr> to call ConfigAccess instance. It requires ConfigAccess\r
-    // to handle such kind of "ConfigRequest". It is not supported till now.\r
-    //\r
-    // Either the ExportConfig will be updated or the ConfigAccess.ExtractConfig()\r
-    // will be updated as soon as the decision is made.\r
+      Status = AppendToMultiString (Results, AccessResults);\r
+      ASSERT_EFI_ERROR (Status);\r
 \r
-    //\r
-    // Route the request to corresponding ConfigAccess protocol to extract settings.\r
-    //\r
-    Status = gBS->HandleProtocol (\r
-                    Storage->DriverHandle,\r
-                    &gEfiHiiConfigAccessProtocolGuid,\r
-                    (VOID **)  &ConfigAccess\r
-                    );\r
-    ASSERT_EFI_ERROR (Status);\r
+      FirstElement = FALSE;\r
 \r
-    Status = ConfigAccess->ExtractConfig (\r
-                             ConfigAccess,\r
-                             ConfigRequest,\r
-                             &AccessProgress,\r
-                             &AccessResults\r
-                             );\r
-    if (EFI_ERROR (Status)) {\r
-      SafeFreePool (ConfigRequest);\r
-      SafeFreePool (AccessResults);\r
-      return EFI_INVALID_PARAMETER;\r
+      FreePool (AccessResults);\r
+      AccessResults = NULL;\r
     }\r
-\r
-    //\r
-    // Attach this <ConfigAltResp> to a <MultiConfigAltResp>\r
-    //\r
-    ASSERT (*AccessProgress == 0);\r
-    Status = AppendToMultiString (Results, AccessResults);\r
-    ASSERT_EFI_ERROR (Status);\r
-    SafeFreePool (AccessResults);\r
-    AccessResults = NULL;\r
-    SafeFreePool (ConfigRequest);\r
-    ConfigRequest = NULL;\r
-\r
   }\r
 \r
-  //\r
-  // Free the exported storage resource\r
-  //\r
-  while (!IsListEmpty (&StorageListHdr)) {\r
-    Storage = CR (\r
-                StorageListHdr.ForwardLink,\r
-                HII_FORMSET_STORAGE,\r
-                Entry,\r
-                HII_FORMSET_STORAGE_SIGNATURE\r
-                );\r
-    RemoveEntryList (&Storage->Entry);\r
-    SafeFreePool (Storage->Name);\r
-    SafeFreePool (Storage);\r
-  }\r
+  FreePool (ConfigAccessHandles);\r
 \r
   return EFI_SUCCESS;\r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
 }\r
 \r
-\r
 /**\r
   This function processes the results of processing forms and routes it to the\r
   appropriate handlers or storage.\r
@@ -1250,30 +5430,31 @@ HiiConfigRoutingExportConfig (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-HiiConfigRoutingRoutConfig (\r
+HiiConfigRoutingRouteConfig (\r
   IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,\r
   IN  CONST EFI_STRING                       Configuration,\r
   OUT EFI_STRING                             *Progress\r
   )\r
 {\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  EFI_STRING                          StringPtr;\r
-  EFI_STRING                          ConfigResp;\r
-  UINTN                               Length;\r
-  EFI_STATUS                          Status;\r
-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
-  LIST_ENTRY                          *Link;\r
-  HII_DATABASE_RECORD                 *Database;\r
-  UINT8                               *CurrentDevicePath;\r
-  EFI_HANDLE                          DriverHandle;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
-  EFI_STRING                          AccessProgress;\r
-  UINTN                               RemainSize;\r
-  EFI_STRING                          TmpPtr;\r
-\r
-  if (This == NULL || Progress == NULL) {\r
+  HII_DATABASE_PRIVATE_DATA       *Private;\r
+  EFI_STRING                      StringPtr;\r
+  EFI_STRING                      ConfigResp;\r
+  UINTN                           Length;\r
+  EFI_STATUS                      Status;\r
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;\r
+  LIST_ENTRY                      *Link;\r
+  HII_DATABASE_RECORD             *Database;\r
+  UINT8                           *DevicePathPkg;\r
+  UINT8                           *CurrentDevicePath;\r
+  EFI_HANDLE                      DriverHandle;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_STRING                      AccessProgress;\r
+  EFI_IFR_VARSTORE_EFI            *EfiVarStoreInfo;\r
+  BOOLEAN                         IsEfiVarstore;\r
+  UINTN                           DevicePathSize;\r
+\r
+  if ((This == NULL) || (Progress == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1282,9 +5463,13 @@ HiiConfigRoutingRoutConfig (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Private   = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-  StringPtr = Configuration;\r
-  *Progress = StringPtr;\r
+  Private         = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  StringPtr       = Configuration;\r
+  *Progress       = StringPtr;\r
+  Database        = NULL;\r
+  AccessProgress  = NULL;\r
+  EfiVarStoreInfo = NULL;\r
+  IsEfiVarstore   = FALSE;\r
 \r
   //\r
   // The first element of <MultiConfigResp> should be\r
@@ -1308,11 +5493,12 @@ HiiConfigRoutingRoutConfig (
     //\r
     // Process each <ConfigResp> of <MultiConfigResp>\r
     //\r
-    Length = CalculateConfigStringLen (StringPtr);\r
+    Length     = CalculateConfigStringLen (StringPtr);\r
     ConfigResp = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), StringPtr);\r
     if (ConfigResp == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+\r
     //\r
     // Append '\0' to the end of ConfigRequest\r
     //\r
@@ -1321,9 +5507,9 @@ HiiConfigRoutingRoutConfig (
     //\r
     // Get the UEFI device path\r
     //\r
-    Status = GetDevicePath (ConfigResp, (UINT8 **) &DevicePath);\r
+    Status = GetDevicePath (ConfigResp, (UINT8 **)&DevicePath);\r
     if (EFI_ERROR (Status)) {\r
-      SafeFreePool (ConfigResp);\r
+      FreePool (ConfigResp);\r
       return Status;\r
     }\r
 \r
@@ -1334,63 +5520,93 @@ HiiConfigRoutingRoutConfig (
     for (Link = Private->DatabaseList.ForwardLink;\r
          Link != &Private->DatabaseList;\r
          Link = Link->ForwardLink\r
-        ) {\r
+         )\r
+    {\r
       Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
-      CurrentDevicePath = Database->PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
-      if (CurrentDevicePath != NULL) {\r
-        if (CompareMem (\r
-              DevicePath,\r
-              CurrentDevicePath,\r
-              GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
-              ) == 0) {\r
+\r
+      if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
+        CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
+        DevicePathSize    = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);\r
+        if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0) && IsThisPackageList (Database, ConfigResp)) {\r
           DriverHandle = Database->DriverHandle;\r
           break;\r
         }\r
       }\r
     }\r
 \r
-    SafeFreePool (DevicePath);\r
-\r
+    //\r
+    // Try to find driver handle by device path.\r
+    //\r
     if (DriverHandle == NULL) {\r
-      //\r
-      // Routing data does not match any known driver.\r
-      // Set Progress to the 'G' in "GUID" of the routing header.\r
-      //\r
-      *Progress = StringPtr;\r
-      SafeFreePool (ConfigResp);\r
-      return EFI_NOT_FOUND;\r
+      TempDevicePath = DevicePath;\r
+      Status         = gBS->LocateDevicePath (\r
+                              &gEfiDevicePathProtocolGuid,\r
+                              &TempDevicePath,\r
+                              &DriverHandle\r
+                              );\r
+      if (EFI_ERROR (Status) || (DriverHandle == NULL)) {\r
+        //\r
+        // Routing data does not match any known driver.\r
+        // Set Progress to the 'G' in "GUID" of the routing header.\r
+        //\r
+        FreePool (DevicePath);\r
+        *Progress = StringPtr;\r
+        FreePool (ConfigResp);\r
+        return EFI_NOT_FOUND;\r
+      }\r
     }\r
 \r
+    FreePool (DevicePath);\r
+\r
     //\r
-    // Call corresponding ConfigAccess protocol to route settings\r
+    // Check whether this ConfigRequest is search from Efi varstore type storage.\r
     //\r
-    Status = gBS->HandleProtocol (\r
-                    DriverHandle,\r
-                    &gEfiHiiConfigAccessProtocolGuid,\r
-                    (VOID **)  &ConfigAccess\r
-                    );\r
-    ASSERT_EFI_ERROR (Status);\r
+    Status = GetVarStoreType (Database, ConfigResp, &IsEfiVarstore, &EfiVarStoreInfo);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-    Status = ConfigAccess->RouteConfig (\r
-                             ConfigAccess,\r
-                             ConfigResp,\r
-                             &AccessProgress\r
-                             );\r
+    if (IsEfiVarstore) {\r
+      //\r
+      // Call the SetVariable function to route settings.\r
+      //\r
+      Status = RouteConfigRespForEfiVarStore (This, EfiVarStoreInfo, ConfigResp, &AccessProgress);\r
+      FreePool (EfiVarStoreInfo);\r
+    } else {\r
+      //\r
+      // Call corresponding ConfigAccess protocol to route settings\r
+      //\r
+      Status = gBS->HandleProtocol (\r
+                      DriverHandle,\r
+                      &gEfiHiiConfigAccessProtocolGuid,\r
+                      (VOID **)&ConfigAccess\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        *Progress = StringPtr;\r
+        FreePool (ConfigResp);\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Status = ConfigAccess->RouteConfig (\r
+                               ConfigAccess,\r
+                               ConfigResp,\r
+                               &AccessProgress\r
+                               );\r
+    }\r
 \r
     if (EFI_ERROR (Status)) {\r
+      ASSERT (AccessProgress != NULL);\r
       //\r
       // AccessProgress indicates the parsing progress on <ConfigResp>.\r
       // Map it to the progress on <MultiConfigResp> then return it.\r
       //\r
-      RemainSize = StrSize (AccessProgress);\r
-      for (TmpPtr = StringPtr; CompareMem (TmpPtr, AccessProgress, RemainSize) != 0; TmpPtr++);\r
-      *Progress = TmpPtr;\r
+      *Progress = StrStr (StringPtr, AccessProgress);\r
 \r
-      SafeFreePool (ConfigResp);\r
+      FreePool (ConfigResp);\r
       return Status;\r
     }\r
 \r
-    SafeFreePool (ConfigResp);\r
+    FreePool (ConfigResp);\r
     ConfigResp = NULL;\r
 \r
     //\r
@@ -1403,16 +5619,11 @@ HiiConfigRoutingRoutConfig (
     }\r
 \r
     StringPtr++;\r
-\r
   }\r
 \r
   return EFI_SUCCESS;\r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
 }\r
 \r
-\r
 /**\r
   This helper function is to be called by drivers to map configuration data\r
   stored in byte array ("block") formats such as UEFI Variables into current\r
@@ -1426,7 +5637,7 @@ HiiConfigRoutingRoutConfig (
   @param  BlockSize              Length in bytes of Block.\r
   @param  Config                 Filled-in configuration string. String allocated\r
                                  by  the function. Returned only if call is\r
-                                 successful.\r
+                                 successful. It is <ConfigResp> string format.\r
   @param  Progress               A pointer to a string filled in with the offset of\r
                                   the most recent & before the first failing\r
                                  name/value pair (or the beginning of the string if\r
@@ -1459,28 +5670,32 @@ HiiBlockToConfig (
   OUT EFI_STRING                             *Progress\r
   )\r
 {\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  EFI_STRING                          StringPtr;\r
-  UINTN                               Length;\r
-  EFI_STATUS                          Status;\r
-  EFI_STRING                          TmpPtr;\r
-  UINT8                               *TmpBuffer;\r
-  UINTN                               Offset;\r
-  UINTN                               Width;\r
-  UINT8                               *Value;\r
-  EFI_STRING                          ValueStr;\r
-  EFI_STRING                          ConfigElement;\r
-\r
-  if (This == NULL || Progress == NULL || Config == NULL) {\r
+  HII_DATABASE_PRIVATE_DATA  *Private;\r
+  EFI_STRING                 StringPtr;\r
+  UINTN                      Length;\r
+  EFI_STATUS                 Status;\r
+  EFI_STRING                 TmpPtr;\r
+  UINT8                      *TmpBuffer;\r
+  UINTN                      Offset;\r
+  UINTN                      Width;\r
+  UINT8                      *Value;\r
+  EFI_STRING                 ValueStr;\r
+  EFI_STRING                 ConfigElement;\r
+  UINTN                      Index;\r
+  UINT8                      *TemBuffer;\r
+  CHAR16                     *TemString;\r
+\r
+  TmpBuffer = NULL;\r
+\r
+  if ((This == NULL) || (Progress == NULL) || (Config == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (Block == NULL || ConfigRequest == NULL) {\r
+  if ((Block == NULL) || (ConfigRequest == NULL)) {\r
     *Progress = ConfigRequest;\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-\r
   Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
   ASSERT (Private != NULL);\r
 \r
@@ -1493,7 +5708,7 @@ HiiBlockToConfig (
   // Allocate a fix length of memory to store Results. Reallocate memory for\r
   // Results if this fix length is insufficient.\r
   //\r
-  *Config = (EFI_STRING) AllocateZeroPool (MAX_STRING_LENGTH);\r
+  *Config = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);\r
   if (*Config == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -1503,24 +5718,49 @@ HiiBlockToConfig (
   //\r
   if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
     *Progress = StringPtr;\r
-    Status = EFI_INVALID_PARAMETER;\r
+    Status    = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
+\r
   while (*StringPtr != 0 && StrnCmp (StringPtr, L"PATH=", StrLen (L"PATH=")) != 0) {\r
     StringPtr++;\r
   }\r
+\r
   if (*StringPtr == 0) {\r
-    *Progress = StringPtr;\r
-    Status = EFI_INVALID_PARAMETER;\r
+    *Progress = StringPtr - 1;\r
+    Status    = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
-  while (*StringPtr++ != L'&');\r
+\r
+  while (*StringPtr != L'&' && *StringPtr != 0) {\r
+    StringPtr++;\r
+  }\r
+\r
+  if (*StringPtr == 0) {\r
+    *Progress = StringPtr;\r
+\r
+    AppendToMultiString (Config, ConfigRequest);\r
+    HiiToLower (*Config);\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Skip '&'\r
+  //\r
+  StringPtr++;\r
 \r
   //\r
   // Copy <ConfigHdr> and an additional '&' to <ConfigResp>\r
   //\r
-  Length = StringPtr - ConfigRequest;\r
-  CopyMem (*Config, ConfigRequest, Length * sizeof (CHAR16));\r
+  TemString = AllocateCopyPool (sizeof (CHAR16) * (StringPtr - ConfigRequest + 1), ConfigRequest);\r
+  if (TemString == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  TemString[StringPtr - ConfigRequest] = '\0';\r
+  AppendToMultiString (Config, TemString);\r
+  FreePool (TemString);\r
 \r
   //\r
   // Parse each <RequestElement> if exists\r
@@ -1538,46 +5778,49 @@ HiiBlockToConfig (
     // Get Offset\r
     //\r
     Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      *Progress = ConfigRequest;\r
+    if (EFI_ERROR (Status)) {\r
+      *Progress = TmpPtr - 1;\r
       goto Exit;\r
     }\r
+\r
     Offset = 0;\r
     CopyMem (\r
       &Offset,\r
       TmpBuffer,\r
       (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
       );\r
-    SafeFreePool (TmpBuffer);\r
+    FreePool (TmpBuffer);\r
 \r
     StringPtr += Length;\r
     if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
-      *Progress = StringPtr - Length - StrLen (L"OFFSET=") - 1;\r
-      Status = EFI_INVALID_PARAMETER;\r
+      *Progress = TmpPtr - 1;\r
+      Status    = EFI_INVALID_PARAMETER;\r
       goto Exit;\r
     }\r
+\r
     StringPtr += StrLen (L"&WIDTH=");\r
 \r
     //\r
     // Get Width\r
     //\r
     Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      *Progress = ConfigRequest;\r
+    if (EFI_ERROR (Status)) {\r
+      *Progress =  TmpPtr - 1;\r
       goto Exit;\r
     }\r
+\r
     Width = 0;\r
     CopyMem (\r
       &Width,\r
       TmpBuffer,\r
       (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
       );\r
-    SafeFreePool (TmpBuffer);\r
+    FreePool (TmpBuffer);\r
 \r
     StringPtr += Length;\r
-    if (*StringPtr != 0 && *StringPtr != L'&') {\r
-      *Progress = StringPtr - Length - StrLen (L"&WIDTH=");\r
-      Status = EFI_INVALID_PARAMETER;\r
+    if ((*StringPtr != 0) && (*StringPtr != L'&')) {\r
+      *Progress =  TmpPtr - 1;\r
+      Status    = EFI_INVALID_PARAMETER;\r
       goto Exit;\r
     }\r
 \r
@@ -1586,55 +5829,68 @@ HiiBlockToConfig (
     //\r
     if (Offset + Width > BlockSize) {\r
       *Progress = StringPtr;\r
-      Status = EFI_DEVICE_ERROR;\r
+      Status    = EFI_DEVICE_ERROR;\r
       goto Exit;\r
     }\r
 \r
-    Value = (UINT8 *) AllocateZeroPool (Width);\r
+    Value = (UINT8 *)AllocateZeroPool (Width);\r
     if (Value == NULL) {\r
       *Progress = ConfigRequest;\r
-      Status = EFI_OUT_OF_RESOURCES;\r
+      Status    = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
 \r
-    CopyMem (Value, (UINT8 *) Block + Offset, Width);\r
+    CopyMem (Value, (UINT8 *)Block + Offset, Width);\r
 \r
-    Length = Width * 2 + 1;\r
-    ValueStr = (EFI_STRING) AllocateZeroPool (Length  * sizeof (CHAR16));\r
+    Length   = Width * 2 + 1;\r
+    ValueStr = (EFI_STRING)AllocateZeroPool (Length  * sizeof (CHAR16));\r
     if (ValueStr == NULL) {\r
       *Progress = ConfigRequest;\r
-      Status = EFI_OUT_OF_RESOURCES;\r
+      Status    = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
 \r
-    Status = R8_BufToHexString (ValueStr, &Length, Value, Width);\r
-    ASSERT_EFI_ERROR (Status);\r
-    SafeFreePool (Value);\r
+    TemString = ValueStr;\r
+    TemBuffer = Value + Width - 1;\r
+    for (Index = 0; Index < Width; Index++, TemBuffer--) {\r
+      UnicodeValueToStringS (\r
+        TemString,\r
+        Length  * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),\r
+        PREFIX_ZERO | RADIX_HEX,\r
+        *TemBuffer,\r
+        2\r
+        );\r
+      TemString += StrnLenS (TemString, Length - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));\r
+    }\r
+\r
+    FreePool (Value);\r
     Value = NULL;\r
 \r
     //\r
     // Build a ConfigElement\r
     //\r
-    Length += StringPtr - TmpPtr + 1 + StrLen (L"VALUE=");\r
-    ConfigElement = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));\r
+    Length       += StringPtr - TmpPtr + 1 + StrLen (L"VALUE=");\r
+    ConfigElement = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));\r
     if (ConfigElement == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
+\r
     CopyMem (ConfigElement, TmpPtr, (StringPtr - TmpPtr + 1) * sizeof (CHAR16));\r
     if (*StringPtr == 0) {\r
       *(ConfigElement + (StringPtr - TmpPtr)) = L'&';\r
     }\r
+\r
     *(ConfigElement + (StringPtr - TmpPtr) + 1) = 0;\r
-    StrCat (ConfigElement, L"VALUE=");\r
-    StrCat (ConfigElement, ValueStr);\r
+    StrCatS (ConfigElement, Length, L"VALUE=");\r
+    StrCatS (ConfigElement, Length, ValueStr);\r
 \r
     AppendToMultiString (Config, ConfigElement);\r
 \r
-    SafeFreePool (ConfigElement);\r
-    SafeFreePool (ValueStr);\r
+    FreePool (ConfigElement);\r
+    FreePool (ValueStr);\r
     ConfigElement = NULL;\r
-    ValueStr = NULL;\r
+    ValueStr      = NULL;\r
 \r
     //\r
     // If '\0', parsing is finished. Otherwise skip '&' to continue\r
@@ -1642,31 +5898,41 @@ HiiBlockToConfig (
     if (*StringPtr == 0) {\r
       break;\r
     }\r
+\r
     AppendToMultiString (Config, L"&");\r
     StringPtr++;\r
-\r
   }\r
 \r
   if (*StringPtr != 0) {\r
     *Progress = StringPtr - 1;\r
-    Status = EFI_INVALID_PARAMETER;\r
+    Status    = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
 \r
+  HiiToLower (*Config);\r
   *Progress = StringPtr;\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
+  if (*Config != NULL) {\r
+    FreePool (*Config);\r
+    *Config = NULL;\r
+  }\r
 \r
-  SafeFreePool (*Config);\r
-  SafeFreePool (ValueStr);\r
-  SafeFreePool (Value);\r
-  SafeFreePool (ConfigElement);\r
+  if (ValueStr != NULL) {\r
+    FreePool (ValueStr);\r
+  }\r
 \r
-  return Status;\r
+  if (Value != NULL) {\r
+    FreePool (Value);\r
+  }\r
 \r
-}\r
+  if (ConfigElement != NULL) {\r
+    FreePool (ConfigElement);\r
+  }\r
 \r
+  return Status;\r
+}\r
 \r
 /**\r
   This helper function is to be called by drivers to map configuration strings\r
@@ -1686,8 +5952,9 @@ Exit:
                                  (see below)  is returned.\r
   @param  BlockSize              The length of the Block in units of UINT8.  On\r
                                  input, this is the size of the Block. On output,\r
-                                 if successful, contains the index of the  last\r
-                                 modified byte in the Block.\r
+                                 if successful, contains the largest index of the\r
+                                 modified byte in the Block, or the required buffer\r
+                                 size if the Block is not large enough.\r
   @param  Progress               On return, points to an element of the ConfigResp\r
                                  string filled in with the offset of the most\r
                                  recent '&' before the first failing name / value\r
@@ -1707,173 +5974,216 @@ Exit:
                                  value pair. Block is left updated and\r
                                  Progress points at the '&' preceding the first\r
                                  non-<BlockName>.\r
+  @retval EFI_BUFFER_TOO_SMALL   Block not large enough. Progress undefined.\r
+                                 BlockSize is updated with the required buffer size.\r
+  @retval EFI_NOT_FOUND          Target for the specified routing data was not found.\r
+                                 Progress points to the "G" in "GUID" of the errant\r
+                                 routing data.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 HiiConfigToBlock (\r
-  IN     CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,\r
-  IN     CONST EFI_STRING                      ConfigResp,\r
-  IN OUT UINT8                                 *Block,\r
-  IN OUT UINTN                                 *BlockSize,\r
-  OUT    EFI_STRING                            *Progress\r
+  IN     CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,\r
+  IN     CONST EFI_STRING                       ConfigResp,\r
+  IN OUT UINT8                                  *Block,\r
+  IN OUT UINTN                                  *BlockSize,\r
+  OUT    EFI_STRING                             *Progress\r
   )\r
 {\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  EFI_STRING                          StringPtr;\r
-  UINTN                               Length;\r
-  EFI_STATUS                          Status;\r
-  UINT8                               *TmpBuffer;\r
-  UINTN                               Offset;\r
-  UINTN                               Width;\r
-  UINT8                               *Value;\r
-  UINTN                               BufferSize;\r
-\r
-  if (This == NULL || BlockSize == NULL || Progress == NULL) {\r
+  HII_DATABASE_PRIVATE_DATA  *Private;\r
+  EFI_STRING                 StringPtr;\r
+  EFI_STRING                 TmpPtr;\r
+  UINTN                      Length;\r
+  EFI_STATUS                 Status;\r
+  UINT8                      *TmpBuffer;\r
+  UINTN                      Offset;\r
+  UINTN                      Width;\r
+  UINT8                      *Value;\r
+  UINTN                      BufferSize;\r
+  UINTN                      MaxBlockSize;\r
+\r
+  TmpBuffer = NULL;\r
+\r
+  if ((This == NULL) || (BlockSize == NULL) || (Progress == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (ConfigResp == NULL || Block == NULL) {\r
-    *Progress = ConfigResp;\r
+  *Progress = ConfigResp;\r
+  if (ConfigResp == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
   ASSERT (Private != NULL);\r
 \r
-  StringPtr  = ConfigResp;\r
-  BufferSize = *BlockSize;\r
-  Value      = NULL;\r
+  StringPtr    = ConfigResp;\r
+  BufferSize   = *BlockSize;\r
+  Value        = NULL;\r
+  MaxBlockSize = 0;\r
 \r
   //\r
   // Jump <ConfigHdr>\r
   //\r
   if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
     *Progress = StringPtr;\r
-    Status = EFI_INVALID_PARAMETER;\r
+    Status    = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
+\r
   while (*StringPtr != 0 && StrnCmp (StringPtr, L"PATH=", StrLen (L"PATH=")) != 0) {\r
     StringPtr++;\r
   }\r
+\r
+  if (*StringPtr == 0) {\r
+    *Progress = StringPtr;\r
+    Status    = EFI_INVALID_PARAMETER;\r
+    goto Exit;\r
+  }\r
+\r
+  while (*StringPtr != L'&' && *StringPtr != 0) {\r
+    StringPtr++;\r
+  }\r
+\r
   if (*StringPtr == 0) {\r
     *Progress = StringPtr;\r
-    Status = EFI_INVALID_PARAMETER;\r
+    Status    = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
-  while (*StringPtr++ != L'&');\r
 \r
   //\r
   // Parse each <ConfigElement> if exists\r
-  // Only <BlockConfig> format is supported by this help function.\r
+  // Only '&'<BlockConfig> format is supported by this help function.\r
   // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE='<Number>\r
   //\r
-  while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {\r
-    StringPtr += StrLen (L"OFFSET=");\r
+  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
+    TmpPtr     = StringPtr;\r
+    StringPtr += StrLen (L"&OFFSET=");\r
     //\r
     // Get Offset\r
     //\r
     Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      *Progress = ConfigResp;\r
+    if (EFI_ERROR (Status)) {\r
+      *Progress = TmpPtr;\r
       goto Exit;\r
     }\r
+\r
     Offset = 0;\r
     CopyMem (\r
       &Offset,\r
       TmpBuffer,\r
       (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
       );\r
-    SafeFreePool (TmpBuffer);\r
+    FreePool (TmpBuffer);\r
 \r
     StringPtr += Length;\r
     if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
-      *Progress = StringPtr - Length - StrLen (L"OFFSET=") - 1;\r
-      Status = EFI_INVALID_PARAMETER;\r
+      *Progress = TmpPtr;\r
+      Status    = EFI_INVALID_PARAMETER;\r
       goto Exit;\r
     }\r
+\r
     StringPtr += StrLen (L"&WIDTH=");\r
 \r
     //\r
     // Get Width\r
     //\r
     Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      *Progress = ConfigResp;\r
+    if (EFI_ERROR (Status)) {\r
+      *Progress = TmpPtr;\r
       goto Exit;\r
     }\r
+\r
     Width = 0;\r
     CopyMem (\r
       &Width,\r
       TmpBuffer,\r
       (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
       );\r
-    SafeFreePool (TmpBuffer);\r
+    FreePool (TmpBuffer);\r
 \r
     StringPtr += Length;\r
     if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
-      *Progress = StringPtr - Length - StrLen (L"&WIDTH=");\r
-      Status = EFI_INVALID_PARAMETER;\r
+      *Progress = TmpPtr;\r
+      Status    = EFI_INVALID_PARAMETER;\r
       goto Exit;\r
     }\r
+\r
     StringPtr += StrLen (L"&VALUE=");\r
 \r
     //\r
     // Get Value\r
     //\r
     Status = GetValueOfNumber (StringPtr, &Value, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      *Progress = ConfigResp;\r
+    if (EFI_ERROR (Status)) {\r
+      *Progress = TmpPtr;\r
       goto Exit;\r
     }\r
 \r
     StringPtr += Length;\r
-    if (*StringPtr != 0 && *StringPtr != L'&') {\r
-      *Progress = StringPtr - Length - 7;\r
-      Status = EFI_INVALID_PARAMETER;\r
+    if ((*StringPtr != 0) && (*StringPtr != L'&')) {\r
+      *Progress = TmpPtr;\r
+      Status    = EFI_INVALID_PARAMETER;\r
       goto Exit;\r
     }\r
 \r
     //\r
     // Update the Block with configuration info\r
     //\r
-\r
-    if (Offset + Width > BufferSize) {\r
-      return EFI_DEVICE_ERROR;\r
+    if ((Block != NULL) && (Offset + Width <= BufferSize)) {\r
+      CopyMem (Block + Offset, Value, Width);\r
     }\r
 \r
-    CopyMem (Block + Offset, Value, Width);\r
-    *BlockSize = Offset + Width - 1;\r
+    if (Offset + Width > MaxBlockSize) {\r
+      MaxBlockSize = Offset + Width;\r
+    }\r
 \r
-    SafeFreePool (Value);\r
+    FreePool (Value);\r
     Value = NULL;\r
 \r
     //\r
-    // If '\0', parsing is finished. Otherwise skip '&' to continue\r
+    // If '\0', parsing is finished.\r
     //\r
     if (*StringPtr == 0) {\r
       break;\r
     }\r
-\r
-    StringPtr++;\r
   }\r
 \r
+  //\r
+  // The input string is not ConfigResp format, return error.\r
+  //\r
   if (*StringPtr != 0) {\r
-    *Progress = StringPtr - 1;\r
-    Status = EFI_INVALID_PARAMETER;\r
+    *Progress = StringPtr;\r
+    Status    = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
 \r
-  *Progress = StringPtr;\r
+  *Progress  = StringPtr + StrLen (StringPtr);\r
+  *BlockSize = MaxBlockSize - 1;\r
+\r
+  if (MaxBlockSize > BufferSize) {\r
+    *BlockSize = MaxBlockSize;\r
+    if (Block != NULL) {\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+  }\r
+\r
+  if (Block == NULL) {\r
+    *Progress = ConfigResp;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
 \r
-  SafeFreePool (Value);\r
+  if (Value != NULL) {\r
+    FreePool (Value);\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This helper function is to be called by drivers to extract portions of\r
   a larger configuration string.\r
@@ -1903,7 +6213,7 @@ Exit:
   @param  AltCfgResp             A pointer to a buffer which will be allocated by\r
                                  the  function which contains the retrieved string\r
                                  as requested.   This buffer is only allocated if\r
-                                 the call was successful.\r
+                                 the call was successful. It is <ConfigResp> format.\r
 \r
   @retval EFI_SUCCESS            The request succeeded. The requested data was\r
                                  extracted  and placed in the newly allocated\r
@@ -1917,33 +6227,42 @@ Exit:
 EFI_STATUS\r
 EFIAPI\r
 HiiGetAltCfg (\r
-  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL    *This,\r
-  IN  CONST EFI_STRING                         Configuration,\r
-  IN  CONST EFI_GUID                           *Guid,\r
-  IN  CONST EFI_STRING                         Name,\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL           *DevicePath,\r
-  IN  CONST UINT16                             *AltCfgId,\r
-  OUT EFI_STRING                               *AltCfgResp\r
+  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  IN  CONST EFI_GUID                         *Guid,\r
+  IN  CONST EFI_STRING                       Name,\r
+  IN  CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath,\r
+  IN  CONST UINT16                           *AltCfgId,\r
+  OUT EFI_STRING                             *AltCfgResp\r
   )\r
 {\r
-#ifndef DISABLE_UNUSED_HII_PROTOCOLS\r
-\r
-  EFI_STATUS                          Status;\r
-  EFI_STRING                          StringPtr;\r
-  EFI_STRING                          HdrStart = NULL;\r
-  EFI_STRING                          HdrEnd   = NULL;\r
-  EFI_STRING                          TmpPtr;\r
-  UINTN                               Length;\r
-  EFI_STRING                          GuidStr  = NULL;\r
-  EFI_STRING                          NameStr  = NULL;\r
-  EFI_STRING                          PathStr  = NULL;\r
-  EFI_STRING                          AltIdStr = NULL;\r
-  EFI_STRING                          Result   = NULL;\r
-  BOOLEAN                             GuidFlag = FALSE;\r
-  BOOLEAN                             NameFlag = FALSE;\r
-  BOOLEAN                             PathFlag = FALSE;\r
-\r
-  if (This == NULL || Configuration == NULL || AltCfgResp == NULL) {\r
+  EFI_STATUS  Status;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  HdrStart;\r
+  EFI_STRING  HdrEnd;\r
+  EFI_STRING  TmpPtr;\r
+  UINTN       Length;\r
+  EFI_STRING  GuidStr;\r
+  EFI_STRING  NameStr;\r
+  EFI_STRING  PathStr;\r
+  EFI_STRING  AltIdStr;\r
+  EFI_STRING  Result;\r
+  BOOLEAN     GuidFlag;\r
+  BOOLEAN     NameFlag;\r
+  BOOLEAN     PathFlag;\r
+\r
+  HdrStart = NULL;\r
+  HdrEnd   = NULL;\r
+  GuidStr  = NULL;\r
+  NameStr  = NULL;\r
+  PathStr  = NULL;\r
+  AltIdStr = NULL;\r
+  Result   = NULL;\r
+  GuidFlag = FALSE;\r
+  NameFlag = FALSE;\r
+  PathFlag = FALSE;\r
+\r
+  if ((This == NULL) || (Configuration == NULL) || (AltCfgResp == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1955,30 +6274,22 @@ HiiGetAltCfg (
   //\r
   // Generate the sub string for later matching.\r
   //\r
-  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (UINT8 *) Guid, FALSE, &GuidStr);\r
+  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)Guid, 1, &GuidStr);\r
   GenerateSubStr (\r
     L"PATH=",\r
-    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath),\r
-    (UINT8 *) DevicePath,\r
-    TRUE,\r
+    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)DevicePath),\r
+    (VOID *)DevicePath,\r
+    1,\r
     &PathStr\r
     );\r
   if (AltCfgId != NULL) {\r
-    GenerateSubStr (L"ALTCFG=", sizeof (UINT16), (UINT8 *) AltCfgId, FALSE, &AltIdStr);\r
+    GenerateSubStr (L"ALTCFG=", sizeof (UINT16), (VOID *)AltCfgId, 3, &AltIdStr);\r
   }\r
+\r
   if (Name != NULL) {\r
-    Length  = StrLen (Name);\r
-    Length  += StrLen (L"NAME=&") + 1;\r
-    NameStr = AllocateZeroPool (Length * sizeof (CHAR16));\r
-    if (NameStr == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Exit;\r
-    }\r
-    StrCpy (NameStr, L"NAME=");\r
-    StrCat (NameStr, Name);\r
-    StrCat (NameStr, L"&");\r
+    GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *)Name, 2, &NameStr);\r
   } else {\r
-    GenerateSubStr (L"NAME=", 0, NULL, FALSE, &NameStr);\r
+    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
   }\r
 \r
   while (*StringPtr != 0) {\r
@@ -1991,6 +6302,7 @@ HiiGetAltCfg (
         Status = EFI_NOT_FOUND;\r
         goto Exit;\r
       }\r
+\r
       HdrStart = TmpPtr;\r
 \r
       //\r
@@ -2005,6 +6317,7 @@ HiiGetAltCfg (
           goto Exit;\r
         }\r
       }\r
+\r
       GuidFlag = TRUE;\r
     }\r
 \r
@@ -2027,6 +6340,7 @@ HiiGetAltCfg (
             goto Exit;\r
           }\r
         }\r
+\r
         NameFlag = TRUE;\r
       }\r
     }\r
@@ -2050,9 +6364,12 @@ HiiGetAltCfg (
             Status = EFI_NOT_FOUND;\r
             goto Exit;\r
           }\r
+\r
+          StringPtr++;\r
         }\r
+\r
         PathFlag = TRUE;\r
-        HdrEnd   = ++StringPtr;\r
+        HdrEnd   = StringPtr;\r
       }\r
     }\r
 \r
@@ -2067,6 +6384,7 @@ HiiGetAltCfg (
         Status = OutputConfigBody (StringPtr, &Result);\r
         goto Exit;\r
       }\r
+\r
       //\r
       // Search the <ConfigAltResp> to get the <AltResp> with AltCfgId.\r
       //\r
@@ -2075,7 +6393,11 @@ HiiGetAltCfg (
         NameFlag = FALSE;\r
         PathFlag = FALSE;\r
       } else {\r
-        Status = OutputConfigBody (StringPtr, &Result);\r
+        //\r
+        // Skip AltIdStr and &\r
+        //\r
+        StringPtr = StringPtr + StrLen (AltIdStr);\r
+        Status    = OutputConfigBody (StringPtr, &Result);\r
         goto Exit;\r
       }\r
     }\r
@@ -2084,33 +6406,41 @@ HiiGetAltCfg (
   Status = EFI_NOT_FOUND;\r
 \r
 Exit:\r
-\r
-  if (!EFI_ERROR (Status)) {\r
+  *AltCfgResp = NULL;\r
+  if (!EFI_ERROR (Status) && (Result != NULL)) {\r
     //\r
     // Copy the <ConfigHdr> and <ConfigBody>\r
     //\r
-    Length = HdrEnd - HdrStart + StrLen (Result);\r
+    Length      = HdrEnd - HdrStart + StrLen (Result) + 1;\r
     *AltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
     if (*AltCfgResp == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
     } else {\r
-      StrnCpy (*AltCfgResp, HdrStart, HdrEnd - HdrStart);\r
-      StrCat (*AltCfgResp, Result);\r
+      StrnCpyS (*AltCfgResp, Length, HdrStart, HdrEnd - HdrStart);\r
+      StrCatS (*AltCfgResp, Length, Result);\r
       Status = EFI_SUCCESS;\r
     }\r
   }\r
 \r
-  SafeFreePool (GuidStr);\r
-  SafeFreePool (NameStr);\r
-  SafeFreePool (PathStr);\r
-  SafeFreePool (AltIdStr);\r
-  SafeFreePool (Result);\r
+  if (GuidStr != NULL) {\r
+    FreePool (GuidStr);\r
+  }\r
 \r
-  return Status;\r
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
 \r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
+  if (PathStr != NULL) {\r
+    FreePool (PathStr);\r
+  }\r
 \r
-}\r
+  if (AltIdStr != NULL) {\r
+    FreePool (AltIdStr);\r
+  }\r
 \r
+  if (Result != NULL) {\r
+    FreePool (Result);\r
+  }\r
+\r
+  return Status;\r
+}\r