]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
Update the browser logic, make the storage as browser level instead of form set level.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
index 381cefeae5937690e40442d22a4175b9486fefcb..b077a3c0a0335d29ee62788629e478ab777d0b51 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
@@ -378,6 +384,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 +476,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 +486,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 +516,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 +524,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 +543,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 +563,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 +581,6 @@ InitializeSetup (
   )\r
 {\r
   EFI_STATUS                  Status;\r
-  EFI_HANDLE                  NotifyHandle;\r
   EFI_INPUT_KEY               DefaultHotKey;\r
   EFI_STRING                  HelpString;\r
 \r
@@ -662,6 +608,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 +678,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
@@ -888,7 +827,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 +880,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 +929,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 +976,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 +986,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 +1051,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 +1143,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 +1568,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 +2178,52 @@ 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
+    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
@@ -2320,7 +2294,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
@@ -2331,7 +2305,7 @@ DiscardForm (
         continue;\r
       }\r
 \r
-      SynchronizeStorage(Storage, FALSE);\r
+      SynchronizeStorage(Storage->BrowserStorage, FALSE);\r
     }\r
 \r
     Link = GetFirstNode (&FormSet->FormListHead);\r
@@ -2357,8 +2331,11 @@ 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
@@ -2394,7 +2371,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 +2420,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 +2509,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 +2520,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,8 +2617,11 @@ 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
@@ -2673,7 +2655,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
@@ -3161,7 +3143,7 @@ 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
@@ -3324,8 +3306,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, RetrieveValueFirst);\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
@@ -3471,17 +3456,17 @@ LoadStorage (
   EFI_STRING  Result;\r
   CHAR16      *StrPtr;\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
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
     Status = gRT->GetVariable (\r
-                     Storage->Name,\r
-                     &Storage->Guid,\r
+                     Storage->BrowserStorage->Name,\r
+                     &Storage->BrowserStorage->Guid,\r
                      NULL,\r
-                     (UINTN*)&Storage->Size,\r
-                     Storage->EditBuffer\r
+                     (UINTN*)&Storage->BrowserStorage->Size,\r
+                     Storage->BrowserStorage->EditBuffer\r
                      );\r
     return Status;\r
   }\r
@@ -3513,141 +3498,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
-  Get old question value from the saved formset.\r
-\r
-  @param  Statement              The question which need to get old question value.\r
-  @param  OldFormSet             FormSet data structure saved in the list.\r
-\r
-**/\r
-VOID \r
-GetOldQuestionValue (\r
-  IN OUT FORM_BROWSER_STATEMENT  *Statement,\r
-  IN     FORM_BROWSER_FORMSET    *OldFormSet\r
-  )\r
-{\r
-  LIST_ENTRY              *FormLink;\r
-  LIST_ENTRY              *Link;\r
-  FORM_BROWSER_STATEMENT  *Question;\r
-  FORM_BROWSER_FORM       *Form;\r
-\r
-  FormLink = GetFirstNode (&OldFormSet->FormListHead);\r
-  while (!IsNull (&OldFormSet->FormListHead, FormLink)) {\r
-    Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
-    FormLink = GetNextNode (&OldFormSet->FormListHead, FormLink);\r
-\r
-    Link = GetFirstNode (&Form->StatementListHead);\r
-    while (!IsNull (&Form->StatementListHead, Link)) {\r
-      Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-      Link = GetNextNode (&Form->StatementListHead, Link);\r
-\r
-      if (Question->QuestionId != Statement->QuestionId) {\r
-        continue;\r
-      }\r
-\r
-      CopyMem (&Statement->HiiValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
-      return;\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Get old question value from the saved formset, all these questions not have\r
-  storage.\r
-\r
-  @param  FormSet                FormSet data structure which is used now.\r
-  @param  OldFormSet             FormSet data structure saved in the list.\r
-\r
-**/\r
-VOID\r
-CopyOldValueForNoStorageQst (\r
-  IN OUT FORM_BROWSER_FORMSET             *FormSet,\r
-  IN     FORM_BROWSER_FORMSET             *OldFormSet\r
-  )\r
-{\r
-  LIST_ENTRY              *FormLink;\r
-  LIST_ENTRY              *Link;\r
-  FORM_BROWSER_STATEMENT  *Question;\r
-  FORM_BROWSER_FORM       *Form;\r
-\r
-  FormLink = GetFirstNode (&FormSet->FormListHead);\r
-  while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
-    Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
-    FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
-\r
-    Link = GetFirstNode (&Form->StatementListHead);\r
-    while (!IsNull (&Form->StatementListHead, Link)) {\r
-      Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-      Link = GetNextNode (&Form->StatementListHead, Link);\r
-\r
-      if (Question->Storage == NULL) {\r
-        GetOldQuestionValue (Question, OldFormSet);\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
 /**\r
   Get current setting of Questions.\r
 \r
@@ -3700,17 +3560,18 @@ InitializeCurrentSetting (
       }\r
     }\r
 \r
-    if (OldStorage == NULL) {\r
-      //\r
-      // Storage is not found in backup formset, request it from ConfigDriver\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 && Storage->BrowserStorage->ReferenceCount == 1) {\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, TRUE);\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
@@ -3722,12 +3583,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
@@ -4020,6 +3876,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
@@ -4107,6 +3965,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
@@ -4184,6 +4043,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
@@ -4214,10 +4074,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
@@ -4470,11 +4333,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