Home | History | Annotate | Download | only in FrameworkHiiOnUefiHiiThunk
      1 /** @file
      2 Parser for IFR binary encoding.
      3 
      4 Copyright (c) 2008 - 2014, 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 "HiiDatabase.h"
     16 
     17 #include "UefiIfrParserExpression.h"
     18 
     19 UINT16           mStatementIndex;
     20 
     21 BOOLEAN          mInScopeSubtitle;
     22 BOOLEAN          mInScopeSuppress;
     23 BOOLEAN          mInScopeGrayOut;
     24 
     25 EFI_GUID  mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID;
     26 extern EFI_GUID mTianoHiiIfrGuid;
     27 
     28 /**
     29   Find the question's OneOfOptionMap list in FormSet
     30   based on the input question Id.
     31 
     32   @param FormSet     FormSet context.
     33   @param QuestionId  Unique ID to specicy the question in FormSet.
     34 
     35   @return the found OneOfOptionMap list. If not found, NULL will return.
     36 **/
     37 LIST_ENTRY *
     38 GetOneOfOptionMapEntryListHead (
     39   IN CONST FORM_BROWSER_FORMSET  *FormSet,
     40   IN       UINT16                 QuestionId
     41   )
     42 {
     43   LIST_ENTRY            *Link;
     44   ONE_OF_OPTION_MAP     *Map;
     45 
     46   Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);
     47 
     48   while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {
     49     Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);
     50     if (QuestionId == Map->QuestionId) {
     51       return &Map->OneOfOptionMapEntryListHead;
     52     }
     53     Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);
     54   }
     55 
     56   return NULL;
     57 }
     58 
     59 /**
     60   Free OneOfOption map list.
     61 
     62   @param OneOfOptionMapListHead Pointer to list header of OneOfOptionMap list.
     63 
     64 **/
     65 VOID
     66 DestoryOneOfOptionMap (
     67   IN LIST_ENTRY     *OneOfOptionMapListHead
     68   )
     69 {
     70   ONE_OF_OPTION_MAP         *Map;
     71   ONE_OF_OPTION_MAP_ENTRY   *MapEntry;
     72   LIST_ENTRY                *Link;
     73   LIST_ENTRY                *Link2;
     74 
     75   while (!IsListEmpty (OneOfOptionMapListHead)) {
     76     Link = GetFirstNode (OneOfOptionMapListHead);
     77 
     78     Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);
     79 
     80     while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {
     81       Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);
     82 
     83       MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);
     84 
     85       RemoveEntryList (Link2);
     86 
     87       FreePool (MapEntry);
     88     }
     89 
     90     RemoveEntryList (Link);
     91     FreePool (Map);
     92   }
     93 }
     94 
     95 
     96 /**
     97   Initialize Statement header members.
     98 
     99   @param  OpCodeData             Pointer of the raw OpCode data.
    100   @param  FormSet                Pointer of the current FormSe.
    101   @param  Form                   Pointer of the current Form.
    102 
    103   @return The Statement.
    104 
    105 **/
    106 FORM_BROWSER_STATEMENT *
    107 CreateStatement (
    108   IN UINT8                        *OpCodeData,
    109   IN OUT FORM_BROWSER_FORMSET     *FormSet,
    110   IN OUT FORM_BROWSER_FORM        *Form
    111   )
    112 {
    113   FORM_BROWSER_STATEMENT    *Statement;
    114   EFI_IFR_STATEMENT_HEADER  *StatementHdr;
    115 
    116   if (Form == NULL) {
    117     //
    118     // We are currently not in a Form Scope, so just skip this Statement
    119     //
    120     return NULL;
    121   }
    122 
    123   Statement = &FormSet->StatementBuffer[mStatementIndex];
    124   mStatementIndex++;
    125 
    126   InitializeListHead (&Statement->DefaultListHead);
    127   InitializeListHead (&Statement->OptionListHead);
    128 
    129   Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
    130 
    131   Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
    132 
    133   StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
    134   CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
    135   CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
    136 
    137   Statement->InSubtitle = mInScopeSubtitle;
    138 
    139   //
    140   // Insert this Statement into current Form
    141   //
    142   InsertTailList (&Form->StatementListHead, &Statement->Link);
    143 
    144   return Statement;
    145 }
    146 
    147 /**
    148   Initialize Question's members.
    149 
    150   @param  OpCodeData             Pointer of the raw OpCode data.
    151   @param  FormSet                Pointer of the current FormSet.
    152   @param  Form                   Pointer of the current Form.
    153 
    154   @return The Question.
    155 
    156 **/
    157 FORM_BROWSER_STATEMENT *
    158 CreateQuestion (
    159   IN UINT8                        *OpCodeData,
    160   IN OUT FORM_BROWSER_FORMSET     *FormSet,
    161   IN OUT FORM_BROWSER_FORM        *Form
    162   )
    163 {
    164   FORM_BROWSER_STATEMENT   *Statement;
    165   EFI_IFR_QUESTION_HEADER  *QuestionHdr;
    166   LIST_ENTRY               *Link;
    167   FORMSET_STORAGE          *Storage;
    168 
    169   Statement = CreateStatement (OpCodeData, FormSet, Form);
    170   if (Statement == NULL) {
    171     return NULL;
    172   }
    173 
    174   QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
    175   CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
    176   CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
    177   CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
    178 
    179   if (FormSet->MaxQuestionId < QuestionHdr->QuestionId) {
    180     FormSet->MaxQuestionId = QuestionHdr->QuestionId;
    181   }
    182 
    183   Statement->QuestionFlags = QuestionHdr->Flags;
    184 
    185   if (Statement->VarStoreId == 0) {
    186     //
    187     // VarStoreId of zero indicates no variable storage
    188     //
    189     return Statement;
    190   }
    191 
    192   //
    193   // Find Storage for this Question
    194   //
    195   Link = GetFirstNode (&FormSet->StorageListHead);
    196   while (!IsNull (&FormSet->StorageListHead, Link)) {
    197     Storage = FORMSET_STORAGE_FROM_LINK (Link);
    198 
    199     if (Storage->VarStoreId == Statement->VarStoreId) {
    200       Statement->Storage = Storage;
    201       break;
    202     }
    203 
    204     Link = GetNextNode (&FormSet->StorageListHead, Link);
    205   }
    206   ASSERT (Statement->Storage != NULL);
    207 
    208   return Statement;
    209 }
    210 
    211 /**
    212   Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
    213 
    214   @param  FormSet                Pointer of the current FormSet
    215 
    216   @return Pointer to a FORMSET_STORAGE data structure.
    217 
    218 **/
    219 FORMSET_STORAGE *
    220 CreateStorage (
    221   IN FORM_BROWSER_FORMSET  *FormSet
    222   )
    223 {
    224   FORMSET_STORAGE  *Storage;
    225 
    226   Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
    227   ASSERT (Storage != NULL);
    228   Storage->Signature = FORMSET_STORAGE_SIGNATURE;
    229   InsertTailList (&FormSet->StorageListHead, &Storage->Link);
    230 
    231   return Storage;
    232 }
    233 
    234 /**
    235   Free resources of a storage
    236 
    237   @param  Storage                Pointer of the storage
    238 
    239   @return None.
    240 
    241 **/
    242 VOID
    243 DestroyStorage (
    244   IN FORMSET_STORAGE   *Storage
    245   )
    246 {
    247   if (Storage == NULL) {
    248     return;
    249   }
    250 
    251   if (Storage->Name!= NULL) {
    252     FreePool (Storage->Name);
    253   }
    254 
    255   FreePool (Storage);
    256 }
    257 
    258 
    259 /**
    260   Free resources of a Statement
    261 
    262   @param  Statement              Pointer of the Statement
    263 
    264   @return None.
    265 
    266 **/
    267 VOID
    268 DestroyStatement (
    269   IN OUT FORM_BROWSER_STATEMENT  *Statement
    270   )
    271 {
    272   LIST_ENTRY        *Link;
    273   QUESTION_DEFAULT  *Default;
    274   QUESTION_OPTION   *Option;
    275 
    276   //
    277   // Free Default value List
    278   //
    279   while (!IsListEmpty (&Statement->DefaultListHead)) {
    280     Link = GetFirstNode (&Statement->DefaultListHead);
    281     Default = QUESTION_DEFAULT_FROM_LINK (Link);
    282     RemoveEntryList (&Default->Link);
    283 
    284     gBS->FreePool (Default);
    285   }
    286 
    287   //
    288   // Free Options List
    289   //
    290   while (!IsListEmpty (&Statement->OptionListHead)) {
    291     Link = GetFirstNode (&Statement->OptionListHead);
    292     Option = QUESTION_OPTION_FROM_LINK (Link);
    293     RemoveEntryList (&Option->Link);
    294 
    295     gBS->FreePool (Option);
    296   }
    297 
    298 }
    299 
    300 
    301 
    302 /**
    303   Free resources of a Form
    304 
    305   @param  Form                   Pointer of the Form
    306 
    307   @return None.
    308 
    309 **/
    310 VOID
    311 DestroyForm (
    312   IN OUT FORM_BROWSER_FORM  *Form
    313   )
    314 {
    315   LIST_ENTRY              *Link;
    316   FORM_BROWSER_STATEMENT  *Statement;
    317 
    318   //
    319   // Free Statements/Questions
    320   //
    321   while (!IsListEmpty (&Form->StatementListHead)) {
    322     Link = GetFirstNode (&Form->StatementListHead);
    323     Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
    324     RemoveEntryList (&Statement->Link);
    325 
    326     DestroyStatement (Statement);
    327   }
    328 
    329   //
    330   // Free this Form
    331   //
    332   gBS->FreePool (Form);
    333 }
    334 
    335 
    336 /**
    337   Free resources allocated for a FormSet
    338 
    339   @param  FormSet                Pointer of the FormSet
    340 
    341   @return None.
    342 
    343 **/
    344 VOID
    345 DestroyFormSet (
    346   IN OUT FORM_BROWSER_FORMSET  *FormSet
    347   )
    348 {
    349   LIST_ENTRY            *Link;
    350   FORMSET_STORAGE       *Storage;
    351   FORMSET_DEFAULTSTORE  *DefaultStore;
    352   FORM_BROWSER_FORM     *Form;
    353 
    354   //
    355   // Free IFR binary buffer
    356   //
    357   FreePool (FormSet->IfrBinaryData);
    358 
    359   //
    360   // Free FormSet Storage
    361   //
    362   if (FormSet->StorageListHead.ForwardLink != NULL) {
    363     while (!IsListEmpty (&FormSet->StorageListHead)) {
    364       Link = GetFirstNode (&FormSet->StorageListHead);
    365       Storage = FORMSET_STORAGE_FROM_LINK (Link);
    366       RemoveEntryList (&Storage->Link);
    367 
    368       DestroyStorage (Storage);
    369     }
    370   }
    371 
    372   //
    373   // Free FormSet Default Store
    374   //
    375   if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
    376     while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
    377       Link = GetFirstNode (&FormSet->DefaultStoreListHead);
    378       DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
    379       RemoveEntryList (&DefaultStore->Link);
    380 
    381       gBS->FreePool (DefaultStore);
    382     }
    383   }
    384 
    385   //
    386   // Free Forms
    387   //
    388   if (FormSet->FormListHead.ForwardLink != NULL) {
    389     while (!IsListEmpty (&FormSet->FormListHead)) {
    390       Link = GetFirstNode (&FormSet->FormListHead);
    391       Form = FORM_BROWSER_FORM_FROM_LINK (Link);
    392       RemoveEntryList (&Form->Link);
    393 
    394       DestroyForm (Form);
    395     }
    396   }
    397 
    398   if (FormSet->StatementBuffer != NULL) {
    399     FreePool (FormSet->StatementBuffer);
    400   }
    401 
    402   DestoryOneOfOptionMap (&FormSet->OneOfOptionMapListHead);
    403 
    404   if (FormSet->OriginalDefaultVarStoreName != NULL) {
    405     FreePool (FormSet->OriginalDefaultVarStoreName);
    406   }
    407 
    408   FreePool (FormSet);
    409 }
    410 
    411 
    412 /**
    413   Tell whether this Operand is an Expression OpCode or not
    414 
    415   @param  Operand                Operand of an IFR OpCode.
    416 
    417   @retval TRUE                   This is an Expression OpCode.
    418   @retval FALSE                  Not an Expression OpCode.
    419 
    420 **/
    421 BOOLEAN
    422 IsExpressionOpCode (
    423   IN UINT8              Operand
    424   )
    425 {
    426   if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
    427       ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP))  ||
    428       ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
    429       (Operand == EFI_IFR_CATENATE_OP) ||
    430       (Operand == EFI_IFR_TO_LOWER_OP) ||
    431       (Operand == EFI_IFR_TO_UPPER_OP) ||
    432       (Operand == EFI_IFR_MAP_OP)      ||
    433       (Operand == EFI_IFR_VERSION_OP)  ||
    434       (Operand == EFI_IFR_SECURITY_OP)) {
    435     return TRUE;
    436   } else {
    437     return FALSE;
    438   }
    439 }
    440 
    441 
    442 /**
    443   Calculate number of Statemens(Questions) and Expression OpCodes.
    444 
    445   @param  FormSet                The FormSet to be counted.
    446   @param  NumberOfStatement      Number of Statemens(Questions)
    447   @param  NumberOfExpression     Number of Expression OpCodes
    448 
    449   @return None.
    450 
    451 **/
    452 VOID
    453 CountOpCodes (
    454   IN  FORM_BROWSER_FORMSET  *FormSet,
    455   IN OUT  UINT16            *NumberOfStatement,
    456   IN OUT  UINT16            *NumberOfExpression
    457   )
    458 {
    459   UINT16  StatementCount;
    460   UINT16  ExpressionCount;
    461   UINT8   *OpCodeData;
    462   UINTN   Offset;
    463   UINTN   OpCodeLen;
    464 
    465   Offset = 0;
    466   StatementCount = 0;
    467   ExpressionCount = 0;
    468 
    469   while (Offset < FormSet->IfrBinaryLength) {
    470     OpCodeData = FormSet->IfrBinaryData + Offset;
    471     OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
    472     Offset += OpCodeLen;
    473 
    474     if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
    475       ExpressionCount++;
    476     } else {
    477       StatementCount++;
    478     }
    479   }
    480 
    481   *NumberOfStatement = StatementCount;
    482   *NumberOfExpression = ExpressionCount;
    483 }
    484 
    485 
    486 /**
    487   Parse opcodes in the formset IFR binary.
    488 
    489   @param  FormSet                Pointer of the FormSet data structure.
    490 
    491   @retval EFI_SUCCESS            Opcode parse success.
    492   @retval Other                  Opcode parse fail.
    493 
    494 **/
    495 EFI_STATUS
    496 ParseOpCodes (
    497   IN FORM_BROWSER_FORMSET              *FormSet
    498   )
    499 {
    500   EFI_STATUS              Status;
    501   UINT16                  Index;
    502   FORM_BROWSER_FORM       *CurrentForm;
    503   FORM_BROWSER_STATEMENT  *CurrentStatement;
    504   UINT8                   Operand;
    505   UINT8                   Scope;
    506   UINTN                   OpCodeOffset;
    507   UINTN                   OpCodeLength;
    508   UINT8                   *OpCodeData;
    509   UINT8                   ScopeOpCode;
    510   FORMSET_STORAGE         *Storage;
    511   FORMSET_DEFAULTSTORE    *DefaultStore;
    512   QUESTION_DEFAULT        *CurrentDefault;
    513   QUESTION_OPTION         *CurrentOption;
    514   CHAR8                   *AsciiString;
    515   UINT16                  NumberOfStatement;
    516   UINT16                  NumberOfExpression;
    517   EFI_IMAGE_ID            *ImageId;
    518   EFI_HII_VALUE           *Value;
    519   LIST_ENTRY              *OneOfOptinMapEntryListHead;
    520   EFI_IFR_GUID_OPTIONKEY  *OptionMap;
    521   ONE_OF_OPTION_MAP       *OneOfOptionMap;
    522   ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
    523   UINT8                   OneOfType;
    524   EFI_IFR_ONE_OF          *OneOfOpcode;
    525   HII_THUNK_CONTEXT       *ThunkContext;
    526   EFI_IFR_FORM_MAP_METHOD *MapMethod;
    527 
    528   mInScopeSubtitle = FALSE;
    529   mInScopeSuppress = FALSE;
    530   mInScopeGrayOut  = FALSE;
    531   CurrentDefault   = NULL;
    532   CurrentOption    = NULL;
    533   MapMethod        = NULL;
    534   ThunkContext     = UefiHiiHandleToThunkContext ((CONST HII_THUNK_PRIVATE_DATA*) mHiiThunkPrivateData, FormSet->HiiHandle);
    535 
    536   //
    537   // Set to a invalid value.
    538   //
    539   OneOfType = (UINT8) -1;
    540 
    541   //
    542   // Get the number of Statements and Expressions
    543   //
    544   CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
    545   FormSet->NumberOfStatement = NumberOfStatement;
    546 
    547   mStatementIndex = 0;
    548   FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
    549   if (FormSet->StatementBuffer == NULL) {
    550     return EFI_OUT_OF_RESOURCES;
    551   }
    552 
    553   InitializeListHead (&FormSet->StorageListHead);
    554   InitializeListHead (&FormSet->DefaultStoreListHead);
    555   InitializeListHead (&FormSet->FormListHead);
    556   InitializeListHead (&FormSet->OneOfOptionMapListHead);
    557 
    558   CurrentForm = NULL;
    559   CurrentStatement = NULL;
    560 
    561   ResetScopeStack ();
    562 
    563   OpCodeOffset = 0;
    564   while (OpCodeOffset < FormSet->IfrBinaryLength) {
    565     OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
    566 
    567     OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
    568     OpCodeOffset += OpCodeLength;
    569     Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
    570     Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
    571 
    572     //
    573     // If scope bit set, push onto scope stack
    574     //
    575     if (Scope != 0) {
    576       PushScope (Operand);
    577     }
    578 
    579     if (IsExpressionOpCode (Operand)) {
    580       continue;
    581     }
    582 
    583     //
    584     // Parse the Opcode
    585     //
    586     switch (Operand) {
    587 
    588     case EFI_IFR_FORM_SET_OP:
    589       //
    590       // check the formset GUID
    591       //
    592       if (!CompareGuid ((EFI_GUID *)(VOID *)&FormSet->Guid, (EFI_GUID *)(VOID *)&((EFI_IFR_FORM_SET *) OpCodeData)->Guid)) {
    593         return EFI_INVALID_PARAMETER;
    594       }
    595 
    596       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
    597       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));
    598       break;
    599 
    600     case EFI_IFR_FORM_OP:
    601       //
    602       // Create a new Form for this FormSet
    603       //
    604       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
    605       ASSERT (CurrentForm != NULL);
    606       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
    607 
    608       InitializeListHead (&CurrentForm->StatementListHead);
    609 
    610       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));
    611       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
    612 
    613       //
    614       // Insert into Form list of this FormSet
    615       //
    616       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
    617       break;
    618 
    619     case EFI_IFR_FORM_MAP_OP:
    620       //
    621       // Create a new Form Map for this FormSet
    622       //
    623       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
    624       ASSERT (CurrentForm != NULL);
    625       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
    626 
    627       InitializeListHead (&CurrentForm->StatementListHead);
    628 
    629       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
    630       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
    631 
    632       //
    633       // FormMap Form must contain at least one Map Method.
    634       //
    635       if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
    636         return EFI_INVALID_PARAMETER;
    637       }
    638 
    639       //
    640       // Try to find the standard form map method.
    641       //
    642       while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
    643         if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
    644           CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
    645           break;
    646         }
    647         MapMethod ++;
    648       }
    649       //
    650       // If the standard form map method is not found, the first map method title will be used.
    651       //
    652       if (CurrentForm->FormTitle == 0) {
    653         MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
    654         CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
    655       }
    656 
    657       //
    658       // Insert into Form list of this FormSet
    659       //
    660       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
    661       break;
    662 
    663     //
    664     // Storage
    665     //
    666     case EFI_IFR_VARSTORE_OP:
    667       //
    668       // Create a buffer Storage for this FormSet
    669       //
    670       Storage = CreateStorage (FormSet);
    671       Storage->Type = EFI_HII_VARSTORE_BUFFER;
    672 
    673       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
    674       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE *) OpCodeData)->Guid,       sizeof (EFI_GUID));
    675       CopyMem (&Storage->Size,       &((EFI_IFR_VARSTORE *) OpCodeData)->Size,       sizeof (UINT16));
    676 
    677       AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
    678       Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
    679       ASSERT (Storage->Name != NULL);
    680       for (Index = 0; AsciiString[Index] != 0; Index++) {
    681         Storage->Name[Index] = (CHAR16) AsciiString[Index];
    682       }
    683 
    684       break;
    685 
    686     case EFI_IFR_VARSTORE_NAME_VALUE_OP:
    687       //
    688       // Framework IFR doesn't support Name/Value VarStore opcode
    689       //
    690       if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {
    691         ASSERT (FALSE);
    692       }
    693 
    694       //
    695       // Create a name/value Storage for this FormSet
    696       //
    697       Storage = CreateStorage (FormSet);
    698       Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
    699 
    700       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
    701       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid,       sizeof (EFI_GUID));
    702 
    703       break;
    704 
    705     case EFI_IFR_VARSTORE_EFI_OP:
    706       //
    707       // Create a EFI variable Storage for this FormSet
    708       //
    709       Storage = CreateStorage (FormSet);
    710       Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
    711 
    712       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
    713       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid,       sizeof (EFI_GUID));
    714       CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
    715       break;
    716 
    717     //
    718     // DefaultStore
    719     //
    720     case EFI_IFR_DEFAULTSTORE_OP:
    721       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
    722       ASSERT (DefaultStore != NULL);
    723       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
    724 
    725       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));
    726       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
    727 
    728       //
    729       // Insert to DefaultStore list of this Formset
    730       //
    731       InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
    732       break;
    733 
    734     //
    735     // Statements
    736     //
    737     case EFI_IFR_SUBTITLE_OP:
    738       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
    739       ASSERT (CurrentStatement != NULL);
    740       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
    741 
    742       if (Scope != 0) {
    743         mInScopeSubtitle = TRUE;
    744       }
    745       break;
    746 
    747     case EFI_IFR_TEXT_OP:
    748       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
    749       ASSERT (CurrentStatement != NULL);
    750 
    751       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
    752       break;
    753 
    754     //
    755     // Questions
    756     //
    757     case EFI_IFR_ACTION_OP:
    758       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    759       ASSERT (CurrentStatement != NULL);
    760 
    761       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
    762         //
    763         // No QuestionConfig present, so no configuration string will be processed
    764         //
    765         CurrentStatement->QuestionConfig = 0;
    766       } else {
    767         CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
    768       }
    769       break;
    770 
    771     case EFI_IFR_RESET_BUTTON_OP:
    772       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
    773       ASSERT (CurrentStatement != NULL);
    774       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
    775       break;
    776 
    777     case EFI_IFR_REF_OP:
    778       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    779       ASSERT (CurrentStatement != NULL);
    780 
    781       CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
    782       if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
    783         CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
    784 
    785         if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
    786           CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
    787 
    788           if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
    789             CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
    790           }
    791         }
    792       }
    793       break;
    794 
    795     case EFI_IFR_ONE_OF_OP:
    796     case EFI_IFR_NUMERIC_OP:
    797       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    798       ASSERT (CurrentStatement != NULL);
    799 
    800       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
    801       Value = &CurrentStatement->HiiValue;
    802 
    803       switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
    804       case EFI_IFR_NUMERIC_SIZE_1:
    805         CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
    806         CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
    807         CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
    808         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
    809         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
    810         break;
    811 
    812       case EFI_IFR_NUMERIC_SIZE_2:
    813         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
    814         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
    815         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));
    816         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
    817         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
    818         break;
    819 
    820       case EFI_IFR_NUMERIC_SIZE_4:
    821         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
    822         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
    823         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));
    824         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
    825         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
    826         break;
    827 
    828       case EFI_IFR_NUMERIC_SIZE_8:
    829         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
    830         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
    831         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));
    832         CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
    833         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
    834         break;
    835 
    836       default:
    837         break;
    838       }
    839 
    840       if (Operand == EFI_IFR_ONE_OF_OP) {
    841         OneOfOpcode = (EFI_IFR_ONE_OF *) OpCodeData;
    842         OneOfType   = (UINT8) (OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE);
    843       }
    844       break;
    845 
    846     case EFI_IFR_ORDERED_LIST_OP:
    847       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    848       ASSERT (CurrentStatement != NULL);
    849 
    850       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
    851       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
    852       CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));
    853 
    854       //
    855       // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
    856       // has to use FormBrowser2.Callback() to retrieve the uncommited data for
    857       // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
    858       //
    859       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;
    860       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
    861 
    862       break;
    863 
    864     case EFI_IFR_CHECKBOX_OP:
    865       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    866       ASSERT (CurrentStatement != NULL);
    867 
    868       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
    869       CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
    870       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
    871 
    872       break;
    873 
    874     case EFI_IFR_STRING_OP:
    875       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    876       ASSERT (CurrentStatement != NULL);
    877 
    878       //
    879       // MinSize is the minimum number of characters that can be accepted for this opcode,
    880       // MaxSize is the maximum number of characters that can be accepted for this opcode.
    881       // The characters are stored as Unicode, so the storage width should multiply 2.
    882       //
    883       CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
    884       CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
    885       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
    886       CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
    887 
    888       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
    889       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
    890 
    891       break;
    892 
    893     case EFI_IFR_PASSWORD_OP:
    894       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    895       ASSERT (CurrentStatement != NULL);
    896 
    897       //
    898       // MinSize is the minimum number of characters that can be accepted for this opcode,
    899       // MaxSize is the maximum number of characters that can be accepted for this opcode.
    900       // The characters are stored as Unicode, so the storage width should multiply 2.
    901       //
    902       CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
    903       CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
    904       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
    905 
    906       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
    907       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
    908 
    909       break;
    910 
    911     case EFI_IFR_DATE_OP:
    912       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    913       ASSERT (CurrentStatement != NULL);
    914 
    915       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
    916       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
    917 
    918       break;
    919 
    920     case EFI_IFR_TIME_OP:
    921       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
    922       ASSERT (CurrentStatement != NULL);
    923 
    924       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
    925       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
    926 
    927       break;
    928 
    929     //
    930     // Default
    931     //
    932     case EFI_IFR_DEFAULT_OP:
    933       //
    934       // EFI_IFR_DEFAULT appear in scope of a Question,
    935       // It creates a default value for the current question.
    936       // A Question may have more than one Default value which have different default types.
    937       //
    938       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
    939       ASSERT (CurrentDefault != NULL);
    940       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
    941 
    942       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
    943       CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
    944       CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
    945       ExtendValueToU64 (&CurrentDefault->Value);
    946 
    947       //
    948       // Insert to Default Value list of current Question
    949       //
    950       InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
    951 
    952       break;
    953 
    954     //
    955     // Option
    956     //
    957     case EFI_IFR_ONE_OF_OPTION_OP:
    958       //
    959       // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
    960       // It create a selection for use in current Question.
    961       //
    962       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
    963       ASSERT (CurrentOption != NULL);
    964       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
    965 
    966       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
    967       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
    968       CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
    969       CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
    970       ExtendValueToU64 (&CurrentOption->Value);
    971 
    972       //
    973       // Insert to Option list of current Question
    974       //
    975       InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
    976       break;
    977 
    978     //
    979     // Conditional
    980     //
    981     case EFI_IFR_NO_SUBMIT_IF_OP:
    982     case EFI_IFR_INCONSISTENT_IF_OP:
    983       break;
    984 
    985     case EFI_IFR_SUPPRESS_IF_OP:
    986       break;
    987 
    988     case EFI_IFR_GRAY_OUT_IF_OP:
    989       break;
    990 
    991     case EFI_IFR_DISABLE_IF_OP:
    992       //
    993       // Framework IFR doesn't support DisableIf opcode
    994       //
    995       if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {
    996         ASSERT (FALSE);
    997       }
    998 
    999     //
   1000     // Expression
   1001     //
   1002     case EFI_IFR_VALUE_OP:
   1003     case EFI_IFR_READ_OP:
   1004     case EFI_IFR_WRITE_OP:
   1005       break;
   1006 
   1007     case EFI_IFR_RULE_OP:
   1008       break;
   1009 
   1010     //
   1011     // Image
   1012     //
   1013     case EFI_IFR_IMAGE_OP:
   1014       //
   1015       // Get ScopeOpcode from top of stack
   1016       //
   1017       PopScope (&ScopeOpCode);
   1018       PushScope (ScopeOpCode);
   1019 
   1020       switch (ScopeOpCode) {
   1021       case EFI_IFR_FORM_SET_OP:
   1022         ImageId = &FormSet->ImageId;
   1023         break;
   1024 
   1025       case EFI_IFR_FORM_OP:
   1026       case EFI_IFR_FORM_MAP_OP:
   1027         ASSERT (CurrentForm != NULL);
   1028         ImageId = &CurrentForm->ImageId;
   1029         break;
   1030 
   1031       case EFI_IFR_ONE_OF_OPTION_OP:
   1032         ASSERT (CurrentOption != NULL);
   1033         ImageId = &CurrentOption->ImageId;
   1034         break;
   1035 
   1036       default:
   1037         //
   1038         // Make sure CurrentStatement is not NULL.
   1039         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
   1040         // file is wrongly generated by tools such as VFR Compiler.
   1041         //
   1042         ASSERT (CurrentStatement != NULL);
   1043         ImageId = &CurrentStatement->ImageId;
   1044         break;
   1045       }
   1046 
   1047       ASSERT (ImageId != NULL);
   1048       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
   1049       break;
   1050 
   1051     //
   1052     // Refresh
   1053     //
   1054     case EFI_IFR_REFRESH_OP:
   1055       ASSERT (CurrentStatement != NULL);
   1056       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
   1057       break;
   1058 
   1059     //
   1060     // Vendor specific
   1061     //
   1062     case EFI_IFR_GUID_OP:
   1063       OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCodeData;
   1064 
   1065       if (CompareGuid (&mTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
   1066         //
   1067         // Tiano specific GUIDed opcodes
   1068         //
   1069         switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
   1070         case EFI_IFR_EXTEND_OP_LABEL:
   1071           //
   1072           // just ignore label
   1073           //
   1074           break;
   1075 
   1076 
   1077         case EFI_IFR_EXTEND_OP_CLASS:
   1078           CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
   1079           break;
   1080 
   1081         case EFI_IFR_EXTEND_OP_SUBCLASS:
   1082           CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
   1083           break;
   1084 
   1085         default:
   1086           break;
   1087         }
   1088       } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) {
   1089         if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {
   1090           OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (FormSet, OptionMap->QuestionId);
   1091           if (OneOfOptinMapEntryListHead == NULL) {
   1092             OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));
   1093             ASSERT (OneOfOptionMap != NULL);
   1094 
   1095             OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;
   1096             OneOfOptionMap->QuestionId = OptionMap->QuestionId;
   1097 
   1098             //
   1099             // Make sure OneOfType is initialized.
   1100             //
   1101             ASSERT (OneOfType != (UINT8) -1);
   1102             OneOfOptionMap->ValueType = OneOfType;
   1103             InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);
   1104             OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;
   1105             InsertTailList (&FormSet->OneOfOptionMapListHead, &OneOfOptionMap->Link);
   1106           }
   1107           OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));
   1108           ASSERT (OneOfOptionMapEntry != NULL);
   1109 
   1110           OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;
   1111           OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;
   1112           CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));
   1113 
   1114           InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);
   1115         }
   1116      }
   1117       break;
   1118 
   1119     //
   1120     // Scope End
   1121     //
   1122     case EFI_IFR_END_OP:
   1123       Status = PopScope (&ScopeOpCode);
   1124       if (EFI_ERROR (Status)) {
   1125         ResetScopeStack ();
   1126         return Status;
   1127       }
   1128 
   1129       switch (ScopeOpCode) {
   1130       case EFI_IFR_FORM_SET_OP:
   1131         //
   1132         // End of FormSet, update FormSet IFR binary length
   1133         // to stop parsing substantial OpCodes
   1134         //
   1135         FormSet->IfrBinaryLength = OpCodeOffset;
   1136         break;
   1137 
   1138       case EFI_IFR_FORM_OP:
   1139       case EFI_IFR_FORM_MAP_OP:
   1140         //
   1141         // End of Form
   1142         //
   1143         CurrentForm = NULL;
   1144         break;
   1145 
   1146       case EFI_IFR_ONE_OF_OPTION_OP:
   1147         //
   1148         // End of Option
   1149         //
   1150         CurrentOption = NULL;
   1151         break;
   1152 
   1153       case EFI_IFR_SUBTITLE_OP:
   1154         mInScopeSubtitle = FALSE;
   1155         break;
   1156 
   1157       case EFI_IFR_NO_SUBMIT_IF_OP:
   1158       case EFI_IFR_INCONSISTENT_IF_OP:
   1159         //
   1160         // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
   1161         //
   1162         break;
   1163 
   1164       case EFI_IFR_GRAY_OUT_IF_OP:
   1165         mInScopeGrayOut = FALSE;
   1166         break;
   1167 
   1168       default:
   1169         if (IsExpressionOpCode (ScopeOpCode)) {
   1170         }
   1171         break;
   1172       }
   1173       break;
   1174 
   1175     default:
   1176       break;
   1177     }
   1178   }
   1179 
   1180   return EFI_SUCCESS;
   1181 }
   1182 
   1183 
   1184 
   1185 
   1186