]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
Fix a bug for vlan ping failure.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
index ba72d1220b594cb1857ed9bba97eee0ee1079a52..c7c7f9ae43eb780aede99081c6d567d51693f717 100644 (file)
@@ -48,11 +48,13 @@ LIST_ENTRY      gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFor
 LIST_ENTRY      gBrowserHotKeyList  = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);\r
 LIST_ENTRY      gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
 \r
+BOOLEAN               gFinishRetrieveCall;\r
 BOOLEAN               gResetRequired;\r
 BOOLEAN               gExitRequired;\r
 BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;\r
 BOOLEAN               mBrowserScopeFirstSet = TRUE;\r
 EXIT_HANDLER          ExitHandlerFunction = NULL;\r
+FORM_BROWSER_FORMSET  *mSystemLevelFormSet;\r
 \r
 //\r
 // Browser Global Strings\r
@@ -255,6 +257,12 @@ LoadAllHiiFormset (
   UINTN                   Index;\r
   EFI_GUID                ZeroGuid;\r
   EFI_STATUS              Status;\r
+  FORM_BROWSER_FORMSET    *OldFormset;\r
+  BOOLEAN                 OldRetrieveValue;\r
+\r
+  OldFormset = mSystemLevelFormSet;\r
+  OldRetrieveValue = gFinishRetrieveCall;\r
+  gFinishRetrieveCall = FALSE;\r
 \r
   //\r
   // Get all the Hii handles\r
@@ -278,6 +286,8 @@ LoadAllHiiFormset (
     //\r
     LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
     ASSERT (LocalFormSet != NULL);\r
+    mSystemLevelFormSet = LocalFormSet;\r
+\r
     ZeroMem (&ZeroGuid, sizeof (ZeroGuid));\r
     Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);\r
     if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {\r
@@ -300,6 +310,9 @@ LoadAllHiiFormset (
   // Free resources, and restore gOldFormSet and gClassOfVfr\r
   //\r
   FreePool (HiiHandles);\r
+\r
+  gFinishRetrieveCall = OldRetrieveValue;\r
+  mSystemLevelFormSet = OldFormset;\r
 }\r
 \r
 /**\r
@@ -357,6 +370,7 @@ SendForm (
   //\r
   SaveBrowserContext ();\r
 \r
+  gFinishRetrieveCall = FALSE;\r
   gResetRequired = FALSE;\r
   gExitRequired  = FALSE;\r
   Status         = EFI_SUCCESS;\r
@@ -388,6 +402,7 @@ SendForm (
         break;\r
       }\r
       Selection->FormSet = FormSet;\r
+      mSystemLevelFormSet = FormSet;\r
 \r
       //\r
       // Display this formset\r
@@ -397,6 +412,7 @@ SendForm (
       Status = SetupBrowser (Selection);\r
 \r
       gCurrentSelection = NULL;\r
+      mSystemLevelFormSet = NULL;\r
 \r
       //\r
       // If no data is changed, don't need to save current FormSet into the maintain list.\r
@@ -580,7 +596,6 @@ BrowserCallback (
   LIST_ENTRY            *Link;\r
   BROWSER_STORAGE       *Storage;\r
   FORMSET_STORAGE       *FormsetStorage;\r
-  FORM_BROWSER_FORMSET  *FormSet;\r
   UINTN                 TotalSize;\r
   BOOLEAN               Found;\r
 \r
@@ -630,6 +645,17 @@ BrowserCallback (
         }\r
       }\r
 \r
+      if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE ||\r
+          Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+        if (mSystemLevelFormSet == NULL || mSystemLevelFormSet->HiiHandle == NULL) {\r
+          return EFI_NOT_FOUND;\r
+        }\r
+\r
+        if (Storage->HiiHandle != mSystemLevelFormSet->HiiHandle) {\r
+          continue;\r
+        }\r
+      }\r
+\r
       Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
@@ -650,16 +676,15 @@ BrowserCallback (
     //\r
     // GUID/Name is not specified, take the first storage in FormSet\r
     //\r
-    if (gCurrentSelection == NULL) {\r
+    if (mSystemLevelFormSet == NULL) {\r
       return EFI_NOT_READY;\r
     }\r
 \r
     //\r
     // Generate <ConfigResp>\r
     //\r
-    FormSet = gCurrentSelection->FormSet;\r
-    Link = GetFirstNode (&FormSet->StorageListHead);\r
-    if (IsNull (&FormSet->StorageListHead, Link)) {\r
+    Link = GetFirstNode (&mSystemLevelFormSet->StorageListHead);\r
+    if (IsNull (&mSystemLevelFormSet->StorageListHead, Link)) {\r
       return EFI_UNSUPPORTED;\r
     }\r
 \r
@@ -766,7 +791,8 @@ InitializeSetup (
   //\r
   // Install FormBrowserEx2 protocol\r
   //\r
-  InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);  \r
+  InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
+  InitializeListHead (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
   mPrivateData.Handle = NULL;\r
   Status = gBS->InstallProtocolInterface (\r
                   &mPrivateData.Handle,\r
@@ -1244,7 +1270,6 @@ GetQuestionValue (
   BOOLEAN             IsString;\r
   CHAR16              TemStr[5];\r
   UINT8               DigitUint8;\r
-  UINT8               *TemBuffer;\r
 \r
   Status = EFI_SUCCESS;\r
   Value  = NULL;\r
@@ -1254,13 +1279,6 @@ GetQuestionValue (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Statement don't have storage, skip them\r
-  //\r
-  if (Question->QuestionId == 0) {\r
-    return Status;\r
-  }\r
-\r
   //\r
   // Question value is provided by an Expression, evaluate it\r
   //\r
@@ -1468,147 +1486,118 @@ GetQuestionValue (
       FreePool (Value);\r
     }\r
   } else {\r
-    if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-      //\r
-      // Request current settings from Configuration Driver\r
-      //\r
-      if (FormSet->ConfigAccess == NULL) {\r
-        return EFI_NOT_FOUND;\r
-      }\r
-\r
-      //\r
-      // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
-      //                   <ConfigHdr> + "&" + <VariableName>\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
+    // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
+    //                   <ConfigHdr> + "&" + <VariableName>\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
+    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
 \r
-      Status = FormSet->ConfigAccess->ExtractConfig (\r
-                                        FormSet->ConfigAccess,\r
-                                        ConfigRequest,\r
-                                        &Progress,\r
-                                        &Result\r
-                                        );\r
-      FreePool (ConfigRequest);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
+    //\r
+    // Request current settings from Configuration Driver\r
+    //\r
+    Status = mHiiConfigRouting->ExtractConfig (\r
+                                      mHiiConfigRouting,\r
+                                      ConfigRequest,\r
+                                      &Progress,\r
+                                      &Result\r
+                                      );\r
+    FreePool (ConfigRequest);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-      //\r
-      // Skip <ConfigRequest>\r
-      //\r
-      if (IsBufferStorage) {\r
-        Value = StrStr (Result, L"&VALUE");\r
-        if (Value == NULL) {\r
-          FreePool (Result);\r
-          return EFI_NOT_FOUND;\r
-        }\r
-        //\r
-        // Skip "&VALUE"\r
-        //\r
-        Value = Value + 6;\r
-      } else {\r
-        Value = Result + Length;\r
-      }\r
-      if (*Value != '=') {\r
+    //\r
+    // Skip <ConfigRequest>\r
+    //\r
+    if (IsBufferStorage) {\r
+      Value = StrStr (Result, L"&VALUE");\r
+      if (Value == NULL) {\r
         FreePool (Result);\r
         return EFI_NOT_FOUND;\r
       }\r
       //\r
-      // Skip '=', point to value\r
+      // Skip "&VALUE"\r
       //\r
-      Value = Value + 1;\r
+      Value = Value + 6;\r
+    } else {\r
+      Value = Result + Length;\r
+    }\r
+    if (*Value != '=') {\r
+      FreePool (Result);\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
+    //\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
-      // Suppress <AltResp> if any\r
+      // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
+      // Add string tail char L'\0' into Length\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
+      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
-        // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
-        // Add string tail char L'\0' into Length\r
+        // Add tailing L'\0' character\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
+        StringPtr[Index/4] = L'\0';\r
+      }\r
+    } else {\r
+      if (StorageWidth < ((LengthStr + 1) / 2)) {\r
+        Status = EFI_BUFFER_TOO_SMALL;\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
+        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
-      if (EFI_ERROR (Status)) {\r
-        FreePool (Result);\r
-        return Status;\r
-      }\r
-    } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-      TemBuffer = NULL;\r
-      TemBuffer = AllocateZeroPool (Storage->Size);\r
-      if (TemBuffer == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        return Status;\r
-      }\r
-      Length = Storage->Size;\r
-      Status = gRT->GetVariable (\r
-                       Storage->Name,\r
-                       &Storage->Guid,\r
-                       NULL,\r
-                       &Length,\r
-                       TemBuffer\r
-                       );\r
-      if (EFI_ERROR (Status)) {\r
-        FreePool (TemBuffer);\r
-        return Status;\r
-      }\r
-\r
-      CopyMem (Dst, TemBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
-\r
-      FreePool (TemBuffer);\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (Result);\r
+      return Status;\r
     }\r
 \r
     //\r
@@ -1676,13 +1665,6 @@ SetQuestionValue (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Statement don't have storage, skip them\r
-  //\r
-  if (Question->QuestionId == 0) {\r
-    return Status;\r
-  }\r
-\r
   //\r
   // If Question value is provided by an Expression, then it is read only\r
   //\r
@@ -1859,111 +1841,78 @@ SetQuestionValue (
       }\r
     }\r
   } else if (SetValueTo == GetSetValueWithHiiDriver) {\r
-    if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-      //\r
-      // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||\r
-      //                <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"\r
-      //\r
-      if (IsBufferStorage) {\r
-        Length = StrLen (Question->BlockName) + 7;\r
-      } else {\r
-        Length = StrLen (Question->VariableName) + 2;\r
-      }\r
-      if (!IsBufferStorage && IsString) {\r
-        Length += (StrLen ((CHAR16 *) Src) * 4);\r
-      } else {\r
-        Length += (StorageWidth * 2);\r
-      }\r
-      ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));\r
-      ASSERT (ConfigResp != NULL);\r
+    //\r
+    // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||\r
+    //                <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"\r
+    //\r
+    if (IsBufferStorage) {\r
+      Length = StrLen (Question->BlockName) + 7;\r
+    } else {\r
+      Length = StrLen (Question->VariableName) + 2;\r
+    }\r
+    if (!IsBufferStorage && IsString) {\r
+      Length += (StrLen ((CHAR16 *) Src) * 4);\r
+    } else {\r
+      Length += (StorageWidth * 2);\r
+    }\r
+    ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));\r
+    ASSERT (ConfigResp != NULL);\r
 \r
-      StrCpy (ConfigResp, Storage->ConfigHdr);\r
-      if (IsBufferStorage) {\r
-        StrCat (ConfigResp, Question->BlockName);\r
-        StrCat (ConfigResp, L"&VALUE=");\r
-      } else {\r
-        StrCat (ConfigResp, L"&");\r
-        StrCat (ConfigResp, Question->VariableName);\r
-        StrCat (ConfigResp, L"=");\r
-      }\r
+    StrCpy (ConfigResp, Storage->ConfigHdr);\r
+    if (IsBufferStorage) {\r
+      StrCat (ConfigResp, Question->BlockName);\r
+      StrCat (ConfigResp, L"&VALUE=");\r
+    } else {\r
+      StrCat (ConfigResp, L"&");\r
+      StrCat (ConfigResp, Question->VariableName);\r
+      StrCat (ConfigResp, L"=");\r
+    }\r
 \r
-      Value = ConfigResp + StrLen (ConfigResp);\r
-\r
-      if (!IsBufferStorage && IsString) {\r
-        //\r
-        // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
-        //\r
-        TemName = (CHAR16 *) Src;\r
-        TemString = Value;\r
-        for (; *TemName != L'\0'; TemName++) {\r
-          TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
-        }\r
-      } else {\r
-        //\r
-        // Convert Buffer to Hex String\r
-        //\r
-        TemBuffer = Src + StorageWidth - 1;\r
-        TemString = Value;\r
-        for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
-          TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
-        }\r
-      }\r
+    Value = ConfigResp + StrLen (ConfigResp);\r
 \r
+    if (!IsBufferStorage && IsString) {\r
       //\r
-      // Convert to lower char.\r
+      // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
       //\r
-      for (TemString = Value; *Value != L'\0'; Value++) {\r
-        if (*Value >= L'A' && *Value <= L'Z') {\r
-          *Value = (CHAR16) (*Value - L'A' + L'a');\r
-        }\r
+      TemName = (CHAR16 *) Src;\r
+      TemString = Value;\r
+      for (; *TemName != L'\0'; TemName++) {\r
+        TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
       }\r
-\r
+    } else {\r
       //\r
-      // Submit Question Value to Configuration Driver\r
+      // Convert Buffer to Hex String\r
       //\r
-      if (FormSet->ConfigAccess != NULL) {\r
-        Status = FormSet->ConfigAccess->RouteConfig (\r
-                                          FormSet->ConfigAccess,\r
-                                          ConfigResp,\r
-                                          &Progress\r
-                                          );\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (ConfigResp);\r
-          return Status;\r
-        }\r
-      }\r
-      FreePool (ConfigResp);\r
-      \r
-    } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-      TemBuffer = NULL;\r
-      TemBuffer = AllocateZeroPool(Storage->Size);\r
-      if (TemBuffer == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        return Status;\r
+      TemBuffer = Src + StorageWidth - 1;\r
+      TemString = Value;\r
+      for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
+        TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
       }\r
-      Length = Storage->Size;\r
-      Status = gRT->GetVariable (\r
-                       Storage->Name,\r
-                       &Storage->Guid,\r
-                       NULL,\r
-                       &Length,\r
-                       TemBuffer\r
-                       );\r
-\r
-      CopyMem (TemBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
-      \r
-      Status = gRT->SetVariable (\r
-                       Storage->Name,\r
-                       &Storage->Guid,\r
-                       Storage->Attributes,\r
-                       Storage->Size,\r
-                       TemBuffer\r
-                       );\r
-      FreePool (TemBuffer);\r
-      if (EFI_ERROR (Status)){\r
-        return Status;\r
+    }\r
+\r
+    //\r
+    // Convert to lower char.\r
+    //\r
+    for (TemString = Value; *Value != L'\0'; Value++) {\r
+      if (*Value >= L'A' && *Value <= L'Z') {\r
+        *Value = (CHAR16) (*Value - L'A' + L'a');\r
       }\r
     }\r
+\r
+    //\r
+    // Submit Question Value to Configuration Driver\r
+    //\r
+    Status = mHiiConfigRouting->RouteConfig (\r
+                                      mHiiConfigRouting,\r
+                                      ConfigResp,\r
+                                      &Progress\r
+                                      );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (ConfigResp);\r
+      return Status;\r
+    }\r
+    FreePool (ConfigResp);\r
+    \r
     //\r
     // Sync storage, from editbuffer to buffer.\r
     //\r
@@ -2374,7 +2323,8 @@ DiscardForm (
   LIST_ENTRY                   *Link;\r
   FORMSET_STORAGE              *Storage;\r
   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
-  FORM_BROWSER_FORMSET    *LocalFormSet;\r
+  FORM_BROWSER_FORMSET         *LocalFormSet;\r
+  FORM_BROWSER_FORMSET         *OldFormSet;\r
 \r
   //\r
   // Check the supported setting level.\r
@@ -2453,7 +2403,8 @@ DiscardForm (
     //\r
     // System Level Discard.\r
     //\r
-    \r
+    OldFormSet = mSystemLevelFormSet;\r
+\r
     //\r
     // Discard changed value for each FormSet in the maintain list.\r
     //\r
@@ -2464,6 +2415,9 @@ DiscardForm (
       if (!ValidateFormSet(LocalFormSet)) {\r
         continue;\r
       }\r
+\r
+      mSystemLevelFormSet = LocalFormSet;\r
+\r
       DiscardForm (LocalFormSet, NULL, FormSetLevel);\r
       if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
         //\r
@@ -2474,6 +2428,8 @@ DiscardForm (
         DestroyFormSet (LocalFormSet);\r
       }\r
     }\r
+\r
+    mSystemLevelFormSet = OldFormSet;\r
   }\r
 \r
   return EFI_SUCCESS;  \r
@@ -2503,8 +2459,6 @@ SubmitForm (
   EFI_STRING              Progress;\r
   BROWSER_STORAGE         *Storage;\r
   FORMSET_STORAGE         *FormSetStorage;\r
-  UINTN                   BufferSize;\r
-  UINT8                   *TmpBuf;  \r
   FORM_BROWSER_FORMSET    *LocalFormSet;\r
   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
@@ -2556,72 +2510,18 @@ SubmitForm (
       }\r
 \r
       //\r
-      // 2. Set value to hii driver or efi variable.\r
+      // 2. Set value to hii config routine protocol.\r
       //\r
-      if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
-          Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-        //\r
-        // Send <ConfigResp> to Configuration Driver\r
-        //\r
-        if (FormSet->ConfigAccess != NULL) {\r
-          Status = FormSet->ConfigAccess->RouteConfig (\r
-                                            FormSet->ConfigAccess,\r
-                                            ConfigResp,\r
-                                            &Progress\r
-                                            );\r
-          if (EFI_ERROR (Status)) {\r
-            FreePool (ConfigResp);\r
-            return Status;\r
-          }\r
-        }\r
-      } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-        TmpBuf = NULL;\r
-        TmpBuf = AllocateZeroPool(Storage->Size);\r
-        if (TmpBuf == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          return Status;\r
-        }\r
-\r
-        BufferSize = Storage->Size;\r
-        Status = gRT->GetVariable (\r
-                         Storage->Name,\r
-                         &Storage->Guid,\r
-                         NULL,\r
-                         &BufferSize,\r
-                         TmpBuf\r
-                         );\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (TmpBuf);\r
-          FreePool (ConfigResp);\r
-          return Status;\r
-        }\r
-        ASSERT (BufferSize == Storage->Size);      \r
-        Status = mHiiConfigRouting->ConfigToBlock (\r
-                                      mHiiConfigRouting,\r
-                                      ConfigResp,\r
-                                      TmpBuf,\r
-                                      &BufferSize,\r
-                                      &Progress\r
-                                      );\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (TmpBuf);\r
-          FreePool (ConfigResp);\r
-          return Status;\r
-        }\r
-\r
-        Status = gRT->SetVariable (\r
-                         Storage->Name,\r
-                         &Storage->Guid,\r
-                         Storage->Attributes,\r
-                         Storage->Size,\r
-                         TmpBuf\r
-                         );\r
-        FreePool (TmpBuf);\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (ConfigResp);\r
-          return Status;\r
-        }\r
+      Status = mHiiConfigRouting->RouteConfig (\r
+                                        mHiiConfigRouting,\r
+                                        ConfigResp,\r
+                                        &Progress\r
+                                        );\r
+      if (EFI_ERROR (Status)) {\r
+        FreePool (ConfigResp);\r
+        return Status;\r
       }\r
+\r
       FreePool (ConfigResp);\r
       //\r
       // 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
@@ -2662,69 +2562,19 @@ SubmitForm (
         return Status;\r
       }\r
 \r
-      if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
-          Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-\r
-        //\r
-        // 2. Send <ConfigResp> to Configuration Driver\r
-        //\r
-        if (FormSet->ConfigAccess != NULL) {\r
-          Status = FormSet->ConfigAccess->RouteConfig (\r
-                                            FormSet->ConfigAccess,\r
-                                            ConfigResp,\r
-                                            &Progress\r
-                                            );\r
-          if (EFI_ERROR (Status)) {\r
-            FreePool (ConfigResp);\r
-            return Status;\r
-          }\r
-        }\r
-      } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-        //\r
-        // 1&2. Set the edit data to the variable.\r
-        //\r
-        TmpBuf = NULL;\r
-        TmpBuf = AllocateZeroPool (Storage->Size);\r
-        if (TmpBuf == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          return Status;\r
-        }        \r
-        BufferSize = Storage->Size;\r
-        Status = gRT->GetVariable (\r
-                       Storage->Name,\r
-                       &Storage->Guid,\r
-                       NULL,\r
-                       &BufferSize,\r
-                       TmpBuf\r
-                       );\r
-        ASSERT (BufferSize == Storage->Size);      \r
-        Status = mHiiConfigRouting->ConfigToBlock (\r
-                                      mHiiConfigRouting,\r
-                                      ConfigResp,\r
-                                      TmpBuf,\r
-                                      &BufferSize,\r
-                                      &Progress\r
-                                      );\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (TmpBuf);\r
-          FreePool (ConfigResp);\r
-          return Status;\r
-        }\r
-\r
-        Status = gRT->SetVariable (\r
-                         Storage->Name,\r
-                         &Storage->Guid,\r
-                         Storage->Attributes,\r
-                         Storage->Size,\r
-                         TmpBuf\r
-                         );\r
-        if (EFI_ERROR (Status)) {\r
-          FreePool (TmpBuf);\r
-          FreePool (ConfigResp);\r
-          return Status;\r
-        }\r
-        FreePool (TmpBuf);\r
+      //\r
+      // 2. Send <ConfigResp> to Routine config Protocol.\r
+      //\r
+      Status = mHiiConfigRouting->RouteConfig (\r
+                                        mHiiConfigRouting,\r
+                                        ConfigResp,\r
+                                        &Progress\r
+                                        );\r
+      if (EFI_ERROR (Status)) {\r
+        FreePool (ConfigResp);\r
+        return Status;\r
       }\r
+\r
       FreePool (ConfigResp);\r
       //\r
       // 3. Config success, update storage shadow Buffer\r
@@ -2809,9 +2659,7 @@ GetDefaultValueFromAltCfg (
   Value         = NULL;\r
   Storage       = Question->Storage;\r
 \r
-  if ((Storage == NULL) || \r
-      (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) || \r
-      (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+  if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
     return Status;\r
   }\r
 \r
@@ -2830,7 +2678,11 @@ GetDefaultValueFromAltCfg (
     Dst = (UINT8 *) &Question->HiiValue.Value;\r
   }\r
 \r
-  IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\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
   //\r
@@ -2855,8 +2707,8 @@ GetDefaultValueFromAltCfg (
     StrCat (ConfigRequest, Question->VariableName);\r
   }\r
 \r
-  Status = FormSet->ConfigAccess->ExtractConfig (\r
-                                    FormSet->ConfigAccess,\r
+  Status = mHiiConfigRouting->ExtractConfig (\r
+                                    mHiiConfigRouting,\r
                                     ConfigRequest,\r
                                     &Progress,\r
                                     &Result\r
@@ -2886,6 +2738,11 @@ GetDefaultValueFromAltCfg (
     goto Done;\r
   }\r
 \r
+  if (ConfigResp == NULL) {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Done;\r
+  }\r
+\r
   //\r
   // Skip <ConfigRequest>\r
   //\r
@@ -3415,6 +3272,7 @@ ExtractDefault (
   LIST_ENTRY              *Link;\r
   FORM_BROWSER_STATEMENT  *Question;\r
   FORM_BROWSER_FORMSET    *LocalFormSet;\r
+  FORM_BROWSER_FORMSET    *OldFormSet;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -3498,7 +3356,9 @@ ExtractDefault (
     // Preload all Hii formset.\r
     //\r
     LoadAllHiiFormset();\r
-       \r
+\r
+    OldFormSet = mSystemLevelFormSet;\r
+\r
     //\r
     // Set Default Value for each FormSet in the maintain list.\r
     //\r
@@ -3509,8 +3369,13 @@ ExtractDefault (
       if (!ValidateFormSet(LocalFormSet)) {\r
         continue;\r
       }\r
+\r
+      mSystemLevelFormSet = LocalFormSet;\r
+\r
       ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);\r
     }\r
+\r
+    mSystemLevelFormSet = OldFormSet;\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -3641,7 +3506,8 @@ LoadFormConfig (
     // Call the Retrieve call back function for all questions.\r
     //\r
     if ((FormSet->ConfigAccess != NULL) && (Selection != NULL) &&\r
-        ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {\r
+        ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&\r
+        !gFinishRetrieveCall) {\r
       //\r
       // Check QuestionValue does exist.\r
       //\r
@@ -3665,7 +3531,7 @@ LoadFormConfig (
                          );\r
       }\r
 \r
-      Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
+      Status = ProcessCallBackFunction(Selection, FormSet, Form, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
     }\r
 \r
     //\r
@@ -3863,18 +3729,20 @@ CleanBrowserStorage (
     Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
 \r
-    if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) && \r
-        (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) && \r
-        (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
-      continue;\r
-    }\r
+    if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+      if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {\r
+        continue;\r
+      }\r
 \r
-    if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {\r
-      continue;\r
+      ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;\r
+      RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);\r
+    } else if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||\r
+               Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+      if (Storage->BrowserStorage->ConfigRequest != NULL) { \r
+        FreePool (Storage->BrowserStorage->ConfigRequest);\r
+      }\r
+      Storage->BrowserStorage->Initialized = FALSE;\r
     }\r
-\r
-    ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;\r
-    RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);\r
   }\r
 }\r
 \r
@@ -4217,95 +4085,92 @@ LoadStorage (
   EFI_STRING  Progress;\r
   EFI_STRING  Result;\r
   CHAR16      *StrPtr;\r
+  EFI_STRING  ConfigRequest;\r
+  UINTN       StrLen;\r
+\r
+  ConfigRequest = NULL;\r
 \r
   switch (Storage->BrowserStorage->Type) {\r
     case EFI_HII_VARSTORE_EFI_VARIABLE:\r
       return;\r
 \r
     case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
-      if (Storage->BrowserStorage->ReferenceCount > 1) {\r
+      if (Storage->BrowserStorage->ConfigRequest != NULL) {\r
         ConfigRequestAdjust(Storage);\r
         return;\r
       }\r
 \r
-      Status = gRT->GetVariable (\r
-                       Storage->BrowserStorage->Name,\r
-                       &Storage->BrowserStorage->Guid,\r
-                       NULL,\r
-                       (UINTN*)&Storage->BrowserStorage->Size,\r
-                       Storage->BrowserStorage->EditBuffer\r
-                       );\r
-      //\r
-      // If get variable fail, extract default from IFR binary\r
       //\r
-      if (EFI_ERROR (Status)) {\r
-        ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
-      }\r
-\r
-      Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
+      // Create the config request string to get all fields for this storage.\r
+      // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
+      // followed by "&OFFSET=0&WIDTH=WWWW"followed by a Null-terminator\r
       //\r
-      // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer. \r
-      //\r
-      SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);\r
+      StrLen = StrSize (Storage->BrowserStorage->ConfigHdr) + 20 * sizeof (CHAR16);\r
+      ConfigRequest = AllocateZeroPool (StrLen);\r
+      ASSERT (ConfigRequest != NULL);\r
+      UnicodeSPrint (\r
+                 ConfigRequest, \r
+                 StrLen, \r
+                 L"%s&OFFSET=0&WIDTH=%04x", \r
+                 Storage->BrowserStorage->ConfigHdr,\r
+                 Storage->BrowserStorage->Size);\r
       break;\r
 \r
     case EFI_HII_VARSTORE_BUFFER:\r
     case EFI_HII_VARSTORE_NAME_VALUE:\r
       //\r
-      // Skip if there is no RequestElement\r
+      // Skip if there is no RequestElement or data has initilized.\r
       //\r
-      if (Storage->ElementCount == 0) {\r
+      if (Storage->ElementCount == 0 || Storage->BrowserStorage->Initialized) {\r
         return;\r
       }\r
+      Storage->BrowserStorage->Initialized = TRUE;\r
+      ConfigRequest = Storage->ConfigRequest;\r
+      break;\r
 \r
-      //\r
-      // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig\r
-      // will used to call ExtractConfig.\r
-      // If not elements need to udpate, return.\r
-      //\r
-      if (!ConfigRequestAdjust(Storage)) {\r
-        return;\r
-      }\r
-      ASSERT (Storage->ConfigElements != NULL);\r
+    default:\r
+      return;\r
+  }\r
 \r
-      Status = EFI_NOT_FOUND;\r
-      if (FormSet->ConfigAccess != NULL) { \r
-        //\r
-        // Request current settings from Configuration Driver\r
-        //\r
-        Status = FormSet->ConfigAccess->ExtractConfig (\r
-                                          FormSet->ConfigAccess,\r
-                                          Storage->ConfigElements,\r
-                                          &Progress,\r
-                                          &Result\r
-                                          );\r
-        \r
-        if (!EFI_ERROR (Status)) {\r
-          //\r
-          // Convert Result from <ConfigAltResp> to <ConfigResp>\r
-          //\r
-          StrPtr = StrStr (Result, L"&GUID=");\r
-          if (StrPtr != NULL) {\r
-            *StrPtr = L'\0';\r
-          }\r
-          \r
-          Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
-          FreePool (Result);\r
-        }\r
-      }\r
+  //\r
+  // Request current settings from Configuration Driver\r
+  //\r
+  Status = mHiiConfigRouting->ExtractConfig (\r
+                                    mHiiConfigRouting,\r
+                                    ConfigRequest,\r
+                                    &Progress,\r
+                                    &Result\r
+                                    );\r
 \r
-      if (EFI_ERROR (Status)) {\r
-        //\r
-        // Base on the configRequest string to get default value.\r
-        //\r
-        GetDefaultForFormset (FormSet, Storage->BrowserStorage, Storage->ConfigElements);\r
-      }\r
+  //\r
+  // If get value fail, extract default from IFR binary\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
+  } else {\r
+    //\r
+    // Convert Result from <ConfigAltResp> to <ConfigResp>\r
+    //\r
+    StrPtr = StrStr (Result, L"&GUID=");\r
+    if (StrPtr != NULL) {\r
+      *StrPtr = L'\0';\r
+    }\r
+    \r
+    Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
+    FreePool (Result);\r
+  }\r
 \r
-      SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigElements, TRUE);\r
-      break;\r
+  Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
 \r
-    default:\r
-      break;\r
+  //\r
+  // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer. \r
+  //\r
+  SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);\r
+\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+    if (ConfigRequest != NULL) {\r
+      FreePool (ConfigRequest);\r
+    }\r
   }\r
 }\r
 \r
@@ -4324,6 +4189,17 @@ InitializeCurrentSetting (
   FORMSET_STORAGE         *Storage;\r
   FORM_BROWSER_FORMSET    *OldFormSet;\r
 \r
+  //\r
+  // Try to find pre FormSet in the maintain backup list.\r
+  // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.\r
+  //\r
+  OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);\r
+  if (OldFormSet != NULL) {\r
+    RemoveEntryList (&OldFormSet->Link);\r
+    DestroyFormSet (OldFormSet);\r
+  }\r
+  InsertTailList (&gBrowserFormSetList, &FormSet->Link);\r
+\r
   //\r
   // Extract default from IFR binary for no storage questions.\r
   //  \r
@@ -4340,17 +4216,6 @@ InitializeCurrentSetting (
 \r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
   }\r
-\r
-  //\r
-  // Try to find pre FormSet in the maintain backup list.\r
-  // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.\r
-  //\r
-  OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);\r
-  if (OldFormSet != NULL) {\r
-    RemoveEntryList (&OldFormSet->Link);\r
-    DestroyFormSet (OldFormSet);\r
-  }\r
-  InsertTailList (&gBrowserFormSetList, &FormSet->Link);\r
 }\r
 \r
 \r