]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Add PI complied S3 implementation. Include the Opcode definition and EFI_BOOT_SCRIPT_...
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
index 02f555625566c53dae7e0c48de833e494a86348a..c0b2de7f05e7da3aa6cfd48ec18f4b88b020ec36 100644 (file)
@@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "Setup.h"\r
-#include "Ui.h"\r
 \r
 UINT16           mStatementIndex;\r
 UINT16           mExpressionOpCodeIndex;\r
@@ -21,8 +20,10 @@ UINT16           mExpressionOpCodeIndex;
 BOOLEAN          mInScopeSubtitle;\r
 BOOLEAN          mInScopeSuppress;\r
 BOOLEAN          mInScopeGrayOut;\r
+BOOLEAN          mInScopeDisable;\r
 FORM_EXPRESSION  *mSuppressExpression;\r
 FORM_EXPRESSION  *mGrayOutExpression;\r
+FORM_EXPRESSION  *mDisableExpression;\r
 \r
 /**\r
   Initialize Statement header members.\r
@@ -75,6 +76,11 @@ CreateStatement (
     Statement->GrayOutExpression = mGrayOutExpression;\r
   }\r
 \r
+\r
+  if (mInScopeDisable) {\r
+    Statement->DisableExpression = mDisableExpression;\r
+  }\r
+\r
   Statement->InSubtitle = mInScopeSubtitle;\r
 \r
   //\r
@@ -89,15 +95,15 @@ CreateStatement (
   Convert a numeric value to a Unicode String and insert it to String Package.\r
   This string is used as the Unicode Name for the EFI Variable. This is to support\r
   the deprecated vareqval opcode.\r
-  \r
+\r
   @param FormSet        The FormSet.\r
   @param Statement      The numeric question whose VarStoreInfo.VarName is the\r
                         numeric value which is used to produce the Unicode Name\r
                         for the EFI Variable.\r
-                        \r
+\r
   If the Statement is NULL, the ASSERT.\r
   If the opcode is not Numeric, then ASSERT.\r
-  \r
+\r
   @retval EFI_SUCCESS The funtion always succeeds.\r
 **/\r
 EFI_STATUS\r
@@ -111,7 +117,7 @@ UpdateCheckBoxStringToken (
 \r
   ASSERT (Statement != NULL);\r
   ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);\r
-  \r
+\r
   UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
 \r
   Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);\r
@@ -120,21 +126,21 @@ UpdateCheckBoxStringToken (
   }\r
 \r
   Statement->VarStoreInfo.VarName = Id;\r
-    \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.\r
-  \r
+\r
   @param OpCodeData     The current opcode.\r
-                        \r
+\r
   @retval TRUE Yes.\r
   @retval FALSE No.\r
 **/\r
 BOOLEAN\r
 IsNextOpCodeGuidedVarEqName (\r
-  UINT8 *OpCodeData\r
+  IN UINT8 *OpCodeData\r
   )\r
 {\r
   //\r
@@ -144,7 +150,7 @@ IsNextOpCodeGuidedVarEqName (
   if (*OpCodeData == EFI_IFR_GUID_OP) {\r
     if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
       //\r
-      // Specific GUIDed opcodes to support IFR generated from Framework HII VFR \r
+      // Specific GUIDed opcodes to support IFR generated from Framework HII VFR\r
       //\r
       if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {\r
         return TRUE;\r
@@ -322,19 +328,19 @@ InitializeConfigHdr (
   )\r
 {\r
   CHAR16      *Name;\r
-  \r
+\r
   if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
     Name = Storage->Name;\r
   } else {\r
     Name = NULL;\r
   }\r
-  \r
+\r
   Storage->ConfigHdr = HiiConstructConfigHdr (\r
                          &Storage->Guid,\r
                          Name,\r
                          FormSet->DriverHandle\r
                          );\r
-  \r
+\r
   if (Storage->ConfigHdr == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -645,8 +651,17 @@ DestroyFormSet (
   LIST_ENTRY            *Link;\r
   FORMSET_STORAGE       *Storage;\r
   FORMSET_DEFAULTSTORE  *DefaultStore;\r
+  FORM_EXPRESSION       *Expression;\r
   FORM_BROWSER_FORM     *Form;\r
 \r
+  if (FormSet->IfrBinaryData == NULL) {\r
+    //\r
+    // Uninitialized FormSet\r
+    //\r
+    FreePool (FormSet);\r
+    return;\r
+  }\r
+\r
   //\r
   // Free IFR binary buffer\r
   //\r
@@ -678,6 +693,17 @@ DestroyFormSet (
     }\r
   }\r
 \r
+  //\r
+  // Free Formset Expressions\r
+  //\r
+  while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
+    Link = GetFirstNode (&FormSet->ExpressionListHead);\r
+    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+    RemoveEntryList (&Expression->Link);\r
+\r
+    DestroyExpression (Expression);\r
+  }\r
+\r
   //\r
   // Free Forms\r
   //\r
@@ -803,14 +829,17 @@ ParseOpCodes (
   FORMSET_DEFAULTSTORE    *DefaultStore;\r
   QUESTION_DEFAULT        *CurrentDefault;\r
   QUESTION_OPTION         *CurrentOption;\r
+  UINT8                   Width;\r
   CHAR8                   *AsciiString;\r
   UINT16                  NumberOfStatement;\r
   UINT16                  NumberOfExpression;\r
   EFI_IMAGE_ID            *ImageId;\r
+  BOOLEAN                 SuppressForQuestion;\r
   BOOLEAN                 SuppressForOption;\r
   BOOLEAN                 InScopeOptionSuppress;\r
   FORM_EXPRESSION         *OptionSuppressExpression;\r
-  BOOLEAN                 InScopeDisable;\r
+  BOOLEAN                 InScopeFormSuppress;\r
+  FORM_EXPRESSION         *FormSuppressExpression;\r
   UINT16                  DepthOfDisable;\r
   BOOLEAN                 OpCodeDisabled;\r
   BOOLEAN                 SingleOpCodeExpression;\r
@@ -818,11 +847,13 @@ ParseOpCodes (
   EFI_HII_VALUE           *Value;\r
 \r
   mInScopeSubtitle         = FALSE;\r
+  SuppressForQuestion      = FALSE;\r
   SuppressForOption        = FALSE;\r
+  InScopeFormSuppress      = FALSE;\r
   mInScopeSuppress         = FALSE;\r
   InScopeOptionSuppress    = FALSE;\r
   mInScopeGrayOut          = FALSE;\r
-  InScopeDisable           = FALSE;\r
+  mInScopeDisable          = FALSE;\r
   DepthOfDisable           = 0;\r
   OpCodeDisabled           = FALSE;\r
   SingleOpCodeExpression   = FALSE;\r
@@ -831,6 +862,7 @@ ParseOpCodes (
   CurrentDefault           = NULL;\r
   CurrentOption            = NULL;\r
   OptionSuppressExpression = NULL;\r
+  FormSuppressExpression   = NULL;\r
   ImageId                  = NULL;\r
 \r
   //\r
@@ -890,7 +922,7 @@ ParseOpCodes (
 \r
         if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
           if (DepthOfDisable == 0) {\r
-            InScopeDisable = FALSE;\r
+            mInScopeDisable = FALSE;\r
             OpCodeDisabled = FALSE;\r
           } else {\r
             DepthOfDisable--;\r
@@ -922,9 +954,9 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_EQ_ID_LIST_OP:\r
-        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
-        CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
-        ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ValueList);\r
+        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+        CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
+        ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
         break;\r
 \r
       case EFI_IFR_TO_STRING_OP:\r
@@ -951,7 +983,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_QUESTION_REF1_OP:\r
-        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
+        CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
         break;\r
 \r
       case EFI_IFR_QUESTION_REF3_OP:\r
@@ -1013,7 +1045,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_UNDEFINED_OP:\r
-        Value->Type = EFI_IFR_TYPE_OTHER;\r
+        Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
         break;\r
 \r
       case EFI_IFR_VERSION_OP:\r
@@ -1025,6 +1057,7 @@ ParseOpCodes (
         break;\r
       }\r
 \r
+      ASSERT (CurrentExpression != NULL);\r
       InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
 \r
       if (SingleOpCodeExpression) {\r
@@ -1035,16 +1068,15 @@ ParseOpCodes (
         //\r
         SingleOpCodeExpression = FALSE;\r
 \r
-        if (InScopeDisable) {\r
+        if (mInScopeDisable && CurrentForm == NULL) {\r
           //\r
-          // Evaluate DisableIf expression\r
+          // This is DisableIf expression for Form, it should be a constant expression\r
           //\r
           Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
           if (EFI_ERROR (Status)) {\r
             return Status;\r
           }\r
 \r
-          ASSERT (CurrentExpression != NULL);\r
           if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
             return EFI_INVALID_PARAMETER;\r
           }\r
@@ -1065,7 +1097,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_FORM_SET_OP:\r
       //\r
-      // check the formset GUID\r
+      // Check the formset GUID\r
       //\r
       if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
         return EFI_INVALID_PARAMETER;\r
@@ -1073,6 +1105,14 @@ ParseOpCodes (
 \r
       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));\r
+\r
+      //\r
+      // The formset OpCode contains ClassGuid\r
+      //\r
+      FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
+      CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
+\r
+      InitializeListHead (&FormSet->ExpressionListHead);\r
       break;\r
 \r
     case EFI_IFR_FORM_OP:\r
@@ -1088,6 +1128,20 @@ ParseOpCodes (
       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
 \r
+      if (InScopeFormSuppress) {\r
+        //\r
+        // Form is inside of suppressif\r
+        //\r
+        CurrentForm->SuppressExpression = FormSuppressExpression;\r
+      }\r
+\r
+      if (Scope != 0) {\r
+        //\r
+        // Enter scope of a Form, suppressif will be used for Question or Option\r
+        //\r
+        SuppressForQuestion = TRUE;\r
+      }\r
+\r
       //\r
       // Insert into Form list of this FormSet\r
       //\r
@@ -1175,7 +1229,7 @@ ParseOpCodes (
     case EFI_IFR_SUBTITLE_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
-      \r
+\r
       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
 \r
       if (Scope != 0) {\r
@@ -1190,12 +1244,19 @@ ParseOpCodes (
       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
       break;\r
 \r
+    case EFI_IFR_RESET_BUTTON_OP:\r
+      CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
+      CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
+      break;\r
+\r
     //\r
     // Questions\r
     //\r
     case EFI_IFR_ACTION_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
 \r
       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
         //\r
@@ -1207,15 +1268,10 @@ ParseOpCodes (
       }\r
       break;\r
 \r
-    case EFI_IFR_RESET_BUTTON_OP:\r
-      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
-\r
-      CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
-      break;\r
-\r
     case EFI_IFR_REF_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
-\r
+      ASSERT (CurrentStatement != NULL);\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;\r
       CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
       if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
         CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
@@ -1233,6 +1289,7 @@ ParseOpCodes (
     case EFI_IFR_ONE_OF_OP:\r
     case EFI_IFR_NUMERIC_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT(CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
       Value = &CurrentStatement->HiiValue;\r
@@ -1283,19 +1340,12 @@ ParseOpCodes (
 \r
     case EFI_IFR_ORDERED_LIST_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT(CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
-      CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));\r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
 \r
-      //\r
-      // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver\r
-      // has to use FormBrowser2.Callback() to retrieve the uncommited data for\r
-      // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).\r
-      //\r
-      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;\r
-      CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
+      CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
 \r
       if (Scope != 0) {\r
         SuppressForOption = TRUE;\r
@@ -1304,6 +1354,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_CHECKBOX_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT(CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
       CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
@@ -1315,7 +1366,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_STRING_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
-\r
+      ASSERT (CurrentStatement != NULL);\r
       //\r
       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
       // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
@@ -1334,7 +1385,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_PASSWORD_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
-\r
+      ASSERT (CurrentStatement != NULL);\r
       //\r
       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
       // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
@@ -1352,6 +1403,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_DATE_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT(CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
@@ -1371,6 +1423,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_TIME_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT(CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
@@ -1442,6 +1495,42 @@ ParseOpCodes (
       // Insert to Option list of current Question\r
       //\r
       InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
+\r
+      //\r
+      // Now we know the Storage width of nested Ordered List\r
+      //\r
+      if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
+        Width = 1;\r
+        switch (CurrentOption->Value.Type) {\r
+        case EFI_IFR_TYPE_NUM_SIZE_8:\r
+          Width = 1;\r
+          break;\r
+\r
+        case EFI_IFR_TYPE_NUM_SIZE_16:\r
+          Width = 2;\r
+          break;\r
+\r
+        case EFI_IFR_TYPE_NUM_SIZE_32:\r
+          Width = 4;\r
+          break;\r
+\r
+        case EFI_IFR_TYPE_NUM_SIZE_64:\r
+          Width = 8;\r
+          break;\r
+\r
+        default:\r
+          //\r
+          // Invalid type for Ordered List\r
+          //\r
+          break;\r
+        }\r
+\r
+        CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
+        CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
+        CurrentStatement->ValueType = CurrentOption->Value.Type;\r
+\r
+        InitializeRequestElement (FormSet, CurrentStatement);\r
+      }\r
       break;\r
 \r
     //\r
@@ -1462,6 +1551,14 @@ ParseOpCodes (
         CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
         InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
       }\r
+\r
+      //\r
+      // Take a look at next OpCode to see whether current expression consists\r
+      // of single OpCode\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+        SingleOpCodeExpression = TRUE;\r
+      }\r
       break;\r
 \r
     case EFI_IFR_SUPPRESS_IF_OP:\r
@@ -1470,14 +1567,30 @@ ParseOpCodes (
       //\r
       CurrentExpression = CreateExpression (CurrentForm);\r
       CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
-      InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+\r
+      if (CurrentForm == NULL) {\r
+        InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
+      } else {\r
+        InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+      }\r
 \r
       if (SuppressForOption) {\r
         InScopeOptionSuppress = TRUE;\r
         OptionSuppressExpression = CurrentExpression;\r
-      } else {\r
+      } else if (SuppressForQuestion) {\r
         mInScopeSuppress = TRUE;\r
         mSuppressExpression = CurrentExpression;\r
+      } else {\r
+        InScopeFormSuppress = TRUE;\r
+        FormSuppressExpression = CurrentExpression;\r
+      }\r
+\r
+      //\r
+      // Take a look at next OpCode to see whether current expression consists\r
+      // of single OpCode\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+        SingleOpCodeExpression = TRUE;\r
       }\r
       break;\r
 \r
@@ -1491,6 +1604,14 @@ ParseOpCodes (
 \r
       mInScopeGrayOut = TRUE;\r
       mGrayOutExpression = CurrentExpression;\r
+\r
+      //\r
+      // Take a look at next OpCode to see whether current expression consists\r
+      // of single OpCode\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+        SingleOpCodeExpression = TRUE;\r
+      }\r
       break;\r
 \r
     case EFI_IFR_DISABLE_IF_OP:\r
@@ -1504,8 +1625,16 @@ ParseOpCodes (
       CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
       InitializeListHead (&CurrentExpression->OpCodeListHead);\r
 \r
-      InScopeDisable = TRUE;\r
-      OpCodeDisabled = FALSE;\r
+      if (CurrentForm != NULL) {\r
+        //\r
+        // This is DisableIf for Question, enqueue it to Form expression list\r
+        //\r
+        InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+      }\r
+\r
+      mDisableExpression = CurrentExpression;\r
+      mInScopeDisable    = TRUE;\r
+      OpCodeDisabled     = FALSE;\r
 \r
       //\r
       // Take a look at next OpCode to see whether current expression consists\r
@@ -1541,6 +1670,14 @@ ParseOpCodes (
         ASSERT (CurrentStatement != NULL);\r
         CurrentStatement->ValueExpression = CurrentExpression;\r
       }\r
+\r
+      //\r
+      // Take a look at next OpCode to see whether current expression consists\r
+      // of single OpCode\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+        SingleOpCodeExpression = TRUE;\r
+      }\r
       break;\r
 \r
     case EFI_IFR_RULE_OP:\r
@@ -1549,6 +1686,14 @@ ParseOpCodes (
 \r
       CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
+\r
+      //\r
+      // Take a look at next OpCode to see whether current expression consists\r
+      // of single OpCode\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+        SingleOpCodeExpression = TRUE;\r
+      }\r
       break;\r
 \r
     //\r
@@ -1614,9 +1759,12 @@ ParseOpCodes (
           break;\r
 \r
         case EFI_IFR_EXTEND_OP_BANNER:\r
+          //\r
+          // By SubClass to get Banner Data from Front Page\r
+          //\r
           if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
             CopyMem (\r
-              &BannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
+              &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
               ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
               &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
               sizeof (EFI_STRING_ID)\r
@@ -1663,6 +1811,7 @@ ParseOpCodes (
         // End of Form\r
         //\r
         CurrentForm = NULL;\r
+        SuppressForQuestion = FALSE;\r
         break;\r
 \r
       case EFI_IFR_ONE_OF_OPTION_OP:\r
@@ -1686,8 +1835,10 @@ ParseOpCodes (
       case EFI_IFR_SUPPRESS_IF_OP:\r
         if (SuppressForOption) {\r
           InScopeOptionSuppress = FALSE;\r
-        } else {\r
+        } else if (SuppressForQuestion) {\r
           mInScopeSuppress = FALSE;\r
+        } else {\r
+          InScopeFormSuppress = FALSE;\r
         }\r
         break;\r
 \r
@@ -1696,7 +1847,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_DISABLE_IF_OP:\r
-        InScopeDisable = FALSE;\r
+        mInScopeDisable = FALSE;\r
         OpCodeDisabled = FALSE;\r
         break;\r
 \r
@@ -1711,16 +1862,16 @@ ParseOpCodes (
 \r
       default:\r
         if (IsExpressionOpCode (ScopeOpCode)) {\r
-          if (InScopeDisable) {\r
+          if (mInScopeDisable && CurrentForm == NULL) {\r
             //\r
-            // Evaluate DisableIf expression\r
+            // This is DisableIf expression for Form, it should be a constant expression\r
             //\r
+            ASSERT (CurrentExpression != NULL);\r
             Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
             if (EFI_ERROR (Status)) {\r
               return Status;\r
             }\r
 \r
-            ASSERT (CurrentExpression != NULL);\r
             if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
               return EFI_INVALID_PARAMETER;\r
             }\r