From: ydong10 Date: Mon, 31 Oct 2011 03:33:55 +0000 (+0000) Subject: When browser was requested to go to another formset, it also needs to update the... X-Git-Tag: edk2-stable201903~13997 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=b2e444aaf7adcf97a52303f6785336ea19312729 When browser was requested to go to another formset, it also needs to update the hiihandle in Selection structure. If not update this handle, later when call function GetIfrBinaryData to get binary ifr data will return failed. Also add sample code to use it. Signed-off-by: ydong10 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12607 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr b/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr index cedb665fe6..e3710acd1b 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr +++ b/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr @@ -494,6 +494,13 @@ formset prompt = STRING_TOKEN(STR_GOTO_FORM6), //SixthSetupPage // this too has no end-op and basically it's a jump to a form ONLY help = STRING_TOKEN(STR_GOTO_HELP); + goto + formsetguid = DRIVER_SAMPLE_INVENTORY_GUID, + formid = 0x1, + question = 0x1, + prompt = STRING_TOKEN(STR_GOTO_ANOTHER_FORMSET), + help = STRING_TOKEN(STR_GOTO_ANOTHER_FORMSET_HELP); + guidop guid = DRIVER_SAMPLE_FORMSET_GUID, datatype = MY_EFI_VARSTORE_DATA, diff --git a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni index 8aa526b83a..5a1e23f03d 100644 Binary files a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni and b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni differ diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c index 62ce070462..b58a00a544 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c @@ -1006,14 +1006,32 @@ FindNextMenu ( CHAR16 NoResponse; EFI_INPUT_KEY Key; EFI_STATUS Status; + BROWSER_SETTING_SCOPE Scope; CurrentMenu = Selection->CurrentMenu; if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) { + // + // we have a parent, so go to the parent menu + // + if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) { + // + // The parent menu and current menu are in the same formset + // + Selection->Action = UI_ACTION_REFRESH_FORM; + Scope = FormLevel; + } else { + Selection->Action = UI_ACTION_REFRESH_FORMSET; + CopyMem (&Selection->FormSetGuid, &CurrentMenu->Parent->FormSetGuid, sizeof (EFI_GUID)); + Selection->Handle = CurrentMenu->Parent->HiiHandle; + Scope = FormSetLevel; + } + // // Form Level Check whether the data is changed. // - if (gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) { + if ((gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) || + (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequired(Selection->FormSet) && Scope == FormSetLevel)) { Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); YesResponse = gYesResponse[0]; @@ -1050,26 +1068,15 @@ FindNextMenu ( // // If the user hits the YesResponse key // - Status = SubmitForm (Selection->FormSet, Selection->Form, FormLevel); + Status = SubmitForm (Selection->FormSet, Selection->Form, Scope); } else { // // If the user hits the NoResponse key // - Status = DiscardForm (Selection->FormSet, Selection->Form, FormLevel); + Status = DiscardForm (Selection->FormSet, Selection->Form, Scope); } } - // - // we have a parent, so go to the parent menu - // - if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) { - // - // The parent menu and current menu are in the same formset - // - Selection->Action = UI_ACTION_REFRESH_FORM; - } else { - Selection->Action = UI_ACTION_REFRESH_FORMSET; - } Selection->Statement = NULL; Selection->FormId = CurrentMenu->Parent->FormId; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c index 2b0f052060..a1e6f81ecb 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c @@ -322,11 +322,6 @@ SendForm ( CopyMem (&Selection->FormSetGuid, &gEfiHiiPlatformSetupFormsetGuid, sizeof (EFI_GUID)); } - // - // Try to find pre FormSet in the maintain backup list. - // - gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle); - do { FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); ASSERT (FormSet != NULL); @@ -341,6 +336,11 @@ SendForm ( } Selection->FormSet = FormSet; + // + // Try to find pre FormSet in the maintain backup list. + // + gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle); + // // Display this formset // diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c index e972bad6c3..4dd439521e 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c @@ -175,6 +175,7 @@ UiFreeMenu ( of the given parent menu. @param Parent The parent of menu to be added. + @param HiiHandle Hii handle related to this formset. @param FormSetGuid The Formset Guid of menu to be added. @param FormId The Form ID of menu to be added. @@ -184,6 +185,7 @@ UiFreeMenu ( UI_MENU_LIST * UiAddMenuList ( IN OUT UI_MENU_LIST *Parent, + IN EFI_HII_HANDLE HiiHandle, IN EFI_GUID *FormSetGuid, IN UINT16 FormId ) @@ -198,6 +200,7 @@ UiAddMenuList ( MenuList->Signature = UI_MENU_LIST_SIGNATURE; InitializeListHead (&MenuList->ChildListHead); + MenuList->HiiHandle = HiiHandle; CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID)); MenuList->FormId = FormId; MenuList->Parent = Parent; @@ -216,9 +219,10 @@ UiAddMenuList ( /** - Search Menu with given FormId in the parent menu and all its child menus. + Search Menu with given FormId and FormSetGuid in all cached menu list. @param Parent The parent of menu to search. + @param FormSetGuid The Formset GUID of the menu to search. @param FormId The Form ID of menu to search. @return A pointer to menu found or NULL if not found. @@ -227,6 +231,7 @@ UiAddMenuList ( UI_MENU_LIST * UiFindChildMenuList ( IN UI_MENU_LIST *Parent, + IN EFI_GUID *FormSetGuid, IN UINT16 FormId ) { @@ -234,7 +239,9 @@ UiFindChildMenuList ( UI_MENU_LIST *Child; UI_MENU_LIST *MenuList; - if (Parent->FormId == FormId) { + ASSERT (Parent != NULL); + + if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid)) { return Parent; } @@ -242,7 +249,7 @@ UiFindChildMenuList ( while (!IsNull (&Parent->ChildListHead, Link)) { Child = UI_MENU_LIST_FROM_LINK (Link); - MenuList = UiFindChildMenuList (Child, FormId); + MenuList = UiFindChildMenuList (Child, FormSetGuid, FormId); if (MenuList != NULL) { return MenuList; } @@ -277,14 +284,9 @@ UiFindMenuList ( while (!IsNull (&gMenuList, Link)) { MenuList = UI_MENU_LIST_FROM_LINK (Link); - if (CompareGuid (FormSetGuid, &MenuList->FormSetGuid)) { - // - // This is the formset we are looking for, find the form in this formset - // - Child = UiFindChildMenuList (MenuList, FormId); - if (Child != NULL) { - return Child; - } + Child = UiFindChildMenuList(MenuList, FormSetGuid, FormId); + if (Child != NULL) { + return Child; } Link = GetNextNode (&gMenuList, Link); @@ -1664,6 +1666,112 @@ DevicePathToHiiHandle ( return HiiHandle; } +/** + Find HII Handle in the HII database associated with given form set guid. + + If FormSetGuid is NULL, then ASSERT. + + @param ComparingGuid FormSet Guid associated with the HII package list + handle. + + @retval Handle HII package list Handle associated with the Device + Path. + @retval NULL Hii Package list handle is not found. + +**/ +EFI_HII_HANDLE +FormSetGuidToHiiHandle ( + EFI_GUID *ComparingGuid + ) +{ + EFI_HII_HANDLE *HiiHandles; + UINTN Index; + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList; + UINTN BufferSize; + UINT32 Offset; + UINT32 Offset2; + UINT32 PackageListLength; + EFI_HII_PACKAGE_HEADER PackageHeader; + UINT8 *Package; + UINT8 *OpCodeData; + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + + ASSERT (ComparingGuid != NULL); + + HiiHandle = NULL; + // + // Get all the Hii handles + // + HiiHandles = HiiGetHiiHandles (NULL); + ASSERT (HiiHandles != NULL); + + // + // Search for formset of each class type + // + for (Index = 0; HiiHandles[Index] != NULL; Index++) { + BufferSize = 0; + HiiPackageList = NULL; + Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList); + if (Status == EFI_BUFFER_TOO_SMALL) { + HiiPackageList = AllocatePool (BufferSize); + ASSERT (HiiPackageList != NULL); + + Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList); + } + if (EFI_ERROR (Status) || HiiPackageList == NULL) { + return NULL; + } + + // + // Get Form package from this HII package List + // + Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); + Offset2 = 0; + CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); + + while (Offset < PackageListLength) { + Package = ((UINT8 *) HiiPackageList) + Offset; + CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER)); + + if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) { + // + // Search FormSet in this Form Package + // + Offset2 = sizeof (EFI_HII_PACKAGE_HEADER); + while (Offset2 < PackageHeader.Length) { + OpCodeData = Package + Offset2; + + if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) { + // + // Try to compare against formset GUID + // + if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) { + HiiHandle = HiiHandles[Index]; + break; + } + } + + Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; + } + } + if (HiiHandle != NULL) { + break; + } + Offset += PackageHeader.Length; + } + + FreePool (HiiPackageList); + if (HiiHandle != NULL) { + break; + } + } + + FreePool (HiiHandles); + + return HiiHandle; +} + /** Process the goto op code, update the info in the selection structure. @@ -1694,8 +1802,10 @@ ProcessGotoOpCode ( EFI_INPUT_KEY Key; EFI_STATUS Status; UI_MENU_LIST *MenuList; + BOOLEAN UpdateFormInfo; Status = EFI_SUCCESS; + UpdateFormInfo = TRUE; if (Statement->HiiValue.Value.ref.DevicePath != 0) { if (Selection->Form->ModalForm) { @@ -1763,6 +1873,16 @@ ProcessGotoOpCode ( // Goto another Formset, check for uncommitted data // Selection->Action = UI_ACTION_REFRESH_FORMSET; + + Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid); + if (Selection->Handle == NULL) { + // + // If target Hii Handle not found, exit + // + Selection->Action = UI_ACTION_EXIT; + Selection->Statement = NULL; + return Status; + } CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID)); Selection->FormId = Statement->HiiValue.Value.ref.FormId; @@ -1798,14 +1918,6 @@ ProcessGotoOpCode ( // Selection->Action = UI_ACTION_REFRESH_FORM; - // - // Link current form so that we can always go back when someone hits the ESC - // - MenuList = UiFindMenuList (&Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId); - if (MenuList == NULL && Selection->CurrentMenu != NULL) { - MenuList = UiAddMenuList (Selection->CurrentMenu, &Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId); - } - Selection->FormId = Statement->HiiValue.Value.ref.FormId; Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId; } else if (Statement->HiiValue.Value.ref.QuestionId != 0) { @@ -1824,10 +1936,22 @@ ProcessGotoOpCode ( *NewLine = TRUE; } } + UpdateFormInfo = FALSE; } else { if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) { Selection->Action = UI_ACTION_REFRESH_FORM; } + UpdateFormInfo = FALSE; + } + + if (UpdateFormInfo) { + // + // Link current form so that we can always go back when someone hits the ESC + // + MenuList = UiFindMenuList (&Selection->FormSetGuid, Selection->FormId); + if (MenuList == NULL && Selection->CurrentMenu != NULL) { + MenuList = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId); + } } return Status; @@ -1953,7 +2077,7 @@ UiDisplayMenu ( // // Current menu not found, add it to the menu tree // - CurrentMenu = UiAddMenuList (NULL, &Selection->FormSetGuid, Selection->FormId); + CurrentMenu = UiAddMenuList (NULL, Selection->Handle, &Selection->FormSetGuid, Selection->FormId); } ASSERT (CurrentMenu != NULL); Selection->CurrentMenu = CurrentMenu; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h index df5a22fe71..f8797725e9 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h @@ -160,6 +160,7 @@ struct _UI_MENU_LIST { UINTN Signature; LIST_ENTRY Link; + EFI_HII_HANDLE HiiHandle; EFI_GUID FormSetGuid; UINT16 FormId; UINT16 QuestionId; @@ -233,6 +234,7 @@ UiFreeMenu ( of the given parent menu. @param Parent The parent of menu to be added. + @param HiiHandle Hii handle related to this formset. @param FormSetGuid The Formset Guid of menu to be added. @param FormId The Form ID of menu to be added. @@ -242,6 +244,7 @@ UiFreeMenu ( UI_MENU_LIST * UiAddMenuList ( IN OUT UI_MENU_LIST *Parent, + IN EFI_HII_HANDLE HiiHandle, IN EFI_GUID *FormSetGuid, IN UINT16 FormId ); @@ -250,6 +253,7 @@ UiAddMenuList ( Search Menu with given FormId in the parent menu and all its child menus. @param Parent The parent of menu to search. + @param FormSetGuid The Formset GUID of the menu to search. @param FormId The Form ID of menu to search. @return A pointer to menu found or NULL if not found. @@ -258,6 +262,7 @@ UiAddMenuList ( UI_MENU_LIST * UiFindChildMenuList ( IN UI_MENU_LIST *Parent, + IN EFI_GUID *FormSetGuid, IN UINT16 FormId );