]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
When finish using the browser storage for one formset, browser should clean the Confi...
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
index 8aced87c85e0febdfbaf7e55c70d967e9b1a5ffc..ed904161b619dd538b8ce296c83764791da2f225 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Entry and initialization module for the browser.\r
 \r
-Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -32,11 +32,13 @@ SETUP_DRIVER_PRIVATE_DATA  mPrivateData = {
 EFI_HII_DATABASE_PROTOCOL         *mHiiDatabase;\r
 EFI_HII_STRING_PROTOCOL           *mHiiString;\r
 EFI_HII_CONFIG_ROUTING_PROTOCOL   *mHiiConfigRouting;\r
+EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
 \r
 UINTN           gBrowserContextCount = 0;\r
 LIST_ENTRY      gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);\r
 LIST_ENTRY      gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);\r
 LIST_ENTRY      gBrowserHotKeyList  = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);\r
+LIST_ENTRY      gBrowserStorageList  = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
 \r
 BANNER_DATA           *gBannerData;\r
 EFI_HII_HANDLE        gFrontPageHandle;\r
@@ -84,6 +86,7 @@ CHAR16            *gAdjustNumber;
 CHAR16            *gSaveChanges;\r
 CHAR16            *gOptionMismatch;\r
 CHAR16            *gFormSuppress;\r
+CHAR16            *gProtocolNotFound;\r
 \r
 CHAR16            *mUnknownString = L"!";\r
 \r
@@ -242,6 +245,11 @@ SendForm (
   //\r
   gFooterHeight = FOOTER_HEIGHT + (Index / 3);\r
 \r
+  //\r
+  // Clean the history menu list.\r
+  //\r
+  InitializeListHead (&gMenuList);\r
+\r
   //\r
   // Save globals used by SendForm()\r
   //\r
@@ -303,8 +311,6 @@ SendForm (
   //\r
   InitializeBrowserStrings ();\r
 \r
-  gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;\r
-\r
   //\r
   // Ensure we are in Text mode\r
   //\r
@@ -361,6 +367,7 @@ SendForm (
       // If no data is changed, don't need to save current FormSet into the maintain list.\r
       //\r
       if (!IsNvUpdateRequired (gOldFormSet)) {\r
+        CleanBrowserStorage(gOldFormSet);\r
         RemoveEntryList (&gOldFormSet->Link);\r
         DestroyFormSet (gOldFormSet);\r
       }\r
@@ -378,6 +385,7 @@ SendForm (
   }\r
 \r
   FreeBrowserStrings ();\r
+  UiFreeMenuList(&gMenuList);\r
 \r
   gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
   gST->ConOut->ClearScreen (gST->ConOut);\r
@@ -469,9 +477,9 @@ BrowserCallback (
       Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
       Link = GetNextNode (&FormSet->StorageListHead, Link);\r
 \r
-      if (CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {\r
-        if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||\r
-            Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+      if (CompareGuid (&Storage->BrowserStorage->Guid, (EFI_GUID *) VariableGuid)) {\r
+        if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||\r
+            Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
           //\r
           // Buffer storage require both GUID and Name\r
           //\r
@@ -479,7 +487,7 @@ BrowserCallback (
             return EFI_NOT_FOUND;\r
           }\r
 \r
-          if (StrCmp (Storage->Name, (CHAR16 *) VariableName) != 0) {\r
+          if (StrCmp (Storage->BrowserStorage->Name, (CHAR16 *) VariableName) != 0) {\r
             continue;\r
           }\r
         }\r
@@ -509,7 +517,7 @@ BrowserCallback (
     //\r
     // Generate <ConfigResp>\r
     //\r
-    Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);\r
+    Status = StorageToConfigResp (Storage->BrowserStorage, &ConfigResp, Storage->ConfigRequest);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -517,7 +525,7 @@ BrowserCallback (
     //\r
     // Skip <ConfigHdr> and '&' to point to <ConfigBody>\r
     //\r
-    StrPtr = ConfigResp + StrLen (Storage->ConfigHdr) + 1;\r
+    StrPtr = ConfigResp + StrLen (Storage->BrowserStorage->ConfigHdr) + 1;\r
 \r
     BufferSize = StrSize (StrPtr);\r
     if (*ResultsDataSize < BufferSize) {\r
@@ -536,18 +544,18 @@ BrowserCallback (
     // Prepare <ConfigResp>\r
     //\r
     TmpSize = StrLen (ResultsData);\r
-    BufferSize = (TmpSize + StrLen (Storage->ConfigHdr) + 2) * sizeof (CHAR16);\r
+    BufferSize = (TmpSize + StrLen (Storage->BrowserStorage->ConfigHdr) + 2) * sizeof (CHAR16);\r
     ConfigResp = AllocateZeroPool (BufferSize);\r
     ASSERT (ConfigResp != NULL);\r
 \r
-    StrCpy (ConfigResp, Storage->ConfigHdr);\r
+    StrCpy (ConfigResp, Storage->BrowserStorage->ConfigHdr);\r
     StrCat (ConfigResp, L"&");\r
     StrCat (ConfigResp, ResultsData);\r
 \r
     //\r
     // Update Browser uncommited data\r
     //\r
-    Status = ConfigRespToStorage (Storage, ConfigResp);\r
+    Status = ConfigRespToStorage (Storage->BrowserStorage, ConfigResp);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -556,66 +564,6 @@ BrowserCallback (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Notify function will remove the formset in the maintain list \r
-  once this formset is removed.\r
-  \r
-  Functions which are registered to receive notification of\r
-  database events have this prototype. The actual event is encoded\r
-  in NotifyType. The following table describes how PackageType,\r
-  PackageGuid, Handle, and Package are used for each of the\r
-  notification types.\r
-\r
-  @param PackageType  Package type of the notification.\r
-\r
-  @param PackageGuid  If PackageType is\r
-                      EFI_HII_PACKAGE_TYPE_GUID, then this is\r
-                      the pointer to the GUID from the Guid\r
-                      field of EFI_HII_PACKAGE_GUID_HEADER.\r
-                      Otherwise, it must be NULL.\r
-\r
-  @param Package  Points to the package referred to by the\r
-                  notification Handle The handle of the package\r
-                  list which contains the specified package.\r
-\r
-  @param Handle       The HII handle.\r
-\r
-  @param NotifyType   The type of change concerning the\r
-                      database. See\r
-                      EFI_HII_DATABASE_NOTIFY_TYPE.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FormsetRemoveNotify (\r
-  IN UINT8                              PackageType,\r
-  IN CONST EFI_GUID                     *PackageGuid,\r
-  IN CONST EFI_HII_PACKAGE_HEADER       *Package,\r
-  IN EFI_HII_HANDLE                     Handle,\r
-  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType\r
-  )\r
-{\r
-  FORM_BROWSER_FORMSET *FormSet;\r
-\r
-  //\r
-  // Ignore the update for current using formset, which is handled by another notify function.\r
-  //\r
-  if (IsHiiHandleInBrowserContext (Handle)) {\r
-    return EFI_SUCCESS;\r
-  }\r
-  \r
-  //\r
-  // Remove the backup FormSet data when the Form Package is removed.\r
-  //\r
-  FormSet = GetFormSetFromHiiHandle (Handle);\r
-  if (FormSet != NULL) {\r
-    RemoveEntryList (&FormSet->Link);\r
-    DestroyFormSet (FormSet);\r
-  }\r
-  \r
-  return EFI_SUCCESS;\r
-}\r
-\r
 /**\r
   Initialize Setup Browser driver.\r
 \r
@@ -634,7 +582,6 @@ InitializeSetup (
   )\r
 {\r
   EFI_STATUS                  Status;\r
-  EFI_HANDLE                  NotifyHandle;\r
   EFI_INPUT_KEY               DefaultHotKey;\r
   EFI_STRING                  HelpString;\r
 \r
@@ -662,6 +609,12 @@ InitializeSetup (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDevicePathFromTextProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mPathFromText\r
+                  );\r
+\r
   //\r
   // Publish our HII data\r
   //\r
@@ -726,19 +679,6 @@ InitializeSetup (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Register notify for Form package remove\r
-  //\r
-  Status = mHiiDatabase->RegisterPackageNotify (\r
-                           mHiiDatabase,\r
-                           EFI_HII_PACKAGE_FORMS,\r
-                           NULL,\r
-                           FormsetRemoveNotify,\r
-                           EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
-                           &NotifyHandle\r
-                           );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
   return Status;\r
 }\r
 \r
@@ -815,7 +755,7 @@ GetToken (
 \r
   String = HiiGetString (HiiHandle, Token, NULL);\r
   if (String == NULL) {\r
-    String = AllocateCopyPool (sizeof (mUnknownString), mUnknownString);\r
+    String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);\r
     ASSERT (String != NULL);\r
   }\r
   return (CHAR16 *) String;\r
@@ -888,7 +828,7 @@ NewStringCat (
 **/\r
 VOID\r
 SynchronizeStorage (\r
-  IN FORMSET_STORAGE         *Storage,\r
+  IN BROWSER_STORAGE         *Storage,\r
   IN BOOLEAN                 SyncOrRestore\r
   )\r
 {\r
@@ -941,7 +881,7 @@ SynchronizeStorage (
 **/\r
 EFI_STATUS\r
 GetValueByName (\r
-  IN FORMSET_STORAGE             *Storage,\r
+  IN BROWSER_STORAGE             *Storage,\r
   IN CHAR16                      *Name,\r
   IN OUT CHAR16                  **Value,\r
   IN GET_SET_QUESTION_VALUE_WITH GetValueFrom\r
@@ -990,7 +930,7 @@ GetValueByName (
 **/\r
 EFI_STATUS\r
 SetValueByName (\r
-  IN FORMSET_STORAGE         *Storage,\r
+  IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  *Name,\r
   IN CHAR16                  *Value,\r
   IN GET_SET_QUESTION_VALUE_WITH SetValueTo\r
@@ -1037,9 +977,9 @@ SetValueByName (
 /**\r
   Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.\r
 \r
-  @param  Buffer                 The Storage to be conveted.\r
+  @param  Storage                The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
-  @param  SingleForm             Whether update data for single form or formset level.\r
+  @param  ConfigRequest          The ConfigRequest string.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
@@ -1047,28 +987,17 @@ SetValueByName (
 **/\r
 EFI_STATUS\r
 StorageToConfigResp (\r
-  IN VOID                    *Buffer,\r
+  IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  **ConfigResp,\r
-  IN BOOLEAN                 SingleForm\r
+  IN CHAR16                  *ConfigRequest\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  EFI_STRING  Progress;\r
+  EFI_STATUS              Status;\r
+  EFI_STRING              Progress;\r
   LIST_ENTRY              *Link;\r
   NAME_VALUE_NODE         *Node;\r
-  CHAR16                  *ConfigRequest;\r
-  FORMSET_STORAGE         *Storage;\r
-  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   Status = EFI_SUCCESS;\r
-  if (SingleForm) {\r
-    ConfigInfo    = (FORM_BROWSER_CONFIG_REQUEST *) Buffer;\r
-    Storage       = ConfigInfo->Storage;\r
-    ConfigRequest = ConfigInfo->ConfigRequest;\r
-  } else {\r
-    Storage       = (FORMSET_STORAGE *) Buffer;\r
-    ConfigRequest = Storage->ConfigRequest;\r
-  }\r
 \r
   switch (Storage->Type) {\r
   case EFI_HII_VARSTORE_BUFFER:\r
@@ -1123,7 +1052,7 @@ StorageToConfigResp (
 **/\r
 EFI_STATUS\r
 ConfigRespToStorage (\r
-  IN FORMSET_STORAGE         *Storage,\r
+  IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  *ConfigResp\r
   )\r
 {\r
@@ -1215,7 +1144,7 @@ GetQuestionValue (
   UINT8               *Dst;\r
   UINTN               StorageWidth;\r
   EFI_TIME            EfiTime;\r
-  FORMSET_STORAGE     *Storage;\r
+  BROWSER_STORAGE     *Storage;\r
   EFI_IFR_TYPE_VALUE  *QuestionValue;\r
   CHAR16              *ConfigRequest;\r
   CHAR16              *Progress;\r
@@ -1640,7 +1569,7 @@ SetQuestionValue (
   EFI_TIME            EfiTime;\r
   UINTN               BufferLen;\r
   UINTN               StorageWidth;\r
-  FORMSET_STORAGE     *Storage;\r
+  BROWSER_STORAGE     *Storage;\r
   EFI_IFR_TYPE_VALUE  *QuestionValue;\r
   CHAR16              *ConfigResp;\r
   CHAR16              *Progress;\r
@@ -2250,6 +2179,53 @@ SendDiscardInfoToDriver (
   }\r
 }\r
 \r
+/**\r
+  Validate the FormSet. If the formset is not validate, remove it from the list.\r
+\r
+  @param  FormSet                The input FormSet which need to validate.\r
+\r
+  @retval TRUE                   The handle is validate.\r
+  @retval FALSE                  The handle is invalidate.\r
+\r
+**/\r
+BOOLEAN\r
+ValidateFormSet (\r
+  FORM_BROWSER_FORMSET    *FormSet\r
+  )\r
+{\r
+  EFI_HII_HANDLE          *HiiHandles;\r
+  UINTN                   Index;\r
+  BOOLEAN                 Find;\r
+\r
+  ASSERT (FormSet != NULL);\r
+  Find = FALSE;\r
+  //\r
+  // Get all the Hii handles\r
+  //\r
+  HiiHandles = HiiGetHiiHandles (NULL);\r
+  ASSERT (HiiHandles != NULL);\r
+\r
+  //\r
+  // Search for formset of each class type\r
+  //\r
+  for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+    if (HiiHandles[Index] == FormSet->HiiHandle) {\r
+      Find = TRUE;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (!Find) {\r
+    CleanBrowserStorage(FormSet);\r
+    RemoveEntryList (&FormSet->Link);\r
+    DestroyFormSet (FormSet);\r
+  }\r
+\r
+  FreePool (HiiHandles);\r
+\r
+  return Find;\r
+}\r
+\r
 /**\r
   Discard data based on the input setting scope (Form, FormSet or System).\r
 \r
@@ -2298,31 +2274,20 @@ DiscardForm (
         continue;\r
       }\r
 \r
-      //\r
-      // Call callback with Changed type to inform the driver.\r
-      //\r
-      SendDiscardInfoToDriver (FormSet, Form);\r
-\r
       //\r
       // Prepare <ConfigResp>\r
       //\r
       SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);\r
-    }\r
 \r
-    Form->NvUpdateRequired = FALSE;\r
-  } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
-\r
-    Link = GetFirstNode (&FormSet->FormListHead);\r
-    while (!IsNull (&FormSet->FormListHead, Link)) {\r
-      Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-      Link = GetNextNode (&FormSet->FormListHead, Link);\r
-      \r
       //\r
       // Call callback with Changed type to inform the driver.\r
       //\r
       SendDiscardInfoToDriver (FormSet, Form);\r
     }\r
 \r
+    Form->NvUpdateRequired = FALSE;\r
+  } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
+\r
     //\r
     // Discard Buffer storage or Name/Value storage\r
     //\r
@@ -2331,7 +2296,7 @@ DiscardForm (
       Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
       Link = GetNextNode (&FormSet->StorageListHead, Link);\r
 \r
-      if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+      if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
         continue;\r
       }\r
 \r
@@ -2342,7 +2307,18 @@ DiscardForm (
         continue;\r
       }\r
 \r
-      SynchronizeStorage(Storage, FALSE);\r
+      SynchronizeStorage(Storage->BrowserStorage, FALSE);\r
+    }\r
+\r
+    Link = GetFirstNode (&FormSet->FormListHead);\r
+    while (!IsNull (&FormSet->FormListHead, Link)) {\r
+      Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+      Link = GetNextNode (&FormSet->FormListHead, Link);\r
+      \r
+      //\r
+      // Call callback with Changed type to inform the driver.\r
+      //\r
+      SendDiscardInfoToDriver (FormSet, Form);\r
     }\r
 \r
     UpdateNvInfoInForm (FormSet, FALSE);   \r
@@ -2357,12 +2333,16 @@ DiscardForm (
     Link = GetFirstNode (&gBrowserFormSetList);\r
     while (!IsNull (&gBrowserFormSetList, Link)) {\r
       LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
-      DiscardForm (LocalFormSet, NULL, FormSetLevel);\r
       Link = GetNextNode (&gBrowserFormSetList, Link);\r
+      if (!ValidateFormSet(LocalFormSet)) {\r
+        continue;\r
+      }\r
+      DiscardForm (LocalFormSet, NULL, FormSetLevel);\r
       if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
         //\r
         // Remove maintain backup list after discard except for the current using FormSet.\r
         //\r
+        CleanBrowserStorage(LocalFormSet);\r
         RemoveEntryList (&LocalFormSet->Link);\r
         DestroyFormSet (LocalFormSet);\r
       }\r
@@ -2394,7 +2374,8 @@ SubmitForm (
   LIST_ENTRY              *Link;\r
   EFI_STRING              ConfigResp;\r
   EFI_STRING              Progress;\r
-  FORMSET_STORAGE         *Storage;\r
+  BROWSER_STORAGE         *Storage;\r
+  FORMSET_STORAGE         *FormSetStorage;\r
   UINTN                   BufferSize;\r
   UINT8                   *TmpBuf;  \r
   FORM_BROWSER_FORMSET    *LocalFormSet;\r
@@ -2442,7 +2423,7 @@ SubmitForm (
       //\r
       // 1. Prepare <ConfigResp>\r
       //\r
-      Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE);\r
+      Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
@@ -2531,7 +2512,8 @@ SubmitForm (
     //\r
     Link = GetFirstNode (&FormSet->StorageListHead);\r
     while (!IsNull (&FormSet->StorageListHead, Link)) {\r
-      Storage = FORMSET_STORAGE_FROM_LINK (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
@@ -2541,14 +2523,14 @@ SubmitForm (
       //\r
       // Skip if there is no RequestElement\r
       //\r
-      if (Storage->ElementCount == 0) {\r
+      if (FormSetStorage->ElementCount == 0) {\r
         continue;\r
       }\r
 \r
       //\r
       // 1. Prepare <ConfigResp>\r
       //\r
-      Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);\r
+      Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
@@ -2638,12 +2620,16 @@ SubmitForm (
     Link = GetFirstNode (&gBrowserFormSetList);\r
     while (!IsNull (&gBrowserFormSetList, Link)) {\r
       LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
-      SubmitForm (LocalFormSet, NULL, FormSetLevel);\r
       Link = GetNextNode (&gBrowserFormSetList, Link);\r
+      if (!ValidateFormSet(LocalFormSet)) {\r
+        continue;\r
+      }\r
+      SubmitForm (LocalFormSet, NULL, FormSetLevel);\r
       if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
         //\r
         // Remove maintain backup list after save except for the current using FormSet.\r
         //\r
+        CleanBrowserStorage(LocalFormSet);\r
         RemoveEntryList (&LocalFormSet->Link);\r
         DestroyFormSet (LocalFormSet);\r
       }\r
@@ -2673,7 +2659,7 @@ GetDefaultValueFromAltCfg (
   BOOLEAN             IsBufferStorage;\r
   BOOLEAN             IsString;  \r
   UINTN               Length;\r
-  FORMSET_STORAGE     *Storage;\r
+  BROWSER_STORAGE     *Storage;\r
   CHAR16              *ConfigRequest;\r
   CHAR16              *Progress;\r
   CHAR16              *Result;\r
@@ -3026,6 +3012,12 @@ GetQuestionDefault (
       Link = GetFirstNode (&Question->OptionListHead);\r
       while (!IsNull (&Question->OptionListHead, Link)) {\r
         Option = QUESTION_OPTION_FROM_LINK (Link);\r
+        Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+        if ((Option->SuppressExpression != NULL) &&\r
+            EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {\r
+          continue;\r
+        }\r
 \r
         if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||\r
             ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))\r
@@ -3034,8 +3026,6 @@ GetQuestionDefault (
 \r
           return EFI_SUCCESS;\r
         }\r
-\r
-        Link = GetNextNode (&Question->OptionListHead, Link);\r
       }\r
     }\r
   }\r
@@ -3081,10 +3071,18 @@ GetQuestionDefault (
     //\r
     if (ValueToOption (Question, HiiValue) == NULL) {\r
       Link = GetFirstNode (&Question->OptionListHead);\r
-      if (!IsNull (&Question->OptionListHead, Link)) {\r
+      while (!IsNull (&Question->OptionListHead, Link)) {\r
         Option = QUESTION_OPTION_FROM_LINK (Link);\r
+        Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+        if ((Option->SuppressExpression != NULL) &&\r
+            EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {\r
+          continue;\r
+        }\r
+\r
         CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
         Status = EFI_SUCCESS;\r
+        break;\r
       }\r
     }\r
     break;\r
@@ -3098,6 +3096,12 @@ GetQuestionDefault (
     while (!IsNull (&Question->OptionListHead, Link)) {\r
       Status = EFI_SUCCESS;\r
       Option = QUESTION_OPTION_FROM_LINK (Link);\r
+      Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+      if ((Option->SuppressExpression != NULL) &&\r
+          EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {\r
+        continue;\r
+      }\r
 \r
       SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);\r
 \r
@@ -3105,8 +3109,6 @@ GetQuestionDefault (
       if (Index >= Question->MaxContainers) {\r
         break;\r
       }\r
-\r
-      Link = GetNextNode (&Question->OptionListHead, Link);\r
     }\r
     break;\r
 \r
@@ -3119,7 +3121,7 @@ GetQuestionDefault (
 \r
 \r
 /**\r
-  Reset Questions to their default value in a Form, Formset or System.\r
+  Reset Questions to their initial value or default value in a Form, Formset or System.\r
 \r
   GetDefaultValueScope parameter decides which questions will reset \r
   to its default value.\r
@@ -3130,6 +3132,9 @@ GetQuestionDefault (
   @param  SettingScope           Setting Scope for Default action.\r
   @param  GetDefaultValueScope   Get default value scope.\r
   @param  Storage                Get default value only for this storage.\r
+  @param  RetrieveValueFirst     Whether call the retrieve call back to\r
+                                 get the initial value before get default\r
+                                 value.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
   @retval EFI_UNSUPPORTED        Unsupport SettingScope.\r
@@ -3142,7 +3147,8 @@ ExtractDefault (
   IN UINT16                           DefaultId,\r
   IN BROWSER_SETTING_SCOPE            SettingScope,\r
   IN BROWSER_GET_DEFAULT_VALUE        GetDefaultValueScope,\r
-  IN FORMSET_STORAGE                  *Storage OPTIONAL\r
+  IN BROWSER_STORAGE                  *Storage OPTIONAL,\r
+  IN BOOLEAN                          RetrieveValueFirst\r
   )\r
 {\r
   EFI_STATUS              Status;\r
@@ -3155,6 +3161,8 @@ ExtractDefault (
   UINTN                   Index;\r
   EFI_GUID                ZeroGuid;\r
 \r
+  Status = EFI_SUCCESS;\r
+\r
   //\r
   // Check the supported setting level.\r
   //\r
@@ -3197,15 +3205,24 @@ ExtractDefault (
           continue;\r
         }\r
       }\r
-  \r
+\r
+      if (RetrieveValueFirst) {\r
+        //\r
+        // Call the Retrieve call back to get the initial question value.\r
+        //\r
+        Status = ProcessRetrieveForQuestion(FormSet->ConfigAccess, Question);\r
+      }\r
+\r
       //\r
-      // Reset Question to its default value\r
+      // If not request to get the initial value or get initial value fail, then get default value.\r
       //\r
-      Status = GetQuestionDefault (FormSet, Form, Question, DefaultId);\r
-      if (EFI_ERROR (Status)) {\r
-        continue;\r
+      if (!RetrieveValueFirst || EFI_ERROR (Status)) {\r
+        Status = GetQuestionDefault (FormSet, Form, Question, DefaultId);\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
       }\r
-  \r
+\r
       //\r
       // Synchronize Buffer storage's Edit buffer\r
       //\r
@@ -3222,7 +3239,7 @@ ExtractDefault (
     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);\r
+      ExtractDefault (FormSet, Form, DefaultId, FormLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);\r
       FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
     }\r
   } else if (SettingScope == SystemLevel) {\r
@@ -3269,7 +3286,7 @@ ExtractDefault (
       //\r
       // Initilize Questions' Value\r
       //\r
-      LoadFormSetConfig (NULL, LocalFormSet);\r
+      Status = LoadFormSetConfig (NULL, LocalFormSet);\r
       if (EFI_ERROR (Status)) {\r
         DestroyFormSet (LocalFormSet);\r
         continue;\r
@@ -3293,8 +3310,11 @@ ExtractDefault (
     Link = GetFirstNode (&gBrowserFormSetList);\r
     while (!IsNull (&gBrowserFormSetList, Link)) {\r
       LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
-      ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage);\r
       Link = GetNextNode (&gBrowserFormSetList, Link);\r
+      if (!ValidateFormSet(LocalFormSet)) {\r
+        continue;\r
+      }\r
+      ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);\r
     }\r
   }\r
 \r
@@ -3344,26 +3364,10 @@ LoadFormConfig (
     }\r
 \r
     //\r
-    // According the spec, ref opcode try to get value from call back with "retrieve" type.\r
+    // Call the Retrieve call back function for all questions.\r
     //\r
-    if ((Question->Operand == EFI_IFR_REF_OP) && (FormSet->ConfigAccess != NULL) && (Selection != NULL)) {\r
-      Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Check whether EfiVarstore with CallBack can be got.\r
-    //\r
-    if ((FormSet->ConfigAccess != NULL) &&\r
-        (Selection != NULL) &&\r
-        (Selection->Action != UI_ACTION_REFRESH_FORMSET) &&\r
-        (Question->QuestionId != 0) && \r
-        (Question->Storage != NULL) &&\r
-        (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) && \r
+    if ((FormSet->ConfigAccess != NULL) && (Selection != NULL) &&\r
         ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {\r
-\r
       //\r
       // Check QuestionValue does exist.\r
       //\r
@@ -3373,17 +3377,21 @@ LoadFormConfig (
       } else {\r
         BufferValue = (UINT8 *) &Question->HiiValue.Value;\r
       }\r
-      Status = gRT->GetVariable (\r
-                       Question->VariableName,\r
-                       &Question->Storage->Guid,\r
-                       NULL,\r
-                       &StorageWidth,\r
-                       BufferValue\r
-                       );\r
 \r
-      if (!EFI_ERROR (Status)) {\r
-        Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
+      //\r
+      // For efivarstore storage, initial question value first.\r
+      //\r
+      if ((Question->Storage != NULL) && (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
+        Status = gRT->GetVariable (\r
+                         Question->VariableName,\r
+                         &Question->Storage->Guid,\r
+                         NULL,\r
+                         &StorageWidth,\r
+                         BufferValue\r
+                         );\r
       }\r
+\r
+      Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
     }\r
 \r
     Link = GetNextNode (&Form->StatementListHead, Link);\r
@@ -3432,6 +3440,319 @@ LoadFormSetConfig (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Remove the Request element from the Config Request.\r
+\r
+  @param  Storage                Pointer to the browser storage.\r
+  @param  RequestElement         The pointer to the Request element.\r
+\r
+**/\r
+VOID\r
+RemoveElement (\r
+  IN OUT BROWSER_STORAGE      *Storage,\r
+  IN     CHAR16               *RequestElement\r
+  )\r
+{\r
+  CHAR16   *NewStr;\r
+  CHAR16   *DestStr;\r
+\r
+  ASSERT (Storage->ConfigRequest != NULL && RequestElement != NULL);\r
+\r
+  NewStr = StrStr (Storage->ConfigRequest, RequestElement);\r
+\r
+  if (NewStr == NULL) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Remove this element from this ConfigRequest.\r
+  //\r
+  DestStr = NewStr;\r
+  NewStr += StrLen (RequestElement);\r
+  CopyMem (DestStr, NewStr, StrSize (NewStr));\r
+  \r
+  Storage->SpareStrLen += StrLen (RequestElement);  \r
+}\r
+\r
+/**\r
+  Adjust config request in storage, remove the request elements existed in the input ConfigRequest.\r
+\r
+  @param  Storage                Pointer to the browser storage.\r
+  @param  ConfigRequest          The pointer to the Request element.\r
+\r
+**/\r
+VOID\r
+RemoveConfigRequest (\r
+  BROWSER_STORAGE   *Storage,\r
+  CHAR16            *ConfigRequest\r
+  )\r
+{\r
+  CHAR16       *RequestElement;\r
+  CHAR16       *NextRequestElement;\r
+  CHAR16       *SearchKey;\r
+\r
+  if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    //\r
+    // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
+    //\r
+    SearchKey = L"&";\r
+  } else {\r
+    //\r
+    // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
+    //\r
+    SearchKey = L"&OFFSET";\r
+  }\r
+\r
+  //\r
+  // Find SearchKey storage\r
+  //\r
+  if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    RequestElement = StrStr (ConfigRequest, L"PATH");\r
+    ASSERT (RequestElement != NULL);\r
+    RequestElement = StrStr (RequestElement, SearchKey);    \r
+  } else {\r
+    RequestElement = StrStr (ConfigRequest, SearchKey);\r
+  }\r
+\r
+  while (RequestElement != NULL) {\r
+    //\r
+    // +1 to avoid find header itself.\r
+    //\r
+    NextRequestElement = StrStr (RequestElement + 1, SearchKey);\r
+\r
+    //\r
+    // The last Request element in configRequest string.\r
+    //\r
+    if (NextRequestElement != NULL) {\r
+      //\r
+      // Replace "&" with '\0'.\r
+      //\r
+      *NextRequestElement = L'\0';\r
+    }\r
+\r
+    RemoveElement (Storage, RequestElement);\r
+\r
+    if (NextRequestElement != NULL) {\r
+      //\r
+      // Restore '&' with '\0' for later used.\r
+      //\r
+      *NextRequestElement = L'&';\r
+    }\r
+\r
+    RequestElement = NextRequestElement;\r
+  }\r
+\r
+  //\r
+  // If no request element remain, just remove the ConfigRequest string.\r
+  //\r
+  if (StrCmp (Storage->ConfigRequest, Storage->ConfigHdr) == 0) {\r
+    FreePool (Storage->ConfigRequest);\r
+    Storage->ConfigRequest = NULL;\r
+    Storage->SpareStrLen   = 0;\r
+  }\r
+}\r
+\r
+/**\r
+  Base on the current formset info, clean the ConfigRequest string in browser storage.\r
+\r
+  @param  FormSet                Pointer of the FormSet\r
+\r
+**/\r
+VOID\r
+CleanBrowserStorage (\r
+  IN OUT FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+{\r
+  LIST_ENTRY            *Link;\r
+  FORMSET_STORAGE       *Storage;\r
+\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+    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
+      continue;\r
+    }\r
+\r
+    if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {\r
+      continue;\r
+    }\r
+\r
+    RemoveConfigRequest (Storage->BrowserStorage, Storage->ConfigRequest);\r
+  }\r
+}\r
+\r
+/**\r
+  Check whether current element in the ConfigReqeust string.\r
+\r
+  @param  BrowserStorage                Storage which includes ConfigReqeust.\r
+  @param  RequestElement                New element need to check.\r
+\r
+  @retval TRUE        The Element is in the ConfigReqeust string.\r
+  @retval FALSE       The Element not in the configReqeust String.\r
+\r
+**/\r
+BOOLEAN \r
+ElementValidation (\r
+  BROWSER_STORAGE   *BrowserStorage,\r
+  CHAR16            *RequestElement\r
+  )\r
+{\r
+  return StrStr (BrowserStorage->ConfigRequest, RequestElement) != NULL ? TRUE : FALSE;\r
+}\r
+\r
+/**\r
+  Append the Request element to the Config Request.\r
+\r
+  @param  ConfigRequest          Current ConfigRequest info.\r
+  @param  SpareStrLen            Current remain free buffer for config reqeust.\r
+  @param  RequestElement         New Request element.\r
+\r
+**/\r
+VOID\r
+AppendConfigRequest (\r
+  IN OUT CHAR16               **ConfigRequest,\r
+  IN OUT UINTN                *SpareStrLen,\r
+  IN     CHAR16               *RequestElement\r
+  )\r
+{\r
+  CHAR16   *NewStr;\r
+  UINTN    StringSize;\r
+  UINTN    StrLength;\r
+\r
+  StrLength = StrLen (RequestElement);\r
+\r
+  //\r
+  // Append <RequestElement> to <ConfigRequest>\r
+  //\r
+  if (StrLength > *SpareStrLen) {\r
+    //\r
+    // Old String buffer is not sufficient for RequestElement, allocate a new one\r
+    //\r
+    StringSize = (*ConfigRequest != NULL) ? StrSize (*ConfigRequest) : sizeof (CHAR16);\r
+    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    ASSERT (NewStr != NULL);\r
+\r
+    if (*ConfigRequest != NULL) {\r
+      CopyMem (NewStr, *ConfigRequest, StringSize);\r
+      FreePool (*ConfigRequest);\r
+    }\r
+    *ConfigRequest = NewStr;\r
+    *SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
+  }\r
+\r
+  StrCat (*ConfigRequest, RequestElement);\r
+  *SpareStrLen -= StrLength;\r
+}\r
+\r
+/**\r
+  Adjust the config request info, remove the request elements which already in AllConfigRequest string.\r
+\r
+  @param  Storage                Form set Storage.\r
+  @param  ConfigRequest          Return the ConfigRequest info.\r
+\r
+  @retval TRUE                   Has element not covered by current used elements, need to continue to call ExtractConfig\r
+  @retval FALSE                  All elements covered by current used elements.\r
+\r
+**/\r
+BOOLEAN \r
+ConfigRequestAdjust (\r
+  IN  FORMSET_STORAGE         *Storage,\r
+  OUT CHAR16                  **ConfigRequest\r
+  )\r
+{\r
+  CHAR16       *RequestElement;\r
+  CHAR16       *NextRequestElement;\r
+  CHAR16       *RetBuf;\r
+  UINTN        SpareBufLen;\r
+  CHAR16       *SearchKey;\r
+  BOOLEAN      RetVal;\r
+\r
+  SpareBufLen    = 0;\r
+  RetBuf         = NULL;\r
+  RetVal         = FALSE;\r
+\r
+  if (Storage->BrowserStorage->ConfigRequest == NULL) {\r
+    Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
+    *ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
+    return TRUE;\r
+  }\r
+\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    //\r
+    // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
+    //\r
+    SearchKey = L"&";\r
+  } else {\r
+    //\r
+    // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
+    //\r
+    SearchKey = L"&OFFSET";\r
+  }\r
+\r
+  //\r
+  // Prepare the config header.\r
+  // \r
+  RetBuf = AllocateCopyPool(StrSize (Storage->BrowserStorage->ConfigHdr), Storage->BrowserStorage->ConfigHdr);\r
+  ASSERT (RetBuf != NULL);\r
+\r
+  //\r
+  // Find SearchKey storage\r
+  //\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    RequestElement = StrStr (Storage->ConfigRequest, L"PATH");\r
+    ASSERT (RequestElement != NULL);\r
+    RequestElement = StrStr (RequestElement, SearchKey);    \r
+  } else {\r
+    RequestElement = StrStr (Storage->ConfigRequest, SearchKey);\r
+  }\r
+\r
+  while (RequestElement != NULL) {\r
+    //\r
+    // +1 to avoid find header itself.\r
+    //\r
+    NextRequestElement = StrStr (RequestElement + 1, SearchKey);\r
+\r
+    //\r
+    // The last Request element in configRequest string.\r
+    //\r
+    if (NextRequestElement != NULL) {\r
+      //\r
+      // Replace "&" with '\0'.\r
+      //\r
+      *NextRequestElement = L'\0';\r
+    }\r
\r
+    if (!ElementValidation (Storage->BrowserStorage, RequestElement)) {\r
+      //\r
+      // Add this element to the Storage->BrowserStorage->AllRequestElement.\r
+      //\r
+      AppendConfigRequest(&Storage->BrowserStorage->ConfigRequest, &Storage->BrowserStorage->SpareStrLen, RequestElement);\r
+      AppendConfigRequest (&RetBuf, &SpareBufLen, RequestElement);\r
+      RetVal = TRUE;\r
+    }\r
+\r
+    if (NextRequestElement != NULL) {\r
+      //\r
+      // Restore '&' with '\0' for later used.\r
+      //\r
+      *NextRequestElement = L'&';\r
+    }\r
+\r
+    RequestElement = NextRequestElement;\r
+  }\r
+\r
+  if (RetVal) {\r
+    *ConfigRequest = RetBuf;\r
+  } else {\r
+    FreePool (RetBuf);\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
 /**\r
   Fill storage's edit copy with settings requested from Configuration Driver.\r
 \r
@@ -3451,19 +3772,26 @@ LoadStorage (
   EFI_STRING  Progress;\r
   EFI_STRING  Result;\r
   CHAR16      *StrPtr;\r
+  CHAR16      *ConfigRequest;\r
 \r
-  if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-    Status = gRT->GetVariable (\r
-                     Storage->Name,\r
-                     &Storage->Guid,\r
-                     NULL,\r
-                     (UINTN*)&Storage->Size,\r
-                     Storage->EditBuffer\r
-                     );\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+    Status = EFI_SUCCESS;\r
+    //\r
+    // EFI varstore data all get from variable, so no need to get again.\r
+    //\r
+    if (Storage->BrowserStorage->ReferenceCount == 1) {\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
     return Status;\r
   }\r
 \r
@@ -3478,15 +3806,25 @@ LoadStorage (
     return EFI_SUCCESS;\r
   }\r
 \r
+  //\r
+  // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig\r
+  // will used to call ExtractConfig.\r
+  //\r
+  if (!ConfigRequestAdjust(Storage, &ConfigRequest)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   // Request current settings from Configuration Driver\r
   //\r
   Status = FormSet->ConfigAccess->ExtractConfig (\r
                                     FormSet->ConfigAccess,\r
-                                    Storage->ConfigRequest,\r
+                                    ConfigRequest,\r
                                     &Progress,\r
                                     &Result\r
                                     );\r
+  FreePool (ConfigRequest);\r
+\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -3494,68 +3832,16 @@ LoadStorage (
   //\r
   // Convert Result from <ConfigAltResp> to <ConfigResp>\r
   //\r
-  StrPtr = StrStr (Result, L"ALTCFG");\r
+  StrPtr = StrStr (Result, L"&GUID=");\r
   if (StrPtr != NULL) {\r
     *StrPtr = L'\0';\r
   }\r
 \r
-  Status = ConfigRespToStorage (Storage, Result);\r
+  Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
   FreePool (Result);\r
   return Status;\r
 }\r
 \r
-\r
-/**\r
-  Copy uncommitted data from source Storage to destination Storage.\r
-\r
-  @param  Dst                    Target Storage for uncommitted data.\r
-  @param  Src                    Source Storage for uncommitted data.\r
-\r
-  @retval EFI_SUCCESS            The function completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  Source and destination Storage is not the same type.\r
-\r
-**/\r
-EFI_STATUS\r
-CopyStorage (\r
-  IN OUT FORMSET_STORAGE     *Dst,\r
-  IN FORMSET_STORAGE         *Src\r
-  )\r
-{\r
-  LIST_ENTRY          *Link;\r
-  NAME_VALUE_NODE     *Node;\r
-\r
-  if ((Dst->Type != Src->Type) || (Dst->Size != Src->Size)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  switch (Src->Type) {\r
-  case EFI_HII_VARSTORE_BUFFER:\r
-  case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
-    CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size);\r
-    CopyMem (Dst->Buffer, Src->Buffer, Src->Size);\r
-    break;\r
-\r
-  case EFI_HII_VARSTORE_NAME_VALUE:\r
-    Link = GetFirstNode (&Src->NameValueListHead);\r
-    while (!IsNull (&Src->NameValueListHead, Link)) {\r
-      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
-\r
-      SetValueByName (Dst, Node->Name, Node->EditValue, GetSetValueWithEditBuffer);\r
-      SetValueByName (Dst, Node->Name, Node->Value, GetSetValueWithBuffer);\r
-\r
-      Link = GetNextNode (&Src->NameValueListHead, Link);\r
-    }\r
-    break;\r
-\r
-  case EFI_HII_VARSTORE_EFI_VARIABLE:\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 /**\r
   Get current setting of Questions.\r
 \r
@@ -3580,8 +3866,8 @@ InitializeCurrentSetting (
 \r
   //\r
   // Extract default from IFR binary for no storage questions.\r
-  //\r
-  ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForNoStorage, NULL);\r
+  //  \r
+  ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForNoStorage, NULL, TRUE);\r
 \r
   //\r
   // Request current settings from Configuration Driver\r
@@ -3608,17 +3894,18 @@ InitializeCurrentSetting (
       }\r
     }\r
 \r
+    //\r
+    // Storage is not found in backup formset and current global storage not has other driver used,\r
+    // request it from ConfigDriver\r
+    //\r
     if (OldStorage == NULL) {\r
-      //\r
-      // Storage is not found in backup formset, request it from ConfigDriver\r
-      //\r
       Status = LoadStorage (FormSet, Storage);\r
 \r
       if (EFI_ERROR (Status)) {\r
         //\r
         // If get last time changed value failed, extract default from IFR binary\r
         //\r
-        ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage);\r
+        ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
         //\r
         // ExtractDefault will set the NV flag to TRUE, so need this function to clean the flag\r
         // in current situation.\r
@@ -3630,12 +3917,7 @@ InitializeCurrentSetting (
       // Now Edit Buffer is filled with default values(lower priority) or current\r
       // settings(higher priority), sychronize it to shadow Buffer\r
       //\r
-      SynchronizeStorage (Storage, TRUE);\r
-    } else {\r
-      //\r
-      // Storage found in backup formset, use it\r
-      //\r
-      Status = CopyStorage (Storage, OldStorage);\r
+      SynchronizeStorage (Storage->BrowserStorage, TRUE);\r
     }\r
 \r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
@@ -3645,23 +3927,23 @@ InitializeCurrentSetting (
   // If has old formset, get the old nv update status.\r
   //\r
   if (gOldFormSet != NULL) {\r
-      Link = GetFirstNode (&FormSet->FormListHead);\r
-      while (!IsNull (&FormSet->FormListHead, Link)) {\r
-        Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-\r
-        Link2 = GetFirstNode (&gOldFormSet->FormListHead);\r
-        while (!IsNull (&gOldFormSet->FormListHead, Link2)) {\r
-          Form2 = FORM_BROWSER_FORM_FROM_LINK (Link2);\r
+    Link = GetFirstNode (&FormSet->FormListHead);\r
+    while (!IsNull (&FormSet->FormListHead, Link)) {\r
+      Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
 \r
-          if (Form->FormId == Form2->FormId) {\r
-            Form->NvUpdateRequired = Form2->NvUpdateRequired;\r
-            break;\r
-          }\r
+      Link2 = GetFirstNode (&gOldFormSet->FormListHead);\r
+      while (!IsNull (&gOldFormSet->FormListHead, Link2)) {\r
+        Form2 = FORM_BROWSER_FORM_FROM_LINK (Link2);\r
 \r
-          Link2 = GetNextNode (&gOldFormSet->FormListHead, Link2);\r
+        if (Form->FormId == Form2->FormId) {\r
+          Form->NvUpdateRequired = Form2->NvUpdateRequired;\r
+          break;\r
         }\r
-          Link = GetNextNode (&FormSet->FormListHead, Link);\r
+\r
+        Link2 = GetNextNode (&gOldFormSet->FormListHead, Link2);\r
       }\r
+      Link = GetNextNode (&FormSet->FormListHead, Link);\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -3928,6 +4210,8 @@ InitializeFormSet (
     }\r
   }\r
 \r
+  gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;\r
+\r
   if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
     gFrontPageHandle = FormSet->HiiHandle;\r
     gFunctionKeySetting = NONE_FUNCTION_KEY_SETTING;\r
@@ -4015,6 +4299,7 @@ SaveBrowserContext (
   Context->HelpBlockWidth       = gHelpBlockWidth;\r
   Context->OldFormSet           = gOldFormSet;\r
   Context->MenuRefreshHead      = gMenuRefreshHead;\r
+  Context->ProtocolNotFound     = gProtocolNotFound;\r
 \r
   CopyMem (&Context->ScreenDimensions, &gScreenDimensions, sizeof (gScreenDimensions));\r
   CopyMem (&Context->MenuOption, &gMenuOption, sizeof (gMenuOption));\r
@@ -4092,6 +4377,7 @@ RestoreBrowserContext (
   gHelpBlockWidth       = Context->HelpBlockWidth;\r
   gOldFormSet           = Context->OldFormSet;\r
   gMenuRefreshHead      = Context->MenuRefreshHead;\r
+  gProtocolNotFound     = Context->ProtocolNotFound;\r
 \r
   CopyMem (&gScreenDimensions, &Context->ScreenDimensions, sizeof (gScreenDimensions));\r
   CopyMem (&gMenuOption, &Context->MenuOption, sizeof (gMenuOption));\r
@@ -4122,10 +4408,13 @@ GetFormSetFromHiiHandle (
   Link = GetFirstNode (&gBrowserFormSetList);\r
   while (!IsNull (&gBrowserFormSetList, Link)) {\r
     FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+    Link = GetNextNode (&gBrowserFormSetList, Link);\r
+    if (!ValidateFormSet(FormSet)) {\r
+      continue;\r
+    }\r
     if (FormSet->HiiHandle == Handle) {\r
       return FormSet;\r
     }\r
-    Link = GetNextNode (&gBrowserFormSetList, Link);\r
   }\r
   \r
   return NULL;\r
@@ -4378,11 +4667,14 @@ SaveReminder (
   Link = GetFirstNode (&gBrowserFormSetList);\r
   while (!IsNull (&gBrowserFormSetList, Link)) {\r
     FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+    Link = GetNextNode (&gBrowserFormSetList, Link);\r
+    if (!ValidateFormSet(FormSet)) {\r
+      continue;\r
+    }\r
     if (IsNvUpdateRequired (FormSet)) {\r
       IsDataChanged = TRUE;\r
       break;\r
     }\r
-    Link = GetNextNode (&gBrowserFormSetList, Link);\r
   }\r
   \r
   //\r