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 *
GetOneOfOptionMapEntryListHead(IN CONST FORM_BROWSER_FORMSET * FormSet,IN UINT16 QuestionId)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
DestoryOneOfOptionMap(IN LIST_ENTRY * OneOfOptionMapListHead)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 *
CreateStatement(IN UINT8 * OpCodeData,IN OUT FORM_BROWSER_FORMSET * FormSet,IN OUT FORM_BROWSER_FORM * Form)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 *
CreateQuestion(IN UINT8 * OpCodeData,IN OUT FORM_BROWSER_FORMSET * FormSet,IN OUT FORM_BROWSER_FORM * Form)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 *
CreateStorage(IN FORM_BROWSER_FORMSET * FormSet)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
DestroyStorage(IN FORMSET_STORAGE * Storage)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
DestroyStatement(IN OUT FORM_BROWSER_STATEMENT * Statement)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
DestroyForm(IN OUT FORM_BROWSER_FORM * Form)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
DestroyFormSet(IN OUT FORM_BROWSER_FORMSET * FormSet)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
IsExpressionOpCode(IN UINT8 Operand)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
CountOpCodes(IN FORM_BROWSER_FORMSET * FormSet,IN OUT UINT16 * NumberOfStatement,IN OUT UINT16 * NumberOfExpression)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
ParseOpCodes(IN FORM_BROWSER_FORMSET * FormSet)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