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
);
593 if (Statement
->BufferValue
!= NULL
) {
594 FreePool (Statement
->BufferValue
);
600 Free resources of a Form.
602 @param Form Pointer of the Form.
607 IN OUT FORM_BROWSER_FORM
*Form
611 FORM_EXPRESSION
*Expression
;
612 FORM_BROWSER_STATEMENT
*Statement
;
615 // Free Form Expressions
617 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
618 Link
= GetFirstNode (&Form
->ExpressionListHead
);
619 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
620 RemoveEntryList (&Expression
->Link
);
622 DestroyExpression (Expression
);
626 // Free Statements/Questions
628 while (!IsListEmpty (&Form
->StatementListHead
)) {
629 Link
= GetFirstNode (&Form
->StatementListHead
);
630 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
631 RemoveEntryList (&Statement
->Link
);
633 DestroyStatement (Statement
);
644 Free resources allocated for a FormSet.
646 @param FormSet Pointer of the FormSet
651 IN OUT FORM_BROWSER_FORMSET
*FormSet
655 FORMSET_STORAGE
*Storage
;
656 FORMSET_DEFAULTSTORE
*DefaultStore
;
657 FORM_EXPRESSION
*Expression
;
658 FORM_BROWSER_FORM
*Form
;
660 if (FormSet
->IfrBinaryData
== NULL
) {
662 // Uninitialized FormSet
669 // Free IFR binary buffer
671 FreePool (FormSet
->IfrBinaryData
);
674 // Free FormSet Storage
676 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
677 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
678 Link
= GetFirstNode (&FormSet
->StorageListHead
);
679 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
680 RemoveEntryList (&Storage
->Link
);
682 DestroyStorage (Storage
);
687 // Free FormSet Default Store
689 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
690 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
691 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
692 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
693 RemoveEntryList (&DefaultStore
->Link
);
695 FreePool (DefaultStore
);
700 // Free Formset Expressions
702 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
703 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
704 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
705 RemoveEntryList (&Expression
->Link
);
707 DestroyExpression (Expression
);
713 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
714 while (!IsListEmpty (&FormSet
->FormListHead
)) {
715 Link
= GetFirstNode (&FormSet
->FormListHead
);
716 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
717 RemoveEntryList (&Form
->Link
);
723 if (FormSet
->StatementBuffer
!= NULL
) {
724 FreePool (FormSet
->StatementBuffer
);
726 if (FormSet
->ExpressionBuffer
!= NULL
) {
727 FreePool (FormSet
->ExpressionBuffer
);
735 Tell whether this Operand is an Expression OpCode or not
737 @param Operand Operand of an IFR OpCode.
739 @retval TRUE This is an Expression OpCode.
740 @retval FALSE Not an Expression OpCode.
748 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
749 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
750 (Operand
== EFI_IFR_CATENATE_OP
) ||
751 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
752 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
753 (Operand
== EFI_IFR_VERSION_OP
) ||
754 (Operand
== EFI_IFR_SECURITY_OP
)) {
763 Calculate number of Statemens(Questions) and Expression OpCodes.
765 @param FormSet The FormSet to be counted.
766 @param NumberOfStatement Number of Statemens(Questions)
767 @param NumberOfExpression Number of Expression OpCodes
772 IN FORM_BROWSER_FORMSET
*FormSet
,
773 IN OUT UINT16
*NumberOfStatement
,
774 IN OUT UINT16
*NumberOfExpression
777 UINT16 StatementCount
;
778 UINT16 ExpressionCount
;
787 while (Offset
< FormSet
->IfrBinaryLength
) {
788 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
789 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
792 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
799 *NumberOfStatement
= StatementCount
;
800 *NumberOfExpression
= ExpressionCount
;
806 Parse opcodes in the formset IFR binary.
808 @param FormSet Pointer of the FormSet data structure.
810 @retval EFI_SUCCESS Opcode parse success.
811 @retval Other Opcode parse fail.
816 IN FORM_BROWSER_FORMSET
*FormSet
821 FORM_BROWSER_FORM
*CurrentForm
;
822 FORM_BROWSER_STATEMENT
*CurrentStatement
;
823 EXPRESSION_OPCODE
*ExpressionOpCode
;
824 FORM_EXPRESSION
*CurrentExpression
;
831 FORMSET_STORAGE
*Storage
;
832 FORMSET_DEFAULTSTORE
*DefaultStore
;
833 QUESTION_DEFAULT
*CurrentDefault
;
834 QUESTION_OPTION
*CurrentOption
;
837 UINT16 NumberOfStatement
;
838 UINT16 NumberOfExpression
;
839 EFI_IMAGE_ID
*ImageId
;
840 BOOLEAN SuppressForQuestion
;
841 BOOLEAN SuppressForOption
;
842 BOOLEAN InScopeOptionSuppress
;
843 FORM_EXPRESSION
*OptionSuppressExpression
;
844 BOOLEAN InScopeFormSuppress
;
845 FORM_EXPRESSION
*FormSuppressExpression
;
846 UINT16 DepthOfDisable
;
847 BOOLEAN OpCodeDisabled
;
848 BOOLEAN SingleOpCodeExpression
;
849 BOOLEAN InScopeDefault
;
850 EFI_HII_VALUE
*Value
;
852 mInScopeSubtitle
= FALSE
;
853 SuppressForQuestion
= FALSE
;
854 SuppressForOption
= FALSE
;
855 InScopeFormSuppress
= FALSE
;
856 mInScopeSuppress
= FALSE
;
857 InScopeOptionSuppress
= FALSE
;
858 mInScopeGrayOut
= FALSE
;
859 mInScopeDisable
= FALSE
;
861 OpCodeDisabled
= FALSE
;
862 SingleOpCodeExpression
= FALSE
;
863 InScopeDefault
= FALSE
;
864 CurrentExpression
= NULL
;
865 CurrentDefault
= NULL
;
866 CurrentOption
= NULL
;
867 OptionSuppressExpression
= NULL
;
868 FormSuppressExpression
= NULL
;
872 // Get the number of Statements and Expressions
874 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
877 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
878 if (FormSet
->StatementBuffer
== NULL
) {
879 return EFI_OUT_OF_RESOURCES
;
882 mExpressionOpCodeIndex
= 0;
883 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
884 if (FormSet
->ExpressionBuffer
== NULL
) {
885 return EFI_OUT_OF_RESOURCES
;
888 InitializeListHead (&FormSet
->StorageListHead
);
889 InitializeListHead (&FormSet
->DefaultStoreListHead
);
890 InitializeListHead (&FormSet
->FormListHead
);
893 CurrentStatement
= NULL
;
898 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
899 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
901 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
902 OpCodeOffset
+= OpCodeLength
;
903 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
904 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
907 // If scope bit set, push onto scope stack
913 if (OpCodeDisabled
) {
915 // DisableIf Expression is evaluated to be TRUE, try to find its end.
916 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
918 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
920 } else if (Operand
== EFI_IFR_END_OP
) {
921 Status
= PopScope (&ScopeOpCode
);
922 if (EFI_ERROR (Status
)) {
926 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
927 if (DepthOfDisable
== 0) {
928 mInScopeDisable
= FALSE
;
929 OpCodeDisabled
= FALSE
;
938 if (IsExpressionOpCode (Operand
)) {
939 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
940 mExpressionOpCodeIndex
++;
942 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
943 ExpressionOpCode
->Operand
= Operand
;
944 Value
= &ExpressionOpCode
->Value
;
947 case EFI_IFR_EQ_ID_VAL_OP
:
948 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
950 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
951 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
954 case EFI_IFR_EQ_ID_ID_OP
:
955 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
956 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
959 case EFI_IFR_EQ_ID_LIST_OP
:
960 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
961 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
962 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
965 case EFI_IFR_TO_STRING_OP
:
966 case EFI_IFR_FIND_OP
:
967 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
970 case EFI_IFR_STRING_REF1_OP
:
971 Value
->Type
= EFI_IFR_TYPE_STRING
;
972 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
975 case EFI_IFR_RULE_REF_OP
:
976 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
979 case EFI_IFR_SPAN_OP
:
980 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
983 case EFI_IFR_THIS_OP
:
984 ASSERT (CurrentStatement
!= NULL
);
985 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
988 case EFI_IFR_SECURITY_OP
:
989 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
992 case EFI_IFR_QUESTION_REF1_OP
:
993 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
996 case EFI_IFR_QUESTION_REF3_OP
:
997 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
998 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1000 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1001 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1009 case EFI_IFR_TRUE_OP
:
1010 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1011 Value
->Value
.b
= TRUE
;
1014 case EFI_IFR_FALSE_OP
:
1015 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1016 Value
->Value
.b
= FALSE
;
1019 case EFI_IFR_ONE_OP
:
1020 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1021 Value
->Value
.u8
= 1;
1024 case EFI_IFR_ZERO_OP
:
1025 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1026 Value
->Value
.u8
= 0;
1029 case EFI_IFR_ONES_OP
:
1030 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1031 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1034 case EFI_IFR_UINT8_OP
:
1035 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1036 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1039 case EFI_IFR_UINT16_OP
:
1040 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1041 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1044 case EFI_IFR_UINT32_OP
:
1045 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1046 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1049 case EFI_IFR_UINT64_OP
:
1050 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1051 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1054 case EFI_IFR_UNDEFINED_OP
:
1055 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1058 case EFI_IFR_VERSION_OP
:
1059 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1060 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1067 ASSERT (CurrentExpression
!= NULL
);
1068 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1070 if (SingleOpCodeExpression
) {
1072 // There are two cases to indicate the end of an Expression:
1073 // for single OpCode expression: one Expression OpCode
1074 // for expression consists of more than one OpCode: EFI_IFR_END
1076 SingleOpCodeExpression
= FALSE
;
1078 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1080 // This is DisableIf expression for Form, it should be a constant expression
1082 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1083 if (EFI_ERROR (Status
)) {
1087 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1088 return EFI_INVALID_PARAMETER
;
1091 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1094 CurrentExpression
= NULL
;
1105 case EFI_IFR_FORM_SET_OP
:
1107 // Check the formset GUID
1109 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1110 return EFI_INVALID_PARAMETER
;
1113 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1114 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1116 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1118 // The formset OpCode contains ClassGuid
1120 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1121 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1124 InitializeListHead (&FormSet
->ExpressionListHead
);
1127 case EFI_IFR_FORM_OP
:
1129 // Create a new Form for this FormSet
1131 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1132 ASSERT (CurrentForm
!= NULL
);
1133 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1134 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1135 InitializeListHead (&CurrentForm
->StatementListHead
);
1137 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1138 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1140 if (InScopeFormSuppress
) {
1142 // Form is inside of suppressif
1144 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1149 // Enter scope of a Form, suppressif will be used for Question or Option
1151 SuppressForQuestion
= TRUE
;
1155 // Insert into Form list of this FormSet
1157 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1163 case EFI_IFR_VARSTORE_OP
:
1165 // Create a buffer Storage for this FormSet
1167 Storage
= CreateStorage (FormSet
);
1168 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1170 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1171 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1172 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1174 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1175 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1177 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1178 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1179 ASSERT (Storage
->Name
!= NULL
);
1180 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1181 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1185 // Initialize <ConfigHdr>
1187 InitializeConfigHdr (FormSet
, Storage
);
1190 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1192 // Create a name/value Storage for this FormSet
1194 Storage
= CreateStorage (FormSet
);
1195 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1197 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1198 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1201 // Initialize <ConfigHdr>
1203 InitializeConfigHdr (FormSet
, Storage
);
1206 case EFI_IFR_VARSTORE_EFI_OP
:
1208 // Create a EFI variable Storage for this FormSet
1210 Storage
= CreateStorage (FormSet
);
1211 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1213 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1214 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1215 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1221 case EFI_IFR_DEFAULTSTORE_OP
:
1222 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1223 ASSERT (DefaultStore
!= NULL
);
1224 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1226 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1227 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1230 // Insert to DefaultStore list of this Formset
1232 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1238 case EFI_IFR_SUBTITLE_OP
:
1239 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1240 ASSERT (CurrentStatement
!= NULL
);
1242 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1245 mInScopeSubtitle
= TRUE
;
1249 case EFI_IFR_TEXT_OP
:
1250 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1251 ASSERT (CurrentStatement
!= NULL
);
1253 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1256 case EFI_IFR_RESET_BUTTON_OP
:
1257 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1258 ASSERT (CurrentStatement
!= NULL
);
1259 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1265 case EFI_IFR_ACTION_OP
:
1266 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1267 ASSERT (CurrentStatement
!= NULL
);
1268 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1270 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1272 // No QuestionConfig present, so no configuration string will be processed
1274 CurrentStatement
->QuestionConfig
= 0;
1276 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1280 case EFI_IFR_REF_OP
:
1281 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1282 ASSERT (CurrentStatement
!= NULL
);
1283 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_UNDEFINED
;
1284 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1285 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1286 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1288 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1289 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1291 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1292 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1298 case EFI_IFR_ONE_OF_OP
:
1299 case EFI_IFR_NUMERIC_OP
:
1300 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1301 ASSERT(CurrentStatement
!= NULL
);
1303 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1304 Value
= &CurrentStatement
->HiiValue
;
1306 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1307 case EFI_IFR_NUMERIC_SIZE_1
:
1308 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1309 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1310 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1311 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1312 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1315 case EFI_IFR_NUMERIC_SIZE_2
:
1316 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1317 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1318 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1319 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1320 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1323 case EFI_IFR_NUMERIC_SIZE_4
:
1324 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1325 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1326 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1327 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1328 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1331 case EFI_IFR_NUMERIC_SIZE_8
:
1332 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1333 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1334 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1335 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1336 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1343 InitializeRequestElement (FormSet
, CurrentStatement
);
1345 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1346 SuppressForOption
= TRUE
;
1350 case EFI_IFR_ORDERED_LIST_OP
:
1351 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1352 ASSERT(CurrentStatement
!= NULL
);
1354 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1355 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1357 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1358 CurrentStatement
->BufferValue
= NULL
;
1361 SuppressForOption
= TRUE
;
1365 case EFI_IFR_CHECKBOX_OP
:
1366 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1367 ASSERT(CurrentStatement
!= NULL
);
1369 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1370 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1371 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1373 InitializeRequestElement (FormSet
, CurrentStatement
);
1377 case EFI_IFR_STRING_OP
:
1378 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1379 ASSERT (CurrentStatement
!= NULL
);
1381 // MinSize is the minimum number of characters that can be accepted for this opcode,
1382 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1383 // The characters are stored as Unicode, so the storage width should multiply 2.
1385 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1386 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1387 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1388 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1390 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1391 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1393 InitializeRequestElement (FormSet
, CurrentStatement
);
1396 case EFI_IFR_PASSWORD_OP
:
1397 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1398 ASSERT (CurrentStatement
!= NULL
);
1400 // MinSize is the minimum number of characters that can be accepted for this opcode,
1401 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1402 // The characters are stored as Unicode, so the storage width should multiply 2.
1404 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1405 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1406 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1408 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1409 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1411 InitializeRequestElement (FormSet
, CurrentStatement
);
1414 case EFI_IFR_DATE_OP
:
1415 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1416 ASSERT(CurrentStatement
!= NULL
);
1418 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1419 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1421 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1422 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1424 InitializeRequestElement (FormSet
, CurrentStatement
);
1427 // Don't assign storage for RTC type of date/time
1429 CurrentStatement
->Storage
= NULL
;
1430 CurrentStatement
->StorageWidth
= 0;
1434 case EFI_IFR_TIME_OP
:
1435 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1436 ASSERT(CurrentStatement
!= NULL
);
1438 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1439 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1441 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1442 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1444 InitializeRequestElement (FormSet
, CurrentStatement
);
1447 // Don't assign storage for RTC type of date/time
1449 CurrentStatement
->Storage
= NULL
;
1450 CurrentStatement
->StorageWidth
= 0;
1457 case EFI_IFR_DEFAULT_OP
:
1459 // EFI_IFR_DEFAULT appear in scope of a Question,
1460 // It creates a default value for the current question.
1461 // A Question may have more than one Default value which have different default types.
1463 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1464 ASSERT (CurrentDefault
!= NULL
);
1465 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1467 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1468 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1469 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1470 ExtendValueToU64 (&CurrentDefault
->Value
);
1473 // Insert to Default Value list of current Question
1475 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1478 InScopeDefault
= TRUE
;
1485 case EFI_IFR_ONE_OF_OPTION_OP
:
1487 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1488 // It create a selection for use in current Question.
1490 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1491 ASSERT (CurrentOption
!= NULL
);
1492 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1494 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1495 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1496 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1497 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1498 ExtendValueToU64 (&CurrentOption
->Value
);
1500 if (InScopeOptionSuppress
) {
1501 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1505 // Insert to Option list of current Question
1507 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1510 // Now we know the Storage width of nested Ordered List
1512 ASSERT (CurrentStatement
!= NULL
);
1513 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1515 switch (CurrentOption
->Value
.Type
) {
1516 case EFI_IFR_TYPE_NUM_SIZE_8
:
1520 case EFI_IFR_TYPE_NUM_SIZE_16
:
1524 case EFI_IFR_TYPE_NUM_SIZE_32
:
1528 case EFI_IFR_TYPE_NUM_SIZE_64
:
1534 // Invalid type for Ordered List
1539 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1540 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1541 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1543 InitializeRequestElement (FormSet
, CurrentStatement
);
1550 case EFI_IFR_NO_SUBMIT_IF_OP
:
1551 case EFI_IFR_INCONSISTENT_IF_OP
:
1553 // Create an Expression node
1555 CurrentExpression
= CreateExpression (CurrentForm
);
1556 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1558 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1559 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1560 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1562 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1563 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1567 // Take a look at next OpCode to see whether current expression consists
1570 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1571 SingleOpCodeExpression
= TRUE
;
1575 case EFI_IFR_SUPPRESS_IF_OP
:
1577 // Question and Option will appear in scope of this OpCode
1579 CurrentExpression
= CreateExpression (CurrentForm
);
1580 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1582 if (CurrentForm
== NULL
) {
1583 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1585 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1588 if (SuppressForOption
) {
1589 InScopeOptionSuppress
= TRUE
;
1590 OptionSuppressExpression
= CurrentExpression
;
1591 } else if (SuppressForQuestion
) {
1592 mInScopeSuppress
= TRUE
;
1593 mSuppressExpression
= CurrentExpression
;
1595 InScopeFormSuppress
= TRUE
;
1596 FormSuppressExpression
= CurrentExpression
;
1600 // Take a look at next OpCode to see whether current expression consists
1603 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1604 SingleOpCodeExpression
= TRUE
;
1608 case EFI_IFR_GRAY_OUT_IF_OP
:
1610 // Questions will appear in scope of this OpCode
1612 CurrentExpression
= CreateExpression (CurrentForm
);
1613 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1614 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1616 mInScopeGrayOut
= TRUE
;
1617 mGrayOutExpression
= CurrentExpression
;
1620 // Take a look at next OpCode to see whether current expression consists
1623 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1624 SingleOpCodeExpression
= TRUE
;
1628 case EFI_IFR_DISABLE_IF_OP
:
1630 // The DisableIf expression should only rely on constant, so it could be
1631 // evaluated at initialization and it will not be queued
1633 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1634 ASSERT (CurrentExpression
!= NULL
);
1635 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1636 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1637 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1639 if (CurrentForm
!= NULL
) {
1641 // This is DisableIf for Question, enqueue it to Form expression list
1643 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1646 mDisableExpression
= CurrentExpression
;
1647 mInScopeDisable
= TRUE
;
1648 OpCodeDisabled
= FALSE
;
1651 // Take a look at next OpCode to see whether current expression consists
1654 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1655 SingleOpCodeExpression
= TRUE
;
1662 case EFI_IFR_VALUE_OP
:
1663 CurrentExpression
= CreateExpression (CurrentForm
);
1664 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1665 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1667 if (InScopeDefault
) {
1669 // Used for default (EFI_IFR_DEFAULT)
1671 CurrentDefault
->ValueExpression
= CurrentExpression
;
1674 // If used for a question, then the question will be read-only
1677 // Make sure CurrentStatement is not NULL.
1678 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1679 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1681 ASSERT (CurrentStatement
!= NULL
);
1682 CurrentStatement
->ValueExpression
= CurrentExpression
;
1686 // Take a look at next OpCode to see whether current expression consists
1689 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1690 SingleOpCodeExpression
= TRUE
;
1694 case EFI_IFR_RULE_OP
:
1695 CurrentExpression
= CreateExpression (CurrentForm
);
1696 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1698 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1699 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1702 // Take a look at next OpCode to see whether current expression consists
1705 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1706 SingleOpCodeExpression
= TRUE
;
1713 case EFI_IFR_IMAGE_OP
:
1715 // Get ScopeOpcode from top of stack
1717 PopScope (&ScopeOpCode
);
1718 PushScope (ScopeOpCode
);
1720 switch (ScopeOpCode
) {
1721 case EFI_IFR_FORM_SET_OP
:
1722 ImageId
= &FormSet
->ImageId
;
1725 case EFI_IFR_FORM_OP
:
1726 ASSERT (CurrentForm
!= NULL
);
1727 ImageId
= &CurrentForm
->ImageId
;
1730 case EFI_IFR_ONE_OF_OPTION_OP
:
1731 ImageId
= &CurrentOption
->ImageId
;
1736 // Make sure CurrentStatement is not NULL.
1737 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1738 // file is wrongly generated by tools such as VFR Compiler.
1740 ASSERT (CurrentStatement
!= NULL
);
1741 ImageId
= &CurrentStatement
->ImageId
;
1745 ASSERT (ImageId
!= NULL
);
1746 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1752 case EFI_IFR_REFRESH_OP
:
1753 ASSERT (CurrentStatement
!= NULL
);
1754 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1760 case EFI_IFR_GUID_OP
:
1761 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1763 // Tiano specific GUIDed opcodes
1765 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1766 case EFI_IFR_EXTEND_OP_LABEL
:
1768 // just ignore label
1772 case EFI_IFR_EXTEND_OP_BANNER
:
1774 // By SubClass to get Banner Data from Front Page
1776 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1778 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1779 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1780 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1781 sizeof (EFI_STRING_ID
)
1786 case EFI_IFR_EXTEND_OP_CLASS
:
1787 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1790 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1791 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1804 case EFI_IFR_END_OP
:
1805 Status
= PopScope (&ScopeOpCode
);
1806 if (EFI_ERROR (Status
)) {
1811 switch (ScopeOpCode
) {
1812 case EFI_IFR_FORM_SET_OP
:
1814 // End of FormSet, update FormSet IFR binary length
1815 // to stop parsing substantial OpCodes
1817 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1820 case EFI_IFR_FORM_OP
:
1825 SuppressForQuestion
= FALSE
;
1828 case EFI_IFR_ONE_OF_OPTION_OP
:
1832 CurrentOption
= NULL
;
1835 case EFI_IFR_SUBTITLE_OP
:
1836 mInScopeSubtitle
= FALSE
;
1839 case EFI_IFR_NO_SUBMIT_IF_OP
:
1840 case EFI_IFR_INCONSISTENT_IF_OP
:
1842 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1846 case EFI_IFR_SUPPRESS_IF_OP
:
1847 if (SuppressForOption
) {
1848 InScopeOptionSuppress
= FALSE
;
1849 } else if (SuppressForQuestion
) {
1850 mInScopeSuppress
= FALSE
;
1852 InScopeFormSuppress
= FALSE
;
1856 case EFI_IFR_GRAY_OUT_IF_OP
:
1857 mInScopeGrayOut
= FALSE
;
1860 case EFI_IFR_DISABLE_IF_OP
:
1861 mInScopeDisable
= FALSE
;
1862 OpCodeDisabled
= FALSE
;
1865 case EFI_IFR_ONE_OF_OP
:
1866 case EFI_IFR_ORDERED_LIST_OP
:
1867 SuppressForOption
= FALSE
;
1870 case EFI_IFR_DEFAULT_OP
:
1871 InScopeDefault
= FALSE
;
1875 if (IsExpressionOpCode (ScopeOpCode
)) {
1876 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1878 // This is DisableIf expression for Form, it should be a constant expression
1880 ASSERT (CurrentExpression
!= NULL
);
1881 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1882 if (EFI_ERROR (Status
)) {
1886 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1887 return EFI_INVALID_PARAMETER
;
1890 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1892 // DisableIf Expression is only used once and not quequed, free it
1894 DestroyExpression (CurrentExpression
);
1898 // End of current Expression
1900 CurrentExpression
= NULL
;