CHAR16 NoResponse;\r
EFI_INPUT_KEY Key;\r
EFI_STATUS Status;\r
+ BROWSER_SETTING_SCOPE Scope;\r
\r
CurrentMenu = Selection->CurrentMenu;\r
\r
if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {\r
+ //\r
+ // we have a parent, so go to the parent menu\r
+ //\r
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {\r
+ //\r
+ // The parent menu and current menu are in the same formset\r
+ //\r
+ Selection->Action = UI_ACTION_REFRESH_FORM;\r
+ Scope = FormLevel;\r
+ } else {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ CopyMem (&Selection->FormSetGuid, &CurrentMenu->Parent->FormSetGuid, sizeof (EFI_GUID));\r
+ Selection->Handle = CurrentMenu->Parent->HiiHandle;\r
+ Scope = FormSetLevel;\r
+ }\r
+\r
//\r
// Form Level Check whether the data is changed.\r
//\r
- if (gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) {\r
+ if ((gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) ||\r
+ (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequired(Selection->FormSet) && Scope == FormSetLevel)) {\r
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
\r
YesResponse = gYesResponse[0];\r
//\r
// If the user hits the YesResponse key\r
//\r
- Status = SubmitForm (Selection->FormSet, Selection->Form, FormLevel);\r
+ Status = SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
} else {\r
//\r
// If the user hits the NoResponse key\r
//\r
- Status = DiscardForm (Selection->FormSet, Selection->Form, FormLevel);\r
+ Status = DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
}\r
}\r
\r
- //\r
- // we have a parent, so go to the parent menu\r
- //\r
- if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {\r
- //\r
- // The parent menu and current menu are in the same formset\r
- //\r
- Selection->Action = UI_ACTION_REFRESH_FORM;\r
- } else {\r
- Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
- }\r
Selection->Statement = NULL;\r
\r
Selection->FormId = CurrentMenu->Parent->FormId;\r
of the given parent menu.\r
\r
@param Parent The parent of menu to be added.\r
+ @param HiiHandle Hii handle related to this formset.\r
@param FormSetGuid The Formset Guid of menu to be added.\r
@param FormId The Form ID of menu to be added.\r
\r
UI_MENU_LIST *\r
UiAddMenuList (\r
IN OUT UI_MENU_LIST *Parent,\r
+ IN EFI_HII_HANDLE HiiHandle,\r
IN EFI_GUID *FormSetGuid,\r
IN UINT16 FormId\r
)\r
MenuList->Signature = UI_MENU_LIST_SIGNATURE;\r
InitializeListHead (&MenuList->ChildListHead);\r
\r
+ MenuList->HiiHandle = HiiHandle;\r
CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
MenuList->FormId = FormId;\r
MenuList->Parent = Parent;\r
\r
\r
/**\r
- Search Menu with given FormId in the parent menu and all its child menus.\r
+ Search Menu with given FormId and FormSetGuid in all cached menu list.\r
\r
@param Parent The parent of menu to search.\r
+ @param FormSetGuid The Formset GUID of the menu to search. \r
@param FormId The Form ID of menu to search.\r
\r
@return A pointer to menu found or NULL if not found.\r
UI_MENU_LIST *\r
UiFindChildMenuList (\r
IN UI_MENU_LIST *Parent,\r
+ IN EFI_GUID *FormSetGuid, \r
IN UINT16 FormId\r
)\r
{\r
UI_MENU_LIST *Child;\r
UI_MENU_LIST *MenuList;\r
\r
- if (Parent->FormId == FormId) {\r
+ ASSERT (Parent != NULL);\r
+\r
+ if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid)) {\r
return Parent;\r
}\r
\r
while (!IsNull (&Parent->ChildListHead, Link)) {\r
Child = UI_MENU_LIST_FROM_LINK (Link);\r
\r
- MenuList = UiFindChildMenuList (Child, FormId);\r
+ MenuList = UiFindChildMenuList (Child, FormSetGuid, FormId);\r
if (MenuList != NULL) {\r
return MenuList;\r
}\r
while (!IsNull (&gMenuList, Link)) {\r
MenuList = UI_MENU_LIST_FROM_LINK (Link);\r
\r
- if (CompareGuid (FormSetGuid, &MenuList->FormSetGuid)) {\r
- //\r
- // This is the formset we are looking for, find the form in this formset\r
- //\r
- Child = UiFindChildMenuList (MenuList, FormId);\r
- if (Child != NULL) {\r
- return Child;\r
- }\r
+ Child = UiFindChildMenuList(MenuList, FormSetGuid, FormId);\r
+ if (Child != NULL) {\r
+ return Child;\r
}\r
\r
Link = GetNextNode (&gMenuList, Link);\r
return HiiHandle;\r
}\r
\r
+/**\r
+ Find HII Handle in the HII database associated with given form set guid.\r
+\r
+ If FormSetGuid is NULL, then ASSERT.\r
+\r
+ @param ComparingGuid FormSet Guid associated with the HII package list\r
+ handle.\r
+\r
+ @retval Handle HII package list Handle associated with the Device\r
+ Path.\r
+ @retval NULL Hii Package list handle is not found.\r
+\r
+**/\r
+EFI_HII_HANDLE\r
+FormSetGuidToHiiHandle (\r
+ EFI_GUID *ComparingGuid\r
+ )\r
+{\r
+ EFI_HII_HANDLE *HiiHandles;\r
+ UINTN Index;\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ UINT32 Offset;\r
+ UINT32 Offset2;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ UINT8 *Package;\r
+ UINT8 *OpCodeData;\r
+ EFI_STATUS Status;\r
+ EFI_HII_HANDLE HiiHandle;\r
+\r
+ ASSERT (ComparingGuid != NULL);\r
+\r
+ HiiHandle = NULL;\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
+ BufferSize = 0;\r
+ HiiPackageList = NULL;\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocatePool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
+ }\r
+ if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Get Form package from this HII package List\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ Offset2 = 0;\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
+\r
+ while (Offset < PackageListLength) {\r
+ Package = ((UINT8 *) HiiPackageList) + Offset;\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+ //\r
+ // Search FormSet in this Form Package\r
+ //\r
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset2 < PackageHeader.Length) {\r
+ OpCodeData = Package + Offset2;\r
+\r
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+ //\r
+ // Try to compare against formset GUID\r
+ //\r
+ if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ HiiHandle = HiiHandles[Index];\r
+ break;\r
+ }\r
+ }\r
+\r
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+ }\r
+ }\r
+ if (HiiHandle != NULL) {\r
+ break;\r
+ }\r
+ Offset += PackageHeader.Length;\r
+ }\r
+ \r
+ FreePool (HiiPackageList);\r
+ if (HiiHandle != NULL) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (HiiHandles);\r
+\r
+ return HiiHandle;\r
+}\r
+\r
/**\r
Process the goto op code, update the info in the selection structure.\r
\r
EFI_INPUT_KEY Key;\r
EFI_STATUS Status;\r
UI_MENU_LIST *MenuList;\r
+ BOOLEAN UpdateFormInfo;\r
\r
Status = EFI_SUCCESS;\r
+ UpdateFormInfo = TRUE;\r
\r
if (Statement->HiiValue.Value.ref.DevicePath != 0) {\r
if (Selection->Form->ModalForm) {\r
// Goto another Formset, check for uncommitted data\r
//\r
Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ \r
+ Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);\r
+ if (Selection->Handle == NULL) {\r
+ //\r
+ // If target Hii Handle not found, exit\r
+ //\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ Selection->Statement = NULL;\r
+ return Status;\r
+ } \r
\r
CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
//\r
Selection->Action = UI_ACTION_REFRESH_FORM;\r
\r
- //\r
- // Link current form so that we can always go back when someone hits the ESC\r
- //\r
- MenuList = UiFindMenuList (&Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId);\r
- if (MenuList == NULL && Selection->CurrentMenu != NULL) {\r
- MenuList = UiAddMenuList (Selection->CurrentMenu, &Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId);\r
- }\r
-\r
Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
} else if (Statement->HiiValue.Value.ref.QuestionId != 0) {\r
*NewLine = TRUE;\r
}\r
}\r
+ UpdateFormInfo = FALSE;\r
} else {\r
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
Selection->Action = UI_ACTION_REFRESH_FORM;\r
}\r
+ UpdateFormInfo = FALSE;\r
+ }\r
+\r
+ if (UpdateFormInfo) {\r
+ //\r
+ // Link current form so that we can always go back when someone hits the ESC\r
+ //\r
+ MenuList = UiFindMenuList (&Selection->FormSetGuid, Selection->FormId);\r
+ if (MenuList == NULL && Selection->CurrentMenu != NULL) {\r
+ MenuList = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);\r
+ }\r
}\r
\r
return Status;\r
//\r
// Current menu not found, add it to the menu tree\r
//\r
- CurrentMenu = UiAddMenuList (NULL, &Selection->FormSetGuid, Selection->FormId);\r
+ CurrentMenu = UiAddMenuList (NULL, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);\r
}\r
ASSERT (CurrentMenu != NULL);\r
Selection->CurrentMenu = CurrentMenu;\r