Home | History | Annotate | Download | only in SetupBrowserDxe
      1 /** @file
      2 Parser for IFR binary encoding.
      3 
      4 Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "Setup.h"
     16 
     17 UINT16           mStatementIndex;
     18 UINT16           mExpressionOpCodeIndex;
     19 EFI_QUESTION_ID  mUsedQuestionId;
     20 extern LIST_ENTRY      gBrowserStorageList;
     21 /**
     22   Initialize Statement header members.
     23 
     24   @param  OpCodeData             Pointer of the raw OpCode data.
     25   @param  FormSet                Pointer of the current FormSet.
     26   @param  Form                   Pointer of the current Form.
     27 
     28   @return The Statement.
     29 
     30 **/
     31 FORM_BROWSER_STATEMENT *
     32 CreateStatement (
     33   IN UINT8                        *OpCodeData,
     34   IN OUT FORM_BROWSER_FORMSET     *FormSet,
     35   IN OUT FORM_BROWSER_FORM        *Form
     36   )
     37 {
     38   FORM_BROWSER_STATEMENT    *Statement;
     39   EFI_IFR_STATEMENT_HEADER  *StatementHdr;
     40   INTN                      ConditionalExprCount;
     41 
     42   if (Form == NULL) {
     43     //
     44     // Only guid op may out side the form level.
     45     //
     46     ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);
     47   }
     48 
     49   Statement = &FormSet->StatementBuffer[mStatementIndex];
     50   mStatementIndex++;
     51 
     52   InitializeListHead (&Statement->DefaultListHead);
     53   InitializeListHead (&Statement->OptionListHead);
     54   InitializeListHead (&Statement->InconsistentListHead);
     55   InitializeListHead (&Statement->NoSubmitListHead);
     56   InitializeListHead (&Statement->WarningListHead);
     57 
     58   Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
     59 
     60   Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
     61   Statement->OpCode  = (EFI_IFR_OP_HEADER *) OpCodeData;
     62 
     63   StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
     64   CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
     65   CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
     66 
     67   ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement);
     68   if (ConditionalExprCount > 0) {
     69     //
     70     // Form is inside of suppressif
     71     //
     72 
     73     Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool(
     74                                              (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
     75     ASSERT (Statement->Expression != NULL);
     76     Statement->Expression->Count     = (UINTN) ConditionalExprCount;
     77     Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
     78     CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
     79   }
     80 
     81   //
     82   // Insert this Statement into current Form
     83   //
     84   if (Form == NULL) {
     85     InsertTailList (&FormSet->StatementListOSF, &Statement->Link);
     86   } else {
     87     InsertTailList (&Form->StatementListHead, &Statement->Link);
     88   }
     89   return Statement;
     90 }
     91 
     92 /**
     93   Convert a numeric value to a Unicode String and insert it to String Package.
     94   This string is used as the Unicode Name for the EFI Variable. This is to support
     95   the deprecated vareqval opcode.
     96 
     97   @param FormSet        The FormSet.
     98   @param Statement      The numeric question whose VarStoreInfo.VarName is the
     99                         numeric value which is used to produce the Unicode Name
    100                         for the EFI Variable.
    101 
    102   If the Statement is NULL, the ASSERT.
    103   If the opcode is not Numeric, then ASSERT.
    104 
    105   @retval EFI_SUCCESS The funtion always succeeds.
    106 **/
    107 EFI_STATUS
    108 UpdateCheckBoxStringToken (
    109   IN CONST FORM_BROWSER_FORMSET *FormSet,
    110   IN       FORM_BROWSER_STATEMENT *Statement
    111   )
    112 {
    113   CHAR16                  Str[MAXIMUM_VALUE_CHARACTERS];
    114   EFI_STRING_ID           Id;
    115 
    116   ASSERT (Statement != NULL);
    117   ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);
    118 
    119   UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);
    120 
    121   Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);
    122   if (Id == 0) {
    123     return EFI_OUT_OF_RESOURCES;
    124   }
    125 
    126   Statement->VarStoreInfo.VarName = Id;
    127 
    128   return EFI_SUCCESS;
    129 }
    130 
    131 /**
    132   Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
    133 
    134   @param OpCodeData     The current opcode.
    135 
    136   @retval TRUE Yes.
    137   @retval FALSE No.
    138 **/
    139 BOOLEAN
    140 IsNextOpCodeGuidedVarEqName (
    141   IN UINT8 *OpCodeData
    142   )
    143 {
    144   //
    145   // Get next opcode
    146   //
    147   OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
    148   if (*OpCodeData == EFI_IFR_GUID_OP) {
    149     if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
    150       //
    151       // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
    152       //
    153       if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {
    154         return TRUE;
    155       }
    156     }
    157   }
    158 
    159   return FALSE;
    160 }
    161 
    162 /**
    163   Initialize Question's members.
    164 
    165   @param  OpCodeData             Pointer of the raw OpCode data.
    166   @param  FormSet                Pointer of the current FormSet.
    167   @param  Form                   Pointer of the current Form.
    168 
    169   @return The Question.
    170 
    171 **/
    172 FORM_BROWSER_STATEMENT *
    173 CreateQuestion (
    174   IN UINT8                        *OpCodeData,
    175   IN OUT FORM_BROWSER_FORMSET     *FormSet,
    176   IN OUT FORM_BROWSER_FORM        *Form
    177   )
    178 {
    179   FORM_BROWSER_STATEMENT   *Statement;
    180   EFI_IFR_QUESTION_HEADER  *QuestionHdr;
    181   LIST_ENTRY               *Link;
    182   FORMSET_STORAGE          *Storage;
    183   NAME_VALUE_NODE          *NameValueNode;
    184   EFI_STATUS               Status;
    185   BOOLEAN                  Find;
    186 
    187   Statement = CreateStatement (OpCodeData, FormSet, Form);
    188   if (Statement == NULL) {
    189     return NULL;
    190   }
    191 
    192   QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
    193   CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
    194   CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
    195   CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
    196 
    197   Statement->QuestionFlags = QuestionHdr->Flags;
    198 
    199   if (Statement->VarStoreId == 0) {
    200     //
    201     // VarStoreId of zero indicates no variable storage
    202     //
    203     return Statement;
    204   }
    205 
    206   //
    207   // Take a look at next OpCode to see whether it is a GUIDed opcode to support
    208   // Framework Compatibility
    209   //
    210   if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
    211     if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {
    212       Status = UpdateCheckBoxStringToken (FormSet, Statement);
    213       if (EFI_ERROR (Status)) {
    214         return NULL;
    215       }
    216     }
    217   }
    218 
    219   //
    220   // Find Storage for this Question
    221   //
    222   Link = GetFirstNode (&FormSet->StorageListHead);
    223   while (!IsNull (&FormSet->StorageListHead, Link)) {
    224     Storage = FORMSET_STORAGE_FROM_LINK (Link);
    225 
    226     if (Storage->VarStoreId == Statement->VarStoreId) {
    227       Statement->Storage = Storage->BrowserStorage;
    228       break;
    229     }
    230 
    231     Link = GetNextNode (&FormSet->StorageListHead, Link);
    232   }
    233   ASSERT (Statement->Storage != NULL);
    234 
    235   //
    236   // Initialilze varname for Name/Value or EFI Variable
    237   //
    238   if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
    239       (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
    240     Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
    241     ASSERT (Statement->VariableName != NULL);
    242 
    243     if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
    244       //
    245       // Check whether old string node already exist.
    246       //
    247       Find = FALSE;
    248       if (!IsListEmpty(&Statement->Storage->NameValueListHead)) {
    249         Link = GetFirstNode (&Statement->Storage->NameValueListHead);
    250         while (!IsNull (&Statement->Storage->NameValueListHead, Link)) {
    251           NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
    252 
    253           if (StrCmp (Statement->VariableName, NameValueNode->Name) == 0) {
    254             Find = TRUE;
    255             break;
    256           }
    257 
    258           Link = GetNextNode (&Statement->Storage->NameValueListHead, Link);
    259         }
    260       }
    261 
    262       if (!Find) {
    263         //
    264         // Insert to Name/Value varstore list
    265         //
    266         NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
    267         ASSERT (NameValueNode != NULL);
    268         NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
    269         NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
    270         ASSERT (NameValueNode->Name != NULL);
    271         NameValueNode->Value = AllocateZeroPool (0x10);
    272         ASSERT (NameValueNode->Value != NULL);
    273         NameValueNode->EditValue = AllocateZeroPool (0x10);
    274         ASSERT (NameValueNode->EditValue != NULL);
    275 
    276         InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
    277       }
    278     }
    279   }
    280 
    281   return Statement;
    282 }
    283 
    284 
    285 /**
    286   Allocate a FORM_EXPRESSION node.
    287 
    288   @param  Form                   The Form associated with this Expression
    289   @param  OpCode                 The binary opcode data.
    290 
    291   @return Pointer to a FORM_EXPRESSION data structure.
    292 
    293 **/
    294 FORM_EXPRESSION *
    295 CreateExpression (
    296   IN OUT FORM_BROWSER_FORM        *Form,
    297   IN     UINT8                    *OpCode
    298   )
    299 {
    300   FORM_EXPRESSION  *Expression;
    301 
    302   Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
    303   ASSERT (Expression != NULL);
    304   Expression->Signature = FORM_EXPRESSION_SIGNATURE;
    305   InitializeListHead (&Expression->OpCodeListHead);
    306   Expression->OpCode = (EFI_IFR_OP_HEADER *) OpCode;
    307 
    308   return Expression;
    309 }
    310 
    311 /**
    312   Create ConfigHdr string for a storage.
    313 
    314   @param  FormSet                Pointer of the current FormSet
    315   @param  Storage                Pointer of the storage
    316 
    317   @retval EFI_SUCCESS            Initialize ConfigHdr success
    318 
    319 **/
    320 EFI_STATUS
    321 InitializeConfigHdr (
    322   IN FORM_BROWSER_FORMSET  *FormSet,
    323   IN OUT FORMSET_STORAGE   *Storage
    324   )
    325 {
    326   CHAR16      *Name;
    327 
    328   if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||
    329       Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
    330     Name = Storage->BrowserStorage->Name;
    331   } else {
    332     Name = NULL;
    333   }
    334 
    335   Storage->ConfigHdr = HiiConstructConfigHdr (
    336                          &Storage->BrowserStorage->Guid,
    337                          Name,
    338                          FormSet->DriverHandle
    339                          );
    340 
    341   if (Storage->ConfigHdr == NULL) {
    342     return EFI_NOT_FOUND;
    343   }
    344 
    345   return EFI_SUCCESS;
    346 }
    347 
    348 /**
    349   Find the global storage link base on the input storate type, name and guid.
    350 
    351   For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
    352   same guid + name = same storage
    353 
    354   For EFI_HII_VARSTORE_NAME_VALUE:
    355   same guid + HiiHandle = same storage
    356 
    357   For EFI_HII_VARSTORE_BUFFER:
    358   same guid + name + HiiHandle = same storage
    359 
    360   @param  StorageType                Storage type.
    361   @param  StorageGuid                Storage guid.
    362   @param  StorageName                Storage Name.
    363   @param  HiiHandle                  HiiHandle for this varstore.
    364 
    365   @return Pointer to a GLOBAL_STORAGE data structure.
    366 
    367 **/
    368 BROWSER_STORAGE *
    369 FindStorageInList (
    370   IN UINT8                 StorageType,
    371   IN EFI_GUID              *StorageGuid,
    372   IN CHAR16                *StorageName,
    373   IN EFI_HII_HANDLE        HiiHandle
    374   )
    375 {
    376   LIST_ENTRY       *Link;
    377   BROWSER_STORAGE  *BrowserStorage;
    378 
    379   Link  = GetFirstNode (&gBrowserStorageList);
    380   while (!IsNull (&gBrowserStorageList, Link)) {
    381     BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);
    382     Link = GetNextNode (&gBrowserStorageList, Link);
    383 
    384     if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {
    385       if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {
    386         if (BrowserStorage->HiiHandle == HiiHandle) {
    387           return BrowserStorage;
    388         }
    389 
    390         continue;
    391       }
    392 
    393       ASSERT (StorageName != NULL);
    394       if (StrCmp (BrowserStorage->Name, StorageName) == 0) {
    395         if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
    396           return BrowserStorage;
    397         } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {
    398           return BrowserStorage;
    399         }
    400       }
    401     }
    402   }
    403 
    404   return NULL;
    405 }
    406 
    407 /**
    408   Intialize the Global Storage.
    409 
    410   @param  BrowserStorage              Pointer to the global storage.
    411   @param  StorageType                Storage type.
    412   @param  OpCodeData                 Binary data for this opcode.
    413 
    414 **/
    415 VOID
    416 IntializeBrowserStorage (
    417   IN BROWSER_STORAGE       *BrowserStorage,
    418   IN UINT8                 StorageType,
    419   IN UINT8                 *OpCodeData
    420   )
    421 {
    422   switch (StorageType) {
    423     case EFI_HII_VARSTORE_BUFFER:
    424       CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
    425       CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
    426 
    427       BrowserStorage->Buffer     = AllocateZeroPool (BrowserStorage->Size);
    428       BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
    429       break;
    430 
    431     case EFI_HII_VARSTORE_EFI_VARIABLE:
    432     case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
    433       CopyMem (&BrowserStorage->Guid,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid,       sizeof (EFI_GUID));
    434       CopyMem (&BrowserStorage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
    435       CopyMem (&BrowserStorage->Size,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size,       sizeof (UINT16));
    436 
    437       if (StorageType ==  EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
    438         BrowserStorage->Buffer     = AllocateZeroPool (BrowserStorage->Size);
    439         BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
    440       }
    441       break;
    442 
    443     case EFI_HII_VARSTORE_NAME_VALUE:
    444       CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
    445 
    446       InitializeListHead (&BrowserStorage->NameValueListHead);
    447       break;
    448 
    449     default:
    450       break;
    451   }
    452 }
    453 
    454 /**
    455   Check whether exist device path info in the ConfigHdr string.
    456 
    457   @param  String                 UEFI configuration string
    458 
    459   @retval TRUE                   Device Path exist.
    460   @retval FALSE                  Not exist device path info.
    461 
    462 **/
    463 BOOLEAN
    464 IsDevicePathExist (
    465   IN  EFI_STRING                   String
    466   )
    467 {
    468   UINTN                    Length;
    469 
    470   for (; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++);
    471   if (*String == 0) {
    472     return FALSE;
    473   }
    474 
    475   String += StrLen (L"PATH=");
    476   if (*String == 0) {
    477     return FALSE;
    478   }
    479 
    480   for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);
    481   if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
    482     return FALSE;
    483   }
    484 
    485   return TRUE;
    486 }
    487 
    488 /**
    489   Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
    490 
    491   @param  FormSet                    Pointer of the current FormSet
    492   @param  StorageType                Storage type.
    493   @param  OpCodeData                 Binary data for this opcode.
    494 
    495   @return Pointer to a FORMSET_STORAGE data structure.
    496 
    497 **/
    498 FORMSET_STORAGE *
    499 CreateStorage (
    500   IN FORM_BROWSER_FORMSET  *FormSet,
    501   IN UINT8                 StorageType,
    502   IN UINT8                 *OpCodeData
    503   )
    504 {
    505   FORMSET_STORAGE         *Storage;
    506   CHAR16                  *UnicodeString;
    507   UINT16                  Index;
    508   BROWSER_STORAGE         *BrowserStorage;
    509   EFI_GUID                *StorageGuid;
    510   CHAR8                   *StorageName;
    511 
    512   UnicodeString = NULL;
    513   StorageName   = NULL;
    514   switch (StorageType) {
    515     case EFI_HII_VARSTORE_BUFFER:
    516       StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE *) OpCodeData)->Guid;
    517       StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
    518       break;
    519 
    520     case EFI_HII_VARSTORE_EFI_VARIABLE:
    521     case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
    522       StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid;
    523       StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;
    524       break;
    525 
    526     default:
    527       ASSERT (StorageType == EFI_HII_VARSTORE_NAME_VALUE);
    528       StorageGuid = &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid;
    529       break;
    530   }
    531 
    532   if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
    533     ASSERT (StorageName != NULL);
    534 
    535     UnicodeString = AllocateZeroPool (AsciiStrSize (StorageName) * 2);
    536     ASSERT (UnicodeString != NULL);
    537     for (Index = 0; StorageName[Index] != 0; Index++) {
    538       UnicodeString[Index] = (CHAR16) StorageName[Index];
    539     }
    540   }
    541 
    542   Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
    543   ASSERT (Storage != NULL);
    544   Storage->Signature = FORMSET_STORAGE_SIGNATURE;
    545   InsertTailList (&FormSet->StorageListHead, &Storage->Link);
    546 
    547   BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);
    548   if (BrowserStorage == NULL) {
    549     BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));
    550     ASSERT (BrowserStorage != NULL);
    551 
    552     BrowserStorage->Signature = BROWSER_STORAGE_SIGNATURE;
    553     InsertTailList (&gBrowserStorageList, &BrowserStorage->Link);
    554 
    555     IntializeBrowserStorage (BrowserStorage, StorageType, OpCodeData);
    556     BrowserStorage->Type = StorageType;
    557     if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
    558       BrowserStorage->Name = UnicodeString;
    559     }
    560 
    561     BrowserStorage->HiiHandle = FormSet->HiiHandle;
    562 
    563     BrowserStorage->Initialized = FALSE;
    564   }
    565 
    566   Storage->BrowserStorage = BrowserStorage;
    567   InitializeConfigHdr (FormSet, Storage);
    568   Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
    569   Storage->SpareStrLen = 0;
    570 
    571   return Storage;
    572 }
    573 
    574 /**
    575   Get Formset_storage base on the input varstoreid info.
    576 
    577   @param  FormSet                Pointer of the current FormSet.
    578   @param  VarStoreId             Varstore ID info.
    579 
    580   @return Pointer to a FORMSET_STORAGE data structure.
    581 
    582 **/
    583 FORMSET_STORAGE *
    584 GetFstStgFromVarId (
    585   IN FORM_BROWSER_FORMSET  *FormSet,
    586   IN EFI_VARSTORE_ID       VarStoreId
    587   )
    588 {
    589   FORMSET_STORAGE  *FormsetStorage;
    590   LIST_ENTRY       *Link;
    591   BOOLEAN          Found;
    592 
    593   Found = FALSE;
    594   FormsetStorage = NULL;
    595   //
    596   // Find Formset Storage for this Question
    597   //
    598   Link = GetFirstNode (&FormSet->StorageListHead);
    599   while (!IsNull (&FormSet->StorageListHead, Link)) {
    600     FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
    601 
    602     if (FormsetStorage->VarStoreId == VarStoreId) {
    603       Found = TRUE;
    604       break;
    605     }
    606 
    607     Link = GetNextNode (&FormSet->StorageListHead, Link);
    608   }
    609 
    610   return Found ? FormsetStorage : NULL;
    611 }
    612 
    613 /**
    614   Get Formset_storage base on the input browser storage.
    615 
    616   More than one formsets may share the same browser storage,
    617   this function just get the first formset storage which
    618   share the browser storage.
    619 
    620   @param  Storage              browser storage info.
    621 
    622   @return Pointer to a FORMSET_STORAGE data structure.
    623 
    624 
    625 **/
    626 FORMSET_STORAGE *
    627 GetFstStgFromBrsStg (
    628   IN BROWSER_STORAGE       *Storage
    629   )
    630 {
    631   FORMSET_STORAGE      *FormsetStorage;
    632   LIST_ENTRY           *Link;
    633   LIST_ENTRY           *FormsetLink;
    634   FORM_BROWSER_FORMSET *FormSet;
    635   BOOLEAN              Found;
    636 
    637   Found = FALSE;
    638   FormsetStorage = NULL;
    639 
    640   FormsetLink = GetFirstNode (&gBrowserFormSetList);
    641   while (!IsNull (&gBrowserFormSetList, FormsetLink)) {
    642     FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink);
    643     FormsetLink = GetNextNode (&gBrowserFormSetList, FormsetLink);
    644 
    645     Link = GetFirstNode (&FormSet->StorageListHead);
    646     while (!IsNull (&FormSet->StorageListHead, Link)) {
    647       FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
    648       Link = GetNextNode (&FormSet->StorageListHead, Link);
    649 
    650       if (FormsetStorage->BrowserStorage == Storage) {
    651         Found = TRUE;
    652         break;
    653       }
    654     }
    655 
    656     if (Found) {
    657       break;
    658     }
    659   }
    660 
    661   return Found ? FormsetStorage : NULL;
    662 }
    663 
    664 /**
    665   Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
    666 
    667   @param  FormSet                Pointer of the current FormSet.
    668   @param  Question               The Question to be initialized.
    669   @param  Form                   Pointer of the current form.
    670 
    671   @retval EFI_SUCCESS            Function success.
    672   @retval EFI_INVALID_PARAMETER  No storage associated with the Question.
    673 
    674 **/
    675 EFI_STATUS
    676 InitializeRequestElement (
    677   IN OUT FORM_BROWSER_FORMSET     *FormSet,
    678   IN OUT FORM_BROWSER_STATEMENT   *Question,
    679   IN OUT FORM_BROWSER_FORM        *Form
    680   )
    681 {
    682   BROWSER_STORAGE  *Storage;
    683   FORMSET_STORAGE  *FormsetStorage;
    684   UINTN            StrLen;
    685   UINTN            StringSize;
    686   CHAR16           *NewStr;
    687   CHAR16           RequestElement[30];
    688   LIST_ENTRY       *Link;
    689   BOOLEAN          Find;
    690   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;
    691   UINTN            MaxLen;
    692 
    693   Storage = Question->Storage;
    694   if (Storage == NULL) {
    695     return EFI_INVALID_PARAMETER;
    696   }
    697 
    698   if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
    699     //
    700     // <ConfigRequest> is unnecessary for EFI variable storage,
    701     // GetVariable()/SetVariable() will be used to retrieve/save values
    702     //
    703     return EFI_SUCCESS;
    704   }
    705 
    706   //
    707   // Prepare <RequestElement>
    708   //
    709   if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
    710       Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
    711     StrLen = UnicodeSPrint (
    712                RequestElement,
    713                30 * sizeof (CHAR16),
    714                L"&OFFSET=%04x&WIDTH=%04x",
    715                Question->VarStoreInfo.VarOffset,
    716                Question->StorageWidth
    717                );
    718     HiiToLower(RequestElement);
    719     Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
    720   } else {
    721     StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
    722   }
    723 
    724   if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
    725     //
    726     // Password with CALLBACK flag is stored in encoded format,
    727     // so don't need to append it to <ConfigRequest>
    728     //
    729     return EFI_SUCCESS;
    730   }
    731 
    732   //
    733   // Find Formset Storage for this Question
    734   //
    735   FormsetStorage = GetFstStgFromVarId(FormSet, Question->VarStoreId);
    736   ASSERT (FormsetStorage != NULL);
    737   StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);
    738   MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;
    739 
    740   //
    741   // Append <RequestElement> to <ConfigRequest>
    742   //
    743   if (StrLen > FormsetStorage->SpareStrLen) {
    744     //
    745     // Old String buffer is not sufficient for RequestElement, allocate a new one
    746     //
    747     MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
    748     NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
    749     ASSERT (NewStr != NULL);
    750     if (FormsetStorage->ConfigRequest != NULL) {
    751       CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);
    752       FreePool (FormsetStorage->ConfigRequest);
    753     }
    754     FormsetStorage->ConfigRequest = NewStr;
    755     FormsetStorage->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;
    756   }
    757 
    758   StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);
    759   FormsetStorage->ElementCount++;
    760   FormsetStorage->SpareStrLen -= StrLen;
    761 
    762   //
    763   // Update the Config Request info saved in the form.
    764   //
    765   ConfigInfo = NULL;
    766   Find       = FALSE;
    767   Link = GetFirstNode (&Form->ConfigRequestHead);
    768   while (!IsNull (&Form->ConfigRequestHead, Link)) {
    769     ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
    770 
    771     if (ConfigInfo != NULL && ConfigInfo->Storage == FormsetStorage->BrowserStorage) {
    772       Find = TRUE;
    773       break;
    774     }
    775 
    776     Link = GetNextNode (&Form->ConfigRequestHead, Link);
    777   }
    778 
    779   if (!Find) {
    780     ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
    781     ASSERT (ConfigInfo != NULL);
    782     ConfigInfo->Signature     = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
    783     ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (FormsetStorage->ConfigHdr), FormsetStorage->ConfigHdr);
    784     ASSERT (ConfigInfo->ConfigRequest != NULL);
    785     ConfigInfo->SpareStrLen   = 0;
    786     ConfigInfo->Storage       = FormsetStorage->BrowserStorage;
    787     InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
    788   }
    789   StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
    790   MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;
    791 
    792   //
    793   // Append <RequestElement> to <ConfigRequest>
    794   //
    795   if (StrLen > ConfigInfo->SpareStrLen) {
    796     //
    797     // Old String buffer is not sufficient for RequestElement, allocate a new one
    798     //
    799     MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
    800     NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
    801     ASSERT (NewStr != NULL);
    802     if (ConfigInfo->ConfigRequest != NULL) {
    803       CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
    804       FreePool (ConfigInfo->ConfigRequest);
    805     }
    806     ConfigInfo->ConfigRequest = NewStr;
    807     ConfigInfo->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;
    808   }
    809 
    810   StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);
    811   ConfigInfo->ElementCount++;
    812   ConfigInfo->SpareStrLen -= StrLen;
    813   return EFI_SUCCESS;
    814 }
    815 
    816 
    817 /**
    818   Free resources of a Expression.
    819 
    820   @param  FormSet                Pointer of the Expression
    821 
    822 **/
    823 VOID
    824 DestroyExpression (
    825   IN FORM_EXPRESSION   *Expression
    826   )
    827 {
    828   LIST_ENTRY         *Link;
    829   EXPRESSION_OPCODE  *OpCode;
    830   LIST_ENTRY         *SubExpressionLink;
    831   FORM_EXPRESSION    *SubExpression;
    832 
    833   while (!IsListEmpty (&Expression->OpCodeListHead)) {
    834     Link = GetFirstNode (&Expression->OpCodeListHead);
    835     OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
    836     RemoveEntryList (&OpCode->Link);
    837 
    838     if (OpCode->ValueList != NULL) {
    839       FreePool (OpCode->ValueList);
    840     }
    841 
    842     if (OpCode->ValueName != NULL) {
    843       FreePool (OpCode->ValueName);
    844     }
    845 
    846     if (OpCode->MapExpressionList.ForwardLink != NULL) {
    847       while (!IsListEmpty (&OpCode->MapExpressionList)) {
    848         SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
    849         SubExpression     = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
    850         RemoveEntryList(&SubExpression->Link);
    851         DestroyExpression (SubExpression);
    852       }
    853     }
    854   }
    855 
    856   //
    857   // Free this Expression
    858   //
    859   FreePool (Expression);
    860 }
    861 
    862 /**
    863   Free resources of a storage.
    864 
    865   @param  Storage                Pointer of the storage
    866 
    867 **/
    868 VOID
    869 DestroyStorage (
    870   IN FORMSET_STORAGE   *Storage
    871   )
    872 {
    873   if (Storage == NULL) {
    874     return;
    875   }
    876 
    877   if (Storage->ConfigRequest != NULL) {
    878     FreePool (Storage->ConfigRequest);
    879   }
    880 
    881   FreePool (Storage);
    882 }
    883 
    884 
    885 /**
    886   Free resources of a Statement.
    887 
    888   @param  FormSet                Pointer of the FormSet
    889   @param  Statement              Pointer of the Statement
    890 
    891 **/
    892 VOID
    893 DestroyStatement (
    894   IN     FORM_BROWSER_FORMSET    *FormSet,
    895   IN OUT FORM_BROWSER_STATEMENT  *Statement
    896   )
    897 {
    898   LIST_ENTRY        *Link;
    899   QUESTION_DEFAULT  *Default;
    900   QUESTION_OPTION   *Option;
    901   FORM_EXPRESSION   *Expression;
    902 
    903   //
    904   // Free Default value List
    905   //
    906   while (!IsListEmpty (&Statement->DefaultListHead)) {
    907     Link = GetFirstNode (&Statement->DefaultListHead);
    908     Default = QUESTION_DEFAULT_FROM_LINK (Link);
    909     RemoveEntryList (&Default->Link);
    910 
    911     if (Default->Value.Buffer != NULL) {
    912       FreePool (Default->Value.Buffer);
    913     }
    914     FreePool (Default);
    915   }
    916 
    917   //
    918   // Free Options List
    919   //
    920   while (!IsListEmpty (&Statement->OptionListHead)) {
    921     Link = GetFirstNode (&Statement->OptionListHead);
    922     Option = QUESTION_OPTION_FROM_LINK (Link);
    923     if (Option->SuppressExpression != NULL) {
    924       FreePool (Option->SuppressExpression);
    925     }
    926     RemoveEntryList (&Option->Link);
    927 
    928     FreePool (Option);
    929   }
    930 
    931   //
    932   // Free Inconsistent List
    933   //
    934   while (!IsListEmpty (&Statement->InconsistentListHead)) {
    935     Link = GetFirstNode (&Statement->InconsistentListHead);
    936     Expression = FORM_EXPRESSION_FROM_LINK (Link);
    937     RemoveEntryList (&Expression->Link);
    938 
    939     DestroyExpression (Expression);
    940   }
    941 
    942   //
    943   // Free NoSubmit List
    944   //
    945   while (!IsListEmpty (&Statement->NoSubmitListHead)) {
    946     Link = GetFirstNode (&Statement->NoSubmitListHead);
    947     Expression = FORM_EXPRESSION_FROM_LINK (Link);
    948     RemoveEntryList (&Expression->Link);
    949 
    950     DestroyExpression (Expression);
    951   }
    952 
    953   //
    954   // Free WarningIf List
    955   //
    956   while (!IsListEmpty (&Statement->WarningListHead)) {
    957     Link = GetFirstNode (&Statement->WarningListHead);
    958     Expression = FORM_EXPRESSION_FROM_LINK (Link);
    959     RemoveEntryList (&Expression->Link);
    960 
    961     DestroyExpression (Expression);
    962   }
    963 
    964   if (Statement->Expression != NULL) {
    965     FreePool (Statement->Expression);
    966   }
    967 
    968   if (Statement->VariableName != NULL) {
    969     FreePool (Statement->VariableName);
    970   }
    971   if (Statement->BlockName != NULL) {
    972     FreePool (Statement->BlockName);
    973   }
    974   if (Statement->BufferValue != NULL) {
    975     FreePool (Statement->BufferValue);
    976   }
    977   if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
    978     DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
    979   }
    980 }
    981 
    982 
    983 /**
    984   Free resources of a Form.
    985 
    986   @param  FormSet                Pointer of the FormSet
    987   @param  Form                   Pointer of the Form.
    988 
    989 **/
    990 VOID
    991 DestroyForm (
    992   IN     FORM_BROWSER_FORMSET  *FormSet,
    993   IN OUT FORM_BROWSER_FORM     *Form
    994   )
    995 {
    996   LIST_ENTRY              *Link;
    997   FORM_EXPRESSION         *Expression;
    998   FORM_BROWSER_STATEMENT  *Statement;
    999   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;
   1000 
   1001   //
   1002   // Free Form Expressions
   1003   //
   1004   while (!IsListEmpty (&Form->ExpressionListHead)) {
   1005     Link = GetFirstNode (&Form->ExpressionListHead);
   1006     Expression = FORM_EXPRESSION_FROM_LINK (Link);
   1007     RemoveEntryList (&Expression->Link);
   1008 
   1009     DestroyExpression (Expression);
   1010   }
   1011 
   1012   //
   1013   // Free Statements/Questions
   1014   //
   1015   while (!IsListEmpty (&Form->StatementListHead)) {
   1016     Link = GetFirstNode (&Form->StatementListHead);
   1017     Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
   1018     RemoveEntryList (&Statement->Link);
   1019 
   1020     DestroyStatement (FormSet, Statement);
   1021   }
   1022 
   1023   //
   1024   // Free ConfigRequest string.
   1025   //
   1026   while (!IsListEmpty (&Form->ConfigRequestHead)) {
   1027     Link = GetFirstNode (&Form->ConfigRequestHead);
   1028     ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
   1029     RemoveEntryList (&ConfigInfo->Link);
   1030 
   1031     FreePool (ConfigInfo->ConfigRequest);
   1032     FreePool (ConfigInfo);
   1033   }
   1034 
   1035   if (Form->SuppressExpression != NULL) {
   1036     FreePool (Form->SuppressExpression);
   1037   }
   1038 
   1039   UiFreeMenuList (&Form->FormViewListHead);
   1040 
   1041   //
   1042   // Free this Form
   1043   //
   1044   FreePool (Form);
   1045 }
   1046 
   1047 
   1048 /**
   1049   Free resources allocated for a FormSet.
   1050 
   1051   @param  FormSet                Pointer of the FormSet
   1052 
   1053 **/
   1054 VOID
   1055 DestroyFormSet (
   1056   IN OUT FORM_BROWSER_FORMSET  *FormSet
   1057   )
   1058 {
   1059   LIST_ENTRY            *Link;
   1060   FORMSET_STORAGE       *Storage;
   1061   FORMSET_DEFAULTSTORE  *DefaultStore;
   1062   FORM_EXPRESSION       *Expression;
   1063   FORM_BROWSER_FORM     *Form;
   1064 
   1065   if (FormSet->IfrBinaryData == NULL) {
   1066     //
   1067     // Uninitialized FormSet
   1068     //
   1069     FreePool (FormSet);
   1070     return;
   1071   }
   1072 
   1073   //
   1074   // Free IFR binary buffer
   1075   //
   1076   FreePool (FormSet->IfrBinaryData);
   1077 
   1078   //
   1079   // Free FormSet Storage
   1080   //
   1081   if (FormSet->StorageListHead.ForwardLink != NULL) {
   1082     while (!IsListEmpty (&FormSet->StorageListHead)) {
   1083       Link = GetFirstNode (&FormSet->StorageListHead);
   1084       Storage = FORMSET_STORAGE_FROM_LINK (Link);
   1085       RemoveEntryList (&Storage->Link);
   1086 
   1087       DestroyStorage (Storage);
   1088     }
   1089   }
   1090 
   1091   //
   1092   // Free FormSet Default Store
   1093   //
   1094   if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
   1095     while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
   1096       Link = GetFirstNode (&FormSet->DefaultStoreListHead);
   1097       DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
   1098       RemoveEntryList (&DefaultStore->Link);
   1099 
   1100       FreePool (DefaultStore);
   1101     }
   1102   }
   1103 
   1104   //
   1105   // Free Formset Expressions
   1106   //
   1107   while (!IsListEmpty (&FormSet->ExpressionListHead)) {
   1108     Link = GetFirstNode (&FormSet->ExpressionListHead);
   1109     Expression = FORM_EXPRESSION_FROM_LINK (Link);
   1110     RemoveEntryList (&Expression->Link);
   1111 
   1112     DestroyExpression (Expression);
   1113   }
   1114 
   1115   //
   1116   // Free Forms
   1117   //
   1118   if (FormSet->FormListHead.ForwardLink != NULL) {
   1119     while (!IsListEmpty (&FormSet->FormListHead)) {
   1120       Link = GetFirstNode (&FormSet->FormListHead);
   1121       Form = FORM_BROWSER_FORM_FROM_LINK (Link);
   1122       RemoveEntryList (&Form->Link);
   1123 
   1124       DestroyForm (FormSet, Form);
   1125     }
   1126   }
   1127 
   1128   if (FormSet->StatementBuffer != NULL) {
   1129     FreePool (FormSet->StatementBuffer);
   1130   }
   1131   if (FormSet->ExpressionBuffer != NULL) {
   1132     FreePool (FormSet->ExpressionBuffer);
   1133   }
   1134 
   1135   FreePool (FormSet);
   1136 }
   1137 
   1138 
   1139 /**
   1140   Tell whether this Operand is an Expression OpCode or not
   1141 
   1142   @param  Operand                Operand of an IFR OpCode.
   1143 
   1144   @retval TRUE                   This is an Expression OpCode.
   1145   @retval FALSE                  Not an Expression OpCode.
   1146 
   1147 **/
   1148 BOOLEAN
   1149 IsExpressionOpCode (
   1150   IN UINT8              Operand
   1151   )
   1152 {
   1153   if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
   1154       ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP))  ||
   1155       ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
   1156       (Operand == EFI_IFR_CATENATE_OP) ||
   1157       (Operand == EFI_IFR_TO_LOWER_OP) ||
   1158       (Operand == EFI_IFR_TO_UPPER_OP) ||
   1159       (Operand == EFI_IFR_MAP_OP)      ||
   1160       (Operand == EFI_IFR_VERSION_OP)  ||
   1161       (Operand == EFI_IFR_SECURITY_OP) ||
   1162       (Operand == EFI_IFR_MATCH2_OP)) {
   1163     return TRUE;
   1164   } else {
   1165     return FALSE;
   1166   }
   1167 }
   1168 
   1169 /**
   1170   Tell whether this Operand is an Statement OpCode.
   1171 
   1172   @param  Operand                Operand of an IFR OpCode.
   1173 
   1174   @retval TRUE                   This is an Statement OpCode.
   1175   @retval FALSE                  Not an Statement OpCode.
   1176 
   1177 **/
   1178 BOOLEAN
   1179 IsStatementOpCode (
   1180   IN UINT8              Operand
   1181   )
   1182 {
   1183   if ((Operand == EFI_IFR_SUBTITLE_OP) ||
   1184       (Operand == EFI_IFR_TEXT_OP) ||
   1185       (Operand == EFI_IFR_RESET_BUTTON_OP) ||
   1186       (Operand == EFI_IFR_REF_OP) ||
   1187       (Operand == EFI_IFR_ACTION_OP) ||
   1188       (Operand == EFI_IFR_NUMERIC_OP) ||
   1189       (Operand == EFI_IFR_ORDERED_LIST_OP) ||
   1190       (Operand == EFI_IFR_CHECKBOX_OP) ||
   1191       (Operand == EFI_IFR_STRING_OP) ||
   1192       (Operand == EFI_IFR_PASSWORD_OP) ||
   1193       (Operand == EFI_IFR_DATE_OP) ||
   1194       (Operand == EFI_IFR_TIME_OP) ||
   1195       (Operand == EFI_IFR_GUID_OP) ||
   1196       (Operand == EFI_IFR_ONE_OF_OP)) {
   1197     return TRUE;
   1198   } else {
   1199     return FALSE;
   1200   }
   1201 }
   1202 
   1203 /**
   1204   Tell whether this Operand is an known OpCode.
   1205 
   1206   @param  Operand                Operand of an IFR OpCode.
   1207 
   1208   @retval TRUE                   This is an Statement OpCode.
   1209   @retval FALSE                  Not an Statement OpCode.
   1210 
   1211 **/
   1212 BOOLEAN
   1213 IsUnKnownOpCode (
   1214   IN UINT8              Operand
   1215   )
   1216 {
   1217   return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;
   1218 }
   1219 
   1220 /**
   1221   Calculate number of Statemens(Questions) and Expression OpCodes.
   1222 
   1223   @param  FormSet                The FormSet to be counted.
   1224   @param  NumberOfStatement      Number of Statemens(Questions)
   1225   @param  NumberOfExpression     Number of Expression OpCodes
   1226 
   1227 **/
   1228 VOID
   1229 CountOpCodes (
   1230   IN  FORM_BROWSER_FORMSET  *FormSet,
   1231   IN OUT  UINT16            *NumberOfStatement,
   1232   IN OUT  UINT16            *NumberOfExpression
   1233   )
   1234 {
   1235   UINT16  StatementCount;
   1236   UINT16  ExpressionCount;
   1237   UINT8   *OpCodeData;
   1238   UINTN   Offset;
   1239   UINTN   OpCodeLen;
   1240 
   1241   Offset = 0;
   1242   StatementCount = 0;
   1243   ExpressionCount = 0;
   1244 
   1245   while (Offset < FormSet->IfrBinaryLength) {
   1246     OpCodeData = FormSet->IfrBinaryData + Offset;
   1247     OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
   1248     Offset += OpCodeLen;
   1249 
   1250     if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
   1251       ExpressionCount++;
   1252     } else {
   1253       StatementCount++;
   1254     }
   1255   }
   1256 
   1257   *NumberOfStatement = StatementCount;
   1258   *NumberOfExpression = ExpressionCount;
   1259 }
   1260 
   1261 
   1262 
   1263 /**
   1264   Parse opcodes in the formset IFR binary.
   1265 
   1266   @param  FormSet                Pointer of the FormSet data structure.
   1267 
   1268   @retval EFI_SUCCESS            Opcode parse success.
   1269   @retval Other                  Opcode parse fail.
   1270 
   1271 **/
   1272 EFI_STATUS
   1273 ParseOpCodes (
   1274   IN FORM_BROWSER_FORMSET              *FormSet
   1275   )
   1276 {
   1277   EFI_STATUS              Status;
   1278   FORM_BROWSER_FORM       *CurrentForm;
   1279   FORM_BROWSER_STATEMENT  *CurrentStatement;
   1280   FORM_BROWSER_STATEMENT  *ParentStatement;
   1281   EXPRESSION_OPCODE       *ExpressionOpCode;
   1282   FORM_EXPRESSION         *CurrentExpression;
   1283   UINT8                   Operand;
   1284   UINT8                   Scope;
   1285   UINTN                   OpCodeOffset;
   1286   UINTN                   OpCodeLength;
   1287   UINT8                   *OpCodeData;
   1288   UINT8                   ScopeOpCode;
   1289   FORMSET_STORAGE         *Storage;
   1290   FORMSET_DEFAULTSTORE    *DefaultStore;
   1291   QUESTION_DEFAULT        *CurrentDefault;
   1292   QUESTION_OPTION         *CurrentOption;
   1293   UINT8                   Width;
   1294   UINT16                  NumberOfStatement;
   1295   UINT16                  NumberOfExpression;
   1296   EFI_IMAGE_ID            *ImageId;
   1297   BOOLEAN                 SuppressForQuestion;
   1298   BOOLEAN                 SuppressForOption;
   1299   UINT16                  DepthOfDisable;
   1300   BOOLEAN                 OpCodeDisabled;
   1301   BOOLEAN                 SingleOpCodeExpression;
   1302   BOOLEAN                 InScopeDefault;
   1303   EFI_HII_VALUE           *Value;
   1304   EFI_IFR_FORM_MAP_METHOD *MapMethod;
   1305   UINT8                   MapScopeDepth;
   1306   LIST_ENTRY              *Link;
   1307   FORMSET_STORAGE         *VarStorage;
   1308   LIST_ENTRY              *MapExpressionList;
   1309   EFI_VARSTORE_ID         TempVarstoreId;
   1310   BOOLEAN                 InScopeDisable;
   1311   INTN                    ConditionalExprCount;
   1312   BOOLEAN                 InUnknownScope;
   1313   UINT8                   UnknownDepth;
   1314   FORMSET_DEFAULTSTORE    *PreDefaultStore;
   1315   LIST_ENTRY              *DefaultLink;
   1316   BOOLEAN                 HaveInserted;
   1317 
   1318   SuppressForQuestion      = FALSE;
   1319   SuppressForOption        = FALSE;
   1320   InScopeDisable           = FALSE;
   1321   DepthOfDisable           = 0;
   1322   OpCodeDisabled           = FALSE;
   1323   SingleOpCodeExpression   = FALSE;
   1324   InScopeDefault           = FALSE;
   1325   CurrentExpression        = NULL;
   1326   CurrentDefault           = NULL;
   1327   CurrentOption            = NULL;
   1328   ImageId                  = NULL;
   1329   MapMethod                = NULL;
   1330   MapScopeDepth            = 0;
   1331   Link                     = NULL;
   1332   VarStorage               = NULL;
   1333   MapExpressionList        = NULL;
   1334   TempVarstoreId           = 0;
   1335   ConditionalExprCount     = 0;
   1336   InUnknownScope           = FALSE;
   1337   UnknownDepth             = 0;
   1338 
   1339   //
   1340   // Get the number of Statements and Expressions
   1341   //
   1342   CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
   1343 
   1344   mStatementIndex = 0;
   1345   mUsedQuestionId = 1;
   1346   FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
   1347   if (FormSet->StatementBuffer == NULL) {
   1348     return EFI_OUT_OF_RESOURCES;
   1349   }
   1350 
   1351   mExpressionOpCodeIndex = 0;
   1352   FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
   1353   if (FormSet->ExpressionBuffer == NULL) {
   1354     return EFI_OUT_OF_RESOURCES;
   1355   }
   1356 
   1357   InitializeListHead (&FormSet->StatementListOSF);
   1358   InitializeListHead (&FormSet->StorageListHead);
   1359   InitializeListHead (&FormSet->SaveFailStorageListHead);
   1360   InitializeListHead (&FormSet->DefaultStoreListHead);
   1361   InitializeListHead (&FormSet->FormListHead);
   1362   InitializeListHead (&FormSet->ExpressionListHead);
   1363   ResetCurrentExpressionStack ();
   1364   ResetMapExpressionListStack ();
   1365 
   1366   CurrentForm = NULL;
   1367   CurrentStatement = NULL;
   1368   ParentStatement  = NULL;
   1369 
   1370   ResetScopeStack ();
   1371 
   1372   OpCodeOffset = 0;
   1373   while (OpCodeOffset < FormSet->IfrBinaryLength) {
   1374     OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
   1375 
   1376     OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
   1377     OpCodeOffset += OpCodeLength;
   1378     Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
   1379     Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
   1380 
   1381     if (InUnknownScope) {
   1382       if (Operand == EFI_IFR_END_OP) {
   1383         UnknownDepth --;
   1384 
   1385         if (UnknownDepth == 0) {
   1386           InUnknownScope = FALSE;
   1387         }
   1388       } else {
   1389         if (Scope != 0) {
   1390           UnknownDepth ++;
   1391         }
   1392       }
   1393 
   1394       continue;
   1395     }
   1396 
   1397     if (IsUnKnownOpCode(Operand)) {
   1398       if (Scope != 0) {
   1399         InUnknownScope = TRUE;
   1400         UnknownDepth ++;
   1401       }
   1402 
   1403       continue;
   1404     }
   1405 
   1406     //
   1407     // If scope bit set, push onto scope stack
   1408     //
   1409     if (Scope != 0) {
   1410       PushScope (Operand);
   1411     }
   1412 
   1413     if (OpCodeDisabled) {
   1414       //
   1415       // DisableIf Expression is evaluated to be TRUE, try to find its end.
   1416       // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
   1417       //
   1418       if (Operand == EFI_IFR_DISABLE_IF_OP) {
   1419         DepthOfDisable++;
   1420       } else if (Operand == EFI_IFR_END_OP) {
   1421         Status = PopScope (&ScopeOpCode);
   1422         if (EFI_ERROR (Status)) {
   1423           return Status;
   1424         }
   1425 
   1426         if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
   1427           if (DepthOfDisable == 0) {
   1428             InScopeDisable = FALSE;
   1429             OpCodeDisabled = FALSE;
   1430           } else {
   1431             DepthOfDisable--;
   1432           }
   1433         }
   1434       }
   1435       continue;
   1436     }
   1437 
   1438     if (IsExpressionOpCode (Operand)) {
   1439       ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
   1440       mExpressionOpCodeIndex++;
   1441 
   1442       ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
   1443       ExpressionOpCode->Operand = Operand;
   1444       Value = &ExpressionOpCode->Value;
   1445 
   1446       switch (Operand) {
   1447       case EFI_IFR_EQ_ID_VAL_OP:
   1448         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1449 
   1450         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1451         CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
   1452         break;
   1453 
   1454       case EFI_IFR_EQ_ID_ID_OP:
   1455         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
   1456         CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
   1457         break;
   1458 
   1459       case EFI_IFR_EQ_ID_VAL_LIST_OP:
   1460         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1461         CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
   1462         ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
   1463         break;
   1464 
   1465       case EFI_IFR_TO_STRING_OP:
   1466       case EFI_IFR_FIND_OP:
   1467         ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
   1468         break;
   1469 
   1470       case EFI_IFR_STRING_REF1_OP:
   1471         Value->Type = EFI_IFR_TYPE_STRING;
   1472         CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
   1473         break;
   1474 
   1475       case EFI_IFR_RULE_REF_OP:
   1476         ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
   1477         break;
   1478 
   1479       case EFI_IFR_SPAN_OP:
   1480         ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
   1481         break;
   1482 
   1483       case EFI_IFR_THIS_OP:
   1484         ASSERT (ParentStatement != NULL);
   1485         ExpressionOpCode->QuestionId = ParentStatement->QuestionId;
   1486         break;
   1487 
   1488       case EFI_IFR_SECURITY_OP:
   1489         CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
   1490         break;
   1491 
   1492       case EFI_IFR_MATCH2_OP:
   1493         CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));
   1494         break;
   1495 
   1496       case EFI_IFR_GET_OP:
   1497       case EFI_IFR_SET_OP:
   1498         CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
   1499         if (TempVarstoreId != 0) {
   1500           if (FormSet->StorageListHead.ForwardLink != NULL) {
   1501             Link = GetFirstNode (&FormSet->StorageListHead);
   1502             while (!IsNull (&FormSet->StorageListHead, Link)) {
   1503               VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
   1504               if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
   1505                 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
   1506                 break;
   1507               }
   1508               Link = GetNextNode (&FormSet->StorageListHead, Link);
   1509             }
   1510           }
   1511           if (ExpressionOpCode->VarStorage == NULL) {
   1512             //
   1513             // VarStorage is not found.
   1514             //
   1515             return EFI_INVALID_PARAMETER;
   1516           }
   1517         }
   1518         ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
   1519         switch (ExpressionOpCode->ValueType) {
   1520         case EFI_IFR_TYPE_BOOLEAN:
   1521         case EFI_IFR_TYPE_NUM_SIZE_8:
   1522           ExpressionOpCode->ValueWidth = 1;
   1523           break;
   1524 
   1525         case EFI_IFR_TYPE_NUM_SIZE_16:
   1526         case EFI_IFR_TYPE_STRING:
   1527           ExpressionOpCode->ValueWidth = 2;
   1528           break;
   1529 
   1530         case EFI_IFR_TYPE_NUM_SIZE_32:
   1531           ExpressionOpCode->ValueWidth = 4;
   1532           break;
   1533 
   1534         case EFI_IFR_TYPE_NUM_SIZE_64:
   1535           ExpressionOpCode->ValueWidth = 8;
   1536           break;
   1537 
   1538         case EFI_IFR_TYPE_DATE:
   1539           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
   1540           break;
   1541 
   1542         case EFI_IFR_TYPE_TIME:
   1543           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
   1544           break;
   1545 
   1546         case EFI_IFR_TYPE_REF:
   1547           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
   1548           break;
   1549 
   1550         case EFI_IFR_TYPE_OTHER:
   1551         case EFI_IFR_TYPE_UNDEFINED:
   1552         case EFI_IFR_TYPE_ACTION:
   1553         case EFI_IFR_TYPE_BUFFER:
   1554         default:
   1555           //
   1556           // Invalid value type for Get/Set opcode.
   1557           //
   1558           return EFI_INVALID_PARAMETER;
   1559         }
   1560         CopyMem (&ExpressionOpCode->VarStoreInfo.VarName,   &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName,   sizeof (EFI_STRING_ID));
   1561         CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
   1562         if ((ExpressionOpCode->VarStorage != NULL) &&
   1563             (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
   1564              ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
   1565           ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
   1566           if (ExpressionOpCode->ValueName == NULL) {
   1567             //
   1568             // String ID is invalid.
   1569             //
   1570             return EFI_INVALID_PARAMETER;
   1571           }
   1572         }
   1573         break;
   1574 
   1575       case EFI_IFR_QUESTION_REF1_OP:
   1576         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1577         break;
   1578 
   1579       case EFI_IFR_QUESTION_REF3_OP:
   1580         if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
   1581           CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
   1582 
   1583           if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
   1584             CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
   1585           }
   1586         }
   1587         break;
   1588 
   1589       //
   1590       // constant
   1591       //
   1592       case EFI_IFR_TRUE_OP:
   1593         Value->Type = EFI_IFR_TYPE_BOOLEAN;
   1594         Value->Value.b = TRUE;
   1595         break;
   1596 
   1597       case EFI_IFR_FALSE_OP:
   1598         Value->Type = EFI_IFR_TYPE_BOOLEAN;
   1599         Value->Value.b = FALSE;
   1600         break;
   1601 
   1602       case EFI_IFR_ONE_OP:
   1603         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1604         Value->Value.u8 = 1;
   1605         break;
   1606 
   1607       case EFI_IFR_ZERO_OP:
   1608         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1609         Value->Value.u8 = 0;
   1610         break;
   1611 
   1612       case EFI_IFR_ONES_OP:
   1613         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
   1614         Value->Value.u64 = 0xffffffffffffffffULL;
   1615         break;
   1616 
   1617       case EFI_IFR_UINT8_OP:
   1618         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1619         Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
   1620         break;
   1621 
   1622       case EFI_IFR_UINT16_OP:
   1623         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1624         CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
   1625         break;
   1626 
   1627       case EFI_IFR_UINT32_OP:
   1628         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
   1629         CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
   1630         break;
   1631 
   1632       case EFI_IFR_UINT64_OP:
   1633         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
   1634         CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
   1635         break;
   1636 
   1637       case EFI_IFR_UNDEFINED_OP:
   1638         Value->Type = EFI_IFR_TYPE_UNDEFINED;
   1639         break;
   1640 
   1641       case EFI_IFR_VERSION_OP:
   1642         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1643         Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
   1644         break;
   1645 
   1646       default:
   1647         break;
   1648       }
   1649       //
   1650       // Create sub expression nested in MAP opcode
   1651       //
   1652       if (CurrentExpression == NULL && MapScopeDepth > 0) {
   1653         CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   1654         ASSERT (MapExpressionList != NULL);
   1655         InsertTailList (MapExpressionList, &CurrentExpression->Link);
   1656         if (Scope == 0) {
   1657           SingleOpCodeExpression = TRUE;
   1658         }
   1659       }
   1660       ASSERT (CurrentExpression != NULL);
   1661       InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
   1662       if (Operand == EFI_IFR_MAP_OP) {
   1663         //
   1664         // Store current Map Expression List.
   1665         //
   1666         if (MapExpressionList != NULL) {
   1667           PushMapExpressionList (MapExpressionList);
   1668         }
   1669         //
   1670         // Initialize new Map Expression List.
   1671         //
   1672         MapExpressionList = &ExpressionOpCode->MapExpressionList;
   1673         InitializeListHead (MapExpressionList);
   1674         //
   1675         // Store current expression.
   1676         //
   1677         PushCurrentExpression (CurrentExpression);
   1678         CurrentExpression = NULL;
   1679         MapScopeDepth ++;
   1680       } else if (SingleOpCodeExpression) {
   1681         //
   1682         // There are two cases to indicate the end of an Expression:
   1683         // for single OpCode expression: one Expression OpCode
   1684         // for expression consists of more than one OpCode: EFI_IFR_END
   1685         //
   1686         SingleOpCodeExpression = FALSE;
   1687 
   1688         if (InScopeDisable && CurrentForm == NULL) {
   1689           //
   1690           // This is DisableIf expression for Form, it should be a constant expression
   1691           //
   1692           Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
   1693           if (EFI_ERROR (Status)) {
   1694             return Status;
   1695           }
   1696 
   1697           OpCodeDisabled = IsTrue(&CurrentExpression->Result);
   1698         }
   1699 
   1700         CurrentExpression = NULL;
   1701       }
   1702 
   1703       continue;
   1704     }
   1705 
   1706     //
   1707     // Parse the Opcode
   1708     //
   1709     switch (Operand) {
   1710 
   1711     case EFI_IFR_FORM_SET_OP:
   1712       //
   1713       // Check the formset GUID
   1714       //
   1715       if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
   1716         return EFI_INVALID_PARAMETER;
   1717       }
   1718 
   1719       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
   1720       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));
   1721       FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset
   1722 
   1723       if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
   1724         //
   1725         // The formset OpCode contains ClassGuid
   1726         //
   1727         FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
   1728         CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
   1729       }
   1730       break;
   1731 
   1732     case EFI_IFR_FORM_OP:
   1733       //
   1734       // Create a new Form for this FormSet
   1735       //
   1736       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
   1737       ASSERT (CurrentForm != NULL);
   1738       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
   1739       InitializeListHead (&CurrentForm->ExpressionListHead);
   1740       InitializeListHead (&CurrentForm->StatementListHead);
   1741       InitializeListHead (&CurrentForm->ConfigRequestHead);
   1742       InitializeListHead (&CurrentForm->FormViewListHead);
   1743 
   1744       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
   1745       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));
   1746       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
   1747 
   1748       ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
   1749       if ( ConditionalExprCount > 0) {
   1750         //
   1751         // Form is inside of suppressif
   1752         //
   1753         CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
   1754                                                  (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
   1755         ASSERT (CurrentForm->SuppressExpression != NULL);
   1756         CurrentForm->SuppressExpression->Count     = (UINTN) ConditionalExprCount;
   1757         CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
   1758         CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
   1759       }
   1760 
   1761       if (Scope != 0) {
   1762         //
   1763         // Enter scope of a Form, suppressif will be used for Question or Option
   1764         //
   1765         SuppressForQuestion = TRUE;
   1766       }
   1767 
   1768       //
   1769       // Insert into Form list of this FormSet
   1770       //
   1771       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
   1772       break;
   1773 
   1774     case EFI_IFR_FORM_MAP_OP:
   1775       //
   1776       // Create a new Form for this FormSet
   1777       //
   1778       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
   1779       ASSERT (CurrentForm != NULL);
   1780       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
   1781       InitializeListHead (&CurrentForm->ExpressionListHead);
   1782       InitializeListHead (&CurrentForm->StatementListHead);
   1783       InitializeListHead (&CurrentForm->ConfigRequestHead);
   1784       InitializeListHead (&CurrentForm->FormViewListHead);
   1785 
   1786       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
   1787 
   1788       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
   1789       //
   1790       // FormMap Form must contain at least one Map Method.
   1791       //
   1792       if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
   1793         return EFI_INVALID_PARAMETER;
   1794       }
   1795       //
   1796       // Try to find the standard form map method.
   1797       //
   1798       while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
   1799         if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
   1800           CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
   1801           CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
   1802           break;
   1803         }
   1804         MapMethod ++;
   1805       }
   1806       //
   1807       // If the standard form map method is not found, the first map method title will be used.
   1808       //
   1809       if (CurrentForm->FormTitle == 0) {
   1810         MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
   1811         CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
   1812       }
   1813 
   1814       ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
   1815       if ( ConditionalExprCount > 0) {
   1816         //
   1817         // Form is inside of suppressif
   1818         //
   1819         CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
   1820                                                  (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
   1821         ASSERT (CurrentForm->SuppressExpression != NULL);
   1822         CurrentForm->SuppressExpression->Count     = (UINTN) ConditionalExprCount;
   1823         CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
   1824         CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
   1825       }
   1826 
   1827       if (Scope != 0) {
   1828         //
   1829         // Enter scope of a Form, suppressif will be used for Question or Option
   1830         //
   1831         SuppressForQuestion = TRUE;
   1832       }
   1833 
   1834       //
   1835       // Insert into Form list of this FormSet
   1836       //
   1837       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
   1838       break;
   1839 
   1840     //
   1841     // Storage
   1842     //
   1843     case EFI_IFR_VARSTORE_OP:
   1844       //
   1845       // Create a buffer Storage for this FormSet
   1846       //
   1847       Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
   1848       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
   1849       break;
   1850 
   1851     case EFI_IFR_VARSTORE_NAME_VALUE_OP:
   1852       //
   1853       // Create a name/value Storage for this FormSet
   1854       //
   1855       Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
   1856       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
   1857       break;
   1858 
   1859     case EFI_IFR_VARSTORE_EFI_OP:
   1860       //
   1861       // Create a EFI variable Storage for this FormSet
   1862       //
   1863       if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
   1864         //
   1865         // Create efi varstore with format follow UEFI spec before 2.3.1.
   1866         //
   1867         Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
   1868       } else {
   1869         //
   1870         // Create efi varstore with format follow UEFI spec 2.3.1 and later.
   1871         //
   1872         Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
   1873       }
   1874       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
   1875       break;
   1876 
   1877     //
   1878     // DefaultStore
   1879     //
   1880     case EFI_IFR_DEFAULTSTORE_OP:
   1881       HaveInserted = FALSE;
   1882       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
   1883       ASSERT (DefaultStore != NULL);
   1884       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
   1885 
   1886       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));
   1887       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
   1888       //
   1889       // Insert it to the DefaultStore list of this Formset with ascending order.
   1890       //
   1891       if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
   1892         DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);
   1893         while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {
   1894           PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);
   1895           DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);
   1896           if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {
   1897             InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);
   1898             HaveInserted = TRUE;
   1899             break;
   1900           }
   1901         }
   1902       }
   1903       if (!HaveInserted) {
   1904         InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
   1905       }
   1906       break;
   1907 
   1908     //
   1909     // Statements
   1910     //
   1911     case EFI_IFR_SUBTITLE_OP:
   1912       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   1913       ASSERT (CurrentStatement != NULL);
   1914 
   1915       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
   1916       CurrentStatement->FakeQuestionId = mUsedQuestionId++;
   1917       break;
   1918 
   1919     case EFI_IFR_TEXT_OP:
   1920       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   1921       ASSERT (CurrentStatement != NULL);
   1922       CurrentStatement->FakeQuestionId = mUsedQuestionId++;
   1923       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
   1924       break;
   1925 
   1926     case EFI_IFR_RESET_BUTTON_OP:
   1927       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   1928       ASSERT (CurrentStatement != NULL);
   1929       CurrentStatement->FakeQuestionId = mUsedQuestionId++;
   1930       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
   1931       break;
   1932 
   1933     //
   1934     // Questions
   1935     //
   1936     case EFI_IFR_ACTION_OP:
   1937       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   1938       ASSERT (CurrentStatement != NULL);
   1939       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
   1940 
   1941       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
   1942         //
   1943         // No QuestionConfig present, so no configuration string will be processed
   1944         //
   1945         CurrentStatement->QuestionConfig = 0;
   1946       } else {
   1947         CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
   1948       }
   1949       break;
   1950 
   1951     case EFI_IFR_REF_OP:
   1952       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   1953       ASSERT (CurrentStatement != NULL);
   1954       Value = &CurrentStatement->HiiValue;
   1955       Value->Type = EFI_IFR_TYPE_REF;
   1956       if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
   1957         CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
   1958 
   1959         if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
   1960           CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1961 
   1962           if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
   1963             CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
   1964 
   1965             if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
   1966               CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
   1967             }
   1968           }
   1969         }
   1970       }
   1971       CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
   1972       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   1973       break;
   1974 
   1975     case EFI_IFR_ONE_OF_OP:
   1976     case EFI_IFR_NUMERIC_OP:
   1977       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   1978       ASSERT(CurrentStatement != NULL);
   1979 
   1980       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
   1981       Value = &CurrentStatement->HiiValue;
   1982 
   1983       switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
   1984       case EFI_IFR_NUMERIC_SIZE_1:
   1985         CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
   1986         CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
   1987         CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
   1988         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
   1989         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1990         break;
   1991 
   1992       case EFI_IFR_NUMERIC_SIZE_2:
   1993         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
   1994         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
   1995         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));
   1996         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
   1997         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1998         break;
   1999 
   2000       case EFI_IFR_NUMERIC_SIZE_4:
   2001         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
   2002         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
   2003         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));
   2004         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
   2005         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
   2006         break;
   2007 
   2008       case EFI_IFR_NUMERIC_SIZE_8:
   2009         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
   2010         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
   2011         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));
   2012         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
   2013         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
   2014         break;
   2015 
   2016       default:
   2017         break;
   2018       }
   2019 
   2020       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2021 
   2022       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
   2023         SuppressForOption = TRUE;
   2024       }
   2025       break;
   2026 
   2027     case EFI_IFR_ORDERED_LIST_OP:
   2028       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2029       ASSERT(CurrentStatement != NULL);
   2030 
   2031       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
   2032       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
   2033 
   2034       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
   2035       CurrentStatement->BufferValue = NULL;
   2036 
   2037       if (Scope != 0) {
   2038         SuppressForOption = TRUE;
   2039       }
   2040       break;
   2041 
   2042     case EFI_IFR_CHECKBOX_OP:
   2043       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2044       ASSERT(CurrentStatement != NULL);
   2045 
   2046       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
   2047       CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
   2048       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
   2049 
   2050       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2051 
   2052       break;
   2053 
   2054     case EFI_IFR_STRING_OP:
   2055       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2056       ASSERT (CurrentStatement != NULL);
   2057       //
   2058       // MinSize is the minimum number of characters that can be accepted for this opcode,
   2059       // MaxSize is the maximum number of characters that can be accepted for this opcode.
   2060       // The characters are stored as Unicode, so the storage width should multiply 2.
   2061       //
   2062       CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
   2063       CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
   2064       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
   2065       CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
   2066 
   2067       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
   2068       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
   2069       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
   2070 
   2071       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2072       break;
   2073 
   2074     case EFI_IFR_PASSWORD_OP:
   2075       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2076       ASSERT (CurrentStatement != NULL);
   2077       //
   2078       // MinSize is the minimum number of characters that can be accepted for this opcode,
   2079       // MaxSize is the maximum number of characters that can be accepted for this opcode.
   2080       // The characters are stored as Unicode, so the storage width should multiply 2.
   2081       //
   2082       CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
   2083       CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
   2084       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
   2085 
   2086       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
   2087       CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
   2088       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
   2089 
   2090       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2091       break;
   2092 
   2093     case EFI_IFR_DATE_OP:
   2094       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2095       ASSERT(CurrentStatement != NULL);
   2096 
   2097       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
   2098       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
   2099 
   2100       if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
   2101         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
   2102 
   2103         InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2104       } else {
   2105         //
   2106         // Don't assign storage for RTC type of date/time
   2107         //
   2108         CurrentStatement->Storage = NULL;
   2109         CurrentStatement->StorageWidth = 0;
   2110       }
   2111       break;
   2112 
   2113     case EFI_IFR_TIME_OP:
   2114       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2115       ASSERT(CurrentStatement != NULL);
   2116 
   2117       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
   2118       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
   2119 
   2120       if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
   2121         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
   2122 
   2123         InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2124       } else {
   2125         //
   2126         // Don't assign storage for RTC type of date/time
   2127         //
   2128         CurrentStatement->Storage = NULL;
   2129         CurrentStatement->StorageWidth = 0;
   2130       }
   2131       break;
   2132 
   2133     //
   2134     // Default
   2135     //
   2136     case EFI_IFR_DEFAULT_OP:
   2137       //
   2138       // EFI_IFR_DEFAULT appear in scope of a Question,
   2139       // It creates a default value for the current question.
   2140       // A Question may have more than one Default value which have different default types.
   2141       //
   2142       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
   2143       ASSERT (CurrentDefault != NULL);
   2144       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
   2145 
   2146       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
   2147       CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
   2148       if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {
   2149         CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
   2150         CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);
   2151         ASSERT (CurrentDefault->Value.Buffer != NULL);
   2152       } else {
   2153         CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
   2154         ExtendValueToU64 (&CurrentDefault->Value);
   2155       }
   2156 
   2157       //
   2158       // Insert to Default Value list of current Question
   2159       //
   2160       InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
   2161 
   2162       if (Scope != 0) {
   2163         InScopeDefault = TRUE;
   2164       }
   2165       break;
   2166 
   2167     //
   2168     // Option
   2169     //
   2170     case EFI_IFR_ONE_OF_OPTION_OP:
   2171       ASSERT (ParentStatement != NULL);
   2172       if (ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP && ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {
   2173         //
   2174         // It's keep the default value for ordered list opcode.
   2175         //
   2176         CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
   2177         ASSERT (CurrentDefault != NULL);
   2178         CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
   2179 
   2180         CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;
   2181         if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
   2182           CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
   2183         } else {
   2184           CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
   2185         }
   2186 
   2187         CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
   2188         CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);
   2189         ASSERT (CurrentDefault->Value.Buffer != NULL);
   2190 
   2191         //
   2192         // Insert to Default Value list of current Question
   2193         //
   2194         InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
   2195         break;
   2196       }
   2197 
   2198       //
   2199       // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
   2200       // It create a selection for use in current Question.
   2201       //
   2202       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
   2203       ASSERT (CurrentOption != NULL);
   2204       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
   2205       CurrentOption->OpCode    = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
   2206 
   2207       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
   2208       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
   2209       CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
   2210       CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
   2211       ExtendValueToU64 (&CurrentOption->Value);
   2212 
   2213       ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
   2214       if ( ConditionalExprCount > 0) {
   2215         //
   2216         // Form is inside of suppressif
   2217         //
   2218         CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
   2219                                                  (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
   2220         ASSERT (CurrentOption->SuppressExpression != NULL);
   2221         CurrentOption->SuppressExpression->Count     = (UINTN) ConditionalExprCount;
   2222         CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
   2223         CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
   2224       }
   2225 
   2226       //
   2227       // Insert to Option list of current Question
   2228       //
   2229       InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);
   2230       //
   2231       // Now we know the Storage width of nested Ordered List
   2232       //
   2233       if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {
   2234         Width = 1;
   2235         switch (CurrentOption->Value.Type) {
   2236         case EFI_IFR_TYPE_NUM_SIZE_8:
   2237           Width = 1;
   2238           break;
   2239 
   2240         case EFI_IFR_TYPE_NUM_SIZE_16:
   2241           Width = 2;
   2242           break;
   2243 
   2244         case EFI_IFR_TYPE_NUM_SIZE_32:
   2245           Width = 4;
   2246           break;
   2247 
   2248         case EFI_IFR_TYPE_NUM_SIZE_64:
   2249           Width = 8;
   2250           break;
   2251 
   2252         default:
   2253           //
   2254           // Invalid type for Ordered List
   2255           //
   2256           break;
   2257         }
   2258 
   2259         ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);
   2260         ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);
   2261         ParentStatement->ValueType = CurrentOption->Value.Type;
   2262         if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
   2263           ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;
   2264           ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;
   2265         }
   2266 
   2267         InitializeRequestElement (FormSet, ParentStatement, CurrentForm);
   2268       }
   2269       break;
   2270 
   2271     //
   2272     // Conditional
   2273     //
   2274     case EFI_IFR_NO_SUBMIT_IF_OP:
   2275     case EFI_IFR_INCONSISTENT_IF_OP:
   2276       //
   2277       // Create an Expression node
   2278       //
   2279       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2280       CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
   2281 
   2282       if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
   2283         CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
   2284         InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);
   2285       } else {
   2286         CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
   2287         InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);
   2288       }
   2289 
   2290       //
   2291       // Take a look at next OpCode to see whether current expression consists
   2292       // of single OpCode
   2293       //
   2294       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2295         SingleOpCodeExpression = TRUE;
   2296       }
   2297       break;
   2298 
   2299     case EFI_IFR_WARNING_IF_OP:
   2300       //
   2301       // Create an Expression node
   2302       //
   2303       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2304       CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));
   2305       CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;
   2306       CurrentExpression->Type    = EFI_HII_EXPRESSION_WARNING_IF;
   2307       InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);
   2308 
   2309       //
   2310       // Take a look at next OpCode to see whether current expression consists
   2311       // of single OpCode
   2312       //
   2313       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2314         SingleOpCodeExpression = TRUE;
   2315       }
   2316       break;
   2317 
   2318     case EFI_IFR_SUPPRESS_IF_OP:
   2319       //
   2320       // Question and Option will appear in scope of this OpCode
   2321       //
   2322       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2323       CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
   2324 
   2325       if (CurrentForm == NULL) {
   2326         InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
   2327       } else {
   2328         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2329       }
   2330 
   2331       if (SuppressForOption) {
   2332         PushConditionalExpression(CurrentExpression, ExpressOption);
   2333       } else if (SuppressForQuestion) {
   2334         PushConditionalExpression(CurrentExpression, ExpressStatement);
   2335       } else {
   2336         PushConditionalExpression(CurrentExpression, ExpressForm);
   2337       }
   2338 
   2339       //
   2340       // Take a look at next OpCode to see whether current expression consists
   2341       // of single OpCode
   2342       //
   2343       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2344         SingleOpCodeExpression = TRUE;
   2345       }
   2346       break;
   2347 
   2348     case EFI_IFR_GRAY_OUT_IF_OP:
   2349       //
   2350       // Questions will appear in scope of this OpCode
   2351       //
   2352       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2353       CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
   2354       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2355       PushConditionalExpression(CurrentExpression, ExpressStatement);
   2356 
   2357       //
   2358       // Take a look at next OpCode to see whether current expression consists
   2359       // of single OpCode
   2360       //
   2361       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2362         SingleOpCodeExpression = TRUE;
   2363       }
   2364       break;
   2365 
   2366     case EFI_IFR_DISABLE_IF_OP:
   2367       //
   2368       // The DisableIf expression should only rely on constant, so it could be
   2369       // evaluated at initialization and it will not be queued
   2370       //
   2371       CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
   2372       ASSERT (CurrentExpression != NULL);
   2373       CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
   2374       CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
   2375       InitializeListHead (&CurrentExpression->OpCodeListHead);
   2376 
   2377       if (CurrentForm != NULL) {
   2378         //
   2379         // This is DisableIf for Question, enqueue it to Form expression list
   2380         //
   2381         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2382         PushConditionalExpression(CurrentExpression, ExpressStatement);
   2383       }
   2384 
   2385       OpCodeDisabled  = FALSE;
   2386       InScopeDisable  = TRUE;
   2387       //
   2388       // Take a look at next OpCode to see whether current expression consists
   2389       // of single OpCode
   2390       //
   2391       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2392         SingleOpCodeExpression = TRUE;
   2393       }
   2394       break;
   2395 
   2396     //
   2397     // Expression
   2398     //
   2399     case EFI_IFR_VALUE_OP:
   2400       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2401       CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
   2402       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2403 
   2404       if (InScopeDefault) {
   2405         //
   2406         // Used for default (EFI_IFR_DEFAULT)
   2407         //
   2408         CurrentDefault->ValueExpression = CurrentExpression;
   2409       } else {
   2410         //
   2411         // If used for a question, then the question will be read-only
   2412         //
   2413         //
   2414         // Make sure CurrentStatement is not NULL.
   2415         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2416         // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
   2417         //
   2418         ASSERT (ParentStatement != NULL);
   2419         ParentStatement->ValueExpression = CurrentExpression;
   2420       }
   2421 
   2422       //
   2423       // Take a look at next OpCode to see whether current expression consists
   2424       // of single OpCode
   2425       //
   2426       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2427         SingleOpCodeExpression = TRUE;
   2428       }
   2429       break;
   2430 
   2431     case EFI_IFR_RULE_OP:
   2432       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2433       CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
   2434 
   2435       CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
   2436       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2437 
   2438       //
   2439       // Take a look at next OpCode to see whether current expression consists
   2440       // of single OpCode
   2441       //
   2442       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2443         SingleOpCodeExpression = TRUE;
   2444       }
   2445       break;
   2446 
   2447     case EFI_IFR_READ_OP:
   2448       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2449       CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
   2450       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2451 
   2452       //
   2453       // Make sure CurrentStatement is not NULL.
   2454       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2455       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
   2456       //
   2457       ASSERT (ParentStatement != NULL);
   2458       ParentStatement->ReadExpression = CurrentExpression;
   2459 
   2460       //
   2461       // Take a look at next OpCode to see whether current expression consists
   2462       // of single OpCode
   2463       //
   2464       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2465         SingleOpCodeExpression = TRUE;
   2466       }
   2467       break;
   2468 
   2469     case EFI_IFR_WRITE_OP:
   2470       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2471       CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
   2472       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2473 
   2474       //
   2475       // Make sure CurrentStatement is not NULL.
   2476       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2477       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
   2478       //
   2479       ASSERT (ParentStatement != NULL);
   2480       ParentStatement->WriteExpression = CurrentExpression;
   2481 
   2482       //
   2483       // Take a look at next OpCode to see whether current expression consists
   2484       // of single OpCode
   2485       //
   2486       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2487         SingleOpCodeExpression = TRUE;
   2488       }
   2489       break;
   2490 
   2491     //
   2492     // Image
   2493     //
   2494     case EFI_IFR_IMAGE_OP:
   2495       //
   2496       // Get ScopeOpcode from top of stack
   2497       //
   2498       PopScope (&ScopeOpCode);
   2499       PushScope (ScopeOpCode);
   2500 
   2501       switch (ScopeOpCode) {
   2502       case EFI_IFR_FORM_SET_OP:
   2503         ImageId = &FormSet->ImageId;
   2504         break;
   2505 
   2506       case EFI_IFR_FORM_OP:
   2507       case EFI_IFR_FORM_MAP_OP:
   2508         ASSERT (CurrentForm != NULL);
   2509         ImageId = &CurrentForm->ImageId;
   2510         break;
   2511 
   2512       case EFI_IFR_ONE_OF_OPTION_OP:
   2513         ASSERT (CurrentOption != NULL);
   2514         ImageId = &CurrentOption->ImageId;
   2515         break;
   2516 
   2517       default:
   2518         //
   2519         // Make sure CurrentStatement is not NULL.
   2520         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2521         // file is wrongly generated by tools such as VFR Compiler.
   2522         //
   2523         ASSERT (ParentStatement != NULL);
   2524         ImageId = &ParentStatement->ImageId;
   2525         break;
   2526       }
   2527 
   2528       ASSERT (ImageId != NULL);
   2529       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
   2530       break;
   2531 
   2532     //
   2533     // Refresh
   2534     //
   2535     case EFI_IFR_REFRESH_OP:
   2536       ASSERT (ParentStatement != NULL);
   2537       ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
   2538       break;
   2539 
   2540     //
   2541     // Refresh guid.
   2542     //
   2543     case EFI_IFR_REFRESH_ID_OP:
   2544       //
   2545       // Get ScopeOpcode from top of stack
   2546       //
   2547       PopScope (&ScopeOpCode);
   2548       PushScope (ScopeOpCode);
   2549 
   2550       switch (ScopeOpCode) {
   2551       case EFI_IFR_FORM_OP:
   2552       case EFI_IFR_FORM_MAP_OP:
   2553         ASSERT (CurrentForm != NULL);
   2554         CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
   2555         break;
   2556 
   2557       default:
   2558         ASSERT (ParentStatement != NULL);
   2559         CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
   2560         break;
   2561       }
   2562       break;
   2563 
   2564     //
   2565     // Modal tag
   2566     //
   2567     case EFI_IFR_MODAL_TAG_OP:
   2568       ASSERT (CurrentForm != NULL);
   2569       CurrentForm->ModalForm = TRUE;
   2570       break;
   2571 
   2572     //
   2573     // Lock tag, used by form and statement.
   2574     //
   2575     case EFI_IFR_LOCKED_OP:
   2576       //
   2577       // Get ScopeOpcode from top of stack
   2578       //
   2579       PopScope (&ScopeOpCode);
   2580       PushScope (ScopeOpCode);
   2581       switch (ScopeOpCode) {
   2582       case EFI_IFR_FORM_OP:
   2583       case EFI_IFR_FORM_MAP_OP:
   2584         ASSERT (CurrentForm != NULL);
   2585         CurrentForm->Locked = TRUE;
   2586         break;
   2587 
   2588       default:
   2589         ASSERT (ParentStatement != NULL);
   2590         ParentStatement->Locked = TRUE;
   2591       }
   2592       break;
   2593 
   2594     //
   2595     // Vendor specific
   2596     //
   2597     case EFI_IFR_GUID_OP:
   2598       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   2599       break;
   2600 
   2601     //
   2602     // Scope End
   2603     //
   2604     case EFI_IFR_END_OP:
   2605       Status = PopScope (&ScopeOpCode);
   2606       if (EFI_ERROR (Status)) {
   2607         ResetScopeStack ();
   2608         return Status;
   2609       }
   2610 
   2611       //
   2612       // Parent statement end tag found, update ParentStatement info.
   2613       //
   2614       if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {
   2615         ParentStatement  = ParentStatement->ParentStatement;
   2616       }
   2617 
   2618       switch (ScopeOpCode) {
   2619       case EFI_IFR_FORM_SET_OP:
   2620         //
   2621         // End of FormSet, update FormSet IFR binary length
   2622         // to stop parsing substantial OpCodes
   2623         //
   2624         FormSet->IfrBinaryLength = OpCodeOffset;
   2625         break;
   2626 
   2627       case EFI_IFR_FORM_OP:
   2628       case EFI_IFR_FORM_MAP_OP:
   2629         //
   2630         // End of Form
   2631         //
   2632         CurrentForm = NULL;
   2633         SuppressForQuestion = FALSE;
   2634         break;
   2635 
   2636       case EFI_IFR_ONE_OF_OPTION_OP:
   2637         //
   2638         // End of Option
   2639         //
   2640         CurrentOption = NULL;
   2641         break;
   2642 
   2643       case EFI_IFR_NO_SUBMIT_IF_OP:
   2644       case EFI_IFR_INCONSISTENT_IF_OP:
   2645       case EFI_IFR_WARNING_IF_OP:
   2646         //
   2647         // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
   2648         //
   2649         break;
   2650 
   2651       case EFI_IFR_SUPPRESS_IF_OP:
   2652         if (SuppressForOption) {
   2653           PopConditionalExpression(ExpressOption);
   2654         } else if (SuppressForQuestion) {
   2655           PopConditionalExpression(ExpressStatement);
   2656         } else {
   2657           PopConditionalExpression(ExpressForm);
   2658         }
   2659         break;
   2660 
   2661       case EFI_IFR_GRAY_OUT_IF_OP:
   2662         PopConditionalExpression(ExpressStatement);
   2663         break;
   2664 
   2665       case EFI_IFR_DISABLE_IF_OP:
   2666         if (CurrentForm != NULL) {
   2667           PopConditionalExpression(ExpressStatement);
   2668         }
   2669         InScopeDisable = FALSE;
   2670         OpCodeDisabled = FALSE;
   2671         break;
   2672 
   2673       case EFI_IFR_ONE_OF_OP:
   2674       case EFI_IFR_ORDERED_LIST_OP:
   2675         SuppressForOption = FALSE;
   2676         break;
   2677 
   2678       case EFI_IFR_DEFAULT_OP:
   2679         InScopeDefault = FALSE;
   2680         break;
   2681 
   2682       case EFI_IFR_MAP_OP:
   2683         //
   2684         // Get current Map Expression List.
   2685         //
   2686         Status = PopMapExpressionList ((VOID **) &MapExpressionList);
   2687         if (Status == EFI_ACCESS_DENIED) {
   2688           MapExpressionList = NULL;
   2689         }
   2690         //
   2691         // Get current expression.
   2692         //
   2693         Status = PopCurrentExpression ((VOID **) &CurrentExpression);
   2694         ASSERT_EFI_ERROR (Status);
   2695         ASSERT (MapScopeDepth > 0);
   2696         MapScopeDepth --;
   2697         break;
   2698 
   2699       default:
   2700         if (IsExpressionOpCode (ScopeOpCode)) {
   2701           if (InScopeDisable && CurrentForm == NULL) {
   2702             //
   2703             // This is DisableIf expression for Form, it should be a constant expression
   2704             //
   2705             ASSERT (CurrentExpression != NULL);
   2706             Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
   2707             if (EFI_ERROR (Status)) {
   2708               return Status;
   2709             }
   2710 
   2711             OpCodeDisabled = IsTrue (&CurrentExpression->Result);
   2712 
   2713             //
   2714             // DisableIf Expression is only used once and not queued, free it
   2715             //
   2716             DestroyExpression (CurrentExpression);
   2717           }
   2718 
   2719           //
   2720           // End of current Expression
   2721           //
   2722           CurrentExpression = NULL;
   2723         }
   2724         break;
   2725       }
   2726       break;
   2727 
   2728     default:
   2729       break;
   2730     }
   2731 
   2732     if (IsStatementOpCode(Operand)) {
   2733       CurrentStatement->ParentStatement = ParentStatement;
   2734       if (Scope != 0) {
   2735         //
   2736         // Scope != 0, other statements or options may nest in this statement.
   2737         // Update the ParentStatement info.
   2738         //
   2739         ParentStatement = CurrentStatement;
   2740       }
   2741     }
   2742   }
   2743 
   2744   return EFI_SUCCESS;
   2745 }
   2746