Fix deadloop issue in BrowserCallback function.

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14711 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index ac7dce6..4006fcd 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -510,10 +510,6 @@
 

     InitializeConfigHdr (FormSet, BrowserStorage);

   }

-  //

-  // Add count because one formset storage use this global storage.

-  //

-  BrowserStorage->ReferenceCount++;

 

   Storage->BrowserStorage = BrowserStorage;

   Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr);

@@ -742,12 +738,6 @@
     FreePool (Storage->ConfigRequest);

   }

 

-  //

-  // Minus the reference to the global storage.

-  //

-  ASSERT (Storage->BrowserStorage->ReferenceCount > 0);

-  Storage->BrowserStorage->ReferenceCount--; 

-

   FreePool (Storage);

 }

 

diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index 63f8680..7cba785 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -53,6 +53,7 @@
 BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;

 BOOLEAN               mBrowserScopeFirstSet = TRUE;

 EXIT_HANDLER          ExitHandlerFunction = NULL;

+FORM_BROWSER_FORMSET  *mSystemLevelFormSet;

 

 //

 // Browser Global Strings

@@ -255,6 +256,9 @@
   UINTN                   Index;

   EFI_GUID                ZeroGuid;

   EFI_STATUS              Status;

+  FORM_BROWSER_FORMSET    *OldFormset;

+

+  OldFormset = mSystemLevelFormSet;

 

   //

   // Get all the Hii handles

@@ -278,6 +282,8 @@
     //

     LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));

     ASSERT (LocalFormSet != NULL);

+    mSystemLevelFormSet = LocalFormSet;

+

     ZeroMem (&ZeroGuid, sizeof (ZeroGuid));

     Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);

     if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {

@@ -300,6 +306,8 @@
   // Free resources, and restore gOldFormSet and gClassOfVfr

   //

   FreePool (HiiHandles);

+

+  mSystemLevelFormSet = OldFormset;

 }

 

 /**

@@ -388,6 +396,7 @@
         break;

       }

       Selection->FormSet = FormSet;

+      mSystemLevelFormSet = FormSet;

 

       //

       // Display this formset

@@ -397,6 +406,7 @@
       Status = SetupBrowser (Selection);

 

       gCurrentSelection = NULL;

+      mSystemLevelFormSet = NULL;

 

       //

       // If no data is changed, don't need to save current FormSet into the maintain list.

@@ -580,7 +590,6 @@
   LIST_ENTRY            *Link;

   BROWSER_STORAGE       *Storage;

   FORMSET_STORAGE       *FormsetStorage;

-  FORM_BROWSER_FORMSET  *FormSet;

   UINTN                 TotalSize;

   BOOLEAN               Found;

 

@@ -650,16 +659,15 @@
     //

     // GUID/Name is not specified, take the first storage in FormSet

     //

-    if (gCurrentSelection == NULL) {

+    if (mSystemLevelFormSet == NULL) {

       return EFI_NOT_READY;

     }

 

     //

     // Generate <ConfigResp>

     //

-    FormSet = gCurrentSelection->FormSet;

-    Link = GetFirstNode (&FormSet->StorageListHead);

-    if (IsNull (&FormSet->StorageListHead, Link)) {

+    Link = GetFirstNode (&mSystemLevelFormSet->StorageListHead);

+    if (IsNull (&mSystemLevelFormSet->StorageListHead, Link)) {

       return EFI_UNSUPPORTED;

     }

 

@@ -2361,7 +2369,8 @@
   LIST_ENTRY                   *Link;

   FORMSET_STORAGE              *Storage;

   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;

-  FORM_BROWSER_FORMSET    *LocalFormSet;

+  FORM_BROWSER_FORMSET         *LocalFormSet;

+  FORM_BROWSER_FORMSET         *OldFormSet;

 

   //

   // Check the supported setting level.

@@ -2440,7 +2449,8 @@
     //

     // System Level Discard.

     //

-    

+    OldFormSet = mSystemLevelFormSet;

+

     //

     // Discard changed value for each FormSet in the maintain list.

     //

@@ -2451,6 +2461,9 @@
       if (!ValidateFormSet(LocalFormSet)) {

         continue;

       }

+

+      mSystemLevelFormSet = LocalFormSet;

+

       DiscardForm (LocalFormSet, NULL, FormSetLevel);

       if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {

         //

@@ -2461,6 +2474,8 @@
         DestroyFormSet (LocalFormSet);

       }

     }

+

+    mSystemLevelFormSet = OldFormSet;

   }

 

   return EFI_SUCCESS;  

@@ -3402,6 +3417,7 @@
   LIST_ENTRY              *Link;

   FORM_BROWSER_STATEMENT  *Question;

   FORM_BROWSER_FORMSET    *LocalFormSet;

+  FORM_BROWSER_FORMSET    *OldFormSet;

 

   Status = EFI_SUCCESS;

 

@@ -3485,7 +3501,9 @@
     // Preload all Hii formset.

     //

     LoadAllHiiFormset();

-       

+

+    OldFormSet = mSystemLevelFormSet;

+

     //

     // Set Default Value for each FormSet in the maintain list.

     //

@@ -3496,8 +3514,13 @@
       if (!ValidateFormSet(LocalFormSet)) {

         continue;

       }

+

+      mSystemLevelFormSet = LocalFormSet;

+

       ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);

     }

+

+    mSystemLevelFormSet = OldFormSet;

   }

 

   return EFI_SUCCESS;

@@ -4210,7 +4233,7 @@
       return;

 

     case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:

-      if (Storage->BrowserStorage->ReferenceCount > 1) {

+      if (Storage->BrowserStorage->ConfigRequest != NULL) {

         ConfigRequestAdjust(Storage);

         return;

       }

@@ -4312,6 +4335,17 @@
   FORM_BROWSER_FORMSET    *OldFormSet;

 

   //

+  // Try to find pre FormSet in the maintain backup list.

+  // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.

+  //

+  OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);

+  if (OldFormSet != NULL) {

+    RemoveEntryList (&OldFormSet->Link);

+    DestroyFormSet (OldFormSet);

+  }

+  InsertTailList (&gBrowserFormSetList, &FormSet->Link);

+

+  //

   // Extract default from IFR binary for no storage questions.

   //  

   ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForNoStorage, NULL, TRUE);

@@ -4327,17 +4361,6 @@
 

     Link = GetNextNode (&FormSet->StorageListHead, Link);

   }

-

-  //

-  // Try to find pre FormSet in the maintain backup list.

-  // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.

-  //

-  OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);

-  if (OldFormSet != NULL) {

-    RemoveEntryList (&OldFormSet->Link);

-    DestroyFormSet (OldFormSet);

-  }

-  InsertTailList (&gBrowserFormSetList, &FormSet->Link);

 }

 

 

diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index bd19ae6..7da21b7 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -151,7 +151,6 @@
   CHAR16           *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>

                                    // <RequestElement> includes all fields which is used by current form sets.

   UINTN            SpareStrLen;    // Spare length of ConfigRequest string buffer

-  UINT8            ReferenceCount; // How many form set storage refrence this storage.

 } BROWSER_STORAGE;

 

 #define BROWSER_STORAGE_FROM_LINK(a)  CR (a, BROWSER_STORAGE, Link, BROWSER_STORAGE_SIGNATURE)