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
;
454 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
455 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
456 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
457 RemoveEntryList (&OpCode
->Link
);
459 if (OpCode
->ValueList
!= NULL
) {
460 FreePool (OpCode
->ValueList
);
465 // Free this Expression
467 FreePool (Expression
);
472 Free resources of a storage.
474 @param Storage Pointer of the storage
479 IN FORMSET_STORAGE
*Storage
483 NAME_VALUE_NODE
*NameValueNode
;
485 if (Storage
== NULL
) {
489 if (Storage
->Name
!= NULL
) {
490 FreePool (Storage
->Name
);
492 if (Storage
->Buffer
!= NULL
) {
493 FreePool (Storage
->Buffer
);
495 if (Storage
->EditBuffer
!= NULL
) {
496 FreePool (Storage
->EditBuffer
);
499 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
500 Link
= GetFirstNode (&Storage
->NameValueListHead
);
501 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
502 RemoveEntryList (&NameValueNode
->Link
);
504 if (NameValueNode
->Name
!= NULL
) {
505 FreePool (NameValueNode
->Name
);
507 if (NameValueNode
->Value
!= NULL
) {
508 FreePool (NameValueNode
->Value
);
510 if (NameValueNode
->EditValue
!= NULL
) {
511 FreePool (NameValueNode
->EditValue
);
513 FreePool (NameValueNode
);
516 if (Storage
->ConfigHdr
!= NULL
) {
517 FreePool (Storage
->ConfigHdr
);
519 if (Storage
->ConfigRequest
!= NULL
) {
520 FreePool (Storage
->ConfigRequest
);
528 Free resources of a Statement.
530 @param Statement Pointer of the Statement
535 IN OUT FORM_BROWSER_STATEMENT
*Statement
539 QUESTION_DEFAULT
*Default
;
540 QUESTION_OPTION
*Option
;
541 FORM_EXPRESSION
*Expression
;
544 // Free Default value List
546 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
547 Link
= GetFirstNode (&Statement
->DefaultListHead
);
548 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
549 RemoveEntryList (&Default
->Link
);
557 while (!IsListEmpty (&Statement
->OptionListHead
)) {
558 Link
= GetFirstNode (&Statement
->OptionListHead
);
559 Option
= QUESTION_OPTION_FROM_LINK (Link
);
560 RemoveEntryList (&Option
->Link
);
566 // Free Inconsistent List
568 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
569 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
570 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
571 RemoveEntryList (&Expression
->Link
);
573 DestroyExpression (Expression
);
577 // Free NoSubmit List
579 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
580 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
581 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
582 RemoveEntryList (&Expression
->Link
);
584 DestroyExpression (Expression
);
587 if (Statement
->VariableName
!= NULL
) {
588 FreePool (Statement
->VariableName
);
590 if (Statement
->BlockName
!= NULL
) {
591 FreePool (Statement
->BlockName
);
597 Free resources of a Form.
599 @param Form Pointer of the Form.
604 IN OUT FORM_BROWSER_FORM
*Form
608 FORM_EXPRESSION
*Expression
;
609 FORM_BROWSER_STATEMENT
*Statement
;
612 // Free Form Expressions
614 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
615 Link
= GetFirstNode (&Form
->ExpressionListHead
);
616 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
617 RemoveEntryList (&Expression
->Link
);
619 DestroyExpression (Expression
);
623 // Free Statements/Questions
625 while (!IsListEmpty (&Form
->StatementListHead
)) {
626 Link
= GetFirstNode (&Form
->StatementListHead
);
627 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
628 RemoveEntryList (&Statement
->Link
);
630 DestroyStatement (Statement
);
641 Free resources allocated for a FormSet.
643 @param FormSet Pointer of the FormSet
648 IN OUT FORM_BROWSER_FORMSET
*FormSet
652 FORMSET_STORAGE
*Storage
;
653 FORMSET_DEFAULTSTORE
*DefaultStore
;
654 FORM_EXPRESSION
*Expression
;
655 FORM_BROWSER_FORM
*Form
;
657 if (FormSet
->IfrBinaryData
== NULL
) {
659 // Uninitialized FormSet
666 // Free IFR binary buffer
668 FreePool (FormSet
->IfrBinaryData
);
671 // Free FormSet Storage
673 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
674 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
675 Link
= GetFirstNode (&FormSet
->StorageListHead
);
676 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
677 RemoveEntryList (&Storage
->Link
);
679 DestroyStorage (Storage
);
684 // Free FormSet Default Store
686 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
687 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
688 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
689 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
690 RemoveEntryList (&DefaultStore
->Link
);
692 FreePool (DefaultStore
);
697 // Free Formset Expressions
699 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
700 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
701 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
702 RemoveEntryList (&Expression
->Link
);
704 DestroyExpression (Expression
);
710 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
711 while (!IsListEmpty (&FormSet
->FormListHead
)) {
712 Link
= GetFirstNode (&FormSet
->FormListHead
);
713 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
714 RemoveEntryList (&Form
->Link
);
720 if (FormSet
->StatementBuffer
!= NULL
) {
721 FreePool (FormSet
->StatementBuffer
);
723 if (FormSet
->ExpressionBuffer
!= NULL
) {
724 FreePool (FormSet
->ExpressionBuffer
);
732 Tell whether this Operand is an Expression OpCode or not
734 @param Operand Operand of an IFR OpCode.
736 @retval TRUE This is an Expression OpCode.
737 @retval FALSE Not an Expression OpCode.
745 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
746 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
747 (Operand
== EFI_IFR_CATENATE_OP
) ||
748 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
749 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
750 (Operand
== EFI_IFR_VERSION_OP
) ||
751 (Operand
== EFI_IFR_SECURITY_OP
)) {
760 Calculate number of Statemens(Questions) and Expression OpCodes.
762 @param FormSet The FormSet to be counted.
763 @param NumberOfStatement Number of Statemens(Questions)
764 @param NumberOfExpression Number of Expression OpCodes
769 IN FORM_BROWSER_FORMSET
*FormSet
,
770 IN OUT UINT16
*NumberOfStatement
,
771 IN OUT UINT16
*NumberOfExpression
774 UINT16 StatementCount
;
775 UINT16 ExpressionCount
;
784 while (Offset
< FormSet
->IfrBinaryLength
) {
785 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
786 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
789 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
796 *NumberOfStatement
= StatementCount
;
797 *NumberOfExpression
= ExpressionCount
;
803 Parse opcodes in the formset IFR binary.
805 @param FormSet Pointer of the FormSet data structure.
807 @retval EFI_SUCCESS Opcode parse success.
808 @retval Other Opcode parse fail.
813 IN FORM_BROWSER_FORMSET
*FormSet
818 FORM_BROWSER_FORM
*CurrentForm
;
819 FORM_BROWSER_STATEMENT
*CurrentStatement
;
820 EXPRESSION_OPCODE
*ExpressionOpCode
;
821 FORM_EXPRESSION
*CurrentExpression
;
828 FORMSET_STORAGE
*Storage
;
829 FORMSET_DEFAULTSTORE
*DefaultStore
;
830 QUESTION_DEFAULT
*CurrentDefault
;
831 QUESTION_OPTION
*CurrentOption
;
834 UINT16 NumberOfStatement
;
835 UINT16 NumberOfExpression
;
836 EFI_IMAGE_ID
*ImageId
;
837 BOOLEAN SuppressForQuestion
;
838 BOOLEAN SuppressForOption
;
839 BOOLEAN InScopeOptionSuppress
;
840 FORM_EXPRESSION
*OptionSuppressExpression
;
841 BOOLEAN InScopeFormSuppress
;
842 FORM_EXPRESSION
*FormSuppressExpression
;
843 UINT16 DepthOfDisable
;
844 BOOLEAN OpCodeDisabled
;
845 BOOLEAN SingleOpCodeExpression
;
846 BOOLEAN InScopeDefault
;
847 EFI_HII_VALUE
*Value
;
849 mInScopeSubtitle
= FALSE
;
850 SuppressForQuestion
= FALSE
;
851 SuppressForOption
= FALSE
;
852 InScopeFormSuppress
= FALSE
;
853 mInScopeSuppress
= FALSE
;
854 InScopeOptionSuppress
= FALSE
;
855 mInScopeGrayOut
= FALSE
;
856 mInScopeDisable
= FALSE
;
858 OpCodeDisabled
= FALSE
;
859 SingleOpCodeExpression
= FALSE
;
860 InScopeDefault
= FALSE
;
861 CurrentExpression
= NULL
;
862 CurrentDefault
= NULL
;
863 CurrentOption
= NULL
;
864 OptionSuppressExpression
= NULL
;
865 FormSuppressExpression
= NULL
;
869 // Get the number of Statements and Expressions
871 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
874 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
875 if (FormSet
->StatementBuffer
== NULL
) {
876 return EFI_OUT_OF_RESOURCES
;
879 mExpressionOpCodeIndex
= 0;
880 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
881 if (FormSet
->ExpressionBuffer
== NULL
) {
882 return EFI_OUT_OF_RESOURCES
;
885 InitializeListHead (&FormSet
->StorageListHead
);
886 InitializeListHead (&FormSet
->DefaultStoreListHead
);
887 InitializeListHead (&FormSet
->FormListHead
);
890 CurrentStatement
= NULL
;
895 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
896 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
898 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
899 OpCodeOffset
+= OpCodeLength
;
900 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
901 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
904 // If scope bit set, push onto scope stack
910 if (OpCodeDisabled
) {
912 // DisableIf Expression is evaluated to be TRUE, try to find its end.
913 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
915 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
917 } else if (Operand
== EFI_IFR_END_OP
) {
918 Status
= PopScope (&ScopeOpCode
);
919 if (EFI_ERROR (Status
)) {
923 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
924 if (DepthOfDisable
== 0) {
925 mInScopeDisable
= FALSE
;
926 OpCodeDisabled
= FALSE
;
935 if (IsExpressionOpCode (Operand
)) {
936 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
937 mExpressionOpCodeIndex
++;
939 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
940 ExpressionOpCode
->Operand
= Operand
;
941 Value
= &ExpressionOpCode
->Value
;
944 case EFI_IFR_EQ_ID_VAL_OP
:
945 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
947 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
948 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
951 case EFI_IFR_EQ_ID_ID_OP
:
952 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
953 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
956 case EFI_IFR_EQ_ID_LIST_OP
:
957 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
958 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
959 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
962 case EFI_IFR_TO_STRING_OP
:
963 case EFI_IFR_FIND_OP
:
964 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
967 case EFI_IFR_STRING_REF1_OP
:
968 Value
->Type
= EFI_IFR_TYPE_STRING
;
969 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
972 case EFI_IFR_RULE_REF_OP
:
973 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
976 case EFI_IFR_SPAN_OP
:
977 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
980 case EFI_IFR_THIS_OP
:
981 ASSERT (CurrentStatement
!= NULL
);
982 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
985 case EFI_IFR_SECURITY_OP
:
986 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
989 case EFI_IFR_QUESTION_REF1_OP
:
990 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
993 case EFI_IFR_QUESTION_REF3_OP
:
994 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
995 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
997 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
998 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1006 case EFI_IFR_TRUE_OP
:
1007 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1008 Value
->Value
.b
= TRUE
;
1011 case EFI_IFR_FALSE_OP
:
1012 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1013 Value
->Value
.b
= FALSE
;
1016 case EFI_IFR_ONE_OP
:
1017 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1018 Value
->Value
.u8
= 1;
1021 case EFI_IFR_ZERO_OP
:
1022 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1023 Value
->Value
.u8
= 0;
1026 case EFI_IFR_ONES_OP
:
1027 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1028 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1031 case EFI_IFR_UINT8_OP
:
1032 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1033 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1036 case EFI_IFR_UINT16_OP
:
1037 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1038 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1041 case EFI_IFR_UINT32_OP
:
1042 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1043 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1046 case EFI_IFR_UINT64_OP
:
1047 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1048 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1051 case EFI_IFR_UNDEFINED_OP
:
1052 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1055 case EFI_IFR_VERSION_OP
:
1056 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1057 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1064 ASSERT (CurrentExpression
!= NULL
);
1065 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1067 if (SingleOpCodeExpression
) {
1069 // There are two cases to indicate the end of an Expression:
1070 // for single OpCode expression: one Expression OpCode
1071 // for expression consists of more than one OpCode: EFI_IFR_END
1073 SingleOpCodeExpression
= FALSE
;
1075 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1077 // This is DisableIf expression for Form, it should be a constant expression
1079 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1080 if (EFI_ERROR (Status
)) {
1084 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1085 return EFI_INVALID_PARAMETER
;
1088 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1091 CurrentExpression
= NULL
;
1102 case EFI_IFR_FORM_SET_OP
:
1104 // Check the formset GUID
1106 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1107 return EFI_INVALID_PARAMETER
;
1110 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1111 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1113 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1115 // The formset OpCode contains ClassGuid
1117 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1118 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1121 InitializeListHead (&FormSet
->ExpressionListHead
);
1124 case EFI_IFR_FORM_OP
:
1126 // Create a new Form for this FormSet
1128 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1129 ASSERT (CurrentForm
!= NULL
);
1130 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1131 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1132 InitializeListHead (&CurrentForm
->StatementListHead
);
1134 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1135 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1137 if (InScopeFormSuppress
) {
1139 // Form is inside of suppressif
1141 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1146 // Enter scope of a Form, suppressif will be used for Question or Option
1148 SuppressForQuestion
= TRUE
;
1152 // Insert into Form list of this FormSet
1154 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1160 case EFI_IFR_VARSTORE_OP
:
1162 // Create a buffer Storage for this FormSet
1164 Storage
= CreateStorage (FormSet
);
1165 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1167 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1168 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1169 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1171 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1172 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1174 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1175 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1176 ASSERT (Storage
->Name
!= NULL
);
1177 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1178 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1182 // Initialize <ConfigHdr>
1184 InitializeConfigHdr (FormSet
, Storage
);
1187 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1189 // Create a name/value Storage for this FormSet
1191 Storage
= CreateStorage (FormSet
);
1192 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1194 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1195 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1198 // Initialize <ConfigHdr>
1200 InitializeConfigHdr (FormSet
, Storage
);
1203 case EFI_IFR_VARSTORE_EFI_OP
:
1205 // Create a EFI variable Storage for this FormSet
1207 Storage
= CreateStorage (FormSet
);
1208 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1210 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1211 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1212 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1218 case EFI_IFR_DEFAULTSTORE_OP
:
1219 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1220 ASSERT (DefaultStore
!= NULL
);
1221 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1223 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1224 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1227 // Insert to DefaultStore list of this Formset
1229 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1235 case EFI_IFR_SUBTITLE_OP
:
1236 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1237 ASSERT (CurrentStatement
!= NULL
);
1239 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1242 mInScopeSubtitle
= TRUE
;
1246 case EFI_IFR_TEXT_OP
:
1247 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1248 ASSERT (CurrentStatement
!= NULL
);
1250 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1253 case EFI_IFR_RESET_BUTTON_OP
:
1254 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1255 ASSERT (CurrentStatement
!= NULL
);
1256 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1262 case EFI_IFR_ACTION_OP
:
1263 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1264 ASSERT (CurrentStatement
!= NULL
);
1265 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1267 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1269 // No QuestionConfig present, so no configuration string will be processed
1271 CurrentStatement
->QuestionConfig
= 0;
1273 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1277 case EFI_IFR_REF_OP
:
1278 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1279 ASSERT (CurrentStatement
!= NULL
);
1280 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_UNDEFINED
;
1281 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1282 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1283 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1285 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1286 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1288 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1289 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1295 case EFI_IFR_ONE_OF_OP
:
1296 case EFI_IFR_NUMERIC_OP
:
1297 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1298 ASSERT(CurrentStatement
!= NULL
);
1300 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1301 Value
= &CurrentStatement
->HiiValue
;
1303 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1304 case EFI_IFR_NUMERIC_SIZE_1
:
1305 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1306 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1307 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1308 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1309 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1312 case EFI_IFR_NUMERIC_SIZE_2
:
1313 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1314 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1315 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1316 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1317 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1320 case EFI_IFR_NUMERIC_SIZE_4
:
1321 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1322 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1323 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1324 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1325 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1328 case EFI_IFR_NUMERIC_SIZE_8
:
1329 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1330 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1331 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1332 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1333 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1340 InitializeRequestElement (FormSet
, CurrentStatement
);
1342 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1343 SuppressForOption
= TRUE
;
1347 case EFI_IFR_ORDERED_LIST_OP
:
1348 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1349 ASSERT(CurrentStatement
!= NULL
);
1351 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1352 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1354 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1357 SuppressForOption
= TRUE
;
1361 case EFI_IFR_CHECKBOX_OP
:
1362 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1363 ASSERT(CurrentStatement
!= NULL
);
1365 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1366 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1367 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1369 InitializeRequestElement (FormSet
, CurrentStatement
);
1373 case EFI_IFR_STRING_OP
:
1374 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1375 ASSERT (CurrentStatement
!= NULL
);
1377 // MinSize is the minimum number of characters that can be accepted for this opcode,
1378 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1379 // The characters are stored as Unicode, so the storage width should multiply 2.
1381 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1382 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1383 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1384 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1386 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1387 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1389 InitializeRequestElement (FormSet
, CurrentStatement
);
1392 case EFI_IFR_PASSWORD_OP
:
1393 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1394 ASSERT (CurrentStatement
!= NULL
);
1396 // MinSize is the minimum number of characters that can be accepted for this opcode,
1397 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1398 // The characters are stored as Unicode, so the storage width should multiply 2.
1400 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1401 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1402 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1404 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1405 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1407 InitializeRequestElement (FormSet
, CurrentStatement
);
1410 case EFI_IFR_DATE_OP
:
1411 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1412 ASSERT(CurrentStatement
!= NULL
);
1414 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1415 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1417 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1418 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1420 InitializeRequestElement (FormSet
, CurrentStatement
);
1423 // Don't assign storage for RTC type of date/time
1425 CurrentStatement
->Storage
= NULL
;
1426 CurrentStatement
->StorageWidth
= 0;
1430 case EFI_IFR_TIME_OP
:
1431 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1432 ASSERT(CurrentStatement
!= NULL
);
1434 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1435 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1437 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1438 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1440 InitializeRequestElement (FormSet
, CurrentStatement
);
1443 // Don't assign storage for RTC type of date/time
1445 CurrentStatement
->Storage
= NULL
;
1446 CurrentStatement
->StorageWidth
= 0;
1453 case EFI_IFR_DEFAULT_OP
:
1455 // EFI_IFR_DEFAULT appear in scope of a Question,
1456 // It creates a default value for the current question.
1457 // A Question may have more than one Default value which have different default types.
1459 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1460 ASSERT (CurrentDefault
!= NULL
);
1461 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1463 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1464 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1465 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1466 ExtendValueToU64 (&CurrentDefault
->Value
);
1469 // Insert to Default Value list of current Question
1471 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1474 InScopeDefault
= TRUE
;
1481 case EFI_IFR_ONE_OF_OPTION_OP
:
1483 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1484 // It create a selection for use in current Question.
1486 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1487 ASSERT (CurrentOption
!= NULL
);
1488 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1490 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1491 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1492 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1493 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1494 ExtendValueToU64 (&CurrentOption
->Value
);
1496 if (InScopeOptionSuppress
) {
1497 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1501 // Insert to Option list of current Question
1503 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1506 // Now we know the Storage width of nested Ordered List
1508 ASSERT (CurrentStatement
!= NULL
);
1509 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1511 switch (CurrentOption
->Value
.Type
) {
1512 case EFI_IFR_TYPE_NUM_SIZE_8
:
1516 case EFI_IFR_TYPE_NUM_SIZE_16
:
1520 case EFI_IFR_TYPE_NUM_SIZE_32
:
1524 case EFI_IFR_TYPE_NUM_SIZE_64
:
1530 // Invalid type for Ordered List
1535 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1536 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1537 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1539 InitializeRequestElement (FormSet
, CurrentStatement
);
1546 case EFI_IFR_NO_SUBMIT_IF_OP
:
1547 case EFI_IFR_INCONSISTENT_IF_OP
:
1549 // Create an Expression node
1551 CurrentExpression
= CreateExpression (CurrentForm
);
1552 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1554 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1555 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1556 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1558 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1559 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1563 // Take a look at next OpCode to see whether current expression consists
1566 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1567 SingleOpCodeExpression
= TRUE
;
1571 case EFI_IFR_SUPPRESS_IF_OP
:
1573 // Question and Option will appear in scope of this OpCode
1575 CurrentExpression
= CreateExpression (CurrentForm
);
1576 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1578 if (CurrentForm
== NULL
) {
1579 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1581 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1584 if (SuppressForOption
) {
1585 InScopeOptionSuppress
= TRUE
;
1586 OptionSuppressExpression
= CurrentExpression
;
1587 } else if (SuppressForQuestion
) {
1588 mInScopeSuppress
= TRUE
;
1589 mSuppressExpression
= CurrentExpression
;
1591 InScopeFormSuppress
= TRUE
;
1592 FormSuppressExpression
= CurrentExpression
;
1596 // Take a look at next OpCode to see whether current expression consists
1599 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1600 SingleOpCodeExpression
= TRUE
;
1604 case EFI_IFR_GRAY_OUT_IF_OP
:
1606 // Questions will appear in scope of this OpCode
1608 CurrentExpression
= CreateExpression (CurrentForm
);
1609 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1610 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1612 mInScopeGrayOut
= TRUE
;
1613 mGrayOutExpression
= CurrentExpression
;
1616 // Take a look at next OpCode to see whether current expression consists
1619 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1620 SingleOpCodeExpression
= TRUE
;
1624 case EFI_IFR_DISABLE_IF_OP
:
1626 // The DisableIf expression should only rely on constant, so it could be
1627 // evaluated at initialization and it will not be queued
1629 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1630 ASSERT (CurrentExpression
!= NULL
);
1631 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1632 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1633 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1635 if (CurrentForm
!= NULL
) {
1637 // This is DisableIf for Question, enqueue it to Form expression list
1639 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1642 mDisableExpression
= CurrentExpression
;
1643 mInScopeDisable
= TRUE
;
1644 OpCodeDisabled
= FALSE
;
1647 // Take a look at next OpCode to see whether current expression consists
1650 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1651 SingleOpCodeExpression
= TRUE
;
1658 case EFI_IFR_VALUE_OP
:
1659 CurrentExpression
= CreateExpression (CurrentForm
);
1660 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1661 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1663 if (InScopeDefault
) {
1665 // Used for default (EFI_IFR_DEFAULT)
1667 CurrentDefault
->ValueExpression
= CurrentExpression
;
1670 // If used for a question, then the question will be read-only
1673 // Make sure CurrentStatement is not NULL.
1674 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1675 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1677 ASSERT (CurrentStatement
!= NULL
);
1678 CurrentStatement
->ValueExpression
= CurrentExpression
;
1682 // Take a look at next OpCode to see whether current expression consists
1685 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1686 SingleOpCodeExpression
= TRUE
;
1690 case EFI_IFR_RULE_OP
:
1691 CurrentExpression
= CreateExpression (CurrentForm
);
1692 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1694 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1695 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1698 // Take a look at next OpCode to see whether current expression consists
1701 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1702 SingleOpCodeExpression
= TRUE
;
1709 case EFI_IFR_IMAGE_OP
:
1711 // Get ScopeOpcode from top of stack
1713 PopScope (&ScopeOpCode
);
1714 PushScope (ScopeOpCode
);
1716 switch (ScopeOpCode
) {
1717 case EFI_IFR_FORM_SET_OP
:
1718 ImageId
= &FormSet
->ImageId
;
1721 case EFI_IFR_FORM_OP
:
1722 ASSERT (CurrentForm
!= NULL
);
1723 ImageId
= &CurrentForm
->ImageId
;
1726 case EFI_IFR_ONE_OF_OPTION_OP
:
1727 ImageId
= &CurrentOption
->ImageId
;
1732 // Make sure CurrentStatement is not NULL.
1733 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1734 // file is wrongly generated by tools such as VFR Compiler.
1736 ASSERT (CurrentStatement
!= NULL
);
1737 ImageId
= &CurrentStatement
->ImageId
;
1741 ASSERT (ImageId
!= NULL
);
1742 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1748 case EFI_IFR_REFRESH_OP
:
1749 ASSERT (CurrentStatement
!= NULL
);
1750 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1756 case EFI_IFR_GUID_OP
:
1757 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1759 // Tiano specific GUIDed opcodes
1761 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1762 case EFI_IFR_EXTEND_OP_LABEL
:
1764 // just ignore label
1768 case EFI_IFR_EXTEND_OP_BANNER
:
1770 // By SubClass to get Banner Data from Front Page
1772 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1774 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1775 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1776 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1777 sizeof (EFI_STRING_ID
)
1782 case EFI_IFR_EXTEND_OP_CLASS
:
1783 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1786 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1787 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1800 case EFI_IFR_END_OP
:
1801 Status
= PopScope (&ScopeOpCode
);
1802 if (EFI_ERROR (Status
)) {
1807 switch (ScopeOpCode
) {
1808 case EFI_IFR_FORM_SET_OP
:
1810 // End of FormSet, update FormSet IFR binary length
1811 // to stop parsing substantial OpCodes
1813 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1816 case EFI_IFR_FORM_OP
:
1821 SuppressForQuestion
= FALSE
;
1824 case EFI_IFR_ONE_OF_OPTION_OP
:
1828 CurrentOption
= NULL
;
1831 case EFI_IFR_SUBTITLE_OP
:
1832 mInScopeSubtitle
= FALSE
;
1835 case EFI_IFR_NO_SUBMIT_IF_OP
:
1836 case EFI_IFR_INCONSISTENT_IF_OP
:
1838 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1842 case EFI_IFR_SUPPRESS_IF_OP
:
1843 if (SuppressForOption
) {
1844 InScopeOptionSuppress
= FALSE
;
1845 } else if (SuppressForQuestion
) {
1846 mInScopeSuppress
= FALSE
;
1848 InScopeFormSuppress
= FALSE
;
1852 case EFI_IFR_GRAY_OUT_IF_OP
:
1853 mInScopeGrayOut
= FALSE
;
1856 case EFI_IFR_DISABLE_IF_OP
:
1857 mInScopeDisable
= FALSE
;
1858 OpCodeDisabled
= FALSE
;
1861 case EFI_IFR_ONE_OF_OP
:
1862 case EFI_IFR_ORDERED_LIST_OP
:
1863 SuppressForOption
= FALSE
;
1866 case EFI_IFR_DEFAULT_OP
:
1867 InScopeDefault
= FALSE
;
1871 if (IsExpressionOpCode (ScopeOpCode
)) {
1872 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1874 // This is DisableIf expression for Form, it should be a constant expression
1876 ASSERT (CurrentExpression
!= NULL
);
1877 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1878 if (EFI_ERROR (Status
)) {
1882 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1883 return EFI_INVALID_PARAMETER
;
1886 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1888 // DisableIf Expression is only used once and not quequed, free it
1890 DestroyExpression (CurrentExpression
);
1894 // End of current Expression
1896 CurrentExpression
= NULL
;