]> 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 6b278afe173a36f86aceb6b28fc69334c9c5a5a0..d5ef60b7f5ed3eb223d96c60123df4b3bb319351 100644 (file)
@@ -61,8 +61,9 @@ CalculateConfigStringLen (
   This is a internal function.\r
 \r
   @param  String                 UEFI configuration string\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
 \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
   @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
@@ -72,18 +73,19 @@ CalculateConfigStringLen (
 EFI_STATUS\r
 GetDevicePath (\r
   IN  EFI_STRING                   String,\r
 EFI_STATUS\r
 GetDevicePath (\r
   IN  EFI_STRING                   String,\r
-  OUT UINT8                        **DevicePath\r
+  OUT UINT8                        **DevicePathData\r
   )\r
 {\r
   )\r
 {\r
-  UINTN      Length;\r
-  EFI_STRING PathHdr;\r
-  EFI_STRING DevicePathString;\r
-  UINT8      *DevicePathBuffer;\r
-  CHAR16     TemStr[2];\r
-  UINTN      Index;\r
-  UINT8      DigitUint8;\r
-\r
-  if (String == NULL || DevicePath == NULL) {\r
+  UINTN                    Length;\r
+  EFI_STRING               PathHdr;\r
+  UINT8                    *DevicePathBuffer;\r
+  CHAR16                   TemStr[2];\r
+  UINTN                    Index;\r
+  UINT8                    DigitUint8;\r
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+\r
+  if (String == NULL || DevicePathData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -94,8 +96,13 @@ GetDevicePath (
   if (*String == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (*String == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-\r
+  //\r
+  // Check whether path data does exist.\r
+  //\r
   String += StrLen (L"PATH=");\r
   String += StrLen (L"PATH=");\r
+  if (*String == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
   PathHdr = String;\r
 \r
   //\r
   PathHdr = String;\r
 \r
   //\r
@@ -104,13 +111,13 @@ GetDevicePath (
   // of UEFI device path.\r
   //\r
   for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);\r
   // of UEFI device path.\r
   //\r
   for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);\r
-  DevicePathString = (EFI_STRING) AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
-  if (DevicePathString == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  //\r
+  // Check DevicePath Length\r
+  //\r
+  if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+    return EFI_NOT_FOUND;\r
   }\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
   //\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
@@ -118,13 +125,15 @@ GetDevicePath (
   //\r
   DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2);\r
   if (DevicePathBuffer == NULL) {\r
   //\r
   DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2);\r
   if (DevicePathBuffer == NULL) {\r
-    FreePool (DevicePathString);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-\r
+  \r
+  //\r
+  // Convert DevicePath\r
+  //\r
   ZeroMem (TemStr, sizeof (TemStr));\r
   ZeroMem (TemStr, sizeof (TemStr));\r
-  for (Index = 0; DevicePathString[Index] != L'\0'; Index ++) {\r
-    TemStr[0] = DevicePathString[Index];\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
     DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
     if ((Index & 1) == 0) {\r
       DevicePathBuffer [Index/2] = DigitUint8;\r
@@ -132,13 +141,27 @@ GetDevicePath (
       DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);\r
     }\r
   }\r
       DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);\r
     }\r
   }\r
-\r
-  FreePool (DevicePathString);\r
   \r
   \r
-  *DevicePath = DevicePathBuffer;\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
 \r
+  //\r
+  // return the device path\r
+  //\r
+  *DevicePathData = DevicePathBuffer;\r
   return EFI_SUCCESS;\r
   return EFI_SUCCESS;\r
-\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -577,6 +600,10 @@ MergeDefaultString (
                                      SizeAltCfgResp + StrSize (StringPtrDefault),\r
                                      (VOID *) (*AltCfgResp)\r
                                      );\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
         StrCat (*AltCfgResp, StringPtrDefault);\r
         break;\r
       } else {\r
@@ -587,6 +614,10 @@ MergeDefaultString (
                                      SizeAltCfgResp + StrSize (StringPtrDefault),\r
                                      (VOID *) (*AltCfgResp)\r
                                      );\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
         StrCat (*AltCfgResp, StringPtrDefault);\r
         *StringPtrEnd = TempChar;\r
       }\r
@@ -594,11 +625,12 @@ MergeDefaultString (
     \r
     //\r
     // Find next AltCfg String\r
     \r
     //\r
     // Find next AltCfg String\r
-    //    \r
+    //\r
     *(AltConfigHdr + HeaderLength) = L'\0';\r
     StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);    \r
   }\r
     *(AltConfigHdr + HeaderLength) = L'\0';\r
     StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);    \r
   }\r
-\r
+  \r
+  FreePool (AltConfigHdr);\r
   return EFI_SUCCESS;  \r
 }\r
 \r
   return EFI_SUCCESS;  \r
 }\r
 \r
@@ -652,10 +684,17 @@ InsertDefaultValue (
   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
   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
-      //\r
-      // Update the default value array in BlockData.\r
-      //\r
-      DefaultValueArray->Value = DefaultValueData->Value;\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
       FreePool (DefaultValueData);\r
       return;\r
     } else if (DefaultValueArray->DefaultId > DefaultValueData->DefaultId) {\r
@@ -796,7 +835,7 @@ ParseIfrData (
   IN     EFI_STRING          ConfigHdr,\r
   IN     IFR_BLOCK_DATA      *RequestBlockArray,\r
   IN OUT IFR_VARSTORAGE_DATA *VarStorageData,\r
   IN     EFI_STRING          ConfigHdr,\r
   IN     IFR_BLOCK_DATA      *RequestBlockArray,\r
   IN OUT IFR_VARSTORAGE_DATA *VarStorageData,\r
-  OUT    IFR_DEFAULT_DATA    **PIfrDefaultIdArray\r
+  OUT    IFR_DEFAULT_DATA    *DefaultIdArray\r
   )\r
 {\r
   EFI_STATUS               Status;\r
   )\r
 {\r
   EFI_STATUS               Status;\r
@@ -810,7 +849,6 @@ ParseIfrData (
   EFI_IFR_CHECKBOX         *IfrCheckBox;\r
   EFI_IFR_PASSWORD         *IfrPassword;\r
   EFI_IFR_STRING           *IfrString;\r
   EFI_IFR_CHECKBOX         *IfrCheckBox;\r
   EFI_IFR_PASSWORD         *IfrPassword;\r
   EFI_IFR_STRING           *IfrString;\r
-  IFR_DEFAULT_DATA         *DefaultIdArray;\r
   IFR_DEFAULT_DATA         *DefaultData;\r
   IFR_BLOCK_DATA           *BlockData;\r
   CHAR16                   *VarStoreName;\r
   IFR_DEFAULT_DATA         *DefaultData;\r
   IFR_BLOCK_DATA           *BlockData;\r
   CHAR16                   *VarStoreName;\r
@@ -823,9 +861,6 @@ ParseIfrData (
   EFI_STRING               TempStr;\r
   UINTN                    LengthString;\r
 \r
   EFI_STRING               TempStr;\r
   UINTN                    LengthString;\r
 \r
-  //\r
-  // Initialize DefaultIdArray to store the map between DeaultId and DefaultName\r
-  //\r
   LengthString     = 0;\r
   Status           = EFI_SUCCESS;\r
   GuidStr          = NULL;\r
   LengthString     = 0;\r
   Status           = EFI_SUCCESS;\r
   GuidStr          = NULL;\r
@@ -833,11 +868,6 @@ ParseIfrData (
   TempStr          = NULL;\r
   BlockData        = NULL;\r
   DefaultData      = NULL;\r
   TempStr          = NULL;\r
   BlockData        = NULL;\r
   DefaultData      = NULL;\r
-  DefaultIdArray   = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
-  if (DefaultIdArray == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  InitializeListHead (&DefaultIdArray->Entry);\r
 \r
   //\r
   // Go through the form package to parse OpCode one by one.\r
 \r
   //\r
   // Go through the form package to parse OpCode one by one.\r
@@ -873,9 +903,10 @@ ParseIfrData (
       LengthString = StrLen (GuidStr);\r
       LengthString = LengthString + StrLen (NameStr) + 1;\r
       TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
       LengthString = StrLen (GuidStr);\r
       LengthString = LengthString + StrLen (NameStr) + 1;\r
       TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
-      if (TempStr == NULL) {\r
+    if (TempStr == NULL) {\r
         FreePool (GuidStr);\r
         FreePool (NameStr);\r
         FreePool (GuidStr);\r
         FreePool (NameStr);\r
+        FreePool (VarStoreName);\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
@@ -898,9 +929,9 @@ ParseIfrData (
       //\r
       // Free alllocated temp string.\r
       //\r
       //\r
       // Free alllocated temp string.\r
       //\r
-      FreePool (TempStr);\r
       FreePool (GuidStr);\r
       FreePool (NameStr);\r
       FreePool (GuidStr);\r
       FreePool (NameStr);\r
+      FreePool (TempStr);\r
       break;\r
 \r
     case EFI_IFR_DEFAULTSTORE_OP:\r
       break;\r
 \r
     case EFI_IFR_DEFAULTSTORE_OP:\r
@@ -934,6 +965,13 @@ ParseIfrData (
       // Numeric and OneOf has the same opcode structure.\r
       //\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
       //\r
       // Check whether this question is for the requested varstore.\r
       //\r
@@ -991,7 +1029,14 @@ ParseIfrData (
       // width by EFI_IFR_ORDERED_LIST MaxContainers * OneofOption Type\r
       // no default value and default id, how to define its default value?\r
       //\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
+      //\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
       //\r
       // Check whether this question is for the requested varstore.\r
       //\r
@@ -1055,6 +1100,13 @@ ParseIfrData (
       // default id by DeaultOption DefaultId can override CheckBox Flags and Default value.\r
       // \r
 \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
       //\r
       // Check whether this question is for the requested varstore.\r
       //\r
@@ -1126,6 +1178,7 @@ ParseIfrData (
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Done;\r
         }\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
         DefaultData->DefaultId   = VarDefaultId;\r
         DefaultData->DefaultName = VarDefaultName;\r
         DefaultData->Value       = 1;\r
@@ -1152,6 +1205,7 @@ ParseIfrData (
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Done;\r
         }\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
         DefaultData->DefaultId   = VarDefaultId;\r
         DefaultData->DefaultName = VarDefaultName;\r
         DefaultData->Value       = 1;\r
@@ -1169,6 +1223,13 @@ ParseIfrData (
       // no default value, only block array\r
       //\r
 \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
       //\r
       // Check whether this question is for the requested varstore.\r
       //\r
@@ -1233,6 +1294,13 @@ ParseIfrData (
       // no default value, only block array\r
       //\r
 \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
       //\r
       // Check whether this question is for the requested varstore.\r
       //\r
@@ -1343,6 +1411,7 @@ ParseIfrData (
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Done;\r
         }\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
         DefaultData->DefaultId   = VarDefaultId;\r
         DefaultData->DefaultName = VarDefaultName;\r
         DefaultData->Value       = IfrOneOfOption->Value.u64;\r
@@ -1369,6 +1438,7 @@ ParseIfrData (
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Done;\r
         }\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
         DefaultData->DefaultId   = VarDefaultId;\r
         DefaultData->DefaultName = VarDefaultName;\r
         DefaultData->Value       = IfrOneOfOption->Value.u64;\r
@@ -1413,6 +1483,7 @@ ParseIfrData (
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\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
       DefaultData->DefaultId   = VarDefaultId;\r
       DefaultData->DefaultName = VarDefaultName;\r
       DefaultData->Value       = IfrDefault->Value.u64;\r
@@ -1423,7 +1494,7 @@ ParseIfrData (
       break;\r
     case EFI_IFR_END_OP:\r
       //\r
       break;\r
     case EFI_IFR_END_OP:\r
       //\r
-      // End Opcode is for Var.\r
+      // End Opcode is for Var question.\r
       //\r
       if (BlockData != NULL && BlockData->Scope > 0) {\r
         BlockData->Scope--;\r
       //\r
       if (BlockData != NULL && BlockData->Scope > 0) {\r
         BlockData->Scope--;\r
@@ -1440,11 +1511,6 @@ ParseIfrData (
   }\r
 \r
 Done:\r
   }\r
 \r
 Done:\r
-  //\r
-  // Set the defualt ID array.\r
-  //\r
-  *PIfrDefaultIdArray = DefaultIdArray;\r
-\r
   return Status;  \r
 }\r
 \r
   return Status;  \r
 }\r
 \r
@@ -1455,7 +1521,7 @@ Done:
   When Request points to NULL string, the request string and default value string \r
   for each varstore in form package will return. \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  HiiHandle              Hii Handle which Hii Packages are registered.\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
   @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
@@ -1473,36 +1539,44 @@ Done:
                                  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
                                  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_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
+  @retval EFI_INVALID_PARAMETER  Request points to NULL.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 GetFullStringFromHiiFormPackages (\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 GetFullStringFromHiiFormPackages (\r
-  IN     EFI_HII_HANDLE             HiiHandle,\r
+  IN     HII_DATABASE_RECORD        *DataBaseRecord,\r
   IN     EFI_DEVICE_PATH_PROTOCOL   *DevicePath,\r
   IN OUT EFI_STRING                 *Request,\r
   IN     EFI_DEVICE_PATH_PROTOCOL   *DevicePath,\r
   IN OUT EFI_STRING                 *Request,\r
-  IN OUT EFI_STRING                 *AltCfgResp\r
+  IN OUT EFI_STRING                 *AltCfgResp,\r
+  OUT    EFI_STRING                 *PointerProgress OPTIONAL\r
   )\r
 {\r
   EFI_STATUS                   Status;\r
   )\r
 {\r
   EFI_STATUS                   Status;\r
-  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
-  UINT32                       PackageListLength;  \r
-  UINTN                        BufferSize;\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_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
-  EFI_HII_PACKAGE_HEADER       PacakgeHeader;\r
-  UINT32                       PackageOffset;\r
   IFR_VARSTORAGE_DATA          *VarStorageData;\r
   EFI_STRING                   DefaultAltCfgResp;\r
   EFI_STRING                   FullConfigRequest;\r
   IFR_VARSTORAGE_DATA          *VarStorageData;\r
   EFI_STRING                   DefaultAltCfgResp;\r
   EFI_STRING                   FullConfigRequest;\r
@@ -1511,6 +1585,7 @@ GetFullStringFromHiiFormPackages (
   EFI_STRING                   NameStr;\r
   EFI_STRING                   PathStr;\r
   EFI_STRING                   StringPtr;\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
   UINTN                        Length;\r
   UINT8                        *TmpBuffer;\r
   UINT16                       Offset;\r
@@ -1518,72 +1593,116 @@ GetFullStringFromHiiFormPackages (
   LIST_ENTRY                   *Link;\r
   LIST_ENTRY                   *LinkData;\r
   LIST_ENTRY                   *LinkDefault;\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
 \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
   VarStorageData    = NULL;\r
   DefaultAltCfgResp = NULL;\r
   FullConfigRequest = NULL;\r
   ConfigHdr         = NULL;\r
-  DefaultIdArray    = NULL;\r
   GuidStr           = NULL;\r
   NameStr           = NULL;\r
   PathStr           = NULL;\r
   GuidStr           = NULL;\r
   NameStr           = NULL;\r
   PathStr           = NULL;\r
-\r
-  //\r
-  // 1. Get HiiPackage by HiiHandle\r
-  //\r
-  BufferSize      = 0;\r
-  HiiPackageList  = NULL;\r
-  Status = HiiExportPackageLists (&mPrivate.HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
-\r
-  //\r
-  // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.\r
-  //\r
-  if (Status != EFI_BUFFER_TOO_SMALL) {\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
     return Status;\r
   }\r
-\r
-  HiiPackageList = AllocatePool (BufferSize);\r
-  if (HiiPackageList == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Get PackageList on HiiHandle\r
-  //\r
-  Status = HiiExportPackageLists (&mPrivate.HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
-  if (EFI_ERROR (Status)) {\r
\r
+  HiiFormPackage = AllocatePool (ResultSize);\r
+  if (HiiFormPackage == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
 \r
   //\r
     goto Done;\r
   }\r
 \r
   //\r
-  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
-  //    1) Request is NULL.\r
-  //    2) Request is not NULL. And it doesn't contain any BlockArray.\r
-  //    3) Request is not NULL. And it containts BlockArray.\r
-  //\r
-\r
+  // Get HiiFormPackage by HiiHandle\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
+  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
     goto Done;\r
   }\r
 \r
-  InitializeListHead (&VarStorageData->Entry);\r
-  InitializeListHead (&VarStorageData->BlockEntry);\r
-\r
   //\r
   //\r
-  // Gte the request block array by Request String \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
   //\r
   StringPtr = NULL;\r
   if (*Request != NULL) {\r
-    StringPtr = StrStr (*Request, L"&OFFSET=");\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
   }\r
   if (StringPtr != NULL) {\r
     //\r
@@ -1609,7 +1728,8 @@ GetFullStringFromHiiFormPackages (
     while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
       //\r
       // Skip the OFFSET string\r
     while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
       //\r
       // Skip the OFFSET string\r
-      //  \r
+      //\r
+      Progress   = StringPtr;\r
       StringPtr += StrLen (L"&OFFSET=");\r
       //\r
       // Get Offset\r
       StringPtr += StrLen (L"&OFFSET=");\r
       //\r
       // Get Offset\r
@@ -1665,7 +1785,28 @@ GetFullStringFromHiiFormPackages (
       BlockData->Offset = Offset;\r
       BlockData->Width  = Width;\r
       InsertBlockData (&RequestBlockArray->Entry, &BlockData);\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
 \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
       //\r
       // If '\0', parsing is finished. \r
       //\r
@@ -1694,39 +1835,44 @@ GetFullStringFromHiiFormPackages (
   }\r
   \r
   //\r
   }\r
   \r
   //\r
-  // Get the form package\r
+  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
   //\r
   //\r
-  PackageOffset     = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-  PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);\r
-  while (PackageOffset < PackageListLength) {\r
-    CopyMem (&PacakgeHeader, (UINT8 *) HiiPackageList + PackageOffset, sizeof (PacakgeHeader));\r
-\r
-    if (PacakgeHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
-      //\r
-      // Reset VarStorageData\r
-      //\r
-      VarStorageData->Size = 0;\r
-      VarStorageData->VarStoreId = 0;\r
-      if (VarStorageData->Name != NULL) {\r
-        FreePool (VarStorageData->Name);\r
-        VarStorageData->Name = NULL;\r
-      }\r
 \r
 \r
-      //\r
-      // Parse the opcode in form package \r
-      //\r
-      Status = ParseIfrData ((UINT8 *) HiiPackageList + PackageOffset, PacakgeHeader.Length, *Request, RequestBlockArray, VarStorageData, &DefaultIdArray);\r
-      if (EFI_ERROR (Status)) {\r
-        goto Done;\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
-      //\r
-      // Only one form is in a pacakge list.\r
-      //\r
-      break;\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
-    PackageOffset += PacakgeHeader.Length;\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
   }\r
 \r
   //\r
@@ -1777,7 +1923,8 @@ GetFullStringFromHiiFormPackages (
     // Compute the length of the entire request starting with <ConfigHdr> and a \r
     // Null-terminator\r
     //\r
     // Compute the length of the entire request starting with <ConfigHdr> and a \r
     // Null-terminator\r
     //\r
-    Length = StrLen (ConfigHdr) + 1;\r
+    DataExist = FALSE;\r
+    Length    = StrLen (ConfigHdr) + 1;\r
 \r
     for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
       //\r
 \r
     for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
       //\r
@@ -1786,14 +1933,24 @@ GetFullStringFromHiiFormPackages (
       // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
       //                 |  8   | 4 |   7  | 4 |\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
       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
     //\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
       goto Done;\r
     }\r
     StringPtr = FullConfigRequest;\r
@@ -1836,7 +1993,7 @@ GetFullStringFromHiiFormPackages (
   // 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
   // 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
-\r
+  DataExist = FALSE;\r
   //\r
   // Add length for <ConfigHdr> + '\0'\r
   //\r
   //\r
   // Add length for <ConfigHdr> + '\0'\r
   //\r
@@ -1859,17 +2016,27 @@ GetFullStringFromHiiFormPackages (
           // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"\r
           //                |    8  | 4 |   7  | 4 |   7  | Width * 2 |\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
+          Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);\r
+          DataExist = TRUE;\r
         }\r
       }\r
     }\r
   }\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
 \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
     goto Done;\r
   }\r
   StringPtr = DefaultAltCfgResp;\r
@@ -1931,11 +2098,11 @@ GetFullStringFromHiiFormPackages (
   //\r
   // 5. Merge string into the input AltCfgResp if the iput *AltCfgResp is not NULL.\r
   //\r
   //\r
   // 5. Merge string into the input AltCfgResp if the iput *AltCfgResp is not NULL.\r
   //\r
-  if (*AltCfgResp != NULL) {\r
+  if (*AltCfgResp != NULL && DefaultAltCfgResp != NULL) {\r
     Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);\r
     FreePool (DefaultAltCfgResp);\r
     Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);\r
     FreePool (DefaultAltCfgResp);\r
-  } else {\r
-   *AltCfgResp = DefaultAltCfgResp;\r
+  } else if (*AltCfgResp == NULL) {\r
+    *AltCfgResp = DefaultAltCfgResp;\r
   }\r
 \r
 Done:\r
   }\r
 \r
 Done:\r
@@ -2003,8 +2170,18 @@ Done:
   //\r
   // Free Pacakge data\r
   //\r
   //\r
   // Free Pacakge data\r
   //\r
-  if (HiiPackageList != NULL) {\r
-    FreePool (HiiPackageList);\r
+  if (HiiFormPackage != NULL) {\r
+    FreePool (HiiFormPackage);\r
+  }\r
+\r
+  if (PointerProgress != NULL) {\r
+    if (*Request == NULL) {\r
+      *PointerProgress = NULL;\r
+    } else if (EFI_ERROR (Status)) {\r
+      *PointerProgress = Progress;\r
+    } else {\r
+      *PointerProgress = *Request + StrLen (*Request);\r
+    }\r
   }\r
 \r
   return Status;\r
   }\r
 \r
   return Status;\r
@@ -2076,7 +2253,7 @@ HiiConfigRoutingExtractConfig (
   EFI_STRING                          AccessResults;\r
   EFI_STRING                          DefaultResults;\r
   BOOLEAN                             FirstElement;\r
   EFI_STRING                          AccessResults;\r
   EFI_STRING                          DefaultResults;\r
   BOOLEAN                             FirstElement;\r
-  UINTN                               DevicePathLength;\r
+  BOOLEAN                             IfrDataParsedFlag;\r
 \r
   if (This == NULL || Progress == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if (This == NULL || Progress == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2095,6 +2272,7 @@ HiiConfigRoutingExtractConfig (
   Status         = EFI_SUCCESS;\r
   AccessResults  = NULL;\r
   DevicePath     = 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
 \r
   //\r
   // The first element of <MultiConfigRequest> should be\r
@@ -2150,21 +2328,19 @@ HiiConfigRoutingExtractConfig (
     //\r
     DriverHandle     = NULL;\r
     HiiHandle        = NULL;\r
     //\r
     DriverHandle     = NULL;\r
     HiiHandle        = NULL;\r
-    DevicePathLength = GetDevicePathSize (DevicePath);\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
     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
-   \r
       if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
         CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
       if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
         CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
-        if ((DevicePathLength == GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)) && \r
-            (CompareMem (\r
+        if (CompareMem (\r
               DevicePath,\r
               CurrentDevicePath,\r
               DevicePath,\r
               CurrentDevicePath,\r
-              DevicePathLength\r
-              ) == 0)) {\r
+              GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
+              ) == 0) {\r
           DriverHandle = Database->DriverHandle;\r
           HiiHandle    = Database->Handle;\r
           break;\r
           DriverHandle = Database->DriverHandle;\r
           HiiHandle    = Database->Handle;\r
           break;\r
@@ -2196,14 +2372,28 @@ HiiConfigRoutingExtractConfig (
     //\r
     // Check whether ConfigRequest contains request string OFFSET/WIDTH\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
       // Get the full request string from IFR when HiiPackage is registered to HiiHandle \r
       //\r
     if ((HiiHandle != NULL) && (StrStr (ConfigRequest, L"&OFFSET=") == NULL)) {\r
       //\r
       // Get the full request string from IFR when HiiPackage is registered to HiiHandle \r
       //\r
-      Status = GetFullStringFromHiiFormPackages (HiiHandle, DevicePath, &ConfigRequest, &DefaultResults);\r
+      IfrDataParsedFlag = TRUE;\r
+      Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, &AccessProgress);\r
       if (EFI_ERROR (Status)) {\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
         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
     }\r
 \r
     //\r
@@ -2240,28 +2430,22 @@ HiiConfigRoutingExtractConfig (
     //\r
     // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
     //\r
     //\r
     // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
     //\r
-    if (HiiHandle != NULL) {\r
-      if (DefaultResults == NULL) {\r
-        Status = GetFullStringFromHiiFormPackages (HiiHandle, DevicePath, &ConfigRequest, &AccessResults);\r
-      } else {\r
-        Status = MergeDefaultString (&AccessResults, DefaultResults);\r
-      }\r
+    if (!IfrDataParsedFlag && HiiHandle != NULL) {\r
+      Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+      ASSERT_EFI_ERROR (Status);\r
     }\r
     }\r
+\r
     FreePool (DevicePath);\r
     DevicePath = NULL;\r
     FreePool (DevicePath);\r
     DevicePath = NULL;\r
-    \r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
 \r
 \r
-    //\r
-    // Free the allocated memory.\r
-    //\r
     if (DefaultResults != NULL) {\r
     if (DefaultResults != NULL) {\r
+      Status = MergeDefaultString (&AccessResults, DefaultResults);\r
+      ASSERT_EFI_ERROR (Status);\r
       FreePool (DefaultResults);\r
       DefaultResults = NULL;\r
     }\r
     \r
       FreePool (DefaultResults);\r
       DefaultResults = NULL;\r
     }\r
     \r
+NextConfigString:   \r
     if (!FirstElement) {\r
       Status = AppendToMultiString (Results, L"&");\r
       ASSERT_EFI_ERROR (Status);\r
     if (!FirstElement) {\r
       Status = AppendToMultiString (Results, L"&");\r
       ASSERT_EFI_ERROR (Status);\r
@@ -2292,6 +2476,7 @@ HiiConfigRoutingExtractConfig (
 Done:\r
   if (EFI_ERROR (Status)) {\r
     FreePool (*Results);\r
 Done:\r
   if (EFI_ERROR (Status)) {\r
     FreePool (*Results);\r
+    *Results = NULL;\r
   }\r
   \r
   if (ConfigRequest != NULL) {\r
   }\r
   \r
   if (ConfigRequest != NULL) {\r
@@ -2347,6 +2532,7 @@ HiiConfigRoutingExportConfig (
   EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
   EFI_STRING                          AccessResults;\r
   EFI_STRING                          Progress;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
   EFI_STRING                          AccessResults;\r
   EFI_STRING                          Progress;\r
+  EFI_STRING                          StringPtr;\r
   EFI_STRING                          ConfigRequest;\r
   UINTN                               Index;\r
   EFI_HANDLE                          *ConfigAccessHandles;\r
   EFI_STRING                          ConfigRequest;\r
   UINTN                               Index;\r
   EFI_HANDLE                          *ConfigAccessHandles;\r
@@ -2360,7 +2546,7 @@ HiiConfigRoutingExportConfig (
   HII_DATABASE_RECORD                 *Database;\r
   UINT8                               *DevicePathPkg;\r
   UINT8                               *CurrentDevicePath;\r
   HII_DATABASE_RECORD                 *Database;\r
   UINT8                               *DevicePathPkg;\r
   UINT8                               *CurrentDevicePath;\r
-  UINTN                               DevicePathLength;\r
+  BOOLEAN                             IfrDataParsedFlag;\r
 \r
   if (This == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if (This == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2404,12 +2590,13 @@ HiiConfigRoutingExportConfig (
     //\r
     // Get DevicePath and HiiHandle for this ConfigAccess driver handle\r
     //\r
     //\r
     // Get DevicePath and HiiHandle for this ConfigAccess driver handle\r
     //\r
+    IfrDataParsedFlag = FALSE;\r
     Progress         = NULL;\r
     HiiHandle        = NULL;\r
     Progress         = NULL;\r
     HiiHandle        = NULL;\r
-    ConfigRequest    = NULL;\r
     DefaultResults   = NULL;\r
     DefaultResults   = NULL;\r
+    Database         = NULL;\r
+    ConfigRequest    = NULL;\r
     DevicePath       = DevicePathFromHandle (ConfigAccessHandles[Index]);\r
     DevicePath       = DevicePathFromHandle (ConfigAccessHandles[Index]);\r
-    DevicePathLength = GetDevicePathSize (DevicePath);\r
     if (DevicePath != NULL) {\r
       for (Link = Private->DatabaseList.ForwardLink;\r
            Link != &Private->DatabaseList;\r
     if (DevicePath != NULL) {\r
       for (Link = Private->DatabaseList.ForwardLink;\r
            Link != &Private->DatabaseList;\r
@@ -2418,12 +2605,11 @@ HiiConfigRoutingExportConfig (
         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
         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 ((DevicePathLength == GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)) &&\r
-              (CompareMem (\r
+          if (CompareMem (\r
                 DevicePath,\r
                 CurrentDevicePath,\r
                 DevicePath,\r
                 CurrentDevicePath,\r
-                DevicePathLength\r
-                ) == 0)) {\r
+                GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
+                ) == 0) {\r
             HiiHandle = Database->Handle;\r
             break;\r
           }\r
             HiiHandle = Database->Handle;\r
             break;\r
           }\r
@@ -2431,33 +2617,61 @@ HiiConfigRoutingExportConfig (
       }\r
     }\r
 \r
       }\r
     }\r
 \r
-    //\r
-    // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
-    //\r
-    if (HiiHandle != NULL && DevicePath != NULL) {\r
-      Status = GetFullStringFromHiiFormPackages (HiiHandle, DevicePath, &ConfigRequest, &DefaultResults);\r
-    }\r
-    //\r
-    // Can't parse IFR data to get the request string and default string.\r
-    //\r
-    if (EFI_ERROR (Status)) {\r
-      ConfigRequest  = NULL;\r
-      DefaultResults = NULL;\r
-    }\r
-       \r
     Status = ConfigAccess->ExtractConfig (\r
                              ConfigAccess,\r
     Status = ConfigAccess->ExtractConfig (\r
                              ConfigAccess,\r
-                             ConfigRequest,\r
+                             NULL,\r
                              &Progress,\r
                              &AccessResults\r
                              );\r
                              &Progress,\r
                              &AccessResults\r
                              );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
+      //\r
+      if (HiiHandle != NULL && DevicePath != NULL) {\r
+        IfrDataParsedFlag = TRUE;\r
+        Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+        //\r
+        // Get the full request string to get the Current setting again.\r
+        //\r
+        if (!EFI_ERROR (Status) && ConfigRequest != NULL) {\r
+          Status = ConfigAccess->ExtractConfig (\r
+                                   ConfigAccess,\r
+                                   ConfigRequest,\r
+                                   &Progress,\r
+                                   &AccessResults\r
+                                   );\r
+          FreePool (ConfigRequest);\r
+        } else {\r
+          Status = EFI_NOT_FOUND;\r
+        }\r
+      }\r
+    }\r
+\r
     if (!EFI_ERROR (Status)) {\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
       //\r
       // Merge the default sting from IFR code into the got setting from driver.\r
       //\r
       if (DefaultResults != NULL) {\r
-        MergeDefaultString (&AccessResults, DefaultResults);\r
+        Status = MergeDefaultString (&AccessResults, DefaultResults);\r
+        ASSERT_EFI_ERROR (Status);\r
         FreePool (DefaultResults);\r
         FreePool (DefaultResults);\r
+        DefaultResults = NULL;\r
       }\r
       \r
       //\r
       }\r
       \r
       //\r
@@ -2531,7 +2745,6 @@ HiiConfigRoutingRouteConfig (
   EFI_HANDLE                          DriverHandle;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
   EFI_STRING                          AccessProgress;\r
   EFI_HANDLE                          DriverHandle;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL      *ConfigAccess;\r
   EFI_STRING                          AccessProgress;\r
-  UINTN                               DevicePathLength;\r
 \r
   if (This == NULL || Progress == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if (This == NULL || Progress == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2591,7 +2804,6 @@ HiiConfigRoutingRouteConfig (
     // Find driver which matches the routing data.\r
     //\r
     DriverHandle     = NULL;\r
     // Find driver which matches the routing data.\r
     //\r
     DriverHandle     = NULL;\r
-    DevicePathLength = GetDevicePathSize (DevicePath);\r
     for (Link = Private->DatabaseList.ForwardLink;\r
          Link != &Private->DatabaseList;\r
          Link = Link->ForwardLink\r
     for (Link = Private->DatabaseList.ForwardLink;\r
          Link != &Private->DatabaseList;\r
          Link = Link->ForwardLink\r
@@ -2600,12 +2812,11 @@ HiiConfigRoutingRouteConfig (
 \r
       if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
         CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
 \r
       if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {\r
         CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
-        if ((DevicePathLength == GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)) &&\r
-            (CompareMem (\r
+        if (CompareMem (\r
               DevicePath,\r
               CurrentDevicePath,\r
               DevicePath,\r
               CurrentDevicePath,\r
-              DevicePathLength\r
-              ) == 0)) {\r
+              GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
+              ) == 0) {\r
           DriverHandle = Database->DriverHandle;\r
           break;\r
         }\r
           DriverHandle = Database->DriverHandle;\r
           break;\r
         }\r
@@ -2783,7 +2994,7 @@ HiiBlockToConfig (
     StringPtr++;\r
   }\r
   if (*StringPtr == 0) {\r
     StringPtr++;\r
   }\r
   if (*StringPtr == 0) {\r
-    *Progress = StringPtr;\r
+    *Progress = StringPtr - 1;\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
@@ -2792,7 +3003,7 @@ HiiBlockToConfig (
     StringPtr++;\r
   }\r
   if (*StringPtr == 0) {\r
     StringPtr++;\r
   }\r
   if (*StringPtr == 0) {\r
-    *Progress = StringPtr;\r
+    *Progress = StringPtr - 1;\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Exit;\r
   }\r
@@ -2947,7 +3158,10 @@ HiiBlockToConfig (
   return EFI_SUCCESS;\r
 \r
 Exit:\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
+  if (*Config != NULL) {\r
   FreePool (*Config);\r
   FreePool (*Config);\r
+  *Config = NULL;\r
+  }\r
   if (ValueStr != NULL) {\r
     FreePool (ValueStr);\r
   }\r
   if (ValueStr != NULL) {\r
     FreePool (ValueStr);\r
   }\r
@@ -3174,7 +3388,7 @@ HiiConfigToBlock (
     goto Exit;\r
   }\r
 \r
     goto Exit;\r
   }\r
 \r
-  *Progress = StringPtr;\r
+  *Progress = StringPtr + StrLen (StringPtr);\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r
@@ -3401,7 +3615,7 @@ HiiGetAltCfg (
   Status = EFI_NOT_FOUND;\r
 \r
 Exit:\r
   Status = EFI_NOT_FOUND;\r
 \r
 Exit:\r
-\r
+  *AltCfgResp = NULL;\r
   if (!EFI_ERROR (Status) && (Result != NULL)) {\r
     //\r
     // Copy the <ConfigHdr> and <ConfigBody>\r
   if (!EFI_ERROR (Status) && (Result != NULL)) {\r
     //\r
     // Copy the <ConfigHdr> and <ConfigBody>\r