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 );