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
This commit is contained in:
Eric Dong 2013-09-24 10:08:04 +00:00 committed by ydong10
parent ea0f646433
commit 6e74560f20
3 changed files with 43 additions and 31 deletions

View File

@ -510,10 +510,6 @@ CreateStorage (
InitializeConfigHdr (FormSet, BrowserStorage); InitializeConfigHdr (FormSet, BrowserStorage);
} }
//
// Add count because one formset storage use this global storage.
//
BrowserStorage->ReferenceCount++;
Storage->BrowserStorage = BrowserStorage; Storage->BrowserStorage = BrowserStorage;
Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr); Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr);
@ -742,12 +738,6 @@ DestroyStorage (
FreePool (Storage->ConfigRequest); FreePool (Storage->ConfigRequest);
} }
//
// Minus the reference to the global storage.
//
ASSERT (Storage->BrowserStorage->ReferenceCount > 0);
Storage->BrowserStorage->ReferenceCount--;
FreePool (Storage); FreePool (Storage);
} }

View File

@ -53,6 +53,7 @@ BOOLEAN gExitRequired;
BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel; BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;
BOOLEAN mBrowserScopeFirstSet = TRUE; BOOLEAN mBrowserScopeFirstSet = TRUE;
EXIT_HANDLER ExitHandlerFunction = NULL; EXIT_HANDLER ExitHandlerFunction = NULL;
FORM_BROWSER_FORMSET *mSystemLevelFormSet;
// //
// Browser Global Strings // Browser Global Strings
@ -255,6 +256,9 @@ LoadAllHiiFormset (
UINTN Index; UINTN Index;
EFI_GUID ZeroGuid; EFI_GUID ZeroGuid;
EFI_STATUS Status; EFI_STATUS Status;
FORM_BROWSER_FORMSET *OldFormset;
OldFormset = mSystemLevelFormSet;
// //
// Get all the Hii handles // Get all the Hii handles
@ -278,6 +282,8 @@ LoadAllHiiFormset (
// //
LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
ASSERT (LocalFormSet != NULL); ASSERT (LocalFormSet != NULL);
mSystemLevelFormSet = LocalFormSet;
ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet); Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);
if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) { if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {
@ -300,6 +306,8 @@ LoadAllHiiFormset (
// Free resources, and restore gOldFormSet and gClassOfVfr // Free resources, and restore gOldFormSet and gClassOfVfr
// //
FreePool (HiiHandles); FreePool (HiiHandles);
mSystemLevelFormSet = OldFormset;
} }
/** /**
@ -388,6 +396,7 @@ SendForm (
break; break;
} }
Selection->FormSet = FormSet; Selection->FormSet = FormSet;
mSystemLevelFormSet = FormSet;
// //
// Display this formset // Display this formset
@ -397,6 +406,7 @@ SendForm (
Status = SetupBrowser (Selection); Status = SetupBrowser (Selection);
gCurrentSelection = NULL; gCurrentSelection = NULL;
mSystemLevelFormSet = NULL;
// //
// If no data is changed, don't need to save current FormSet into the maintain list. // If no data is changed, don't need to save current FormSet into the maintain list.
@ -580,7 +590,6 @@ BrowserCallback (
LIST_ENTRY *Link; LIST_ENTRY *Link;
BROWSER_STORAGE *Storage; BROWSER_STORAGE *Storage;
FORMSET_STORAGE *FormsetStorage; FORMSET_STORAGE *FormsetStorage;
FORM_BROWSER_FORMSET *FormSet;
UINTN TotalSize; UINTN TotalSize;
BOOLEAN Found; BOOLEAN Found;
@ -650,16 +659,15 @@ BrowserCallback (
// //
// GUID/Name is not specified, take the first storage in FormSet // GUID/Name is not specified, take the first storage in FormSet
// //
if (gCurrentSelection == NULL) { if (mSystemLevelFormSet == NULL) {
return EFI_NOT_READY; return EFI_NOT_READY;
} }
// //
// Generate <ConfigResp> // Generate <ConfigResp>
// //
FormSet = gCurrentSelection->FormSet; Link = GetFirstNode (&mSystemLevelFormSet->StorageListHead);
Link = GetFirstNode (&FormSet->StorageListHead); if (IsNull (&mSystemLevelFormSet->StorageListHead, Link)) {
if (IsNull (&FormSet->StorageListHead, Link)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -2361,7 +2369,8 @@ DiscardForm (
LIST_ENTRY *Link; LIST_ENTRY *Link;
FORMSET_STORAGE *Storage; FORMSET_STORAGE *Storage;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
FORM_BROWSER_FORMSET *LocalFormSet; FORM_BROWSER_FORMSET *LocalFormSet;
FORM_BROWSER_FORMSET *OldFormSet;
// //
// Check the supported setting level. // Check the supported setting level.
@ -2440,7 +2449,8 @@ DiscardForm (
// //
// System Level Discard. // System Level Discard.
// //
OldFormSet = mSystemLevelFormSet;
// //
// Discard changed value for each FormSet in the maintain list. // Discard changed value for each FormSet in the maintain list.
// //
@ -2451,6 +2461,9 @@ DiscardForm (
if (!ValidateFormSet(LocalFormSet)) { if (!ValidateFormSet(LocalFormSet)) {
continue; continue;
} }
mSystemLevelFormSet = LocalFormSet;
DiscardForm (LocalFormSet, NULL, FormSetLevel); DiscardForm (LocalFormSet, NULL, FormSetLevel);
if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) { if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {
// //
@ -2461,6 +2474,8 @@ DiscardForm (
DestroyFormSet (LocalFormSet); DestroyFormSet (LocalFormSet);
} }
} }
mSystemLevelFormSet = OldFormSet;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -3402,6 +3417,7 @@ ExtractDefault (
LIST_ENTRY *Link; LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question; FORM_BROWSER_STATEMENT *Question;
FORM_BROWSER_FORMSET *LocalFormSet; FORM_BROWSER_FORMSET *LocalFormSet;
FORM_BROWSER_FORMSET *OldFormSet;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -3485,7 +3501,9 @@ ExtractDefault (
// Preload all Hii formset. // Preload all Hii formset.
// //
LoadAllHiiFormset(); LoadAllHiiFormset();
OldFormSet = mSystemLevelFormSet;
// //
// Set Default Value for each FormSet in the maintain list. // Set Default Value for each FormSet in the maintain list.
// //
@ -3496,8 +3514,13 @@ ExtractDefault (
if (!ValidateFormSet(LocalFormSet)) { if (!ValidateFormSet(LocalFormSet)) {
continue; continue;
} }
mSystemLevelFormSet = LocalFormSet;
ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst); ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst);
} }
mSystemLevelFormSet = OldFormSet;
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -4210,7 +4233,7 @@ LoadStorage (
return; return;
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER: case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
if (Storage->BrowserStorage->ReferenceCount > 1) { if (Storage->BrowserStorage->ConfigRequest != NULL) {
ConfigRequestAdjust(Storage); ConfigRequestAdjust(Storage);
return; return;
} }
@ -4311,6 +4334,17 @@ InitializeCurrentSetting (
FORMSET_STORAGE *Storage; FORMSET_STORAGE *Storage;
FORM_BROWSER_FORMSET *OldFormSet; 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. // Extract default from IFR binary for no storage questions.
// //
@ -4327,17 +4361,6 @@ InitializeCurrentSetting (
Link = GetNextNode (&FormSet->StorageListHead, Link); 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);
} }

View File

@ -151,7 +151,6 @@ typedef struct {
CHAR16 *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement> CHAR16 *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>
// <RequestElement> includes all fields which is used by current form sets. // <RequestElement> includes all fields which is used by current form sets.
UINTN SpareStrLen; // Spare length of ConfigRequest string buffer UINTN SpareStrLen; // Spare length of ConfigRequest string buffer
UINT8 ReferenceCount; // How many form set storage refrence this storage.
} BROWSER_STORAGE; } BROWSER_STORAGE;
#define BROWSER_STORAGE_FROM_LINK(a) CR (a, BROWSER_STORAGE, Link, BROWSER_STORAGE_SIGNATURE) #define BROWSER_STORAGE_FROM_LINK(a) CR (a, BROWSER_STORAGE, Link, BROWSER_STORAGE_SIGNATURE)