2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2010, 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.
17 UINT16 mStatementIndex
;
18 UINT16 mExpressionOpCodeIndex
;
20 BOOLEAN mInScopeSubtitle
;
21 BOOLEAN mInScopeSuppress
;
22 BOOLEAN mInScopeGrayOut
;
23 BOOLEAN mInScopeDisable
;
24 FORM_EXPRESSION
*mSuppressExpression
;
25 FORM_EXPRESSION
*mGrayOutExpression
;
26 FORM_EXPRESSION
*mDisableExpression
;
29 Initialize Statement header members.
31 @param OpCodeData Pointer of the raw OpCode data.
32 @param FormSet Pointer of the current FormSe.
33 @param Form Pointer of the current Form.
35 @return The Statement.
38 FORM_BROWSER_STATEMENT
*
41 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
42 IN OUT FORM_BROWSER_FORM
*Form
45 FORM_BROWSER_STATEMENT
*Statement
;
46 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
50 // We are currently not in a Form Scope, so just skip this Statement
55 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
58 InitializeListHead (&Statement
->DefaultListHead
);
59 InitializeListHead (&Statement
->OptionListHead
);
60 InitializeListHead (&Statement
->InconsistentListHead
);
61 InitializeListHead (&Statement
->NoSubmitListHead
);
63 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
65 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
67 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
68 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
69 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
71 if (mInScopeSuppress
) {
72 Statement
->SuppressExpression
= mSuppressExpression
;
75 if (mInScopeGrayOut
) {
76 Statement
->GrayOutExpression
= mGrayOutExpression
;
80 if (mInScopeDisable
) {
81 Statement
->DisableExpression
= mDisableExpression
;
84 Statement
->InSubtitle
= mInScopeSubtitle
;
87 // Insert this Statement into current Form
89 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
95 Convert a numeric value to a Unicode String and insert it to String Package.
96 This string is used as the Unicode Name for the EFI Variable. This is to support
97 the deprecated vareqval opcode.
99 @param FormSet The FormSet.
100 @param Statement The numeric question whose VarStoreInfo.VarName is the
101 numeric value which is used to produce the Unicode Name
102 for the EFI Variable.
104 If the Statement is NULL, the ASSERT.
105 If the opcode is not Numeric, then ASSERT.
107 @retval EFI_SUCCESS The funtion always succeeds.
110 UpdateCheckBoxStringToken (
111 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
112 IN FORM_BROWSER_STATEMENT
*Statement
115 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
118 ASSERT (Statement
!= NULL
);
119 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
121 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
123 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
125 return EFI_OUT_OF_RESOURCES
;
128 Statement
->VarStoreInfo
.VarName
= Id
;
134 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
136 @param OpCodeData The current opcode.
142 IsNextOpCodeGuidedVarEqName (
149 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
150 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
151 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
153 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
155 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
165 Initialize Question's members.
167 @param OpCodeData Pointer of the raw OpCode data.
168 @param FormSet Pointer of the current FormSet.
169 @param Form Pointer of the current Form.
171 @return The Question.
174 FORM_BROWSER_STATEMENT
*
176 IN UINT8
*OpCodeData
,
177 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
178 IN OUT FORM_BROWSER_FORM
*Form
181 FORM_BROWSER_STATEMENT
*Statement
;
182 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
184 FORMSET_STORAGE
*Storage
;
185 NAME_VALUE_NODE
*NameValueNode
;
188 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
189 if (Statement
== NULL
) {
193 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
194 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
195 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
196 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
198 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
200 if (Statement
->VarStoreId
== 0) {
202 // VarStoreId of zero indicates no variable storage
208 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
209 // Framework Compatibility
211 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
212 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
213 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
214 if (EFI_ERROR (Status
)) {
221 // Find Storage for this Question
223 Link
= GetFirstNode (&FormSet
->StorageListHead
);
224 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
225 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
227 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
228 Statement
->Storage
= Storage
;
232 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
234 ASSERT (Statement
->Storage
!= NULL
);
237 // Initialilze varname for Name/Value or EFI Variable
239 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
240 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
241 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
242 ASSERT (Statement
->VariableName
!= NULL
);
244 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
246 // Insert to Name/Value varstore list
248 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
249 ASSERT (NameValueNode
!= NULL
);
250 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
251 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
252 ASSERT (NameValueNode
->Name
!= NULL
);
253 NameValueNode
->Value
= AllocateZeroPool (0x10);
254 ASSERT (NameValueNode
->Value
!= NULL
);
255 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
256 ASSERT (NameValueNode
->EditValue
!= NULL
);
258 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
267 Allocate a FORM_EXPRESSION node.
269 @param Form The Form associated with this Expression
271 @return Pointer to a FORM_EXPRESSION data structure.
276 IN OUT FORM_BROWSER_FORM
*Form
279 FORM_EXPRESSION
*Expression
;
281 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
282 ASSERT (Expression
!= NULL
);
283 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
284 InitializeListHead (&Expression
->OpCodeListHead
);
291 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
293 @param FormSet Pointer of the current FormSet
295 @return Pointer to a FORMSET_STORAGE data structure.
300 IN FORM_BROWSER_FORMSET
*FormSet
303 FORMSET_STORAGE
*Storage
;
305 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
306 ASSERT (Storage
!= NULL
);
307 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
308 InitializeListHead (&Storage
->NameValueListHead
);
309 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
316 Create ConfigHdr string for a storage.
318 @param FormSet Pointer of the current FormSet
319 @param Storage Pointer of the storage
321 @retval EFI_SUCCESS Initialize ConfigHdr success
325 InitializeConfigHdr (
326 IN FORM_BROWSER_FORMSET
*FormSet
,
327 IN OUT FORMSET_STORAGE
*Storage
332 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
333 Name
= Storage
->Name
;
338 Storage
->ConfigHdr
= HiiConstructConfigHdr (
341 FormSet
->DriverHandle
344 if (Storage
->ConfigHdr
== NULL
) {
345 return EFI_NOT_FOUND
;
348 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
349 Storage
->SpareStrLen
= 0;
356 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
358 @param FormSet Pointer of the current FormSet.
359 @param Question The Question to be initialized.
361 @retval EFI_SUCCESS Function success.
362 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
366 InitializeRequestElement (
367 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
368 IN OUT FORM_BROWSER_STATEMENT
*Question
371 FORMSET_STORAGE
*Storage
;
375 CHAR16 RequestElement
[30];
377 Storage
= Question
->Storage
;
378 if (Storage
== NULL
) {
379 return EFI_INVALID_PARAMETER
;
382 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
384 // <ConfigRequest> is unnecessary for EFI variable storage,
385 // GetVariable()/SetVariable() will be used to retrieve/save values
391 // Prepare <RequestElement>
393 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
394 StrLen
= UnicodeSPrint (
396 30 * sizeof (CHAR16
),
397 L
"&OFFSET=%x&WIDTH=%x",
398 Question
->VarStoreInfo
.VarOffset
,
399 Question
->StorageWidth
401 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
403 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
406 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
408 // Password with CALLBACK flag is stored in encoded format,
409 // so don't need to append it to <ConfigRequest>
415 // Append <RequestElement> to <ConfigRequest>
417 if (StrLen
> Storage
->SpareStrLen
) {
419 // Old String buffer is not sufficient for RequestElement, allocate a new one
421 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
422 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
423 ASSERT (NewStr
!= NULL
);
424 if (Storage
->ConfigRequest
!= NULL
) {
425 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
426 FreePool (Storage
->ConfigRequest
);
428 Storage
->ConfigRequest
= NewStr
;
429 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
432 StrCat (Storage
->ConfigRequest
, RequestElement
);
433 Storage
->ElementCount
++;
434 Storage
->SpareStrLen
-= StrLen
;
441 Free resources of a Expression.
443 @param FormSet Pointer of the Expression
448 IN FORM_EXPRESSION
*Expression
452 EXPRESSION_OPCODE
*OpCode
;
453 LIST_ENTRY
*SubExpressionLink
;
454 FORM_EXPRESSION
*SubExpression
;
456 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
457 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
458 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
459 RemoveEntryList (&OpCode
->Link
);
461 if (OpCode
->ValueList
!= NULL
) {
462 FreePool (OpCode
->ValueList
);
465 if (OpCode
->ValueName
!= NULL
) {
466 FreePool (OpCode
->ValueName
);
469 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
470 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
471 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
472 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
473 RemoveEntryList(&SubExpression
->Link
);
474 DestroyExpression (SubExpression
);
480 // Free this Expression
482 FreePool (Expression
);
487 Free resources of a storage.
489 @param Storage Pointer of the storage
494 IN FORMSET_STORAGE
*Storage
498 NAME_VALUE_NODE
*NameValueNode
;
500 if (Storage
== NULL
) {
504 if (Storage
->Name
!= NULL
) {
505 FreePool (Storage
->Name
);
507 if (Storage
->Buffer
!= NULL
) {
508 FreePool (Storage
->Buffer
);
510 if (Storage
->EditBuffer
!= NULL
) {
511 FreePool (Storage
->EditBuffer
);
514 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
515 Link
= GetFirstNode (&Storage
->NameValueListHead
);
516 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
517 RemoveEntryList (&NameValueNode
->Link
);
519 if (NameValueNode
->Name
!= NULL
) {
520 FreePool (NameValueNode
->Name
);
522 if (NameValueNode
->Value
!= NULL
) {
523 FreePool (NameValueNode
->Value
);
525 if (NameValueNode
->EditValue
!= NULL
) {
526 FreePool (NameValueNode
->EditValue
);
528 FreePool (NameValueNode
);
531 if (Storage
->ConfigHdr
!= NULL
) {
532 FreePool (Storage
->ConfigHdr
);
534 if (Storage
->ConfigRequest
!= NULL
) {
535 FreePool (Storage
->ConfigRequest
);
543 Free resources of a Statement.
545 @param Statement Pointer of the Statement
550 IN OUT FORM_BROWSER_STATEMENT
*Statement
554 QUESTION_DEFAULT
*Default
;
555 QUESTION_OPTION
*Option
;
556 FORM_EXPRESSION
*Expression
;
559 // Free Default value List
561 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
562 Link
= GetFirstNode (&Statement
->DefaultListHead
);
563 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
564 RemoveEntryList (&Default
->Link
);
572 while (!IsListEmpty (&Statement
->OptionListHead
)) {
573 Link
= GetFirstNode (&Statement
->OptionListHead
);
574 Option
= QUESTION_OPTION_FROM_LINK (Link
);
575 RemoveEntryList (&Option
->Link
);
581 // Free Inconsistent List
583 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
584 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
585 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
586 RemoveEntryList (&Expression
->Link
);
588 DestroyExpression (Expression
);
592 // Free NoSubmit List
594 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
595 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
596 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
597 RemoveEntryList (&Expression
->Link
);
599 DestroyExpression (Expression
);
602 if (Statement
->VariableName
!= NULL
) {
603 FreePool (Statement
->VariableName
);
605 if (Statement
->BlockName
!= NULL
) {
606 FreePool (Statement
->BlockName
);
608 if (Statement
->BufferValue
!= NULL
) {
609 FreePool (Statement
->BufferValue
);
615 Free resources of a Form.
617 @param Form Pointer of the Form.
622 IN OUT FORM_BROWSER_FORM
*Form
626 FORM_EXPRESSION
*Expression
;
627 FORM_BROWSER_STATEMENT
*Statement
;
630 // Free Form Expressions
632 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
633 Link
= GetFirstNode (&Form
->ExpressionListHead
);
634 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
635 RemoveEntryList (&Expression
->Link
);
637 DestroyExpression (Expression
);
641 // Free Statements/Questions
643 while (!IsListEmpty (&Form
->StatementListHead
)) {
644 Link
= GetFirstNode (&Form
->StatementListHead
);
645 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
646 RemoveEntryList (&Statement
->Link
);
648 DestroyStatement (Statement
);
659 Free resources allocated for a FormSet.
661 @param FormSet Pointer of the FormSet
666 IN OUT FORM_BROWSER_FORMSET
*FormSet
670 FORMSET_STORAGE
*Storage
;
671 FORMSET_DEFAULTSTORE
*DefaultStore
;
672 FORM_EXPRESSION
*Expression
;
673 FORM_BROWSER_FORM
*Form
;
675 if (FormSet
->IfrBinaryData
== NULL
) {
677 // Uninitialized FormSet
684 // Free IFR binary buffer
686 FreePool (FormSet
->IfrBinaryData
);
689 // Free FormSet Storage
691 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
692 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
693 Link
= GetFirstNode (&FormSet
->StorageListHead
);
694 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
695 RemoveEntryList (&Storage
->Link
);
697 DestroyStorage (Storage
);
702 // Free FormSet Default Store
704 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
705 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
706 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
707 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
708 RemoveEntryList (&DefaultStore
->Link
);
710 FreePool (DefaultStore
);
715 // Free Formset Expressions
717 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
718 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
719 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
720 RemoveEntryList (&Expression
->Link
);
722 DestroyExpression (Expression
);
728 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
729 while (!IsListEmpty (&FormSet
->FormListHead
)) {
730 Link
= GetFirstNode (&FormSet
->FormListHead
);
731 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
732 RemoveEntryList (&Form
->Link
);
738 if (FormSet
->StatementBuffer
!= NULL
) {
739 FreePool (FormSet
->StatementBuffer
);
741 if (FormSet
->ExpressionBuffer
!= NULL
) {
742 FreePool (FormSet
->ExpressionBuffer
);
750 Tell whether this Operand is an Expression OpCode or not
752 @param Operand Operand of an IFR OpCode.
754 @retval TRUE This is an Expression OpCode.
755 @retval FALSE Not an Expression OpCode.
763 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
764 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
765 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
766 (Operand
== EFI_IFR_CATENATE_OP
) ||
767 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
768 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
769 (Operand
== EFI_IFR_MAP_OP
) ||
770 (Operand
== EFI_IFR_VERSION_OP
) ||
771 (Operand
== EFI_IFR_SECURITY_OP
)) {
780 Calculate number of Statemens(Questions) and Expression OpCodes.
782 @param FormSet The FormSet to be counted.
783 @param NumberOfStatement Number of Statemens(Questions)
784 @param NumberOfExpression Number of Expression OpCodes
789 IN FORM_BROWSER_FORMSET
*FormSet
,
790 IN OUT UINT16
*NumberOfStatement
,
791 IN OUT UINT16
*NumberOfExpression
794 UINT16 StatementCount
;
795 UINT16 ExpressionCount
;
804 while (Offset
< FormSet
->IfrBinaryLength
) {
805 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
806 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
809 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
816 *NumberOfStatement
= StatementCount
;
817 *NumberOfExpression
= ExpressionCount
;
823 Parse opcodes in the formset IFR binary.
825 @param FormSet Pointer of the FormSet data structure.
827 @retval EFI_SUCCESS Opcode parse success.
828 @retval Other Opcode parse fail.
833 IN FORM_BROWSER_FORMSET
*FormSet
838 FORM_BROWSER_FORM
*CurrentForm
;
839 FORM_BROWSER_STATEMENT
*CurrentStatement
;
840 EXPRESSION_OPCODE
*ExpressionOpCode
;
841 FORM_EXPRESSION
*CurrentExpression
;
848 FORMSET_STORAGE
*Storage
;
849 FORMSET_DEFAULTSTORE
*DefaultStore
;
850 QUESTION_DEFAULT
*CurrentDefault
;
851 QUESTION_OPTION
*CurrentOption
;
854 UINT16 NumberOfStatement
;
855 UINT16 NumberOfExpression
;
856 EFI_IMAGE_ID
*ImageId
;
857 BOOLEAN SuppressForQuestion
;
858 BOOLEAN SuppressForOption
;
859 BOOLEAN InScopeOptionSuppress
;
860 FORM_EXPRESSION
*OptionSuppressExpression
;
861 BOOLEAN InScopeFormSuppress
;
862 FORM_EXPRESSION
*FormSuppressExpression
;
863 UINT16 DepthOfDisable
;
864 BOOLEAN OpCodeDisabled
;
865 BOOLEAN SingleOpCodeExpression
;
866 BOOLEAN InScopeDefault
;
867 EFI_HII_VALUE
*Value
;
868 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
871 FORMSET_STORAGE
*VarStorage
;
872 LIST_ENTRY
*MapExpressionList
;
873 EFI_VARSTORE_ID TempVarstoreId
;
875 mInScopeSubtitle
= FALSE
;
876 SuppressForQuestion
= FALSE
;
877 SuppressForOption
= FALSE
;
878 InScopeFormSuppress
= FALSE
;
879 mInScopeSuppress
= FALSE
;
880 InScopeOptionSuppress
= FALSE
;
881 mInScopeGrayOut
= FALSE
;
882 mInScopeDisable
= FALSE
;
884 OpCodeDisabled
= FALSE
;
885 SingleOpCodeExpression
= FALSE
;
886 InScopeDefault
= FALSE
;
887 CurrentExpression
= NULL
;
888 CurrentDefault
= NULL
;
889 CurrentOption
= NULL
;
890 OptionSuppressExpression
= NULL
;
891 FormSuppressExpression
= NULL
;
897 MapExpressionList
= NULL
;
901 // Get the number of Statements and Expressions
903 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
906 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
907 if (FormSet
->StatementBuffer
== NULL
) {
908 return EFI_OUT_OF_RESOURCES
;
911 mExpressionOpCodeIndex
= 0;
912 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
913 if (FormSet
->ExpressionBuffer
== NULL
) {
914 return EFI_OUT_OF_RESOURCES
;
917 InitializeListHead (&FormSet
->StorageListHead
);
918 InitializeListHead (&FormSet
->DefaultStoreListHead
);
919 InitializeListHead (&FormSet
->FormListHead
);
920 ResetCurrentExpressionStack ();
921 ResetMapExpressionListStack ();
924 CurrentStatement
= NULL
;
929 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
930 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
932 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
933 OpCodeOffset
+= OpCodeLength
;
934 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
935 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
938 // If scope bit set, push onto scope stack
944 if (OpCodeDisabled
) {
946 // DisableIf Expression is evaluated to be TRUE, try to find its end.
947 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
949 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
951 } else if (Operand
== EFI_IFR_END_OP
) {
952 Status
= PopScope (&ScopeOpCode
);
953 if (EFI_ERROR (Status
)) {
957 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
958 if (DepthOfDisable
== 0) {
959 mInScopeDisable
= FALSE
;
960 OpCodeDisabled
= FALSE
;
969 if (IsExpressionOpCode (Operand
)) {
970 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
971 mExpressionOpCodeIndex
++;
973 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
974 ExpressionOpCode
->Operand
= Operand
;
975 Value
= &ExpressionOpCode
->Value
;
978 case EFI_IFR_EQ_ID_VAL_OP
:
979 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
981 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
982 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
985 case EFI_IFR_EQ_ID_ID_OP
:
986 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
987 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
990 case EFI_IFR_EQ_ID_LIST_OP
:
991 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
992 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
993 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
996 case EFI_IFR_TO_STRING_OP
:
997 case EFI_IFR_FIND_OP
:
998 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1001 case EFI_IFR_STRING_REF1_OP
:
1002 Value
->Type
= EFI_IFR_TYPE_STRING
;
1003 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1006 case EFI_IFR_RULE_REF_OP
:
1007 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1010 case EFI_IFR_SPAN_OP
:
1011 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1014 case EFI_IFR_THIS_OP
:
1015 ASSERT (CurrentStatement
!= NULL
);
1016 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1019 case EFI_IFR_SECURITY_OP
:
1020 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1023 case EFI_IFR_GET_OP
:
1024 case EFI_IFR_SET_OP
:
1025 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1026 if (TempVarstoreId
!= 0) {
1027 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1028 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1029 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1030 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1031 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1032 ExpressionOpCode
->VarStorage
= VarStorage
;
1035 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1038 if (ExpressionOpCode
->VarStorage
== NULL
) {
1040 // VarStorage is not found.
1042 return EFI_INVALID_PARAMETER
;
1045 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1046 switch (ExpressionOpCode
->ValueType
) {
1047 case EFI_IFR_TYPE_BOOLEAN
:
1048 case EFI_IFR_TYPE_NUM_SIZE_8
:
1049 ExpressionOpCode
->ValueWidth
= 1;
1052 case EFI_IFR_TYPE_NUM_SIZE_16
:
1053 case EFI_IFR_TYPE_STRING
:
1054 ExpressionOpCode
->ValueWidth
= 2;
1057 case EFI_IFR_TYPE_NUM_SIZE_32
:
1058 ExpressionOpCode
->ValueWidth
= 4;
1061 case EFI_IFR_TYPE_NUM_SIZE_64
:
1062 ExpressionOpCode
->ValueWidth
= 8;
1065 case EFI_IFR_TYPE_DATE
:
1066 ExpressionOpCode
->ValueWidth
= sizeof (EFI_IFR_DATE
);
1069 case EFI_IFR_TYPE_TIME
:
1070 ExpressionOpCode
->ValueWidth
= sizeof (EFI_IFR_TIME
);
1073 case EFI_IFR_TYPE_OTHER
:
1074 case EFI_IFR_TYPE_UNDEFINED
:
1075 case EFI_IFR_TYPE_ACTION
:
1076 case EFI_IFR_TYPE_BUFFER
:
1079 // Invalid value type for Get/Set opcode.
1081 return EFI_INVALID_PARAMETER
;
1083 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1084 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1085 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1086 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1087 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1088 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1089 if (ExpressionOpCode
->ValueName
== NULL
) {
1091 // String ID is invalid.
1093 return EFI_INVALID_PARAMETER
;
1098 case EFI_IFR_QUESTION_REF1_OP
:
1099 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1102 case EFI_IFR_QUESTION_REF3_OP
:
1103 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1104 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1106 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1107 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1115 case EFI_IFR_TRUE_OP
:
1116 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1117 Value
->Value
.b
= TRUE
;
1120 case EFI_IFR_FALSE_OP
:
1121 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1122 Value
->Value
.b
= FALSE
;
1125 case EFI_IFR_ONE_OP
:
1126 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1127 Value
->Value
.u8
= 1;
1130 case EFI_IFR_ZERO_OP
:
1131 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1132 Value
->Value
.u8
= 0;
1135 case EFI_IFR_ONES_OP
:
1136 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1137 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1140 case EFI_IFR_UINT8_OP
:
1141 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1142 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1145 case EFI_IFR_UINT16_OP
:
1146 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1147 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1150 case EFI_IFR_UINT32_OP
:
1151 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1152 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1155 case EFI_IFR_UINT64_OP
:
1156 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1157 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1160 case EFI_IFR_UNDEFINED_OP
:
1161 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1164 case EFI_IFR_VERSION_OP
:
1165 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1166 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1173 // Create sub expression nested in MAP opcode
1175 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1176 CurrentExpression
= CreateExpression (CurrentForm
);
1177 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1179 SingleOpCodeExpression
= TRUE
;
1182 ASSERT (CurrentExpression
!= NULL
);
1183 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1184 if (Operand
== EFI_IFR_MAP_OP
) {
1186 // Store current Map Expression List.
1188 if (MapExpressionList
!= NULL
) {
1189 PushMapExpressionList (MapExpressionList
);
1192 // Initialize new Map Expression List.
1194 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1195 InitializeListHead (MapExpressionList
);
1197 // Store current expression.
1199 PushCurrentExpression (CurrentExpression
);
1200 CurrentExpression
= NULL
;
1202 } else if (SingleOpCodeExpression
) {
1204 // There are two cases to indicate the end of an Expression:
1205 // for single OpCode expression: one Expression OpCode
1206 // for expression consists of more than one OpCode: EFI_IFR_END
1208 SingleOpCodeExpression
= FALSE
;
1210 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1212 // This is DisableIf expression for Form, it should be a constant expression
1214 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1215 if (EFI_ERROR (Status
)) {
1219 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1220 return EFI_INVALID_PARAMETER
;
1223 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1226 CurrentExpression
= NULL
;
1237 case EFI_IFR_FORM_SET_OP
:
1239 // Check the formset GUID
1241 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1242 return EFI_INVALID_PARAMETER
;
1245 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1246 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1248 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1250 // The formset OpCode contains ClassGuid
1252 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1253 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1256 InitializeListHead (&FormSet
->ExpressionListHead
);
1259 case EFI_IFR_FORM_OP
:
1261 // Create a new Form for this FormSet
1263 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1264 ASSERT (CurrentForm
!= NULL
);
1265 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1266 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1267 InitializeListHead (&CurrentForm
->StatementListHead
);
1269 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1270 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1271 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1273 if (InScopeFormSuppress
) {
1275 // Form is inside of suppressif
1277 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1282 // Enter scope of a Form, suppressif will be used for Question or Option
1284 SuppressForQuestion
= TRUE
;
1288 // Insert into Form list of this FormSet
1290 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1293 case EFI_IFR_FORM_MAP_OP
:
1295 // Create a new Form for this FormSet
1297 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1298 ASSERT (CurrentForm
!= NULL
);
1299 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1300 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1301 InitializeListHead (&CurrentForm
->StatementListHead
);
1302 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1304 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1306 // FormMap Form must contain at least one Map Method.
1308 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1309 return EFI_INVALID_PARAMETER
;
1312 // Try to find the standard form map method.
1314 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1315 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1316 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1317 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1323 // If the standard form map method is not found, the first map method title will be used.
1325 if (CurrentForm
->FormTitle
== 0) {
1326 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1327 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1330 if (InScopeFormSuppress
) {
1332 // Form is inside of suppressif
1334 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1339 // Enter scope of a Form, suppressif will be used for Question or Option
1341 SuppressForQuestion
= TRUE
;
1345 // Insert into Form list of this FormSet
1347 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1353 case EFI_IFR_VARSTORE_OP
:
1355 // Create a buffer Storage for this FormSet
1357 Storage
= CreateStorage (FormSet
);
1358 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1360 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1361 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1362 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1364 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1365 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1367 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1368 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1369 ASSERT (Storage
->Name
!= NULL
);
1370 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1371 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1375 // Initialize <ConfigHdr>
1377 InitializeConfigHdr (FormSet
, Storage
);
1380 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1382 // Create a name/value Storage for this FormSet
1384 Storage
= CreateStorage (FormSet
);
1385 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1387 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1388 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1391 // Initialize <ConfigHdr>
1393 InitializeConfigHdr (FormSet
, Storage
);
1396 case EFI_IFR_VARSTORE_EFI_OP
:
1398 // Create a EFI variable Storage for this FormSet
1400 Storage
= CreateStorage (FormSet
);
1401 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1403 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1404 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1405 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1411 case EFI_IFR_DEFAULTSTORE_OP
:
1412 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1413 ASSERT (DefaultStore
!= NULL
);
1414 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1416 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1417 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1420 // Insert to DefaultStore list of this Formset
1422 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1428 case EFI_IFR_SUBTITLE_OP
:
1429 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1430 ASSERT (CurrentStatement
!= NULL
);
1432 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1435 mInScopeSubtitle
= TRUE
;
1439 case EFI_IFR_TEXT_OP
:
1440 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1441 ASSERT (CurrentStatement
!= NULL
);
1443 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1446 case EFI_IFR_RESET_BUTTON_OP
:
1447 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1448 ASSERT (CurrentStatement
!= NULL
);
1449 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1455 case EFI_IFR_ACTION_OP
:
1456 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1457 ASSERT (CurrentStatement
!= NULL
);
1458 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1460 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1462 // No QuestionConfig present, so no configuration string will be processed
1464 CurrentStatement
->QuestionConfig
= 0;
1466 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1470 case EFI_IFR_REF_OP
:
1471 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1472 ASSERT (CurrentStatement
!= NULL
);
1473 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_UNDEFINED
;
1474 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1475 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1476 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1478 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1479 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1481 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1482 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1488 case EFI_IFR_ONE_OF_OP
:
1489 case EFI_IFR_NUMERIC_OP
:
1490 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1491 ASSERT(CurrentStatement
!= NULL
);
1493 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1494 Value
= &CurrentStatement
->HiiValue
;
1496 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1497 case EFI_IFR_NUMERIC_SIZE_1
:
1498 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1499 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1500 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1501 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1502 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1505 case EFI_IFR_NUMERIC_SIZE_2
:
1506 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1507 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1508 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1509 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1510 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1513 case EFI_IFR_NUMERIC_SIZE_4
:
1514 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1515 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1516 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1517 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1518 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1521 case EFI_IFR_NUMERIC_SIZE_8
:
1522 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1523 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1524 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1525 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1526 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1533 InitializeRequestElement (FormSet
, CurrentStatement
);
1535 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1536 SuppressForOption
= TRUE
;
1540 case EFI_IFR_ORDERED_LIST_OP
:
1541 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1542 ASSERT(CurrentStatement
!= NULL
);
1544 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1545 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1547 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1548 CurrentStatement
->BufferValue
= NULL
;
1551 SuppressForOption
= TRUE
;
1555 case EFI_IFR_CHECKBOX_OP
:
1556 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1557 ASSERT(CurrentStatement
!= NULL
);
1559 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1560 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1561 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1563 InitializeRequestElement (FormSet
, CurrentStatement
);
1567 case EFI_IFR_STRING_OP
:
1568 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1569 ASSERT (CurrentStatement
!= NULL
);
1571 // MinSize is the minimum number of characters that can be accepted for this opcode,
1572 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1573 // The characters are stored as Unicode, so the storage width should multiply 2.
1575 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1576 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1577 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1578 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1580 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1581 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1583 InitializeRequestElement (FormSet
, CurrentStatement
);
1586 case EFI_IFR_PASSWORD_OP
:
1587 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1588 ASSERT (CurrentStatement
!= NULL
);
1590 // MinSize is the minimum number of characters that can be accepted for this opcode,
1591 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1592 // The characters are stored as Unicode, so the storage width should multiply 2.
1594 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1595 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1596 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1598 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1599 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1601 InitializeRequestElement (FormSet
, CurrentStatement
);
1604 case EFI_IFR_DATE_OP
:
1605 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1606 ASSERT(CurrentStatement
!= NULL
);
1608 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1609 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1611 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1612 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1614 InitializeRequestElement (FormSet
, CurrentStatement
);
1617 // Don't assign storage for RTC type of date/time
1619 CurrentStatement
->Storage
= NULL
;
1620 CurrentStatement
->StorageWidth
= 0;
1624 case EFI_IFR_TIME_OP
:
1625 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1626 ASSERT(CurrentStatement
!= NULL
);
1628 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1629 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1631 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1632 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1634 InitializeRequestElement (FormSet
, CurrentStatement
);
1637 // Don't assign storage for RTC type of date/time
1639 CurrentStatement
->Storage
= NULL
;
1640 CurrentStatement
->StorageWidth
= 0;
1647 case EFI_IFR_DEFAULT_OP
:
1649 // EFI_IFR_DEFAULT appear in scope of a Question,
1650 // It creates a default value for the current question.
1651 // A Question may have more than one Default value which have different default types.
1653 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1654 ASSERT (CurrentDefault
!= NULL
);
1655 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1657 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1658 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1659 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1660 ExtendValueToU64 (&CurrentDefault
->Value
);
1663 // Insert to Default Value list of current Question
1665 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1668 InScopeDefault
= TRUE
;
1675 case EFI_IFR_ONE_OF_OPTION_OP
:
1677 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1678 // It create a selection for use in current Question.
1680 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1681 ASSERT (CurrentOption
!= NULL
);
1682 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1684 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1685 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1686 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1687 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1688 ExtendValueToU64 (&CurrentOption
->Value
);
1690 if (InScopeOptionSuppress
) {
1691 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1695 // Insert to Option list of current Question
1697 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1700 // Now we know the Storage width of nested Ordered List
1702 ASSERT (CurrentStatement
!= NULL
);
1703 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1705 switch (CurrentOption
->Value
.Type
) {
1706 case EFI_IFR_TYPE_NUM_SIZE_8
:
1710 case EFI_IFR_TYPE_NUM_SIZE_16
:
1714 case EFI_IFR_TYPE_NUM_SIZE_32
:
1718 case EFI_IFR_TYPE_NUM_SIZE_64
:
1724 // Invalid type for Ordered List
1729 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1730 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1731 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1733 InitializeRequestElement (FormSet
, CurrentStatement
);
1740 case EFI_IFR_NO_SUBMIT_IF_OP
:
1741 case EFI_IFR_INCONSISTENT_IF_OP
:
1743 // Create an Expression node
1745 CurrentExpression
= CreateExpression (CurrentForm
);
1746 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1748 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1749 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1750 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1752 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1753 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1757 // Take a look at next OpCode to see whether current expression consists
1760 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1761 SingleOpCodeExpression
= TRUE
;
1765 case EFI_IFR_SUPPRESS_IF_OP
:
1767 // Question and Option will appear in scope of this OpCode
1769 CurrentExpression
= CreateExpression (CurrentForm
);
1770 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1772 if (CurrentForm
== NULL
) {
1773 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1775 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1778 if (SuppressForOption
) {
1779 InScopeOptionSuppress
= TRUE
;
1780 OptionSuppressExpression
= CurrentExpression
;
1781 } else if (SuppressForQuestion
) {
1782 mInScopeSuppress
= TRUE
;
1783 mSuppressExpression
= CurrentExpression
;
1785 InScopeFormSuppress
= TRUE
;
1786 FormSuppressExpression
= CurrentExpression
;
1790 // Take a look at next OpCode to see whether current expression consists
1793 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1794 SingleOpCodeExpression
= TRUE
;
1798 case EFI_IFR_GRAY_OUT_IF_OP
:
1800 // Questions will appear in scope of this OpCode
1802 CurrentExpression
= CreateExpression (CurrentForm
);
1803 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1804 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1806 mInScopeGrayOut
= TRUE
;
1807 mGrayOutExpression
= CurrentExpression
;
1810 // Take a look at next OpCode to see whether current expression consists
1813 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1814 SingleOpCodeExpression
= TRUE
;
1818 case EFI_IFR_DISABLE_IF_OP
:
1820 // The DisableIf expression should only rely on constant, so it could be
1821 // evaluated at initialization and it will not be queued
1823 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1824 ASSERT (CurrentExpression
!= NULL
);
1825 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1826 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1827 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1829 if (CurrentForm
!= NULL
) {
1831 // This is DisableIf for Question, enqueue it to Form expression list
1833 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1836 mDisableExpression
= CurrentExpression
;
1837 mInScopeDisable
= TRUE
;
1838 OpCodeDisabled
= FALSE
;
1841 // Take a look at next OpCode to see whether current expression consists
1844 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1845 SingleOpCodeExpression
= TRUE
;
1852 case EFI_IFR_VALUE_OP
:
1853 CurrentExpression
= CreateExpression (CurrentForm
);
1854 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1855 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1857 if (InScopeDefault
) {
1859 // Used for default (EFI_IFR_DEFAULT)
1861 CurrentDefault
->ValueExpression
= CurrentExpression
;
1864 // If used for a question, then the question will be read-only
1867 // Make sure CurrentStatement is not NULL.
1868 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1869 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1871 ASSERT (CurrentStatement
!= NULL
);
1872 CurrentStatement
->ValueExpression
= CurrentExpression
;
1876 // Take a look at next OpCode to see whether current expression consists
1879 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1880 SingleOpCodeExpression
= TRUE
;
1884 case EFI_IFR_RULE_OP
:
1885 CurrentExpression
= CreateExpression (CurrentForm
);
1886 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1888 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1889 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1892 // Take a look at next OpCode to see whether current expression consists
1895 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1896 SingleOpCodeExpression
= TRUE
;
1900 case EFI_IFR_READ_OP
:
1901 CurrentExpression
= CreateExpression (CurrentForm
);
1902 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
1903 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1906 // Make sure CurrentStatement is not NULL.
1907 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1908 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1910 ASSERT (CurrentStatement
!= NULL
);
1911 CurrentStatement
->ReadExpression
= CurrentExpression
;
1914 // Take a look at next OpCode to see whether current expression consists
1917 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1918 SingleOpCodeExpression
= TRUE
;
1922 case EFI_IFR_WRITE_OP
:
1923 CurrentExpression
= CreateExpression (CurrentForm
);
1924 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
1925 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1928 // Make sure CurrentStatement is not NULL.
1929 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1930 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1932 ASSERT (CurrentStatement
!= NULL
);
1933 CurrentStatement
->WriteExpression
= CurrentExpression
;
1936 // Take a look at next OpCode to see whether current expression consists
1939 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1940 SingleOpCodeExpression
= TRUE
;
1947 case EFI_IFR_IMAGE_OP
:
1949 // Get ScopeOpcode from top of stack
1951 PopScope (&ScopeOpCode
);
1952 PushScope (ScopeOpCode
);
1954 switch (ScopeOpCode
) {
1955 case EFI_IFR_FORM_SET_OP
:
1956 ImageId
= &FormSet
->ImageId
;
1959 case EFI_IFR_FORM_OP
:
1960 case EFI_IFR_FORM_MAP_OP
:
1961 ASSERT (CurrentForm
!= NULL
);
1962 ImageId
= &CurrentForm
->ImageId
;
1965 case EFI_IFR_ONE_OF_OPTION_OP
:
1966 ImageId
= &CurrentOption
->ImageId
;
1971 // Make sure CurrentStatement is not NULL.
1972 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1973 // file is wrongly generated by tools such as VFR Compiler.
1975 ASSERT (CurrentStatement
!= NULL
);
1976 ImageId
= &CurrentStatement
->ImageId
;
1980 ASSERT (ImageId
!= NULL
);
1981 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1987 case EFI_IFR_REFRESH_OP
:
1988 ASSERT (CurrentStatement
!= NULL
);
1989 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1995 case EFI_IFR_GUID_OP
:
1996 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1998 // Tiano specific GUIDed opcodes
2000 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2001 case EFI_IFR_EXTEND_OP_LABEL
:
2003 // just ignore label
2007 case EFI_IFR_EXTEND_OP_BANNER
:
2009 // By SubClass to get Banner Data from Front Page
2011 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2013 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2014 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2015 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2016 sizeof (EFI_STRING_ID
)
2021 case EFI_IFR_EXTEND_OP_CLASS
:
2022 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2025 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2026 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2039 case EFI_IFR_END_OP
:
2040 Status
= PopScope (&ScopeOpCode
);
2041 if (EFI_ERROR (Status
)) {
2046 switch (ScopeOpCode
) {
2047 case EFI_IFR_FORM_SET_OP
:
2049 // End of FormSet, update FormSet IFR binary length
2050 // to stop parsing substantial OpCodes
2052 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2055 case EFI_IFR_FORM_OP
:
2056 case EFI_IFR_FORM_MAP_OP
:
2061 SuppressForQuestion
= FALSE
;
2064 case EFI_IFR_ONE_OF_OPTION_OP
:
2068 CurrentOption
= NULL
;
2071 case EFI_IFR_SUBTITLE_OP
:
2072 mInScopeSubtitle
= FALSE
;
2075 case EFI_IFR_NO_SUBMIT_IF_OP
:
2076 case EFI_IFR_INCONSISTENT_IF_OP
:
2078 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2082 case EFI_IFR_SUPPRESS_IF_OP
:
2083 if (SuppressForOption
) {
2084 InScopeOptionSuppress
= FALSE
;
2085 } else if (SuppressForQuestion
) {
2086 mInScopeSuppress
= FALSE
;
2088 InScopeFormSuppress
= FALSE
;
2092 case EFI_IFR_GRAY_OUT_IF_OP
:
2093 mInScopeGrayOut
= FALSE
;
2096 case EFI_IFR_DISABLE_IF_OP
:
2097 mInScopeDisable
= FALSE
;
2098 OpCodeDisabled
= FALSE
;
2101 case EFI_IFR_ONE_OF_OP
:
2102 case EFI_IFR_ORDERED_LIST_OP
:
2103 SuppressForOption
= FALSE
;
2106 case EFI_IFR_DEFAULT_OP
:
2107 InScopeDefault
= FALSE
;
2110 case EFI_IFR_MAP_OP
:
2112 // Get current Map Expression List.
2114 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2115 if (Status
== EFI_ACCESS_DENIED
) {
2116 MapExpressionList
= NULL
;
2119 // Get current expression.
2121 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2122 ASSERT_EFI_ERROR (Status
);
2127 if (IsExpressionOpCode (ScopeOpCode
)) {
2128 if (mInScopeDisable
&& CurrentForm
== NULL
) {
2130 // This is DisableIf expression for Form, it should be a constant expression
2132 ASSERT (CurrentExpression
!= NULL
);
2133 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2134 if (EFI_ERROR (Status
)) {
2138 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2139 return EFI_INVALID_PARAMETER
;
2142 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2144 // DisableIf Expression is only used once and not queued, free it
2146 DestroyExpression (CurrentExpression
);
2150 // End of current Expression
2152 CurrentExpression
= NULL
;