2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 UINT16 mStatementIndex
;
18 UINT16 mExpressionOpCodeIndex
;
20 BOOLEAN mInScopeSubtitle
;
22 Initialize Statement header members.
24 @param OpCodeData Pointer of the raw OpCode data.
25 @param FormSet Pointer of the current FormSe.
26 @param Form Pointer of the current Form.
28 @return The Statement.
31 FORM_BROWSER_STATEMENT
*
34 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
35 IN OUT FORM_BROWSER_FORM
*Form
38 FORM_BROWSER_STATEMENT
*Statement
;
39 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
40 INTN ConditionalExprCount
;
44 // We are currently not in a Form Scope, so just skip this Statement
49 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
52 InitializeListHead (&Statement
->DefaultListHead
);
53 InitializeListHead (&Statement
->OptionListHead
);
54 InitializeListHead (&Statement
->InconsistentListHead
);
55 InitializeListHead (&Statement
->NoSubmitListHead
);
57 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
59 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
61 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
62 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
63 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
65 ConditionalExprCount
= GetConditionalExpressionCount(ExpressStatement
);
66 if (ConditionalExprCount
> 0) {
68 // Form is inside of suppressif
71 Statement
->Expression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
72 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
73 ASSERT (Statement
->Expression
!= NULL
);
74 Statement
->Expression
->Count
= (UINTN
) ConditionalExprCount
;
75 Statement
->Expression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
76 CopyMem (Statement
->Expression
->Expression
, GetConditionalExpressionList(ExpressStatement
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
79 Statement
->InSubtitle
= mInScopeSubtitle
;
82 // Insert this Statement into current Form
84 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
90 Convert a numeric value to a Unicode String and insert it to String Package.
91 This string is used as the Unicode Name for the EFI Variable. This is to support
92 the deprecated vareqval opcode.
94 @param FormSet The FormSet.
95 @param Statement The numeric question whose VarStoreInfo.VarName is the
96 numeric value which is used to produce the Unicode Name
99 If the Statement is NULL, the ASSERT.
100 If the opcode is not Numeric, then ASSERT.
102 @retval EFI_SUCCESS The funtion always succeeds.
105 UpdateCheckBoxStringToken (
106 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
107 IN FORM_BROWSER_STATEMENT
*Statement
110 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
113 ASSERT (Statement
!= NULL
);
114 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
116 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
118 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
120 return EFI_OUT_OF_RESOURCES
;
123 Statement
->VarStoreInfo
.VarName
= Id
;
129 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
131 @param OpCodeData The current opcode.
137 IsNextOpCodeGuidedVarEqName (
144 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
145 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
146 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
148 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
150 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
160 Initialize Question's members.
162 @param OpCodeData Pointer of the raw OpCode data.
163 @param FormSet Pointer of the current FormSet.
164 @param Form Pointer of the current Form.
166 @return The Question.
169 FORM_BROWSER_STATEMENT
*
171 IN UINT8
*OpCodeData
,
172 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
173 IN OUT FORM_BROWSER_FORM
*Form
176 FORM_BROWSER_STATEMENT
*Statement
;
177 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
179 FORMSET_STORAGE
*Storage
;
180 NAME_VALUE_NODE
*NameValueNode
;
183 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
184 if (Statement
== NULL
) {
188 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
189 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
190 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
191 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
193 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
195 if (Statement
->VarStoreId
== 0) {
197 // VarStoreId of zero indicates no variable storage
203 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
204 // Framework Compatibility
206 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
207 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
208 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
209 if (EFI_ERROR (Status
)) {
216 // Find Storage for this Question
218 Link
= GetFirstNode (&FormSet
->StorageListHead
);
219 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
220 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
222 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
223 Statement
->Storage
= Storage
;
227 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
229 ASSERT (Statement
->Storage
!= NULL
);
232 // Initialilze varname for Name/Value or EFI Variable
234 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
235 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
236 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
237 ASSERT (Statement
->VariableName
!= NULL
);
239 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
241 // Insert to Name/Value varstore list
243 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
244 ASSERT (NameValueNode
!= NULL
);
245 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
246 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
247 ASSERT (NameValueNode
->Name
!= NULL
);
248 NameValueNode
->Value
= AllocateZeroPool (0x10);
249 ASSERT (NameValueNode
->Value
!= NULL
);
250 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
251 ASSERT (NameValueNode
->EditValue
!= NULL
);
253 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
262 Allocate a FORM_EXPRESSION node.
264 @param Form The Form associated with this Expression
266 @return Pointer to a FORM_EXPRESSION data structure.
271 IN OUT FORM_BROWSER_FORM
*Form
274 FORM_EXPRESSION
*Expression
;
276 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
277 ASSERT (Expression
!= NULL
);
278 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
279 InitializeListHead (&Expression
->OpCodeListHead
);
286 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
288 @param FormSet Pointer of the current FormSet
290 @return Pointer to a FORMSET_STORAGE data structure.
295 IN FORM_BROWSER_FORMSET
*FormSet
298 FORMSET_STORAGE
*Storage
;
300 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
301 ASSERT (Storage
!= NULL
);
302 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
303 InitializeListHead (&Storage
->NameValueListHead
);
304 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
311 Create ConfigHdr string for a storage.
313 @param FormSet Pointer of the current FormSet
314 @param Storage Pointer of the storage
316 @retval EFI_SUCCESS Initialize ConfigHdr success
320 InitializeConfigHdr (
321 IN FORM_BROWSER_FORMSET
*FormSet
,
322 IN OUT FORMSET_STORAGE
*Storage
327 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
328 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
329 Name
= Storage
->Name
;
334 Storage
->ConfigHdr
= HiiConstructConfigHdr (
337 FormSet
->DriverHandle
340 if (Storage
->ConfigHdr
== NULL
) {
341 return EFI_NOT_FOUND
;
344 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
345 Storage
->SpareStrLen
= 0;
352 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
354 @param FormSet Pointer of the current FormSet.
355 @param Question The Question to be initialized.
356 @param Form Pointer of the current form.
358 @retval EFI_SUCCESS Function success.
359 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
363 InitializeRequestElement (
364 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
365 IN OUT FORM_BROWSER_STATEMENT
*Question
,
366 IN OUT FORM_BROWSER_FORM
*Form
369 FORMSET_STORAGE
*Storage
;
373 CHAR16 RequestElement
[30];
376 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
378 Storage
= Question
->Storage
;
379 if (Storage
== NULL
) {
380 return EFI_INVALID_PARAMETER
;
383 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
385 // <ConfigRequest> is unnecessary for EFI variable storage,
386 // GetVariable()/SetVariable() will be used to retrieve/save values
392 // Prepare <RequestElement>
394 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
395 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
396 StrLen
= UnicodeSPrint (
398 30 * sizeof (CHAR16
),
399 L
"&OFFSET=%x&WIDTH=%x",
400 Question
->VarStoreInfo
.VarOffset
,
401 Question
->StorageWidth
403 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
405 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
408 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
410 // Password with CALLBACK flag is stored in encoded format,
411 // so don't need to append it to <ConfigRequest>
417 // Append <RequestElement> to <ConfigRequest>
419 if (StrLen
> Storage
->SpareStrLen
) {
421 // Old String buffer is not sufficient for RequestElement, allocate a new one
423 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
424 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
425 ASSERT (NewStr
!= NULL
);
426 if (Storage
->ConfigRequest
!= NULL
) {
427 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
428 FreePool (Storage
->ConfigRequest
);
430 Storage
->ConfigRequest
= NewStr
;
431 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
434 StrCat (Storage
->ConfigRequest
, RequestElement
);
435 Storage
->ElementCount
++;
436 Storage
->SpareStrLen
-= StrLen
;
439 // Update the Config Request info saved in the form.
443 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
444 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
445 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
447 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
->VarStoreId
== Storage
->VarStoreId
) {
452 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
456 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
457 ASSERT (ConfigInfo
!= NULL
);
458 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
459 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
460 ConfigInfo
->SpareStrLen
= 0;
461 ConfigInfo
->Storage
= Storage
;
462 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
466 // Append <RequestElement> to <ConfigRequest>
468 if (StrLen
> ConfigInfo
->SpareStrLen
) {
470 // Old String buffer is not sufficient for RequestElement, allocate a new one
472 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
473 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
474 ASSERT (NewStr
!= NULL
);
475 if (ConfigInfo
->ConfigRequest
!= NULL
) {
476 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
477 FreePool (ConfigInfo
->ConfigRequest
);
479 ConfigInfo
->ConfigRequest
= NewStr
;
480 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
483 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
484 ConfigInfo
->ElementCount
++;
485 ConfigInfo
->SpareStrLen
-= StrLen
;
491 Free resources of a Expression.
493 @param FormSet Pointer of the Expression
498 IN FORM_EXPRESSION
*Expression
502 EXPRESSION_OPCODE
*OpCode
;
503 LIST_ENTRY
*SubExpressionLink
;
504 FORM_EXPRESSION
*SubExpression
;
506 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
507 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
508 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
509 RemoveEntryList (&OpCode
->Link
);
511 if (OpCode
->ValueList
!= NULL
) {
512 FreePool (OpCode
->ValueList
);
515 if (OpCode
->ValueName
!= NULL
) {
516 FreePool (OpCode
->ValueName
);
519 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
520 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
521 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
522 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
523 RemoveEntryList(&SubExpression
->Link
);
524 DestroyExpression (SubExpression
);
530 // Free this Expression
532 FreePool (Expression
);
537 Free resources of a storage.
539 @param Storage Pointer of the storage
544 IN FORMSET_STORAGE
*Storage
548 NAME_VALUE_NODE
*NameValueNode
;
550 if (Storage
== NULL
) {
554 if (Storage
->Name
!= NULL
) {
555 FreePool (Storage
->Name
);
557 if (Storage
->Buffer
!= NULL
) {
558 FreePool (Storage
->Buffer
);
560 if (Storage
->EditBuffer
!= NULL
) {
561 FreePool (Storage
->EditBuffer
);
564 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
565 Link
= GetFirstNode (&Storage
->NameValueListHead
);
566 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
567 RemoveEntryList (&NameValueNode
->Link
);
569 if (NameValueNode
->Name
!= NULL
) {
570 FreePool (NameValueNode
->Name
);
572 if (NameValueNode
->Value
!= NULL
) {
573 FreePool (NameValueNode
->Value
);
575 if (NameValueNode
->EditValue
!= NULL
) {
576 FreePool (NameValueNode
->EditValue
);
578 FreePool (NameValueNode
);
581 if (Storage
->ConfigHdr
!= NULL
) {
582 FreePool (Storage
->ConfigHdr
);
584 if (Storage
->ConfigRequest
!= NULL
) {
585 FreePool (Storage
->ConfigRequest
);
593 Free resources of a Statement.
595 @param FormSet Pointer of the FormSet
596 @param Statement Pointer of the Statement
601 IN FORM_BROWSER_FORMSET
*FormSet
,
602 IN OUT FORM_BROWSER_STATEMENT
*Statement
606 QUESTION_DEFAULT
*Default
;
607 QUESTION_OPTION
*Option
;
608 FORM_EXPRESSION
*Expression
;
611 // Free Default value List
613 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
614 Link
= GetFirstNode (&Statement
->DefaultListHead
);
615 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
616 RemoveEntryList (&Default
->Link
);
624 while (!IsListEmpty (&Statement
->OptionListHead
)) {
625 Link
= GetFirstNode (&Statement
->OptionListHead
);
626 Option
= QUESTION_OPTION_FROM_LINK (Link
);
627 if (Option
->SuppressExpression
!= NULL
) {
628 FreePool (Option
->SuppressExpression
);
630 RemoveEntryList (&Option
->Link
);
636 // Free Inconsistent List
638 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
639 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
640 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
641 RemoveEntryList (&Expression
->Link
);
643 DestroyExpression (Expression
);
647 // Free NoSubmit List
649 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
650 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
651 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
652 RemoveEntryList (&Expression
->Link
);
654 DestroyExpression (Expression
);
657 if (Statement
->Expression
!= NULL
) {
658 FreePool (Statement
->Expression
);
661 if (Statement
->VariableName
!= NULL
) {
662 FreePool (Statement
->VariableName
);
664 if (Statement
->BlockName
!= NULL
) {
665 FreePool (Statement
->BlockName
);
667 if (Statement
->BufferValue
!= NULL
) {
668 FreePool (Statement
->BufferValue
);
670 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
671 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
677 Free resources of a Form.
679 @param FormSet Pointer of the FormSet
680 @param Form Pointer of the Form.
685 IN FORM_BROWSER_FORMSET
*FormSet
,
686 IN OUT FORM_BROWSER_FORM
*Form
690 FORM_EXPRESSION
*Expression
;
691 FORM_BROWSER_STATEMENT
*Statement
;
692 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
695 // Free Form Expressions
697 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
698 Link
= GetFirstNode (&Form
->ExpressionListHead
);
699 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
700 RemoveEntryList (&Expression
->Link
);
702 DestroyExpression (Expression
);
706 // Free Statements/Questions
708 while (!IsListEmpty (&Form
->StatementListHead
)) {
709 Link
= GetFirstNode (&Form
->StatementListHead
);
710 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
711 RemoveEntryList (&Statement
->Link
);
713 DestroyStatement (FormSet
, Statement
);
717 // Free ConfigRequest string.
719 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
720 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
721 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
722 RemoveEntryList (&ConfigInfo
->Link
);
724 FreePool (ConfigInfo
->ConfigRequest
);
725 FreePool (ConfigInfo
);
728 if (Form
->SuppressExpression
!= NULL
) {
729 FreePool (Form
->SuppressExpression
);
740 Free resources allocated for a FormSet.
742 @param FormSet Pointer of the FormSet
747 IN OUT FORM_BROWSER_FORMSET
*FormSet
751 FORMSET_STORAGE
*Storage
;
752 FORMSET_DEFAULTSTORE
*DefaultStore
;
753 FORM_EXPRESSION
*Expression
;
754 FORM_BROWSER_FORM
*Form
;
756 if (FormSet
->IfrBinaryData
== NULL
) {
758 // Uninitialized FormSet
765 // Free IFR binary buffer
767 FreePool (FormSet
->IfrBinaryData
);
770 // Free FormSet Storage
772 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
773 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
774 Link
= GetFirstNode (&FormSet
->StorageListHead
);
775 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
776 RemoveEntryList (&Storage
->Link
);
778 DestroyStorage (Storage
);
783 // Free FormSet Default Store
785 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
786 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
787 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
788 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
789 RemoveEntryList (&DefaultStore
->Link
);
791 FreePool (DefaultStore
);
796 // Free Formset Expressions
798 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
799 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
800 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
801 RemoveEntryList (&Expression
->Link
);
803 DestroyExpression (Expression
);
809 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
810 while (!IsListEmpty (&FormSet
->FormListHead
)) {
811 Link
= GetFirstNode (&FormSet
->FormListHead
);
812 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
813 RemoveEntryList (&Form
->Link
);
815 DestroyForm (FormSet
, Form
);
819 if (FormSet
->StatementBuffer
!= NULL
) {
820 FreePool (FormSet
->StatementBuffer
);
822 if (FormSet
->ExpressionBuffer
!= NULL
) {
823 FreePool (FormSet
->ExpressionBuffer
);
831 Tell whether this Operand is an Expression OpCode or not
833 @param Operand Operand of an IFR OpCode.
835 @retval TRUE This is an Expression OpCode.
836 @retval FALSE Not an Expression OpCode.
844 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
845 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
846 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
847 (Operand
== EFI_IFR_CATENATE_OP
) ||
848 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
849 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
850 (Operand
== EFI_IFR_MAP_OP
) ||
851 (Operand
== EFI_IFR_VERSION_OP
) ||
852 (Operand
== EFI_IFR_SECURITY_OP
)) {
861 Calculate number of Statemens(Questions) and Expression OpCodes.
863 @param FormSet The FormSet to be counted.
864 @param NumberOfStatement Number of Statemens(Questions)
865 @param NumberOfExpression Number of Expression OpCodes
870 IN FORM_BROWSER_FORMSET
*FormSet
,
871 IN OUT UINT16
*NumberOfStatement
,
872 IN OUT UINT16
*NumberOfExpression
875 UINT16 StatementCount
;
876 UINT16 ExpressionCount
;
885 while (Offset
< FormSet
->IfrBinaryLength
) {
886 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
887 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
890 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
897 *NumberOfStatement
= StatementCount
;
898 *NumberOfExpression
= ExpressionCount
;
904 Parse opcodes in the formset IFR binary.
906 @param FormSet Pointer of the FormSet data structure.
908 @retval EFI_SUCCESS Opcode parse success.
909 @retval Other Opcode parse fail.
914 IN FORM_BROWSER_FORMSET
*FormSet
919 FORM_BROWSER_FORM
*CurrentForm
;
920 FORM_BROWSER_STATEMENT
*CurrentStatement
;
921 EXPRESSION_OPCODE
*ExpressionOpCode
;
922 FORM_EXPRESSION
*CurrentExpression
;
929 FORMSET_STORAGE
*Storage
;
930 FORMSET_DEFAULTSTORE
*DefaultStore
;
931 QUESTION_DEFAULT
*CurrentDefault
;
932 QUESTION_OPTION
*CurrentOption
;
935 UINT16 NumberOfStatement
;
936 UINT16 NumberOfExpression
;
937 EFI_IMAGE_ID
*ImageId
;
938 BOOLEAN SuppressForQuestion
;
939 BOOLEAN SuppressForOption
;
940 UINT16 DepthOfDisable
;
941 BOOLEAN OpCodeDisabled
;
942 BOOLEAN SingleOpCodeExpression
;
943 BOOLEAN InScopeDefault
;
944 EFI_HII_VALUE
*Value
;
945 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
948 FORMSET_STORAGE
*VarStorage
;
949 LIST_ENTRY
*MapExpressionList
;
950 EFI_VARSTORE_ID TempVarstoreId
;
951 BOOLEAN InScopeDisable
;
952 INTN ConditionalExprCount
;
954 mInScopeSubtitle
= FALSE
;
955 SuppressForQuestion
= FALSE
;
956 SuppressForOption
= FALSE
;
957 InScopeDisable
= FALSE
;
959 OpCodeDisabled
= FALSE
;
960 SingleOpCodeExpression
= FALSE
;
961 InScopeDefault
= FALSE
;
962 CurrentExpression
= NULL
;
963 CurrentDefault
= NULL
;
964 CurrentOption
= NULL
;
970 MapExpressionList
= NULL
;
972 ConditionalExprCount
= 0;
975 // Get the number of Statements and Expressions
977 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
980 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
981 if (FormSet
->StatementBuffer
== NULL
) {
982 return EFI_OUT_OF_RESOURCES
;
985 mExpressionOpCodeIndex
= 0;
986 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
987 if (FormSet
->ExpressionBuffer
== NULL
) {
988 return EFI_OUT_OF_RESOURCES
;
991 InitializeListHead (&FormSet
->StorageListHead
);
992 InitializeListHead (&FormSet
->DefaultStoreListHead
);
993 InitializeListHead (&FormSet
->FormListHead
);
994 InitializeListHead (&FormSet
->ExpressionListHead
);
995 ResetCurrentExpressionStack ();
996 ResetMapExpressionListStack ();
999 CurrentStatement
= NULL
;
1004 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1005 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1007 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1008 OpCodeOffset
+= OpCodeLength
;
1009 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1010 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1013 // If scope bit set, push onto scope stack
1016 PushScope (Operand
);
1019 if (OpCodeDisabled
) {
1021 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1022 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1024 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1026 } else if (Operand
== EFI_IFR_END_OP
) {
1027 Status
= PopScope (&ScopeOpCode
);
1028 if (EFI_ERROR (Status
)) {
1032 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1033 if (DepthOfDisable
== 0) {
1034 InScopeDisable
= FALSE
;
1035 OpCodeDisabled
= FALSE
;
1044 if (IsExpressionOpCode (Operand
)) {
1045 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1046 mExpressionOpCodeIndex
++;
1048 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1049 ExpressionOpCode
->Operand
= Operand
;
1050 Value
= &ExpressionOpCode
->Value
;
1053 case EFI_IFR_EQ_ID_VAL_OP
:
1054 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1056 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1057 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1060 case EFI_IFR_EQ_ID_ID_OP
:
1061 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1062 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1065 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1066 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1067 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1068 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1071 case EFI_IFR_TO_STRING_OP
:
1072 case EFI_IFR_FIND_OP
:
1073 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1076 case EFI_IFR_STRING_REF1_OP
:
1077 Value
->Type
= EFI_IFR_TYPE_STRING
;
1078 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1081 case EFI_IFR_RULE_REF_OP
:
1082 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1085 case EFI_IFR_SPAN_OP
:
1086 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1089 case EFI_IFR_THIS_OP
:
1090 ASSERT (CurrentStatement
!= NULL
);
1091 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1094 case EFI_IFR_SECURITY_OP
:
1095 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1098 case EFI_IFR_GET_OP
:
1099 case EFI_IFR_SET_OP
:
1100 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1101 if (TempVarstoreId
!= 0) {
1102 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1103 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1104 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1105 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1106 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1107 ExpressionOpCode
->VarStorage
= VarStorage
;
1110 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1113 if (ExpressionOpCode
->VarStorage
== NULL
) {
1115 // VarStorage is not found.
1117 return EFI_INVALID_PARAMETER
;
1120 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1121 switch (ExpressionOpCode
->ValueType
) {
1122 case EFI_IFR_TYPE_BOOLEAN
:
1123 case EFI_IFR_TYPE_NUM_SIZE_8
:
1124 ExpressionOpCode
->ValueWidth
= 1;
1127 case EFI_IFR_TYPE_NUM_SIZE_16
:
1128 case EFI_IFR_TYPE_STRING
:
1129 ExpressionOpCode
->ValueWidth
= 2;
1132 case EFI_IFR_TYPE_NUM_SIZE_32
:
1133 ExpressionOpCode
->ValueWidth
= 4;
1136 case EFI_IFR_TYPE_NUM_SIZE_64
:
1137 ExpressionOpCode
->ValueWidth
= 8;
1140 case EFI_IFR_TYPE_DATE
:
1141 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1144 case EFI_IFR_TYPE_TIME
:
1145 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1148 case EFI_IFR_TYPE_REF
:
1149 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
1152 case EFI_IFR_TYPE_OTHER
:
1153 case EFI_IFR_TYPE_UNDEFINED
:
1154 case EFI_IFR_TYPE_ACTION
:
1155 case EFI_IFR_TYPE_BUFFER
:
1158 // Invalid value type for Get/Set opcode.
1160 return EFI_INVALID_PARAMETER
;
1162 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1163 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1164 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1165 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1166 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1167 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1168 if (ExpressionOpCode
->ValueName
== NULL
) {
1170 // String ID is invalid.
1172 return EFI_INVALID_PARAMETER
;
1177 case EFI_IFR_QUESTION_REF1_OP
:
1178 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1181 case EFI_IFR_QUESTION_REF3_OP
:
1182 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1183 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1185 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1186 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1194 case EFI_IFR_TRUE_OP
:
1195 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1196 Value
->Value
.b
= TRUE
;
1199 case EFI_IFR_FALSE_OP
:
1200 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1201 Value
->Value
.b
= FALSE
;
1204 case EFI_IFR_ONE_OP
:
1205 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1206 Value
->Value
.u8
= 1;
1209 case EFI_IFR_ZERO_OP
:
1210 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1211 Value
->Value
.u8
= 0;
1214 case EFI_IFR_ONES_OP
:
1215 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1216 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1219 case EFI_IFR_UINT8_OP
:
1220 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1221 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1224 case EFI_IFR_UINT16_OP
:
1225 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1226 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1229 case EFI_IFR_UINT32_OP
:
1230 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1231 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1234 case EFI_IFR_UINT64_OP
:
1235 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1236 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1239 case EFI_IFR_UNDEFINED_OP
:
1240 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1243 case EFI_IFR_VERSION_OP
:
1244 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1245 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1252 // Create sub expression nested in MAP opcode
1254 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1255 CurrentExpression
= CreateExpression (CurrentForm
);
1256 ASSERT (MapExpressionList
!= NULL
);
1257 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1259 SingleOpCodeExpression
= TRUE
;
1262 ASSERT (CurrentExpression
!= NULL
);
1263 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1264 if (Operand
== EFI_IFR_MAP_OP
) {
1266 // Store current Map Expression List.
1268 if (MapExpressionList
!= NULL
) {
1269 PushMapExpressionList (MapExpressionList
);
1272 // Initialize new Map Expression List.
1274 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1275 InitializeListHead (MapExpressionList
);
1277 // Store current expression.
1279 PushCurrentExpression (CurrentExpression
);
1280 CurrentExpression
= NULL
;
1282 } else if (SingleOpCodeExpression
) {
1284 // There are two cases to indicate the end of an Expression:
1285 // for single OpCode expression: one Expression OpCode
1286 // for expression consists of more than one OpCode: EFI_IFR_END
1288 SingleOpCodeExpression
= FALSE
;
1290 if (InScopeDisable
&& CurrentForm
== NULL
) {
1292 // This is DisableIf expression for Form, it should be a constant expression
1294 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1295 if (EFI_ERROR (Status
)) {
1299 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1300 return EFI_INVALID_PARAMETER
;
1303 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1306 CurrentExpression
= NULL
;
1317 case EFI_IFR_FORM_SET_OP
:
1319 // Check the formset GUID
1321 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1322 return EFI_INVALID_PARAMETER
;
1325 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1326 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1328 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1330 // The formset OpCode contains ClassGuid
1332 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1333 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1337 case EFI_IFR_FORM_OP
:
1339 // Create a new Form for this FormSet
1341 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1342 ASSERT (CurrentForm
!= NULL
);
1343 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1344 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1345 InitializeListHead (&CurrentForm
->StatementListHead
);
1346 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1348 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1349 CurrentForm
->NvUpdateRequired
= FALSE
;
1350 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1351 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1353 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1354 if ( ConditionalExprCount
> 0) {
1356 // Form is inside of suppressif
1358 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1359 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1360 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1361 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1362 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1363 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1368 // Enter scope of a Form, suppressif will be used for Question or Option
1370 SuppressForQuestion
= TRUE
;
1374 // Insert into Form list of this FormSet
1376 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1379 case EFI_IFR_FORM_MAP_OP
:
1381 // Create a new Form for this FormSet
1383 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1384 ASSERT (CurrentForm
!= NULL
);
1385 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1386 CurrentForm
->NvUpdateRequired
= FALSE
;
1387 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1388 InitializeListHead (&CurrentForm
->StatementListHead
);
1389 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1390 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1392 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1394 // FormMap Form must contain at least one Map Method.
1396 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1397 return EFI_INVALID_PARAMETER
;
1400 // Try to find the standard form map method.
1402 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1403 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1404 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1405 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1411 // If the standard form map method is not found, the first map method title will be used.
1413 if (CurrentForm
->FormTitle
== 0) {
1414 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1415 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1418 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1419 if ( ConditionalExprCount
> 0) {
1421 // Form is inside of suppressif
1423 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1424 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1425 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1426 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1427 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1428 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1433 // Enter scope of a Form, suppressif will be used for Question or Option
1435 SuppressForQuestion
= TRUE
;
1439 // Insert into Form list of this FormSet
1441 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1447 case EFI_IFR_VARSTORE_OP
:
1449 // Create a buffer Storage for this FormSet
1451 Storage
= CreateStorage (FormSet
);
1452 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1454 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1455 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1456 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1458 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1459 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1461 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1462 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1463 ASSERT (Storage
->Name
!= NULL
);
1464 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1465 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1469 // Initialize <ConfigHdr>
1471 InitializeConfigHdr (FormSet
, Storage
);
1474 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1476 // Create a name/value Storage for this FormSet
1478 Storage
= CreateStorage (FormSet
);
1479 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1481 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1482 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1485 // Initialize <ConfigHdr>
1487 InitializeConfigHdr (FormSet
, Storage
);
1490 case EFI_IFR_VARSTORE_EFI_OP
:
1492 // Create a EFI variable Storage for this FormSet
1494 Storage
= CreateStorage (FormSet
);
1496 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1497 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1498 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1499 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
1501 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1502 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1506 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
;
1507 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1508 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1510 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
1511 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1512 ASSERT (Storage
->Name
!= NULL
);
1513 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1514 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1518 // Initialize <ConfigHdr>
1520 InitializeConfigHdr (FormSet
, Storage
);
1526 case EFI_IFR_DEFAULTSTORE_OP
:
1527 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1528 ASSERT (DefaultStore
!= NULL
);
1529 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1531 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1532 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1535 // Insert to DefaultStore list of this Formset
1537 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1543 case EFI_IFR_SUBTITLE_OP
:
1544 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1545 ASSERT (CurrentStatement
!= NULL
);
1547 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1550 mInScopeSubtitle
= TRUE
;
1554 case EFI_IFR_TEXT_OP
:
1555 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1556 ASSERT (CurrentStatement
!= NULL
);
1558 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1561 case EFI_IFR_RESET_BUTTON_OP
:
1562 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1563 ASSERT (CurrentStatement
!= NULL
);
1564 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1570 case EFI_IFR_ACTION_OP
:
1571 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1572 ASSERT (CurrentStatement
!= NULL
);
1573 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1575 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1577 // No QuestionConfig present, so no configuration string will be processed
1579 CurrentStatement
->QuestionConfig
= 0;
1581 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1585 case EFI_IFR_REF_OP
:
1586 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1587 ASSERT (CurrentStatement
!= NULL
);
1588 Value
= &CurrentStatement
->HiiValue
;
1589 Value
->Type
= EFI_IFR_TYPE_REF
;
1590 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1591 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1593 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1594 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1596 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1597 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1599 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1600 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1605 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
1606 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1609 case EFI_IFR_ONE_OF_OP
:
1610 case EFI_IFR_NUMERIC_OP
:
1611 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1612 ASSERT(CurrentStatement
!= NULL
);
1614 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1615 Value
= &CurrentStatement
->HiiValue
;
1617 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1618 case EFI_IFR_NUMERIC_SIZE_1
:
1619 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1620 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1621 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1622 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1623 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1626 case EFI_IFR_NUMERIC_SIZE_2
:
1627 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1628 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1629 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1630 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1631 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1634 case EFI_IFR_NUMERIC_SIZE_4
:
1635 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1636 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1637 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1638 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1639 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1642 case EFI_IFR_NUMERIC_SIZE_8
:
1643 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1644 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1645 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1646 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1647 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1654 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1656 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1657 SuppressForOption
= TRUE
;
1661 case EFI_IFR_ORDERED_LIST_OP
:
1662 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1663 ASSERT(CurrentStatement
!= NULL
);
1665 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1666 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1668 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1669 CurrentStatement
->BufferValue
= NULL
;
1672 SuppressForOption
= TRUE
;
1676 case EFI_IFR_CHECKBOX_OP
:
1677 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1678 ASSERT(CurrentStatement
!= NULL
);
1680 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1681 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1682 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1684 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1688 case EFI_IFR_STRING_OP
:
1689 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1690 ASSERT (CurrentStatement
!= NULL
);
1692 // MinSize is the minimum number of characters that can be accepted for this opcode,
1693 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1694 // The characters are stored as Unicode, so the storage width should multiply 2.
1696 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1697 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1698 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1699 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1701 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1702 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1703 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1705 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1708 case EFI_IFR_PASSWORD_OP
:
1709 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1710 ASSERT (CurrentStatement
!= NULL
);
1712 // MinSize is the minimum number of characters that can be accepted for this opcode,
1713 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1714 // The characters are stored as Unicode, so the storage width should multiply 2.
1716 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1717 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1718 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1720 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1721 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1722 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1724 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1727 case EFI_IFR_DATE_OP
:
1728 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1729 ASSERT(CurrentStatement
!= NULL
);
1731 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1732 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1734 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1735 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1737 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1740 // Don't assign storage for RTC type of date/time
1742 CurrentStatement
->Storage
= NULL
;
1743 CurrentStatement
->StorageWidth
= 0;
1747 case EFI_IFR_TIME_OP
:
1748 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1749 ASSERT(CurrentStatement
!= NULL
);
1751 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1752 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1754 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1755 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1757 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1760 // Don't assign storage for RTC type of date/time
1762 CurrentStatement
->Storage
= NULL
;
1763 CurrentStatement
->StorageWidth
= 0;
1770 case EFI_IFR_DEFAULT_OP
:
1772 // EFI_IFR_DEFAULT appear in scope of a Question,
1773 // It creates a default value for the current question.
1774 // A Question may have more than one Default value which have different default types.
1776 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1777 ASSERT (CurrentDefault
!= NULL
);
1778 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1780 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1781 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1782 if (OpCodeLength
> OFFSET_OF (EFI_IFR_DEFAULT
, Value
)) {
1783 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
1784 ExtendValueToU64 (&CurrentDefault
->Value
);
1788 // Insert to Default Value list of current Question
1790 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1793 InScopeDefault
= TRUE
;
1800 case EFI_IFR_ONE_OF_OPTION_OP
:
1802 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1803 // It create a selection for use in current Question.
1805 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1806 ASSERT (CurrentOption
!= NULL
);
1807 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1809 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1810 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1811 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1812 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
1813 ExtendValueToU64 (&CurrentOption
->Value
);
1815 ConditionalExprCount
= GetConditionalExpressionCount(ExpressOption
);
1816 if ( ConditionalExprCount
> 0) {
1818 // Form is inside of suppressif
1820 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1821 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1822 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
1823 CurrentOption
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1824 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1825 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressOption
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1829 // Insert to Option list of current Question
1831 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1834 // Now we know the Storage width of nested Ordered List
1836 ASSERT (CurrentStatement
!= NULL
);
1837 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1839 switch (CurrentOption
->Value
.Type
) {
1840 case EFI_IFR_TYPE_NUM_SIZE_8
:
1844 case EFI_IFR_TYPE_NUM_SIZE_16
:
1848 case EFI_IFR_TYPE_NUM_SIZE_32
:
1852 case EFI_IFR_TYPE_NUM_SIZE_64
:
1858 // Invalid type for Ordered List
1863 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1864 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1865 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1866 if (CurrentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
1867 CurrentStatement
->HiiValue
.Buffer
= CurrentStatement
->BufferValue
;
1868 CurrentStatement
->HiiValue
.BufferLen
= CurrentStatement
->StorageWidth
;
1871 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1878 case EFI_IFR_NO_SUBMIT_IF_OP
:
1879 case EFI_IFR_INCONSISTENT_IF_OP
:
1881 // Create an Expression node
1883 CurrentExpression
= CreateExpression (CurrentForm
);
1884 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1886 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1887 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1888 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1890 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1891 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1895 // Take a look at next OpCode to see whether current expression consists
1898 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1899 SingleOpCodeExpression
= TRUE
;
1903 case EFI_IFR_SUPPRESS_IF_OP
:
1905 // Question and Option will appear in scope of this OpCode
1907 CurrentExpression
= CreateExpression (CurrentForm
);
1908 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1910 if (CurrentForm
== NULL
) {
1911 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1913 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1916 if (SuppressForOption
) {
1917 PushConditionalExpression(CurrentExpression
, ExpressOption
);
1918 } else if (SuppressForQuestion
) {
1919 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
1921 PushConditionalExpression(CurrentExpression
, ExpressForm
);
1925 // Take a look at next OpCode to see whether current expression consists
1928 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1929 SingleOpCodeExpression
= TRUE
;
1933 case EFI_IFR_GRAY_OUT_IF_OP
:
1935 // Questions will appear in scope of this OpCode
1937 CurrentExpression
= CreateExpression (CurrentForm
);
1938 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1939 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1940 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
1943 // Take a look at next OpCode to see whether current expression consists
1946 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1947 SingleOpCodeExpression
= TRUE
;
1951 case EFI_IFR_DISABLE_IF_OP
:
1953 // The DisableIf expression should only rely on constant, so it could be
1954 // evaluated at initialization and it will not be queued
1956 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1957 ASSERT (CurrentExpression
!= NULL
);
1958 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1959 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1960 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1962 if (CurrentForm
!= NULL
) {
1964 // This is DisableIf for Question, enqueue it to Form expression list
1966 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1967 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
1970 OpCodeDisabled
= FALSE
;
1971 InScopeDisable
= TRUE
;
1973 // Take a look at next OpCode to see whether current expression consists
1976 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1977 SingleOpCodeExpression
= TRUE
;
1984 case EFI_IFR_VALUE_OP
:
1985 CurrentExpression
= CreateExpression (CurrentForm
);
1986 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1987 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1989 if (InScopeDefault
) {
1991 // Used for default (EFI_IFR_DEFAULT)
1993 CurrentDefault
->ValueExpression
= CurrentExpression
;
1996 // If used for a question, then the question will be read-only
1999 // Make sure CurrentStatement is not NULL.
2000 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2001 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2003 ASSERT (CurrentStatement
!= NULL
);
2004 CurrentStatement
->ValueExpression
= CurrentExpression
;
2008 // Take a look at next OpCode to see whether current expression consists
2011 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2012 SingleOpCodeExpression
= TRUE
;
2016 case EFI_IFR_RULE_OP
:
2017 CurrentExpression
= CreateExpression (CurrentForm
);
2018 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2020 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2021 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2024 // Take a look at next OpCode to see whether current expression consists
2027 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2028 SingleOpCodeExpression
= TRUE
;
2032 case EFI_IFR_READ_OP
:
2033 CurrentExpression
= CreateExpression (CurrentForm
);
2034 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2035 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2038 // Make sure CurrentStatement is not NULL.
2039 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2040 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2042 ASSERT (CurrentStatement
!= NULL
);
2043 CurrentStatement
->ReadExpression
= CurrentExpression
;
2046 // Take a look at next OpCode to see whether current expression consists
2049 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2050 SingleOpCodeExpression
= TRUE
;
2054 case EFI_IFR_WRITE_OP
:
2055 CurrentExpression
= CreateExpression (CurrentForm
);
2056 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2057 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2060 // Make sure CurrentStatement is not NULL.
2061 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2062 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2064 ASSERT (CurrentStatement
!= NULL
);
2065 CurrentStatement
->WriteExpression
= CurrentExpression
;
2068 // Take a look at next OpCode to see whether current expression consists
2071 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2072 SingleOpCodeExpression
= TRUE
;
2079 case EFI_IFR_IMAGE_OP
:
2081 // Get ScopeOpcode from top of stack
2083 PopScope (&ScopeOpCode
);
2084 PushScope (ScopeOpCode
);
2086 switch (ScopeOpCode
) {
2087 case EFI_IFR_FORM_SET_OP
:
2088 ImageId
= &FormSet
->ImageId
;
2091 case EFI_IFR_FORM_OP
:
2092 case EFI_IFR_FORM_MAP_OP
:
2093 ASSERT (CurrentForm
!= NULL
);
2094 ImageId
= &CurrentForm
->ImageId
;
2097 case EFI_IFR_ONE_OF_OPTION_OP
:
2098 ImageId
= &CurrentOption
->ImageId
;
2103 // Make sure CurrentStatement is not NULL.
2104 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2105 // file is wrongly generated by tools such as VFR Compiler.
2107 ASSERT (CurrentStatement
!= NULL
);
2108 ImageId
= &CurrentStatement
->ImageId
;
2112 ASSERT (ImageId
!= NULL
);
2113 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2119 case EFI_IFR_REFRESH_OP
:
2120 ASSERT (CurrentStatement
!= NULL
);
2121 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2127 case EFI_IFR_REFRESH_ID_OP
:
2128 ASSERT (CurrentStatement
!= NULL
);
2129 CopyMem (&CurrentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2135 case EFI_IFR_MODAL_TAG_OP
:
2136 ASSERT (CurrentForm
!= NULL
);
2137 CurrentForm
->ModalForm
= TRUE
;
2141 // Lock tag, used by form and statement.
2143 case EFI_IFR_LOCKED_OP
:
2145 // Get ScopeOpcode from top of stack
2147 PopScope (&ScopeOpCode
);
2148 PushScope (ScopeOpCode
);
2149 switch (ScopeOpCode
) {
2150 case EFI_IFR_FORM_OP
:
2151 case EFI_IFR_FORM_MAP_OP
:
2152 ASSERT (CurrentForm
!= NULL
);
2153 CurrentForm
->Locked
= TRUE
;
2157 ASSERT (CurrentStatement
!= NULL
);
2158 CurrentStatement
->Locked
= TRUE
;
2165 case EFI_IFR_GUID_OP
:
2166 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2168 // Tiano specific GUIDed opcodes
2170 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2171 case EFI_IFR_EXTEND_OP_LABEL
:
2173 // just ignore label
2177 case EFI_IFR_EXTEND_OP_BANNER
:
2179 // By SubClass to get Banner Data from Front Page
2181 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2183 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2184 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2185 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2186 sizeof (EFI_STRING_ID
)
2191 case EFI_IFR_EXTEND_OP_CLASS
:
2192 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2195 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2196 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2209 case EFI_IFR_END_OP
:
2210 Status
= PopScope (&ScopeOpCode
);
2211 if (EFI_ERROR (Status
)) {
2216 switch (ScopeOpCode
) {
2217 case EFI_IFR_FORM_SET_OP
:
2219 // End of FormSet, update FormSet IFR binary length
2220 // to stop parsing substantial OpCodes
2222 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2225 case EFI_IFR_FORM_OP
:
2226 case EFI_IFR_FORM_MAP_OP
:
2231 SuppressForQuestion
= FALSE
;
2234 case EFI_IFR_ONE_OF_OPTION_OP
:
2238 CurrentOption
= NULL
;
2241 case EFI_IFR_SUBTITLE_OP
:
2242 mInScopeSubtitle
= FALSE
;
2245 case EFI_IFR_NO_SUBMIT_IF_OP
:
2246 case EFI_IFR_INCONSISTENT_IF_OP
:
2248 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2252 case EFI_IFR_SUPPRESS_IF_OP
:
2253 if (SuppressForOption
) {
2254 PopConditionalExpression(ExpressOption
);
2255 } else if (SuppressForQuestion
) {
2256 PopConditionalExpression(ExpressStatement
);
2258 PopConditionalExpression(ExpressForm
);
2262 case EFI_IFR_GRAY_OUT_IF_OP
:
2263 PopConditionalExpression(ExpressStatement
);
2266 case EFI_IFR_DISABLE_IF_OP
:
2267 if (CurrentForm
!= NULL
) {
2268 PopConditionalExpression(ExpressStatement
);
2270 InScopeDisable
= FALSE
;
2271 OpCodeDisabled
= FALSE
;
2274 case EFI_IFR_ONE_OF_OP
:
2275 case EFI_IFR_ORDERED_LIST_OP
:
2276 SuppressForOption
= FALSE
;
2279 case EFI_IFR_DEFAULT_OP
:
2280 InScopeDefault
= FALSE
;
2283 case EFI_IFR_MAP_OP
:
2285 // Get current Map Expression List.
2287 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2288 if (Status
== EFI_ACCESS_DENIED
) {
2289 MapExpressionList
= NULL
;
2292 // Get current expression.
2294 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2295 ASSERT_EFI_ERROR (Status
);
2296 ASSERT (MapScopeDepth
> 0);
2301 if (IsExpressionOpCode (ScopeOpCode
)) {
2302 if (InScopeDisable
&& CurrentForm
== NULL
) {
2304 // This is DisableIf expression for Form, it should be a constant expression
2306 ASSERT (CurrentExpression
!= NULL
);
2307 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2308 if (EFI_ERROR (Status
)) {
2312 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2313 return EFI_INVALID_PARAMETER
;
2316 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2318 // DisableIf Expression is only used once and not queued, free it
2320 DestroyExpression (CurrentExpression
);
2324 // End of current Expression
2326 CurrentExpression
= NULL
;