]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
Roll back changes to apply GetBestLanguage() in HiiDataBase. Exact language match...
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigRouting.c
index 3f35ed9005e27405399beb58e09ae6da29bdc13e..d5ef60b7f5ed3eb223d96c60123df4b3bb319351 100644 (file)
@@ -1,4 +1,5 @@
 /** @file\r
+Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
 \r
 Copyright (c) 2007 - 2008, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
@@ -9,224 +10,30 @@ http://opensource.org/licenses/bsd-license.php
 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
-\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; 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
-    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
   )\r
 {\r
-  UINTN Length;\r
+  EFI_STRING  TmpPtr;\r
 \r
   //\r
   // "GUID=" should be the first element of incoming string.\r
@@ -234,19 +41,16 @@ 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
+  // \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
@@ -254,27 +58,34 @@ CalculateConfigStringLen (
   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_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
+  OUT UINT8                        **DevicePathData\r
   )\r
 {\r
-  UINTN      Length;\r
-  EFI_STRING PathHdr;\r
-  EFI_STRING DevicePathString;\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
 \r
-  if (String == NULL || DevicePath == NULL) {\r
+  if (String == NULL || DevicePathData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -285,8 +96,13 @@ GetDevicePath (
   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
   PathHdr = String;\r
 \r
   //\r
@@ -295,238 +111,131 @@ GetDevicePath (
   // 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
+  //\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
   //\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
+  //\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
+  // 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
+      // Invalid device path\r
+      //\r
+      FreePool (DevicePathBuffer);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+    DevicePath = NextDevicePathNode (DevicePath);\r
+  }\r
 \r
-  HexStringToBufPrivate (*DevicePath, &Length, DevicePathString, NULL);\r
-\r
-  SafeFreePool (DevicePathString);\r
-\r
+  //\r
+  // return the device path\r
+  //\r
+  *DevicePathData = DevicePathBuffer;\r
   return EFI_SUCCESS;\r
-\r
 }\r
 \r
-\r
 /**\r
-  Extract Storage from all Form Packages in current hii database.\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\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
+  @param Str     String to be converted\r
 \r
 **/\r
-STATIC\r
-EFI_STATUS\r
-ExportAllStorage (\r
-  IN EFI_HII_DATABASE_PROTOCOL     *HiiDatabase,\r
-  IN OUT LIST_ENTRY                *StorageListHead\r
-)\r
+VOID\r
+EFIAPI\r
+HiiToLower (\r
+  IN EFI_STRING  ConfigString\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
+  EFI_STRING  String;\r
+  BOOLEAN     Lower;\r
 \r
-  HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    HiiHandle = HandleBuffer[Index];\r
+  ASSERT (ConfigString != NULL);\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
-    }\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
-      // Error here: No Form package found in this Package List\r
-      //\r
-      ASSERT (FALSE);\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
-\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
-        if (Operand == EFI_IFR_VARSTORE_OP) {\r
-          Storage->Type = EFI_HII_VARSTORE_BUFFER;\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
-\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
-          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
-\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
+  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
@@ -535,24 +244,61 @@ GenerateSubStr (
     ASSERT (*SubStr != NULL);\r
     return ;\r
   }\r
-\r
-  Length = BufferLen * 2 + 1 + StrLen (String) + 1;\r
-  Str = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  \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
 \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
+      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\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
+      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
+    }\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
+      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+    }\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
 \r
-  ASSERT_EFI_ERROR (Status);\r
-  StrCat (Str, L"&");\r
+  //\r
+  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.\r
+  //\r
+  StrCat (Str, L"&");  \r
+  HiiToLower (Str);\r
 \r
   *SubStr = Str;\r
 }\r
@@ -561,6 +307,8 @@ GenerateSubStr (
 /**\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,7 +319,6 @@ GenerateSubStr (
   @retval EFI_SUCCESS            All existing storage is exported.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 OutputConfigBody (\r
   IN  EFI_STRING                   String,\r
@@ -585,6 +332,13 @@ OutputConfigBody (
   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
   TmpPtr = StrStr (String, L"GUID=");\r
   if (TmpPtr == NULL) {\r
@@ -609,55 +363,13 @@ OutputConfigBody (
   *(Result + Length - 1) = 0;\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,7 +381,6 @@ 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
@@ -692,12 +403,12 @@ AppendToMultiString (
   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
+                                  MultiStringSize + AppendStringSize,\r
+                                  (VOID *) (*MultiString)\r
                                   );\r
+    ASSERT (*MultiString != NULL);\r
   }\r
-\r
   //\r
   // Append the incoming string\r
   //\r
@@ -712,6 +423,8 @@ AppendToMultiString (
   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
@@ -724,7 +437,6 @@ AppendToMultiString (
                                  successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetValueOfNumber (\r
   IN EFI_STRING                    StringPtr,\r
@@ -737,48 +449,1744 @@ GetValueOfNumber (
   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
+  ASSERT (*StringPtr != L'\0');\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
-  *Len   = StringPtr - TmpPtr;\r
-  Length = *Len + 1;\r
+  *Len   = StringPtr - TmpPtr;\r
+  Length = *Len + 1;\r
+\r
+  Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (Str == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+  CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
+  *(Str + *Len) = L'\0';\r
+\r
+  Length = (Length + 1) / 2;\r
+  Buf = (UINT8 *) AllocateZeroPool (Length);\r
+  if (Buf == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+  \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
+  if (Str != NULL) {\r
+    FreePool (Str);\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
+  \r
+  if (*AltCfgResp == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  //\r
+  // Get the requestr 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
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+  if (*StringPtr == L'\0') {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  StringPtr += StrLen (L"&PATH=");\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr ++;\r
+  }\r
+  HeaderLength = StringPtr - *AltCfgResp;\r
+\r
+  //\r
+  // Construct AltConfigHdr string  "&<ConfigHdr>&ALTCFG=XXXX\0"\r
+  //                                  |1| StrLen (ConfigHdr) | 8 | 4 | 1 |\r
+  //\r
+  AltConfigHdr = AllocateZeroPool ((1 + HeaderLength + 8 + 4 + 1) * sizeof (CHAR16));\r
+  if (AltConfigHdr == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  StrCpy (AltConfigHdr, L"&");\r
+  StrnCat (AltConfigHdr, *AltCfgResp, HeaderLength);\r
+  StrCat (AltConfigHdr, L"&ALTCFG=");\r
+  HeaderLength = StrLen (AltConfigHdr);\r
+  \r
+  StringPtrDefault = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+  while (StringPtrDefault != NULL) {\r
+    //\r
+    // Get AltCfg Name\r
+    //\r
+    StrnCat (AltConfigHdr, 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
+        *AltCfgResp    = (EFI_STRING) ReallocatePool (\r
+                                     SizeAltCfgResp,\r
+                                     SizeAltCfgResp + StrSize (StringPtrDefault),\r
+                                     (VOID *) (*AltCfgResp)\r
+                                     );\r
+        if (*AltCfgResp == NULL) {\r
+          FreePool (AltConfigHdr);\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        StrCat (*AltCfgResp, StringPtrDefault);\r
+        break;\r
+      } else {\r
+        TempChar = *StringPtrEnd;\r
+        *StringPtrEnd = L'\0';\r
+        *AltCfgResp = (EFI_STRING) ReallocatePool (\r
+                                     SizeAltCfgResp,\r
+                                     SizeAltCfgResp + StrSize (StringPtrDefault),\r
+                                     (VOID *) (*AltCfgResp)\r
+                                     );\r
+        if (*AltCfgResp == NULL) {\r
+          FreePool (AltConfigHdr);\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        StrCat (*AltCfgResp, StringPtrDefault);\r
+        *StringPtrEnd = TempChar;\r
+      }\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 finds the matched DefaultName for the input DefaultId\r
+\r
+  @param  DefaultIdArray    Array stores the map table between DefaultId and DefaultName.\r
+  @param  VarDefaultId      Default Id\r
+  @param  VarDefaultName    Default Name string ID for the input default ID.\r
+  \r
+  @retval EFI_SUCCESS       The mapped default name string ID is found.\r
+  @retval EFI_NOT_FOUND     The mapped default name string ID is not found.\r
+**/\r
+EFI_STATUS\r
+FindDefaultName (\r
+  IN  IFR_DEFAULT_DATA *DefaultIdArray, \r
+  IN  UINT16           VarDefaultId, \r
+  OUT EFI_STRING_ID    *VarDefaultName\r
+  )\r
+{\r
+  LIST_ENTRY        *Link;\r
+  IFR_DEFAULT_DATA  *DefaultData;\r
+\r
+  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+    DefaultData = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    if (DefaultData->DefaultId == VarDefaultId) {\r
+      *VarDefaultName = DefaultData->DefaultName;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\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
+\r
+  for (Link = BlockData->DefaultValueEntry.ForwardLink; Link != &BlockData->DefaultValueEntry; Link = Link->ForwardLink) {\r
+    DefaultValueArray = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {\r
+      if (DefaultValueData->OpCode == EFI_IFR_DEFAULT_OP) {\r
+        //\r
+        // Update the default value array in BlockData.\r
+        //\r
+        DefaultValueArray->Value = DefaultValueData->Value;\r
+      } else if (DefaultValueArray->OpCode != EFI_IFR_DEFAULT_OP) {\r
+        //\r
+        // Update the default value array in BlockData.\r
+        //\r
+        DefaultValueArray->Value = DefaultValueData->Value;\r
+      }\r
+      FreePool (DefaultValueData);\r
+      return;\r
+    } else if (DefaultValueArray->DefaultId > DefaultValueData->DefaultId) {\r
+      //\r
+      // Insert new default value data in the front of this default value array.\r
+      //\r
+      InsertTailList (Link, &DefaultValueData->Entry);\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Insert new default value data in tail.\r
+  //\r
+  InsertTailList (Link, &DefaultValueData->Entry);\r
+  return;\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
+  //\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) {\r
+        //\r
+        // Insert this block data in the front of block array\r
+        //\r
+        InsertTailList (Link, &BlockSingleData->Entry);\r
+        return;\r
+      }\r
+\r
+      if (BlockArray->Width == BlockSingleData->Width) {\r
+        //\r
+        // The same block array has been added.\r
+        //\r
+        FreePool (BlockSingleData);\r
+        *BlockData = BlockArray;\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
+  return;  \r
+}\r
+\r
+/**\r
+  This function checks VarOffset and VarWidth is in the block range.\r
+\r
+  @param  BlockArray         The block array is to be checked. \r
+  @param  VarOffset          Offset of var to the structure\r
+  @param  VarWidth           Width of var.\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
+  )\r
+{\r
+  LIST_ENTRY          *Link;\r
+  IFR_BLOCK_DATA      *BlockData;\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
+    if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\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  Package               Pointer to the form package data.\r
+  @param  PackageLength         Length of the pacakge.\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  PIfrDefaultIdArray    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 defintion in the differnt form pacakges\r
+                                are conflicted. \r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ParseIfrData (\r
+  IN     UINT8               *Package,\r
+  IN     UINT32              PackageLenth,\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
+  EFI_IFR_VARSTORE         *IfrVarStore;\r
+  EFI_IFR_OP_HEADER        *IfrOpHdr;\r
+  EFI_IFR_ONE_OF           *IfrOneOf;\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
+  IFR_DEFAULT_DATA         *DefaultData;\r
+  IFR_BLOCK_DATA           *BlockData;\r
+  CHAR16                   *VarStoreName;\r
+  UINT16                   VarOffset;\r
+  UINT16                   VarWidth;\r
+  EFI_STRING_ID            VarDefaultName;\r
+  UINT16                   VarDefaultId;\r
+  EFI_STRING               GuidStr;\r
+  EFI_STRING               NameStr;\r
+  EFI_STRING               TempStr;\r
+  UINTN                    LengthString;\r
+\r
+  LengthString     = 0;\r
+  Status           = EFI_SUCCESS;\r
+  GuidStr          = NULL;\r
+  NameStr          = NULL;\r
+  TempStr          = NULL;\r
+  BlockData        = NULL;\r
+  DefaultData      = NULL;\r
+\r
+  //\r
+  // Go through the form package to parse OpCode one by one.\r
+  //\r
+  IfrOffset   = sizeof (EFI_HII_PACKAGE_HEADER);\r
+  while (IfrOffset < PackageLenth) {\r
+    IfrOpHdr  = (EFI_IFR_OP_HEADER *) (Package + IfrOffset);\r
+\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 (VarStorageData->Size != 0) {\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Get the requied varstore information\r
+      // Add varstore by Guid and Name in ConfigHdr\r
+      // Make sure Offset is in varstore size and varstoreid\r
+      //\r
+      IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
+      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));\r
+      if (VarStoreName == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      AsciiStrToUnicodeStr ((CHAR8 *) IfrVarStore->Name, VarStoreName);\r
+\r
+      GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrVarStore->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
+      StrCpy (TempStr, GuidStr);\r
+      StrCat (TempStr, NameStr);\r
+      if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+        //\r
+        // Find the matched VarStore\r
+        //\r
+        CopyGuid (&VarStorageData->Guid, (EFI_GUID *) (VOID *) &IfrVarStore->Guid);\r
+        VarStorageData->VarStoreId = IfrVarStore->VarStoreId;\r
+        VarStorageData->Size       = IfrVarStore->Size;\r
+        VarStorageData->Name       = VarStoreName;\r
+      } else {\r
+        //\r
+        // No found, free the allocated memory \r
+        //\r
+        FreePool (VarStoreName);\r
+      }\r
+      //\r
+      // Free alllocated temp string.\r
+      //\r
+      FreePool (GuidStr);\r
+      FreePool (NameStr);\r
+      FreePool (TempStr);\r
+      break;\r
+\r
+    case EFI_IFR_DEFAULTSTORE_OP:\r
+      //\r
+      // Add new the map between default id and default name.\r
+      //\r
+      DefaultData = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+      if (DefaultData == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      DefaultData->DefaultId   = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId;\r
+      DefaultData->DefaultName = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultName;\r
+      InsertTailList (&DefaultIdArray->Entry, &DefaultData->Entry);\r
+      DefaultData = NULL;\r
+      break;\r
+\r
+    case EFI_IFR_FORM_OP:\r
+      //\r
+      // No matched varstore is found and directly return.\r
+      //\r
+      if (VarStorageData->Size == 0) {\r
+        Status = EFI_SUCCESS;\r
+        goto Done;\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 (VarStorageData->Size == 0) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\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 != VarStorageData->VarStoreId) {\r
+        break;\r
+      }\r
+      \r
+      //\r
+      // Get Offset/Width by Question header and OneOf Flags\r
+      //\r
+      VarOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+      VarWidth  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+      //\r
+      // Check whether this question is in requested block array.\r
+      //\r
+      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+        //\r
+        // This question is not in the requested string. Skip it.\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Check this var question is in the var storage \r
+      //\r
+      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
+        Status = EFI_INVALID_PARAMETER;\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
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      BlockData->Offset     = VarOffset;\r
+      BlockData->Width      = VarWidth;\r
+      BlockData->QuestionId = IfrOneOf->Question.QuestionId;\r
+      BlockData->OpCode     = IfrOpHdr->OpCode;\r
+      BlockData->Scope      = IfrOpHdr->Scope;\r
+      InitializeListHead (&BlockData->DefaultValueEntry);\r
+      //\r
+      // Add Block Data into VarStorageData BlockEntry\r
+      //\r
+      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\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
+      // no default value and default id, how to define its default value?\r
+      //\r
+\r
+      //\r
+      // OrderedList question is not in IFR Form. This IFR form is not valid. \r
+      //\r
+      if (VarStorageData->Size == 0) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\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 != VarStorageData->VarStoreId) {\r
+        break;\r
+      }\r
+      \r
+      //\r
+      // Get Offset/Width by Question header and OneOf Flags\r
+      //\r
+      VarOffset = IfrOrderedList->Question.VarStoreInfo.VarOffset;\r
+      VarWidth  = IfrOrderedList->MaxContainers;\r
+\r
+      //\r
+      // Check whether this question is in requested block array.\r
+      //\r
+      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+        //\r
+        // This question is not in the requested string. Skip it.\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Check this var question is in the var storage \r
+      //\r
+      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
+        Status = EFI_INVALID_PARAMETER;\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
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      BlockData->Offset     = VarOffset;\r
+      BlockData->Width      = VarWidth;\r
+      BlockData->QuestionId = IfrOrderedList->Question.QuestionId;\r
+      BlockData->OpCode     = IfrOpHdr->OpCode;\r
+      BlockData->Scope      = IfrOpHdr->Scope;\r
+      InitializeListHead (&BlockData->DefaultValueEntry);\r
+      \r
+      //\r
+      // Add Block Data into VarStorageData BlockEntry\r
+      //\r
+      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\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 (VarStorageData->Size == 0) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+      //\r
+      // Check whether this question is for the requested varstore.\r
+      //\r
+      IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpHdr;\r
+      if (IfrCheckBox->Question.VarStoreId != VarStorageData->VarStoreId) {\r
+        break;\r
+      }\r
+      \r
+      //\r
+      // Get Offset/Width by Question header and OneOf Flags\r
+      //\r
+      VarOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+      VarWidth  = sizeof (BOOLEAN);\r
+\r
+      //\r
+      // Check whether this question is in requested block array.\r
+      //\r
+      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+        //\r
+        // This question is not in the requested string. Skip it.\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Check this var question is in the var storage \r
+      //\r
+      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
+        Status = EFI_INVALID_PARAMETER;\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
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      BlockData->Offset     = VarOffset;\r
+      BlockData->Width      = VarWidth;\r
+      BlockData->QuestionId = IfrCheckBox->Question.QuestionId;\r
+      BlockData->OpCode     = IfrOpHdr->OpCode;\r
+      BlockData->Scope      = IfrOpHdr->Scope;\r
+      InitializeListHead (&BlockData->DefaultValueEntry);\r
+      //\r
+      // Add Block Data into VarStorageData BlockEntry\r
+      //\r
+      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+      \r
+      //\r
+      // Add default value by CheckBox Flags \r
+      //\r
+      if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {\r
+        //\r
+        // Set standard ID to Manufacture ID and Get DefaultName String ID\r
+        //\r
+        VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+        Status       = FindDefaultName (DefaultIdArray, VarDefaultId, &VarDefaultName);\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+        if (DefaultData == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+        DefaultData->OpCode      = IfrOpHdr->OpCode;\r
+        DefaultData->DefaultId   = VarDefaultId;\r
+        DefaultData->DefaultName = VarDefaultName;\r
+        DefaultData->Value       = 1;\r
+        //\r
+        // Add DefaultValue into current BlockData\r
+        //\r
+        InsertDefaultValue (BlockData, DefaultData);\r
+      }\r
+\r
+      if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {\r
+        //\r
+        // Set standard ID to Manufacture ID and Get DefaultName String ID\r
+        //\r
+        VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+        Status       = FindDefaultName (DefaultIdArray, VarDefaultId, &VarDefaultName);\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+        if (DefaultData == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+        DefaultData->OpCode      = IfrOpHdr->OpCode;\r
+        DefaultData->DefaultId   = VarDefaultId;\r
+        DefaultData->DefaultName = VarDefaultName;\r
+        DefaultData->Value       = 1;\r
+        //\r
+        // Add DefaultValue into current BlockData\r
+        //\r
+        InsertDefaultValue (BlockData, DefaultData);\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 (VarStorageData->Size == 0) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+      //\r
+      // Check whether this question is for the requested varstore.\r
+      //\r
+      IfrString = (EFI_IFR_STRING *) IfrOpHdr;\r
+      if (IfrString->Question.VarStoreId != VarStorageData->VarStoreId) {\r
+        break;\r
+      }\r
+      \r
+      //\r
+      // Get Offset/Width by Question header and OneOf Flags\r
+      //\r
+      VarOffset = IfrString->Question.VarStoreInfo.VarOffset;\r
+      VarWidth  = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
+\r
+      //\r
+      // Check whether this question is in requested block array.\r
+      //\r
+      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+        //\r
+        // This question is not in the requested string. Skip it.\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Check this var question is in the var storage \r
+      //\r
+      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
+        Status = EFI_INVALID_PARAMETER;\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
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      BlockData->Offset     = VarOffset;\r
+      BlockData->Width      = VarWidth;\r
+      BlockData->QuestionId = IfrString->Question.QuestionId;\r
+      BlockData->OpCode     = IfrOpHdr->OpCode;\r
+      InitializeListHead (&BlockData->DefaultValueEntry);\r
+      \r
+      //\r
+      // Add Block Data into VarStorageData BlockEntry\r
+      //\r
+      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+      \r
+      //\r
+      // No default value for string.\r
+      //\r
+      BlockData = NULL;\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 (VarStorageData->Size == 0) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+      //\r
+      // Check whether this question is for the requested varstore.\r
+      //\r
+      IfrPassword = (EFI_IFR_PASSWORD *) IfrOpHdr;\r
+      if (IfrPassword->Question.VarStoreId != VarStorageData->VarStoreId) {\r
+        break;\r
+      }\r
+      \r
+      //\r
+      // Get Offset/Width by Question header and OneOf Flags\r
+      //\r
+      VarOffset = IfrPassword->Question.VarStoreInfo.VarOffset;\r
+      VarWidth  = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));\r
+\r
+      //\r
+      // Check whether this question is in requested block array.\r
+      //\r
+      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+        //\r
+        // This question is not in the requested string. Skip it.\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Check this var question is in the var storage \r
+      //\r
+      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
+        Status = EFI_INVALID_PARAMETER;\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
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      BlockData->Offset     = VarOffset;\r
+      BlockData->Width      = VarWidth;\r
+      BlockData->QuestionId = IfrPassword->Question.QuestionId;\r
+      BlockData->OpCode     = IfrOpHdr->OpCode;\r
+      InitializeListHead (&BlockData->DefaultValueEntry);\r
+      \r
+      //\r
+      // Add Block Data into VarStorageData BlockEntry\r
+      //\r
+      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\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
+        //\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
+          goto Done;\r
+        }\r
+        //\r
+        // Calculate Ordered list QuestionId width.\r
+        //\r
+        BlockData->Width = (UINT16) (BlockData->Width * VarWidth);\r
+        BlockData = NULL;\r
+        break;\r
+      }\r
+\r
+      if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {\r
+        //\r
+        // Set standard ID to Manufacture ID and Get DefaultName String ID\r
+        //\r
+        VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+        Status       = FindDefaultName (DefaultIdArray, VarDefaultId, &VarDefaultName);\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+        if (DefaultData == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+        DefaultData->OpCode      = IfrOpHdr->OpCode;\r
+        DefaultData->DefaultId   = VarDefaultId;\r
+        DefaultData->DefaultName = VarDefaultName;\r
+        DefaultData->Value       = IfrOneOfOption->Value.u64;\r
+        //\r
+        // Add DefaultValue into current BlockData\r
+        //\r
+        InsertDefaultValue (BlockData, DefaultData);\r
+      }\r
+\r
+      if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {\r
+        //\r
+        // Set default ID to Manufacture ID and Get DefaultName String ID\r
+        //\r
+        VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+        Status       = FindDefaultName (DefaultIdArray, VarDefaultId, &VarDefaultName);\r
+        if (EFI_ERROR (Status)) {\r
+          goto Done;\r
+        }\r
+        //\r
+        // Prepare new DefaultValue\r
+        //\r
+        DefaultData = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+        if (DefaultData == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Done;\r
+        }\r
+        DefaultData->OpCode      = IfrOpHdr->OpCode;\r
+        DefaultData->DefaultId   = VarDefaultId;\r
+        DefaultData->DefaultName = VarDefaultName;\r
+        DefaultData->Value       = IfrOneOfOption->Value.u64;\r
+        //\r
+        // Add DefaultValue into current BlockData\r
+        //\r
+        InsertDefaultValue (BlockData, DefaultData);\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
+      if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+        //\r
+        // OrderedList Opcode is no default value.\r
+        //\r
+        break;\r
+      }\r
+      //\r
+      // Get the DefaultId and DefaultName String ID\r
+      //\r
+      IfrDefault     = (EFI_IFR_DEFAULT *) IfrOpHdr;\r
+      VarDefaultId   = IfrDefault->DefaultId;\r
+      Status       = FindDefaultName (DefaultIdArray, VarDefaultId, &VarDefaultName);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+      //\r
+      // Prepare new DefaultValue\r
+      //\r
+      DefaultData = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+      if (DefaultData == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      DefaultData->OpCode      = IfrOpHdr->OpCode;\r
+      DefaultData->DefaultId   = VarDefaultId;\r
+      DefaultData->DefaultName = VarDefaultName;\r
+      DefaultData->Value       = IfrDefault->Value.u64;\r
+      //\r
+      // Add DefaultValue into current BlockData\r
+      //\r
+      InsertDefaultValue (BlockData, DefaultData);\r
+      break;\r
+    case EFI_IFR_END_OP:\r
+      //\r
+      // End Opcode is for Var question.\r
+      //\r
+      if (BlockData != NULL && BlockData->Scope > 0) {\r
+        BlockData->Scope--;\r
+      }\r
+      break;\r
+    default:\r
+      if (BlockData != NULL && BlockData->Scope > 0) {\r
+        BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);\r
+      }\r
+      break;\r
+    }\r
+\r
+    IfrOffset += IfrOpHdr->Length;\r
+  }\r
+\r
+Done:\r
+  return Status;  \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 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
+  UINTN                        ResultSize;\r
+  IFR_BLOCK_DATA               *RequestBlockArray;\r
+  IFR_BLOCK_DATA               *BlockData;\r
+  IFR_BLOCK_DATA               *NextBlockData;\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                   FullConfigRequest;\r
+  EFI_STRING                   ConfigHdr;\r
+  EFI_STRING                   GuidStr;\r
+  EFI_STRING                   NameStr;\r
+  EFI_STRING                   PathStr;\r
+  EFI_STRING                   StringPtr;\r
+  EFI_STRING                   Progress;\r
+  UINTN                        Length;\r
+  UINT8                        *TmpBuffer;\r
+  UINT16                       Offset;\r
+  UINT16                       Width;\r
+  LIST_ENTRY                   *Link;\r
+  LIST_ENTRY                   *LinkData;\r
+  LIST_ENTRY                   *LinkDefault;\r
+  BOOLEAN                      DataExist;\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
+  FullConfigRequest = NULL;\r
+  ConfigHdr         = NULL;\r
+  GuidStr           = NULL;\r
+  NameStr           = NULL;\r
+  PathStr           = NULL;\r
+  HiiFormPackage    = NULL;\r
+  ResultSize        = 0;\r
+  PackageSize       = 0;\r
+  DataExist         = FALSE;\r
+  Progress          = *Request;\r
\r
+  //\r
+  // 0. Get Hii Form Package by HiiHandle\r
+  //\r
+  Status = ExportFormPackages (\r
+             &mPrivate, \r
+             DataBaseRecord->Handle, \r
+             DataBaseRecord->PackageList, \r
+             0, \r
+             PackageSize, \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
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Get HiiFormPackage by HiiHandle\r
+  //\r
+  PackageSize   = ResultSize;\r
+  ResultSize    = 0;\r
+  Status = ExportFormPackages (\r
+             &mPrivate, \r
+             DataBaseRecord->Handle, \r
+             DataBaseRecord->PackageList, \r
+             0,\r
+             PackageSize, \r
+             HiiFormPackage,\r
+             &ResultSize\r
+           );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // 1. Get the request block array by Request String when Request string containts 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
+    StringPtr += StrLen (L"GUID=");\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+    if (*StringPtr == L'\0') {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+    StringPtr += StrLen (L"&NAME=");\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+    if (*StringPtr == L'\0') {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+    StringPtr += StrLen (L"&PATH=");\r
+    while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+      StringPtr ++;\r
+    }\r
+    //\r
+    // Check the following string &OFFSET=\r
+    //\r
+    if (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+      Progress = StringPtr;\r
+      Status   = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    } else if (*StringPtr == L'\0') {\r
+      //\r
+      // No request block is found.\r
+      //\r
+      StringPtr = NULL;\r
+    }\r
+  }\r
+  if (StringPtr != NULL) {\r
+    //\r
+    // Init RequestBlockArray\r
+    //\r
+    RequestBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+    if (RequestBlockArray == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\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
+    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
+      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
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\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
+      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
+        Status = EFI_INVALID_PARAMETER;\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
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\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
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
+        }\r
+\r
+        StringPtr += Length;\r
+        if (*StringPtr != 0 && *StringPtr != L'&') {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\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
+        RemoveEntryList (Link->ForwardLink);\r
+        FreePool (NextBlockData);\r
+        continue;\r
+      }\r
+      Link = Link->ForwardLink;      \r
+    }\r
+  }\r
+  \r
+  //\r
+  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\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
+  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
+  InitializeListHead (&VarStorageData->Entry);\r
+  InitializeListHead (&VarStorageData->BlockEntry);\r
+\r
+  //\r
+  // Parse the opcode in form pacakge to get the default setting.\r
+  //\r
+  Status = ParseIfrData (HiiFormPackage, (UINT32) PackageSize, *Request, RequestBlockArray, VarStorageData, DefaultIdArray);\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->Size == 0) {\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
+\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
+  GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *) VarStorageData->Name, 2, &NameStr);\r
+  GenerateSubStr (\r
+    L"PATH=",\r
+    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath),\r
+    (VOID *) DevicePath,\r
+    1,\r
+    &PathStr\r
+    );\r
+  Length = StrLen (GuidStr);\r
+  Length = Length + StrLen (NameStr);\r
+  Length = Length + StrLen (PathStr) + 1;\r
+  ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (ConfigHdr == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;    \r
+  }\r
+  StrCpy (ConfigHdr, GuidStr);\r
+  StrCat (ConfigHdr, NameStr);\r
+  StrCat (ConfigHdr, PathStr);\r
+\r
+  //\r
+  // Remove the last character L'&'\r
+  //\r
+  *(ConfigHdr + StrLen (ConfigHdr) - 1) = L'\0';\r
+\r
+  if (RequestBlockArray == NULL) {\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
+      //\r
+      // Add <BlockName> length for each Offset/Width pair\r
+      //\r
+      // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
+      //                 |  8   | 4 |   7  | 4 |\r
+      //\r
+      DataExist = TRUE;\r
+      Length = Length + (8 + 4 + 7 + 4);\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
+      goto Done;\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
+      goto Done;\r
+    }\r
+    StringPtr = FullConfigRequest;\r
+  \r
+    //\r
+    // Start with <ConfigHdr>\r
+    //\r
+    StrCpy (StringPtr, 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
+      //\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
+      StringPtr += StrLen (StringPtr);\r
+    }\r
+    //\r
+    // Set to the got full request string.\r
+    //\r
+    HiiToLower (FullConfigRequest);\r
+    if (*Request != NULL) {\r
+      FreePool (*Request);\r
+    }\r
+    *Request = FullConfigRequest;\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
+  DataExist = FALSE;\r
+  //\r
+  // Add length for <ConfigHdr> + '\0'\r
+  //\r
+  Length = StrLen (ConfigHdr) + 1;\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
+      for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+        if (DefaultValueData->DefaultId == DefaultId->DefaultId) {\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
+          DataExist = TRUE;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  \r
+  //\r
+  // No default value is found. The default string doesn't exist.\r
+  //\r
+  if (!DataExist) {\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Allocate buffer for the entire <DefaultAltCfgResp>\r
+  //\r
+  DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (DefaultAltCfgResp == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+  StringPtr = DefaultAltCfgResp;\r
+\r
+  //\r
+  // Start with <ConfigHdr>\r
+  //\r
+  StrCpy (StringPtr, 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->DefaultName\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
+      for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+        if (DefaultValueData->DefaultId == DefaultId->DefaultId) {\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
+          // Convert Value to a hex string in "%x" format\r
+          // NOTE: This is in the opposite byte that GUID and PATH use\r
+          //\r
+          Width     = BlockData->Width;\r
+          TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
+          for (; Width > 0; Width--) {\r
+            StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+  HiiToLower (DefaultAltCfgResp);\r
+\r
+  //\r
+  // 5. Merge string into the input AltCfgResp if the iput *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
+      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
+      //\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
+      FreePool (BlockData);\r
+    }\r
+    FreePool (VarStorageData);\r
+  }\r
 \r
-  Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (EFI_STRING));\r
-  if (Str == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\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
+    FreePool (DefaultIdArray);\r
   }\r
-  CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
-  *(Str + *Len) = 0;\r
-\r
-  Length = (Length + 1) / 2;\r
-  Buf = (UINT8 *) AllocateZeroPool (Length);\r
-  if (Buf == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
+  \r
+  //\r
+  // Free the allocated string \r
+  //\r
+  if (GuidStr != NULL) {\r
+    FreePool (GuidStr);\r
+  }\r
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
+  if (PathStr != NULL) {\r
+    FreePool (PathStr);\r
+  }\r
+  if (ConfigHdr != NULL) {\r
+    FreePool (ConfigHdr);\r
   }\r
 \r
-  Status = HexStringToBuf (Buf, &Length, Str, NULL);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
+  //\r
+  // Free Pacakge data\r
+  //\r
+  if (HiiFormPackage != NULL) {\r
+    FreePool (HiiFormPackage);\r
   }\r
 \r
-  *Number = Buf;\r
-  Status  = EFI_SUCCESS;\r
+  if (PointerProgress != NULL) {\r
+    if (*Request == NULL) {\r
+      *PointerProgress = NULL;\r
+    } else if (EFI_ERROR (Status)) {\r
+      *PointerProgress = Progress;\r
+    } else {\r
+      *PointerProgress = *Request + StrLen (*Request);\r
+    }\r
+  }\r
 \r
-Exit:\r
-  SafeFreePool (Str);\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
@@ -827,23 +2235,25 @@ 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_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
-  UINTN                               RemainSize;\r
-  EFI_STRING                          TmpPtr;\r
+  EFI_STRING                          DefaultResults;\r
+  BOOLEAN                             FirstElement;\r
+  BOOLEAN                             IfrDataParsedFlag;\r
 \r
   if (This == NULL || Progress == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -857,6 +2267,12 @@ HiiConfigRoutingExtractConfig (
   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
+  DevicePath     = NULL;\r
+  IfrDataParsedFlag = FALSE;\r
 \r
   //\r
   // The first element of <MultiConfigRequest> should be\r
@@ -866,6 +2282,8 @@ 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
@@ -892,7 +2310,8 @@ HiiConfigRoutingExtractConfig (
     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
     *(ConfigRequest + Length) = 0;\r
 \r
@@ -901,42 +2320,80 @@ HiiConfigRoutingExtractConfig (
     //\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
+    DriverHandle     = NULL;\r
+    HiiHandle        = NULL;\r
+    Database         = NULL;\r
     for (Link = Private->DatabaseList.ForwardLink;\r
          Link != &Private->DatabaseList;\r
          Link = Link->ForwardLink\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 ((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
           DriverHandle = Database->DriverHandle;\r
+          HiiHandle    = Database->Handle;\r
           break;\r
         }\r
       }\r
     }\r
-\r
-    SafeFreePool (DevicePath);\r
-\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
+    // Check whether ConfigRequest contains request string OFFSET/WIDTH\r
+    //\r
+    IfrDataParsedFlag = FALSE;\r
+    if ((HiiHandle != NULL) && (StrStr (ConfigRequest, L"&OFFSET=") == NULL)) {\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
+        *Progress = StrStr (StringPtr, AccessProgress);\r
+        goto Done;\r
+      }\r
+      //\r
+      // Not any request block is found.\r
+      //\r
+      if (StrStr (ConfigRequest, L"&OFFSET=") == NULL) {\r
+        AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
+        goto NextConfigString;\r
+      }\r
     }\r
 \r
     //\r
@@ -960,23 +2417,48 @@ HiiConfigRoutingExtractConfig (
       // 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 seperates 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,14 +2471,31 @@ HiiConfigRoutingExtractConfig (
     }\r
 \r
     StringPtr++;\r
-\r
   }\r
 \r
-  return EFI_SUCCESS;\r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\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
+  if (DevicePath != NULL) {\r
+    FreePool (DevicePath);\r
+  }  \r
 \r
+  return Status;\r
 }\r
 \r
 \r
@@ -1029,24 +2528,25 @@ 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
+  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
@@ -1054,13 +2554,6 @@ HiiConfigRoutingExportConfig (
 \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
@@ -1070,156 +2563,138 @@ HiiConfigRoutingExportConfig (
     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
-    }\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
-    //\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
+      continue;\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
+    // Get DevicePath and HiiHandle for this ConfigAccess driver handle\r
+    //\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
+        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
+            HiiHandle = Database->Handle;\r
+            break;\r
+          }\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
-\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
-\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
-\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
-    SafeFreePool (PathHdr);\r
-    PathHdr = NULL;\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
-\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
-\r
     Status = ConfigAccess->ExtractConfig (\r
                              ConfigAccess,\r
-                             ConfigRequest,\r
-                             &AccessProgress,\r
+                             NULL,\r
+                             &Progress,\r
                              &AccessResults\r
                              );\r
     if (EFI_ERROR (Status)) {\r
-      SafeFreePool (ConfigRequest);\r
-      SafeFreePool (AccessResults);\r
-      return EFI_INVALID_PARAMETER;\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
-    // 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
+    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
+        if (StrStr (AccessResults, L"&OFFSET=") != NULL) {\r
+          Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);\r
+          ASSERT_EFI_ERROR (Status);\r
+        }\r
+        if (StringPtr != NULL) {\r
+          *StringPtr = L'&';\r
+        }\r
+      }\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
+      //\r
+      // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
+      // which seperates the first <ConfigAltResp> and the following ones.      \r
+      //\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
+\r
+      FirstElement = FALSE;\r
+      \r
+      FreePool (AccessResults);\r
+      AccessResults = NULL;\r
+    }\r
   }\r
+  FreePool (ConfigAccessHandles);\r
 \r
-  return EFI_SUCCESS;\r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
+  return EFI_SUCCESS;  \r
 }\r
 \r
 \r
@@ -1250,28 +2725,26 @@ 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
+  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
-  UINTN                               RemainSize;\r
-  EFI_STRING                          TmpPtr;\r
 \r
   if (This == NULL || Progress == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1323,21 +2796,22 @@ HiiConfigRoutingRoutConfig (
     //\r
     Status = GetDevicePath (ConfigResp, (UINT8 **) &DevicePath);\r
     if (EFI_ERROR (Status)) {\r
-      SafeFreePool (ConfigResp);\r
+      FreePool (ConfigResp);\r
       return Status;\r
     }\r
 \r
     //\r
     // Find driver which matches the routing data.\r
     //\r
-    DriverHandle = NULL;\r
+    DriverHandle     = NULL;\r
     for (Link = Private->DatabaseList.ForwardLink;\r
          Link != &Private->DatabaseList;\r
          Link = Link->ForwardLink\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
+\r
+      if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
+        CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
         if (CompareMem (\r
               DevicePath,\r
               CurrentDevicePath,\r
@@ -1349,18 +2823,30 @@ HiiConfigRoutingRoutConfig (
       }\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
     //\r
@@ -1382,15 +2868,13 @@ HiiConfigRoutingRoutConfig (
       // 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
@@ -1407,9 +2891,6 @@ HiiConfigRoutingRoutConfig (
   }\r
 \r
   return EFI_SUCCESS;\r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
 }\r
 \r
 \r
@@ -1426,7 +2907,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
@@ -1470,6 +2951,9 @@ HiiBlockToConfig (
   UINT8                               *Value;\r
   EFI_STRING                          ValueStr;\r
   EFI_STRING                          ConfigElement;\r
+  UINTN                               Index;\r
+  UINT8                               *TemBuffer;\r
+  CHAR16                              *TemString;\r
 \r
   if (This == NULL || Progress == NULL || Config == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1510,11 +2994,23 @@ HiiBlockToConfig (
     StringPtr++;\r
   }\r
   if (*StringPtr == 0) {\r
-    *Progress = StringPtr;\r
+    *Progress = StringPtr - 1;\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Exit;\r
+  }\r
+\r
+  while (*StringPtr != L'&' && *StringPtr != 0) {\r
+    StringPtr++;\r
+  }\r
+  if (*StringPtr == 0) {\r
+    *Progress = StringPtr - 1;\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
-  while (*StringPtr++ != L'&');\r
+  //\r
+  // Skip '&'\r
+  //\r
+  StringPtr++;\r
 \r
   //\r
   // Copy <ConfigHdr> and an additional '&' to <ConfigResp>\r
@@ -1548,7 +3044,7 @@ HiiBlockToConfig (
       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
@@ -1572,7 +3068,7 @@ HiiBlockToConfig (
       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
@@ -1606,10 +3102,14 @@ HiiBlockToConfig (
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
+    \r
+    TemString = ValueStr;\r
+    TemBuffer = Value + Width - 1;\r
+    for (Index = 0; Index < Width; Index ++, TemBuffer --) {\r
+      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+    }\r
 \r
-    Status = BufToHexString (ValueStr, &Length, Value, Width);\r
-    ASSERT_EFI_ERROR (Status);\r
-    SafeFreePool (Value);\r
+    FreePool (Value);\r
     Value = NULL;\r
 \r
     //\r
@@ -1631,8 +3131,8 @@ HiiBlockToConfig (
 \r
     AppendToMultiString (Config, ConfigElement);\r
 \r
-    SafeFreePool (ConfigElement);\r
-    SafeFreePool (ValueStr);\r
+    FreePool (ConfigElement);\r
+    FreePool (ValueStr);\r
     ConfigElement = NULL;\r
     ValueStr = NULL;\r
 \r
@@ -1652,16 +3152,25 @@ HiiBlockToConfig (
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
-\r
+  \r
+  HiiToLower (*Config);\r
   *Progress = StringPtr;\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
-\r
-  SafeFreePool (*Config);\r
-  SafeFreePool (ValueStr);\r
-  SafeFreePool (Value);\r
-  SafeFreePool (ConfigElement);\r
+  if (*Config != NULL) {\r
+  FreePool (*Config);\r
+  *Config = NULL;\r
+  }\r
+  if (ValueStr != NULL) {\r
+    FreePool (ValueStr);\r
+  }\r
+  if (Value != NULL) {\r
+    FreePool (Value);\r
+  }\r
+  if (ConfigElement != NULL) {\r
+    FreePool (ConfigElement);\r
+  }\r
 \r
   return Status;\r
 \r
@@ -1675,7 +3184,7 @@ Exit:
   @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
                                  instance.\r
   @param  ConfigResp             A null-terminated Unicode string in <ConfigResp>\r
-                                 format.\r
+                                 format. It can be ConfigAltResp format string.\r
   @param  Block                  A possibly null array of bytes representing the\r
                                  current  block. Only bytes referenced in the\r
                                  ConfigResp string  in the block are modified. If\r
@@ -1761,7 +3270,19 @@ HiiConfigToBlock (
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
-  while (*StringPtr++ != L'&');\r
+\r
+  while (*StringPtr != L'&' && *StringPtr != 0) {\r
+    StringPtr++;\r
+  }\r
+  if (*StringPtr == 0) {\r
+    *Progress = StringPtr;\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Exit;\r
+  }\r
+  //\r
+  // Skip '&'\r
+  //\r
+  StringPtr++;\r
 \r
   //\r
   // Parse each <ConfigElement> if exists\r
@@ -1774,7 +3295,7 @@ HiiConfigToBlock (
     // Get Offset\r
     //\r
     Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
+    if (EFI_ERROR (Status)) {\r
       *Progress = ConfigResp;\r
       goto Exit;\r
     }\r
@@ -1784,7 +3305,7 @@ HiiConfigToBlock (
       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
@@ -1808,7 +3329,7 @@ HiiConfigToBlock (
       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
@@ -1822,7 +3343,7 @@ HiiConfigToBlock (
     // Get Value\r
     //\r
     Status = GetValueOfNumber (StringPtr, &Value, &Length);\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
+    if (EFI_ERROR (Status)) {\r
       *Progress = ConfigResp;\r
       goto Exit;\r
     }\r
@@ -1845,7 +3366,7 @@ HiiConfigToBlock (
     CopyMem (Block + Offset, Value, Width);\r
     *BlockSize = Offset + Width - 1;\r
 \r
-    SafeFreePool (Value);\r
+    FreePool (Value);\r
     Value = NULL;\r
 \r
     //\r
@@ -1857,19 +3378,24 @@ HiiConfigToBlock (
 \r
     StringPtr++;\r
   }\r
-\r
-  if (*StringPtr != 0) {\r
+  \r
+  //\r
+  // The input string is ConfigAltResp format.\r
+  //\r
+  if ((*StringPtr != 0) && (StrnCmp (StringPtr, L"&GUID=", StrLen (L"&GUID=")) != 0)) {\r
     *Progress = StringPtr - 1;\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
 \r
-  *Progress = StringPtr;\r
+  *Progress = StringPtr + StrLen (StringPtr);\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
 \r
-  SafeFreePool (Value);\r
+  if (Value != NULL) {\r
+    FreePool (Value);\r
+  }\r
   return Status;\r
 }\r
 \r
@@ -1881,7 +3407,7 @@ Exit:
   @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
                                  instance.\r
   @param  Configuration          A null-terminated Unicode string in\r
-                                 <MultiConfigAltResp> format.\r
+                                 <MultiConfigAltResp> format. It is <ConfigAltResp> format.\r
   @param  Guid                   A pointer to the GUID value to search for in the\r
                                  routing portion of the ConfigResp string when\r
                                  retrieving  the requested data. If Guid is NULL,\r
@@ -1903,7 +3429,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
@@ -1926,22 +3452,31 @@ HiiGetAltCfg (
   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                          HdrStart;\r
+  EFI_STRING                          HdrEnd;\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
+  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
@@ -1955,30 +3490,21 @@ 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
+    (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
   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
@@ -2050,9 +3576,10 @@ HiiGetAltCfg (
             Status = EFI_NOT_FOUND;\r
             goto Exit;\r
           }\r
+          StringPtr ++;\r
         }\r
         PathFlag = TRUE;\r
-        HdrEnd   = ++StringPtr;\r
+        HdrEnd   = StringPtr;\r
       }\r
     }\r
 \r
@@ -2075,7 +3602,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,12 +3615,12 @@ 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
@@ -2100,18 +3631,24 @@ Exit:
     }\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
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
+  if (PathStr != NULL) {\r
+    FreePool (PathStr);\r
+  }\r
+  if (AltIdStr != NULL) {\r
+    FreePool (AltIdStr);\r
+  }\r
+  if (Result != NULL) {\r
+    FreePool (Result);\r
+  }\r
 \r
   return Status;\r
 \r
-#else\r
-  return EFI_UNSUPPORTED;\r
-#endif\r
-\r
 }\r
 \r
 \r