]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c
add #pragma pack(1) for some structures.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / UefiIfrParser.c
CommitLineData
59336178 1/** @file\r
2Parser for IFR binary encoding.\r
3\r
4Copyright (c) 2008, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiIfrParser.h"\r
16#include "UefiIfrParserExpression.h"\r
17#include "UefiIfrParserInternal.h"\r
18#include "UefiIfrParserCommon.h"\r
19\r
20\r
21UINT16 mStatementIndex;\r
22UINT16 mExpressionOpCodeIndex;\r
23\r
24BOOLEAN mInScopeSubtitle;\r
25BOOLEAN mInScopeSuppress;\r
26BOOLEAN mInScopeGrayOut;\r
27FORM_EXPRESSION *mSuppressExpression;\r
28FORM_EXPRESSION *mGrayOutExpression;\r
29\r
30EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
59336178 31\r
32/**\r
33 Initialize Statement header members.\r
34\r
35 @param OpCodeData Pointer of the raw OpCode data.\r
36 @param FormSet Pointer of the current FormSe.\r
37 @param Form Pointer of the current Form.\r
38\r
39 @return The Statement.\r
40\r
41**/\r
42FORM_BROWSER_STATEMENT *\r
43CreateStatement (\r
44 IN UINT8 *OpCodeData,\r
45 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
46 IN OUT FORM_BROWSER_FORM *Form\r
47 )\r
48{\r
49 FORM_BROWSER_STATEMENT *Statement;\r
50 EFI_IFR_STATEMENT_HEADER *StatementHdr;\r
51\r
52 if (Form == NULL) {\r
53 //\r
54 // We are currently not in a Form Scope, so just skip this Statement\r
55 //\r
56 return NULL;\r
57 }\r
58\r
59 Statement = &FormSet->StatementBuffer[mStatementIndex];\r
60 mStatementIndex++;\r
61\r
62 InitializeListHead (&Statement->DefaultListHead);\r
63 InitializeListHead (&Statement->OptionListHead);\r
64 InitializeListHead (&Statement->InconsistentListHead);\r
65 InitializeListHead (&Statement->NoSubmitListHead);\r
66\r
67 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
68\r
69 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
70\r
71 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
72 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
73 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
74\r
75 if (mInScopeSuppress) {\r
76 Statement->SuppressExpression = mSuppressExpression;\r
77 }\r
78\r
79 if (mInScopeGrayOut) {\r
80 Statement->GrayOutExpression = mGrayOutExpression;\r
81 }\r
82\r
83 Statement->InSubtitle = mInScopeSubtitle;\r
84\r
85 //\r
86 // Insert this Statement into current Form\r
87 //\r
88 InsertTailList (&Form->StatementListHead, &Statement->Link);\r
89\r
90 return Statement;\r
91}\r
92\r
93\r
94/**\r
95 Initialize Question's members.\r
96\r
97 @param OpCodeData Pointer of the raw OpCode data.\r
98 @param FormSet Pointer of the current FormSet.\r
99 @param Form Pointer of the current Form.\r
100\r
101 @return The Question.\r
102\r
103**/\r
104FORM_BROWSER_STATEMENT *\r
105CreateQuestion (\r
106 IN UINT8 *OpCodeData,\r
107 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
108 IN OUT FORM_BROWSER_FORM *Form\r
109 )\r
110{\r
111 FORM_BROWSER_STATEMENT *Statement;\r
112 EFI_IFR_QUESTION_HEADER *QuestionHdr;\r
113 LIST_ENTRY *Link;\r
114 FORMSET_STORAGE *Storage;\r
115 NAME_VALUE_NODE *NameValueNode;\r
116\r
117 Statement = CreateStatement (OpCodeData, FormSet, Form);\r
118 if (Statement == NULL) {\r
119 return NULL;\r
120 }\r
121\r
122 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
123 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
124 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
125 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
126\r
127 Statement->QuestionFlags = QuestionHdr->Flags;\r
128\r
129 if (Statement->VarStoreId == 0) {\r
130 //\r
131 // VarStoreId of zero indicates no variable storage\r
132 //\r
133 return Statement;\r
134 }\r
135\r
136 //\r
137 // Find Storage for this Question\r
138 //\r
139 Link = GetFirstNode (&FormSet->StorageListHead);\r
140 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
141 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
142\r
143 if (Storage->VarStoreId == Statement->VarStoreId) {\r
144 Statement->Storage = Storage;\r
145 break;\r
146 }\r
147\r
148 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
149 }\r
150 ASSERT (Statement->Storage != NULL);\r
151\r
152 //\r
153 // Initialilze varname for Name/Value or EFI Variable\r
154 //\r
155 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
156 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
157 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
158 ASSERT (Statement->VariableName != NULL);\r
159\r
160 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
161 //\r
162 // Insert to Name/Value varstore list\r
163 //\r
164 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
165 ASSERT (NameValueNode != NULL);\r
166 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
167 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
168 ASSERT (NameValueNode->Name != NULL);\r
169 NameValueNode->Value = AllocateZeroPool (0x10);\r
170 ASSERT (NameValueNode->Value != NULL);\r
171 NameValueNode->EditValue = AllocateZeroPool (0x10);\r
172 ASSERT (NameValueNode->EditValue != NULL);\r
173\r
174 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
175 }\r
176 }\r
177\r
178 return Statement;\r
179}\r
180\r
181\r
182/**\r
183 Allocate a FORM_EXPRESSION node.\r
184\r
185 @param Form The Form associated with this Expression\r
186\r
187 @return Pointer to a FORM_EXPRESSION data structure.\r
188\r
189**/\r
190FORM_EXPRESSION *\r
191CreateExpression (\r
192 IN OUT FORM_BROWSER_FORM *Form\r
193 )\r
194{\r
195 FORM_EXPRESSION *Expression;\r
196\r
197 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
198 Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
199 InitializeListHead (&Expression->OpCodeListHead);\r
200\r
201 return Expression;\r
202}\r
203\r
204\r
205/**\r
206 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
207\r
208 @param FormSet Pointer of the current FormSet\r
209\r
210 @return Pointer to a FORMSET_STORAGE data structure.\r
211\r
212**/\r
213FORMSET_STORAGE *\r
214CreateStorage (\r
215 IN FORM_BROWSER_FORMSET *FormSet\r
216 )\r
217{\r
218 FORMSET_STORAGE *Storage;\r
219\r
220 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
221 Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
222 InitializeListHead (&Storage->NameValueListHead);\r
223 InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
224\r
225 return Storage;\r
226}\r
227\r
228\r
229/**\r
230 Create ConfigHdr string for a storage.\r
231\r
232 @param FormSet Pointer of the current FormSet\r
233 @param Storage Pointer of the storage\r
234\r
235 @retval EFI_SUCCESS Initialize ConfigHdr success\r
236\r
237**/\r
238EFI_STATUS\r
239InitializeConfigHdr (\r
240 IN FORM_BROWSER_FORMSET *FormSet,\r
241 IN OUT FORMSET_STORAGE *Storage\r
242 )\r
243{\r
244 EFI_STATUS Status;\r
245 UINTN StrBufferLen;\r
246 CHAR16 *Name;\r
247\r
248 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
249 Name = Storage->Name;\r
250 } else {\r
251 Name = NULL;\r
252 }\r
253\r
254 StrBufferLen = 0;\r
255 Status = ConstructConfigHdr (\r
256 Storage->ConfigHdr,\r
257 &StrBufferLen,\r
258 &Storage->Guid,\r
259 Name,\r
260 FormSet->DriverHandle\r
261 );\r
262 if (Status == EFI_BUFFER_TOO_SMALL) {\r
263 Storage->ConfigHdr = AllocateZeroPool (StrBufferLen);\r
264 Status = ConstructConfigHdr (\r
265 Storage->ConfigHdr,\r
266 &StrBufferLen,\r
267 &Storage->Guid,\r
268 Name,\r
269 FormSet->DriverHandle\r
270 );\r
271 }\r
272\r
273 if (EFI_ERROR (Status)) {\r
274 return Status;\r
275 }\r
276\r
277 Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr);\r
278 Storage->SpareStrLen = 0;\r
279\r
280 return EFI_SUCCESS;\r
281}\r
282\r
283\r
284/**\r
285 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
286\r
287 @param FormSet Pointer of the current FormSet.\r
288 @param Question The Question to be initialized.\r
289\r
290 @retval EFI_SUCCESS Function success.\r
291 @retval EFI_INVALID_PARAMETER No storage associated with the Question.\r
292\r
293**/\r
294EFI_STATUS\r
295InitializeRequestElement (\r
296 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
297 IN OUT FORM_BROWSER_STATEMENT *Question\r
298 )\r
299{\r
300 FORMSET_STORAGE *Storage;\r
301 UINTN StrLen;\r
302 UINTN StringSize;\r
303 CHAR16 *NewStr;\r
304 CHAR16 RequestElement[30];\r
305\r
306 Storage = Question->Storage;\r
307 if (Storage == NULL) {\r
308 return EFI_INVALID_PARAMETER;\r
309 }\r
310\r
311 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
312 //\r
313 // <ConfigRequest> is unnecessary for EFI variable storage,\r
314 // GetVariable()/SetVariable() will be used to retrieve/save values\r
315 //\r
316 return EFI_SUCCESS;\r
317 }\r
318\r
319 //\r
320 // Prepare <RequestElement>\r
321 //\r
322 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
323 StrLen = UnicodeSPrint (\r
324 RequestElement,\r
325 30 * sizeof (CHAR16),\r
326 L"&OFFSET=%x&WIDTH=%x",\r
327 Question->VarStoreInfo.VarOffset,\r
328 Question->StorageWidth\r
329 );\r
330 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
331 } else {\r
332 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
333 }\r
334\r
335 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)) {\r
336 //\r
337 // Password with CALLBACK flag is stored in encoded format,\r
338 // so don't need to append it to <ConfigRequest>\r
339 //\r
340 return EFI_SUCCESS;\r
341 }\r
342\r
343 //\r
344 // Append <RequestElement> to <ConfigRequest>\r
345 //\r
346 if (StrLen > Storage->SpareStrLen) {\r
347 //\r
348 // Old String buffer is not sufficient for RequestElement, allocate a new one\r
349 //\r
350 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);\r
351 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
352 if (Storage->ConfigRequest != NULL) {\r
353 CopyMem (NewStr, Storage->ConfigRequest, StringSize);\r
354 gBS->FreePool (Storage->ConfigRequest);\r
355 }\r
356 Storage->ConfigRequest = NewStr;\r
357 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
358 }\r
359\r
360 StrCat (Storage->ConfigRequest, RequestElement);\r
361 Storage->ElementCount++;\r
362 Storage->SpareStrLen -= StrLen;\r
363\r
364 return EFI_SUCCESS;\r
365}\r
366\r
367\r
368/**\r
369 Free resources of a Expression\r
370\r
371 @param FormSet Pointer of the Expression\r
372\r
373 @return None.\r
374\r
375**/\r
376VOID\r
377DestroyExpression (\r
378 IN FORM_EXPRESSION *Expression\r
379 )\r
380{\r
381 LIST_ENTRY *Link;\r
382 EXPRESSION_OPCODE *OpCode;\r
383\r
384 while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
385 Link = GetFirstNode (&Expression->OpCodeListHead);\r
386 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
387 RemoveEntryList (&OpCode->Link);\r
388\r
7001eaf8 389 if (OpCode->ValueList != NULL) {\r
390 FreePool (OpCode->ValueList);\r
391 }\r
59336178 392 }\r
393\r
394 //\r
395 // Free this Expression\r
396 //\r
397 gBS->FreePool (Expression);\r
398}\r
399\r
400\r
401/**\r
402 Free resources of a storage\r
403\r
404 @param Storage Pointer of the storage\r
405\r
406 @return None.\r
407\r
408**/\r
409VOID\r
410DestroyStorage (\r
411 IN FORMSET_STORAGE *Storage\r
412 )\r
413{\r
414 LIST_ENTRY *Link;\r
415 NAME_VALUE_NODE *NameValueNode;\r
416\r
417 if (Storage == NULL) {\r
418 return;\r
419 }\r
420\r
7001eaf8 421 FreePool (Storage->Name);\r
422 FreePool (Storage->Buffer);\r
423 FreePool (Storage->EditBuffer);\r
59336178 424\r
425 while (!IsListEmpty (&Storage->NameValueListHead)) {\r
426 Link = GetFirstNode (&Storage->NameValueListHead);\r
427 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
428 RemoveEntryList (&NameValueNode->Link);\r
429\r
7001eaf8 430 FreePool (NameValueNode->Name);\r
431 FreePool (NameValueNode->Value);\r
432 FreePool (NameValueNode->EditValue);\r
433 FreePool (NameValueNode);\r
59336178 434 }\r
435\r
7001eaf8 436 FreePool (Storage->ConfigHdr);\r
437 FreePool (Storage->ConfigRequest);\r
59336178 438\r
7001eaf8 439 FreePool (Storage);\r
59336178 440}\r
441\r
442\r
443/**\r
444 Free resources of a Statement\r
445\r
446 @param Statement Pointer of the Statement\r
447\r
448 @return None.\r
449\r
450**/\r
451VOID\r
452DestroyStatement (\r
453 IN OUT FORM_BROWSER_STATEMENT *Statement\r
454 )\r
455{\r
456 LIST_ENTRY *Link;\r
457 QUESTION_DEFAULT *Default;\r
458 QUESTION_OPTION *Option;\r
459 FORM_EXPRESSION *Expression;\r
460\r
461 //\r
462 // Free Default value List\r
463 //\r
464 while (!IsListEmpty (&Statement->DefaultListHead)) {\r
465 Link = GetFirstNode (&Statement->DefaultListHead);\r
466 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
467 RemoveEntryList (&Default->Link);\r
468\r
469 gBS->FreePool (Default);\r
470 }\r
471\r
472 //\r
473 // Free Options List\r
474 //\r
475 while (!IsListEmpty (&Statement->OptionListHead)) {\r
476 Link = GetFirstNode (&Statement->OptionListHead);\r
477 Option = QUESTION_OPTION_FROM_LINK (Link);\r
478 RemoveEntryList (&Option->Link);\r
479\r
480 gBS->FreePool (Option);\r
481 }\r
482\r
483 //\r
484 // Free Inconsistent List\r
485 //\r
486 while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
487 Link = GetFirstNode (&Statement->InconsistentListHead);\r
488 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
489 RemoveEntryList (&Expression->Link);\r
490\r
491 DestroyExpression (Expression);\r
492 }\r
493\r
494 //\r
495 // Free NoSubmit List\r
496 //\r
497 while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
498 Link = GetFirstNode (&Statement->NoSubmitListHead);\r
499 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
500 RemoveEntryList (&Expression->Link);\r
501\r
502 DestroyExpression (Expression);\r
503 }\r
504\r
7001eaf8 505 if (Statement->VariableName != NULL) {\r
506 FreePool (Statement->VariableName);\r
507 }\r
508 if (Statement->BlockName != NULL) {\r
509 FreePool (Statement->BlockName);\r
510 }\r
59336178 511}\r
512\r
513\r
7001eaf8 514\r
59336178 515/**\r
516 Free resources of a Form\r
517\r
518 @param Form Pointer of the Form\r
519\r
520 @return None.\r
521\r
522**/\r
523VOID\r
524DestroyForm (\r
525 IN OUT FORM_BROWSER_FORM *Form\r
526 )\r
527{\r
528 LIST_ENTRY *Link;\r
529 FORM_EXPRESSION *Expression;\r
530 FORM_BROWSER_STATEMENT *Statement;\r
531\r
532 //\r
533 // Free Form Expressions\r
534 //\r
535 while (!IsListEmpty (&Form->ExpressionListHead)) {\r
536 Link = GetFirstNode (&Form->ExpressionListHead);\r
537 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
538 RemoveEntryList (&Expression->Link);\r
539\r
540 DestroyExpression (Expression);\r
541 }\r
542\r
543 //\r
544 // Free Statements/Questions\r
545 //\r
546 while (!IsListEmpty (&Form->StatementListHead)) {\r
547 Link = GetFirstNode (&Form->StatementListHead);\r
548 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
549 RemoveEntryList (&Statement->Link);\r
550\r
551 DestroyStatement (Statement);\r
552 }\r
553\r
554 //\r
555 // Free this Form\r
556 //\r
557 gBS->FreePool (Form);\r
558}\r
559\r
560\r
561/**\r
562 Free resources allocated for a FormSet\r
563\r
564 @param FormSet Pointer of the FormSet\r
565\r
566 @return None.\r
567\r
568**/\r
569VOID\r
570DestroyFormSet (\r
571 IN OUT FORM_BROWSER_FORMSET *FormSet\r
572 )\r
573{\r
574 LIST_ENTRY *Link;\r
575 FORMSET_STORAGE *Storage;\r
576 FORMSET_DEFAULTSTORE *DefaultStore;\r
577 FORM_BROWSER_FORM *Form;\r
578\r
579 //\r
580 // Free IFR binary buffer\r
581 //\r
7001eaf8 582 FreePool (FormSet->IfrBinaryData);\r
59336178 583\r
584 //\r
585 // Free FormSet Storage\r
586 //\r
587 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
588 while (!IsListEmpty (&FormSet->StorageListHead)) {\r
589 Link = GetFirstNode (&FormSet->StorageListHead);\r
590 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
591 RemoveEntryList (&Storage->Link);\r
592\r
593 DestroyStorage (Storage);\r
594 }\r
595 }\r
596\r
597 //\r
598 // Free FormSet Default Store\r
599 //\r
600 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
601 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
602 Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
603 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
604 RemoveEntryList (&DefaultStore->Link);\r
605\r
606 gBS->FreePool (DefaultStore);\r
607 }\r
608 }\r
609\r
610 //\r
611 // Free Forms\r
612 //\r
613 if (FormSet->FormListHead.ForwardLink != NULL) {\r
614 while (!IsListEmpty (&FormSet->FormListHead)) {\r
615 Link = GetFirstNode (&FormSet->FormListHead);\r
616 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
617 RemoveEntryList (&Form->Link);\r
618\r
619 DestroyForm (Form);\r
620 }\r
621 }\r
622\r
7001eaf8 623 if (FormSet->StatementBuffer != NULL) {\r
624 FreePool (FormSet->StatementBuffer);\r
625 }\r
626 if (FormSet->ExpressionBuffer != NULL) {\r
627 FreePool (FormSet->ExpressionBuffer);\r
628 }\r
59336178 629\r
7001eaf8 630 FreePool (FormSet);\r
59336178 631}\r
632\r
633\r
634/**\r
635 Tell whether this Operand is an Expression OpCode or not\r
636\r
637 @param Operand Operand of an IFR OpCode.\r
638\r
639 @retval TRUE This is an Expression OpCode.\r
640 @retval FALSE Not an Expression OpCode.\r
641\r
642**/\r
643BOOLEAN\r
644IsExpressionOpCode (\r
645 IN UINT8 Operand\r
646 )\r
647{\r
648 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
649 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
650 (Operand == EFI_IFR_CATENATE_OP)\r
651 ) {\r
652 return TRUE;\r
653 } else {\r
654 return FALSE;\r
655 }\r
656}\r
657\r
658\r
659/**\r
660 Calculate number of Statemens(Questions) and Expression OpCodes.\r
661\r
662 @param FormSet The FormSet to be counted.\r
663 @param NumberOfStatement Number of Statemens(Questions)\r
664 @param NumberOfExpression Number of Expression OpCodes\r
665\r
666 @return None.\r
667\r
668**/\r
669VOID\r
670CountOpCodes (\r
671 IN FORM_BROWSER_FORMSET *FormSet,\r
672 IN OUT UINT16 *NumberOfStatement,\r
673 IN OUT UINT16 *NumberOfExpression\r
674 )\r
675{\r
676 UINT16 StatementCount;\r
677 UINT16 ExpressionCount;\r
678 UINT8 *OpCodeData;\r
679 UINTN Offset;\r
680 UINTN OpCodeLen;\r
681\r
682 Offset = 0;\r
683 StatementCount = 0;\r
684 ExpressionCount = 0;\r
685\r
686 while (Offset < FormSet->IfrBinaryLength) {\r
687 OpCodeData = FormSet->IfrBinaryData + Offset;\r
688 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
689 Offset += OpCodeLen;\r
690\r
691 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
692 ExpressionCount++;\r
693 } else {\r
694 StatementCount++;\r
695 }\r
696 }\r
697\r
698 *NumberOfStatement = StatementCount;\r
699 *NumberOfExpression = ExpressionCount;\r
700}\r
701\r
702\r
703/**\r
704 Parse opcodes in the formset IFR binary.\r
705\r
706 @param FormSet Pointer of the FormSet data structure.\r
707\r
708 @retval EFI_SUCCESS Opcode parse success.\r
709 @retval Other Opcode parse fail.\r
710\r
711**/\r
712EFI_STATUS\r
713ParseOpCodes (\r
714 IN FORM_BROWSER_FORMSET *FormSet\r
715 )\r
716{\r
717 EFI_STATUS Status;\r
718 UINT16 Index;\r
719 FORM_BROWSER_FORM *CurrentForm;\r
720 FORM_BROWSER_STATEMENT *CurrentStatement;\r
721 EXPRESSION_OPCODE *ExpressionOpCode;\r
722 FORM_EXPRESSION *CurrentExpression;\r
723 UINT8 Operand;\r
724 UINT8 Scope;\r
725 UINTN OpCodeOffset;\r
726 UINTN OpCodeLength;\r
727 UINT8 *OpCodeData;\r
728 UINT8 ScopeOpCode;\r
729 FORMSET_STORAGE *Storage;\r
730 FORMSET_DEFAULTSTORE *DefaultStore;\r
731 QUESTION_DEFAULT *CurrentDefault;\r
732 QUESTION_OPTION *CurrentOption;\r
733 CHAR8 *AsciiString;\r
734 UINT16 NumberOfStatement;\r
735 UINT16 NumberOfExpression;\r
736 EFI_IMAGE_ID *ImageId;\r
737 BOOLEAN SuppressForOption;\r
738 BOOLEAN InScopeOptionSuppress;\r
739 FORM_EXPRESSION *OptionSuppressExpression;\r
740 BOOLEAN InScopeDisable;\r
741 UINT16 DepthOfDisable;\r
742 BOOLEAN OpCodeDisabled;\r
743 BOOLEAN SingleOpCodeExpression;\r
744 BOOLEAN InScopeDefault;\r
745 EFI_HII_VALUE *Value;\r
746\r
747 mInScopeSubtitle = FALSE;\r
748 SuppressForOption = FALSE;\r
749 mInScopeSuppress = FALSE;\r
750 InScopeOptionSuppress = FALSE;\r
751 mInScopeGrayOut = FALSE;\r
752 InScopeDisable = FALSE;\r
753 DepthOfDisable = 0;\r
754 OpCodeDisabled = FALSE;\r
755 SingleOpCodeExpression = FALSE;\r
756 InScopeDefault = FALSE;\r
757 CurrentExpression = NULL;\r
758 CurrentDefault = NULL;\r
759 CurrentOption = NULL;\r
760 OptionSuppressExpression = NULL;\r
761\r
762 //\r
763 // Get the number of Statements and Expressions\r
764 //\r
765 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
766\r
767 mStatementIndex = 0;\r
768 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
769 if (FormSet->StatementBuffer == NULL) {\r
770 return EFI_OUT_OF_RESOURCES;\r
771 }\r
772\r
773 mExpressionOpCodeIndex = 0;\r
774 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
775 if (FormSet->ExpressionBuffer == NULL) {\r
776 return EFI_OUT_OF_RESOURCES;\r
777 }\r
778\r
779 InitializeListHead (&FormSet->StorageListHead);\r
780 InitializeListHead (&FormSet->DefaultStoreListHead);\r
781 InitializeListHead (&FormSet->FormListHead);\r
782\r
783 CurrentForm = NULL;\r
784 CurrentStatement = NULL;\r
785\r
786 ResetScopeStack ();\r
787\r
788 OpCodeOffset = 0;\r
789 while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
790 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
791\r
792 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
793 OpCodeOffset += OpCodeLength;\r
794 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
795 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
796\r
797 //\r
798 // If scope bit set, push onto scope stack\r
799 //\r
800 if (Scope) {\r
801 PushScope (Operand);\r
802 }\r
803\r
804 if (OpCodeDisabled) {\r
805 //\r
806 // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
807 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
808 //\r
809 if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
810 DepthOfDisable++;\r
811 } else if (Operand == EFI_IFR_END_OP) {\r
812 Status = PopScope (&ScopeOpCode);\r
813 if (EFI_ERROR (Status)) {\r
814 return Status;\r
815 }\r
816\r
817 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
818 if (DepthOfDisable == 0) {\r
819 InScopeDisable = FALSE;\r
820 OpCodeDisabled = FALSE;\r
821 } else {\r
822 DepthOfDisable--;\r
823 }\r
824 }\r
825 }\r
826 continue;\r
827 }\r
828\r
829 if (IsExpressionOpCode (Operand)) {\r
830 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
831 mExpressionOpCodeIndex++;\r
832\r
833 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
834 ExpressionOpCode->Operand = Operand;\r
835 Value = &ExpressionOpCode->Value;\r
836\r
837 switch (Operand) {\r
838 case EFI_IFR_EQ_ID_VAL_OP:\r
839 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
840\r
841 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
842 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
843 break;\r
844\r
845 case EFI_IFR_EQ_ID_ID_OP:\r
846 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
847 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
848 break;\r
849\r
850 case EFI_IFR_EQ_ID_LIST_OP:\r
851 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
852 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
853 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ValueList);\r
854 break;\r
855\r
856 case EFI_IFR_TO_STRING_OP:\r
857 case EFI_IFR_FIND_OP:\r
858 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
859 break;\r
860\r
861 case EFI_IFR_STRING_REF1_OP:\r
862 Value->Type = EFI_IFR_TYPE_STRING;\r
863 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
864 break;\r
865\r
866 case EFI_IFR_RULE_REF_OP:\r
867 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
868 break;\r
869\r
870 case EFI_IFR_SPAN_OP:\r
871 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
872 break;\r
873\r
874 case EFI_IFR_THIS_OP:\r
875 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
876 break;\r
877\r
878 case EFI_IFR_QUESTION_REF1_OP:\r
879 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
880 break;\r
881\r
882 case EFI_IFR_QUESTION_REF3_OP:\r
883 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
884 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
885\r
886 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
887 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
888 }\r
889 }\r
890 break;\r
891\r
892 //\r
893 // constant\r
894 //\r
895 case EFI_IFR_TRUE_OP:\r
896 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
897 Value->Value.b = TRUE;\r
898 break;\r
899\r
900 case EFI_IFR_FALSE_OP:\r
901 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
902 Value->Value.b = FALSE;\r
903 break;\r
904\r
905 case EFI_IFR_ONE_OP:\r
906 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
907 Value->Value.u8 = 1;\r
908 break;\r
909\r
910 case EFI_IFR_ZERO_OP:\r
911 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
912 Value->Value.u8 = 0;\r
913 break;\r
914\r
915 case EFI_IFR_ONES_OP:\r
916 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
917 Value->Value.u64 = 0xffffffffffffffffULL;\r
918 break;\r
919\r
920 case EFI_IFR_UINT8_OP:\r
921 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
922 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
923 break;\r
924\r
925 case EFI_IFR_UINT16_OP:\r
926 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
927 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
928 break;\r
929\r
930 case EFI_IFR_UINT32_OP:\r
931 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
932 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
933 break;\r
934\r
935 case EFI_IFR_UINT64_OP:\r
936 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
937 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
938 break;\r
939\r
940 case EFI_IFR_UNDEFINED_OP:\r
941 Value->Type = EFI_IFR_TYPE_OTHER;\r
942 break;\r
943\r
944 case EFI_IFR_VERSION_OP:\r
945 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
946 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
947 break;\r
948\r
949 default:\r
950 break;\r
951 }\r
952\r
953 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
954\r
955 if (SingleOpCodeExpression) {\r
956 //\r
957 // There are two cases to indicate the end of an Expression:\r
958 // for single OpCode expression: one Expression OpCode\r
959 // for expression consists of more than one OpCode: EFI_IFR_END\r
960 //\r
961 SingleOpCodeExpression = FALSE;\r
962\r
963 if (InScopeDisable) {\r
964 //\r
965 // Evaluate DisableIf expression\r
966 //\r
967 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
968 if (EFI_ERROR (Status)) {\r
969 return Status;\r
970 }\r
971 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
972 return EFI_INVALID_PARAMETER;\r
973 }\r
974\r
975 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
976 }\r
977\r
978 CurrentExpression = NULL;\r
979 }\r
980\r
981 continue;\r
982 }\r
983\r
984 //\r
985 // Parse the Opcode\r
986 //\r
987 switch (Operand) {\r
988\r
989 case EFI_IFR_FORM_SET_OP:\r
990 //\r
991 // check the formset GUID\r
992 //\r
5a58200d 993 if (!CompareGuid ((EFI_GUID *)(VOID *)&FormSet->Guid, (EFI_GUID *)(VOID *)&((EFI_IFR_FORM_SET *) OpCodeData)->Guid)) {\r
59336178 994 return EFI_INVALID_PARAMETER;\r
995 }\r
996\r
997 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
998 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
999 break;\r
1000\r
1001 case EFI_IFR_FORM_OP:\r
1002 //\r
1003 // Create a new Form for this FormSet\r
1004 //\r
1005 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1006 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1007 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1008 InitializeListHead (&CurrentForm->StatementListHead);\r
1009\r
1010 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1011 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1012\r
1013 //\r
1014 // Insert into Form list of this FormSet\r
1015 //\r
1016 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1017 break;\r
1018\r
1019 //\r
1020 // Storage\r
1021 //\r
1022 case EFI_IFR_VARSTORE_OP:\r
1023 //\r
1024 // Create a buffer Storage for this FormSet\r
1025 //\r
1026 Storage = CreateStorage (FormSet);\r
1027 Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1028\r
1029 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1030 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1031 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
1032\r
1033 Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1034 Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1035\r
1036 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1037 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1038 ASSERT (Storage->Name != NULL);\r
1039 for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1040 Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1041 }\r
1042\r
1043 //\r
1044 // Initialize <ConfigHdr>\r
1045 //\r
1046 InitializeConfigHdr (FormSet, Storage);\r
1047 break;\r
1048\r
1049 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1050 //\r
1051 // Create a name/value Storage for this FormSet\r
1052 //\r
1053 Storage = CreateStorage (FormSet);\r
1054 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1055\r
1056 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1057 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1058\r
1059 //\r
1060 // Initialize <ConfigHdr>\r
1061 //\r
1062 InitializeConfigHdr (FormSet, Storage);\r
1063 break;\r
1064\r
1065 case EFI_IFR_VARSTORE_EFI_OP:\r
1066 //\r
1067 // Create a EFI variable Storage for this FormSet\r
1068 //\r
1069 Storage = CreateStorage (FormSet);\r
1070 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1071\r
1072 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1073 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1074 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1075 break;\r
1076\r
1077 //\r
1078 // DefaultStore\r
1079 //\r
1080 case EFI_IFR_DEFAULTSTORE_OP:\r
1081 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1082 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1083\r
1084 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1085 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1086\r
1087 //\r
1088 // Insert to DefaultStore list of this Formset\r
1089 //\r
1090 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1091 break;\r
1092\r
1093 //\r
1094 // Statements\r
1095 //\r
1096 case EFI_IFR_SUBTITLE_OP:\r
1097 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1098 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1099\r
1100 if (Scope) {\r
1101 mInScopeSubtitle = TRUE;\r
1102 }\r
1103 break;\r
1104\r
1105 case EFI_IFR_TEXT_OP:\r
1106 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1107\r
1108 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1109 break;\r
1110\r
1111 //\r
1112 // Questions\r
1113 //\r
1114 case EFI_IFR_ACTION_OP:\r
1115 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1116\r
1117 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1118 //\r
1119 // No QuestionConfig present, so no configuration string will be processed\r
1120 //\r
1121 CurrentStatement->QuestionConfig = 0;\r
1122 } else {\r
1123 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1124 }\r
1125 break;\r
1126\r
1127 case EFI_IFR_RESET_BUTTON_OP:\r
1128 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1129\r
1130 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1131 break;\r
1132\r
1133 case EFI_IFR_REF_OP:\r
1134 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1135\r
1136 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
1137 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1138 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1139\r
1140 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1141 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1142\r
1143 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1144 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1145 }\r
1146 }\r
1147 }\r
1148 break;\r
1149\r
1150 case EFI_IFR_ONE_OF_OP:\r
1151 case EFI_IFR_NUMERIC_OP:\r
1152 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1153\r
1154 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1155 Value = &CurrentStatement->HiiValue;\r
1156\r
1157 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1158 case EFI_IFR_NUMERIC_SIZE_1:\r
1159 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1160 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1161 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1162 CurrentStatement->StorageWidth = sizeof (UINT8);\r
1163 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1164 break;\r
1165\r
1166 case EFI_IFR_NUMERIC_SIZE_2:\r
1167 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1168 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1169 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
1170 CurrentStatement->StorageWidth = sizeof (UINT16);\r
1171 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1172 break;\r
1173\r
1174 case EFI_IFR_NUMERIC_SIZE_4:\r
1175 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1176 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1177 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
1178 CurrentStatement->StorageWidth = sizeof (UINT32);\r
1179 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1180 break;\r
1181\r
1182 case EFI_IFR_NUMERIC_SIZE_8:\r
1183 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1184 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1185 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
1186 CurrentStatement->StorageWidth = sizeof (UINT64);\r
1187 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1188 break;\r
1189\r
1190 default:\r
1191 break;\r
1192 }\r
1193\r
1194 InitializeRequestElement (FormSet, CurrentStatement);\r
1195\r
1196 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope) {\r
1197 SuppressForOption = TRUE;\r
1198 }\r
1199 break;\r
1200\r
1201 case EFI_IFR_ORDERED_LIST_OP:\r
1202 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1203\r
1204 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1205 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
1206 CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));\r
1207 InitializeRequestElement (FormSet, CurrentStatement);\r
1208\r
1209 //\r
1210 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver\r
1211 // has to use FormBrowser2.Callback() to retrieve the uncommited data for\r
1212 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).\r
1213 //\r
1214 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;\r
1215 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1216\r
1217 if (Scope) {\r
1218 SuppressForOption = TRUE;\r
1219 }\r
1220 break;\r
1221\r
1222 case EFI_IFR_CHECKBOX_OP:\r
1223 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1224\r
1225 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
1226 CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
1227 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1228\r
1229 InitializeRequestElement (FormSet, CurrentStatement);\r
1230 break;\r
1231\r
1232 case EFI_IFR_STRING_OP:\r
1233 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1234\r
1235 //\r
1236 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1237 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1238 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1239 //\r
1240 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1241 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1242 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
1243 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1244\r
1245 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1246 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1247\r
1248 InitializeRequestElement (FormSet, CurrentStatement);\r
1249 break;\r
1250\r
1251 case EFI_IFR_PASSWORD_OP:\r
1252 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1253\r
1254 //\r
1255 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1256 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1257 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1258 //\r
1259 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1260 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1261 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
1262\r
1263 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1264 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1265\r
1266 InitializeRequestElement (FormSet, CurrentStatement);\r
1267 break;\r
1268\r
1269 case EFI_IFR_DATE_OP:\r
1270 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1271\r
1272 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1273 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1274\r
1275 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
1276 CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
1277\r
1278 InitializeRequestElement (FormSet, CurrentStatement);\r
1279 } else {\r
1280 //\r
1281 // Don't assign storage for RTC type of date/time\r
1282 //\r
1283 CurrentStatement->Storage = NULL;\r
1284 CurrentStatement->StorageWidth = 0;\r
1285 }\r
1286 break;\r
1287\r
1288 case EFI_IFR_TIME_OP:\r
1289 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1290\r
1291 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1292 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1293\r
1294 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
1295 CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
1296\r
1297 InitializeRequestElement (FormSet, CurrentStatement);\r
1298 } else {\r
1299 //\r
1300 // Don't assign storage for RTC type of date/time\r
1301 //\r
1302 CurrentStatement->Storage = NULL;\r
1303 CurrentStatement->StorageWidth = 0;\r
1304 }\r
1305 break;\r
1306\r
1307 //\r
1308 // Default\r
1309 //\r
1310 case EFI_IFR_DEFAULT_OP:\r
1311 //\r
1312 // EFI_IFR_DEFAULT appear in scope of a Question,\r
1313 // It creates a default value for the current question.\r
1314 // A Question may have more than one Default value which have different default types.\r
1315 //\r
1316 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1317 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1318\r
1319 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1320 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1321 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1322 ExtendValueToU64 (&CurrentDefault->Value);\r
1323\r
1324 //\r
1325 // Insert to Default Value list of current Question\r
1326 //\r
1327 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1328\r
1329 if (Scope) {\r
1330 InScopeDefault = TRUE;\r
1331 }\r
1332 break;\r
1333\r
1334 //\r
1335 // Option\r
1336 //\r
1337 case EFI_IFR_ONE_OF_OPTION_OP:\r
1338 //\r
1339 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1340 // It create a selection for use in current Question.\r
1341 //\r
1342 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1343 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1344\r
1345 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1346 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1347 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1348 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1349 ExtendValueToU64 (&CurrentOption->Value);\r
1350\r
1351 if (InScopeOptionSuppress) {\r
1352 CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1353 }\r
1354\r
1355 //\r
1356 // Insert to Option list of current Question\r
1357 //\r
1358 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
1359 break;\r
1360\r
1361 //\r
1362 // Conditional\r
1363 //\r
1364 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1365 case EFI_IFR_INCONSISTENT_IF_OP:\r
1366 //\r
1367 // Create an Expression node\r
1368 //\r
1369 CurrentExpression = CreateExpression (CurrentForm);\r
1370 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1371\r
1372 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1373 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1374 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1375 } else {\r
1376 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1377 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1378 }\r
1379 break;\r
1380\r
1381 case EFI_IFR_SUPPRESS_IF_OP:\r
1382 //\r
1383 // Question and Option will appear in scope of this OpCode\r
1384 //\r
1385 CurrentExpression = CreateExpression (CurrentForm);\r
1386 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
1387 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1388\r
1389 if (SuppressForOption) {\r
1390 InScopeOptionSuppress = TRUE;\r
1391 OptionSuppressExpression = CurrentExpression;\r
1392 } else {\r
1393 mInScopeSuppress = TRUE;\r
1394 mSuppressExpression = CurrentExpression;\r
1395 }\r
1396 break;\r
1397\r
1398 case EFI_IFR_GRAY_OUT_IF_OP:\r
1399 //\r
1400 // Questions will appear in scope of this OpCode\r
1401 //\r
1402 CurrentExpression = CreateExpression (CurrentForm);\r
1403 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1404 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1405\r
1406 mInScopeGrayOut = TRUE;\r
1407 mGrayOutExpression = CurrentExpression;\r
1408 break;\r
1409\r
1410 case EFI_IFR_DISABLE_IF_OP:\r
1411 //\r
1412 // The DisableIf expression should only rely on constant, so it could be\r
1413 // evaluated at initialization and it will not be queued\r
1414 //\r
1415 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1416 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1417 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1418 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1419\r
1420 InScopeDisable = TRUE;\r
1421 OpCodeDisabled = FALSE;\r
1422\r
1423 //\r
1424 // Take a look at next OpCode to see whether current expression consists\r
1425 // of single OpCode\r
1426 //\r
1427 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1428 SingleOpCodeExpression = TRUE;\r
1429 }\r
1430 break;\r
1431\r
1432 //\r
1433 // Expression\r
1434 //\r
1435 case EFI_IFR_VALUE_OP:\r
1436 CurrentExpression = CreateExpression (CurrentForm);\r
1437 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1438 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1439\r
1440 if (InScopeDefault) {\r
1441 //\r
1442 // Used for default (EFI_IFR_DEFAULT)\r
1443 //\r
1444 CurrentDefault->ValueExpression = CurrentExpression;\r
1445 } else {\r
1446 //\r
1447 // If used for a question, then the question will be read-only\r
1448 //\r
1449 CurrentStatement->ValueExpression = CurrentExpression;\r
1450 }\r
1451 break;\r
1452\r
1453 case EFI_IFR_RULE_OP:\r
1454 CurrentExpression = CreateExpression (CurrentForm);\r
1455 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1456\r
1457 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1458 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1459 break;\r
1460\r
1461 //\r
1462 // Image\r
1463 //\r
1464 case EFI_IFR_IMAGE_OP:\r
1465 //\r
1466 // Get ScopeOpcode from top of stack\r
1467 //\r
1468 PopScope (&ScopeOpCode);\r
1469 PushScope (ScopeOpCode);\r
1470\r
1471 switch (ScopeOpCode) {\r
1472 case EFI_IFR_FORM_SET_OP:\r
1473 ImageId = &FormSet->ImageId;\r
1474 break;\r
1475\r
1476 case EFI_IFR_FORM_OP:\r
1477 ImageId = &CurrentForm->ImageId;\r
1478 break;\r
1479\r
1480 case EFI_IFR_ONE_OF_OPTION_OP:\r
1481 ImageId = &CurrentOption->ImageId;\r
1482 break;\r
1483\r
1484 default:\r
1485 ImageId = &CurrentStatement->ImageId;\r
1486 break;\r
1487 }\r
1488\r
1489 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
1490 break;\r
1491\r
1492 //\r
1493 // Refresh\r
1494 //\r
1495 case EFI_IFR_REFRESH_OP:\r
1496 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
1497 break;\r
1498\r
1499 //\r
1500 // Vendor specific\r
1501 //\r
1502 case EFI_IFR_GUID_OP:\r
1503 if (CompareGuid (&gTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
1504 //\r
1505 // Tiano specific GUIDed opcodes\r
1506 //\r
1507 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
1508 case EFI_IFR_EXTEND_OP_LABEL:\r
1509 //\r
1510 // just ignore label\r
1511 //\r
1512 break;\r
1513\r
1514#if 0\r
1515 case EFI_IFR_EXTEND_OP_BANNER:\r
1516 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
1517 CopyMem (\r
1518 &BannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
1519 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
1520 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
1521 sizeof (EFI_STRING_ID)\r
1522 );\r
1523 }\r
1524 break;\r
1525#endif\r
1526\r
1527 case EFI_IFR_EXTEND_OP_CLASS:\r
1528 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
1529 break;\r
1530\r
1531 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
1532 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
1533 break;\r
1534\r
1535 default:\r
1536 break;\r
1537 }\r
1538 }\r
1539 break;\r
1540\r
1541 //\r
1542 // Scope End\r
1543 //\r
1544 case EFI_IFR_END_OP:\r
1545 Status = PopScope (&ScopeOpCode);\r
1546 if (EFI_ERROR (Status)) {\r
1547 ResetScopeStack ();\r
1548 return Status;\r
1549 }\r
1550\r
1551 switch (ScopeOpCode) {\r
1552 case EFI_IFR_FORM_SET_OP:\r
1553 //\r
1554 // End of FormSet, update FormSet IFR binary length\r
1555 // to stop parsing substantial OpCodes\r
1556 //\r
1557 FormSet->IfrBinaryLength = OpCodeOffset;\r
1558 break;\r
1559\r
1560 case EFI_IFR_FORM_OP:\r
1561 //\r
1562 // End of Form\r
1563 //\r
1564 CurrentForm = NULL;\r
1565 break;\r
1566\r
1567 case EFI_IFR_ONE_OF_OPTION_OP:\r
1568 //\r
1569 // End of Option\r
1570 //\r
1571 CurrentOption = NULL;\r
1572 break;\r
1573\r
1574 case EFI_IFR_SUBTITLE_OP:\r
1575 mInScopeSubtitle = FALSE;\r
1576 break;\r
1577\r
1578 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1579 case EFI_IFR_INCONSISTENT_IF_OP:\r
1580 //\r
1581 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
1582 //\r
1583 break;\r
1584\r
1585 case EFI_IFR_SUPPRESS_IF_OP:\r
1586 if (SuppressForOption) {\r
1587 InScopeOptionSuppress = FALSE;\r
1588 } else {\r
1589 mInScopeSuppress = FALSE;\r
1590 }\r
1591 break;\r
1592\r
1593 case EFI_IFR_GRAY_OUT_IF_OP:\r
1594 mInScopeGrayOut = FALSE;\r
1595 break;\r
1596\r
1597 case EFI_IFR_DISABLE_IF_OP:\r
1598 InScopeDisable = FALSE;\r
1599 OpCodeDisabled = FALSE;\r
1600 break;\r
1601\r
1602 case EFI_IFR_ONE_OF_OP:\r
1603 case EFI_IFR_ORDERED_LIST_OP:\r
1604 SuppressForOption = FALSE;\r
1605 break;\r
1606\r
1607 case EFI_IFR_DEFAULT_OP:\r
1608 InScopeDefault = FALSE;\r
1609 break;\r
1610\r
1611 default:\r
1612 if (IsExpressionOpCode (ScopeOpCode)) {\r
1613 if (InScopeDisable) {\r
1614 //\r
1615 // Evaluate DisableIf expression\r
1616 //\r
1617 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1618 if (EFI_ERROR (Status)) {\r
1619 return Status;\r
1620 }\r
1621 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1622 return EFI_INVALID_PARAMETER;\r
1623 }\r
1624\r
1625 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1626 //\r
1627 // DisableIf Expression is only used once and not quequed, free it\r
1628 //\r
1629 DestroyExpression (CurrentExpression);\r
1630 }\r
1631\r
1632 //\r
1633 // End of current Expression\r
1634 //\r
1635 CurrentExpression = NULL;\r
1636 }\r
1637 break;\r
1638 }\r
1639 break;\r
1640\r
1641 default:\r
1642 break;\r
1643 }\r
1644 }\r
1645\r
1646 return EFI_SUCCESS;\r
1647}\r
1648\r
1649\r
1650\r
1651\r