5593b6eeb5c47649d1766febdee885d6c855cbf6
[efi/edk2/.git] / edk2 / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
1 /** @file\r
2 Parser for IFR binary encoding.\r
3 \r
4 Copyright (c) 2007 - 2010, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution.  The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9 \r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13 **/\r
14 \r
15 #include "Setup.h"\r
16 \r
17 UINT16           mStatementIndex;\r
18 UINT16           mExpressionOpCodeIndex;\r
19 \r
20 BOOLEAN          mInScopeSubtitle;\r
21 BOOLEAN          mInScopeSuppress;\r
22 BOOLEAN          mInScopeGrayOut;\r
23 BOOLEAN          mInScopeDisable;\r
24 FORM_EXPRESSION  *mSuppressExpression;\r
25 FORM_EXPRESSION  *mGrayOutExpression;\r
26 FORM_EXPRESSION  *mDisableExpression;\r
27 \r
28 /**\r
29   Initialize Statement header members.\r
30 \r
31   @param  OpCodeData             Pointer of the raw OpCode data.\r
32   @param  FormSet                Pointer of the current FormSe.\r
33   @param  Form                   Pointer of the current Form.\r
34 \r
35   @return The Statement.\r
36 \r
37 **/\r
38 FORM_BROWSER_STATEMENT *\r
39 CreateStatement (\r
40   IN UINT8                        *OpCodeData,\r
41   IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
42   IN OUT FORM_BROWSER_FORM        *Form\r
43   )\r
44 {\r
45   FORM_BROWSER_STATEMENT    *Statement;\r
46   EFI_IFR_STATEMENT_HEADER  *StatementHdr;\r
47 \r
48   if (Form == NULL) {\r
49     //\r
50     // We are currently not in a Form Scope, so just skip this Statement\r
51     //\r
52     return NULL;\r
53   }\r
54 \r
55   Statement = &FormSet->StatementBuffer[mStatementIndex];\r
56   mStatementIndex++;\r
57 \r
58   InitializeListHead (&Statement->DefaultListHead);\r
59   InitializeListHead (&Statement->OptionListHead);\r
60   InitializeListHead (&Statement->InconsistentListHead);\r
61   InitializeListHead (&Statement->NoSubmitListHead);\r
62 \r
63   Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
64 \r
65   Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
66 \r
67   StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
68   CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
69   CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
70 \r
71   if (mInScopeSuppress) {\r
72     Statement->SuppressExpression = mSuppressExpression;\r
73   }\r
74 \r
75   if (mInScopeGrayOut) {\r
76     Statement->GrayOutExpression = mGrayOutExpression;\r
77   }\r
78 \r
79 \r
80   if (mInScopeDisable) {\r
81     Statement->DisableExpression = mDisableExpression;\r
82   }\r
83 \r
84   Statement->InSubtitle = mInScopeSubtitle;\r
85 \r
86   //\r
87   // Insert this Statement into current Form\r
88   //\r
89   InsertTailList (&Form->StatementListHead, &Statement->Link);\r
90 \r
91   return Statement;\r
92 }\r
93 \r
94 /**\r
95   Convert a numeric value to a Unicode String and insert it to String Package.\r
96   This string is used as the Unicode Name for the EFI Variable. This is to support\r
97   the deprecated vareqval opcode.\r
98 \r
99   @param FormSet        The FormSet.\r
100   @param Statement      The numeric question whose VarStoreInfo.VarName is the\r
101                         numeric value which is used to produce the Unicode Name\r
102                         for the EFI Variable.\r
103 \r
104   If the Statement is NULL, the ASSERT.\r
105   If the opcode is not Numeric, then ASSERT.\r
106 \r
107   @retval EFI_SUCCESS The funtion always succeeds.\r
108 **/\r
109 EFI_STATUS\r
110 UpdateCheckBoxStringToken (\r
111   IN CONST FORM_BROWSER_FORMSET *FormSet,\r
112   IN       FORM_BROWSER_STATEMENT *Statement\r
113   )\r
114 {\r
115   CHAR16                  Str[MAXIMUM_VALUE_CHARACTERS];\r
116   EFI_STRING_ID           Id;\r
117 \r
118   ASSERT (Statement != NULL);\r
119   ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);\r
120 \r
121   UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
122 \r
123   Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);\r
124   if (Id == 0) {\r
125     return EFI_OUT_OF_RESOURCES;\r
126   }\r
127 \r
128   Statement->VarStoreInfo.VarName = Id;\r
129 \r
130   return EFI_SUCCESS;\r
131 }\r
132 \r
133 /**\r
134   Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.\r
135 \r
136   @param OpCodeData     The current opcode.\r
137 \r
138   @retval TRUE Yes.\r
139   @retval FALSE No.\r
140 **/\r
141 BOOLEAN\r
142 IsNextOpCodeGuidedVarEqName (\r
143   IN UINT8 *OpCodeData\r
144   )\r
145 {\r
146   //\r
147   // Get next opcode\r
148   //\r
149   OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
150   if (*OpCodeData == EFI_IFR_GUID_OP) {\r
151     if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
152       //\r
153       // Specific GUIDed opcodes to support IFR generated from Framework HII VFR\r
154       //\r
155       if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {\r
156         return TRUE;\r
157       }\r
158     }\r
159   }\r
160 \r
161   return FALSE;\r
162 }\r
163 \r
164 /**\r
165   Initialize Question's members.\r
166 \r
167   @param  OpCodeData             Pointer of the raw OpCode data.\r
168   @param  FormSet                Pointer of the current FormSet.\r
169   @param  Form                   Pointer of the current Form.\r
170 \r
171   @return The Question.\r
172 \r
173 **/\r
174 FORM_BROWSER_STATEMENT *\r
175 CreateQuestion (\r
176   IN UINT8                        *OpCodeData,\r
177   IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
178   IN OUT FORM_BROWSER_FORM        *Form\r
179   )\r
180 {\r
181   FORM_BROWSER_STATEMENT   *Statement;\r
182   EFI_IFR_QUESTION_HEADER  *QuestionHdr;\r
183   LIST_ENTRY               *Link;\r
184   FORMSET_STORAGE          *Storage;\r
185   NAME_VALUE_NODE          *NameValueNode;\r
186   EFI_STATUS               Status;\r
187 \r
188   Statement = CreateStatement (OpCodeData, FormSet, Form);\r
189   if (Statement == NULL) {\r
190     return NULL;\r
191   }\r
192 \r
193   QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
194   CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
195   CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
196   CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
197 \r
198   Statement->QuestionFlags = QuestionHdr->Flags;\r
199 \r
200   if (Statement->VarStoreId == 0) {\r
201     //\r
202     // VarStoreId of zero indicates no variable storage\r
203     //\r
204     return Statement;\r
205   }\r
206 \r
207   //\r
208   // Take a look at next OpCode to see whether it is a GUIDed opcode to support\r
209   // Framework Compatibility\r
210   //\r
211   if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
212     if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {\r
213       Status = UpdateCheckBoxStringToken (FormSet, Statement);\r
214       if (EFI_ERROR (Status)) {\r
215         return NULL;\r
216       }\r
217     }\r
218   }\r
219 \r
220   //\r
221   // Find Storage for this Question\r
222   //\r
223   Link = GetFirstNode (&FormSet->StorageListHead);\r
224   while (!IsNull (&FormSet->StorageListHead, Link)) {\r
225     Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
226 \r
227     if (Storage->VarStoreId == Statement->VarStoreId) {\r
228       Statement->Storage = Storage;\r
229       break;\r
230     }\r
231 \r
232     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
233   }\r
234   ASSERT (Statement->Storage != NULL);\r
235 \r
236   //\r
237   // Initialilze varname for Name/Value or EFI Variable\r
238   //\r
239   if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
240       (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
241     Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
242     ASSERT (Statement->VariableName != NULL);\r
243 \r
244     if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
245       //\r
246       // Insert to Name/Value varstore list\r
247       //\r
248       NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
249       ASSERT (NameValueNode != NULL);\r
250       NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
251       NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
252       ASSERT (NameValueNode->Name != NULL);\r
253       NameValueNode->Value = AllocateZeroPool (0x10);\r
254       ASSERT (NameValueNode->Value != NULL);\r
255       NameValueNode->EditValue = AllocateZeroPool (0x10);\r
256       ASSERT (NameValueNode->EditValue != NULL);\r
257 \r
258       InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
259     }\r
260   }\r
261 \r
262   return Statement;\r
263 }\r
264 \r
265 \r
266 /**\r
267   Allocate a FORM_EXPRESSION node.\r
268 \r
269   @param  Form                   The Form associated with this Expression\r
270 \r
271   @return Pointer to a FORM_EXPRESSION data structure.\r
272 \r
273 **/\r
274 FORM_EXPRESSION *\r
275 CreateExpression (\r
276   IN OUT FORM_BROWSER_FORM        *Form\r
277   )\r
278 {\r
279   FORM_EXPRESSION  *Expression;\r
280 \r
281   Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
282   ASSERT (Expression != NULL);\r
283   Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
284   InitializeListHead (&Expression->OpCodeListHead);\r
285 \r
286   return Expression;\r
287 }\r
288 \r
289 \r
290 /**\r
291   Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
292 \r
293   @param  FormSet                Pointer of the current FormSet\r
294 \r
295   @return Pointer to a FORMSET_STORAGE data structure.\r
296 \r
297 **/\r
298 FORMSET_STORAGE *\r
299 CreateStorage (\r
300   IN FORM_BROWSER_FORMSET  *FormSet\r
301   )\r
302 {\r
303   FORMSET_STORAGE  *Storage;\r
304 \r
305   Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
306   ASSERT (Storage != NULL);\r
307   Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
308   InitializeListHead (&Storage->NameValueListHead);\r
309   InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
310 \r
311   return Storage;\r
312 }\r
313 \r
314 \r
315 /**\r
316   Create ConfigHdr string for a storage.\r
317 \r
318   @param  FormSet                Pointer of the current FormSet\r
319   @param  Storage                Pointer of the storage\r
320 \r
321   @retval EFI_SUCCESS            Initialize ConfigHdr success\r
322 \r
323 **/\r
324 EFI_STATUS\r
325 InitializeConfigHdr (\r
326   IN FORM_BROWSER_FORMSET  *FormSet,\r
327   IN OUT FORMSET_STORAGE   *Storage\r
328   )\r
329 {\r
330   CHAR16      *Name;\r
331 \r
332   if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
333     Name = Storage->Name;\r
334   } else {\r
335     Name = NULL;\r
336   }\r
337 \r
338   Storage->ConfigHdr = HiiConstructConfigHdr (\r
339                          &Storage->Guid,\r
340                          Name,\r
341                          FormSet->DriverHandle\r
342                          );\r
343 \r
344   if (Storage->ConfigHdr == NULL) {\r
345     return EFI_NOT_FOUND;\r
346   }\r
347 \r
348   Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
349   Storage->SpareStrLen = 0;\r
350 \r
351   return EFI_SUCCESS;\r
352 }\r
353 \r
354 \r
355 /**\r
356   Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
357 \r
358   @param  FormSet                Pointer of the current FormSet.\r
359   @param  Question               The Question to be initialized.\r
360 \r
361   @retval EFI_SUCCESS            Function success.\r
362   @retval EFI_INVALID_PARAMETER  No storage associated with the Question.\r
363 \r
364 **/\r
365 EFI_STATUS\r
366 InitializeRequestElement (\r
367   IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
368   IN OUT FORM_BROWSER_STATEMENT   *Question\r
369   )\r
370 {\r
371   FORMSET_STORAGE  *Storage;\r
372   UINTN            StrLen;\r
373   UINTN            StringSize;\r
374   CHAR16           *NewStr;\r
375   CHAR16           RequestElement[30];\r
376 \r
377   Storage = Question->Storage;\r
378   if (Storage == NULL) {\r
379     return EFI_INVALID_PARAMETER;\r
380   }\r
381 \r
382   if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
383     //\r
384     // <ConfigRequest> is unnecessary for EFI variable storage,\r
385     // GetVariable()/SetVariable() will be used to retrieve/save values\r
386     //\r
387     return EFI_SUCCESS;\r
388   }\r
389 \r
390   //\r
391   // Prepare <RequestElement>\r
392   //\r
393   if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
394     StrLen = UnicodeSPrint (\r
395                RequestElement,\r
396                30 * sizeof (CHAR16),\r
397                L"&OFFSET=%x&WIDTH=%x",\r
398                Question->VarStoreInfo.VarOffset,\r
399                Question->StorageWidth\r
400                );\r
401     Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
402   } else {\r
403     StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
404   }\r
405 \r
406   if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {\r
407     //\r
408     // Password with CALLBACK flag is stored in encoded format,\r
409     // so don't need to append it to <ConfigRequest>\r
410     //\r
411     return EFI_SUCCESS;\r
412   }\r
413 \r
414   //\r
415   // Append <RequestElement> to <ConfigRequest>\r
416   //\r
417   if (StrLen > Storage->SpareStrLen) {\r
418     //\r
419     // Old String buffer is not sufficient for RequestElement, allocate a new one\r
420     //\r
421     StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);\r
422     NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
423     ASSERT (NewStr != NULL);\r
424     if (Storage->ConfigRequest != NULL) {\r
425       CopyMem (NewStr, Storage->ConfigRequest, StringSize);\r
426       FreePool (Storage->ConfigRequest);\r
427     }\r
428     Storage->ConfigRequest = NewStr;\r
429     Storage->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
430   }\r
431 \r
432   StrCat (Storage->ConfigRequest, RequestElement);\r
433   Storage->ElementCount++;\r
434   Storage->SpareStrLen -= StrLen;\r
435 \r
436   return EFI_SUCCESS;\r
437 }\r
438 \r
439 \r
440 /**\r
441   Free resources of a Expression.\r
442 \r
443   @param  FormSet                Pointer of the Expression\r
444 \r
445 **/\r
446 VOID\r
447 DestroyExpression (\r
448   IN FORM_EXPRESSION   *Expression\r
449   )\r
450 {\r
451   LIST_ENTRY         *Link;\r
452   EXPRESSION_OPCODE  *OpCode;\r
453   LIST_ENTRY         *SubExpressionLink;\r
454   FORM_EXPRESSION    *SubExpression;\r
455 \r
456   while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
457     Link = GetFirstNode (&Expression->OpCodeListHead);\r
458     OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
459     RemoveEntryList (&OpCode->Link);\r
460 \r
461     if (OpCode->ValueList != NULL) {\r
462       FreePool (OpCode->ValueList);\r
463     }\r
464 \r
465     if (OpCode->ValueName != NULL) {\r
466       FreePool (OpCode->ValueName);\r
467     }\r
468 \r
469     if (OpCode->MapExpressionList.ForwardLink != NULL) {\r
470       while (!IsListEmpty (&OpCode->MapExpressionList)) {\r
471         SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r
472         SubExpression     = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
473         RemoveEntryList(&SubExpression->Link);\r
474         DestroyExpression (SubExpression);\r
475       }\r
476     }\r
477   }\r
478 \r
479   //\r
480   // Free this Expression\r
481   //\r
482   FreePool (Expression);\r
483 }\r
484 \r
485 \r
486 /**\r
487   Free resources of a storage.\r
488 \r
489   @param  Storage                Pointer of the storage\r
490 \r
491 **/\r
492 VOID\r
493 DestroyStorage (\r
494   IN FORMSET_STORAGE   *Storage\r
495   )\r
496 {\r
497   LIST_ENTRY         *Link;\r
498   NAME_VALUE_NODE    *NameValueNode;\r
499 \r
500   if (Storage == NULL) {\r
501     return;\r
502   }\r
503 \r
504   if (Storage->Name != NULL) {\r
505     FreePool (Storage->Name);\r
506   }\r
507   if (Storage->Buffer != NULL) {\r
508     FreePool (Storage->Buffer);\r
509   }\r
510   if (Storage->EditBuffer != NULL) {\r
511     FreePool (Storage->EditBuffer);\r
512   }\r
513 \r
514   while (!IsListEmpty (&Storage->NameValueListHead)) {\r
515     Link = GetFirstNode (&Storage->NameValueListHead);\r
516     NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
517     RemoveEntryList (&NameValueNode->Link);\r
518 \r
519     if (NameValueNode->Name != NULL) {\r
520       FreePool (NameValueNode->Name);\r
521     }\r
522     if (NameValueNode->Value != NULL) {\r
523       FreePool (NameValueNode->Value);\r
524     }\r
525     if (NameValueNode->EditValue != NULL) {\r
526       FreePool (NameValueNode->EditValue);\r
527     }\r
528     FreePool (NameValueNode);\r
529   }\r
530 \r
531   if (Storage->ConfigHdr != NULL) {\r
532     FreePool (Storage->ConfigHdr);\r
533   }\r
534   if (Storage->ConfigRequest != NULL) {\r
535     FreePool (Storage->ConfigRequest);\r
536   }\r
537 \r
538   FreePool (Storage);\r
539 }\r
540 \r
541 \r
542 /**\r
543   Free resources of a Statement.\r
544 \r
545   @param  Statement              Pointer of the Statement\r
546 \r
547 **/\r
548 VOID\r
549 DestroyStatement (\r
550   IN OUT FORM_BROWSER_STATEMENT  *Statement\r
551   )\r
552 {\r
553   LIST_ENTRY        *Link;\r
554   QUESTION_DEFAULT  *Default;\r
555   QUESTION_OPTION   *Option;\r
556   FORM_EXPRESSION   *Expression;\r
557 \r
558   //\r
559   // Free Default value List\r
560   //\r
561   while (!IsListEmpty (&Statement->DefaultListHead)) {\r
562     Link = GetFirstNode (&Statement->DefaultListHead);\r
563     Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
564     RemoveEntryList (&Default->Link);\r
565 \r
566     FreePool (Default);\r
567   }\r
568 \r
569   //\r
570   // Free Options List\r
571   //\r
572   while (!IsListEmpty (&Statement->OptionListHead)) {\r
573     Link = GetFirstNode (&Statement->OptionListHead);\r
574     Option = QUESTION_OPTION_FROM_LINK (Link);\r
575     RemoveEntryList (&Option->Link);\r
576 \r
577     FreePool (Option);\r
578   }\r
579 \r
580   //\r
581   // Free Inconsistent List\r
582   //\r
583   while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
584     Link = GetFirstNode (&Statement->InconsistentListHead);\r
585     Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
586     RemoveEntryList (&Expression->Link);\r
587 \r
588     DestroyExpression (Expression);\r
589   }\r
590 \r
591   //\r
592   // Free NoSubmit List\r
593   //\r
594   while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
595     Link = GetFirstNode (&Statement->NoSubmitListHead);\r
596     Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
597     RemoveEntryList (&Expression->Link);\r
598 \r
599     DestroyExpression (Expression);\r
600   }\r
601 \r
602   if (Statement->VariableName != NULL) {\r
603     FreePool (Statement->VariableName);\r
604   }\r
605   if (Statement->BlockName != NULL) {\r
606     FreePool (Statement->BlockName);\r
607   }\r
608   if (Statement->BufferValue != NULL) {\r
609     FreePool (Statement->BufferValue);\r
610   }\r
611 }\r
612 \r
613 \r
614 /**\r
615   Free resources of a Form.\r
616 \r
617   @param  Form                   Pointer of the Form.\r
618 \r
619 **/\r
620 VOID\r
621 DestroyForm (\r
622   IN OUT FORM_BROWSER_FORM  *Form\r
623   )\r
624 {\r
625   LIST_ENTRY              *Link;\r
626   FORM_EXPRESSION         *Expression;\r
627   FORM_BROWSER_STATEMENT  *Statement;\r
628 \r
629   //\r
630   // Free Form Expressions\r
631   //\r
632   while (!IsListEmpty (&Form->ExpressionListHead)) {\r
633     Link = GetFirstNode (&Form->ExpressionListHead);\r
634     Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
635     RemoveEntryList (&Expression->Link);\r
636 \r
637     DestroyExpression (Expression);\r
638   }\r
639 \r
640   //\r
641   // Free Statements/Questions\r
642   //\r
643   while (!IsListEmpty (&Form->StatementListHead)) {\r
644     Link = GetFirstNode (&Form->StatementListHead);\r
645     Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
646     RemoveEntryList (&Statement->Link);\r
647 \r
648     DestroyStatement (Statement);\r
649   }\r
650 \r
651   //\r
652   // Free this Form\r
653   //\r
654   FreePool (Form);\r
655 }\r
656 \r
657 \r
658 /**\r
659   Free resources allocated for a FormSet.\r
660 \r
661   @param  FormSet                Pointer of the FormSet\r
662 \r
663 **/\r
664 VOID\r
665 DestroyFormSet (\r
666   IN OUT FORM_BROWSER_FORMSET  *FormSet\r
667   )\r
668 {\r
669   LIST_ENTRY            *Link;\r
670   FORMSET_STORAGE       *Storage;\r
671   FORMSET_DEFAULTSTORE  *DefaultStore;\r
672   FORM_EXPRESSION       *Expression;\r
673   FORM_BROWSER_FORM     *Form;\r
674 \r
675   if (FormSet->IfrBinaryData == NULL) {\r
676     //\r
677     // Uninitialized FormSet\r
678     //\r
679     FreePool (FormSet);\r
680     return;\r
681   }\r
682 \r
683   //\r
684   // Free IFR binary buffer\r
685   //\r
686   FreePool (FormSet->IfrBinaryData);\r
687 \r
688   //\r
689   // Free FormSet Storage\r
690   //\r
691   if (FormSet->StorageListHead.ForwardLink != NULL) {\r
692     while (!IsListEmpty (&FormSet->StorageListHead)) {\r
693       Link = GetFirstNode (&FormSet->StorageListHead);\r
694       Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
695       RemoveEntryList (&Storage->Link);\r
696 \r
697       DestroyStorage (Storage);\r
698     }\r
699   }\r
700 \r
701   //\r
702   // Free FormSet Default Store\r
703   //\r
704   if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
705     while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
706       Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
707       DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
708       RemoveEntryList (&DefaultStore->Link);\r
709 \r
710       FreePool (DefaultStore);\r
711     }\r
712   }\r
713 \r
714   //\r
715   // Free Formset Expressions\r
716   //\r
717   while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
718     Link = GetFirstNode (&FormSet->ExpressionListHead);\r
719     Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
720     RemoveEntryList (&Expression->Link);\r
721 \r
722     DestroyExpression (Expression);\r
723   }\r
724 \r
725   //\r
726   // Free Forms\r
727   //\r
728   if (FormSet->FormListHead.ForwardLink != NULL) {\r
729     while (!IsListEmpty (&FormSet->FormListHead)) {\r
730       Link = GetFirstNode (&FormSet->FormListHead);\r
731       Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
732       RemoveEntryList (&Form->Link);\r
733 \r
734       DestroyForm (Form);\r
735     }\r
736   }\r
737 \r
738   if (FormSet->StatementBuffer != NULL) {\r
739     FreePool (FormSet->StatementBuffer);\r
740   }\r
741   if (FormSet->ExpressionBuffer != NULL) {\r
742     FreePool (FormSet->ExpressionBuffer);\r
743   }\r
744 \r
745   FreePool (FormSet);\r
746 }\r
747 \r
748 \r
749 /**\r
750   Tell whether this Operand is an Expression OpCode or not\r
751 \r
752   @param  Operand                Operand of an IFR OpCode.\r
753 \r
754   @retval TRUE                   This is an Expression OpCode.\r
755   @retval FALSE                  Not an Expression OpCode.\r
756 \r
757 **/\r
758 BOOLEAN\r
759 IsExpressionOpCode (\r
760   IN UINT8              Operand\r
761   )\r
762 {\r
763   if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
764       ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP))  ||\r
765       ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
766       (Operand == EFI_IFR_CATENATE_OP) ||\r
767       (Operand == EFI_IFR_TO_LOWER_OP) ||\r
768       (Operand == EFI_IFR_TO_UPPER_OP) ||\r
769       (Operand == EFI_IFR_MAP_OP)      ||\r
770       (Operand == EFI_IFR_VERSION_OP)  ||\r
771       (Operand == EFI_IFR_SECURITY_OP)) {\r
772     return TRUE;\r
773   } else {\r
774     return FALSE;\r
775   }\r
776 }\r
777 \r
778 \r
779 /**\r
780   Calculate number of Statemens(Questions) and Expression OpCodes.\r
781 \r
782   @param  FormSet                The FormSet to be counted.\r
783   @param  NumberOfStatement      Number of Statemens(Questions)\r
784   @param  NumberOfExpression     Number of Expression OpCodes\r
785 \r
786 **/\r
787 VOID\r
788 CountOpCodes (\r
789   IN  FORM_BROWSER_FORMSET  *FormSet,\r
790   IN OUT  UINT16            *NumberOfStatement,\r
791   IN OUT  UINT16            *NumberOfExpression\r
792   )\r
793 {\r
794   UINT16  StatementCount;\r
795   UINT16  ExpressionCount;\r
796   UINT8   *OpCodeData;\r
797   UINTN   Offset;\r
798   UINTN   OpCodeLen;\r
799 \r
800   Offset = 0;\r
801   StatementCount = 0;\r
802   ExpressionCount = 0;\r
803 \r
804   while (Offset < FormSet->IfrBinaryLength) {\r
805     OpCodeData = FormSet->IfrBinaryData + Offset;\r
806     OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
807     Offset += OpCodeLen;\r
808 \r
809     if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
810       ExpressionCount++;\r
811     } else {\r
812       StatementCount++;\r
813     }\r
814   }\r
815 \r
816   *NumberOfStatement = StatementCount;\r
817   *NumberOfExpression = ExpressionCount;\r
818 }\r
819 \r
820 \r
821 \r
822 /**\r
823   Parse opcodes in the formset IFR binary.\r
824 \r
825   @param  FormSet                Pointer of the FormSet data structure.\r
826 \r
827   @retval EFI_SUCCESS            Opcode parse success.\r
828   @retval Other                  Opcode parse fail.\r
829 \r
830 **/\r
831 EFI_STATUS\r
832 ParseOpCodes (\r
833   IN FORM_BROWSER_FORMSET              *FormSet\r
834   )\r
835 {\r
836   EFI_STATUS              Status;\r
837   UINT16                  Index;\r
838   FORM_BROWSER_FORM       *CurrentForm;\r
839   FORM_BROWSER_STATEMENT  *CurrentStatement;\r
840   EXPRESSION_OPCODE       *ExpressionOpCode;\r
841   FORM_EXPRESSION         *CurrentExpression;\r
842   UINT8                   Operand;\r
843   UINT8                   Scope;\r
844   UINTN                   OpCodeOffset;\r
845   UINTN                   OpCodeLength;\r
846   UINT8                   *OpCodeData;\r
847   UINT8                   ScopeOpCode;\r
848   FORMSET_STORAGE         *Storage;\r
849   FORMSET_DEFAULTSTORE    *DefaultStore;\r
850   QUESTION_DEFAULT        *CurrentDefault;\r
851   QUESTION_OPTION         *CurrentOption;\r
852   UINT8                   Width;\r
853   CHAR8                   *AsciiString;\r
854   UINT16                  NumberOfStatement;\r
855   UINT16                  NumberOfExpression;\r
856   EFI_IMAGE_ID            *ImageId;\r
857   BOOLEAN                 SuppressForQuestion;\r
858   BOOLEAN                 SuppressForOption;\r
859   BOOLEAN                 InScopeOptionSuppress;\r
860   FORM_EXPRESSION         *OptionSuppressExpression;\r
861   BOOLEAN                 InScopeFormSuppress;\r
862   FORM_EXPRESSION         *FormSuppressExpression;\r
863   UINT16                  DepthOfDisable;\r
864   BOOLEAN                 OpCodeDisabled;\r
865   BOOLEAN                 SingleOpCodeExpression;\r
866   BOOLEAN                 InScopeDefault;\r
867   EFI_HII_VALUE           *Value;\r
868   EFI_IFR_FORM_MAP_METHOD *MapMethod;\r
869   UINT8                   MapScopeDepth;\r
870   LIST_ENTRY              *Link;\r
871   FORMSET_STORAGE         *VarStorage;\r
872   LIST_ENTRY              *MapExpressionList;\r
873   EFI_VARSTORE_ID         TempVarstoreId;\r
874 \r
875   mInScopeSubtitle         = FALSE;\r
876   SuppressForQuestion      = FALSE;\r
877   SuppressForOption        = FALSE;\r
878   InScopeFormSuppress      = FALSE;\r
879   mInScopeSuppress         = FALSE;\r
880   InScopeOptionSuppress    = FALSE;\r
881   mInScopeGrayOut          = FALSE;\r
882   mInScopeDisable          = FALSE;\r
883   DepthOfDisable           = 0;\r
884   OpCodeDisabled           = FALSE;\r
885   SingleOpCodeExpression   = FALSE;\r
886   InScopeDefault           = FALSE;\r
887   CurrentExpression        = NULL;\r
888   CurrentDefault           = NULL;\r
889   CurrentOption            = NULL;\r
890   OptionSuppressExpression = NULL;\r
891   FormSuppressExpression   = NULL;\r
892   ImageId                  = NULL;\r
893   MapMethod                = NULL;\r
894   MapScopeDepth            = 0;\r
895   Link                     = NULL;\r
896   VarStorage               = NULL;\r
897   MapExpressionList        = NULL;\r
898   TempVarstoreId           = 0;\r
899 \r
900   //\r
901   // Get the number of Statements and Expressions\r
902   //\r
903   CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
904 \r
905   mStatementIndex = 0;\r
906   FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
907   if (FormSet->StatementBuffer == NULL) {\r
908     return EFI_OUT_OF_RESOURCES;\r
909   }\r
910 \r
911   mExpressionOpCodeIndex = 0;\r
912   FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
913   if (FormSet->ExpressionBuffer == NULL) {\r
914     return EFI_OUT_OF_RESOURCES;\r
915   }\r
916 \r
917   InitializeListHead (&FormSet->StorageListHead);\r
918   InitializeListHead (&FormSet->DefaultStoreListHead);\r
919   InitializeListHead (&FormSet->FormListHead);\r
920   ResetCurrentExpressionStack ();\r
921   ResetMapExpressionListStack ();\r
922 \r
923   CurrentForm = NULL;\r
924   CurrentStatement = NULL;\r
925 \r
926   ResetScopeStack ();\r
927 \r
928   OpCodeOffset = 0;\r
929   while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
930     OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
931 \r
932     OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
933     OpCodeOffset += OpCodeLength;\r
934     Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
935     Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
936 \r
937     //\r
938     // If scope bit set, push onto scope stack\r
939     //\r
940     if (Scope != 0) {\r
941       PushScope (Operand);\r
942     }\r
943 \r
944     if (OpCodeDisabled) {\r
945       //\r
946       // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
947       // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
948       //\r
949       if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
950         DepthOfDisable++;\r
951       } else if (Operand == EFI_IFR_END_OP) {\r
952         Status = PopScope (&ScopeOpCode);\r
953         if (EFI_ERROR (Status)) {\r
954           return Status;\r
955         }\r
956 \r
957         if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
958           if (DepthOfDisable == 0) {\r
959             mInScopeDisable = FALSE;\r
960             OpCodeDisabled = FALSE;\r
961           } else {\r
962             DepthOfDisable--;\r
963           }\r
964         }\r
965       }\r
966       continue;\r
967     }\r
968 \r
969     if (IsExpressionOpCode (Operand)) {\r
970       ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
971       mExpressionOpCodeIndex++;\r
972 \r
973       ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
974       ExpressionOpCode->Operand = Operand;\r
975       Value = &ExpressionOpCode->Value;\r
976 \r
977       switch (Operand) {\r
978       case EFI_IFR_EQ_ID_VAL_OP:\r
979         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
980 \r
981         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
982         CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
983         break;\r
984 \r
985       case EFI_IFR_EQ_ID_ID_OP:\r
986         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
987         CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
988         break;\r
989 \r
990       case EFI_IFR_EQ_ID_LIST_OP:\r
991         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
992         CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
993         ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
994         break;\r
995 \r
996       case EFI_IFR_TO_STRING_OP:\r
997       case EFI_IFR_FIND_OP:\r
998         ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
999         break;\r
1000 \r
1001       case EFI_IFR_STRING_REF1_OP:\r
1002         Value->Type = EFI_IFR_TYPE_STRING;\r
1003         CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
1004         break;\r
1005 \r
1006       case EFI_IFR_RULE_REF_OP:\r
1007         ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
1008         break;\r
1009 \r
1010       case EFI_IFR_SPAN_OP:\r
1011         ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
1012         break;\r
1013 \r
1014       case EFI_IFR_THIS_OP:\r
1015         ASSERT (CurrentStatement != NULL);\r
1016         ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
1017         break;\r
1018 \r
1019       case EFI_IFR_SECURITY_OP:\r
1020         CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r
1021         break;\r
1022 \r
1023       case EFI_IFR_GET_OP:\r
1024       case EFI_IFR_SET_OP:\r
1025         CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r
1026         if (TempVarstoreId != 0) {\r
1027           if (FormSet->StorageListHead.ForwardLink != NULL) {\r
1028             Link = GetFirstNode (&FormSet->StorageListHead);\r
1029             while (!IsNull (&FormSet->StorageListHead, Link)) {\r
1030               VarStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
1031               if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {\r
1032                 ExpressionOpCode->VarStorage = VarStorage;\r
1033                 break;\r
1034               }\r
1035               Link = GetNextNode (&FormSet->StorageListHead, Link);\r
1036             }\r
1037           }\r
1038           if (ExpressionOpCode->VarStorage == NULL) {\r
1039             //\r
1040             // VarStorage is not found.\r
1041             //\r
1042             return EFI_INVALID_PARAMETER;\r
1043           }\r
1044         }\r
1045         ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;\r
1046         switch (ExpressionOpCode->ValueType) {\r
1047         case EFI_IFR_TYPE_BOOLEAN:\r
1048         case EFI_IFR_TYPE_NUM_SIZE_8: \r
1049           ExpressionOpCode->ValueWidth = 1;\r
1050           break;\r
1051 \r
1052         case EFI_IFR_TYPE_NUM_SIZE_16:\r
1053         case EFI_IFR_TYPE_STRING:\r
1054           ExpressionOpCode->ValueWidth = 2;\r
1055           break;\r
1056 \r
1057         case EFI_IFR_TYPE_NUM_SIZE_32:\r
1058           ExpressionOpCode->ValueWidth = 4;\r
1059           break;\r
1060 \r
1061         case EFI_IFR_TYPE_NUM_SIZE_64:\r
1062           ExpressionOpCode->ValueWidth = 8;\r
1063           break;\r
1064 \r
1065         case EFI_IFR_TYPE_DATE:\r
1066           ExpressionOpCode->ValueWidth = sizeof (EFI_IFR_DATE);\r
1067           break;\r
1068 \r
1069         case EFI_IFR_TYPE_TIME:\r
1070           ExpressionOpCode->ValueWidth = sizeof (EFI_IFR_TIME);\r
1071           break;\r
1072 \r
1073         case EFI_IFR_TYPE_OTHER:\r
1074         case EFI_IFR_TYPE_UNDEFINED:\r
1075         case EFI_IFR_TYPE_ACTION:\r
1076         case EFI_IFR_TYPE_BUFFER:\r
1077         default:\r
1078           //\r
1079           // Invalid value type for Get/Set opcode.\r
1080           //\r
1081           return EFI_INVALID_PARAMETER;\r
1082         }\r
1083         CopyMem (&ExpressionOpCode->VarStoreInfo.VarName,   &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName,   sizeof (EFI_STRING_ID));\r
1084         CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));\r
1085         if ((ExpressionOpCode->VarStorage != NULL) && \r
1086             (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE || \r
1087              ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
1088           ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);\r
1089           if (ExpressionOpCode->ValueName == NULL) {\r
1090             //\r
1091             // String ID is invalid.\r
1092             //\r
1093             return EFI_INVALID_PARAMETER;\r
1094           }\r
1095         }\r
1096         break;\r
1097 \r
1098       case EFI_IFR_QUESTION_REF1_OP:\r
1099         CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1100         break;\r
1101 \r
1102       case EFI_IFR_QUESTION_REF3_OP:\r
1103         if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
1104           CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1105 \r
1106           if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
1107             CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1108           }\r
1109         }\r
1110         break;\r
1111 \r
1112       //\r
1113       // constant\r
1114       //\r
1115       case EFI_IFR_TRUE_OP:\r
1116         Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1117         Value->Value.b = TRUE;\r
1118         break;\r
1119 \r
1120       case EFI_IFR_FALSE_OP:\r
1121         Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1122         Value->Value.b = FALSE;\r
1123         break;\r
1124 \r
1125       case EFI_IFR_ONE_OP:\r
1126         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1127         Value->Value.u8 = 1;\r
1128         break;\r
1129 \r
1130       case EFI_IFR_ZERO_OP:\r
1131         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1132         Value->Value.u8 = 0;\r
1133         break;\r
1134 \r
1135       case EFI_IFR_ONES_OP:\r
1136         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1137         Value->Value.u64 = 0xffffffffffffffffULL;\r
1138         break;\r
1139 \r
1140       case EFI_IFR_UINT8_OP:\r
1141         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1142         Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
1143         break;\r
1144 \r
1145       case EFI_IFR_UINT16_OP:\r
1146         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1147         CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
1148         break;\r
1149 \r
1150       case EFI_IFR_UINT32_OP:\r
1151         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1152         CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
1153         break;\r
1154 \r
1155       case EFI_IFR_UINT64_OP:\r
1156         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1157         CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
1158         break;\r
1159 \r
1160       case EFI_IFR_UNDEFINED_OP:\r
1161         Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
1162         break;\r
1163 \r
1164       case EFI_IFR_VERSION_OP:\r
1165         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1166         Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
1167         break;\r
1168 \r
1169       default:\r
1170         break;\r
1171       }\r
1172       //\r
1173       // Create sub expression nested in MAP opcode\r
1174       //\r
1175       if (CurrentExpression == NULL && MapScopeDepth > 0) {\r
1176         CurrentExpression = CreateExpression (CurrentForm);\r
1177         InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
1178         if (Scope == 0) {\r
1179           SingleOpCodeExpression = TRUE;\r
1180         }\r
1181       }\r
1182       ASSERT (CurrentExpression != NULL);\r
1183       InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
1184       if (Operand == EFI_IFR_MAP_OP) {\r
1185         //\r
1186         // Store current Map Expression List.\r
1187         //\r
1188         if (MapExpressionList != NULL) {\r
1189           PushMapExpressionList (MapExpressionList);\r
1190         }\r
1191         //\r
1192         // Initialize new Map Expression List.\r
1193         //\r
1194         MapExpressionList = &ExpressionOpCode->MapExpressionList;\r
1195         InitializeListHead (MapExpressionList);\r
1196         //\r
1197         // Store current expression.\r
1198         //\r
1199         PushCurrentExpression (CurrentExpression);\r
1200         CurrentExpression = NULL;\r
1201         MapScopeDepth ++;\r
1202       } else if (SingleOpCodeExpression) {\r
1203         //\r
1204         // There are two cases to indicate the end of an Expression:\r
1205         // for single OpCode expression: one Expression OpCode\r
1206         // for expression consists of more than one OpCode: EFI_IFR_END\r
1207         //\r
1208         SingleOpCodeExpression = FALSE;\r
1209 \r
1210         if (mInScopeDisable && CurrentForm == NULL) {\r
1211           //\r
1212           // This is DisableIf expression for Form, it should be a constant expression\r
1213           //\r
1214           Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1215           if (EFI_ERROR (Status)) {\r
1216             return Status;\r
1217           }\r
1218 \r
1219           if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1220             return EFI_INVALID_PARAMETER;\r
1221           }\r
1222 \r
1223           OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1224         }\r
1225 \r
1226         CurrentExpression = NULL;\r
1227       }\r
1228 \r
1229       continue;\r
1230     }\r
1231 \r
1232     //\r
1233     // Parse the Opcode\r
1234     //\r
1235     switch (Operand) {\r
1236 \r
1237     case EFI_IFR_FORM_SET_OP:\r
1238       //\r
1239       // Check the formset GUID\r
1240       //\r
1241       if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1242         return EFI_INVALID_PARAMETER;\r
1243       }\r
1244 \r
1245       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1246       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));\r
1247 \r
1248       if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
1249         //\r
1250         // The formset OpCode contains ClassGuid\r
1251         //\r
1252         FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1253         CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
1254       }\r
1255 \r
1256       InitializeListHead (&FormSet->ExpressionListHead);\r
1257       break;\r
1258 \r
1259     case EFI_IFR_FORM_OP:\r
1260       //\r
1261       // Create a new Form for this FormSet\r
1262       //\r
1263       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1264       ASSERT (CurrentForm != NULL);\r
1265       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1266       InitializeListHead (&CurrentForm->ExpressionListHead);\r
1267       InitializeListHead (&CurrentForm->StatementListHead);\r
1268 \r
1269       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1270       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
1271       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1272 \r
1273       if (InScopeFormSuppress) {\r
1274         //\r
1275         // Form is inside of suppressif\r
1276         //\r
1277         CurrentForm->SuppressExpression = FormSuppressExpression;\r
1278       }\r
1279 \r
1280       if (Scope != 0) {\r
1281         //\r
1282         // Enter scope of a Form, suppressif will be used for Question or Option\r
1283         //\r
1284         SuppressForQuestion = TRUE;\r
1285       }\r
1286 \r
1287       //\r
1288       // Insert into Form list of this FormSet\r
1289       //\r
1290       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1291       break;\r
1292 \r
1293     case EFI_IFR_FORM_MAP_OP:\r
1294       //\r
1295       // Create a new Form for this FormSet\r
1296       //\r
1297       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1298       ASSERT (CurrentForm != NULL);\r
1299       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1300       InitializeListHead (&CurrentForm->ExpressionListHead);\r
1301       InitializeListHead (&CurrentForm->StatementListHead);\r
1302       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1303 \r
1304       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1305       //\r
1306       // FormMap Form must contain at least one Map Method.\r
1307       //\r
1308       if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
1309         return EFI_INVALID_PARAMETER;\r
1310       }\r
1311       //\r
1312       // Try to find the standard form map method.\r
1313       //\r
1314       while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
1315         if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
1316           CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1317           CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1318           break;\r
1319         }\r
1320         MapMethod ++;\r
1321       }\r
1322       //\r
1323       // If the standard form map method is not found, the first map method title will be used.\r
1324       //\r
1325       if (CurrentForm->FormTitle == 0) {\r
1326         MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1327         CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1328       }\r
1329 \r
1330       if (InScopeFormSuppress) {\r
1331         //\r
1332         // Form is inside of suppressif\r
1333         //\r
1334         CurrentForm->SuppressExpression = FormSuppressExpression;\r
1335       }\r
1336 \r
1337       if (Scope != 0) {\r
1338         //\r
1339         // Enter scope of a Form, suppressif will be used for Question or Option\r
1340         //\r
1341         SuppressForQuestion = TRUE;\r
1342       }\r
1343 \r
1344       //\r
1345       // Insert into Form list of this FormSet\r
1346       //\r
1347       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1348       break;\r
1349 \r
1350     //\r
1351     // Storage\r
1352     //\r
1353     case EFI_IFR_VARSTORE_OP:\r
1354       //\r
1355       // Create a buffer Storage for this FormSet\r
1356       //\r
1357       Storage = CreateStorage (FormSet);\r
1358       Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1359 \r
1360       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1361       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
1362       CopyMem (&Storage->Size,       &((EFI_IFR_VARSTORE *) OpCodeData)->Size,       sizeof (UINT16));\r
1363 \r
1364       Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1365       Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1366 \r
1367       AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1368       Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1369       ASSERT (Storage->Name != NULL);\r
1370       for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1371         Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1372       }\r
1373 \r
1374       //\r
1375       // Initialize <ConfigHdr>\r
1376       //\r
1377       InitializeConfigHdr (FormSet, Storage);\r
1378       break;\r
1379 \r
1380     case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1381       //\r
1382       // Create a name/value Storage for this FormSet\r
1383       //\r
1384       Storage = CreateStorage (FormSet);\r
1385       Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1386 \r
1387       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1388       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
1389 \r
1390       //\r
1391       // Initialize <ConfigHdr>\r
1392       //\r
1393       InitializeConfigHdr (FormSet, Storage);\r
1394       break;\r
1395 \r
1396     case EFI_IFR_VARSTORE_EFI_OP:\r
1397       //\r
1398       // Create a EFI variable Storage for this FormSet\r
1399       //\r
1400       Storage = CreateStorage (FormSet);\r
1401       Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1402 \r
1403       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1404       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
1405       CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1406       break;\r
1407 \r
1408     //\r
1409     // DefaultStore\r
1410     //\r
1411     case EFI_IFR_DEFAULTSTORE_OP:\r
1412       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1413       ASSERT (DefaultStore != NULL);\r
1414       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1415 \r
1416       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));\r
1417       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1418 \r
1419       //\r
1420       // Insert to DefaultStore list of this Formset\r
1421       //\r
1422       InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1423       break;\r
1424 \r
1425     //\r
1426     // Statements\r
1427     //\r
1428     case EFI_IFR_SUBTITLE_OP:\r
1429       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1430       ASSERT (CurrentStatement != NULL);\r
1431 \r
1432       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1433 \r
1434       if (Scope != 0) {\r
1435         mInScopeSubtitle = TRUE;\r
1436       }\r
1437       break;\r
1438 \r
1439     case EFI_IFR_TEXT_OP:\r
1440       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1441       ASSERT (CurrentStatement != NULL);\r
1442 \r
1443       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1444       break;\r
1445 \r
1446     case EFI_IFR_RESET_BUTTON_OP:\r
1447       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1448       ASSERT (CurrentStatement != NULL);\r
1449       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1450       break;\r
1451 \r
1452     //\r
1453     // Questions\r
1454     //\r
1455     case EFI_IFR_ACTION_OP:\r
1456       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1457       ASSERT (CurrentStatement != NULL);\r
1458       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
1459 \r
1460       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1461         //\r
1462         // No QuestionConfig present, so no configuration string will be processed\r
1463         //\r
1464         CurrentStatement->QuestionConfig = 0;\r
1465       } else {\r
1466         CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1467       }\r
1468       break;\r
1469 \r
1470     case EFI_IFR_REF_OP:\r
1471       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1472       ASSERT (CurrentStatement != NULL);\r
1473       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;\r
1474       CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
1475       if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1476         CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1477 \r
1478         if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1479           CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1480 \r
1481           if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1482             CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1483           }\r
1484         }\r
1485       }\r
1486       break;\r
1487 \r
1488     case EFI_IFR_ONE_OF_OP:\r
1489     case EFI_IFR_NUMERIC_OP:\r
1490       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1491       ASSERT(CurrentStatement != NULL);\r
1492 \r
1493       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1494       Value = &CurrentStatement->HiiValue;\r
1495 \r
1496       switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1497       case EFI_IFR_NUMERIC_SIZE_1:\r
1498         CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1499         CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1500         CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1501         CurrentStatement->StorageWidth = sizeof (UINT8);\r
1502         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1503         break;\r
1504 \r
1505       case EFI_IFR_NUMERIC_SIZE_2:\r
1506         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1507         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1508         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));\r
1509         CurrentStatement->StorageWidth = sizeof (UINT16);\r
1510         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1511         break;\r
1512 \r
1513       case EFI_IFR_NUMERIC_SIZE_4:\r
1514         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1515         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1516         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));\r
1517         CurrentStatement->StorageWidth = sizeof (UINT32);\r
1518         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1519         break;\r
1520 \r
1521       case EFI_IFR_NUMERIC_SIZE_8:\r
1522         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1523         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1524         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));\r
1525         CurrentStatement->StorageWidth = sizeof (UINT64);\r
1526         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1527         break;\r
1528 \r
1529       default:\r
1530         break;\r
1531       }\r
1532 \r
1533       InitializeRequestElement (FormSet, CurrentStatement);\r
1534 \r
1535       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
1536         SuppressForOption = TRUE;\r
1537       }\r
1538       break;\r
1539 \r
1540     case EFI_IFR_ORDERED_LIST_OP:\r
1541       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1542       ASSERT(CurrentStatement != NULL);\r
1543 \r
1544       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1545       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
1546 \r
1547       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
1548       CurrentStatement->BufferValue = NULL;\r
1549 \r
1550       if (Scope != 0) {\r
1551         SuppressForOption = TRUE;\r
1552       }\r
1553       break;\r
1554 \r
1555     case EFI_IFR_CHECKBOX_OP:\r
1556       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1557       ASSERT(CurrentStatement != NULL);\r
1558 \r
1559       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
1560       CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
1561       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1562 \r
1563       InitializeRequestElement (FormSet, CurrentStatement);\r
1564 \r
1565       break;\r
1566 \r
1567     case EFI_IFR_STRING_OP:\r
1568       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1569       ASSERT (CurrentStatement != NULL);\r
1570       //\r
1571       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1572       // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1573       // The characters are stored as Unicode, so the storage width should multiply 2.\r
1574       //\r
1575       CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1576       CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1577       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1578       CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1579 \r
1580       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1581       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
1582 \r
1583       InitializeRequestElement (FormSet, CurrentStatement);\r
1584       break;\r
1585 \r
1586     case EFI_IFR_PASSWORD_OP:\r
1587       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1588       ASSERT (CurrentStatement != NULL);\r
1589       //\r
1590       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1591       // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1592       // The characters are stored as Unicode, so the storage width should multiply 2.\r
1593       //\r
1594       CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1595       CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1596       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1597 \r
1598       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1599       CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
1600 \r
1601       InitializeRequestElement (FormSet, CurrentStatement);\r
1602       break;\r
1603 \r
1604     case EFI_IFR_DATE_OP:\r
1605       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1606       ASSERT(CurrentStatement != NULL);\r
1607 \r
1608       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1609       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1610 \r
1611       if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
1612         CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
1613 \r
1614         InitializeRequestElement (FormSet, CurrentStatement);\r
1615       } else {\r
1616         //\r
1617         // Don't assign storage for RTC type of date/time\r
1618         //\r
1619         CurrentStatement->Storage = NULL;\r
1620         CurrentStatement->StorageWidth = 0;\r
1621       }\r
1622       break;\r
1623 \r
1624     case EFI_IFR_TIME_OP:\r
1625       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1626       ASSERT(CurrentStatement != NULL);\r
1627 \r
1628       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1629       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1630 \r
1631       if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
1632         CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
1633 \r
1634         InitializeRequestElement (FormSet, CurrentStatement);\r
1635       } else {\r
1636         //\r
1637         // Don't assign storage for RTC type of date/time\r
1638         //\r
1639         CurrentStatement->Storage = NULL;\r
1640         CurrentStatement->StorageWidth = 0;\r
1641       }\r
1642       break;\r
1643 \r
1644     //\r
1645     // Default\r
1646     //\r
1647     case EFI_IFR_DEFAULT_OP:\r
1648       //\r
1649       // EFI_IFR_DEFAULT appear in scope of a Question,\r
1650       // It creates a default value for the current question.\r
1651       // A Question may have more than one Default value which have different default types.\r
1652       //\r
1653       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1654       ASSERT (CurrentDefault != NULL);\r
1655       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1656 \r
1657       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1658       CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1659       CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1660       ExtendValueToU64 (&CurrentDefault->Value);\r
1661 \r
1662       //\r
1663       // Insert to Default Value list of current Question\r
1664       //\r
1665       InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1666 \r
1667       if (Scope != 0) {\r
1668         InScopeDefault = TRUE;\r
1669       }\r
1670       break;\r
1671 \r
1672     //\r
1673     // Option\r
1674     //\r
1675     case EFI_IFR_ONE_OF_OPTION_OP:\r
1676       //\r
1677       // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1678       // It create a selection for use in current Question.\r
1679       //\r
1680       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1681       ASSERT (CurrentOption != NULL);\r
1682       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1683 \r
1684       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1685       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1686       CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1687       CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1688       ExtendValueToU64 (&CurrentOption->Value);\r
1689 \r
1690       if (InScopeOptionSuppress) {\r
1691         CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1692       }\r
1693 \r
1694       //\r
1695       // Insert to Option list of current Question\r
1696       //\r
1697       InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
1698 \r
1699       //\r
1700       // Now we know the Storage width of nested Ordered List\r
1701       //\r
1702       ASSERT (CurrentStatement != NULL);\r
1703       if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
1704         Width = 1;\r
1705         switch (CurrentOption->Value.Type) {\r
1706         case EFI_IFR_TYPE_NUM_SIZE_8:\r
1707           Width = 1;\r
1708           break;\r
1709 \r
1710         case EFI_IFR_TYPE_NUM_SIZE_16:\r
1711           Width = 2;\r
1712           break;\r
1713 \r
1714         case EFI_IFR_TYPE_NUM_SIZE_32:\r
1715           Width = 4;\r
1716           break;\r
1717 \r
1718         case EFI_IFR_TYPE_NUM_SIZE_64:\r
1719           Width = 8;\r
1720           break;\r
1721 \r
1722         default:\r
1723           //\r
1724           // Invalid type for Ordered List\r
1725           //\r
1726           break;\r
1727         }\r
1728 \r
1729         CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
1730         CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1731         CurrentStatement->ValueType = CurrentOption->Value.Type;\r
1732 \r
1733         InitializeRequestElement (FormSet, CurrentStatement);\r
1734       }\r
1735       break;\r
1736 \r
1737     //\r
1738     // Conditional\r
1739     //\r
1740     case EFI_IFR_NO_SUBMIT_IF_OP:\r
1741     case EFI_IFR_INCONSISTENT_IF_OP:\r
1742       //\r
1743       // Create an Expression node\r
1744       //\r
1745       CurrentExpression = CreateExpression (CurrentForm);\r
1746       CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1747 \r
1748       if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1749         CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1750         InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1751       } else {\r
1752         CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1753         InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1754       }\r
1755 \r
1756       //\r
1757       // Take a look at next OpCode to see whether current expression consists\r
1758       // of single OpCode\r
1759       //\r
1760       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1761         SingleOpCodeExpression = TRUE;\r
1762       }\r
1763       break;\r
1764 \r
1765     case EFI_IFR_SUPPRESS_IF_OP:\r
1766       //\r
1767       // Question and Option will appear in scope of this OpCode\r
1768       //\r
1769       CurrentExpression = CreateExpression (CurrentForm);\r
1770       CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
1771 \r
1772       if (CurrentForm == NULL) {\r
1773         InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
1774       } else {\r
1775         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1776       }\r
1777 \r
1778       if (SuppressForOption) {\r
1779         InScopeOptionSuppress = TRUE;\r
1780         OptionSuppressExpression = CurrentExpression;\r
1781       } else if (SuppressForQuestion) {\r
1782         mInScopeSuppress = TRUE;\r
1783         mSuppressExpression = CurrentExpression;\r
1784       } else {\r
1785         InScopeFormSuppress = TRUE;\r
1786         FormSuppressExpression = CurrentExpression;\r
1787       }\r
1788 \r
1789       //\r
1790       // Take a look at next OpCode to see whether current expression consists\r
1791       // of single OpCode\r
1792       //\r
1793       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1794         SingleOpCodeExpression = TRUE;\r
1795       }\r
1796       break;\r
1797 \r
1798     case EFI_IFR_GRAY_OUT_IF_OP:\r
1799       //\r
1800       // Questions will appear in scope of this OpCode\r
1801       //\r
1802       CurrentExpression = CreateExpression (CurrentForm);\r
1803       CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1804       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1805 \r
1806       mInScopeGrayOut = TRUE;\r
1807       mGrayOutExpression = CurrentExpression;\r
1808 \r
1809       //\r
1810       // Take a look at next OpCode to see whether current expression consists\r
1811       // of single OpCode\r
1812       //\r
1813       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1814         SingleOpCodeExpression = TRUE;\r
1815       }\r
1816       break;\r
1817 \r
1818     case EFI_IFR_DISABLE_IF_OP:\r
1819       //\r
1820       // The DisableIf expression should only rely on constant, so it could be\r
1821       // evaluated at initialization and it will not be queued\r
1822       //\r
1823       CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1824       ASSERT (CurrentExpression != NULL);\r
1825       CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1826       CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1827       InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1828 \r
1829       if (CurrentForm != NULL) {\r
1830         //\r
1831         // This is DisableIf for Question, enqueue it to Form expression list\r
1832         //\r
1833         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1834       }\r
1835 \r
1836       mDisableExpression = CurrentExpression;\r
1837       mInScopeDisable    = TRUE;\r
1838       OpCodeDisabled     = FALSE;\r
1839 \r
1840       //\r
1841       // Take a look at next OpCode to see whether current expression consists\r
1842       // of single OpCode\r
1843       //\r
1844       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1845         SingleOpCodeExpression = TRUE;\r
1846       }\r
1847       break;\r
1848 \r
1849     //\r
1850     // Expression\r
1851     //\r
1852     case EFI_IFR_VALUE_OP:\r
1853       CurrentExpression = CreateExpression (CurrentForm);\r
1854       CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1855       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1856 \r
1857       if (InScopeDefault) {\r
1858         //\r
1859         // Used for default (EFI_IFR_DEFAULT)\r
1860         //\r
1861         CurrentDefault->ValueExpression = CurrentExpression;\r
1862       } else {\r
1863         //\r
1864         // If used for a question, then the question will be read-only\r
1865         //\r
1866         //\r
1867         // Make sure CurrentStatement is not NULL.\r
1868         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1869         // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1870         //\r
1871         ASSERT (CurrentStatement != NULL);\r
1872         CurrentStatement->ValueExpression = CurrentExpression;\r
1873       }\r
1874 \r
1875       //\r
1876       // Take a look at next OpCode to see whether current expression consists\r
1877       // of single OpCode\r
1878       //\r
1879       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1880         SingleOpCodeExpression = TRUE;\r
1881       }\r
1882       break;\r
1883 \r
1884     case EFI_IFR_RULE_OP:\r
1885       CurrentExpression = CreateExpression (CurrentForm);\r
1886       CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1887 \r
1888       CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1889       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1890 \r
1891       //\r
1892       // Take a look at next OpCode to see whether current expression consists\r
1893       // of single OpCode\r
1894       //\r
1895       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1896         SingleOpCodeExpression = TRUE;\r
1897       }\r
1898       break;\r
1899 \r
1900     case EFI_IFR_READ_OP:\r
1901       CurrentExpression = CreateExpression (CurrentForm);\r
1902       CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
1903       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1904 \r
1905       //\r
1906       // Make sure CurrentStatement is not NULL.\r
1907       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1908       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1909       //\r
1910       ASSERT (CurrentStatement != NULL);\r
1911       CurrentStatement->ReadExpression = CurrentExpression;\r
1912 \r
1913       //\r
1914       // Take a look at next OpCode to see whether current expression consists\r
1915       // of single OpCode\r
1916       //\r
1917       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1918         SingleOpCodeExpression = TRUE;\r
1919       }\r
1920       break;\r
1921 \r
1922     case EFI_IFR_WRITE_OP:\r
1923       CurrentExpression = CreateExpression (CurrentForm);\r
1924       CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
1925       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1926 \r
1927       //\r
1928       // Make sure CurrentStatement is not NULL.\r
1929       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1930       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1931       //\r
1932       ASSERT (CurrentStatement != NULL);\r
1933       CurrentStatement->WriteExpression = CurrentExpression;\r
1934 \r
1935       //\r
1936       // Take a look at next OpCode to see whether current expression consists\r
1937       // of single OpCode\r
1938       //\r
1939       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1940         SingleOpCodeExpression = TRUE;\r
1941       }\r
1942       break;\r
1943 \r
1944     //\r
1945     // Image\r
1946     //\r
1947     case EFI_IFR_IMAGE_OP:\r
1948       //\r
1949       // Get ScopeOpcode from top of stack\r
1950       //\r
1951       PopScope (&ScopeOpCode);\r
1952       PushScope (ScopeOpCode);\r
1953 \r
1954       switch (ScopeOpCode) {\r
1955       case EFI_IFR_FORM_SET_OP:\r
1956         ImageId = &FormSet->ImageId;\r
1957         break;\r
1958 \r
1959       case EFI_IFR_FORM_OP:\r
1960       case EFI_IFR_FORM_MAP_OP:\r
1961         ASSERT (CurrentForm != NULL);\r
1962         ImageId = &CurrentForm->ImageId;\r
1963         break;\r
1964 \r
1965       case EFI_IFR_ONE_OF_OPTION_OP:\r
1966         ImageId = &CurrentOption->ImageId;\r
1967         break;\r
1968 \r
1969       default:\r
1970         //\r
1971         // Make sure CurrentStatement is not NULL.\r
1972         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1973         // file is wrongly generated by tools such as VFR Compiler.\r
1974         //\r
1975         ASSERT (CurrentStatement != NULL);\r
1976         ImageId = &CurrentStatement->ImageId;\r
1977         break;\r
1978       }\r
1979 \r
1980       ASSERT (ImageId != NULL);\r
1981       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
1982       break;\r
1983 \r
1984     //\r
1985     // Refresh\r
1986     //\r
1987     case EFI_IFR_REFRESH_OP:\r
1988       ASSERT (CurrentStatement != NULL);\r
1989       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
1990       break;\r
1991 \r
1992     //\r
1993     // Vendor specific\r
1994     //\r
1995     case EFI_IFR_GUID_OP:\r
1996       if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
1997         //\r
1998         // Tiano specific GUIDed opcodes\r
1999         //\r
2000         switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
2001         case EFI_IFR_EXTEND_OP_LABEL:\r
2002           //\r
2003           // just ignore label\r
2004           //\r
2005           break;\r
2006 \r
2007         case EFI_IFR_EXTEND_OP_BANNER:\r
2008           //\r
2009           // By SubClass to get Banner Data from Front Page\r
2010           //\r
2011           if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
2012             CopyMem (\r
2013               &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
2014               ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
2015               &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
2016               sizeof (EFI_STRING_ID)\r
2017               );\r
2018           }\r
2019           break;\r
2020 \r
2021         case EFI_IFR_EXTEND_OP_CLASS:\r
2022           CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
2023           break;\r
2024 \r
2025         case EFI_IFR_EXTEND_OP_SUBCLASS:\r
2026           CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
2027           break;\r
2028 \r
2029         default:\r
2030           break;\r
2031         }\r
2032       }\r
2033 \r
2034       break;\r
2035 \r
2036     //\r
2037     // Scope End\r
2038     //\r
2039     case EFI_IFR_END_OP:\r
2040       Status = PopScope (&ScopeOpCode);\r
2041       if (EFI_ERROR (Status)) {\r
2042         ResetScopeStack ();\r
2043         return Status;\r
2044       }\r
2045 \r
2046       switch (ScopeOpCode) {\r
2047       case EFI_IFR_FORM_SET_OP:\r
2048         //\r
2049         // End of FormSet, update FormSet IFR binary length\r
2050         // to stop parsing substantial OpCodes\r
2051         //\r
2052         FormSet->IfrBinaryLength = OpCodeOffset;\r
2053         break;\r
2054 \r
2055       case EFI_IFR_FORM_OP:\r
2056       case EFI_IFR_FORM_MAP_OP:\r
2057         //\r
2058         // End of Form\r
2059         //\r
2060         CurrentForm = NULL;\r
2061         SuppressForQuestion = FALSE;\r
2062         break;\r
2063 \r
2064       case EFI_IFR_ONE_OF_OPTION_OP:\r
2065         //\r
2066         // End of Option\r
2067         //\r
2068         CurrentOption = NULL;\r
2069         break;\r
2070 \r
2071       case EFI_IFR_SUBTITLE_OP:\r
2072         mInScopeSubtitle = FALSE;\r
2073         break;\r
2074 \r
2075       case EFI_IFR_NO_SUBMIT_IF_OP:\r
2076       case EFI_IFR_INCONSISTENT_IF_OP:\r
2077         //\r
2078         // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
2079         //\r
2080         break;\r
2081 \r
2082       case EFI_IFR_SUPPRESS_IF_OP:\r
2083         if (SuppressForOption) {\r
2084           InScopeOptionSuppress = FALSE;\r
2085         } else if (SuppressForQuestion) {\r
2086           mInScopeSuppress = FALSE;\r
2087         } else {\r
2088           InScopeFormSuppress = FALSE;\r
2089         }\r
2090         break;\r
2091 \r
2092       case EFI_IFR_GRAY_OUT_IF_OP:\r
2093         mInScopeGrayOut = FALSE;\r
2094         break;\r
2095 \r
2096       case EFI_IFR_DISABLE_IF_OP:\r
2097         mInScopeDisable = FALSE;\r
2098         OpCodeDisabled = FALSE;\r
2099         break;\r
2100 \r
2101       case EFI_IFR_ONE_OF_OP:\r
2102       case EFI_IFR_ORDERED_LIST_OP:\r
2103         SuppressForOption = FALSE;\r
2104         break;\r
2105 \r
2106       case EFI_IFR_DEFAULT_OP:\r
2107         InScopeDefault = FALSE;\r
2108         break;\r
2109 \r
2110       case EFI_IFR_MAP_OP:\r
2111         //\r
2112         // Get current Map Expression List.\r
2113         //\r
2114         Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r
2115         if (Status == EFI_ACCESS_DENIED) {\r
2116           MapExpressionList = NULL;\r
2117         }\r
2118         //\r
2119         // Get current expression.\r
2120         //\r
2121         Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r
2122         ASSERT_EFI_ERROR (Status);\r
2123         MapScopeDepth --;\r
2124         break;\r
2125 \r
2126       default:\r
2127         if (IsExpressionOpCode (ScopeOpCode)) {\r
2128           if (mInScopeDisable && CurrentForm == NULL) {\r
2129             //\r
2130             // This is DisableIf expression for Form, it should be a constant expression\r
2131             //\r
2132             ASSERT (CurrentExpression != NULL);\r
2133             Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
2134             if (EFI_ERROR (Status)) {\r
2135               return Status;\r
2136             }\r
2137 \r
2138             if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
2139               return EFI_INVALID_PARAMETER;\r
2140             }\r
2141 \r
2142             OpCodeDisabled = CurrentExpression->Result.Value.b;\r
2143             //\r
2144             // DisableIf Expression is only used once and not queued, free it\r
2145             //\r
2146             DestroyExpression (CurrentExpression);\r
2147           }\r
2148 \r
2149           //\r
2150           // End of current Expression\r
2151           //\r
2152           CurrentExpression = NULL;\r
2153         }\r
2154         break;\r
2155       }\r
2156       break;\r
2157 \r
2158     default:\r
2159       break;\r
2160     }\r
2161   }\r
2162 \r
2163   return EFI_SUCCESS;\r
2164 }\r