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