2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2008, 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
;
27 EFI_GUID gTianoHiiIfrGuid
= EFI_IFR_TIANO_GUID
;
28 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID mFrameworkHiiCompatibilityGuid
= EFI_IFR_FRAMEWORK_GUID
;
32 Initialize Statement header members.
34 @param OpCodeData Pointer of the raw OpCode data.
35 @param FormSet Pointer of the current FormSe.
36 @param Form Pointer of the current Form.
38 @return The Statement.
41 FORM_BROWSER_STATEMENT
*
44 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
45 IN OUT FORM_BROWSER_FORM
*Form
48 FORM_BROWSER_STATEMENT
*Statement
;
49 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
53 // We are currently not in a Form Scope, so just skip this Statement
58 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
61 InitializeListHead (&Statement
->DefaultListHead
);
62 InitializeListHead (&Statement
->OptionListHead
);
63 InitializeListHead (&Statement
->InconsistentListHead
);
64 InitializeListHead (&Statement
->NoSubmitListHead
);
66 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
68 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
70 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
71 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
72 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
74 if (mInScopeSuppress
) {
75 Statement
->SuppressExpression
= mSuppressExpression
;
78 if (mInScopeGrayOut
) {
79 Statement
->GrayOutExpression
= mGrayOutExpression
;
82 Statement
->InSubtitle
= mInScopeSubtitle
;
85 // Insert this Statement into current Form
87 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
93 UpdateCheckBoxStringToken (
94 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
95 IN FORM_BROWSER_STATEMENT
*Statement
98 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
102 ASSERT (Statement
!= NULL
);
103 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
105 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
107 Status
= HiiLibNewString (FormSet
->HiiHandle
, &Id
, Str
);
109 if (EFI_ERROR (Status
)) {
113 Statement
->VarStoreInfo
.VarName
= Id
;
119 IsNextOpCodeGuidedVarEqName (
126 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
127 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
128 if (CompareGuid (&mFrameworkHiiCompatibilityGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
130 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
132 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
142 Initialize Question's members.
144 @param OpCodeData Pointer of the raw OpCode data.
145 @param FormSet Pointer of the current FormSet.
146 @param Form Pointer of the current Form.
148 @return The Question.
151 FORM_BROWSER_STATEMENT
*
153 IN UINT8
*OpCodeData
,
154 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
155 IN OUT FORM_BROWSER_FORM
*Form
158 FORM_BROWSER_STATEMENT
*Statement
;
159 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
161 FORMSET_STORAGE
*Storage
;
162 NAME_VALUE_NODE
*NameValueNode
;
165 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
166 if (Statement
== NULL
) {
170 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
171 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
172 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
173 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
175 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
177 if (Statement
->VarStoreId
== 0) {
179 // VarStoreId of zero indicates no variable storage
185 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
186 // Framework Compatibility
188 if (FeaturePcdGet (PcdFrameworkHiiCompatibilitySupport
)) {
189 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
190 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
191 if (EFI_ERROR (Status
)) {
198 // Find Storage for this Question
200 Link
= GetFirstNode (&FormSet
->StorageListHead
);
201 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
202 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
204 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
205 Statement
->Storage
= Storage
;
209 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
211 ASSERT (Statement
->Storage
!= NULL
);
214 // Initialilze varname for Name/Value or EFI Variable
216 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
217 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
218 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
219 ASSERT (Statement
->VariableName
!= NULL
);
221 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
223 // Insert to Name/Value varstore list
225 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
226 ASSERT (NameValueNode
!= NULL
);
227 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
228 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
229 ASSERT (NameValueNode
->Name
!= NULL
);
230 NameValueNode
->Value
= AllocateZeroPool (0x10);
231 ASSERT (NameValueNode
->Value
!= NULL
);
232 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
233 ASSERT (NameValueNode
->EditValue
!= NULL
);
235 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
244 Allocate a FORM_EXPRESSION node.
246 @param Form The Form associated with this Expression
248 @return Pointer to a FORM_EXPRESSION data structure.
253 IN OUT FORM_BROWSER_FORM
*Form
256 FORM_EXPRESSION
*Expression
;
258 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
259 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
260 InitializeListHead (&Expression
->OpCodeListHead
);
267 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
269 @param FormSet Pointer of the current FormSet
271 @return Pointer to a FORMSET_STORAGE data structure.
276 IN FORM_BROWSER_FORMSET
*FormSet
279 FORMSET_STORAGE
*Storage
;
281 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
282 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
283 InitializeListHead (&Storage
->NameValueListHead
);
284 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
291 Create ConfigHdr string for a storage.
293 @param FormSet Pointer of the current FormSet
294 @param Storage Pointer of the storage
296 @retval EFI_SUCCESS Initialize ConfigHdr success
300 InitializeConfigHdr (
301 IN FORM_BROWSER_FORMSET
*FormSet
,
302 IN OUT FORMSET_STORAGE
*Storage
309 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
310 Name
= Storage
->Name
;
316 Status
= ConstructConfigHdr (
321 FormSet
->DriverHandle
323 if (Status
== EFI_BUFFER_TOO_SMALL
) {
324 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
325 Status
= ConstructConfigHdr (
330 FormSet
->DriverHandle
334 if (EFI_ERROR (Status
)) {
338 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
339 Storage
->SpareStrLen
= 0;
346 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
348 @param FormSet Pointer of the current FormSet.
349 @param Question The Question to be initialized.
351 @retval EFI_SUCCESS Function success.
352 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
356 InitializeRequestElement (
357 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
358 IN OUT FORM_BROWSER_STATEMENT
*Question
361 FORMSET_STORAGE
*Storage
;
365 CHAR16 RequestElement
[30];
367 Storage
= Question
->Storage
;
368 if (Storage
== NULL
) {
369 return EFI_INVALID_PARAMETER
;
372 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
374 // <ConfigRequest> is unnecessary for EFI variable storage,
375 // GetVariable()/SetVariable() will be used to retrieve/save values
381 // Prepare <RequestElement>
383 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
384 StrLen
= UnicodeSPrint (
386 30 * sizeof (CHAR16
),
387 L
"&OFFSET=%x&WIDTH=%x",
388 Question
->VarStoreInfo
.VarOffset
,
389 Question
->StorageWidth
391 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
393 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
396 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
398 // Password with CALLBACK flag is stored in encoded format,
399 // so don't need to append it to <ConfigRequest>
405 // Append <RequestElement> to <ConfigRequest>
407 if (StrLen
> Storage
->SpareStrLen
) {
409 // Old String buffer is not sufficient for RequestElement, allocate a new one
411 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
412 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
413 if (Storage
->ConfigRequest
!= NULL
) {
414 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
415 gBS
->FreePool (Storage
->ConfigRequest
);
417 Storage
->ConfigRequest
= NewStr
;
418 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
421 StrCat (Storage
->ConfigRequest
, RequestElement
);
422 Storage
->ElementCount
++;
423 Storage
->SpareStrLen
-= StrLen
;
430 Free resources of a Expression.
432 @param FormSet Pointer of the Expression
437 IN FORM_EXPRESSION
*Expression
441 EXPRESSION_OPCODE
*OpCode
;
443 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
444 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
445 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
446 RemoveEntryList (&OpCode
->Link
);
448 if (OpCode
->ValueList
!= NULL
) {
449 FreePool (OpCode
->ValueList
);
454 // Free this Expression
456 gBS
->FreePool (Expression
);
461 Free resources of a storage.
463 @param Storage Pointer of the storage
468 IN FORMSET_STORAGE
*Storage
472 NAME_VALUE_NODE
*NameValueNode
;
474 if (Storage
== NULL
) {
478 if (Storage
->Name
!= NULL
) {
479 FreePool (Storage
->Name
);
481 if (Storage
->Buffer
!= NULL
) {
482 FreePool (Storage
->Buffer
);
484 if (Storage
->EditBuffer
!= NULL
) {
485 FreePool (Storage
->EditBuffer
);
488 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
489 Link
= GetFirstNode (&Storage
->NameValueListHead
);
490 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
491 RemoveEntryList (&NameValueNode
->Link
);
493 if (NameValueNode
->Name
!= NULL
) {
494 FreePool (NameValueNode
->Name
);
496 if (NameValueNode
->Value
!= NULL
) {
497 FreePool (NameValueNode
->Value
);
499 if (NameValueNode
->EditValue
!= NULL
) {
500 FreePool (NameValueNode
->EditValue
);
502 FreePool (NameValueNode
);
505 if (Storage
->ConfigHdr
!= NULL
) {
506 FreePool (Storage
->ConfigHdr
);
508 if (Storage
->ConfigRequest
!= NULL
) {
509 FreePool (Storage
->ConfigRequest
);
517 Free resources of a Statement.
519 @param Statement Pointer of the Statement
524 IN OUT FORM_BROWSER_STATEMENT
*Statement
528 QUESTION_DEFAULT
*Default
;
529 QUESTION_OPTION
*Option
;
530 FORM_EXPRESSION
*Expression
;
533 // Free Default value List
535 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
536 Link
= GetFirstNode (&Statement
->DefaultListHead
);
537 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
538 RemoveEntryList (&Default
->Link
);
540 gBS
->FreePool (Default
);
546 while (!IsListEmpty (&Statement
->OptionListHead
)) {
547 Link
= GetFirstNode (&Statement
->OptionListHead
);
548 Option
= QUESTION_OPTION_FROM_LINK (Link
);
549 RemoveEntryList (&Option
->Link
);
551 gBS
->FreePool (Option
);
555 // Free Inconsistent List
557 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
558 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
559 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
560 RemoveEntryList (&Expression
->Link
);
562 DestroyExpression (Expression
);
566 // Free NoSubmit List
568 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
569 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
570 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
571 RemoveEntryList (&Expression
->Link
);
573 DestroyExpression (Expression
);
576 if (Statement
->VariableName
!= NULL
) {
577 FreePool (Statement
->VariableName
);
579 if (Statement
->BlockName
!= NULL
) {
580 FreePool (Statement
->BlockName
);
586 Free resources of a Form.
588 @param Form Pointer of the Form.
593 IN OUT FORM_BROWSER_FORM
*Form
597 FORM_EXPRESSION
*Expression
;
598 FORM_BROWSER_STATEMENT
*Statement
;
601 // Free Form Expressions
603 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
604 Link
= GetFirstNode (&Form
->ExpressionListHead
);
605 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
606 RemoveEntryList (&Expression
->Link
);
608 DestroyExpression (Expression
);
612 // Free Statements/Questions
614 while (!IsListEmpty (&Form
->StatementListHead
)) {
615 Link
= GetFirstNode (&Form
->StatementListHead
);
616 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
617 RemoveEntryList (&Statement
->Link
);
619 DestroyStatement (Statement
);
625 gBS
->FreePool (Form
);
630 Free resources allocated for a FormSet.
632 @param FormSet Pointer of the FormSet
637 IN OUT FORM_BROWSER_FORMSET
*FormSet
641 FORMSET_STORAGE
*Storage
;
642 FORMSET_DEFAULTSTORE
*DefaultStore
;
643 FORM_BROWSER_FORM
*Form
;
646 // Free IFR binary buffer
648 FreePool (FormSet
->IfrBinaryData
);
651 // Free FormSet Storage
653 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
654 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
655 Link
= GetFirstNode (&FormSet
->StorageListHead
);
656 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
657 RemoveEntryList (&Storage
->Link
);
659 DestroyStorage (Storage
);
664 // Free FormSet Default Store
666 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
667 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
668 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
669 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
670 RemoveEntryList (&DefaultStore
->Link
);
672 gBS
->FreePool (DefaultStore
);
679 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
680 while (!IsListEmpty (&FormSet
->FormListHead
)) {
681 Link
= GetFirstNode (&FormSet
->FormListHead
);
682 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
683 RemoveEntryList (&Form
->Link
);
689 if (FormSet
->StatementBuffer
!= NULL
) {
690 FreePool (FormSet
->StatementBuffer
);
692 if (FormSet
->ExpressionBuffer
!= NULL
) {
693 FreePool (FormSet
->ExpressionBuffer
);
701 Tell whether this Operand is an Expression OpCode or not
703 @param Operand Operand of an IFR OpCode.
705 @retval TRUE This is an Expression OpCode.
706 @retval FALSE Not an Expression OpCode.
714 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
715 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
716 (Operand
== EFI_IFR_CATENATE_OP
) ||
717 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
718 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
719 (Operand
== EFI_IFR_VERSION_OP
)
729 Calculate number of Statemens(Questions) and Expression OpCodes.
731 @param FormSet The FormSet to be counted.
732 @param NumberOfStatement Number of Statemens(Questions)
733 @param NumberOfExpression Number of Expression OpCodes
738 IN FORM_BROWSER_FORMSET
*FormSet
,
739 IN OUT UINT16
*NumberOfStatement
,
740 IN OUT UINT16
*NumberOfExpression
743 UINT16 StatementCount
;
744 UINT16 ExpressionCount
;
753 while (Offset
< FormSet
->IfrBinaryLength
) {
754 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
755 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
758 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
765 *NumberOfStatement
= StatementCount
;
766 *NumberOfExpression
= ExpressionCount
;
772 Parse opcodes in the formset IFR binary.
774 @param FormSet Pointer of the FormSet data structure.
776 @retval EFI_SUCCESS Opcode parse success.
777 @retval Other Opcode parse fail.
782 IN FORM_BROWSER_FORMSET
*FormSet
787 FORM_BROWSER_FORM
*CurrentForm
;
788 FORM_BROWSER_STATEMENT
*CurrentStatement
;
789 EXPRESSION_OPCODE
*ExpressionOpCode
;
790 FORM_EXPRESSION
*CurrentExpression
;
797 FORMSET_STORAGE
*Storage
;
798 FORMSET_DEFAULTSTORE
*DefaultStore
;
799 QUESTION_DEFAULT
*CurrentDefault
;
800 QUESTION_OPTION
*CurrentOption
;
802 UINT16 NumberOfStatement
;
803 UINT16 NumberOfExpression
;
804 EFI_IMAGE_ID
*ImageId
;
805 BOOLEAN SuppressForOption
;
806 BOOLEAN InScopeOptionSuppress
;
807 FORM_EXPRESSION
*OptionSuppressExpression
;
808 BOOLEAN InScopeDisable
;
809 UINT16 DepthOfDisable
;
810 BOOLEAN OpCodeDisabled
;
811 BOOLEAN SingleOpCodeExpression
;
812 BOOLEAN InScopeDefault
;
813 EFI_HII_VALUE
*Value
;
815 mInScopeSubtitle
= FALSE
;
816 SuppressForOption
= FALSE
;
817 mInScopeSuppress
= FALSE
;
818 InScopeOptionSuppress
= FALSE
;
819 mInScopeGrayOut
= FALSE
;
820 InScopeDisable
= FALSE
;
822 OpCodeDisabled
= FALSE
;
823 SingleOpCodeExpression
= FALSE
;
824 InScopeDefault
= FALSE
;
825 CurrentExpression
= NULL
;
826 CurrentDefault
= NULL
;
827 CurrentOption
= NULL
;
828 OptionSuppressExpression
= NULL
;
831 // Get the number of Statements and Expressions
833 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
836 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
837 if (FormSet
->StatementBuffer
== NULL
) {
838 return EFI_OUT_OF_RESOURCES
;
841 mExpressionOpCodeIndex
= 0;
842 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
843 if (FormSet
->ExpressionBuffer
== NULL
) {
844 return EFI_OUT_OF_RESOURCES
;
847 InitializeListHead (&FormSet
->StorageListHead
);
848 InitializeListHead (&FormSet
->DefaultStoreListHead
);
849 InitializeListHead (&FormSet
->FormListHead
);
852 CurrentStatement
= NULL
;
857 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
858 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
860 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
861 OpCodeOffset
+= OpCodeLength
;
862 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
863 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
866 // If scope bit set, push onto scope stack
872 if (OpCodeDisabled
) {
874 // DisableIf Expression is evaluated to be TRUE, try to find its end.
875 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
877 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
879 } else if (Operand
== EFI_IFR_END_OP
) {
880 Status
= PopScope (&ScopeOpCode
);
881 if (EFI_ERROR (Status
)) {
885 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
886 if (DepthOfDisable
== 0) {
887 InScopeDisable
= FALSE
;
888 OpCodeDisabled
= FALSE
;
897 if (IsExpressionOpCode (Operand
)) {
898 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
899 mExpressionOpCodeIndex
++;
901 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
902 ExpressionOpCode
->Operand
= Operand
;
903 Value
= &ExpressionOpCode
->Value
;
906 case EFI_IFR_EQ_ID_VAL_OP
:
907 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
909 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
910 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
913 case EFI_IFR_EQ_ID_ID_OP
:
914 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
915 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
918 case EFI_IFR_EQ_ID_LIST_OP
:
919 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
920 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
921 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
924 case EFI_IFR_TO_STRING_OP
:
925 case EFI_IFR_FIND_OP
:
926 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
929 case EFI_IFR_STRING_REF1_OP
:
930 Value
->Type
= EFI_IFR_TYPE_STRING
;
931 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
934 case EFI_IFR_RULE_REF_OP
:
935 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
938 case EFI_IFR_SPAN_OP
:
939 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
942 case EFI_IFR_THIS_OP
:
943 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
946 case EFI_IFR_QUESTION_REF1_OP
:
947 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
950 case EFI_IFR_QUESTION_REF3_OP
:
951 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
952 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
954 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
955 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
963 case EFI_IFR_TRUE_OP
:
964 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
965 Value
->Value
.b
= TRUE
;
968 case EFI_IFR_FALSE_OP
:
969 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
970 Value
->Value
.b
= FALSE
;
974 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
978 case EFI_IFR_ZERO_OP
:
979 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
983 case EFI_IFR_ONES_OP
:
984 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
985 Value
->Value
.u64
= 0xffffffffffffffffULL
;
988 case EFI_IFR_UINT8_OP
:
989 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
990 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
993 case EFI_IFR_UINT16_OP
:
994 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
995 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
998 case EFI_IFR_UINT32_OP
:
999 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1000 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1003 case EFI_IFR_UINT64_OP
:
1004 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1005 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1008 case EFI_IFR_UNDEFINED_OP
:
1009 Value
->Type
= EFI_IFR_TYPE_OTHER
;
1012 case EFI_IFR_VERSION_OP
:
1013 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1014 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1021 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1023 if (SingleOpCodeExpression
) {
1025 // There are two cases to indicate the end of an Expression:
1026 // for single OpCode expression: one Expression OpCode
1027 // for expression consists of more than one OpCode: EFI_IFR_END
1029 SingleOpCodeExpression
= FALSE
;
1031 if (InScopeDisable
) {
1033 // Evaluate DisableIf expression
1035 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1036 if (EFI_ERROR (Status
)) {
1039 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1040 return EFI_INVALID_PARAMETER
;
1043 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1046 CurrentExpression
= NULL
;
1057 case EFI_IFR_FORM_SET_OP
:
1059 // check the formset GUID
1061 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1062 return EFI_INVALID_PARAMETER
;
1065 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1066 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1069 case EFI_IFR_FORM_OP
:
1071 // Create a new Form for this FormSet
1073 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1074 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1075 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1076 InitializeListHead (&CurrentForm
->StatementListHead
);
1078 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1079 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1082 // Insert into Form list of this FormSet
1084 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1090 case EFI_IFR_VARSTORE_OP
:
1092 // Create a buffer Storage for this FormSet
1094 Storage
= CreateStorage (FormSet
);
1095 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1097 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1098 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1099 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1101 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1102 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1104 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1105 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1106 ASSERT (Storage
->Name
!= NULL
);
1107 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1108 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1112 // Initialize <ConfigHdr>
1114 InitializeConfigHdr (FormSet
, Storage
);
1117 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1119 // Create a name/value Storage for this FormSet
1121 Storage
= CreateStorage (FormSet
);
1122 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1124 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1125 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1128 // Initialize <ConfigHdr>
1130 InitializeConfigHdr (FormSet
, Storage
);
1133 case EFI_IFR_VARSTORE_EFI_OP
:
1135 // Create a EFI variable Storage for this FormSet
1137 Storage
= CreateStorage (FormSet
);
1138 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1140 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1141 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1142 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1148 case EFI_IFR_DEFAULTSTORE_OP
:
1149 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1150 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1152 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1153 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1156 // Insert to DefaultStore list of this Formset
1158 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1164 case EFI_IFR_SUBTITLE_OP
:
1165 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1166 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1169 mInScopeSubtitle
= TRUE
;
1173 case EFI_IFR_TEXT_OP
:
1174 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1176 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1182 case EFI_IFR_ACTION_OP
:
1183 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1185 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1187 // No QuestionConfig present, so no configuration string will be processed
1189 CurrentStatement
->QuestionConfig
= 0;
1191 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1195 case EFI_IFR_RESET_BUTTON_OP
:
1196 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1198 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1201 case EFI_IFR_REF_OP
:
1202 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1204 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1205 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1206 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1208 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1209 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1211 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1212 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1218 case EFI_IFR_ONE_OF_OP
:
1219 case EFI_IFR_NUMERIC_OP
:
1220 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1222 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1223 Value
= &CurrentStatement
->HiiValue
;
1225 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1226 case EFI_IFR_NUMERIC_SIZE_1
:
1227 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1228 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1229 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1230 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1231 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1234 case EFI_IFR_NUMERIC_SIZE_2
:
1235 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1236 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1237 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1238 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1239 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1242 case EFI_IFR_NUMERIC_SIZE_4
:
1243 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1244 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1245 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1246 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1247 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1250 case EFI_IFR_NUMERIC_SIZE_8
:
1251 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1252 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1253 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1254 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1255 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1262 InitializeRequestElement (FormSet
, CurrentStatement
);
1264 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1265 SuppressForOption
= TRUE
;
1269 case EFI_IFR_ORDERED_LIST_OP
:
1270 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1272 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1273 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1274 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1275 InitializeRequestElement (FormSet
, CurrentStatement
);
1278 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1279 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1280 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1282 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1283 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1286 SuppressForOption
= TRUE
;
1290 case EFI_IFR_CHECKBOX_OP
:
1291 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1293 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1294 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1295 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1297 InitializeRequestElement (FormSet
, CurrentStatement
);
1301 case EFI_IFR_STRING_OP
:
1302 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1305 // MinSize is the minimum number of characters that can be accepted for this opcode,
1306 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1307 // The characters are stored as Unicode, so the storage width should multiply 2.
1309 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1310 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1311 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1312 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1314 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1315 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1317 InitializeRequestElement (FormSet
, CurrentStatement
);
1320 case EFI_IFR_PASSWORD_OP
:
1321 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1324 // MinSize is the minimum number of characters that can be accepted for this opcode,
1325 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1326 // The characters are stored as Unicode, so the storage width should multiply 2.
1328 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1329 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1330 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1332 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1333 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1335 InitializeRequestElement (FormSet
, CurrentStatement
);
1338 case EFI_IFR_DATE_OP
:
1339 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1341 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1342 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1344 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1345 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1347 InitializeRequestElement (FormSet
, CurrentStatement
);
1350 // Don't assign storage for RTC type of date/time
1352 CurrentStatement
->Storage
= NULL
;
1353 CurrentStatement
->StorageWidth
= 0;
1357 case EFI_IFR_TIME_OP
:
1358 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1360 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1361 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1363 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1364 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1366 InitializeRequestElement (FormSet
, CurrentStatement
);
1369 // Don't assign storage for RTC type of date/time
1371 CurrentStatement
->Storage
= NULL
;
1372 CurrentStatement
->StorageWidth
= 0;
1379 case EFI_IFR_DEFAULT_OP
:
1381 // EFI_IFR_DEFAULT appear in scope of a Question,
1382 // It creates a default value for the current question.
1383 // A Question may have more than one Default value which have different default types.
1385 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1386 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1388 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1389 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1390 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1391 ExtendValueToU64 (&CurrentDefault
->Value
);
1394 // Insert to Default Value list of current Question
1396 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1399 InScopeDefault
= TRUE
;
1406 case EFI_IFR_ONE_OF_OPTION_OP
:
1408 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1409 // It create a selection for use in current Question.
1411 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1412 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1414 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1415 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1416 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1417 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1418 ExtendValueToU64 (&CurrentOption
->Value
);
1420 if (InScopeOptionSuppress
) {
1421 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1425 // Insert to Option list of current Question
1427 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1433 case EFI_IFR_NO_SUBMIT_IF_OP
:
1434 case EFI_IFR_INCONSISTENT_IF_OP
:
1436 // Create an Expression node
1438 CurrentExpression
= CreateExpression (CurrentForm
);
1439 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1441 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1442 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1443 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1445 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1446 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1450 case EFI_IFR_SUPPRESS_IF_OP
:
1452 // Question and Option will appear in scope of this OpCode
1454 CurrentExpression
= CreateExpression (CurrentForm
);
1455 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1456 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1458 if (SuppressForOption
) {
1459 InScopeOptionSuppress
= TRUE
;
1460 OptionSuppressExpression
= CurrentExpression
;
1462 mInScopeSuppress
= TRUE
;
1463 mSuppressExpression
= CurrentExpression
;
1467 case EFI_IFR_GRAY_OUT_IF_OP
:
1469 // Questions will appear in scope of this OpCode
1471 CurrentExpression
= CreateExpression (CurrentForm
);
1472 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1473 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1475 mInScopeGrayOut
= TRUE
;
1476 mGrayOutExpression
= CurrentExpression
;
1479 case EFI_IFR_DISABLE_IF_OP
:
1481 // The DisableIf expression should only rely on constant, so it could be
1482 // evaluated at initialization and it will not be queued
1484 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1485 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1486 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1487 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1489 InScopeDisable
= TRUE
;
1490 OpCodeDisabled
= FALSE
;
1493 // Take a look at next OpCode to see whether current expression consists
1496 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1497 SingleOpCodeExpression
= TRUE
;
1504 case EFI_IFR_VALUE_OP
:
1505 CurrentExpression
= CreateExpression (CurrentForm
);
1506 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1507 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1509 if (InScopeDefault
) {
1511 // Used for default (EFI_IFR_DEFAULT)
1513 CurrentDefault
->ValueExpression
= CurrentExpression
;
1516 // If used for a question, then the question will be read-only
1518 CurrentStatement
->ValueExpression
= CurrentExpression
;
1522 case EFI_IFR_RULE_OP
:
1523 CurrentExpression
= CreateExpression (CurrentForm
);
1524 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1526 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1527 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1533 case EFI_IFR_IMAGE_OP
:
1535 // Get ScopeOpcode from top of stack
1537 PopScope (&ScopeOpCode
);
1538 PushScope (ScopeOpCode
);
1540 switch (ScopeOpCode
) {
1541 case EFI_IFR_FORM_SET_OP
:
1542 ImageId
= &FormSet
->ImageId
;
1545 case EFI_IFR_FORM_OP
:
1546 ImageId
= &CurrentForm
->ImageId
;
1549 case EFI_IFR_ONE_OF_OPTION_OP
:
1550 ImageId
= &CurrentOption
->ImageId
;
1554 ImageId
= &CurrentStatement
->ImageId
;
1558 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1564 case EFI_IFR_REFRESH_OP
:
1565 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1571 case EFI_IFR_GUID_OP
:
1572 if (CompareGuid (&gTianoHiiIfrGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1574 // Tiano specific GUIDed opcodes
1576 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1577 case EFI_IFR_EXTEND_OP_LABEL
:
1579 // just ignore label
1583 case EFI_IFR_EXTEND_OP_BANNER
:
1584 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1586 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1587 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1588 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1589 sizeof (EFI_STRING_ID
)
1594 case EFI_IFR_EXTEND_OP_CLASS
:
1595 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1598 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1599 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1612 case EFI_IFR_END_OP
:
1613 Status
= PopScope (&ScopeOpCode
);
1614 if (EFI_ERROR (Status
)) {
1619 switch (ScopeOpCode
) {
1620 case EFI_IFR_FORM_SET_OP
:
1622 // End of FormSet, update FormSet IFR binary length
1623 // to stop parsing substantial OpCodes
1625 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1628 case EFI_IFR_FORM_OP
:
1635 case EFI_IFR_ONE_OF_OPTION_OP
:
1639 CurrentOption
= NULL
;
1642 case EFI_IFR_SUBTITLE_OP
:
1643 mInScopeSubtitle
= FALSE
;
1646 case EFI_IFR_NO_SUBMIT_IF_OP
:
1647 case EFI_IFR_INCONSISTENT_IF_OP
:
1649 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1653 case EFI_IFR_SUPPRESS_IF_OP
:
1654 if (SuppressForOption
) {
1655 InScopeOptionSuppress
= FALSE
;
1657 mInScopeSuppress
= FALSE
;
1661 case EFI_IFR_GRAY_OUT_IF_OP
:
1662 mInScopeGrayOut
= FALSE
;
1665 case EFI_IFR_DISABLE_IF_OP
:
1666 InScopeDisable
= FALSE
;
1667 OpCodeDisabled
= FALSE
;
1670 case EFI_IFR_ONE_OF_OP
:
1671 case EFI_IFR_ORDERED_LIST_OP
:
1672 SuppressForOption
= FALSE
;
1675 case EFI_IFR_DEFAULT_OP
:
1676 InScopeDefault
= FALSE
;
1680 if (IsExpressionOpCode (ScopeOpCode
)) {
1681 if (InScopeDisable
) {
1683 // Evaluate DisableIf expression
1685 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1686 if (EFI_ERROR (Status
)) {
1689 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1690 return EFI_INVALID_PARAMETER
;
1693 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1695 // DisableIf Expression is only used once and not quequed, free it
1697 DestroyExpression (CurrentExpression
);
1701 // End of current Expression
1703 CurrentExpression
= NULL
;