2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2012, 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 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1783 ExtendValueToU64 (&CurrentDefault
->Value
);
1786 // Insert to Default Value list of current Question
1788 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1791 InScopeDefault
= TRUE
;
1798 case EFI_IFR_ONE_OF_OPTION_OP
:
1800 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1801 // It create a selection for use in current Question.
1803 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1804 ASSERT (CurrentOption
!= NULL
);
1805 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1807 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1808 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1809 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1810 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1811 ExtendValueToU64 (&CurrentOption
->Value
);
1813 ConditionalExprCount
= GetConditionalExpressionCount(ExpressOption
);
1814 if ( ConditionalExprCount
> 0) {
1816 // Form is inside of suppressif
1818 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1819 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1820 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
1821 CurrentOption
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1822 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1823 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressOption
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1827 // Insert to Option list of current Question
1829 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1832 // Now we know the Storage width of nested Ordered List
1834 ASSERT (CurrentStatement
!= NULL
);
1835 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1837 switch (CurrentOption
->Value
.Type
) {
1838 case EFI_IFR_TYPE_NUM_SIZE_8
:
1842 case EFI_IFR_TYPE_NUM_SIZE_16
:
1846 case EFI_IFR_TYPE_NUM_SIZE_32
:
1850 case EFI_IFR_TYPE_NUM_SIZE_64
:
1856 // Invalid type for Ordered List
1861 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1862 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1863 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1864 if (CurrentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
1865 CurrentStatement
->HiiValue
.Buffer
= CurrentStatement
->BufferValue
;
1866 CurrentStatement
->HiiValue
.BufferLen
= CurrentStatement
->StorageWidth
;
1869 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1876 case EFI_IFR_NO_SUBMIT_IF_OP
:
1877 case EFI_IFR_INCONSISTENT_IF_OP
:
1879 // Create an Expression node
1881 CurrentExpression
= CreateExpression (CurrentForm
);
1882 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1884 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1885 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1886 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1888 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1889 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1893 // Take a look at next OpCode to see whether current expression consists
1896 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1897 SingleOpCodeExpression
= TRUE
;
1901 case EFI_IFR_SUPPRESS_IF_OP
:
1903 // Question and Option will appear in scope of this OpCode
1905 CurrentExpression
= CreateExpression (CurrentForm
);
1906 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1908 if (CurrentForm
== NULL
) {
1909 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1911 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1914 if (SuppressForOption
) {
1915 PushConditionalExpression(CurrentExpression
, ExpressOption
);
1916 } else if (SuppressForQuestion
) {
1917 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
1919 PushConditionalExpression(CurrentExpression
, ExpressForm
);
1923 // Take a look at next OpCode to see whether current expression consists
1926 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1927 SingleOpCodeExpression
= TRUE
;
1931 case EFI_IFR_GRAY_OUT_IF_OP
:
1933 // Questions will appear in scope of this OpCode
1935 CurrentExpression
= CreateExpression (CurrentForm
);
1936 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1937 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1938 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
1941 // Take a look at next OpCode to see whether current expression consists
1944 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1945 SingleOpCodeExpression
= TRUE
;
1949 case EFI_IFR_DISABLE_IF_OP
:
1951 // The DisableIf expression should only rely on constant, so it could be
1952 // evaluated at initialization and it will not be queued
1954 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1955 ASSERT (CurrentExpression
!= NULL
);
1956 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1957 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1958 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1960 if (CurrentForm
!= NULL
) {
1962 // This is DisableIf for Question, enqueue it to Form expression list
1964 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1965 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
1968 OpCodeDisabled
= FALSE
;
1969 InScopeDisable
= TRUE
;
1971 // Take a look at next OpCode to see whether current expression consists
1974 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1975 SingleOpCodeExpression
= TRUE
;
1982 case EFI_IFR_VALUE_OP
:
1983 CurrentExpression
= CreateExpression (CurrentForm
);
1984 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1985 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1987 if (InScopeDefault
) {
1989 // Used for default (EFI_IFR_DEFAULT)
1991 CurrentDefault
->ValueExpression
= CurrentExpression
;
1994 // If used for a question, then the question will be read-only
1997 // Make sure CurrentStatement is not NULL.
1998 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1999 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2001 ASSERT (CurrentStatement
!= NULL
);
2002 CurrentStatement
->ValueExpression
= CurrentExpression
;
2006 // Take a look at next OpCode to see whether current expression consists
2009 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2010 SingleOpCodeExpression
= TRUE
;
2014 case EFI_IFR_RULE_OP
:
2015 CurrentExpression
= CreateExpression (CurrentForm
);
2016 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2018 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2019 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2022 // Take a look at next OpCode to see whether current expression consists
2025 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2026 SingleOpCodeExpression
= TRUE
;
2030 case EFI_IFR_READ_OP
:
2031 CurrentExpression
= CreateExpression (CurrentForm
);
2032 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2033 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2036 // Make sure CurrentStatement is not NULL.
2037 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2038 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2040 ASSERT (CurrentStatement
!= NULL
);
2041 CurrentStatement
->ReadExpression
= CurrentExpression
;
2044 // Take a look at next OpCode to see whether current expression consists
2047 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2048 SingleOpCodeExpression
= TRUE
;
2052 case EFI_IFR_WRITE_OP
:
2053 CurrentExpression
= CreateExpression (CurrentForm
);
2054 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2055 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2058 // Make sure CurrentStatement is not NULL.
2059 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2060 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2062 ASSERT (CurrentStatement
!= NULL
);
2063 CurrentStatement
->WriteExpression
= CurrentExpression
;
2066 // Take a look at next OpCode to see whether current expression consists
2069 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2070 SingleOpCodeExpression
= TRUE
;
2077 case EFI_IFR_IMAGE_OP
:
2079 // Get ScopeOpcode from top of stack
2081 PopScope (&ScopeOpCode
);
2082 PushScope (ScopeOpCode
);
2084 switch (ScopeOpCode
) {
2085 case EFI_IFR_FORM_SET_OP
:
2086 ImageId
= &FormSet
->ImageId
;
2089 case EFI_IFR_FORM_OP
:
2090 case EFI_IFR_FORM_MAP_OP
:
2091 ASSERT (CurrentForm
!= NULL
);
2092 ImageId
= &CurrentForm
->ImageId
;
2095 case EFI_IFR_ONE_OF_OPTION_OP
:
2096 ImageId
= &CurrentOption
->ImageId
;
2101 // Make sure CurrentStatement is not NULL.
2102 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2103 // file is wrongly generated by tools such as VFR Compiler.
2105 ASSERT (CurrentStatement
!= NULL
);
2106 ImageId
= &CurrentStatement
->ImageId
;
2110 ASSERT (ImageId
!= NULL
);
2111 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2117 case EFI_IFR_REFRESH_OP
:
2118 ASSERT (CurrentStatement
!= NULL
);
2119 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2125 case EFI_IFR_REFRESH_ID_OP
:
2126 ASSERT (CurrentStatement
!= NULL
);
2127 CopyMem (&CurrentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2133 case EFI_IFR_MODAL_TAG_OP
:
2134 ASSERT (CurrentForm
!= NULL
);
2135 CurrentForm
->ModalForm
= TRUE
;
2139 // Lock tag, used by form and statement.
2141 case EFI_IFR_LOCKED_OP
:
2143 // Get ScopeOpcode from top of stack
2145 PopScope (&ScopeOpCode
);
2146 PushScope (ScopeOpCode
);
2147 switch (ScopeOpCode
) {
2148 case EFI_IFR_FORM_OP
:
2149 case EFI_IFR_FORM_MAP_OP
:
2150 ASSERT (CurrentForm
!= NULL
);
2151 CurrentForm
->Locked
= TRUE
;
2155 ASSERT (CurrentStatement
!= NULL
);
2156 CurrentStatement
->Locked
= TRUE
;
2163 case EFI_IFR_GUID_OP
:
2164 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2166 // Tiano specific GUIDed opcodes
2168 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2169 case EFI_IFR_EXTEND_OP_LABEL
:
2171 // just ignore label
2175 case EFI_IFR_EXTEND_OP_BANNER
:
2177 // By SubClass to get Banner Data from Front Page
2179 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2181 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2182 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2183 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2184 sizeof (EFI_STRING_ID
)
2189 case EFI_IFR_EXTEND_OP_CLASS
:
2190 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2193 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2194 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2207 case EFI_IFR_END_OP
:
2208 Status
= PopScope (&ScopeOpCode
);
2209 if (EFI_ERROR (Status
)) {
2214 switch (ScopeOpCode
) {
2215 case EFI_IFR_FORM_SET_OP
:
2217 // End of FormSet, update FormSet IFR binary length
2218 // to stop parsing substantial OpCodes
2220 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2223 case EFI_IFR_FORM_OP
:
2224 case EFI_IFR_FORM_MAP_OP
:
2229 SuppressForQuestion
= FALSE
;
2232 case EFI_IFR_ONE_OF_OPTION_OP
:
2236 CurrentOption
= NULL
;
2239 case EFI_IFR_SUBTITLE_OP
:
2240 mInScopeSubtitle
= FALSE
;
2243 case EFI_IFR_NO_SUBMIT_IF_OP
:
2244 case EFI_IFR_INCONSISTENT_IF_OP
:
2246 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2250 case EFI_IFR_SUPPRESS_IF_OP
:
2251 if (SuppressForOption
) {
2252 PopConditionalExpression(ExpressOption
);
2253 } else if (SuppressForQuestion
) {
2254 PopConditionalExpression(ExpressStatement
);
2256 PopConditionalExpression(ExpressForm
);
2260 case EFI_IFR_GRAY_OUT_IF_OP
:
2261 PopConditionalExpression(ExpressStatement
);
2264 case EFI_IFR_DISABLE_IF_OP
:
2265 if (CurrentForm
!= NULL
) {
2266 PopConditionalExpression(ExpressStatement
);
2268 InScopeDisable
= FALSE
;
2269 OpCodeDisabled
= FALSE
;
2272 case EFI_IFR_ONE_OF_OP
:
2273 case EFI_IFR_ORDERED_LIST_OP
:
2274 SuppressForOption
= FALSE
;
2277 case EFI_IFR_DEFAULT_OP
:
2278 InScopeDefault
= FALSE
;
2281 case EFI_IFR_MAP_OP
:
2283 // Get current Map Expression List.
2285 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2286 if (Status
== EFI_ACCESS_DENIED
) {
2287 MapExpressionList
= NULL
;
2290 // Get current expression.
2292 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2293 ASSERT_EFI_ERROR (Status
);
2294 ASSERT (MapScopeDepth
> 0);
2299 if (IsExpressionOpCode (ScopeOpCode
)) {
2300 if (InScopeDisable
&& CurrentForm
== NULL
) {
2302 // This is DisableIf expression for Form, it should be a constant expression
2304 ASSERT (CurrentExpression
!= NULL
);
2305 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2306 if (EFI_ERROR (Status
)) {
2310 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2311 return EFI_INVALID_PARAMETER
;
2314 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2316 // DisableIf Expression is only used once and not queued, free it
2318 DestroyExpression (CurrentExpression
);
2322 // End of current Expression
2324 CurrentExpression
= NULL
;