2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2009, Intel Corporation
5 All rights reserved. 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.
18 UINT16 mStatementIndex
;
19 UINT16 mExpressionOpCodeIndex
;
21 BOOLEAN mInScopeSubtitle
;
22 BOOLEAN mInScopeSuppress
;
23 BOOLEAN mInScopeGrayOut
;
24 FORM_EXPRESSION
*mSuppressExpression
;
25 FORM_EXPRESSION
*mGrayOutExpression
;
28 Initialize Statement header members.
30 @param OpCodeData Pointer of the raw OpCode data.
31 @param FormSet Pointer of the current FormSe.
32 @param Form Pointer of the current Form.
34 @return The Statement.
37 FORM_BROWSER_STATEMENT
*
40 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
41 IN OUT FORM_BROWSER_FORM
*Form
44 FORM_BROWSER_STATEMENT
*Statement
;
45 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
49 // We are currently not in a Form Scope, so just skip this Statement
54 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
57 InitializeListHead (&Statement
->DefaultListHead
);
58 InitializeListHead (&Statement
->OptionListHead
);
59 InitializeListHead (&Statement
->InconsistentListHead
);
60 InitializeListHead (&Statement
->NoSubmitListHead
);
62 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
64 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
66 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
67 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
68 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
70 if (mInScopeSuppress
) {
71 Statement
->SuppressExpression
= mSuppressExpression
;
74 if (mInScopeGrayOut
) {
75 Statement
->GrayOutExpression
= mGrayOutExpression
;
78 Statement
->InSubtitle
= mInScopeSubtitle
;
81 // Insert this Statement into current Form
83 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
89 Convert a numeric value to a Unicode String and insert it to String Package.
90 This string is used as the Unicode Name for the EFI Variable. This is to support
91 the deprecated vareqval opcode.
93 @param FormSet The FormSet.
94 @param Statement The numeric question whose VarStoreInfo.VarName is the
95 numeric value which is used to produce the Unicode Name
98 If the Statement is NULL, the ASSERT.
99 If the opcode is not Numeric, then ASSERT.
101 @retval EFI_SUCCESS The funtion always succeeds.
104 UpdateCheckBoxStringToken (
105 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
106 IN FORM_BROWSER_STATEMENT
*Statement
109 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
112 ASSERT (Statement
!= NULL
);
113 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
115 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
117 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
119 return EFI_OUT_OF_RESOURCES
;
122 Statement
->VarStoreInfo
.VarName
= Id
;
128 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
130 @param OpCodeData The current opcode.
136 IsNextOpCodeGuidedVarEqName (
143 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
144 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
145 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
147 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
149 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
159 Initialize Question's members.
161 @param OpCodeData Pointer of the raw OpCode data.
162 @param FormSet Pointer of the current FormSet.
163 @param Form Pointer of the current Form.
165 @return The Question.
168 FORM_BROWSER_STATEMENT
*
170 IN UINT8
*OpCodeData
,
171 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
172 IN OUT FORM_BROWSER_FORM
*Form
175 FORM_BROWSER_STATEMENT
*Statement
;
176 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
178 FORMSET_STORAGE
*Storage
;
179 NAME_VALUE_NODE
*NameValueNode
;
182 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
183 if (Statement
== NULL
) {
187 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
188 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
189 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
190 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
192 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
194 if (Statement
->VarStoreId
== 0) {
196 // VarStoreId of zero indicates no variable storage
202 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
203 // Framework Compatibility
205 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
206 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
207 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
208 if (EFI_ERROR (Status
)) {
215 // Find Storage for this Question
217 Link
= GetFirstNode (&FormSet
->StorageListHead
);
218 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
219 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
221 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
222 Statement
->Storage
= Storage
;
226 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
228 ASSERT (Statement
->Storage
!= NULL
);
231 // Initialilze varname for Name/Value or EFI Variable
233 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
234 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
235 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
236 ASSERT (Statement
->VariableName
!= NULL
);
238 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
240 // Insert to Name/Value varstore list
242 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
243 ASSERT (NameValueNode
!= NULL
);
244 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
245 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
246 ASSERT (NameValueNode
->Name
!= NULL
);
247 NameValueNode
->Value
= AllocateZeroPool (0x10);
248 ASSERT (NameValueNode
->Value
!= NULL
);
249 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
250 ASSERT (NameValueNode
->EditValue
!= NULL
);
252 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
261 Allocate a FORM_EXPRESSION node.
263 @param Form The Form associated with this Expression
265 @return Pointer to a FORM_EXPRESSION data structure.
270 IN OUT FORM_BROWSER_FORM
*Form
273 FORM_EXPRESSION
*Expression
;
275 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
276 ASSERT (Expression
!= NULL
);
277 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
278 InitializeListHead (&Expression
->OpCodeListHead
);
285 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
287 @param FormSet Pointer of the current FormSet
289 @return Pointer to a FORMSET_STORAGE data structure.
294 IN FORM_BROWSER_FORMSET
*FormSet
297 FORMSET_STORAGE
*Storage
;
299 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
300 ASSERT (Storage
!= NULL
);
301 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
302 InitializeListHead (&Storage
->NameValueListHead
);
303 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
310 Create ConfigHdr string for a storage.
312 @param FormSet Pointer of the current FormSet
313 @param Storage Pointer of the storage
315 @retval EFI_SUCCESS Initialize ConfigHdr success
319 InitializeConfigHdr (
320 IN FORM_BROWSER_FORMSET
*FormSet
,
321 IN OUT FORMSET_STORAGE
*Storage
326 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
327 Name
= Storage
->Name
;
332 Storage
->ConfigHdr
= HiiConstructConfigHdr (
335 FormSet
->DriverHandle
338 if (Storage
->ConfigHdr
== NULL
) {
339 return EFI_NOT_FOUND
;
342 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
343 Storage
->SpareStrLen
= 0;
350 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
352 @param FormSet Pointer of the current FormSet.
353 @param Question The Question to be initialized.
355 @retval EFI_SUCCESS Function success.
356 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
360 InitializeRequestElement (
361 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
362 IN OUT FORM_BROWSER_STATEMENT
*Question
365 FORMSET_STORAGE
*Storage
;
369 CHAR16 RequestElement
[30];
371 Storage
= Question
->Storage
;
372 if (Storage
== NULL
) {
373 return EFI_INVALID_PARAMETER
;
376 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
378 // <ConfigRequest> is unnecessary for EFI variable storage,
379 // GetVariable()/SetVariable() will be used to retrieve/save values
385 // Prepare <RequestElement>
387 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
388 StrLen
= UnicodeSPrint (
390 30 * sizeof (CHAR16
),
391 L
"&OFFSET=%x&WIDTH=%x",
392 Question
->VarStoreInfo
.VarOffset
,
393 Question
->StorageWidth
395 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
397 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
400 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
402 // Password with CALLBACK flag is stored in encoded format,
403 // so don't need to append it to <ConfigRequest>
409 // Append <RequestElement> to <ConfigRequest>
411 if (StrLen
> Storage
->SpareStrLen
) {
413 // Old String buffer is not sufficient for RequestElement, allocate a new one
415 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
416 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
417 ASSERT (NewStr
!= NULL
);
418 if (Storage
->ConfigRequest
!= NULL
) {
419 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
420 FreePool (Storage
->ConfigRequest
);
422 Storage
->ConfigRequest
= NewStr
;
423 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
426 StrCat (Storage
->ConfigRequest
, RequestElement
);
427 Storage
->ElementCount
++;
428 Storage
->SpareStrLen
-= StrLen
;
435 Free resources of a Expression.
437 @param FormSet Pointer of the Expression
442 IN FORM_EXPRESSION
*Expression
446 EXPRESSION_OPCODE
*OpCode
;
448 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
449 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
450 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
451 RemoveEntryList (&OpCode
->Link
);
453 if (OpCode
->ValueList
!= NULL
) {
454 FreePool (OpCode
->ValueList
);
459 // Free this Expression
461 FreePool (Expression
);
466 Free resources of a storage.
468 @param Storage Pointer of the storage
473 IN FORMSET_STORAGE
*Storage
477 NAME_VALUE_NODE
*NameValueNode
;
479 if (Storage
== NULL
) {
483 if (Storage
->Name
!= NULL
) {
484 FreePool (Storage
->Name
);
486 if (Storage
->Buffer
!= NULL
) {
487 FreePool (Storage
->Buffer
);
489 if (Storage
->EditBuffer
!= NULL
) {
490 FreePool (Storage
->EditBuffer
);
493 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
494 Link
= GetFirstNode (&Storage
->NameValueListHead
);
495 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
496 RemoveEntryList (&NameValueNode
->Link
);
498 if (NameValueNode
->Name
!= NULL
) {
499 FreePool (NameValueNode
->Name
);
501 if (NameValueNode
->Value
!= NULL
) {
502 FreePool (NameValueNode
->Value
);
504 if (NameValueNode
->EditValue
!= NULL
) {
505 FreePool (NameValueNode
->EditValue
);
507 FreePool (NameValueNode
);
510 if (Storage
->ConfigHdr
!= NULL
) {
511 FreePool (Storage
->ConfigHdr
);
513 if (Storage
->ConfigRequest
!= NULL
) {
514 FreePool (Storage
->ConfigRequest
);
522 Free resources of a Statement.
524 @param Statement Pointer of the Statement
529 IN OUT FORM_BROWSER_STATEMENT
*Statement
533 QUESTION_DEFAULT
*Default
;
534 QUESTION_OPTION
*Option
;
535 FORM_EXPRESSION
*Expression
;
538 // Free Default value List
540 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
541 Link
= GetFirstNode (&Statement
->DefaultListHead
);
542 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
543 RemoveEntryList (&Default
->Link
);
551 while (!IsListEmpty (&Statement
->OptionListHead
)) {
552 Link
= GetFirstNode (&Statement
->OptionListHead
);
553 Option
= QUESTION_OPTION_FROM_LINK (Link
);
554 RemoveEntryList (&Option
->Link
);
560 // Free Inconsistent List
562 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
563 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
564 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
565 RemoveEntryList (&Expression
->Link
);
567 DestroyExpression (Expression
);
571 // Free NoSubmit List
573 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
574 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
575 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
576 RemoveEntryList (&Expression
->Link
);
578 DestroyExpression (Expression
);
581 if (Statement
->VariableName
!= NULL
) {
582 FreePool (Statement
->VariableName
);
584 if (Statement
->BlockName
!= NULL
) {
585 FreePool (Statement
->BlockName
);
591 Free resources of a Form.
593 @param Form Pointer of the Form.
598 IN OUT FORM_BROWSER_FORM
*Form
602 FORM_EXPRESSION
*Expression
;
603 FORM_BROWSER_STATEMENT
*Statement
;
606 // Free Form Expressions
608 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
609 Link
= GetFirstNode (&Form
->ExpressionListHead
);
610 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
611 RemoveEntryList (&Expression
->Link
);
613 DestroyExpression (Expression
);
617 // Free Statements/Questions
619 while (!IsListEmpty (&Form
->StatementListHead
)) {
620 Link
= GetFirstNode (&Form
->StatementListHead
);
621 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
622 RemoveEntryList (&Statement
->Link
);
624 DestroyStatement (Statement
);
635 Free resources allocated for a FormSet.
637 @param FormSet Pointer of the FormSet
642 IN OUT FORM_BROWSER_FORMSET
*FormSet
646 FORMSET_STORAGE
*Storage
;
647 FORMSET_DEFAULTSTORE
*DefaultStore
;
648 FORM_BROWSER_FORM
*Form
;
651 // Free IFR binary buffer
653 FreePool (FormSet
->IfrBinaryData
);
656 // Free FormSet Storage
658 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
659 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
660 Link
= GetFirstNode (&FormSet
->StorageListHead
);
661 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
662 RemoveEntryList (&Storage
->Link
);
664 DestroyStorage (Storage
);
669 // Free FormSet Default Store
671 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
672 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
673 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
674 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
675 RemoveEntryList (&DefaultStore
->Link
);
677 FreePool (DefaultStore
);
684 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
685 while (!IsListEmpty (&FormSet
->FormListHead
)) {
686 Link
= GetFirstNode (&FormSet
->FormListHead
);
687 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
688 RemoveEntryList (&Form
->Link
);
694 if (FormSet
->StatementBuffer
!= NULL
) {
695 FreePool (FormSet
->StatementBuffer
);
697 if (FormSet
->ExpressionBuffer
!= NULL
) {
698 FreePool (FormSet
->ExpressionBuffer
);
706 Tell whether this Operand is an Expression OpCode or not
708 @param Operand Operand of an IFR OpCode.
710 @retval TRUE This is an Expression OpCode.
711 @retval FALSE Not an Expression OpCode.
719 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
720 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
721 (Operand
== EFI_IFR_CATENATE_OP
) ||
722 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
723 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
724 (Operand
== EFI_IFR_VERSION_OP
)
734 Calculate number of Statemens(Questions) and Expression OpCodes.
736 @param FormSet The FormSet to be counted.
737 @param NumberOfStatement Number of Statemens(Questions)
738 @param NumberOfExpression Number of Expression OpCodes
743 IN FORM_BROWSER_FORMSET
*FormSet
,
744 IN OUT UINT16
*NumberOfStatement
,
745 IN OUT UINT16
*NumberOfExpression
748 UINT16 StatementCount
;
749 UINT16 ExpressionCount
;
758 while (Offset
< FormSet
->IfrBinaryLength
) {
759 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
760 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
763 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
770 *NumberOfStatement
= StatementCount
;
771 *NumberOfExpression
= ExpressionCount
;
777 Parse opcodes in the formset IFR binary.
779 @param FormSet Pointer of the FormSet data structure.
781 @retval EFI_SUCCESS Opcode parse success.
782 @retval Other Opcode parse fail.
787 IN FORM_BROWSER_FORMSET
*FormSet
792 FORM_BROWSER_FORM
*CurrentForm
;
793 FORM_BROWSER_STATEMENT
*CurrentStatement
;
794 EXPRESSION_OPCODE
*ExpressionOpCode
;
795 FORM_EXPRESSION
*CurrentExpression
;
802 FORMSET_STORAGE
*Storage
;
803 FORMSET_DEFAULTSTORE
*DefaultStore
;
804 QUESTION_DEFAULT
*CurrentDefault
;
805 QUESTION_OPTION
*CurrentOption
;
807 UINT16 NumberOfStatement
;
808 UINT16 NumberOfExpression
;
809 EFI_IMAGE_ID
*ImageId
;
810 BOOLEAN SuppressForOption
;
811 BOOLEAN InScopeOptionSuppress
;
812 FORM_EXPRESSION
*OptionSuppressExpression
;
813 BOOLEAN InScopeDisable
;
814 UINT16 DepthOfDisable
;
815 BOOLEAN OpCodeDisabled
;
816 BOOLEAN SingleOpCodeExpression
;
817 BOOLEAN InScopeDefault
;
818 EFI_HII_VALUE
*Value
;
820 mInScopeSubtitle
= FALSE
;
821 SuppressForOption
= FALSE
;
822 mInScopeSuppress
= FALSE
;
823 InScopeOptionSuppress
= FALSE
;
824 mInScopeGrayOut
= FALSE
;
825 InScopeDisable
= FALSE
;
827 OpCodeDisabled
= FALSE
;
828 SingleOpCodeExpression
= FALSE
;
829 InScopeDefault
= FALSE
;
830 CurrentExpression
= NULL
;
831 CurrentDefault
= NULL
;
832 CurrentOption
= NULL
;
833 OptionSuppressExpression
= NULL
;
837 // Get the number of Statements and Expressions
839 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
842 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
843 if (FormSet
->StatementBuffer
== NULL
) {
844 return EFI_OUT_OF_RESOURCES
;
847 mExpressionOpCodeIndex
= 0;
848 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
849 if (FormSet
->ExpressionBuffer
== NULL
) {
850 return EFI_OUT_OF_RESOURCES
;
853 InitializeListHead (&FormSet
->StorageListHead
);
854 InitializeListHead (&FormSet
->DefaultStoreListHead
);
855 InitializeListHead (&FormSet
->FormListHead
);
858 CurrentStatement
= NULL
;
863 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
864 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
866 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
867 OpCodeOffset
+= OpCodeLength
;
868 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
869 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
872 // If scope bit set, push onto scope stack
878 if (OpCodeDisabled
) {
880 // DisableIf Expression is evaluated to be TRUE, try to find its end.
881 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
883 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
885 } else if (Operand
== EFI_IFR_END_OP
) {
886 Status
= PopScope (&ScopeOpCode
);
887 if (EFI_ERROR (Status
)) {
891 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
892 if (DepthOfDisable
== 0) {
893 InScopeDisable
= FALSE
;
894 OpCodeDisabled
= FALSE
;
903 if (IsExpressionOpCode (Operand
)) {
904 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
905 mExpressionOpCodeIndex
++;
907 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
908 ExpressionOpCode
->Operand
= Operand
;
909 Value
= &ExpressionOpCode
->Value
;
912 case EFI_IFR_EQ_ID_VAL_OP
:
913 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
915 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
916 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
919 case EFI_IFR_EQ_ID_ID_OP
:
920 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
921 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
924 case EFI_IFR_EQ_ID_LIST_OP
:
925 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
926 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
927 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
930 case EFI_IFR_TO_STRING_OP
:
931 case EFI_IFR_FIND_OP
:
932 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
935 case EFI_IFR_STRING_REF1_OP
:
936 Value
->Type
= EFI_IFR_TYPE_STRING
;
937 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
940 case EFI_IFR_RULE_REF_OP
:
941 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
944 case EFI_IFR_SPAN_OP
:
945 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
948 case EFI_IFR_THIS_OP
:
949 ASSERT (CurrentStatement
!= NULL
);
950 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
953 case EFI_IFR_QUESTION_REF1_OP
:
954 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
957 case EFI_IFR_QUESTION_REF3_OP
:
958 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
959 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
961 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
962 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
970 case EFI_IFR_TRUE_OP
:
971 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
972 Value
->Value
.b
= TRUE
;
975 case EFI_IFR_FALSE_OP
:
976 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
977 Value
->Value
.b
= FALSE
;
981 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
985 case EFI_IFR_ZERO_OP
:
986 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
990 case EFI_IFR_ONES_OP
:
991 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
992 Value
->Value
.u64
= 0xffffffffffffffffULL
;
995 case EFI_IFR_UINT8_OP
:
996 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
997 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1000 case EFI_IFR_UINT16_OP
:
1001 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1002 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1005 case EFI_IFR_UINT32_OP
:
1006 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1007 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1010 case EFI_IFR_UINT64_OP
:
1011 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1012 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1015 case EFI_IFR_UNDEFINED_OP
:
1016 Value
->Type
= EFI_IFR_TYPE_OTHER
;
1019 case EFI_IFR_VERSION_OP
:
1020 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1021 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1028 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1030 if (SingleOpCodeExpression
) {
1032 // There are two cases to indicate the end of an Expression:
1033 // for single OpCode expression: one Expression OpCode
1034 // for expression consists of more than one OpCode: EFI_IFR_END
1036 SingleOpCodeExpression
= FALSE
;
1038 if (InScopeDisable
) {
1040 // Evaluate DisableIf expression
1042 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1043 if (EFI_ERROR (Status
)) {
1047 ASSERT (CurrentExpression
!= NULL
);
1048 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1049 return EFI_INVALID_PARAMETER
;
1052 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1055 CurrentExpression
= NULL
;
1066 case EFI_IFR_FORM_SET_OP
:
1068 // check the formset GUID
1070 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1071 return EFI_INVALID_PARAMETER
;
1074 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1075 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1078 case EFI_IFR_FORM_OP
:
1080 // Create a new Form for this FormSet
1082 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1083 ASSERT (CurrentForm
!= NULL
);
1084 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1085 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1086 InitializeListHead (&CurrentForm
->StatementListHead
);
1088 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1089 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1092 // Insert into Form list of this FormSet
1094 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1100 case EFI_IFR_VARSTORE_OP
:
1102 // Create a buffer Storage for this FormSet
1104 Storage
= CreateStorage (FormSet
);
1105 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1107 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1108 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1109 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1111 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1112 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1114 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1115 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1116 ASSERT (Storage
->Name
!= NULL
);
1117 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1118 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1122 // Initialize <ConfigHdr>
1124 InitializeConfigHdr (FormSet
, Storage
);
1127 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1129 // Create a name/value Storage for this FormSet
1131 Storage
= CreateStorage (FormSet
);
1132 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1134 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1135 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1138 // Initialize <ConfigHdr>
1140 InitializeConfigHdr (FormSet
, Storage
);
1143 case EFI_IFR_VARSTORE_EFI_OP
:
1145 // Create a EFI variable Storage for this FormSet
1147 Storage
= CreateStorage (FormSet
);
1148 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1150 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1151 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1152 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1158 case EFI_IFR_DEFAULTSTORE_OP
:
1159 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1160 ASSERT (DefaultStore
!= NULL
);
1161 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1163 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1164 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1167 // Insert to DefaultStore list of this Formset
1169 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1175 case EFI_IFR_SUBTITLE_OP
:
1176 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1177 ASSERT (CurrentStatement
!= NULL
);
1179 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1182 mInScopeSubtitle
= TRUE
;
1186 case EFI_IFR_TEXT_OP
:
1187 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1188 ASSERT (CurrentStatement
!= NULL
);
1190 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1196 case EFI_IFR_ACTION_OP
:
1197 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1198 ASSERT (CurrentStatement
!= NULL
);
1200 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1202 // No QuestionConfig present, so no configuration string will be processed
1204 CurrentStatement
->QuestionConfig
= 0;
1206 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1210 case EFI_IFR_RESET_BUTTON_OP
:
1211 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1213 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1216 case EFI_IFR_REF_OP
:
1217 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1219 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1220 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1221 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1223 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1224 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1226 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1227 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1233 case EFI_IFR_ONE_OF_OP
:
1234 case EFI_IFR_NUMERIC_OP
:
1235 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1237 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1238 Value
= &CurrentStatement
->HiiValue
;
1240 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1241 case EFI_IFR_NUMERIC_SIZE_1
:
1242 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1243 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1244 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1245 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1246 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1249 case EFI_IFR_NUMERIC_SIZE_2
:
1250 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1251 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1252 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1253 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1254 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1257 case EFI_IFR_NUMERIC_SIZE_4
:
1258 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1259 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1260 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1261 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1262 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1265 case EFI_IFR_NUMERIC_SIZE_8
:
1266 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1267 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1268 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1269 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1270 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1277 InitializeRequestElement (FormSet
, CurrentStatement
);
1279 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1280 SuppressForOption
= TRUE
;
1284 case EFI_IFR_ORDERED_LIST_OP
:
1285 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1287 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1288 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1289 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1290 InitializeRequestElement (FormSet
, CurrentStatement
);
1293 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1294 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1295 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1297 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1298 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1301 SuppressForOption
= TRUE
;
1305 case EFI_IFR_CHECKBOX_OP
:
1306 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1308 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1309 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1310 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1312 InitializeRequestElement (FormSet
, CurrentStatement
);
1316 case EFI_IFR_STRING_OP
:
1317 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1320 // MinSize is the minimum number of characters that can be accepted for this opcode,
1321 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1322 // The characters are stored as Unicode, so the storage width should multiply 2.
1324 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1325 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1326 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1327 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1329 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1330 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1332 InitializeRequestElement (FormSet
, CurrentStatement
);
1335 case EFI_IFR_PASSWORD_OP
:
1336 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1339 // MinSize is the minimum number of characters that can be accepted for this opcode,
1340 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1341 // The characters are stored as Unicode, so the storage width should multiply 2.
1343 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1344 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1345 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1347 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1348 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1350 InitializeRequestElement (FormSet
, CurrentStatement
);
1353 case EFI_IFR_DATE_OP
:
1354 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1356 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1357 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1359 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1360 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1362 InitializeRequestElement (FormSet
, CurrentStatement
);
1365 // Don't assign storage for RTC type of date/time
1367 CurrentStatement
->Storage
= NULL
;
1368 CurrentStatement
->StorageWidth
= 0;
1372 case EFI_IFR_TIME_OP
:
1373 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1375 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1376 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1378 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1379 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1381 InitializeRequestElement (FormSet
, CurrentStatement
);
1384 // Don't assign storage for RTC type of date/time
1386 CurrentStatement
->Storage
= NULL
;
1387 CurrentStatement
->StorageWidth
= 0;
1394 case EFI_IFR_DEFAULT_OP
:
1396 // EFI_IFR_DEFAULT appear in scope of a Question,
1397 // It creates a default value for the current question.
1398 // A Question may have more than one Default value which have different default types.
1400 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1401 ASSERT (CurrentDefault
!= NULL
);
1402 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1404 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1405 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1406 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1407 ExtendValueToU64 (&CurrentDefault
->Value
);
1410 // Insert to Default Value list of current Question
1412 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1415 InScopeDefault
= TRUE
;
1422 case EFI_IFR_ONE_OF_OPTION_OP
:
1424 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1425 // It create a selection for use in current Question.
1427 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1428 ASSERT (CurrentOption
!= NULL
);
1429 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1431 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1432 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1433 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1434 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1435 ExtendValueToU64 (&CurrentOption
->Value
);
1437 if (InScopeOptionSuppress
) {
1438 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1442 // Insert to Option list of current Question
1444 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1450 case EFI_IFR_NO_SUBMIT_IF_OP
:
1451 case EFI_IFR_INCONSISTENT_IF_OP
:
1453 // Create an Expression node
1455 CurrentExpression
= CreateExpression (CurrentForm
);
1456 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1458 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1459 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1460 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1462 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1463 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1467 case EFI_IFR_SUPPRESS_IF_OP
:
1469 // Question and Option will appear in scope of this OpCode
1471 CurrentExpression
= CreateExpression (CurrentForm
);
1472 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1473 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1475 if (SuppressForOption
) {
1476 InScopeOptionSuppress
= TRUE
;
1477 OptionSuppressExpression
= CurrentExpression
;
1479 mInScopeSuppress
= TRUE
;
1480 mSuppressExpression
= CurrentExpression
;
1484 case EFI_IFR_GRAY_OUT_IF_OP
:
1486 // Questions will appear in scope of this OpCode
1488 CurrentExpression
= CreateExpression (CurrentForm
);
1489 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1490 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1492 mInScopeGrayOut
= TRUE
;
1493 mGrayOutExpression
= CurrentExpression
;
1496 case EFI_IFR_DISABLE_IF_OP
:
1498 // The DisableIf expression should only rely on constant, so it could be
1499 // evaluated at initialization and it will not be queued
1501 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1502 ASSERT (CurrentExpression
!= NULL
);
1503 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1504 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1505 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1507 InScopeDisable
= TRUE
;
1508 OpCodeDisabled
= FALSE
;
1511 // Take a look at next OpCode to see whether current expression consists
1514 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1515 SingleOpCodeExpression
= TRUE
;
1522 case EFI_IFR_VALUE_OP
:
1523 CurrentExpression
= CreateExpression (CurrentForm
);
1524 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1525 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1527 if (InScopeDefault
) {
1529 // Used for default (EFI_IFR_DEFAULT)
1531 CurrentDefault
->ValueExpression
= CurrentExpression
;
1534 // If used for a question, then the question will be read-only
1537 // Make sure CurrentStatement is not NULL.
1538 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1539 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1541 ASSERT (CurrentStatement
!= NULL
);
1542 CurrentStatement
->ValueExpression
= CurrentExpression
;
1546 case EFI_IFR_RULE_OP
:
1547 CurrentExpression
= CreateExpression (CurrentForm
);
1548 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1550 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1551 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1557 case EFI_IFR_IMAGE_OP
:
1559 // Get ScopeOpcode from top of stack
1561 PopScope (&ScopeOpCode
);
1562 PushScope (ScopeOpCode
);
1564 switch (ScopeOpCode
) {
1565 case EFI_IFR_FORM_SET_OP
:
1566 ImageId
= &FormSet
->ImageId
;
1569 case EFI_IFR_FORM_OP
:
1570 ASSERT (CurrentForm
!= NULL
);
1571 ImageId
= &CurrentForm
->ImageId
;
1574 case EFI_IFR_ONE_OF_OPTION_OP
:
1575 ImageId
= &CurrentOption
->ImageId
;
1580 // Make sure CurrentStatement is not NULL.
1581 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1582 // file is wrongly generated by tools such as VFR Compiler.
1584 ASSERT (CurrentStatement
!= NULL
);
1585 ImageId
= &CurrentStatement
->ImageId
;
1589 ASSERT (ImageId
!= NULL
);
1590 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1596 case EFI_IFR_REFRESH_OP
:
1597 ASSERT (CurrentStatement
!= NULL
);
1598 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1604 case EFI_IFR_GUID_OP
:
1605 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1607 // Tiano specific GUIDed opcodes
1609 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1610 case EFI_IFR_EXTEND_OP_LABEL
:
1612 // just ignore label
1616 case EFI_IFR_EXTEND_OP_BANNER
:
1617 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1619 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1620 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1621 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1622 sizeof (EFI_STRING_ID
)
1627 case EFI_IFR_EXTEND_OP_CLASS
:
1628 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1631 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1632 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1645 case EFI_IFR_END_OP
:
1646 Status
= PopScope (&ScopeOpCode
);
1647 if (EFI_ERROR (Status
)) {
1652 switch (ScopeOpCode
) {
1653 case EFI_IFR_FORM_SET_OP
:
1655 // End of FormSet, update FormSet IFR binary length
1656 // to stop parsing substantial OpCodes
1658 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1661 case EFI_IFR_FORM_OP
:
1668 case EFI_IFR_ONE_OF_OPTION_OP
:
1672 CurrentOption
= NULL
;
1675 case EFI_IFR_SUBTITLE_OP
:
1676 mInScopeSubtitle
= FALSE
;
1679 case EFI_IFR_NO_SUBMIT_IF_OP
:
1680 case EFI_IFR_INCONSISTENT_IF_OP
:
1682 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1686 case EFI_IFR_SUPPRESS_IF_OP
:
1687 if (SuppressForOption
) {
1688 InScopeOptionSuppress
= FALSE
;
1690 mInScopeSuppress
= FALSE
;
1694 case EFI_IFR_GRAY_OUT_IF_OP
:
1695 mInScopeGrayOut
= FALSE
;
1698 case EFI_IFR_DISABLE_IF_OP
:
1699 InScopeDisable
= FALSE
;
1700 OpCodeDisabled
= FALSE
;
1703 case EFI_IFR_ONE_OF_OP
:
1704 case EFI_IFR_ORDERED_LIST_OP
:
1705 SuppressForOption
= FALSE
;
1708 case EFI_IFR_DEFAULT_OP
:
1709 InScopeDefault
= FALSE
;
1713 if (IsExpressionOpCode (ScopeOpCode
)) {
1714 if (InScopeDisable
) {
1716 // Evaluate DisableIf expression
1718 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1719 if (EFI_ERROR (Status
)) {
1723 ASSERT (CurrentExpression
!= NULL
);
1724 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1725 return EFI_INVALID_PARAMETER
;
1728 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1730 // DisableIf Expression is only used once and not quequed, free it
1732 DestroyExpression (CurrentExpression
);
1736 // End of current Expression
1738 CurrentExpression
= NULL
;