Home | History | Annotate | Download | only in SetupBrowserDxe
      1 /** @file
      2 Parser for IFR binary encoding.
      3 
      4 Copyright (c) 2007 - 2015, 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 FormSe.
     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 
   1315   SuppressForQuestion      = FALSE;
   1316   SuppressForOption        = FALSE;
   1317   InScopeDisable           = FALSE;
   1318   DepthOfDisable           = 0;
   1319   OpCodeDisabled           = FALSE;
   1320   SingleOpCodeExpression   = FALSE;
   1321   InScopeDefault           = FALSE;
   1322   CurrentExpression        = NULL;
   1323   CurrentDefault           = NULL;
   1324   CurrentOption            = NULL;
   1325   ImageId                  = NULL;
   1326   MapMethod                = NULL;
   1327   MapScopeDepth            = 0;
   1328   Link                     = NULL;
   1329   VarStorage               = NULL;
   1330   MapExpressionList        = NULL;
   1331   TempVarstoreId           = 0;
   1332   ConditionalExprCount     = 0;
   1333   InUnknownScope           = FALSE;
   1334   UnknownDepth             = 0;
   1335 
   1336   //
   1337   // Get the number of Statements and Expressions
   1338   //
   1339   CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
   1340 
   1341   mStatementIndex = 0;
   1342   mUsedQuestionId = 1;
   1343   FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
   1344   if (FormSet->StatementBuffer == NULL) {
   1345     return EFI_OUT_OF_RESOURCES;
   1346   }
   1347 
   1348   mExpressionOpCodeIndex = 0;
   1349   FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
   1350   if (FormSet->ExpressionBuffer == NULL) {
   1351     return EFI_OUT_OF_RESOURCES;
   1352   }
   1353 
   1354   InitializeListHead (&FormSet->StatementListOSF);
   1355   InitializeListHead (&FormSet->StorageListHead);
   1356   InitializeListHead (&FormSet->SaveFailStorageListHead);
   1357   InitializeListHead (&FormSet->DefaultStoreListHead);
   1358   InitializeListHead (&FormSet->FormListHead);
   1359   InitializeListHead (&FormSet->ExpressionListHead);
   1360   ResetCurrentExpressionStack ();
   1361   ResetMapExpressionListStack ();
   1362 
   1363   CurrentForm = NULL;
   1364   CurrentStatement = NULL;
   1365   ParentStatement  = NULL;
   1366 
   1367   ResetScopeStack ();
   1368 
   1369   OpCodeOffset = 0;
   1370   while (OpCodeOffset < FormSet->IfrBinaryLength) {
   1371     OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
   1372 
   1373     OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
   1374     OpCodeOffset += OpCodeLength;
   1375     Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
   1376     Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
   1377 
   1378     if (InUnknownScope) {
   1379       if (Operand == EFI_IFR_END_OP) {
   1380         UnknownDepth --;
   1381 
   1382         if (UnknownDepth == 0) {
   1383           InUnknownScope = FALSE;
   1384         }
   1385       } else {
   1386         if (Scope != 0) {
   1387           UnknownDepth ++;
   1388         }
   1389       }
   1390 
   1391       continue;
   1392     }
   1393 
   1394     if (IsUnKnownOpCode(Operand)) {
   1395       if (Scope != 0) {
   1396         InUnknownScope = TRUE;
   1397         UnknownDepth ++;
   1398       }
   1399 
   1400       continue;
   1401     }
   1402 
   1403     //
   1404     // If scope bit set, push onto scope stack
   1405     //
   1406     if (Scope != 0) {
   1407       PushScope (Operand);
   1408     }
   1409 
   1410     if (OpCodeDisabled) {
   1411       //
   1412       // DisableIf Expression is evaluated to be TRUE, try to find its end.
   1413       // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
   1414       //
   1415       if (Operand == EFI_IFR_DISABLE_IF_OP) {
   1416         DepthOfDisable++;
   1417       } else if (Operand == EFI_IFR_END_OP) {
   1418         Status = PopScope (&ScopeOpCode);
   1419         if (EFI_ERROR (Status)) {
   1420           return Status;
   1421         }
   1422 
   1423         if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
   1424           if (DepthOfDisable == 0) {
   1425             InScopeDisable = FALSE;
   1426             OpCodeDisabled = FALSE;
   1427           } else {
   1428             DepthOfDisable--;
   1429           }
   1430         }
   1431       }
   1432       continue;
   1433     }
   1434 
   1435     if (IsExpressionOpCode (Operand)) {
   1436       ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
   1437       mExpressionOpCodeIndex++;
   1438 
   1439       ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
   1440       ExpressionOpCode->Operand = Operand;
   1441       Value = &ExpressionOpCode->Value;
   1442 
   1443       switch (Operand) {
   1444       case EFI_IFR_EQ_ID_VAL_OP:
   1445         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1446 
   1447         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1448         CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
   1449         break;
   1450 
   1451       case EFI_IFR_EQ_ID_ID_OP:
   1452         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
   1453         CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
   1454         break;
   1455 
   1456       case EFI_IFR_EQ_ID_VAL_LIST_OP:
   1457         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1458         CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
   1459         ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
   1460         break;
   1461 
   1462       case EFI_IFR_TO_STRING_OP:
   1463       case EFI_IFR_FIND_OP:
   1464         ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
   1465         break;
   1466 
   1467       case EFI_IFR_STRING_REF1_OP:
   1468         Value->Type = EFI_IFR_TYPE_STRING;
   1469         CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
   1470         break;
   1471 
   1472       case EFI_IFR_RULE_REF_OP:
   1473         ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
   1474         break;
   1475 
   1476       case EFI_IFR_SPAN_OP:
   1477         ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
   1478         break;
   1479 
   1480       case EFI_IFR_THIS_OP:
   1481         ASSERT (ParentStatement != NULL);
   1482         ExpressionOpCode->QuestionId = ParentStatement->QuestionId;
   1483         break;
   1484 
   1485       case EFI_IFR_SECURITY_OP:
   1486         CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
   1487         break;
   1488 
   1489       case EFI_IFR_MATCH2_OP:
   1490         CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));
   1491         break;
   1492 
   1493       case EFI_IFR_GET_OP:
   1494       case EFI_IFR_SET_OP:
   1495         CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
   1496         if (TempVarstoreId != 0) {
   1497           if (FormSet->StorageListHead.ForwardLink != NULL) {
   1498             Link = GetFirstNode (&FormSet->StorageListHead);
   1499             while (!IsNull (&FormSet->StorageListHead, Link)) {
   1500               VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
   1501               if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
   1502                 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
   1503                 break;
   1504               }
   1505               Link = GetNextNode (&FormSet->StorageListHead, Link);
   1506             }
   1507           }
   1508           if (ExpressionOpCode->VarStorage == NULL) {
   1509             //
   1510             // VarStorage is not found.
   1511             //
   1512             return EFI_INVALID_PARAMETER;
   1513           }
   1514         }
   1515         ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
   1516         switch (ExpressionOpCode->ValueType) {
   1517         case EFI_IFR_TYPE_BOOLEAN:
   1518         case EFI_IFR_TYPE_NUM_SIZE_8:
   1519           ExpressionOpCode->ValueWidth = 1;
   1520           break;
   1521 
   1522         case EFI_IFR_TYPE_NUM_SIZE_16:
   1523         case EFI_IFR_TYPE_STRING:
   1524           ExpressionOpCode->ValueWidth = 2;
   1525           break;
   1526 
   1527         case EFI_IFR_TYPE_NUM_SIZE_32:
   1528           ExpressionOpCode->ValueWidth = 4;
   1529           break;
   1530 
   1531         case EFI_IFR_TYPE_NUM_SIZE_64:
   1532           ExpressionOpCode->ValueWidth = 8;
   1533           break;
   1534 
   1535         case EFI_IFR_TYPE_DATE:
   1536           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
   1537           break;
   1538 
   1539         case EFI_IFR_TYPE_TIME:
   1540           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
   1541           break;
   1542 
   1543         case EFI_IFR_TYPE_REF:
   1544           ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
   1545           break;
   1546 
   1547         case EFI_IFR_TYPE_OTHER:
   1548         case EFI_IFR_TYPE_UNDEFINED:
   1549         case EFI_IFR_TYPE_ACTION:
   1550         case EFI_IFR_TYPE_BUFFER:
   1551         default:
   1552           //
   1553           // Invalid value type for Get/Set opcode.
   1554           //
   1555           return EFI_INVALID_PARAMETER;
   1556         }
   1557         CopyMem (&ExpressionOpCode->VarStoreInfo.VarName,   &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName,   sizeof (EFI_STRING_ID));
   1558         CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
   1559         if ((ExpressionOpCode->VarStorage != NULL) &&
   1560             (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
   1561              ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
   1562           ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
   1563           if (ExpressionOpCode->ValueName == NULL) {
   1564             //
   1565             // String ID is invalid.
   1566             //
   1567             return EFI_INVALID_PARAMETER;
   1568           }
   1569         }
   1570         break;
   1571 
   1572       case EFI_IFR_QUESTION_REF1_OP:
   1573         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1574         break;
   1575 
   1576       case EFI_IFR_QUESTION_REF3_OP:
   1577         if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
   1578           CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
   1579 
   1580           if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
   1581             CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
   1582           }
   1583         }
   1584         break;
   1585 
   1586       //
   1587       // constant
   1588       //
   1589       case EFI_IFR_TRUE_OP:
   1590         Value->Type = EFI_IFR_TYPE_BOOLEAN;
   1591         Value->Value.b = TRUE;
   1592         break;
   1593 
   1594       case EFI_IFR_FALSE_OP:
   1595         Value->Type = EFI_IFR_TYPE_BOOLEAN;
   1596         Value->Value.b = FALSE;
   1597         break;
   1598 
   1599       case EFI_IFR_ONE_OP:
   1600         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1601         Value->Value.u8 = 1;
   1602         break;
   1603 
   1604       case EFI_IFR_ZERO_OP:
   1605         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1606         Value->Value.u8 = 0;
   1607         break;
   1608 
   1609       case EFI_IFR_ONES_OP:
   1610         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
   1611         Value->Value.u64 = 0xffffffffffffffffULL;
   1612         break;
   1613 
   1614       case EFI_IFR_UINT8_OP:
   1615         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1616         Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
   1617         break;
   1618 
   1619       case EFI_IFR_UINT16_OP:
   1620         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1621         CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
   1622         break;
   1623 
   1624       case EFI_IFR_UINT32_OP:
   1625         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
   1626         CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
   1627         break;
   1628 
   1629       case EFI_IFR_UINT64_OP:
   1630         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
   1631         CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
   1632         break;
   1633 
   1634       case EFI_IFR_UNDEFINED_OP:
   1635         Value->Type = EFI_IFR_TYPE_UNDEFINED;
   1636         break;
   1637 
   1638       case EFI_IFR_VERSION_OP:
   1639         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1640         Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
   1641         break;
   1642 
   1643       default:
   1644         break;
   1645       }
   1646       //
   1647       // Create sub expression nested in MAP opcode
   1648       //
   1649       if (CurrentExpression == NULL && MapScopeDepth > 0) {
   1650         CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   1651         ASSERT (MapExpressionList != NULL);
   1652         InsertTailList (MapExpressionList, &CurrentExpression->Link);
   1653         if (Scope == 0) {
   1654           SingleOpCodeExpression = TRUE;
   1655         }
   1656       }
   1657       ASSERT (CurrentExpression != NULL);
   1658       InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
   1659       if (Operand == EFI_IFR_MAP_OP) {
   1660         //
   1661         // Store current Map Expression List.
   1662         //
   1663         if (MapExpressionList != NULL) {
   1664           PushMapExpressionList (MapExpressionList);
   1665         }
   1666         //
   1667         // Initialize new Map Expression List.
   1668         //
   1669         MapExpressionList = &ExpressionOpCode->MapExpressionList;
   1670         InitializeListHead (MapExpressionList);
   1671         //
   1672         // Store current expression.
   1673         //
   1674         PushCurrentExpression (CurrentExpression);
   1675         CurrentExpression = NULL;
   1676         MapScopeDepth ++;
   1677       } else if (SingleOpCodeExpression) {
   1678         //
   1679         // There are two cases to indicate the end of an Expression:
   1680         // for single OpCode expression: one Expression OpCode
   1681         // for expression consists of more than one OpCode: EFI_IFR_END
   1682         //
   1683         SingleOpCodeExpression = FALSE;
   1684 
   1685         if (InScopeDisable && CurrentForm == NULL) {
   1686           //
   1687           // This is DisableIf expression for Form, it should be a constant expression
   1688           //
   1689           Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
   1690           if (EFI_ERROR (Status)) {
   1691             return Status;
   1692           }
   1693 
   1694           OpCodeDisabled = IsTrue(&CurrentExpression->Result);
   1695         }
   1696 
   1697         CurrentExpression = NULL;
   1698       }
   1699 
   1700       continue;
   1701     }
   1702 
   1703     //
   1704     // Parse the Opcode
   1705     //
   1706     switch (Operand) {
   1707 
   1708     case EFI_IFR_FORM_SET_OP:
   1709       //
   1710       // Check the formset GUID
   1711       //
   1712       if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
   1713         return EFI_INVALID_PARAMETER;
   1714       }
   1715 
   1716       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
   1717       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));
   1718       FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset
   1719 
   1720       if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
   1721         //
   1722         // The formset OpCode contains ClassGuid
   1723         //
   1724         FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
   1725         CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
   1726       }
   1727       break;
   1728 
   1729     case EFI_IFR_FORM_OP:
   1730       //
   1731       // Create a new Form for this FormSet
   1732       //
   1733       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
   1734       ASSERT (CurrentForm != NULL);
   1735       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
   1736       InitializeListHead (&CurrentForm->ExpressionListHead);
   1737       InitializeListHead (&CurrentForm->StatementListHead);
   1738       InitializeListHead (&CurrentForm->ConfigRequestHead);
   1739       InitializeListHead (&CurrentForm->FormViewListHead);
   1740 
   1741       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
   1742       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));
   1743       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
   1744 
   1745       ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
   1746       if ( ConditionalExprCount > 0) {
   1747         //
   1748         // Form is inside of suppressif
   1749         //
   1750         CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
   1751                                                  (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
   1752         ASSERT (CurrentForm->SuppressExpression != NULL);
   1753         CurrentForm->SuppressExpression->Count     = (UINTN) ConditionalExprCount;
   1754         CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
   1755         CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
   1756       }
   1757 
   1758       if (Scope != 0) {
   1759         //
   1760         // Enter scope of a Form, suppressif will be used for Question or Option
   1761         //
   1762         SuppressForQuestion = TRUE;
   1763       }
   1764 
   1765       //
   1766       // Insert into Form list of this FormSet
   1767       //
   1768       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
   1769       break;
   1770 
   1771     case EFI_IFR_FORM_MAP_OP:
   1772       //
   1773       // Create a new Form for this FormSet
   1774       //
   1775       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
   1776       ASSERT (CurrentForm != NULL);
   1777       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
   1778       InitializeListHead (&CurrentForm->ExpressionListHead);
   1779       InitializeListHead (&CurrentForm->StatementListHead);
   1780       InitializeListHead (&CurrentForm->ConfigRequestHead);
   1781       InitializeListHead (&CurrentForm->FormViewListHead);
   1782 
   1783       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
   1784 
   1785       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
   1786       //
   1787       // FormMap Form must contain at least one Map Method.
   1788       //
   1789       if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
   1790         return EFI_INVALID_PARAMETER;
   1791       }
   1792       //
   1793       // Try to find the standard form map method.
   1794       //
   1795       while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
   1796         if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
   1797           CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
   1798           CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
   1799           break;
   1800         }
   1801         MapMethod ++;
   1802       }
   1803       //
   1804       // If the standard form map method is not found, the first map method title will be used.
   1805       //
   1806       if (CurrentForm->FormTitle == 0) {
   1807         MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
   1808         CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
   1809       }
   1810 
   1811       ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
   1812       if ( ConditionalExprCount > 0) {
   1813         //
   1814         // Form is inside of suppressif
   1815         //
   1816         CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
   1817                                                  (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
   1818         ASSERT (CurrentForm->SuppressExpression != NULL);
   1819         CurrentForm->SuppressExpression->Count     = (UINTN) ConditionalExprCount;
   1820         CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
   1821         CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
   1822       }
   1823 
   1824       if (Scope != 0) {
   1825         //
   1826         // Enter scope of a Form, suppressif will be used for Question or Option
   1827         //
   1828         SuppressForQuestion = TRUE;
   1829       }
   1830 
   1831       //
   1832       // Insert into Form list of this FormSet
   1833       //
   1834       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
   1835       break;
   1836 
   1837     //
   1838     // Storage
   1839     //
   1840     case EFI_IFR_VARSTORE_OP:
   1841       //
   1842       // Create a buffer Storage for this FormSet
   1843       //
   1844       Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
   1845       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
   1846       break;
   1847 
   1848     case EFI_IFR_VARSTORE_NAME_VALUE_OP:
   1849       //
   1850       // Create a name/value Storage for this FormSet
   1851       //
   1852       Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
   1853       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
   1854       break;
   1855 
   1856     case EFI_IFR_VARSTORE_EFI_OP:
   1857       //
   1858       // Create a EFI variable Storage for this FormSet
   1859       //
   1860       if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
   1861         //
   1862         // Create efi varstore with format follow UEFI spec before 2.3.1.
   1863         //
   1864         Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
   1865       } else {
   1866         //
   1867         // Create efi varstore with format follow UEFI spec 2.3.1 and later.
   1868         //
   1869         Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
   1870       }
   1871       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
   1872       break;
   1873 
   1874     //
   1875     // DefaultStore
   1876     //
   1877     case EFI_IFR_DEFAULTSTORE_OP:
   1878       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
   1879       ASSERT (DefaultStore != NULL);
   1880       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
   1881 
   1882       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));
   1883       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
   1884 
   1885       //
   1886       // Insert to DefaultStore list of this Formset
   1887       //
   1888       InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
   1889       break;
   1890 
   1891     //
   1892     // Statements
   1893     //
   1894     case EFI_IFR_SUBTITLE_OP:
   1895       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   1896       ASSERT (CurrentStatement != NULL);
   1897 
   1898       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
   1899       CurrentStatement->FakeQuestionId = mUsedQuestionId++;
   1900       break;
   1901 
   1902     case EFI_IFR_TEXT_OP:
   1903       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   1904       ASSERT (CurrentStatement != NULL);
   1905       CurrentStatement->FakeQuestionId = mUsedQuestionId++;
   1906       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
   1907       break;
   1908 
   1909     case EFI_IFR_RESET_BUTTON_OP:
   1910       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   1911       ASSERT (CurrentStatement != NULL);
   1912       CurrentStatement->FakeQuestionId = mUsedQuestionId++;
   1913       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
   1914       break;
   1915 
   1916     //
   1917     // Questions
   1918     //
   1919     case EFI_IFR_ACTION_OP:
   1920       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   1921       ASSERT (CurrentStatement != NULL);
   1922       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
   1923 
   1924       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
   1925         //
   1926         // No QuestionConfig present, so no configuration string will be processed
   1927         //
   1928         CurrentStatement->QuestionConfig = 0;
   1929       } else {
   1930         CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
   1931       }
   1932       break;
   1933 
   1934     case EFI_IFR_REF_OP:
   1935       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   1936       ASSERT (CurrentStatement != NULL);
   1937       Value = &CurrentStatement->HiiValue;
   1938       Value->Type = EFI_IFR_TYPE_REF;
   1939       if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
   1940         CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
   1941 
   1942         if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
   1943           CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
   1944 
   1945           if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
   1946             CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
   1947 
   1948             if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
   1949               CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
   1950             }
   1951           }
   1952         }
   1953       }
   1954       CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
   1955       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   1956       break;
   1957 
   1958     case EFI_IFR_ONE_OF_OP:
   1959     case EFI_IFR_NUMERIC_OP:
   1960       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   1961       ASSERT(CurrentStatement != NULL);
   1962 
   1963       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
   1964       Value = &CurrentStatement->HiiValue;
   1965 
   1966       switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
   1967       case EFI_IFR_NUMERIC_SIZE_1:
   1968         CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
   1969         CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
   1970         CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
   1971         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
   1972         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
   1973         break;
   1974 
   1975       case EFI_IFR_NUMERIC_SIZE_2:
   1976         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
   1977         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
   1978         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));
   1979         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
   1980         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
   1981         break;
   1982 
   1983       case EFI_IFR_NUMERIC_SIZE_4:
   1984         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
   1985         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
   1986         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));
   1987         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
   1988         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
   1989         break;
   1990 
   1991       case EFI_IFR_NUMERIC_SIZE_8:
   1992         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
   1993         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
   1994         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));
   1995         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
   1996         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
   1997         break;
   1998 
   1999       default:
   2000         break;
   2001       }
   2002 
   2003       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2004 
   2005       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
   2006         SuppressForOption = TRUE;
   2007       }
   2008       break;
   2009 
   2010     case EFI_IFR_ORDERED_LIST_OP:
   2011       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2012       ASSERT(CurrentStatement != NULL);
   2013 
   2014       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
   2015       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
   2016 
   2017       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
   2018       CurrentStatement->BufferValue = NULL;
   2019 
   2020       if (Scope != 0) {
   2021         SuppressForOption = TRUE;
   2022       }
   2023       break;
   2024 
   2025     case EFI_IFR_CHECKBOX_OP:
   2026       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2027       ASSERT(CurrentStatement != NULL);
   2028 
   2029       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
   2030       CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
   2031       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
   2032 
   2033       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2034 
   2035       break;
   2036 
   2037     case EFI_IFR_STRING_OP:
   2038       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2039       ASSERT (CurrentStatement != NULL);
   2040       //
   2041       // MinSize is the minimum number of characters that can be accepted for this opcode,
   2042       // MaxSize is the maximum number of characters that can be accepted for this opcode.
   2043       // The characters are stored as Unicode, so the storage width should multiply 2.
   2044       //
   2045       CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
   2046       CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
   2047       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
   2048       CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
   2049 
   2050       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
   2051       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
   2052       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
   2053 
   2054       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2055       break;
   2056 
   2057     case EFI_IFR_PASSWORD_OP:
   2058       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2059       ASSERT (CurrentStatement != NULL);
   2060       //
   2061       // MinSize is the minimum number of characters that can be accepted for this opcode,
   2062       // MaxSize is the maximum number of characters that can be accepted for this opcode.
   2063       // The characters are stored as Unicode, so the storage width should multiply 2.
   2064       //
   2065       CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
   2066       CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
   2067       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
   2068 
   2069       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
   2070       CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
   2071       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
   2072 
   2073       InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2074       break;
   2075 
   2076     case EFI_IFR_DATE_OP:
   2077       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2078       ASSERT(CurrentStatement != NULL);
   2079 
   2080       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
   2081       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
   2082 
   2083       if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
   2084         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
   2085 
   2086         InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2087       } else {
   2088         //
   2089         // Don't assign storage for RTC type of date/time
   2090         //
   2091         CurrentStatement->Storage = NULL;
   2092         CurrentStatement->StorageWidth = 0;
   2093       }
   2094       break;
   2095 
   2096     case EFI_IFR_TIME_OP:
   2097       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
   2098       ASSERT(CurrentStatement != NULL);
   2099 
   2100       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
   2101       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
   2102 
   2103       if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
   2104         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
   2105 
   2106         InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
   2107       } else {
   2108         //
   2109         // Don't assign storage for RTC type of date/time
   2110         //
   2111         CurrentStatement->Storage = NULL;
   2112         CurrentStatement->StorageWidth = 0;
   2113       }
   2114       break;
   2115 
   2116     //
   2117     // Default
   2118     //
   2119     case EFI_IFR_DEFAULT_OP:
   2120       //
   2121       // EFI_IFR_DEFAULT appear in scope of a Question,
   2122       // It creates a default value for the current question.
   2123       // A Question may have more than one Default value which have different default types.
   2124       //
   2125       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
   2126       ASSERT (CurrentDefault != NULL);
   2127       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
   2128 
   2129       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
   2130       CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
   2131       if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {
   2132         CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
   2133         CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);
   2134         ASSERT (CurrentDefault->Value.Buffer != NULL);
   2135       } else {
   2136         CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
   2137         ExtendValueToU64 (&CurrentDefault->Value);
   2138       }
   2139 
   2140       //
   2141       // Insert to Default Value list of current Question
   2142       //
   2143       InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
   2144 
   2145       if (Scope != 0) {
   2146         InScopeDefault = TRUE;
   2147       }
   2148       break;
   2149 
   2150     //
   2151     // Option
   2152     //
   2153     case EFI_IFR_ONE_OF_OPTION_OP:
   2154       ASSERT (ParentStatement != NULL);
   2155       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)) {
   2156         //
   2157         // It's keep the default value for ordered list opcode.
   2158         //
   2159         CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
   2160         ASSERT (CurrentDefault != NULL);
   2161         CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
   2162 
   2163         CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;
   2164         if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
   2165           CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
   2166         } else {
   2167           CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
   2168         }
   2169 
   2170         CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
   2171         CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);
   2172         ASSERT (CurrentDefault->Value.Buffer != NULL);
   2173 
   2174         //
   2175         // Insert to Default Value list of current Question
   2176         //
   2177         InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
   2178         break;
   2179       }
   2180 
   2181       //
   2182       // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
   2183       // It create a selection for use in current Question.
   2184       //
   2185       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
   2186       ASSERT (CurrentOption != NULL);
   2187       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
   2188       CurrentOption->OpCode    = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
   2189 
   2190       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
   2191       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
   2192       CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
   2193       CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
   2194       ExtendValueToU64 (&CurrentOption->Value);
   2195 
   2196       ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
   2197       if ( ConditionalExprCount > 0) {
   2198         //
   2199         // Form is inside of suppressif
   2200         //
   2201         CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
   2202                                                  (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
   2203         ASSERT (CurrentOption->SuppressExpression != NULL);
   2204         CurrentOption->SuppressExpression->Count     = (UINTN) ConditionalExprCount;
   2205         CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
   2206         CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
   2207       }
   2208 
   2209       //
   2210       // Insert to Option list of current Question
   2211       //
   2212       InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);
   2213       //
   2214       // Now we know the Storage width of nested Ordered List
   2215       //
   2216       if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {
   2217         Width = 1;
   2218         switch (CurrentOption->Value.Type) {
   2219         case EFI_IFR_TYPE_NUM_SIZE_8:
   2220           Width = 1;
   2221           break;
   2222 
   2223         case EFI_IFR_TYPE_NUM_SIZE_16:
   2224           Width = 2;
   2225           break;
   2226 
   2227         case EFI_IFR_TYPE_NUM_SIZE_32:
   2228           Width = 4;
   2229           break;
   2230 
   2231         case EFI_IFR_TYPE_NUM_SIZE_64:
   2232           Width = 8;
   2233           break;
   2234 
   2235         default:
   2236           //
   2237           // Invalid type for Ordered List
   2238           //
   2239           break;
   2240         }
   2241 
   2242         ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);
   2243         ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);
   2244         ParentStatement->ValueType = CurrentOption->Value.Type;
   2245         if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
   2246           ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;
   2247           ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;
   2248         }
   2249 
   2250         InitializeRequestElement (FormSet, ParentStatement, CurrentForm);
   2251       }
   2252       break;
   2253 
   2254     //
   2255     // Conditional
   2256     //
   2257     case EFI_IFR_NO_SUBMIT_IF_OP:
   2258     case EFI_IFR_INCONSISTENT_IF_OP:
   2259       //
   2260       // Create an Expression node
   2261       //
   2262       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2263       CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
   2264 
   2265       if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
   2266         CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
   2267         InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);
   2268       } else {
   2269         CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
   2270         InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);
   2271       }
   2272 
   2273       //
   2274       // Take a look at next OpCode to see whether current expression consists
   2275       // of single OpCode
   2276       //
   2277       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2278         SingleOpCodeExpression = TRUE;
   2279       }
   2280       break;
   2281 
   2282     case EFI_IFR_WARNING_IF_OP:
   2283       //
   2284       // Create an Expression node
   2285       //
   2286       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2287       CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));
   2288       CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;
   2289       CurrentExpression->Type    = EFI_HII_EXPRESSION_WARNING_IF;
   2290       InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);
   2291 
   2292       //
   2293       // Take a look at next OpCode to see whether current expression consists
   2294       // of single OpCode
   2295       //
   2296       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2297         SingleOpCodeExpression = TRUE;
   2298       }
   2299       break;
   2300 
   2301     case EFI_IFR_SUPPRESS_IF_OP:
   2302       //
   2303       // Question and Option will appear in scope of this OpCode
   2304       //
   2305       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2306       CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
   2307 
   2308       if (CurrentForm == NULL) {
   2309         InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
   2310       } else {
   2311         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2312       }
   2313 
   2314       if (SuppressForOption) {
   2315         PushConditionalExpression(CurrentExpression, ExpressOption);
   2316       } else if (SuppressForQuestion) {
   2317         PushConditionalExpression(CurrentExpression, ExpressStatement);
   2318       } else {
   2319         PushConditionalExpression(CurrentExpression, ExpressForm);
   2320       }
   2321 
   2322       //
   2323       // Take a look at next OpCode to see whether current expression consists
   2324       // of single OpCode
   2325       //
   2326       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2327         SingleOpCodeExpression = TRUE;
   2328       }
   2329       break;
   2330 
   2331     case EFI_IFR_GRAY_OUT_IF_OP:
   2332       //
   2333       // Questions will appear in scope of this OpCode
   2334       //
   2335       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2336       CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
   2337       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2338       PushConditionalExpression(CurrentExpression, ExpressStatement);
   2339 
   2340       //
   2341       // Take a look at next OpCode to see whether current expression consists
   2342       // of single OpCode
   2343       //
   2344       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2345         SingleOpCodeExpression = TRUE;
   2346       }
   2347       break;
   2348 
   2349     case EFI_IFR_DISABLE_IF_OP:
   2350       //
   2351       // The DisableIf expression should only rely on constant, so it could be
   2352       // evaluated at initialization and it will not be queued
   2353       //
   2354       CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
   2355       ASSERT (CurrentExpression != NULL);
   2356       CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
   2357       CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
   2358       InitializeListHead (&CurrentExpression->OpCodeListHead);
   2359 
   2360       if (CurrentForm != NULL) {
   2361         //
   2362         // This is DisableIf for Question, enqueue it to Form expression list
   2363         //
   2364         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2365         PushConditionalExpression(CurrentExpression, ExpressStatement);
   2366       }
   2367 
   2368       OpCodeDisabled  = FALSE;
   2369       InScopeDisable  = TRUE;
   2370       //
   2371       // Take a look at next OpCode to see whether current expression consists
   2372       // of single OpCode
   2373       //
   2374       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2375         SingleOpCodeExpression = TRUE;
   2376       }
   2377       break;
   2378 
   2379     //
   2380     // Expression
   2381     //
   2382     case EFI_IFR_VALUE_OP:
   2383       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2384       CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
   2385       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2386 
   2387       if (InScopeDefault) {
   2388         //
   2389         // Used for default (EFI_IFR_DEFAULT)
   2390         //
   2391         CurrentDefault->ValueExpression = CurrentExpression;
   2392       } else {
   2393         //
   2394         // If used for a question, then the question will be read-only
   2395         //
   2396         //
   2397         // Make sure CurrentStatement is not NULL.
   2398         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2399         // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
   2400         //
   2401         ASSERT (ParentStatement != NULL);
   2402         ParentStatement->ValueExpression = CurrentExpression;
   2403       }
   2404 
   2405       //
   2406       // Take a look at next OpCode to see whether current expression consists
   2407       // of single OpCode
   2408       //
   2409       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2410         SingleOpCodeExpression = TRUE;
   2411       }
   2412       break;
   2413 
   2414     case EFI_IFR_RULE_OP:
   2415       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2416       CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
   2417 
   2418       CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
   2419       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2420 
   2421       //
   2422       // Take a look at next OpCode to see whether current expression consists
   2423       // of single OpCode
   2424       //
   2425       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2426         SingleOpCodeExpression = TRUE;
   2427       }
   2428       break;
   2429 
   2430     case EFI_IFR_READ_OP:
   2431       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2432       CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
   2433       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2434 
   2435       //
   2436       // Make sure CurrentStatement is not NULL.
   2437       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2438       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
   2439       //
   2440       ASSERT (ParentStatement != NULL);
   2441       ParentStatement->ReadExpression = CurrentExpression;
   2442 
   2443       //
   2444       // Take a look at next OpCode to see whether current expression consists
   2445       // of single OpCode
   2446       //
   2447       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2448         SingleOpCodeExpression = TRUE;
   2449       }
   2450       break;
   2451 
   2452     case EFI_IFR_WRITE_OP:
   2453       CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
   2454       CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
   2455       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
   2456 
   2457       //
   2458       // Make sure CurrentStatement is not NULL.
   2459       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2460       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
   2461       //
   2462       ASSERT (ParentStatement != NULL);
   2463       ParentStatement->WriteExpression = CurrentExpression;
   2464 
   2465       //
   2466       // Take a look at next OpCode to see whether current expression consists
   2467       // of single OpCode
   2468       //
   2469       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
   2470         SingleOpCodeExpression = TRUE;
   2471       }
   2472       break;
   2473 
   2474     //
   2475     // Image
   2476     //
   2477     case EFI_IFR_IMAGE_OP:
   2478       //
   2479       // Get ScopeOpcode from top of stack
   2480       //
   2481       PopScope (&ScopeOpCode);
   2482       PushScope (ScopeOpCode);
   2483 
   2484       switch (ScopeOpCode) {
   2485       case EFI_IFR_FORM_SET_OP:
   2486         ImageId = &FormSet->ImageId;
   2487         break;
   2488 
   2489       case EFI_IFR_FORM_OP:
   2490       case EFI_IFR_FORM_MAP_OP:
   2491         ASSERT (CurrentForm != NULL);
   2492         ImageId = &CurrentForm->ImageId;
   2493         break;
   2494 
   2495       case EFI_IFR_ONE_OF_OPTION_OP:
   2496         ASSERT (CurrentOption != NULL);
   2497         ImageId = &CurrentOption->ImageId;
   2498         break;
   2499 
   2500       default:
   2501         //
   2502         // Make sure CurrentStatement is not NULL.
   2503         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   2504         // file is wrongly generated by tools such as VFR Compiler.
   2505         //
   2506         ASSERT (ParentStatement != NULL);
   2507         ImageId = &ParentStatement->ImageId;
   2508         break;
   2509       }
   2510 
   2511       ASSERT (ImageId != NULL);
   2512       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
   2513       break;
   2514 
   2515     //
   2516     // Refresh
   2517     //
   2518     case EFI_IFR_REFRESH_OP:
   2519       ASSERT (ParentStatement != NULL);
   2520       ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
   2521       break;
   2522 
   2523     //
   2524     // Refresh guid.
   2525     //
   2526     case EFI_IFR_REFRESH_ID_OP:
   2527       //
   2528       // Get ScopeOpcode from top of stack
   2529       //
   2530       PopScope (&ScopeOpCode);
   2531       PushScope (ScopeOpCode);
   2532 
   2533       switch (ScopeOpCode) {
   2534       case EFI_IFR_FORM_OP:
   2535       case EFI_IFR_FORM_MAP_OP:
   2536         ASSERT (CurrentForm != NULL);
   2537         CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
   2538         break;
   2539 
   2540       default:
   2541         ASSERT (ParentStatement != NULL);
   2542         CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
   2543         break;
   2544       }
   2545       break;
   2546 
   2547     //
   2548     // Modal tag
   2549     //
   2550     case EFI_IFR_MODAL_TAG_OP:
   2551       ASSERT (CurrentForm != NULL);
   2552       CurrentForm->ModalForm = TRUE;
   2553       break;
   2554 
   2555     //
   2556     // Lock tag, used by form and statement.
   2557     //
   2558     case EFI_IFR_LOCKED_OP:
   2559       //
   2560       // Get ScopeOpcode from top of stack
   2561       //
   2562       PopScope (&ScopeOpCode);
   2563       PushScope (ScopeOpCode);
   2564       switch (ScopeOpCode) {
   2565       case EFI_IFR_FORM_OP:
   2566       case EFI_IFR_FORM_MAP_OP:
   2567         ASSERT (CurrentForm != NULL);
   2568         CurrentForm->Locked = TRUE;
   2569         break;
   2570 
   2571       default:
   2572         ASSERT (ParentStatement != NULL);
   2573         ParentStatement->Locked = TRUE;
   2574       }
   2575       break;
   2576 
   2577     //
   2578     // Vendor specific
   2579     //
   2580     case EFI_IFR_GUID_OP:
   2581       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
   2582       break;
   2583 
   2584     //
   2585     // Scope End
   2586     //
   2587     case EFI_IFR_END_OP:
   2588       Status = PopScope (&ScopeOpCode);
   2589       if (EFI_ERROR (Status)) {
   2590         ResetScopeStack ();
   2591         return Status;
   2592       }
   2593 
   2594       //
   2595       // Parent statement end tag found, update ParentStatement info.
   2596       //
   2597       if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {
   2598         ParentStatement  = ParentStatement->ParentStatement;
   2599       }
   2600 
   2601       switch (ScopeOpCode) {
   2602       case EFI_IFR_FORM_SET_OP:
   2603         //
   2604         // End of FormSet, update FormSet IFR binary length
   2605         // to stop parsing substantial OpCodes
   2606         //
   2607         FormSet->IfrBinaryLength = OpCodeOffset;
   2608         break;
   2609 
   2610       case EFI_IFR_FORM_OP:
   2611       case EFI_IFR_FORM_MAP_OP:
   2612         //
   2613         // End of Form
   2614         //
   2615         CurrentForm = NULL;
   2616         SuppressForQuestion = FALSE;
   2617         break;
   2618 
   2619       case EFI_IFR_ONE_OF_OPTION_OP:
   2620         //
   2621         // End of Option
   2622         //
   2623         CurrentOption = NULL;
   2624         break;
   2625 
   2626       case EFI_IFR_NO_SUBMIT_IF_OP:
   2627       case EFI_IFR_INCONSISTENT_IF_OP:
   2628       case EFI_IFR_WARNING_IF_OP:
   2629         //
   2630         // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
   2631         //
   2632         break;
   2633 
   2634       case EFI_IFR_SUPPRESS_IF_OP:
   2635         if (SuppressForOption) {
   2636           PopConditionalExpression(ExpressOption);
   2637         } else if (SuppressForQuestion) {
   2638           PopConditionalExpression(ExpressStatement);
   2639         } else {
   2640           PopConditionalExpression(ExpressForm);
   2641         }
   2642         break;
   2643 
   2644       case EFI_IFR_GRAY_OUT_IF_OP:
   2645         PopConditionalExpression(ExpressStatement);
   2646         break;
   2647 
   2648       case EFI_IFR_DISABLE_IF_OP:
   2649         if (CurrentForm != NULL) {
   2650           PopConditionalExpression(ExpressStatement);
   2651         }
   2652         InScopeDisable = FALSE;
   2653         OpCodeDisabled = FALSE;
   2654         break;
   2655 
   2656       case EFI_IFR_ONE_OF_OP:
   2657       case EFI_IFR_ORDERED_LIST_OP:
   2658         SuppressForOption = FALSE;
   2659         break;
   2660 
   2661       case EFI_IFR_DEFAULT_OP:
   2662         InScopeDefault = FALSE;
   2663         break;
   2664 
   2665       case EFI_IFR_MAP_OP:
   2666         //
   2667         // Get current Map Expression List.
   2668         //
   2669         Status = PopMapExpressionList ((VOID **) &MapExpressionList);
   2670         if (Status == EFI_ACCESS_DENIED) {
   2671           MapExpressionList = NULL;
   2672         }
   2673         //
   2674         // Get current expression.
   2675         //
   2676         Status = PopCurrentExpression ((VOID **) &CurrentExpression);
   2677         ASSERT_EFI_ERROR (Status);
   2678         ASSERT (MapScopeDepth > 0);
   2679         MapScopeDepth --;
   2680         break;
   2681 
   2682       default:
   2683         if (IsExpressionOpCode (ScopeOpCode)) {
   2684           if (InScopeDisable && CurrentForm == NULL) {
   2685             //
   2686             // This is DisableIf expression for Form, it should be a constant expression
   2687             //
   2688             ASSERT (CurrentExpression != NULL);
   2689             Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
   2690             if (EFI_ERROR (Status)) {
   2691               return Status;
   2692             }
   2693 
   2694             OpCodeDisabled = IsTrue (&CurrentExpression->Result);
   2695 
   2696             //
   2697             // DisableIf Expression is only used once and not queued, free it
   2698             //
   2699             DestroyExpression (CurrentExpression);
   2700           }
   2701 
   2702           //
   2703           // End of current Expression
   2704           //
   2705           CurrentExpression = NULL;
   2706         }
   2707         break;
   2708       }
   2709       break;
   2710 
   2711     default:
   2712       break;
   2713     }
   2714 
   2715     if (IsStatementOpCode(Operand)) {
   2716       CurrentStatement->ParentStatement = ParentStatement;
   2717       if (Scope != 0) {
   2718         //
   2719         // Scope != 0, other statements or options may nest in this statement.
   2720         // Update the ParentStatement info.
   2721         //
   2722         ParentStatement = CurrentStatement;
   2723       }
   2724     }
   2725   }
   2726 
   2727   return EFI_SUCCESS;
   2728 }
   2729