]> 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 665b951869d1a15e110c63a56da67df5a0fd8aba..d5ef60b7f5ed3eb223d96c60123df4b3bb319351 100644 (file)
@@ -61,8 +61,9 @@ CalculateConfigStringLen (
   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
@@ -72,18 +73,19 @@ CalculateConfigStringLen (
 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
-  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
@@ -94,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
@@ -104,13 +111,13 @@ 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
@@ -118,13 +125,15 @@ GetDevicePath (
   //\r
   DevicePathBuffer = (UINT8 *) AllocateZeroPool ((Length + 1) / 2);\r
   if (DevicePathBuffer == NULL) {\r
-    FreePool (DevicePathString);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-\r
+  \r
+  //\r
+  // Convert DevicePath\r
+  //\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
@@ -132,13 +141,27 @@ GetDevicePath (
       DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);\r
     }\r
   }\r
-\r
-  FreePool (DevicePathString);\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
+  // return the device path\r
+  //\r
+  *DevicePathData = DevicePathBuffer;\r
   return EFI_SUCCESS;\r
-\r
 }\r
 \r
 /**\r
@@ -591,6 +614,10 @@ MergeDefaultString (
                                      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
@@ -657,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
-      //\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
@@ -1144,6 +1178,7 @@ ParseIfrData (
           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
@@ -1170,6 +1205,7 @@ ParseIfrData (
           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
@@ -1375,6 +1411,7 @@ ParseIfrData (
           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
@@ -1401,6 +1438,7 @@ ParseIfrData (
           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
@@ -1445,6 +1483,7 @@ ParseIfrData (
         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
@@ -1500,13 +1539,22 @@ 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
+  @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
+  @retval EFI_INVALID_PARAMETER  Request points to NULL.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1515,7 +1563,8 @@ GetFullStringFromHiiFormPackages (
   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
+  IN OUT EFI_STRING                 *AltCfgResp,\r
+  OUT    EFI_STRING                 *PointerProgress OPTIONAL\r
   )\r
 {\r
   EFI_STATUS                   Status;\r
@@ -1536,6 +1585,7 @@ GetFullStringFromHiiFormPackages (
   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
@@ -1543,6 +1593,11 @@ GetFullStringFromHiiFormPackages (
   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
@@ -1559,7 +1614,9 @@ GetFullStringFromHiiFormPackages (
   HiiFormPackage    = NULL;\r
   ResultSize        = 0;\r
   PackageSize       = 0;\r
-  \r
+  DataExist         = FALSE;\r
+  Progress          = *Request;\r
\r
   //\r
   // 0. Get Hii Form Package by HiiHandle\r
   //\r
@@ -1605,7 +1662,47 @@ GetFullStringFromHiiFormPackages (
   //\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
@@ -1631,7 +1728,8 @@ GetFullStringFromHiiFormPackages (
     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
@@ -1687,7 +1785,28 @@ GetFullStringFromHiiFormPackages (
       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
@@ -1752,6 +1871,7 @@ GetFullStringFromHiiFormPackages (
   // 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
@@ -1803,7 +1923,8 @@ GetFullStringFromHiiFormPackages (
     // 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
@@ -1812,14 +1933,24 @@ GetFullStringFromHiiFormPackages (
       // <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
@@ -1862,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
-\r
+  DataExist = FALSE;\r
   //\r
   // Add length for <ConfigHdr> + '\0'\r
   //\r
@@ -1885,17 +2016,27 @@ GetFullStringFromHiiFormPackages (
           // 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
+  // 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
@@ -1957,11 +2098,11 @@ GetFullStringFromHiiFormPackages (
   //\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
-  } else {\r
-   *AltCfgResp = DefaultAltCfgResp;\r
+  } else if (*AltCfgResp == NULL) {\r
+    *AltCfgResp = DefaultAltCfgResp;\r
   }\r
 \r
 Done:\r
@@ -2033,6 +2174,16 @@ Done:
     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
@@ -2102,7 +2253,7 @@ HiiConfigRoutingExtractConfig (
   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
@@ -2121,6 +2272,7 @@ HiiConfigRoutingExtractConfig (
   Status         = EFI_SUCCESS;\r
   AccessResults  = NULL;\r
   DevicePath     = NULL;\r
+  IfrDataParsedFlag = FALSE;\r
 \r
   //\r
   // The first element of <MultiConfigRequest> should be\r
@@ -2177,21 +2329,18 @@ HiiConfigRoutingExtractConfig (
     DriverHandle     = NULL;\r
     HiiHandle        = NULL;\r
     Database         = NULL;\r
-    DevicePathLength = GetDevicePathSize (DevicePath);\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 ((DevicePathLength == GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)) && \r
-            (CompareMem (\r
+        if (CompareMem (\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
@@ -2223,12 +2372,19 @@ HiiConfigRoutingExtractConfig (
     //\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
-      Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults);\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
@@ -2274,28 +2430,21 @@ HiiConfigRoutingExtractConfig (
     //\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 (Database, 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
     FreePool (DevicePath);\r
     DevicePath = NULL;\r
-    \r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
 \r
-    //\r
-    // Free the allocated memory.\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
 NextConfigString:   \r
     if (!FirstElement) {\r
       Status = AppendToMultiString (Results, L"&");\r
@@ -2327,7 +2476,7 @@ NextConfigString:
 Done:\r
   if (EFI_ERROR (Status)) {\r
     FreePool (*Results);\r
-  *Results = NULL;\r
+    *Results = NULL;\r
   }\r
   \r
   if (ConfigRequest != NULL) {\r
@@ -2383,6 +2532,7 @@ HiiConfigRoutingExportConfig (
   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
@@ -2396,7 +2546,7 @@ HiiConfigRoutingExportConfig (
   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
@@ -2440,13 +2590,13 @@ HiiConfigRoutingExportConfig (
     //\r
     // Get DevicePath and HiiHandle for this ConfigAccess driver handle\r
     //\r
+    IfrDataParsedFlag = FALSE;\r
     Progress         = NULL;\r
     HiiHandle        = NULL;\r
-    ConfigRequest    = NULL;\r
     DefaultResults   = NULL;\r
     Database         = NULL;\r
+    ConfigRequest    = NULL;\r
     DevicePath       = DevicePathFromHandle (ConfigAccessHandles[Index]);\r
-    DevicePathLength = GetDevicePathSize (DevicePath);\r
     if (DevicePath != NULL) {\r
       for (Link = Private->DatabaseList.ForwardLink;\r
            Link != &Private->DatabaseList;\r
@@ -2455,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
-          if ((DevicePathLength == GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)) &&\r
-              (CompareMem (\r
+          if (CompareMem (\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
@@ -2468,27 +2617,53 @@ HiiConfigRoutingExportConfig (
       }\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 (Database, 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
-                             ConfigRequest,\r
+                             NULL,\r
                              &Progress,\r
                              &AccessResults\r
                              );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle \r
+      //\r
+      if (HiiHandle != NULL && DevicePath != NULL) {\r
+        IfrDataParsedFlag = TRUE;\r
+        Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);\r
+        //\r
+        // Get the full request string to get the Current setting again.\r
+        //\r
+        if (!EFI_ERROR (Status) && ConfigRequest != NULL) {\r
+          Status = ConfigAccess->ExtractConfig (\r
+                                   ConfigAccess,\r
+                                   ConfigRequest,\r
+                                   &Progress,\r
+                                   &AccessResults\r
+                                   );\r
+          FreePool (ConfigRequest);\r
+        } else {\r
+          Status = EFI_NOT_FOUND;\r
+        }\r
+      }\r
+    }\r
+\r
     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
@@ -2570,7 +2745,6 @@ HiiConfigRoutingRouteConfig (
   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
@@ -2630,7 +2804,6 @@ HiiConfigRoutingRouteConfig (
     // 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
@@ -2639,12 +2812,11 @@ HiiConfigRoutingRouteConfig (
 \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
-              DevicePathLength\r
-              ) == 0)) {\r
+              GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)\r
+              ) == 0) {\r
           DriverHandle = Database->DriverHandle;\r
           break;\r
         }\r
@@ -3216,7 +3388,7 @@ HiiConfigToBlock (
     goto Exit;\r
   }\r
 \r
-  *Progress = StringPtr;\r
+  *Progress = StringPtr + StrLen (StringPtr);\r
   return EFI_SUCCESS;\r
 \r
 Exit:\r