]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Check the validation when return from callback function to avoid use the invalid...
authorEric Dong <eric.dong@intel.com>
Mon, 14 Jul 2014 06:14:20 +0000 (06:14 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 14 Jul 2014 06:14:20 +0000 (06:14 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
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@15654 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.h

index 99a30bcfbfd2ee49692c4ef953dd790f018c3b8c..42af5f710326fa082300e3c6794df1d2a7a4c240 100644 (file)
@@ -817,6 +817,13 @@ UpdateStatementStatusForForm (
     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
@@ -1228,15 +1235,7 @@ FindParentFormSet (
   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
@@ -1812,7 +1811,7 @@ IsNvUpdateRequiredForForm (
 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
@@ -1820,31 +1819,16 @@ FindNextMenu (
   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
@@ -2001,6 +1985,17 @@ ProcessCallBackFunction (
                              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
@@ -2134,6 +2129,15 @@ ProcessCallBackFunction (
     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
@@ -2277,6 +2281,8 @@ SetupBrowser (
   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
@@ -2348,7 +2354,7 @@ SetupBrowser (
         }\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
@@ -2406,6 +2412,15 @@ SetupBrowser (
           ((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
@@ -2433,6 +2448,14 @@ SetupBrowser (
 \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
index 5c5fe6f215967a2bbdaf8a4f9c00f80b2c431efa..92474cd282da8992c5c71f6048af0d3a1198c952 100644 (file)
@@ -206,19 +206,56 @@ UiFindMenuList (
   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
@@ -481,6 +518,14 @@ SendForm (
       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
@@ -2356,40 +2401,60 @@ SendDiscardInfoToDriver (
 \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
index 34b6d944d01f1e3d4631e346441ab0884dd5717c..5ef021218445042c80b7fcbdc29ce0c5e0b40fe9 100644 (file)
@@ -1530,12 +1530,31 @@ UiFreeMenuList (
   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
+/**\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
+ValidateHiiHandle (\r
+  EFI_HII_HANDLE          HiiHandle\r
   );\r
 \r
 /**\r