Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
Link = GetNextNode (&Form->StatementListHead, Link);\r
\r
+ //\r
+ // For password opcode, not set the the value changed flag.\r
+ //\r
+ if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
+ continue;\r
+ }\r
+\r
IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);\r
}\r
}\r
FORM_ENTRY_INFO *ParentMenu;\r
\r
CurrentMenu = Selection->CurrentMenu;\r
- ParentMenu = UiFindParentMenu(CurrentMenu);\r
-\r
- //\r
- // Find a menu which has different formset guid with current.\r
- //\r
- while (ParentMenu != NULL && CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
- CurrentMenu = ParentMenu;\r
- ParentMenu = UiFindParentMenu(CurrentMenu);\r
- }\r
+ ParentMenu = UiFindParentMenu(CurrentMenu, FormSetLevel);\r
\r
if (ParentMenu != NULL) {\r
CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
BOOLEAN\r
FindNextMenu (\r
IN OUT UI_MENU_SELECTION *Selection,\r
- IN BROWSER_SETTING_SCOPE SettingLevel\r
+ IN BROWSER_SETTING_SCOPE SettingLevel\r
)\r
{\r
FORM_ENTRY_INFO *CurrentMenu;\r
BROWSER_SETTING_SCOPE Scope;\r
\r
CurrentMenu = Selection->CurrentMenu;\r
- ParentMenu = NULL;\r
Scope = FormSetLevel;\r
\r
- if (CurrentMenu != NULL && (ParentMenu = UiFindParentMenu(CurrentMenu)) != NULL) {\r
- //\r
- // we have a parent, so go to the parent menu\r
- //\r
- if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
- if (SettingLevel == FormSetLevel) {\r
- //\r
- // Find a menu which has different formset guid with current.\r
- //\r
- while (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
- CurrentMenu = ParentMenu;\r
- if ((ParentMenu = UiFindParentMenu(CurrentMenu)) == NULL) {\r
- break;\r
- }\r
- }\r
+ ParentMenu = UiFindParentMenu(CurrentMenu, SettingLevel);\r
+ while (ParentMenu != NULL && !ValidateHiiHandle(ParentMenu->HiiHandle)) {\r
+ ParentMenu = UiFindParentMenu(ParentMenu, SettingLevel);\r
+ }\r
\r
- if (ParentMenu != NULL) {\r
- Scope = FormSetLevel;\r
- }\r
- } else {\r
- Scope = FormLevel;\r
- }\r
+ if (ParentMenu != NULL) {\r
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
+ Scope = FormLevel;\r
} else {\r
Scope = FormSetLevel;\r
}\r
TypeValue,\r
&ActionRequest\r
);\r
+ //\r
+ // IFR is updated, force to reparse the IFR binary\r
+ //\r
+ if (mHiiPackageListUpdated) {\r
+ if (BackUpBuffer != NULL) {\r
+ FreePool (BackUpBuffer);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
if (!EFI_ERROR (Status)) {\r
//\r
// Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue\r
if (BackUpBuffer != NULL) {\r
FreePool (BackUpBuffer);\r
}\r
+\r
+ //\r
+ // If Question != NULL, means just process one question\r
+ // and if code reach here means this question has finished\r
+ // processing, so just break.\r
+ //\r
+ if (Question != NULL) {\r
+ break;\r
+ }\r
}\r
\r
if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
do {\r
//\r
// IFR is updated, force to reparse the IFR binary\r
+ // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and \r
+ // EFI_BROWSER_ACTION_RETRIEVE, so code place here.\r
//\r
if (mHiiPackageListUpdated) {\r
Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
}\r
\r
//\r
- // IFR is updated during callback of open form, force to reparse the IFR binary\r
+ // IFR is updated during callback of EFI_BROWSER_ACTION_FORM_OPEN, force to reparse the IFR binary\r
//\r
if (mHiiPackageListUpdated) {\r
Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
(Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
Status = ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+ //\r
+ // IFR is updated during callback of EFI_BROWSER_ACTION_CHANGING, force to reparse the IFR binary\r
+ //\r
+ if (mHiiPackageListUpdated) {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ mHiiPackageListUpdated = FALSE;\r
+ break;\r
+ }\r
+\r
if (Statement->Operand == EFI_IFR_REF_OP) {\r
//\r
// Process dynamic update ref opcode.\r
\r
if (!EFI_ERROR (Status) && Statement->Operand != EFI_IFR_REF_OP) {\r
ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+ //\r
+ // IFR is updated during callback of EFI_BROWSER_ACTION_CHANGED, force to reparse the IFR binary\r
+ //\r
+ if (mHiiPackageListUpdated) {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ mHiiPackageListUpdated = FALSE;\r
+ break;\r
+ }\r
}\r
} else {\r
//\r
Find parent menu for current menu.\r
\r
@param CurrentMenu Current Menu\r
+ @param SettingLevel Whether find parent menu in Form Level or Formset level.\r
+ In form level, just find the parent menu; \r
+ In formset level, find the parent menu which has different\r
+ formset guid value.\r
\r
@retval The parent menu for current menu.\r
**/\r
FORM_ENTRY_INFO *\r
UiFindParentMenu (\r
- IN FORM_ENTRY_INFO *CurrentMenu\r
+ IN FORM_ENTRY_INFO *CurrentMenu,\r
+ IN BROWSER_SETTING_SCOPE SettingLevel\r
)\r
{\r
FORM_ENTRY_INFO *ParentMenu;\r
+ LIST_ENTRY *Link;\r
+\r
+ ASSERT (SettingLevel == FormLevel || SettingLevel == FormSetLevel);\r
\r
+ if (CurrentMenu == NULL) {\r
+ return NULL;\r
+ }\r
+ \r
ParentMenu = NULL;\r
- if (CurrentMenu->Link.BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
- ParentMenu = FORM_ENTRY_INFO_FROM_LINK (CurrentMenu->Link.BackLink);\r
+ Link = &CurrentMenu->Link;\r
+\r
+ while (Link->BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
+ ParentMenu = FORM_ENTRY_INFO_FROM_LINK (Link->BackLink);\r
+\r
+ if (SettingLevel == FormLevel) {\r
+ //\r
+ // For FormLevel, just find the parent menu, return.\r
+ //\r
+ break;\r
+ }\r
+\r
+ if (!CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
+ //\r
+ // For SystemLevel, must find the menu which has different formset.\r
+ //\r
+ break;\r
+ }\r
+\r
+ Link = Link->BackLink;\r
+ }\r
+\r
+ //\r
+ // Not find the parent menu, just return NULL.\r
+ //\r
+ if (Link->BackLink == &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
+ return NULL;\r
}\r
\r
return ParentMenu;\r
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
ASSERT (FormSet != NULL);\r
\r
+ //\r
+ // Validate the HiiHandle\r
+ // if validate failed, find the first validate parent HiiHandle.\r
+ //\r
+ if (!ValidateHiiHandle(Selection->Handle)) {\r
+ FindNextMenu (Selection, FormSetLevel);\r
+ }\r
+\r
//\r
// Initialize internal data structures of FormSet\r
//\r
\r
**/\r
BOOLEAN\r
-ValidateFormSet (\r
- FORM_BROWSER_FORMSET *FormSet\r
+ValidateHiiHandle (\r
+ EFI_HII_HANDLE HiiHandle\r
)\r
{\r
EFI_HII_HANDLE *HiiHandles;\r
UINTN Index;\r
BOOLEAN Find;\r
\r
- ASSERT (FormSet != NULL);\r
+ if (HiiHandle == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
Find = FALSE;\r
- //\r
- // Get all the Hii handles\r
- //\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
- if (HiiHandles[Index] == FormSet->HiiHandle) {\r
+ if (HiiHandles[Index] == HiiHandle) {\r
Find = TRUE;\r
break;\r
}\r
}\r
\r
+ FreePool (HiiHandles);\r
+\r
+ return Find;\r
+}\r
+\r
+/**\r
+ Validate the FormSet. If the formset is not validate, remove it from the list.\r
+\r
+ @param FormSet The input FormSet which need to validate.\r
+\r
+ @retval TRUE The handle is validate.\r
+ @retval FALSE The handle is invalidate.\r
+\r
+**/\r
+BOOLEAN\r
+ValidateFormSet (\r
+ FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ BOOLEAN Find;\r
+\r
+ ASSERT (FormSet != NULL);\r
+\r
+ Find = ValidateHiiHandle(FormSet->HiiHandle);\r
if (!Find) {\r
CleanBrowserStorage(FormSet);\r
RemoveEntryList (&FormSet->Link);\r
DestroyFormSet (FormSet);\r
}\r
\r
- FreePool (HiiHandles);\r
-\r
return Find;\r
}\r
/**\r