]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
Refine soma code to make code run safely.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Ui.c
index 62c40e3606e9c1c8066f3e3e330b9853e0844be0..d916aeb8cffa6e7e083a41a151155d31437b8d06 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
 Utility functions for User Interface functions.\r
 \r
-Copyright (c) 2004 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -12,10 +12,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include "Ui.h"\r
 #include "Setup.h"\r
 \r
-LIST_ENTRY          Menu;\r
+LIST_ENTRY          gMenuOption;\r
 LIST_ENTRY          gMenuList = INITIALIZE_LIST_HEAD_VARIABLE (gMenuList);\r
 MENU_REFRESH_ENTRY  *gMenuRefreshHead;\r
 \r
@@ -145,7 +144,7 @@ UiInitMenu (
   VOID\r
   )\r
 {\r
-  InitializeListHead (&Menu);\r
+  InitializeListHead (&gMenuOption);\r
 }\r
 \r
 \r
@@ -160,8 +159,8 @@ UiFreeMenu (
 {\r
   UI_MENU_OPTION  *MenuOption;\r
 \r
-  while (!IsListEmpty (&Menu)) {\r
-    MenuOption = MENU_OPTION_FROM_LINK (Menu.ForwardLink);\r
+  while (!IsListEmpty (&gMenuOption)) {\r
+    MenuOption = MENU_OPTION_FROM_LINK (gMenuOption.ForwardLink);\r
     RemoveEntryList (&MenuOption->Link);\r
 \r
     //\r
@@ -645,7 +644,7 @@ UiAddMenuOption (
       MenuOption->ReadOnly = TRUE;\r
     }\r
 \r
-    InsertTailList (&Menu, &MenuOption->Link);\r
+    InsertTailList (&gMenuOption, &MenuOption->Link);\r
   }\r
 \r
   return MenuOption;\r
@@ -679,6 +678,7 @@ UiAddMenuOption (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CreateDialog (\r
   IN  UINTN                       NumberOfLines,\r
   IN  BOOLEAN                     HotKey,\r
@@ -979,6 +979,7 @@ CreateSharedPopUp (
 \r
 **/\r
 VOID\r
+EFIAPI\r
 CreateMultiStringPopUp (\r
   IN  UINTN                       RequestedWidth,\r
   IN  UINTN                       NumberOfLines,\r
@@ -1038,7 +1039,7 @@ UpdateStatusBar (
     break;\r
 \r
   case NV_UPDATE_REQUIRED:\r
-    if (gClassOfVfr != FORMSET_CLASS_FRONT_PAGE) {\r
+    if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
       if (State) {\r
         gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);\r
         PrintStringAt (\r
@@ -1353,11 +1354,11 @@ ValueIsScroll (
 \r
   Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;\r
 \r
-  if (Temp == &Menu) {\r
+  if (Temp == &gMenuOption) {\r
     return TRUE;\r
   }\r
 \r
-  for (; Temp != &Menu; Temp = Direction ? Temp->BackLink : Temp->ForwardLink) {\r
+  for (; Temp != &gMenuOption; Temp = Direction ? Temp->BackLink : Temp->ForwardLink) {\r
     MenuOption = MENU_OPTION_FROM_LINK (Temp);\r
     if (IsSelectable (MenuOption)) {\r
       return FALSE;\r
@@ -1399,7 +1400,7 @@ MoveToNextStatement (
     if (IsSelectable (NextMenuOption)) {\r
       break;\r
     }\r
-    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &Menu) {\r
+    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {\r
       HitEnd = TRUE;\r
       break;\r
     }\r
@@ -1420,7 +1421,7 @@ MoveToNextStatement (
       if (IsSelectable (NextMenuOption)) {\r
         break;\r
       }\r
-      if ((!GoUp ? Pos->BackLink : Pos->ForwardLink) == &Menu) {\r
+      if ((!GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {\r
         ASSERT (FALSE);\r
         break;\r
       }\r
@@ -1643,6 +1644,8 @@ UiDisplayMenu (
   BOOLEAN                         NewLine;\r
   BOOLEAN                         Repaint;\r
   BOOLEAN                         SavedValue;\r
+  BOOLEAN                         UpArrow;\r
+  BOOLEAN                         DownArrow;\r
   EFI_STATUS                      Status;\r
   EFI_INPUT_KEY                   Key;\r
   LIST_ENTRY                      *Link;\r
@@ -1667,6 +1670,7 @@ UiDisplayMenu (
   UINT8                           DigitUint8;\r
   UI_MENU_LIST                    *CurrentMenu;\r
   UI_MENU_LIST                    *MenuList;\r
+  FORM_BROWSER_FORM               *RefForm;\r
 \r
   CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
 \r
@@ -1679,8 +1683,8 @@ UiDisplayMenu (
   DefaultId           = 0;\r
 \r
   OutputString        = NULL;\r
-  gUpArrow            = FALSE;\r
-  gDownArrow          = FALSE;\r
+  UpArrow             = FALSE;\r
+  DownArrow           = FALSE;\r
   SkipValue           = 0;\r
   OldSkipValue        = 0;\r
   MenuRefreshEntry    = gMenuRefreshHead;\r
@@ -1688,10 +1692,11 @@ UiDisplayMenu (
   NextMenuOption      = NULL;\r
   PreviousMenuOption  = NULL;\r
   SavedMenuOption     = NULL;\r
+  RefForm             = NULL;\r
 \r
   ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
 \r
-  if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE){\r
     TopRow  = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;\r
     Row     = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;\r
   } else {\r
@@ -1708,7 +1713,7 @@ UiDisplayMenu (
   Selection->OptionCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;\r
   Selection->Statement = NULL;\r
 \r
-  TopOfScreen = Menu.ForwardLink;\r
+  TopOfScreen = gMenuOption.ForwardLink;\r
   Repaint     = TRUE;\r
   MenuOption  = NULL;\r
 \r
@@ -1734,7 +1739,7 @@ UiDisplayMenu (
   //\r
   // Get user's selection\r
   //\r
-  NewPos = Menu.ForwardLink;\r
+  NewPos = gMenuOption.ForwardLink;\r
 \r
   gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
   UpdateStatusBar (REFRESH_STATUS_BAR, (UINT8) 0, TRUE);\r
@@ -1744,7 +1749,7 @@ UiDisplayMenu (
   while (TRUE) {\r
     switch (ControlFlag) {\r
     case CfInitialization:\r
-      if (IsListEmpty (&Menu)) {\r
+      if (IsListEmpty (&gMenuOption)) {\r
         ControlFlag = CfReadKey;\r
       } else {\r
         ControlFlag = CfCheckSelection;\r
@@ -1766,8 +1771,8 @@ UiDisplayMenu (
         //\r
         // Display menu\r
         //\r
-        gDownArrow      = FALSE;\r
-        gUpArrow        = FALSE;\r
+        DownArrow       = FALSE;\r
+        UpArrow         = FALSE;\r
         Row             = TopRow;\r
 \r
         Temp            = SkipValue;\r
@@ -1784,7 +1789,7 @@ UiDisplayMenu (
         UiFreeRefreshList ();\r
         MinRefreshInterval = 0;\r
 \r
-        for (Link = TopOfScreen; Link != &Menu; Link = Link->ForwardLink) {\r
+        for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {\r
           MenuOption          = MENU_OPTION_FROM_LINK (Link);\r
           MenuOption->Row     = Row;\r
           MenuOption->Col     = Col;\r
@@ -1989,7 +1994,7 @@ UiDisplayMenu (
 \r
           if (Row > BottomRow) {\r
             if (!ValueIsScroll (FALSE, Link)) {\r
-              gDownArrow = TRUE;\r
+              DownArrow = TRUE;\r
             }\r
 \r
             Row = BottomRow + 1;\r
@@ -1998,10 +2003,10 @@ UiDisplayMenu (
         }\r
 \r
         if (!ValueIsScroll (TRUE, TopOfScreen)) {\r
-          gUpArrow = TRUE;\r
+          UpArrow = TRUE;\r
         }\r
 \r
-        if (gUpArrow) {\r
+        if (UpArrow) {\r
           gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);\r
           PrintAt (\r
             LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,\r
@@ -2012,7 +2017,7 @@ UiDisplayMenu (
           gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);\r
         }\r
 \r
-        if (gDownArrow) {\r
+        if (DownArrow) {\r
           gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);\r
           PrintAt (\r
             LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,\r
@@ -2043,10 +2048,10 @@ UiDisplayMenu (
       Repaint     = FALSE;\r
 \r
       if (Selection->QuestionId != 0) {\r
-        NewPos = Menu.ForwardLink;\r
+        NewPos = gMenuOption.ForwardLink;\r
         SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
 \r
-        while (SavedMenuOption->ThisTag->QuestionId != Selection->QuestionId && NewPos->ForwardLink != &Menu) {\r
+        while (SavedMenuOption->ThisTag->QuestionId != Selection->QuestionId && NewPos->ForwardLink != &gMenuOption) {\r
           NewPos     = NewPos->ForwardLink;\r
           SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
         }\r
@@ -2291,6 +2296,7 @@ UiDisplayMenu (
         //\r
         // Don't print anything if it is a NULL help token\r
         //\r
+        ASSERT(MenuOption != NULL);\r
         if (MenuOption->ThisTag->Help == 0) {\r
           StringPtr = L"\0";\r
         } else {\r
@@ -2367,6 +2373,16 @@ UiDisplayMenu (
       //\r
       case '+':\r
       case '-':\r
+        //\r
+        // If the screen has no menu items, and the user didn't select UiReset\r
+        // ignore the selection and go back to reading keys.\r
+        //\r
+        if(IsListEmpty (&gMenuOption)) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+\r
+        ASSERT(MenuOption != NULL);\r
         Statement = MenuOption->ThisTag;\r
         if ((Statement->Operand == EFI_IFR_DATE_OP)\r
           || (Statement->Operand == EFI_IFR_TIME_OP)\r
@@ -2401,7 +2417,17 @@ UiDisplayMenu (
         break;\r
 \r
       case ' ':\r
-        if (gClassOfVfr != FORMSET_CLASS_FRONT_PAGE) {\r
+        if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
+          //\r
+          // If the screen has no menu items, and the user didn't select UiReset\r
+          // ignore the selection and go back to reading keys.\r
+          //\r
+          if(IsListEmpty (&gMenuOption)) {\r
+            ControlFlag = CfReadKey;\r
+            break;\r
+          }\r
+          \r
+          ASSERT(MenuOption != NULL);\r
           if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut) {\r
             ScreenOperation = UiSelect;\r
           }\r
@@ -2439,21 +2465,21 @@ UiDisplayMenu (
         // If the screen has no menu items, and the user didn't select UiReset\r
         // ignore the selection and go back to reading keys.\r
         //\r
-        if (IsListEmpty (&Menu)) {\r
+        if (IsListEmpty (&gMenuOption)) {\r
           ControlFlag = CfReadKey;\r
           break;\r
         }\r
         //\r
         // if there is nothing logical to place a cursor on, just move on to wait for a key.\r
         //\r
-        for (Link = Menu.ForwardLink; Link != &Menu; Link = Link->ForwardLink) {\r
+        for (Link = gMenuOption.ForwardLink; Link != &gMenuOption; Link = Link->ForwardLink) {\r
           NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
           if (IsSelectable (NextMenuOption)) {\r
             break;\r
           }\r
         }\r
 \r
-        if (Link == &Menu) {\r
+        if (Link == &gMenuOption) {\r
           ControlFlag = CfPrepareToReadKey;\r
           break;\r
         }\r
@@ -2473,6 +2499,7 @@ UiDisplayMenu (
     case CfUiSelect:\r
       ControlFlag = CfCheckSelection;\r
 \r
+      ASSERT(MenuOption != NULL);\r
       Statement = MenuOption->ThisTag;\r
       if ((Statement->Operand == EFI_IFR_TEXT_OP) ||\r
           (Statement->Operand == EFI_IFR_DATE_OP) ||\r
@@ -2492,7 +2519,6 @@ UiDisplayMenu (
           //\r
           // Goto another Hii Package list\r
           //\r
-          ControlFlag = CfCheckSelection;\r
           Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
 \r
           StringPtr = GetToken (Statement->RefDevicePath, Selection->FormSet->HiiHandle);\r
@@ -2547,13 +2573,36 @@ UiDisplayMenu (
           //\r
           // Goto another Formset, check for uncommitted data\r
           //\r
-          ControlFlag = CfCheckSelection;\r
           Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
 \r
           CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));\r
           Selection->FormId = Statement->RefFormId;\r
           Selection->QuestionId = Statement->RefQuestionId;\r
         } else if (Statement->RefFormId != 0) {\r
+          //\r
+          // Check whether target From is suppressed.\r
+          //\r
+          RefForm = IdToForm (Selection->FormSet, Statement->RefFormId);\r
+\r
+          if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
+            Status = EvaluateExpression (Selection->FormSet, RefForm, RefForm->SuppressExpression);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
+\r
+            if (RefForm->SuppressExpression->Result.Value.b) {\r
+              //\r
+              // Form is suppressed. \r
+              //\r
+              do {\r
+                CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);\r
+              } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+              Repaint = TRUE;\r
+              break;\r
+            }\r
+          }\r
+\r
           //\r
           // Goto another form inside this formset,\r
           //\r
@@ -2624,9 +2673,9 @@ UiDisplayMenu (
           Selection->Action = UI_ACTION_REFRESH_FORM;\r
         }\r
 \r
-          if (OptionString != NULL) {\r
-            FreePool (OptionString);\r
-          }\r
+        if (OptionString != NULL) {\r
+          FreePool (OptionString);\r
+        }\r
         break;\r
       }\r
       break;\r
@@ -2661,7 +2710,7 @@ UiDisplayMenu (
         break;\r
       }\r
 \r
-      if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
+      if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
         //\r
         // We never exit FrontPage, so skip the ESC\r
         //\r
@@ -2717,11 +2766,13 @@ UiDisplayMenu (
 \r
     case CfUiLeft:\r
       ControlFlag = CfCheckSelection;\r
+      ASSERT(MenuOption != NULL);\r
       if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {\r
         if (MenuOption->Sequence != 0) {\r
           //\r
           // In the middle or tail of the Date/Time op-code set, go left.\r
           //\r
+          ASSERT(NewPos != NULL);\r
           NewPos = NewPos->BackLink;\r
         }\r
       }\r
@@ -2729,11 +2780,13 @@ UiDisplayMenu (
 \r
     case CfUiRight:\r
       ControlFlag = CfCheckSelection;\r
+      ASSERT(MenuOption != NULL);\r
       if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {\r
         if (MenuOption->Sequence != 2) {\r
           //\r
           // In the middle or tail of the Date/Time op-code set, go left.\r
           //\r
+          ASSERT(NewPos != NULL);\r
           NewPos = NewPos->ForwardLink;\r
         }\r
       }\r
@@ -2744,7 +2797,8 @@ UiDisplayMenu (
 \r
       SavedListEntry = TopOfScreen;\r
 \r
-      if (NewPos->BackLink != &Menu) {\r
+      ASSERT(NewPos != NULL);\r
+      if (NewPos->BackLink != &gMenuOption) {\r
         NewLine = TRUE;\r
         //\r
         // Adjust Date/Time position before we advance forward.\r
@@ -2754,7 +2808,7 @@ UiDisplayMenu (
         //\r
         // Caution that we have already rewind to the top, don't go backward in this situation.\r
         //\r
-        if (NewPos->BackLink != &Menu) {\r
+        if (NewPos->BackLink != &gMenuOption) {\r
           NewPos = NewPos->BackLink;\r
         }\r
 \r
@@ -2773,6 +2827,7 @@ UiDisplayMenu (
         // Check the previous menu entry to see if it was a zero-length advance.  If it was,\r
         // don't worry about a redraw.\r
         //\r
+        ASSERT(MenuOption != NULL);\r
         if ((INTN) MenuOption->Row - (INTN) DistanceValue < (INTN) TopRow) {\r
           Repaint     = TRUE;\r
           TopOfScreen = NewPos;\r
@@ -2799,8 +2854,8 @@ UiDisplayMenu (
           // it means that we hit the begining MenuOption that can be focused\r
           // so we simply scroll to the top\r
           //\r
-          if (SavedListEntry != Menu.ForwardLink) {\r
-            TopOfScreen = Menu.ForwardLink;\r
+          if (SavedListEntry != gMenuOption.ForwardLink) {\r
+            TopOfScreen = gMenuOption.ForwardLink;\r
             Repaint     = TRUE;\r
           }\r
         }\r
@@ -2830,7 +2885,8 @@ UiDisplayMenu (
     case CfUiPageUp:\r
       ControlFlag     = CfCheckSelection;\r
 \r
-      if (NewPos->BackLink == &Menu) {\r
+      ASSERT(NewPos != NULL);\r
+      if (NewPos->BackLink == &gMenuOption) {\r
         NewLine = FALSE;\r
         Repaint = FALSE;\r
         break;\r
@@ -2841,7 +2897,7 @@ UiDisplayMenu (
       Link      = TopOfScreen;\r
       PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
       Index = BottomRow;\r
-      while ((Index >= TopRow) && (Link->BackLink != &Menu)) {\r
+      while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {\r
         Index = Index - PreviousMenuOption->Skip;\r
         Link = Link->BackLink;\r
         PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
@@ -2859,7 +2915,7 @@ UiDisplayMenu (
         // This happens when there is no MenuOption can be focused from\r
         // Current MenuOption to the first MenuOption\r
         //\r
-        TopOfScreen = Menu.ForwardLink;\r
+        TopOfScreen = gMenuOption.ForwardLink;\r
       }\r
       Index += Difference;\r
       if (Index < TopRow) {\r
@@ -2884,7 +2940,7 @@ UiDisplayMenu (
     case CfUiPageDown:\r
       ControlFlag     = CfCheckSelection;\r
 \r
-      if (NewPos->ForwardLink == &Menu) {\r
+      if (NewPos->ForwardLink == &gMenuOption) {\r
         NewLine = FALSE;\r
         Repaint = FALSE;\r
         break;\r
@@ -2895,7 +2951,7 @@ UiDisplayMenu (
       Link    = TopOfScreen;\r
       NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
       Index = TopRow;\r
-      while ((Index <= BottomRow) && (Link->ForwardLink != &Menu)) {\r
+      while ((Index <= BottomRow) && (Link->ForwardLink != &gMenuOption)) {\r
         Index = Index + NextMenuOption->Skip;\r
         Link           = Link->ForwardLink;\r
         NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
@@ -2940,7 +2996,7 @@ UiDisplayMenu (
       SavedListEntry = NewPos;\r
       DistanceValue  = AdjustDateAndTimePosition (FALSE, &NewPos);\r
 \r
-      if (NewPos->ForwardLink != &Menu) {\r
+      if (NewPos->ForwardLink != &gMenuOption) {\r
         MenuOption      = MENU_OPTION_FROM_LINK (NewPos);\r
         NewLine         = TRUE;\r
         NewPos          = NewPos->ForwardLink;\r
@@ -3088,6 +3144,7 @@ UiDisplayMenu (
       Status = SubmitForm (Selection->FormSet, Selection->Form);\r
 \r
       if (!EFI_ERROR (Status)) {\r
+        ASSERT(MenuOption != NULL);\r
         UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
         UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE);\r
       } else {\r