]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
Add code check to avoid access violation.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Ui.c
index ebe8fae2cc4391812cc948a29cb2f25f1719dd20..1c3a7f6ba441f54879fd2864b3208231b8b3091e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Utility functions for User Interface functions.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, 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
@@ -731,8 +731,10 @@ UiAddMenuOption (
     }\r
     MenuOption->Sequence = Index;\r
 \r
-    if (Statement->GrayOutExpression != NULL) {\r
-      MenuOption->GrayOut = Statement->GrayOutExpression->Result.Value.b;\r
+    if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut ) {\r
+      MenuOption->GrayOut = TRUE;\r
+    } else {\r
+      MenuOption->GrayOut = FALSE;\r
     }\r
 \r
     //\r
@@ -850,8 +852,6 @@ CreateDialog (
   ASSERT (TempString);\r
   ASSERT (BufferedString);\r
 \r
-  VA_START (Marker, KeyValue);\r
-\r
   //\r
   // Zero the outgoing buffer\r
   //\r
@@ -873,6 +873,8 @@ CreateDialog (
 \r
   LargestString = 0;\r
 \r
+  VA_START (Marker, KeyValue);\r
+\r
   //\r
   // Determine the largest string in the dialog box\r
   // Notice we are starting with 1 since String is the first string\r
@@ -1999,12 +2001,7 @@ ProcessGotoOpCode (
     RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);\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
+      if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\r
         //\r
         // Form is suppressed. \r
         //\r
@@ -2575,7 +2572,18 @@ UiDisplayMenu (
             SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
           }\r
 \r
-          if (Link != NewPos || Index > BottomRow || (Link == NewPos && SavedMenuOption->Row + SavedMenuOption->Skip - 1 > BottomRow)) {\r
+          //\r
+          // Not find the selected menu in current show page.\r
+          // Have two case to enter this if:\r
+          // 1. Not find the menu at current page.\r
+          // 2. Find the menu in current page, but the menu shows at the bottom and not all info shows.\r
+          //    For case 2, has an exception: The menu can show more than one pages and now only this menu shows.\r
+          //\r
+          // Base on the selected menu will show at the bottom of the page,\r
+          // select the menu which will show at the top of the page.\r
+          //\r
+          if (Link != NewPos || Index > BottomRow || \r
+              (Link == NewPos && (SavedMenuOption->Row + SavedMenuOption->Skip - 1 > BottomRow) && (Link != TopOfScreen))) {\r
             //\r
             // Find the MenuOption which has the skip value for Date/Time opcode. \r
             //\r
@@ -2590,7 +2598,11 @@ UiDisplayMenu (
             if (SavedMenuOption->Row == 0) {\r
               UpdateOptionSkipLines (Selection, SavedMenuOption);\r
             }\r
-            \r
+\r
+            //\r
+            // Base on the selected menu will show at the bottome of next page, \r
+            // select the menu show at the top of the next page. \r
+            //\r
             Link    = NewPos;\r
             for (Index = TopRow + SavedMenuOption->Skip; Index <= BottomRow + 1; ) {            \r
               Link = Link->BackLink;\r
@@ -2598,16 +2610,31 @@ UiDisplayMenu (
               if (SavedMenuOption->Row == 0) {\r
                 UpdateOptionSkipLines (Selection, SavedMenuOption);\r
               }\r
-              Index     += SavedMenuOption->Skip;\r
+              Index += SavedMenuOption->Skip;\r
             }\r
-            \r
-            SkipValue = Index - BottomRow - 1;\r
-            if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {\r
-              TopOfScreen     = Link;\r
-              OldSkipValue    = SkipValue;\r
+\r
+            //\r
+            // Found the menu which will show at the top of the page.\r
+            //\r
+            if (Link == NewPos) {\r
+              //\r
+              // The menu can show more than one pages, just show the menu at the top of the page.\r
+              //\r
+              SkipValue    = 0;\r
+              TopOfScreen  = Link;\r
+              OldSkipValue = SkipValue;\r
             } else {\r
-              SkipValue       = 0;\r
-              TopOfScreen     = Link->ForwardLink;\r
+              //\r
+              // Check whether need to skip some line for menu shows at the top of the page.\r
+              //\r
+              SkipValue = Index - BottomRow - 1;\r
+              if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {\r
+                TopOfScreen     = Link;\r
+                OldSkipValue    = SkipValue;\r
+              } else {\r
+                SkipValue       = 0;\r
+                TopOfScreen     = Link->ForwardLink;\r
+              }\r
             }\r
 \r
             Repaint = TRUE;\r
@@ -2876,6 +2903,11 @@ UiDisplayMenu (
 \r
       switch (Key.UnicodeChar) {\r
       case CHAR_CARRIAGE_RETURN:\r
+        if(MenuOption->GrayOut || MenuOption->ReadOnly) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+\r
         ScreenOperation = UiSelect;\r
         gDirection      = 0;\r
         break;\r
@@ -2890,7 +2922,7 @@ 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 (&gMenuOption)) {\r
+        if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {\r
           ControlFlag = CfReadKey;\r
           break;\r
         }\r
@@ -2943,7 +2975,7 @@ UiDisplayMenu (
           }\r
           \r
           ASSERT(MenuOption != NULL);\r
-          if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut) {\r
+          if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {\r
             ScreenOperation = UiSelect;\r
           }\r
         }\r