]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
Refine get default value process for browser.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
index 2b09593b9115b148bd0888272cf8989452ca5f5a..2da4cadd2dc71e1aa293461987acc4ebb02a5f54 100644 (file)
@@ -1346,6 +1346,110 @@ ConfigRespToStorage (
   return Status;\r
 }\r
 \r
+/**\r
+  Convert the buffer value to HiiValue.\r
+\r
+  @param  Question               The question.\r
+  @param  Value                  Unicode buffer save the question value.\r
+\r
+  @retval  Status whether convert the value success.\r
+\r
+**/\r
+EFI_STATUS\r
+BufferToValue (\r
+  IN OUT FORM_BROWSER_STATEMENT           *Question,\r
+  IN     CHAR16                           *Value\r
+  )\r
+{\r
+  CHAR16                       *StringPtr;\r
+  BOOLEAN                      IsBufferStorage;\r
+  CHAR16                       *DstBuf;\r
+  CHAR16                       TempChar;\r
+  UINTN                        LengthStr;\r
+  UINT8                        *Dst;\r
+  CHAR16                       TemStr[5];\r
+  UINTN                        Index;\r
+  UINT8                        DigitUint8;\r
+  BOOLEAN                      IsString;\r
+  UINTN                        Length;\r
+  EFI_STATUS                   Status;\r
+\r
+  IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ?  TRUE : FALSE);\r
+  if (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+      Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+    IsBufferStorage = TRUE;\r
+  } else {\r
+    IsBufferStorage = FALSE;\r
+  }\r
+\r
+  //\r
+  // Question Value is provided by Buffer Storage or NameValue Storage\r
+  //\r
+  if (Question->BufferValue != NULL) {\r
+    //\r
+    // This Question is password or orderedlist\r
+    //\r
+    Dst = Question->BufferValue;\r
+  } else {\r
+    //\r
+    // Other type of Questions\r
+    //\r
+    Dst = (UINT8 *) &Question->HiiValue.Value;\r
+  }\r
+\r
+  //\r
+  // Temp cut at the end of this section, end with '\0' or '&'.\r
+  //\r
+  StringPtr = Value;\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+  TempChar = *StringPtr;\r
+  *StringPtr = L'\0';\r
+\r
+  LengthStr = StrLen (Value);\r
+  Status    = EFI_SUCCESS;\r
+  if (!IsBufferStorage && IsString) {\r
+    //\r
+    // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
+    // Add string tail char L'\0' into Length\r
+    //\r
+    Length    = Question->StorageWidth + sizeof (CHAR16);\r
+    if (Length < ((LengthStr / 4 + 1) * 2)) {\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+    } else {\r
+      DstBuf = (CHAR16 *) Dst;\r
+      ZeroMem (TemStr, sizeof (TemStr));\r
+      for (Index = 0; Index < LengthStr; Index += 4) {\r
+        StrnCpy (TemStr, Value + Index, 4);\r
+        DstBuf[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
+      }\r
+      //\r
+      // Add tailing L'\0' character\r
+      //\r
+      DstBuf[Index/4] = L'\0';\r
+    }\r
+  } else {\r
+    if (Question->StorageWidth < ((LengthStr + 1) / 2)) {\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+    } else {\r
+      ZeroMem (TemStr, sizeof (TemStr));\r
+      for (Index = 0; Index < LengthStr; Index ++) {\r
+        TemStr[0] = Value[LengthStr - Index - 1];\r
+        DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+        if ((Index & 1) == 0) {\r
+          Dst [Index/2] = DigitUint8;\r
+        } else {\r
+          Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  *StringPtr = TempChar;\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Get Question's current Value.\r
@@ -1378,14 +1482,8 @@ GetQuestionValue (
   CHAR16              *Progress;\r
   CHAR16              *Result;\r
   CHAR16              *Value;\r
-  CHAR16              *StringPtr;\r
   UINTN               Length;\r
-  UINTN               Index;\r
-  UINTN               LengthStr;\r
   BOOLEAN             IsBufferStorage;\r
-  BOOLEAN             IsString;\r
-  CHAR16              TemStr[5];\r
-  UINT8               DigitUint8;\r
 \r
   Status = EFI_SUCCESS;\r
   Value  = NULL;\r
@@ -1538,7 +1636,6 @@ GetQuestionValue (
   } else {\r
     IsBufferStorage = FALSE;\r
   }\r
-  IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ?  TRUE : FALSE);\r
   if (GetValueFrom == GetSetValueWithEditBuffer || GetValueFrom == GetSetValueWithBuffer ) {\r
     if (IsBufferStorage) {\r
       if (GetValueFrom == GetSetValueWithEditBuffer) {\r
@@ -1560,45 +1657,7 @@ GetQuestionValue (
       }\r
 \r
       ASSERT (Value != NULL);\r
-      LengthStr = StrLen (Value);\r
-      Status    = EFI_SUCCESS;\r
-      if (IsString) {\r
-        //\r
-        // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
-        // Add string tail char L'\0' into Length\r
-        //\r
-        Length    = StorageWidth + sizeof (CHAR16);\r
-        if (Length < ((LengthStr / 4 + 1) * 2)) {\r
-          Status = EFI_BUFFER_TOO_SMALL;\r
-        } else {\r
-          StringPtr = (CHAR16 *) Dst;\r
-          ZeroMem (TemStr, sizeof (TemStr));\r
-          for (Index = 0; Index < LengthStr; Index += 4) {\r
-            StrnCpy (TemStr, Value + Index, 4);\r
-            StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
-          }\r
-          //\r
-          // Add tailing L'\0' character\r
-          //\r
-          StringPtr[Index/4] = L'\0';\r
-        }\r
-      } else {\r
-        if (StorageWidth < ((LengthStr + 1) / 2)) {\r
-          Status = EFI_BUFFER_TOO_SMALL;\r
-        } else {\r
-          ZeroMem (TemStr, sizeof (TemStr));\r
-          for (Index = 0; Index < LengthStr; Index ++) {\r
-            TemStr[0] = Value[LengthStr - Index - 1];\r
-            DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
-            if ((Index & 1) == 0) {\r
-              Dst [Index/2] = DigitUint8;\r
-            } else {\r
-              Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
-            }\r
-          }\r
-        }\r
-      }\r
-\r
+      Status = BufferToValue (Question, Value);\r
       FreePool (Value);\r
     }\r
   } else {\r
@@ -1663,54 +1722,7 @@ GetQuestionValue (
     //\r
     Value = Value + 1;\r
 \r
-    //\r
-    // Suppress <AltResp> if any\r
-    //\r
-    StringPtr = Value;\r
-    while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
-      StringPtr++;\r
-    }\r
-    *StringPtr = L'\0';\r
-\r
-    LengthStr = StrLen (Value);\r
-    Status    = EFI_SUCCESS;\r
-    if (!IsBufferStorage && IsString) {\r
-      //\r
-      // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
-      // Add string tail char L'\0' into Length\r
-      //\r
-      Length    = StorageWidth + sizeof (CHAR16);\r
-      if (Length < ((LengthStr / 4 + 1) * 2)) {\r
-        Status = EFI_BUFFER_TOO_SMALL;\r
-      } else {\r
-        StringPtr = (CHAR16 *) Dst;\r
-        ZeroMem (TemStr, sizeof (TemStr));\r
-        for (Index = 0; Index < LengthStr; Index += 4) {\r
-          StrnCpy (TemStr, Value + Index, 4);\r
-          StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
-        }\r
-        //\r
-        // Add tailing L'\0' character\r
-        //\r
-        StringPtr[Index/4] = L'\0';\r
-      }\r
-    } else {\r
-      if (StorageWidth < ((LengthStr + 1) / 2)) {\r
-        Status = EFI_BUFFER_TOO_SMALL;\r
-      } else {\r
-        ZeroMem (TemStr, sizeof (TemStr));\r
-        for (Index = 0; Index < LengthStr; Index ++) {\r
-          TemStr[0] = Value[LengthStr - Index - 1];\r
-          DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
-          if ((Index & 1) == 0) {\r
-            Dst [Index/2] = DigitUint8;\r
-          } else {\r
-            Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
+    Status = BufferToValue (Question, Value);\r
     if (EFI_ERROR (Status)) {\r
       FreePool (Result);\r
       return Status;\r
@@ -3373,205 +3385,173 @@ SubmitForm (
 }\r
 \r
 /**\r
-  Get Question default value from AltCfg string.\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\r
 \r
-  @param  FormSet                The form set.\r
-  @param  Question               The question.\r
-  @param  DefaultId              The default Id.\r
-\r
-  @retval EFI_SUCCESS            Question is reset to default value.\r
+  @param ConfigString  String to be converted\r
 \r
 **/\r
-EFI_STATUS\r
-GetDefaultValueFromAltCfg (\r
-  IN     FORM_BROWSER_FORMSET             *FormSet,\r
-  IN OUT FORM_BROWSER_STATEMENT           *Question,\r
-  IN     UINT16                           DefaultId\r
+VOID\r
+EFIAPI\r
+HiiToLower (\r
+  IN EFI_STRING  ConfigString\r
   )\r
 {\r
-  BOOLEAN             IsBufferStorage;\r
-  BOOLEAN             IsString;  \r
-  UINTN               Length;\r
-  BROWSER_STORAGE     *Storage;\r
-  CHAR16              *ConfigRequest;\r
-  CHAR16              *Progress;\r
-  CHAR16              *Result;\r
-  CHAR16              *ConfigResp;\r
-  CHAR16              *Value;\r
-  CHAR16              *StringPtr;\r
-  UINTN               LengthStr;\r
-  UINT8               *Dst;\r
-  CHAR16              TemStr[5];\r
-  UINTN               Index;\r
-  UINT8               DigitUint8;\r
-  EFI_STATUS          Status;\r
-\r
-  Status        = EFI_NOT_FOUND;\r
-  Length        = 0;\r
-  Dst           = NULL;\r
-  ConfigRequest = NULL;\r
-  Result        = NULL;\r
-  ConfigResp    = NULL;\r
-  Value         = NULL;\r
-  Storage       = Question->Storage;\r
+  EFI_STRING  String;\r
+  BOOLEAN     Lower;\r
 \r
-  if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
-    return Status;\r
-  }\r
+  ASSERT (ConfigString != NULL);\r
 \r
   //\r
-  // Question Value is provided by Buffer Storage or NameValue Storage\r
+  // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
   //\r
-  if (Question->BufferValue != NULL) {\r
-    //\r
-    // This Question is password or orderedlist\r
-    //\r
-    Dst = Question->BufferValue;\r
-  } else {\r
-    //\r
-    // Other type of Questions\r
-    //\r
-    Dst = (UINT8 *) &Question->HiiValue.Value;\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
+}\r
 \r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-    IsBufferStorage = TRUE;\r
-  } else {\r
-    IsBufferStorage = FALSE;\r
-  }\r
-  IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ?  TRUE : FALSE);\r
+/**\r
+  Find the point in the ConfigResp string for this question.\r
+\r
+  @param  Question               The question.\r
+  @param  ConfigResp             Get ConfigResp string.\r
+\r
+  @retval  point to the offset where is for this question.\r
+\r
+**/\r
+CHAR16 *\r
+GetOffsetFromConfigResp (\r
+  IN FORM_BROWSER_STATEMENT           *Question,\r
+  IN CHAR16                           *ConfigResp\r
+  )\r
+{\r
+  CHAR16                       *RequestElement;\r
+  CHAR16                       *BlockData;\r
 \r
   //\r
-  // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
-  //                   <ConfigHdr> + "&" + <VariableName>\r
+  // Type is EFI_HII_VARSTORE_NAME_VALUE.\r
   //\r
-  if (IsBufferStorage) {\r
-    Length  = StrLen (Storage->ConfigHdr);\r
-    Length += StrLen (Question->BlockName);\r
-  } else {\r
-    Length  = StrLen (Storage->ConfigHdr);\r
-    Length += StrLen (Question->VariableName) + 1;\r
-  }\r
-  ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
-  ASSERT (ConfigRequest != NULL);\r
-\r
-  StrCpy (ConfigRequest, Storage->ConfigHdr);\r
-  if (IsBufferStorage) {\r
-    StrCat (ConfigRequest, Question->BlockName);\r
-  } else {\r
-    StrCat (ConfigRequest, L"&");\r
-    StrCat (ConfigRequest, Question->VariableName);\r
-  }\r
+  if (Question->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    RequestElement = StrStr (ConfigResp, Question->VariableName);\r
+    if (RequestElement != NULL) {\r
+      //\r
+      // Skip the "VariableName=" field.\r
+      //\r
+      RequestElement += StrLen (Question->VariableName) + 1;\r
+    }\r
 \r
-  Status = mHiiConfigRouting->ExtractConfig (\r
-                                    mHiiConfigRouting,\r
-                                    ConfigRequest,\r
-                                    &Progress,\r
-                                    &Result\r
-                                    );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
+    return RequestElement;\r
   }\r
 \r
   //\r
-  // Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
-  //    Get the default configuration string according to the default ID.\r
+  // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER\r
   //\r
-  Status = mHiiConfigRouting->GetAltConfig (\r
-                                mHiiConfigRouting,\r
-                                Result,\r
-                                &Storage->Guid,\r
-                                Storage->Name,\r
-                                NULL,\r
-                                &DefaultId,  // it can be NULL to get the current setting.\r
-                                &ConfigResp\r
-                              );\r
-  \r
+\r
   //\r
-  // The required setting can't be found. So, it is not required to be validated and set.\r
+  // 1. Directly use Question->BlockName to find.\r
   //\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-\r
-  if (ConfigResp == NULL) {\r
-    Status = EFI_NOT_FOUND;\r
-    goto Done;\r
+  RequestElement = StrStr (ConfigResp, Question->BlockName);\r
+  if (RequestElement != NULL) {\r
+    //\r
+    // Skip the "Question->BlockName&VALUE=" field.\r
+    //\r
+    RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
+    return RequestElement;\r
   }\r
-\r
+  \r
   //\r
-  // Skip <ConfigRequest>\r
+  // 2. Change all hex digits in Question->BlockName to lower and compare again.\r
   //\r
-  if (IsBufferStorage) {\r
-    Value = StrStr (ConfigResp, L"&VALUE");\r
-    ASSERT (Value != NULL);\r
+  BlockData = AllocateCopyPool (StrSize(Question->BlockName), Question->BlockName);\r
+  ASSERT (BlockData != NULL);\r
+  HiiToLower (BlockData);\r
+  RequestElement = StrStr (ConfigResp, BlockData);\r
+  FreePool (BlockData);\r
+\r
+  if (RequestElement != NULL) {\r
     //\r
-    // Skip "&VALUE"\r
+    // Skip the "Question->BlockName&VALUE=" field.\r
     //\r
-    Value = Value + 6;\r
-  } else {\r
-    Value = StrStr (ConfigResp, Question->VariableName);\r
-    ASSERT (Value != NULL);\r
-\r
-    Value = Value + StrLen (Question->VariableName);\r
+    RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
   }\r
-  if (*Value != '=') {\r
-    Status = EFI_NOT_FOUND;\r
-    goto Done;\r
+\r
+  return RequestElement;\r
+}\r
+\r
+/**\r
+  Get Question default value from AltCfg string.\r
+\r
+  @param  FormSet                The form set.\r
+  @param  Form                   The form\r
+  @param  Question               The question.\r
+\r
+  @retval EFI_SUCCESS            Question is reset to default value.\r
+\r
+**/\r
+EFI_STATUS\r
+GetDefaultValueFromAltCfg (\r
+  IN     FORM_BROWSER_FORMSET             *FormSet,\r
+  IN     FORM_BROWSER_FORM                *Form,\r
+  IN OUT FORM_BROWSER_STATEMENT           *Question\r
+  )\r
+{ \r
+  BROWSER_STORAGE              *Storage;\r
+  FORMSET_STORAGE              *FormSetStorage;\r
+  CHAR16                       *ConfigResp;\r
+  CHAR16                       *Value;\r
+  LIST_ENTRY                   *Link;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
+\r
+  Storage = Question->Storage;\r
+  if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
+    return EFI_NOT_FOUND;\r
   }\r
-  //\r
-  // Skip '=', point to value\r
-  //\r
-  Value = Value + 1;\r
 \r
   //\r
-  // Suppress <AltResp> if any\r
+  // Try to get AltCfg string from form. If not found it, then\r
+  // try to get it from formset.\r
   //\r
-  StringPtr = Value;\r
-  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
-    StringPtr++;\r
-  }\r
-  *StringPtr = L'\0';\r
+  ConfigResp    = NULL;\r
+  Link = GetFirstNode (&Form->ConfigRequestHead);\r
+  while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+    Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
 \r
-  LengthStr = StrLen (Value);\r
-  if (!IsBufferStorage && IsString) {\r
-    StringPtr = (CHAR16 *) Dst;\r
-    ZeroMem (TemStr, sizeof (TemStr));\r
-    for (Index = 0; Index < LengthStr; Index += 4) {\r
-      StrnCpy (TemStr, Value + Index, 4);\r
-      StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
+    if (Storage == ConfigInfo->Storage) {\r
+      ConfigResp = ConfigInfo->ConfigAltResp;\r
+      break;\r
     }\r
-    //\r
-    // Add tailing L'\0' character\r
-    //\r
-    StringPtr[Index/4] = L'\0';\r
-  } else {\r
-    ZeroMem (TemStr, sizeof (TemStr));\r
-    for (Index = 0; Index < LengthStr; Index ++) {\r
-      TemStr[0] = Value[LengthStr - Index - 1];\r
-      DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
-      if ((Index & 1) == 0) {\r
-        Dst [Index/2] = DigitUint8;\r
-      } else {\r
-        Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
+  }\r
+\r
+  if (ConfigResp == NULL) {\r
+    Link = GetFirstNode (&FormSet->StorageListHead);\r
+    while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+      FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+      Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+      if (Storage == FormSetStorage->BrowserStorage) {\r
+        ConfigResp = FormSetStorage->ConfigAltResp;\r
+        break;\r
       }\r
     }\r
   }\r
 \r
-Done:\r
-  if (ConfigRequest != NULL){\r
-    FreePool (ConfigRequest);\r
+  if (ConfigResp == NULL) {\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
-  if (ConfigResp != NULL) {\r
-    FreePool (ConfigResp);\r
-  }\r
-  \r
-  if (Result != NULL) {\r
-    FreePool (Result);\r
+  Value = GetOffsetFromConfigResp (Question, ConfigResp);\r
+  if (Value == NULL) {\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
-  return Status;\r
+  return BufferToValue (Question, Value);\r
 }\r
 \r
 /**\r
@@ -3824,7 +3804,7 @@ GetQuestionDefault (
   // Get default value from altcfg string.\r
   //\r
   if (ConfigAccess != NULL) {  \r
-    Status = GetDefaultValueFromAltCfg(FormSet, Question, DefaultId);\r
+    Status = GetDefaultValueFromAltCfg(FormSet, Form, Question);\r
     if (!EFI_ERROR (Status)) {\r
         return Status;\r
     }\r
@@ -4005,6 +3985,228 @@ GetQuestionDefault (
   return Status;\r
 }\r
 \r
+/**\r
+  Get AltCfg string for current form.\r
+\r
+  @param  FormSet                Form data structure.\r
+  @param  Form                   Form data structure.\r
+  @param  DefaultId              The Class of the default.\r
+\r
+**/\r
+VOID\r
+ExtractAltCfgForForm (\r
+  IN FORM_BROWSER_FORMSET   *FormSet,\r
+  IN FORM_BROWSER_FORM      *Form,\r
+  IN UINT16                 DefaultId\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  LIST_ENTRY                   *Link;\r
+  CHAR16                       *ConfigResp;\r
+  CHAR16                       *Progress;\r
+  CHAR16                       *Result;\r
+  BROWSER_STORAGE              *Storage;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
+  FORMSET_STORAGE              *FormSetStorage;\r
+\r
+  //\r
+  // Check whether has get AltCfg string for this formset.\r
+  // If yes, no need to get AltCfg for form.\r
+  //\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+    FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+    Storage        = FormSetStorage->BrowserStorage;\r
+    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+    if (Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE &&\r
+        FormSetStorage->ElementCount != 0 &&\r
+        FormSetStorage->ConfigAltResp != NULL) {\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get AltCfg string for each form.\r
+  //\r
+  Link = GetFirstNode (&Form->ConfigRequestHead);\r
+  while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+    Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+    Storage = ConfigInfo->Storage;\r
+    if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // 1. Skip if there is no RequestElement\r
+    //\r
+    if (ConfigInfo->ElementCount == 0) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // 2. Get value through hii config routine protocol.\r
+    //\r
+    Status = mHiiConfigRouting->ExtractConfig (\r
+                                      mHiiConfigRouting,\r
+                                      ConfigInfo->ConfigRequest,\r
+                                      &Progress,\r
+                                      &Result\r
+                                      );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
+    //    Get the default configuration string according to the default ID.\r
+    //\r
+    Status = mHiiConfigRouting->GetAltConfig (\r
+                                  mHiiConfigRouting,\r
+                                  Result,\r
+                                  &Storage->Guid,\r
+                                  Storage->Name,\r
+                                  NULL,\r
+                                  &DefaultId,  // it can be NULL to get the current setting.\r
+                                  &ConfigResp\r
+                                );\r
+    FreePool (Result);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    ConfigInfo->ConfigAltResp = ConfigResp;\r
+  }\r
+}\r
+\r
+/**\r
+  Clean AltCfg string for current form.\r
+\r
+  @param  Form                   Form data structure.\r
+\r
+**/\r
+VOID\r
+CleanAltCfgForForm (\r
+  IN FORM_BROWSER_FORM   *Form\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
+\r
+  Link = GetFirstNode (&Form->ConfigRequestHead);\r
+  while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+    Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+    if (ConfigInfo->ConfigAltResp != NULL) {\r
+      FreePool (ConfigInfo->ConfigAltResp);\r
+      ConfigInfo->ConfigAltResp = NULL;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Get AltCfg string for current formset.\r
+\r
+  @param  FormSet                Form data structure.\r
+  @param  DefaultId              The Class of the default.\r
+\r
+**/\r
+VOID\r
+ExtractAltCfgForFormSet (\r
+  IN FORM_BROWSER_FORMSET   *FormSet,\r
+  IN UINT16                 DefaultId\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  LIST_ENTRY              *Link;\r
+  CHAR16                  *ConfigResp;\r
+  CHAR16                  *Progress;\r
+  CHAR16                  *Result;\r
+  BROWSER_STORAGE         *Storage;\r
+  FORMSET_STORAGE         *FormSetStorage;\r
+\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+    FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+    Storage        = FormSetStorage->BrowserStorage;\r
+    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+    if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // 1. Skip if there is no RequestElement\r
+    //\r
+    if (FormSetStorage->ElementCount == 0) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // 2. Get value through hii config routine protocol.\r
+    //\r
+    Status = mHiiConfigRouting->ExtractConfig (\r
+                                      mHiiConfigRouting,\r
+                                      FormSetStorage->ConfigRequest,\r
+                                      &Progress,\r
+                                      &Result\r
+                                      );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
+    //    Get the default configuration string according to the default ID.\r
+    //\r
+    Status = mHiiConfigRouting->GetAltConfig (\r
+                                  mHiiConfigRouting,\r
+                                  Result,\r
+                                  &Storage->Guid,\r
+                                  Storage->Name,\r
+                                  NULL,\r
+                                  &DefaultId,  // it can be NULL to get the current setting.\r
+                                  &ConfigResp\r
+                                );\r
+\r
+    FreePool (Result);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    FormSetStorage->ConfigAltResp = ConfigResp;\r
+  }\r
+\r
+}\r
+\r
+/**\r
+  Clean AltCfg string for current formset.\r
+\r
+  @param  FormSet                Form data structure.\r
+\r
+**/\r
+VOID\r
+CleanAltCfgForFormSet (\r
+  IN FORM_BROWSER_FORMSET   *FormSet\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORMSET_STORAGE         *FormSetStorage;\r
+\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+    FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+    if (FormSetStorage->ConfigAltResp != NULL) {\r
+      FreePool (FormSetStorage->ConfigAltResp);\r
+      FormSetStorage->ConfigAltResp = NULL;\r
+    }\r
+  }\r
+}\r
 \r
 /**\r
   Reset Questions to their initial value or default value in a Form, Formset or System.\r
@@ -4056,8 +4258,13 @@ ExtractDefault (
   if (GetDefaultValueScope == GetDefaultForStorage && Storage == NULL) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  \r
+\r
   if (SettingScope == FormLevel) {\r
+    //\r
+    // Prepare the AltCfg String for form.\r
+    //\r
+    ExtractAltCfgForForm (FormSet, Form, DefaultId);\r
+\r
     //\r
     // Extract Form default\r
     //\r
@@ -4114,13 +4321,28 @@ ExtractDefault (
         SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
       }\r
     }\r
+\r
+    //\r
+    // Clean the AltCfg String.\r
+    //\r
+    CleanAltCfgForForm(Form);\r
   } else if (SettingScope == FormSetLevel) {\r
+    //\r
+    // Prepare the AltCfg String for formset.\r
+    //\r
+    ExtractAltCfgForFormSet (FormSet, DefaultId);\r
+\r
     FormLink = GetFirstNode (&FormSet->FormListHead);\r
     while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
       Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
       ExtractDefault (FormSet, Form, DefaultId, FormLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);\r
       FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
     }\r
+\r
+    //\r
+    // Clean the AltCfg String.\r
+    //\r
+    CleanAltCfgForFormSet (FormSet);\r
   } else if (SettingScope == SystemLevel) {\r
     //\r
     // Preload all Hii formset.\r