Add the missing check for NULL pointer before use it.
[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         ASSERT (MapExpressionList != NULL);\r
1178         InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
1179         if (Scope == 0) {\r
1180           SingleOpCodeExpression = TRUE;\r
1181         }\r
1182       }\r
1183       ASSERT (CurrentExpression != NULL);\r
1184       InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
1185       if (Operand == EFI_IFR_MAP_OP) {\r
1186         //\r
1187         // Store current Map Expression List.\r
1188         //\r
1189         if (MapExpressionList != NULL) {\r
1190           PushMapExpressionList (MapExpressionList);\r
1191         }\r
1192         //\r
1193         // Initialize new Map Expression List.\r
1194         //\r
1195         MapExpressionList = &ExpressionOpCode->MapExpressionList;\r
1196         InitializeListHead (MapExpressionList);\r
1197         //\r
1198         // Store current expression.\r
1199         //\r
1200         PushCurrentExpression (CurrentExpression);\r
1201         CurrentExpression = NULL;\r
1202         MapScopeDepth ++;\r
1203       } else if (SingleOpCodeExpression) {\r
1204         //\r
1205         // There are two cases to indicate the end of an Expression:\r
1206         // for single OpCode expression: one Expression OpCode\r
1207         // for expression consists of more than one OpCode: EFI_IFR_END\r
1208         //\r
1209         SingleOpCodeExpression = FALSE;\r
1210 \r
1211         if (mInScopeDisable && CurrentForm == NULL) {\r
1212           //\r
1213           // This is DisableIf expression for Form, it should be a constant expression\r
1214           //\r
1215           Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1216           if (EFI_ERROR (Status)) {\r
1217             return Status;\r
1218           }\r
1219 \r
1220           if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1221             return EFI_INVALID_PARAMETER;\r
1222           }\r
1223 \r
1224           OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1225         }\r
1226 \r
1227         CurrentExpression = NULL;\r
1228       }\r
1229 \r
1230       continue;\r
1231     }\r
1232 \r
1233     //\r
1234     // Parse the Opcode\r
1235     //\r
1236     switch (Operand) {\r
1237 \r
1238     case EFI_IFR_FORM_SET_OP:\r
1239       //\r
1240       // Check the formset GUID\r
1241       //\r
1242       if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1243         return EFI_INVALID_PARAMETER;\r
1244       }\r
1245 \r
1246       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1247       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));\r
1248 \r
1249       if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
1250         //\r
1251         // The formset OpCode contains ClassGuid\r
1252         //\r
1253         FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1254         CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
1255       }\r
1256 \r
1257       InitializeListHead (&FormSet->ExpressionListHead);\r
1258       break;\r
1259 \r
1260     case EFI_IFR_FORM_OP:\r
1261       //\r
1262       // Create a new Form for this FormSet\r
1263       //\r
1264       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1265       ASSERT (CurrentForm != NULL);\r
1266       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1267       InitializeListHead (&CurrentForm->ExpressionListHead);\r
1268       InitializeListHead (&CurrentForm->StatementListHead);\r
1269 \r
1270       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1271       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
1272       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1273 \r
1274       if (InScopeFormSuppress) {\r
1275         //\r
1276         // Form is inside of suppressif\r
1277         //\r
1278         CurrentForm->SuppressExpression = FormSuppressExpression;\r
1279       }\r
1280 \r
1281       if (Scope != 0) {\r
1282         //\r
1283         // Enter scope of a Form, suppressif will be used for Question or Option\r
1284         //\r
1285         SuppressForQuestion = TRUE;\r
1286       }\r
1287 \r
1288       //\r
1289       // Insert into Form list of this FormSet\r
1290       //\r
1291       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1292       break;\r
1293 \r
1294     case EFI_IFR_FORM_MAP_OP:\r
1295       //\r
1296       // Create a new Form for this FormSet\r
1297       //\r
1298       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1299       ASSERT (CurrentForm != NULL);\r
1300       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1301       InitializeListHead (&CurrentForm->ExpressionListHead);\r
1302       InitializeListHead (&CurrentForm->StatementListHead);\r
1303       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1304 \r
1305       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1306       //\r
1307       // FormMap Form must contain at least one Map Method.\r
1308       //\r
1309       if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
1310         return EFI_INVALID_PARAMETER;\r
1311       }\r
1312       //\r
1313       // Try to find the standard form map method.\r
1314       //\r
1315       while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
1316         if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
1317           CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1318           CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1319           break;\r
1320         }\r
1321         MapMethod ++;\r
1322       }\r
1323       //\r
1324       // If the standard form map method is not found, the first map method title will be used.\r
1325       //\r
1326       if (CurrentForm->FormTitle == 0) {\r
1327         MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1328         CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1329       }\r
1330 \r
1331       if (InScopeFormSuppress) {\r
1332         //\r
1333         // Form is inside of suppressif\r
1334         //\r
1335         CurrentForm->SuppressExpression = FormSuppressExpression;\r
1336       }\r
1337 \r
1338       if (Scope != 0) {\r
1339         //\r
1340         // Enter scope of a Form, suppressif will be used for Question or Option\r
1341         //\r
1342         SuppressForQuestion = TRUE;\r
1343       }\r
1344 \r
1345       //\r
1346       // Insert into Form list of this FormSet\r
1347       //\r
1348       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1349       break;\r
1350 \r
1351     //\r
1352     // Storage\r
1353     //\r
1354     case EFI_IFR_VARSTORE_OP:\r
1355       //\r
1356       // Create a buffer Storage for this FormSet\r
1357       //\r
1358       Storage = CreateStorage (FormSet);\r
1359       Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1360 \r
1361       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1362       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
1363       CopyMem (&Storage->Size,       &((EFI_IFR_VARSTORE *) OpCodeData)->Size,       sizeof (UINT16));\r
1364 \r
1365       Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1366       Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1367 \r
1368       AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1369       Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1370       ASSERT (Storage->Name != NULL);\r
1371       for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1372         Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1373       }\r
1374 \r
1375       //\r
1376       // Initialize <ConfigHdr>\r
1377       //\r
1378       InitializeConfigHdr (FormSet, Storage);\r
1379       break;\r
1380 \r
1381     case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1382       //\r
1383       // Create a name/value Storage for this FormSet\r
1384       //\r
1385       Storage = CreateStorage (FormSet);\r
1386       Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1387 \r
1388       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1389       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
1390 \r
1391       //\r
1392       // Initialize <ConfigHdr>\r
1393       //\r
1394       InitializeConfigHdr (FormSet, Storage);\r
1395       break;\r
1396 \r
1397     case EFI_IFR_VARSTORE_EFI_OP:\r
1398       //\r
1399       // Create a EFI variable Storage for this FormSet\r
1400       //\r
1401       Storage = CreateStorage (FormSet);\r
1402       Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1403 \r
1404       CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1405       CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
1406       CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1407       break;\r
1408 \r
1409     //\r
1410     // DefaultStore\r
1411     //\r
1412     case EFI_IFR_DEFAULTSTORE_OP:\r
1413       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1414       ASSERT (DefaultStore != NULL);\r
1415       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1416 \r
1417       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));\r
1418       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1419 \r
1420       //\r
1421       // Insert to DefaultStore list of this Formset\r
1422       //\r
1423       InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1424       break;\r
1425 \r
1426     //\r
1427     // Statements\r
1428     //\r
1429     case EFI_IFR_SUBTITLE_OP:\r
1430       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1431       ASSERT (CurrentStatement != NULL);\r
1432 \r
1433       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1434 \r
1435       if (Scope != 0) {\r
1436         mInScopeSubtitle = TRUE;\r
1437       }\r
1438       break;\r
1439 \r
1440     case EFI_IFR_TEXT_OP:\r
1441       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1442       ASSERT (CurrentStatement != NULL);\r
1443 \r
1444       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1445       break;\r
1446 \r
1447     case EFI_IFR_RESET_BUTTON_OP:\r
1448       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1449       ASSERT (CurrentStatement != NULL);\r
1450       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1451       break;\r
1452 \r
1453     //\r
1454     // Questions\r
1455     //\r
1456     case EFI_IFR_ACTION_OP:\r
1457       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1458       ASSERT (CurrentStatement != NULL);\r
1459       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
1460 \r
1461       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1462         //\r
1463         // No QuestionConfig present, so no configuration string will be processed\r
1464         //\r
1465         CurrentStatement->QuestionConfig = 0;\r
1466       } else {\r
1467         CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1468       }\r
1469       break;\r
1470 \r
1471     case EFI_IFR_REF_OP:\r
1472       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1473       ASSERT (CurrentStatement != NULL);\r
1474       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;\r
1475       CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
1476       if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1477         CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1478 \r
1479         if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1480           CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1481 \r
1482           if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1483             CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1484           }\r
1485         }\r
1486       }\r
1487       break;\r
1488 \r
1489     case EFI_IFR_ONE_OF_OP:\r
1490     case EFI_IFR_NUMERIC_OP:\r
1491       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1492       ASSERT(CurrentStatement != NULL);\r
1493 \r
1494       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1495       Value = &CurrentStatement->HiiValue;\r
1496 \r
1497       switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1498       case EFI_IFR_NUMERIC_SIZE_1:\r
1499         CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1500         CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1501         CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1502         CurrentStatement->StorageWidth = sizeof (UINT8);\r
1503         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1504         break;\r
1505 \r
1506       case EFI_IFR_NUMERIC_SIZE_2:\r
1507         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1508         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1509         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));\r
1510         CurrentStatement->StorageWidth = sizeof (UINT16);\r
1511         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1512         break;\r
1513 \r
1514       case EFI_IFR_NUMERIC_SIZE_4:\r
1515         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1516         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1517         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));\r
1518         CurrentStatement->StorageWidth = sizeof (UINT32);\r
1519         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1520         break;\r
1521 \r
1522       case EFI_IFR_NUMERIC_SIZE_8:\r
1523         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1524         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1525         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));\r
1526         CurrentStatement->StorageWidth = sizeof (UINT64);\r
1527         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1528         break;\r
1529 \r
1530       default:\r
1531         break;\r
1532       }\r
1533 \r
1534       InitializeRequestElement (FormSet, CurrentStatement);\r
1535 \r
1536       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
1537         SuppressForOption = TRUE;\r
1538       }\r
1539       break;\r
1540 \r
1541     case EFI_IFR_ORDERED_LIST_OP:\r
1542       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1543       ASSERT(CurrentStatement != NULL);\r
1544 \r
1545       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1546       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
1547 \r
1548       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
1549       CurrentStatement->BufferValue = NULL;\r
1550 \r
1551       if (Scope != 0) {\r
1552         SuppressForOption = TRUE;\r
1553       }\r
1554       break;\r
1555 \r
1556     case EFI_IFR_CHECKBOX_OP:\r
1557       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1558       ASSERT(CurrentStatement != NULL);\r
1559 \r
1560       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
1561       CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
1562       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1563 \r
1564       InitializeRequestElement (FormSet, CurrentStatement);\r
1565 \r
1566       break;\r
1567 \r
1568     case EFI_IFR_STRING_OP:\r
1569       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1570       ASSERT (CurrentStatement != NULL);\r
1571       //\r
1572       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1573       // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1574       // The characters are stored as Unicode, so the storage width should multiply 2.\r
1575       //\r
1576       CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1577       CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1578       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1579       CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1580 \r
1581       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1582       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
1583 \r
1584       InitializeRequestElement (FormSet, CurrentStatement);\r
1585       break;\r
1586 \r
1587     case EFI_IFR_PASSWORD_OP:\r
1588       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1589       ASSERT (CurrentStatement != NULL);\r
1590       //\r
1591       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1592       // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1593       // The characters are stored as Unicode, so the storage width should multiply 2.\r
1594       //\r
1595       CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1596       CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1597       CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1598 \r
1599       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1600       CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
1601 \r
1602       InitializeRequestElement (FormSet, CurrentStatement);\r
1603       break;\r
1604 \r
1605     case EFI_IFR_DATE_OP:\r
1606       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1607       ASSERT(CurrentStatement != NULL);\r
1608 \r
1609       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1610       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1611 \r
1612       if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
1613         CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
1614 \r
1615         InitializeRequestElement (FormSet, CurrentStatement);\r
1616       } else {\r
1617         //\r
1618         // Don't assign storage for RTC type of date/time\r
1619         //\r
1620         CurrentStatement->Storage = NULL;\r
1621         CurrentStatement->StorageWidth = 0;\r
1622       }\r
1623       break;\r
1624 \r
1625     case EFI_IFR_TIME_OP:\r
1626       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1627       ASSERT(CurrentStatement != NULL);\r
1628 \r
1629       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1630       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1631 \r
1632       if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
1633         CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
1634 \r
1635         InitializeRequestElement (FormSet, CurrentStatement);\r
1636       } else {\r
1637         //\r
1638         // Don't assign storage for RTC type of date/time\r
1639         //\r
1640         CurrentStatement->Storage = NULL;\r
1641         CurrentStatement->StorageWidth = 0;\r
1642       }\r
1643       break;\r
1644 \r
1645     //\r
1646     // Default\r
1647     //\r
1648     case EFI_IFR_DEFAULT_OP:\r
1649       //\r
1650       // EFI_IFR_DEFAULT appear in scope of a Question,\r
1651       // It creates a default value for the current question.\r
1652       // A Question may have more than one Default value which have different default types.\r
1653       //\r
1654       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1655       ASSERT (CurrentDefault != NULL);\r
1656       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1657 \r
1658       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1659       CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1660       CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1661       ExtendValueToU64 (&CurrentDefault->Value);\r
1662 \r
1663       //\r
1664       // Insert to Default Value list of current Question\r
1665       //\r
1666       InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1667 \r
1668       if (Scope != 0) {\r
1669         InScopeDefault = TRUE;\r
1670       }\r
1671       break;\r
1672 \r
1673     //\r
1674     // Option\r
1675     //\r
1676     case EFI_IFR_ONE_OF_OPTION_OP:\r
1677       //\r
1678       // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1679       // It create a selection for use in current Question.\r
1680       //\r
1681       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1682       ASSERT (CurrentOption != NULL);\r
1683       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1684 \r
1685       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1686       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1687       CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1688       CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1689       ExtendValueToU64 (&CurrentOption->Value);\r
1690 \r
1691       if (InScopeOptionSuppress) {\r
1692         CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1693       }\r
1694 \r
1695       //\r
1696       // Insert to Option list of current Question\r
1697       //\r
1698       InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
1699 \r
1700       //\r
1701       // Now we know the Storage width of nested Ordered List\r
1702       //\r
1703       ASSERT (CurrentStatement != NULL);\r
1704       if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
1705         Width = 1;\r
1706         switch (CurrentOption->Value.Type) {\r
1707         case EFI_IFR_TYPE_NUM_SIZE_8:\r
1708           Width = 1;\r
1709           break;\r
1710 \r
1711         case EFI_IFR_TYPE_NUM_SIZE_16:\r
1712           Width = 2;\r
1713           break;\r
1714 \r
1715         case EFI_IFR_TYPE_NUM_SIZE_32:\r
1716           Width = 4;\r
1717           break;\r
1718 \r
1719         case EFI_IFR_TYPE_NUM_SIZE_64:\r
1720           Width = 8;\r
1721           break;\r
1722 \r
1723         default:\r
1724           //\r
1725           // Invalid type for Ordered List\r
1726           //\r
1727           break;\r
1728         }\r
1729 \r
1730         CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
1731         CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1732         CurrentStatement->ValueType = CurrentOption->Value.Type;\r
1733 \r
1734         InitializeRequestElement (FormSet, CurrentStatement);\r
1735       }\r
1736       break;\r
1737 \r
1738     //\r
1739     // Conditional\r
1740     //\r
1741     case EFI_IFR_NO_SUBMIT_IF_OP:\r
1742     case EFI_IFR_INCONSISTENT_IF_OP:\r
1743       //\r
1744       // Create an Expression node\r
1745       //\r
1746       CurrentExpression = CreateExpression (CurrentForm);\r
1747       CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1748 \r
1749       if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1750         CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1751         InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1752       } else {\r
1753         CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1754         InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1755       }\r
1756 \r
1757       //\r
1758       // Take a look at next OpCode to see whether current expression consists\r
1759       // of single OpCode\r
1760       //\r
1761       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1762         SingleOpCodeExpression = TRUE;\r
1763       }\r
1764       break;\r
1765 \r
1766     case EFI_IFR_SUPPRESS_IF_OP:\r
1767       //\r
1768       // Question and Option will appear in scope of this OpCode\r
1769       //\r
1770       CurrentExpression = CreateExpression (CurrentForm);\r
1771       CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
1772 \r
1773       if (CurrentForm == NULL) {\r
1774         InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
1775       } else {\r
1776         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1777       }\r
1778 \r
1779       if (SuppressForOption) {\r
1780         InScopeOptionSuppress = TRUE;\r
1781         OptionSuppressExpression = CurrentExpression;\r
1782       } else if (SuppressForQuestion) {\r
1783         mInScopeSuppress = TRUE;\r
1784         mSuppressExpression = CurrentExpression;\r
1785       } else {\r
1786         InScopeFormSuppress = TRUE;\r
1787         FormSuppressExpression = CurrentExpression;\r
1788       }\r
1789 \r
1790       //\r
1791       // Take a look at next OpCode to see whether current expression consists\r
1792       // of single OpCode\r
1793       //\r
1794       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1795         SingleOpCodeExpression = TRUE;\r
1796       }\r
1797       break;\r
1798 \r
1799     case EFI_IFR_GRAY_OUT_IF_OP:\r
1800       //\r
1801       // Questions will appear in scope of this OpCode\r
1802       //\r
1803       CurrentExpression = CreateExpression (CurrentForm);\r
1804       CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1805       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1806 \r
1807       mInScopeGrayOut = TRUE;\r
1808       mGrayOutExpression = CurrentExpression;\r
1809 \r
1810       //\r
1811       // Take a look at next OpCode to see whether current expression consists\r
1812       // of single OpCode\r
1813       //\r
1814       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1815         SingleOpCodeExpression = TRUE;\r
1816       }\r
1817       break;\r
1818 \r
1819     case EFI_IFR_DISABLE_IF_OP:\r
1820       //\r
1821       // The DisableIf expression should only rely on constant, so it could be\r
1822       // evaluated at initialization and it will not be queued\r
1823       //\r
1824       CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1825       ASSERT (CurrentExpression != NULL);\r
1826       CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1827       CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1828       InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1829 \r
1830       if (CurrentForm != NULL) {\r
1831         //\r
1832         // This is DisableIf for Question, enqueue it to Form expression list\r
1833         //\r
1834         InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1835       }\r
1836 \r
1837       mDisableExpression = CurrentExpression;\r
1838       mInScopeDisable    = TRUE;\r
1839       OpCodeDisabled     = FALSE;\r
1840 \r
1841       //\r
1842       // Take a look at next OpCode to see whether current expression consists\r
1843       // of single OpCode\r
1844       //\r
1845       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1846         SingleOpCodeExpression = TRUE;\r
1847       }\r
1848       break;\r
1849 \r
1850     //\r
1851     // Expression\r
1852     //\r
1853     case EFI_IFR_VALUE_OP:\r
1854       CurrentExpression = CreateExpression (CurrentForm);\r
1855       CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1856       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1857 \r
1858       if (InScopeDefault) {\r
1859         //\r
1860         // Used for default (EFI_IFR_DEFAULT)\r
1861         //\r
1862         CurrentDefault->ValueExpression = CurrentExpression;\r
1863       } else {\r
1864         //\r
1865         // If used for a question, then the question will be read-only\r
1866         //\r
1867         //\r
1868         // Make sure CurrentStatement is not NULL.\r
1869         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1870         // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1871         //\r
1872         ASSERT (CurrentStatement != NULL);\r
1873         CurrentStatement->ValueExpression = CurrentExpression;\r
1874       }\r
1875 \r
1876       //\r
1877       // Take a look at next OpCode to see whether current expression consists\r
1878       // of single OpCode\r
1879       //\r
1880       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1881         SingleOpCodeExpression = TRUE;\r
1882       }\r
1883       break;\r
1884 \r
1885     case EFI_IFR_RULE_OP:\r
1886       CurrentExpression = CreateExpression (CurrentForm);\r
1887       CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1888 \r
1889       CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1890       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1891 \r
1892       //\r
1893       // Take a look at next OpCode to see whether current expression consists\r
1894       // of single OpCode\r
1895       //\r
1896       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1897         SingleOpCodeExpression = TRUE;\r
1898       }\r
1899       break;\r
1900 \r
1901     case EFI_IFR_READ_OP:\r
1902       CurrentExpression = CreateExpression (CurrentForm);\r
1903       CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
1904       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1905 \r
1906       //\r
1907       // Make sure CurrentStatement is not NULL.\r
1908       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1909       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1910       //\r
1911       ASSERT (CurrentStatement != NULL);\r
1912       CurrentStatement->ReadExpression = CurrentExpression;\r
1913 \r
1914       //\r
1915       // Take a look at next OpCode to see whether current expression consists\r
1916       // of single OpCode\r
1917       //\r
1918       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1919         SingleOpCodeExpression = TRUE;\r
1920       }\r
1921       break;\r
1922 \r
1923     case EFI_IFR_WRITE_OP:\r
1924       CurrentExpression = CreateExpression (CurrentForm);\r
1925       CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
1926       InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1927 \r
1928       //\r
1929       // Make sure CurrentStatement is not NULL.\r
1930       // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1931       // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1932       //\r
1933       ASSERT (CurrentStatement != NULL);\r
1934       CurrentStatement->WriteExpression = CurrentExpression;\r
1935 \r
1936       //\r
1937       // Take a look at next OpCode to see whether current expression consists\r
1938       // of single OpCode\r
1939       //\r
1940       if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1941         SingleOpCodeExpression = TRUE;\r
1942       }\r
1943       break;\r
1944 \r
1945     //\r
1946     // Image\r
1947     //\r
1948     case EFI_IFR_IMAGE_OP:\r
1949       //\r
1950       // Get ScopeOpcode from top of stack\r
1951       //\r
1952       PopScope (&ScopeOpCode);\r
1953       PushScope (ScopeOpCode);\r
1954 \r
1955       switch (ScopeOpCode) {\r
1956       case EFI_IFR_FORM_SET_OP:\r
1957         ImageId = &FormSet->ImageId;\r
1958         break;\r
1959 \r
1960       case EFI_IFR_FORM_OP:\r
1961       case EFI_IFR_FORM_MAP_OP:\r
1962         ASSERT (CurrentForm != NULL);\r
1963         ImageId = &CurrentForm->ImageId;\r
1964         break;\r
1965 \r
1966       case EFI_IFR_ONE_OF_OPTION_OP:\r
1967         ImageId = &CurrentOption->ImageId;\r
1968         break;\r
1969 \r
1970       default:\r
1971         //\r
1972         // Make sure CurrentStatement is not NULL.\r
1973         // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1974         // file is wrongly generated by tools such as VFR Compiler.\r
1975         //\r
1976         ASSERT (CurrentStatement != NULL);\r
1977         ImageId = &CurrentStatement->ImageId;\r
1978         break;\r
1979       }\r
1980 \r
1981       ASSERT (ImageId != NULL);\r
1982       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
1983       break;\r
1984 \r
1985     //\r
1986     // Refresh\r
1987     //\r
1988     case EFI_IFR_REFRESH_OP:\r
1989       ASSERT (CurrentStatement != NULL);\r
1990       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
1991       break;\r
1992 \r
1993     //\r
1994     // Vendor specific\r
1995     //\r
1996     case EFI_IFR_GUID_OP:\r
1997       if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
1998         //\r
1999         // Tiano specific GUIDed opcodes\r
2000         //\r
2001         switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
2002         case EFI_IFR_EXTEND_OP_LABEL:\r
2003           //\r
2004           // just ignore label\r
2005           //\r
2006           break;\r
2007 \r
2008         case EFI_IFR_EXTEND_OP_BANNER:\r
2009           //\r
2010           // By SubClass to get Banner Data from Front Page\r
2011           //\r
2012           if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
2013             CopyMem (\r
2014               &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
2015               ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
2016               &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
2017               sizeof (EFI_STRING_ID)\r
2018               );\r
2019           }\r
2020           break;\r
2021 \r
2022         case EFI_IFR_EXTEND_OP_CLASS:\r
2023           CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
2024           break;\r
2025 \r
2026         case EFI_IFR_EXTEND_OP_SUBCLASS:\r
2027           CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
2028           break;\r
2029 \r
2030         default:\r
2031           break;\r
2032         }\r
2033       }\r
2034 \r
2035       break;\r
2036 \r
2037     //\r
2038     // Scope End\r
2039     //\r
2040     case EFI_IFR_END_OP:\r
2041       Status = PopScope (&ScopeOpCode);\r
2042       if (EFI_ERROR (Status)) {\r
2043         ResetScopeStack ();\r
2044         return Status;\r
2045       }\r
2046 \r
2047       switch (ScopeOpCode) {\r
2048       case EFI_IFR_FORM_SET_OP:\r
2049         //\r
2050         // End of FormSet, update FormSet IFR binary length\r
2051         // to stop parsing substantial OpCodes\r
2052         //\r
2053         FormSet->IfrBinaryLength = OpCodeOffset;\r
2054         break;\r
2055 \r
2056       case EFI_IFR_FORM_OP:\r
2057       case EFI_IFR_FORM_MAP_OP:\r
2058         //\r
2059         // End of Form\r
2060         //\r
2061         CurrentForm = NULL;\r
2062         SuppressForQuestion = FALSE;\r
2063         break;\r
2064 \r
2065       case EFI_IFR_ONE_OF_OPTION_OP:\r
2066         //\r
2067         // End of Option\r
2068         //\r
2069         CurrentOption = NULL;\r
2070         break;\r
2071 \r
2072       case EFI_IFR_SUBTITLE_OP:\r
2073         mInScopeSubtitle = FALSE;\r
2074         break;\r
2075 \r
2076       case EFI_IFR_NO_SUBMIT_IF_OP:\r
2077       case EFI_IFR_INCONSISTENT_IF_OP:\r
2078         //\r
2079         // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
2080         //\r
2081         break;\r
2082 \r
2083       case EFI_IFR_SUPPRESS_IF_OP:\r
2084         if (SuppressForOption) {\r
2085           InScopeOptionSuppress = FALSE;\r
2086         } else if (SuppressForQuestion) {\r
2087           mInScopeSuppress = FALSE;\r
2088         } else {\r
2089           InScopeFormSuppress = FALSE;\r
2090         }\r
2091         break;\r
2092 \r
2093       case EFI_IFR_GRAY_OUT_IF_OP:\r
2094         mInScopeGrayOut = FALSE;\r
2095         break;\r
2096 \r
2097       case EFI_IFR_DISABLE_IF_OP:\r
2098         mInScopeDisable = FALSE;\r
2099         OpCodeDisabled = FALSE;\r
2100         break;\r
2101 \r
2102       case EFI_IFR_ONE_OF_OP:\r
2103       case EFI_IFR_ORDERED_LIST_OP:\r
2104         SuppressForOption = FALSE;\r
2105         break;\r
2106 \r
2107       case EFI_IFR_DEFAULT_OP:\r
2108         InScopeDefault = FALSE;\r
2109         break;\r
2110 \r
2111       case EFI_IFR_MAP_OP:\r
2112         //\r
2113         // Get current Map Expression List.\r
2114         //\r
2115         Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r
2116         if (Status == EFI_ACCESS_DENIED) {\r
2117           MapExpressionList = NULL;\r
2118         }\r
2119         //\r
2120         // Get current expression.\r
2121         //\r
2122         Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r
2123         ASSERT_EFI_ERROR (Status);\r
2124         ASSERT (MapScopeDepth > 0);\r
2125         MapScopeDepth --;\r
2126         break;\r
2127 \r
2128       default:\r
2129         if (IsExpressionOpCode (ScopeOpCode)) {\r
2130           if (mInScopeDisable && CurrentForm == NULL) {\r
2131             //\r
2132             // This is DisableIf expression for Form, it should be a constant expression\r
2133             //\r
2134             ASSERT (CurrentExpression != NULL);\r
2135             Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
2136             if (EFI_ERROR (Status)) {\r
2137               return Status;\r
2138             }\r
2139 \r
2140             if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
2141               return EFI_INVALID_PARAMETER;\r
2142             }\r
2143 \r
2144             OpCodeDisabled = CurrentExpression->Result.Value.b;\r
2145             //\r
2146             // DisableIf Expression is only used once and not queued, free it\r
2147             //\r
2148             DestroyExpression (CurrentExpression);\r
2149           }\r
2150 \r
2151           //\r
2152           // End of current Expression\r
2153           //\r
2154           CurrentExpression = NULL;\r
2155         }\r
2156         break;\r
2157       }\r
2158       break;\r
2159 \r
2160     default:\r
2161       break;\r
2162     }\r
2163   }\r
2164 \r
2165   return EFI_SUCCESS;\r
2166 }\r