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
];
113 ASSERT (Statement
!= NULL
);
114 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
116 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
118 Status
= HiiLibNewString (FormSet
->HiiHandle
, &Id
, Str
);
120 if (EFI_ERROR (Status
)) {
124 Statement
->VarStoreInfo
.VarName
= Id
;
130 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
132 @param OpCodeData The current opcode.
138 IsNextOpCodeGuidedVarEqName (
145 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
146 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
147 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
149 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
151 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
161 Initialize Question's members.
163 @param OpCodeData Pointer of the raw OpCode data.
164 @param FormSet Pointer of the current FormSet.
165 @param Form Pointer of the current Form.
167 @return The Question.
170 FORM_BROWSER_STATEMENT
*
172 IN UINT8
*OpCodeData
,
173 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
174 IN OUT FORM_BROWSER_FORM
*Form
177 FORM_BROWSER_STATEMENT
*Statement
;
178 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
180 FORMSET_STORAGE
*Storage
;
181 NAME_VALUE_NODE
*NameValueNode
;
184 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
185 if (Statement
== NULL
) {
189 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
190 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
191 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
192 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
194 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
196 if (Statement
->VarStoreId
== 0) {
198 // VarStoreId of zero indicates no variable storage
204 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
205 // Framework Compatibility
207 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
208 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
209 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
210 if (EFI_ERROR (Status
)) {
217 // Find Storage for this Question
219 Link
= GetFirstNode (&FormSet
->StorageListHead
);
220 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
221 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
223 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
224 Statement
->Storage
= Storage
;
228 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
230 ASSERT (Statement
->Storage
!= NULL
);
233 // Initialilze varname for Name/Value or EFI Variable
235 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
236 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
237 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
238 ASSERT (Statement
->VariableName
!= NULL
);
240 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
242 // Insert to Name/Value varstore list
244 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
245 ASSERT (NameValueNode
!= NULL
);
246 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
247 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
248 ASSERT (NameValueNode
->Name
!= NULL
);
249 NameValueNode
->Value
= AllocateZeroPool (0x10);
250 ASSERT (NameValueNode
->Value
!= NULL
);
251 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
252 ASSERT (NameValueNode
->EditValue
!= NULL
);
254 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
263 Allocate a FORM_EXPRESSION node.
265 @param Form The Form associated with this Expression
267 @return Pointer to a FORM_EXPRESSION data structure.
272 IN OUT FORM_BROWSER_FORM
*Form
275 FORM_EXPRESSION
*Expression
;
277 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
278 ASSERT (Expression
!= NULL
);
279 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
280 InitializeListHead (&Expression
->OpCodeListHead
);
287 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
289 @param FormSet Pointer of the current FormSet
291 @return Pointer to a FORMSET_STORAGE data structure.
296 IN FORM_BROWSER_FORMSET
*FormSet
299 FORMSET_STORAGE
*Storage
;
301 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
302 ASSERT (Storage
!= NULL
);
303 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
304 InitializeListHead (&Storage
->NameValueListHead
);
305 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
312 Create ConfigHdr string for a storage.
314 @param FormSet Pointer of the current FormSet
315 @param Storage Pointer of the storage
317 @retval EFI_SUCCESS Initialize ConfigHdr success
321 InitializeConfigHdr (
322 IN FORM_BROWSER_FORMSET
*FormSet
,
323 IN OUT FORMSET_STORAGE
*Storage
330 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
331 Name
= Storage
->Name
;
337 Status
= ConstructConfigHdr (
342 FormSet
->DriverHandle
344 if (Status
== EFI_BUFFER_TOO_SMALL
) {
345 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
346 Status
= ConstructConfigHdr (
351 FormSet
->DriverHandle
355 if (EFI_ERROR (Status
)) {
359 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
360 Storage
->SpareStrLen
= 0;
367 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
369 @param FormSet Pointer of the current FormSet.
370 @param Question The Question to be initialized.
372 @retval EFI_SUCCESS Function success.
373 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
377 InitializeRequestElement (
378 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
379 IN OUT FORM_BROWSER_STATEMENT
*Question
382 FORMSET_STORAGE
*Storage
;
386 CHAR16 RequestElement
[30];
388 Storage
= Question
->Storage
;
389 if (Storage
== NULL
) {
390 return EFI_INVALID_PARAMETER
;
393 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
395 // <ConfigRequest> is unnecessary for EFI variable storage,
396 // GetVariable()/SetVariable() will be used to retrieve/save values
402 // Prepare <RequestElement>
404 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
405 StrLen
= UnicodeSPrint (
407 30 * sizeof (CHAR16
),
408 L
"&OFFSET=%x&WIDTH=%x",
409 Question
->VarStoreInfo
.VarOffset
,
410 Question
->StorageWidth
412 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
414 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
417 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
419 // Password with CALLBACK flag is stored in encoded format,
420 // so don't need to append it to <ConfigRequest>
426 // Append <RequestElement> to <ConfigRequest>
428 if (StrLen
> Storage
->SpareStrLen
) {
430 // Old String buffer is not sufficient for RequestElement, allocate a new one
432 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
433 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
434 ASSERT (NewStr
!= NULL
);
435 if (Storage
->ConfigRequest
!= NULL
) {
436 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
437 FreePool (Storage
->ConfigRequest
);
439 Storage
->ConfigRequest
= NewStr
;
440 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
443 StrCat (Storage
->ConfigRequest
, RequestElement
);
444 Storage
->ElementCount
++;
445 Storage
->SpareStrLen
-= StrLen
;
452 Free resources of a Expression.
454 @param FormSet Pointer of the Expression
459 IN FORM_EXPRESSION
*Expression
463 EXPRESSION_OPCODE
*OpCode
;
465 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
466 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
467 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
468 RemoveEntryList (&OpCode
->Link
);
470 if (OpCode
->ValueList
!= NULL
) {
471 FreePool (OpCode
->ValueList
);
476 // Free this Expression
478 FreePool (Expression
);
483 Free resources of a storage.
485 @param Storage Pointer of the storage
490 IN FORMSET_STORAGE
*Storage
494 NAME_VALUE_NODE
*NameValueNode
;
496 if (Storage
== NULL
) {
500 if (Storage
->Name
!= NULL
) {
501 FreePool (Storage
->Name
);
503 if (Storage
->Buffer
!= NULL
) {
504 FreePool (Storage
->Buffer
);
506 if (Storage
->EditBuffer
!= NULL
) {
507 FreePool (Storage
->EditBuffer
);
510 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
511 Link
= GetFirstNode (&Storage
->NameValueListHead
);
512 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
513 RemoveEntryList (&NameValueNode
->Link
);
515 if (NameValueNode
->Name
!= NULL
) {
516 FreePool (NameValueNode
->Name
);
518 if (NameValueNode
->Value
!= NULL
) {
519 FreePool (NameValueNode
->Value
);
521 if (NameValueNode
->EditValue
!= NULL
) {
522 FreePool (NameValueNode
->EditValue
);
524 FreePool (NameValueNode
);
527 if (Storage
->ConfigHdr
!= NULL
) {
528 FreePool (Storage
->ConfigHdr
);
530 if (Storage
->ConfigRequest
!= NULL
) {
531 FreePool (Storage
->ConfigRequest
);
539 Free resources of a Statement.
541 @param Statement Pointer of the Statement
546 IN OUT FORM_BROWSER_STATEMENT
*Statement
550 QUESTION_DEFAULT
*Default
;
551 QUESTION_OPTION
*Option
;
552 FORM_EXPRESSION
*Expression
;
555 // Free Default value List
557 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
558 Link
= GetFirstNode (&Statement
->DefaultListHead
);
559 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
560 RemoveEntryList (&Default
->Link
);
568 while (!IsListEmpty (&Statement
->OptionListHead
)) {
569 Link
= GetFirstNode (&Statement
->OptionListHead
);
570 Option
= QUESTION_OPTION_FROM_LINK (Link
);
571 RemoveEntryList (&Option
->Link
);
577 // Free Inconsistent List
579 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
580 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
581 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
582 RemoveEntryList (&Expression
->Link
);
584 DestroyExpression (Expression
);
588 // Free NoSubmit List
590 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
591 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
592 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
593 RemoveEntryList (&Expression
->Link
);
595 DestroyExpression (Expression
);
598 if (Statement
->VariableName
!= NULL
) {
599 FreePool (Statement
->VariableName
);
601 if (Statement
->BlockName
!= NULL
) {
602 FreePool (Statement
->BlockName
);
608 Free resources of a Form.
610 @param Form Pointer of the Form.
615 IN OUT FORM_BROWSER_FORM
*Form
619 FORM_EXPRESSION
*Expression
;
620 FORM_BROWSER_STATEMENT
*Statement
;
623 // Free Form Expressions
625 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
626 Link
= GetFirstNode (&Form
->ExpressionListHead
);
627 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
628 RemoveEntryList (&Expression
->Link
);
630 DestroyExpression (Expression
);
634 // Free Statements/Questions
636 while (!IsListEmpty (&Form
->StatementListHead
)) {
637 Link
= GetFirstNode (&Form
->StatementListHead
);
638 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
639 RemoveEntryList (&Statement
->Link
);
641 DestroyStatement (Statement
);
652 Free resources allocated for a FormSet.
654 @param FormSet Pointer of the FormSet
659 IN OUT FORM_BROWSER_FORMSET
*FormSet
663 FORMSET_STORAGE
*Storage
;
664 FORMSET_DEFAULTSTORE
*DefaultStore
;
665 FORM_BROWSER_FORM
*Form
;
668 // Free IFR binary buffer
670 FreePool (FormSet
->IfrBinaryData
);
673 // Free FormSet Storage
675 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
676 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
677 Link
= GetFirstNode (&FormSet
->StorageListHead
);
678 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
679 RemoveEntryList (&Storage
->Link
);
681 DestroyStorage (Storage
);
686 // Free FormSet Default Store
688 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
689 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
690 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
691 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
692 RemoveEntryList (&DefaultStore
->Link
);
694 FreePool (DefaultStore
);
701 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
702 while (!IsListEmpty (&FormSet
->FormListHead
)) {
703 Link
= GetFirstNode (&FormSet
->FormListHead
);
704 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
705 RemoveEntryList (&Form
->Link
);
711 if (FormSet
->StatementBuffer
!= NULL
) {
712 FreePool (FormSet
->StatementBuffer
);
714 if (FormSet
->ExpressionBuffer
!= NULL
) {
715 FreePool (FormSet
->ExpressionBuffer
);
723 Tell whether this Operand is an Expression OpCode or not
725 @param Operand Operand of an IFR OpCode.
727 @retval TRUE This is an Expression OpCode.
728 @retval FALSE Not an Expression OpCode.
736 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
737 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
738 (Operand
== EFI_IFR_CATENATE_OP
) ||
739 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
740 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
741 (Operand
== EFI_IFR_VERSION_OP
)
751 Calculate number of Statemens(Questions) and Expression OpCodes.
753 @param FormSet The FormSet to be counted.
754 @param NumberOfStatement Number of Statemens(Questions)
755 @param NumberOfExpression Number of Expression OpCodes
760 IN FORM_BROWSER_FORMSET
*FormSet
,
761 IN OUT UINT16
*NumberOfStatement
,
762 IN OUT UINT16
*NumberOfExpression
765 UINT16 StatementCount
;
766 UINT16 ExpressionCount
;
775 while (Offset
< FormSet
->IfrBinaryLength
) {
776 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
777 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
780 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
787 *NumberOfStatement
= StatementCount
;
788 *NumberOfExpression
= ExpressionCount
;
794 Parse opcodes in the formset IFR binary.
796 @param FormSet Pointer of the FormSet data structure.
798 @retval EFI_SUCCESS Opcode parse success.
799 @retval Other Opcode parse fail.
804 IN FORM_BROWSER_FORMSET
*FormSet
809 FORM_BROWSER_FORM
*CurrentForm
;
810 FORM_BROWSER_STATEMENT
*CurrentStatement
;
811 EXPRESSION_OPCODE
*ExpressionOpCode
;
812 FORM_EXPRESSION
*CurrentExpression
;
819 FORMSET_STORAGE
*Storage
;
820 FORMSET_DEFAULTSTORE
*DefaultStore
;
821 QUESTION_DEFAULT
*CurrentDefault
;
822 QUESTION_OPTION
*CurrentOption
;
824 UINT16 NumberOfStatement
;
825 UINT16 NumberOfExpression
;
826 EFI_IMAGE_ID
*ImageId
;
827 BOOLEAN SuppressForOption
;
828 BOOLEAN InScopeOptionSuppress
;
829 FORM_EXPRESSION
*OptionSuppressExpression
;
830 BOOLEAN InScopeDisable
;
831 UINT16 DepthOfDisable
;
832 BOOLEAN OpCodeDisabled
;
833 BOOLEAN SingleOpCodeExpression
;
834 BOOLEAN InScopeDefault
;
835 EFI_HII_VALUE
*Value
;
837 mInScopeSubtitle
= FALSE
;
838 SuppressForOption
= FALSE
;
839 mInScopeSuppress
= FALSE
;
840 InScopeOptionSuppress
= FALSE
;
841 mInScopeGrayOut
= FALSE
;
842 InScopeDisable
= FALSE
;
844 OpCodeDisabled
= FALSE
;
845 SingleOpCodeExpression
= FALSE
;
846 InScopeDefault
= FALSE
;
847 CurrentExpression
= NULL
;
848 CurrentDefault
= NULL
;
849 CurrentOption
= NULL
;
850 OptionSuppressExpression
= NULL
;
854 // Get the number of Statements and Expressions
856 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
859 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
860 if (FormSet
->StatementBuffer
== NULL
) {
861 return EFI_OUT_OF_RESOURCES
;
864 mExpressionOpCodeIndex
= 0;
865 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
866 if (FormSet
->ExpressionBuffer
== NULL
) {
867 return EFI_OUT_OF_RESOURCES
;
870 InitializeListHead (&FormSet
->StorageListHead
);
871 InitializeListHead (&FormSet
->DefaultStoreListHead
);
872 InitializeListHead (&FormSet
->FormListHead
);
875 CurrentStatement
= NULL
;
880 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
881 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
883 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
884 OpCodeOffset
+= OpCodeLength
;
885 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
886 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
889 // If scope bit set, push onto scope stack
895 if (OpCodeDisabled
) {
897 // DisableIf Expression is evaluated to be TRUE, try to find its end.
898 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
900 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
902 } else if (Operand
== EFI_IFR_END_OP
) {
903 Status
= PopScope (&ScopeOpCode
);
904 if (EFI_ERROR (Status
)) {
908 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
909 if (DepthOfDisable
== 0) {
910 InScopeDisable
= FALSE
;
911 OpCodeDisabled
= FALSE
;
920 if (IsExpressionOpCode (Operand
)) {
921 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
922 mExpressionOpCodeIndex
++;
924 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
925 ExpressionOpCode
->Operand
= Operand
;
926 Value
= &ExpressionOpCode
->Value
;
929 case EFI_IFR_EQ_ID_VAL_OP
:
930 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
932 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
933 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
936 case EFI_IFR_EQ_ID_ID_OP
:
937 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
938 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
941 case EFI_IFR_EQ_ID_LIST_OP
:
942 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
943 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
944 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
947 case EFI_IFR_TO_STRING_OP
:
948 case EFI_IFR_FIND_OP
:
949 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
952 case EFI_IFR_STRING_REF1_OP
:
953 Value
->Type
= EFI_IFR_TYPE_STRING
;
954 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
957 case EFI_IFR_RULE_REF_OP
:
958 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
961 case EFI_IFR_SPAN_OP
:
962 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
965 case EFI_IFR_THIS_OP
:
966 ASSERT (CurrentStatement
!= NULL
);
967 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
970 case EFI_IFR_QUESTION_REF1_OP
:
971 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
974 case EFI_IFR_QUESTION_REF3_OP
:
975 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
976 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
978 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
979 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
987 case EFI_IFR_TRUE_OP
:
988 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
989 Value
->Value
.b
= TRUE
;
992 case EFI_IFR_FALSE_OP
:
993 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
994 Value
->Value
.b
= FALSE
;
998 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1002 case EFI_IFR_ZERO_OP
:
1003 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1004 Value
->Value
.u8
= 0;
1007 case EFI_IFR_ONES_OP
:
1008 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1009 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1012 case EFI_IFR_UINT8_OP
:
1013 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1014 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1017 case EFI_IFR_UINT16_OP
:
1018 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1019 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1022 case EFI_IFR_UINT32_OP
:
1023 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1024 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1027 case EFI_IFR_UINT64_OP
:
1028 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1029 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1032 case EFI_IFR_UNDEFINED_OP
:
1033 Value
->Type
= EFI_IFR_TYPE_OTHER
;
1036 case EFI_IFR_VERSION_OP
:
1037 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1038 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1045 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1047 if (SingleOpCodeExpression
) {
1049 // There are two cases to indicate the end of an Expression:
1050 // for single OpCode expression: one Expression OpCode
1051 // for expression consists of more than one OpCode: EFI_IFR_END
1053 SingleOpCodeExpression
= FALSE
;
1055 if (InScopeDisable
) {
1057 // Evaluate DisableIf expression
1059 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1060 if (EFI_ERROR (Status
)) {
1064 ASSERT (CurrentExpression
!= NULL
);
1065 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1066 return EFI_INVALID_PARAMETER
;
1069 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1072 CurrentExpression
= NULL
;
1083 case EFI_IFR_FORM_SET_OP
:
1085 // check the formset GUID
1087 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1088 return EFI_INVALID_PARAMETER
;
1091 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1092 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1095 case EFI_IFR_FORM_OP
:
1097 // Create a new Form for this FormSet
1099 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1100 ASSERT (CurrentForm
!= NULL
);
1101 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1102 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1103 InitializeListHead (&CurrentForm
->StatementListHead
);
1105 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1106 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1109 // Insert into Form list of this FormSet
1111 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1117 case EFI_IFR_VARSTORE_OP
:
1119 // Create a buffer Storage for this FormSet
1121 Storage
= CreateStorage (FormSet
);
1122 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1124 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1125 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1126 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1128 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1129 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1131 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1132 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1133 ASSERT (Storage
->Name
!= NULL
);
1134 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1135 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1139 // Initialize <ConfigHdr>
1141 InitializeConfigHdr (FormSet
, Storage
);
1144 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1146 // Create a name/value Storage for this FormSet
1148 Storage
= CreateStorage (FormSet
);
1149 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1151 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1152 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1155 // Initialize <ConfigHdr>
1157 InitializeConfigHdr (FormSet
, Storage
);
1160 case EFI_IFR_VARSTORE_EFI_OP
:
1162 // Create a EFI variable Storage for this FormSet
1164 Storage
= CreateStorage (FormSet
);
1165 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1167 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1168 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1169 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1175 case EFI_IFR_DEFAULTSTORE_OP
:
1176 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1177 ASSERT (DefaultStore
!= NULL
);
1178 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1180 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1181 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1184 // Insert to DefaultStore list of this Formset
1186 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1192 case EFI_IFR_SUBTITLE_OP
:
1193 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1194 ASSERT (CurrentStatement
!= NULL
);
1196 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1199 mInScopeSubtitle
= TRUE
;
1203 case EFI_IFR_TEXT_OP
:
1204 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1205 ASSERT (CurrentStatement
!= NULL
);
1207 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1213 case EFI_IFR_ACTION_OP
:
1214 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1215 ASSERT (CurrentStatement
!= NULL
);
1217 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1219 // No QuestionConfig present, so no configuration string will be processed
1221 CurrentStatement
->QuestionConfig
= 0;
1223 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1227 case EFI_IFR_RESET_BUTTON_OP
:
1228 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1230 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1233 case EFI_IFR_REF_OP
:
1234 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1236 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1237 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1238 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1240 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1241 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1243 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1244 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1250 case EFI_IFR_ONE_OF_OP
:
1251 case EFI_IFR_NUMERIC_OP
:
1252 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1254 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1255 Value
= &CurrentStatement
->HiiValue
;
1257 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1258 case EFI_IFR_NUMERIC_SIZE_1
:
1259 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1260 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1261 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1262 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1263 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1266 case EFI_IFR_NUMERIC_SIZE_2
:
1267 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1268 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1269 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1270 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1271 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1274 case EFI_IFR_NUMERIC_SIZE_4
:
1275 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1276 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1277 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1278 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1279 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1282 case EFI_IFR_NUMERIC_SIZE_8
:
1283 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1284 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1285 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1286 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1287 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1294 InitializeRequestElement (FormSet
, CurrentStatement
);
1296 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1297 SuppressForOption
= TRUE
;
1301 case EFI_IFR_ORDERED_LIST_OP
:
1302 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1304 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1305 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1306 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1307 InitializeRequestElement (FormSet
, CurrentStatement
);
1310 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1311 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1312 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1314 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1315 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1318 SuppressForOption
= TRUE
;
1322 case EFI_IFR_CHECKBOX_OP
:
1323 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1325 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1326 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1327 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1329 InitializeRequestElement (FormSet
, CurrentStatement
);
1333 case EFI_IFR_STRING_OP
:
1334 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1337 // MinSize is the minimum number of characters that can be accepted for this opcode,
1338 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1339 // The characters are stored as Unicode, so the storage width should multiply 2.
1341 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1342 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1343 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1344 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1346 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1347 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1349 InitializeRequestElement (FormSet
, CurrentStatement
);
1352 case EFI_IFR_PASSWORD_OP
:
1353 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1356 // MinSize is the minimum number of characters that can be accepted for this opcode,
1357 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1358 // The characters are stored as Unicode, so the storage width should multiply 2.
1360 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1361 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1362 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1364 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1365 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1367 InitializeRequestElement (FormSet
, CurrentStatement
);
1370 case EFI_IFR_DATE_OP
:
1371 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1373 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1374 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1376 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1377 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1379 InitializeRequestElement (FormSet
, CurrentStatement
);
1382 // Don't assign storage for RTC type of date/time
1384 CurrentStatement
->Storage
= NULL
;
1385 CurrentStatement
->StorageWidth
= 0;
1389 case EFI_IFR_TIME_OP
:
1390 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1392 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1393 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1395 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1396 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1398 InitializeRequestElement (FormSet
, CurrentStatement
);
1401 // Don't assign storage for RTC type of date/time
1403 CurrentStatement
->Storage
= NULL
;
1404 CurrentStatement
->StorageWidth
= 0;
1411 case EFI_IFR_DEFAULT_OP
:
1413 // EFI_IFR_DEFAULT appear in scope of a Question,
1414 // It creates a default value for the current question.
1415 // A Question may have more than one Default value which have different default types.
1417 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1418 ASSERT (CurrentDefault
!= NULL
);
1419 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1421 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1422 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1423 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1424 ExtendValueToU64 (&CurrentDefault
->Value
);
1427 // Insert to Default Value list of current Question
1429 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1432 InScopeDefault
= TRUE
;
1439 case EFI_IFR_ONE_OF_OPTION_OP
:
1441 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1442 // It create a selection for use in current Question.
1444 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1445 ASSERT (CurrentOption
!= NULL
);
1446 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1448 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1449 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1450 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1451 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1452 ExtendValueToU64 (&CurrentOption
->Value
);
1454 if (InScopeOptionSuppress
) {
1455 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1459 // Insert to Option list of current Question
1461 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1467 case EFI_IFR_NO_SUBMIT_IF_OP
:
1468 case EFI_IFR_INCONSISTENT_IF_OP
:
1470 // Create an Expression node
1472 CurrentExpression
= CreateExpression (CurrentForm
);
1473 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1475 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1476 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1477 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1479 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1480 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1484 case EFI_IFR_SUPPRESS_IF_OP
:
1486 // Question and Option will appear in scope of this OpCode
1488 CurrentExpression
= CreateExpression (CurrentForm
);
1489 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1490 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1492 if (SuppressForOption
) {
1493 InScopeOptionSuppress
= TRUE
;
1494 OptionSuppressExpression
= CurrentExpression
;
1496 mInScopeSuppress
= TRUE
;
1497 mSuppressExpression
= CurrentExpression
;
1501 case EFI_IFR_GRAY_OUT_IF_OP
:
1503 // Questions will appear in scope of this OpCode
1505 CurrentExpression
= CreateExpression (CurrentForm
);
1506 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1507 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1509 mInScopeGrayOut
= TRUE
;
1510 mGrayOutExpression
= CurrentExpression
;
1513 case EFI_IFR_DISABLE_IF_OP
:
1515 // The DisableIf expression should only rely on constant, so it could be
1516 // evaluated at initialization and it will not be queued
1518 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1519 ASSERT (CurrentExpression
!= NULL
);
1520 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1521 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1522 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1524 InScopeDisable
= TRUE
;
1525 OpCodeDisabled
= FALSE
;
1528 // Take a look at next OpCode to see whether current expression consists
1531 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1532 SingleOpCodeExpression
= TRUE
;
1539 case EFI_IFR_VALUE_OP
:
1540 CurrentExpression
= CreateExpression (CurrentForm
);
1541 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1542 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1544 if (InScopeDefault
) {
1546 // Used for default (EFI_IFR_DEFAULT)
1548 CurrentDefault
->ValueExpression
= CurrentExpression
;
1551 // If used for a question, then the question will be read-only
1554 // Make sure CurrentStatement is not NULL.
1555 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1556 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1558 ASSERT (CurrentStatement
!= NULL
);
1559 CurrentStatement
->ValueExpression
= CurrentExpression
;
1563 case EFI_IFR_RULE_OP
:
1564 CurrentExpression
= CreateExpression (CurrentForm
);
1565 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1567 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1568 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1574 case EFI_IFR_IMAGE_OP
:
1576 // Get ScopeOpcode from top of stack
1578 PopScope (&ScopeOpCode
);
1579 PushScope (ScopeOpCode
);
1581 switch (ScopeOpCode
) {
1582 case EFI_IFR_FORM_SET_OP
:
1583 ImageId
= &FormSet
->ImageId
;
1586 case EFI_IFR_FORM_OP
:
1587 ASSERT (CurrentForm
!= NULL
);
1588 ImageId
= &CurrentForm
->ImageId
;
1591 case EFI_IFR_ONE_OF_OPTION_OP
:
1592 ImageId
= &CurrentOption
->ImageId
;
1597 // Make sure CurrentStatement is not NULL.
1598 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1599 // file is wrongly generated by tools such as VFR Compiler.
1601 ASSERT (CurrentStatement
!= NULL
);
1602 ImageId
= &CurrentStatement
->ImageId
;
1606 ASSERT (ImageId
!= NULL
);
1607 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1613 case EFI_IFR_REFRESH_OP
:
1614 ASSERT (CurrentStatement
!= NULL
);
1615 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1621 case EFI_IFR_GUID_OP
:
1622 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1624 // Tiano specific GUIDed opcodes
1626 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1627 case EFI_IFR_EXTEND_OP_LABEL
:
1629 // just ignore label
1633 case EFI_IFR_EXTEND_OP_BANNER
:
1634 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1636 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1637 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1638 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1639 sizeof (EFI_STRING_ID
)
1644 case EFI_IFR_EXTEND_OP_CLASS
:
1645 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1648 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1649 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1662 case EFI_IFR_END_OP
:
1663 Status
= PopScope (&ScopeOpCode
);
1664 if (EFI_ERROR (Status
)) {
1669 switch (ScopeOpCode
) {
1670 case EFI_IFR_FORM_SET_OP
:
1672 // End of FormSet, update FormSet IFR binary length
1673 // to stop parsing substantial OpCodes
1675 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1678 case EFI_IFR_FORM_OP
:
1685 case EFI_IFR_ONE_OF_OPTION_OP
:
1689 CurrentOption
= NULL
;
1692 case EFI_IFR_SUBTITLE_OP
:
1693 mInScopeSubtitle
= FALSE
;
1696 case EFI_IFR_NO_SUBMIT_IF_OP
:
1697 case EFI_IFR_INCONSISTENT_IF_OP
:
1699 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1703 case EFI_IFR_SUPPRESS_IF_OP
:
1704 if (SuppressForOption
) {
1705 InScopeOptionSuppress
= FALSE
;
1707 mInScopeSuppress
= FALSE
;
1711 case EFI_IFR_GRAY_OUT_IF_OP
:
1712 mInScopeGrayOut
= FALSE
;
1715 case EFI_IFR_DISABLE_IF_OP
:
1716 InScopeDisable
= FALSE
;
1717 OpCodeDisabled
= FALSE
;
1720 case EFI_IFR_ONE_OF_OP
:
1721 case EFI_IFR_ORDERED_LIST_OP
:
1722 SuppressForOption
= FALSE
;
1725 case EFI_IFR_DEFAULT_OP
:
1726 InScopeDefault
= FALSE
;
1730 if (IsExpressionOpCode (ScopeOpCode
)) {
1731 if (InScopeDisable
) {
1733 // Evaluate DisableIf expression
1735 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1736 if (EFI_ERROR (Status
)) {
1740 ASSERT (CurrentExpression
!= NULL
);
1741 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1742 return EFI_INVALID_PARAMETER
;
1745 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1747 // DisableIf Expression is only used once and not quequed, free it
1749 DestroyExpression (CurrentExpression
);
1753 // End of current Expression
1755 CurrentExpression
= NULL
;