2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2009, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 UINT16 mStatementIndex
;
19 UINT16 mExpressionOpCodeIndex
;
21 BOOLEAN mInScopeSubtitle
;
22 BOOLEAN mInScopeSuppress
;
23 BOOLEAN mInScopeGrayOut
;
24 BOOLEAN mInScopeDisable
;
25 FORM_EXPRESSION
*mSuppressExpression
;
26 FORM_EXPRESSION
*mGrayOutExpression
;
27 FORM_EXPRESSION
*mDisableExpression
;
30 Initialize Statement header members.
32 @param OpCodeData Pointer of the raw OpCode data.
33 @param FormSet Pointer of the current FormSe.
34 @param Form Pointer of the current Form.
36 @return The Statement.
39 FORM_BROWSER_STATEMENT
*
42 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
43 IN OUT FORM_BROWSER_FORM
*Form
46 FORM_BROWSER_STATEMENT
*Statement
;
47 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
51 // We are currently not in a Form Scope, so just skip this Statement
56 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
59 InitializeListHead (&Statement
->DefaultListHead
);
60 InitializeListHead (&Statement
->OptionListHead
);
61 InitializeListHead (&Statement
->InconsistentListHead
);
62 InitializeListHead (&Statement
->NoSubmitListHead
);
64 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
66 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
68 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
69 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
70 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
72 if (mInScopeSuppress
) {
73 Statement
->SuppressExpression
= mSuppressExpression
;
76 if (mInScopeGrayOut
) {
77 Statement
->GrayOutExpression
= mGrayOutExpression
;
81 if (mInScopeDisable
) {
82 Statement
->DisableExpression
= mDisableExpression
;
85 Statement
->InSubtitle
= mInScopeSubtitle
;
88 // Insert this Statement into current Form
90 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
96 Convert a numeric value to a Unicode String and insert it to String Package.
97 This string is used as the Unicode Name for the EFI Variable. This is to support
98 the deprecated vareqval opcode.
100 @param FormSet The FormSet.
101 @param Statement The numeric question whose VarStoreInfo.VarName is the
102 numeric value which is used to produce the Unicode Name
103 for the EFI Variable.
105 If the Statement is NULL, the ASSERT.
106 If the opcode is not Numeric, then ASSERT.
108 @retval EFI_SUCCESS The funtion always succeeds.
111 UpdateCheckBoxStringToken (
112 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
113 IN FORM_BROWSER_STATEMENT
*Statement
116 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
119 ASSERT (Statement
!= NULL
);
120 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
122 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
124 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
126 return EFI_OUT_OF_RESOURCES
;
129 Statement
->VarStoreInfo
.VarName
= Id
;
135 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
137 @param OpCodeData The current opcode.
143 IsNextOpCodeGuidedVarEqName (
150 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
151 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
152 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
154 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
156 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
166 Initialize Question's members.
168 @param OpCodeData Pointer of the raw OpCode data.
169 @param FormSet Pointer of the current FormSet.
170 @param Form Pointer of the current Form.
172 @return The Question.
175 FORM_BROWSER_STATEMENT
*
177 IN UINT8
*OpCodeData
,
178 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
179 IN OUT FORM_BROWSER_FORM
*Form
182 FORM_BROWSER_STATEMENT
*Statement
;
183 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
185 FORMSET_STORAGE
*Storage
;
186 NAME_VALUE_NODE
*NameValueNode
;
189 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
190 if (Statement
== NULL
) {
194 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
195 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
196 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
197 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
199 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
201 if (Statement
->VarStoreId
== 0) {
203 // VarStoreId of zero indicates no variable storage
209 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
210 // Framework Compatibility
212 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
213 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
214 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
215 if (EFI_ERROR (Status
)) {
222 // Find Storage for this Question
224 Link
= GetFirstNode (&FormSet
->StorageListHead
);
225 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
226 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
228 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
229 Statement
->Storage
= Storage
;
233 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
235 ASSERT (Statement
->Storage
!= NULL
);
238 // Initialilze varname for Name/Value or EFI Variable
240 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
241 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
242 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
243 ASSERT (Statement
->VariableName
!= NULL
);
245 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
247 // Insert to Name/Value varstore list
249 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
250 ASSERT (NameValueNode
!= NULL
);
251 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
252 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
253 ASSERT (NameValueNode
->Name
!= NULL
);
254 NameValueNode
->Value
= AllocateZeroPool (0x10);
255 ASSERT (NameValueNode
->Value
!= NULL
);
256 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
257 ASSERT (NameValueNode
->EditValue
!= NULL
);
259 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
268 Allocate a FORM_EXPRESSION node.
270 @param Form The Form associated with this Expression
272 @return Pointer to a FORM_EXPRESSION data structure.
277 IN OUT FORM_BROWSER_FORM
*Form
280 FORM_EXPRESSION
*Expression
;
282 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
283 ASSERT (Expression
!= NULL
);
284 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
285 InitializeListHead (&Expression
->OpCodeListHead
);
292 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
294 @param FormSet Pointer of the current FormSet
296 @return Pointer to a FORMSET_STORAGE data structure.
301 IN FORM_BROWSER_FORMSET
*FormSet
304 FORMSET_STORAGE
*Storage
;
306 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
307 ASSERT (Storage
!= NULL
);
308 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
309 InitializeListHead (&Storage
->NameValueListHead
);
310 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
317 Create ConfigHdr string for a storage.
319 @param FormSet Pointer of the current FormSet
320 @param Storage Pointer of the storage
322 @retval EFI_SUCCESS Initialize ConfigHdr success
326 InitializeConfigHdr (
327 IN FORM_BROWSER_FORMSET
*FormSet
,
328 IN OUT FORMSET_STORAGE
*Storage
333 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
334 Name
= Storage
->Name
;
339 Storage
->ConfigHdr
= HiiConstructConfigHdr (
342 FormSet
->DriverHandle
345 if (Storage
->ConfigHdr
== NULL
) {
346 return EFI_NOT_FOUND
;
349 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
350 Storage
->SpareStrLen
= 0;
357 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
359 @param FormSet Pointer of the current FormSet.
360 @param Question The Question to be initialized.
362 @retval EFI_SUCCESS Function success.
363 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
367 InitializeRequestElement (
368 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
369 IN OUT FORM_BROWSER_STATEMENT
*Question
372 FORMSET_STORAGE
*Storage
;
376 CHAR16 RequestElement
[30];
378 Storage
= Question
->Storage
;
379 if (Storage
== NULL
) {
380 return EFI_INVALID_PARAMETER
;
383 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
385 // <ConfigRequest> is unnecessary for EFI variable storage,
386 // GetVariable()/SetVariable() will be used to retrieve/save values
392 // Prepare <RequestElement>
394 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
395 StrLen
= UnicodeSPrint (
397 30 * sizeof (CHAR16
),
398 L
"&OFFSET=%x&WIDTH=%x",
399 Question
->VarStoreInfo
.VarOffset
,
400 Question
->StorageWidth
402 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
404 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
407 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
409 // Password with CALLBACK flag is stored in encoded format,
410 // so don't need to append it to <ConfigRequest>
416 // Append <RequestElement> to <ConfigRequest>
418 if (StrLen
> Storage
->SpareStrLen
) {
420 // Old String buffer is not sufficient for RequestElement, allocate a new one
422 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
423 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
424 ASSERT (NewStr
!= NULL
);
425 if (Storage
->ConfigRequest
!= NULL
) {
426 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
427 FreePool (Storage
->ConfigRequest
);
429 Storage
->ConfigRequest
= NewStr
;
430 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
433 StrCat (Storage
->ConfigRequest
, RequestElement
);
434 Storage
->ElementCount
++;
435 Storage
->SpareStrLen
-= StrLen
;
442 Free resources of a Expression.
444 @param FormSet Pointer of the Expression
449 IN FORM_EXPRESSION
*Expression
453 EXPRESSION_OPCODE
*OpCode
;
455 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
456 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
457 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
458 RemoveEntryList (&OpCode
->Link
);
460 if (OpCode
->ValueList
!= NULL
) {
461 FreePool (OpCode
->ValueList
);
466 // Free this Expression
468 FreePool (Expression
);
473 Free resources of a storage.
475 @param Storage Pointer of the storage
480 IN FORMSET_STORAGE
*Storage
484 NAME_VALUE_NODE
*NameValueNode
;
486 if (Storage
== NULL
) {
490 if (Storage
->Name
!= NULL
) {
491 FreePool (Storage
->Name
);
493 if (Storage
->Buffer
!= NULL
) {
494 FreePool (Storage
->Buffer
);
496 if (Storage
->EditBuffer
!= NULL
) {
497 FreePool (Storage
->EditBuffer
);
500 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
501 Link
= GetFirstNode (&Storage
->NameValueListHead
);
502 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
503 RemoveEntryList (&NameValueNode
->Link
);
505 if (NameValueNode
->Name
!= NULL
) {
506 FreePool (NameValueNode
->Name
);
508 if (NameValueNode
->Value
!= NULL
) {
509 FreePool (NameValueNode
->Value
);
511 if (NameValueNode
->EditValue
!= NULL
) {
512 FreePool (NameValueNode
->EditValue
);
514 FreePool (NameValueNode
);
517 if (Storage
->ConfigHdr
!= NULL
) {
518 FreePool (Storage
->ConfigHdr
);
520 if (Storage
->ConfigRequest
!= NULL
) {
521 FreePool (Storage
->ConfigRequest
);
529 Free resources of a Statement.
531 @param Statement Pointer of the Statement
536 IN OUT FORM_BROWSER_STATEMENT
*Statement
540 QUESTION_DEFAULT
*Default
;
541 QUESTION_OPTION
*Option
;
542 FORM_EXPRESSION
*Expression
;
545 // Free Default value List
547 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
548 Link
= GetFirstNode (&Statement
->DefaultListHead
);
549 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
550 RemoveEntryList (&Default
->Link
);
558 while (!IsListEmpty (&Statement
->OptionListHead
)) {
559 Link
= GetFirstNode (&Statement
->OptionListHead
);
560 Option
= QUESTION_OPTION_FROM_LINK (Link
);
561 RemoveEntryList (&Option
->Link
);
567 // Free Inconsistent List
569 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
570 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
571 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
572 RemoveEntryList (&Expression
->Link
);
574 DestroyExpression (Expression
);
578 // Free NoSubmit List
580 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
581 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
582 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
583 RemoveEntryList (&Expression
->Link
);
585 DestroyExpression (Expression
);
588 if (Statement
->VariableName
!= NULL
) {
589 FreePool (Statement
->VariableName
);
591 if (Statement
->BlockName
!= NULL
) {
592 FreePool (Statement
->BlockName
);
598 Free resources of a Form.
600 @param Form Pointer of the Form.
605 IN OUT FORM_BROWSER_FORM
*Form
609 FORM_EXPRESSION
*Expression
;
610 FORM_BROWSER_STATEMENT
*Statement
;
613 // Free Form Expressions
615 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
616 Link
= GetFirstNode (&Form
->ExpressionListHead
);
617 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
618 RemoveEntryList (&Expression
->Link
);
620 DestroyExpression (Expression
);
624 // Free Statements/Questions
626 while (!IsListEmpty (&Form
->StatementListHead
)) {
627 Link
= GetFirstNode (&Form
->StatementListHead
);
628 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
629 RemoveEntryList (&Statement
->Link
);
631 DestroyStatement (Statement
);
642 Free resources allocated for a FormSet.
644 @param FormSet Pointer of the FormSet
649 IN OUT FORM_BROWSER_FORMSET
*FormSet
653 FORMSET_STORAGE
*Storage
;
654 FORMSET_DEFAULTSTORE
*DefaultStore
;
655 FORM_EXPRESSION
*Expression
;
656 FORM_BROWSER_FORM
*Form
;
659 // Free IFR binary buffer
661 FreePool (FormSet
->IfrBinaryData
);
664 // Free FormSet Storage
666 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
667 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
668 Link
= GetFirstNode (&FormSet
->StorageListHead
);
669 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
670 RemoveEntryList (&Storage
->Link
);
672 DestroyStorage (Storage
);
677 // Free FormSet Default Store
679 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
680 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
681 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
682 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
683 RemoveEntryList (&DefaultStore
->Link
);
685 FreePool (DefaultStore
);
690 // Free Formset Expressions
692 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
693 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
694 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
695 RemoveEntryList (&Expression
->Link
);
697 DestroyExpression (Expression
);
703 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
704 while (!IsListEmpty (&FormSet
->FormListHead
)) {
705 Link
= GetFirstNode (&FormSet
->FormListHead
);
706 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
707 RemoveEntryList (&Form
->Link
);
713 if (FormSet
->StatementBuffer
!= NULL
) {
714 FreePool (FormSet
->StatementBuffer
);
716 if (FormSet
->ExpressionBuffer
!= NULL
) {
717 FreePool (FormSet
->ExpressionBuffer
);
725 Tell whether this Operand is an Expression OpCode or not
727 @param Operand Operand of an IFR OpCode.
729 @retval TRUE This is an Expression OpCode.
730 @retval FALSE Not an Expression OpCode.
738 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
739 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
740 (Operand
== EFI_IFR_CATENATE_OP
) ||
741 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
742 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
743 (Operand
== EFI_IFR_VERSION_OP
)
753 Calculate number of Statemens(Questions) and Expression OpCodes.
755 @param FormSet The FormSet to be counted.
756 @param NumberOfStatement Number of Statemens(Questions)
757 @param NumberOfExpression Number of Expression OpCodes
762 IN FORM_BROWSER_FORMSET
*FormSet
,
763 IN OUT UINT16
*NumberOfStatement
,
764 IN OUT UINT16
*NumberOfExpression
767 UINT16 StatementCount
;
768 UINT16 ExpressionCount
;
777 while (Offset
< FormSet
->IfrBinaryLength
) {
778 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
779 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
782 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
789 *NumberOfStatement
= StatementCount
;
790 *NumberOfExpression
= ExpressionCount
;
796 Parse opcodes in the formset IFR binary.
798 @param FormSet Pointer of the FormSet data structure.
800 @retval EFI_SUCCESS Opcode parse success.
801 @retval Other Opcode parse fail.
806 IN FORM_BROWSER_FORMSET
*FormSet
811 FORM_BROWSER_FORM
*CurrentForm
;
812 FORM_BROWSER_STATEMENT
*CurrentStatement
;
813 EXPRESSION_OPCODE
*ExpressionOpCode
;
814 FORM_EXPRESSION
*CurrentExpression
;
821 FORMSET_STORAGE
*Storage
;
822 FORMSET_DEFAULTSTORE
*DefaultStore
;
823 QUESTION_DEFAULT
*CurrentDefault
;
824 QUESTION_OPTION
*CurrentOption
;
827 UINT16 NumberOfStatement
;
828 UINT16 NumberOfExpression
;
829 EFI_IMAGE_ID
*ImageId
;
830 BOOLEAN SuppressForQuestion
;
831 BOOLEAN SuppressForOption
;
832 BOOLEAN InScopeOptionSuppress
;
833 FORM_EXPRESSION
*OptionSuppressExpression
;
834 BOOLEAN InScopeFormSuppress
;
835 FORM_EXPRESSION
*FormSuppressExpression
;
836 UINT16 DepthOfDisable
;
837 BOOLEAN OpCodeDisabled
;
838 BOOLEAN SingleOpCodeExpression
;
839 BOOLEAN InScopeDefault
;
840 EFI_HII_VALUE
*Value
;
842 mInScopeSubtitle
= FALSE
;
843 SuppressForQuestion
= FALSE
;
844 SuppressForOption
= FALSE
;
845 InScopeFormSuppress
= FALSE
;
846 mInScopeSuppress
= FALSE
;
847 InScopeOptionSuppress
= FALSE
;
848 mInScopeGrayOut
= FALSE
;
849 mInScopeDisable
= FALSE
;
851 OpCodeDisabled
= FALSE
;
852 SingleOpCodeExpression
= FALSE
;
853 InScopeDefault
= FALSE
;
854 CurrentExpression
= NULL
;
855 CurrentDefault
= NULL
;
856 CurrentOption
= NULL
;
857 OptionSuppressExpression
= NULL
;
858 FormSuppressExpression
= NULL
;
862 // Get the number of Statements and Expressions
864 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
867 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
868 if (FormSet
->StatementBuffer
== NULL
) {
869 return EFI_OUT_OF_RESOURCES
;
872 mExpressionOpCodeIndex
= 0;
873 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
874 if (FormSet
->ExpressionBuffer
== NULL
) {
875 return EFI_OUT_OF_RESOURCES
;
878 InitializeListHead (&FormSet
->StorageListHead
);
879 InitializeListHead (&FormSet
->DefaultStoreListHead
);
880 InitializeListHead (&FormSet
->FormListHead
);
883 CurrentStatement
= NULL
;
888 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
889 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
891 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
892 OpCodeOffset
+= OpCodeLength
;
893 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
894 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
897 // If scope bit set, push onto scope stack
903 if (OpCodeDisabled
) {
905 // DisableIf Expression is evaluated to be TRUE, try to find its end.
906 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
908 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
910 } else if (Operand
== EFI_IFR_END_OP
) {
911 Status
= PopScope (&ScopeOpCode
);
912 if (EFI_ERROR (Status
)) {
916 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
917 if (DepthOfDisable
== 0) {
918 mInScopeDisable
= FALSE
;
919 OpCodeDisabled
= FALSE
;
928 if (IsExpressionOpCode (Operand
)) {
929 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
930 mExpressionOpCodeIndex
++;
932 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
933 ExpressionOpCode
->Operand
= Operand
;
934 Value
= &ExpressionOpCode
->Value
;
937 case EFI_IFR_EQ_ID_VAL_OP
:
938 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
940 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
941 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
944 case EFI_IFR_EQ_ID_ID_OP
:
945 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
946 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
949 case EFI_IFR_EQ_ID_LIST_OP
:
950 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
951 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
952 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
955 case EFI_IFR_TO_STRING_OP
:
956 case EFI_IFR_FIND_OP
:
957 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
960 case EFI_IFR_STRING_REF1_OP
:
961 Value
->Type
= EFI_IFR_TYPE_STRING
;
962 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
965 case EFI_IFR_RULE_REF_OP
:
966 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
969 case EFI_IFR_SPAN_OP
:
970 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
973 case EFI_IFR_THIS_OP
:
974 ASSERT (CurrentStatement
!= NULL
);
975 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
978 case EFI_IFR_QUESTION_REF1_OP
:
979 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
982 case EFI_IFR_QUESTION_REF3_OP
:
983 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
984 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
986 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
987 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
995 case EFI_IFR_TRUE_OP
:
996 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
997 Value
->Value
.b
= TRUE
;
1000 case EFI_IFR_FALSE_OP
:
1001 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1002 Value
->Value
.b
= FALSE
;
1005 case EFI_IFR_ONE_OP
:
1006 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1007 Value
->Value
.u8
= 1;
1010 case EFI_IFR_ZERO_OP
:
1011 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1012 Value
->Value
.u8
= 0;
1015 case EFI_IFR_ONES_OP
:
1016 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1017 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1020 case EFI_IFR_UINT8_OP
:
1021 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1022 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1025 case EFI_IFR_UINT16_OP
:
1026 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1027 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1030 case EFI_IFR_UINT32_OP
:
1031 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1032 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1035 case EFI_IFR_UINT64_OP
:
1036 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1037 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1040 case EFI_IFR_UNDEFINED_OP
:
1041 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1044 case EFI_IFR_VERSION_OP
:
1045 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1046 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1053 ASSERT (CurrentExpression
!= NULL
);
1054 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1056 if (SingleOpCodeExpression
) {
1058 // There are two cases to indicate the end of an Expression:
1059 // for single OpCode expression: one Expression OpCode
1060 // for expression consists of more than one OpCode: EFI_IFR_END
1062 SingleOpCodeExpression
= FALSE
;
1064 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1066 // This is DisableIf expression for Form, it should be a constant expression
1068 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1069 if (EFI_ERROR (Status
)) {
1073 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1074 return EFI_INVALID_PARAMETER
;
1077 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1080 CurrentExpression
= NULL
;
1091 case EFI_IFR_FORM_SET_OP
:
1093 // Check the formset GUID
1095 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1096 return EFI_INVALID_PARAMETER
;
1099 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1100 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1103 // The formset OpCode contains ClassGuid
1105 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1106 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1108 InitializeListHead (&FormSet
->ExpressionListHead
);
1111 case EFI_IFR_FORM_OP
:
1113 // Create a new Form for this FormSet
1115 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1116 ASSERT (CurrentForm
!= NULL
);
1117 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1118 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1119 InitializeListHead (&CurrentForm
->StatementListHead
);
1121 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1122 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1124 if (InScopeFormSuppress
) {
1126 // Form is inside of suppressif
1128 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1133 // Enter scope of a Form, suppressif will be used for Question or Option
1135 SuppressForQuestion
= TRUE
;
1139 // Insert into Form list of this FormSet
1141 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1147 case EFI_IFR_VARSTORE_OP
:
1149 // Create a buffer Storage for this FormSet
1151 Storage
= CreateStorage (FormSet
);
1152 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1154 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1155 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1156 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1158 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1159 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1161 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1162 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1163 ASSERT (Storage
->Name
!= NULL
);
1164 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1165 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1169 // Initialize <ConfigHdr>
1171 InitializeConfigHdr (FormSet
, Storage
);
1174 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1176 // Create a name/value Storage for this FormSet
1178 Storage
= CreateStorage (FormSet
);
1179 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1181 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1182 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1185 // Initialize <ConfigHdr>
1187 InitializeConfigHdr (FormSet
, Storage
);
1190 case EFI_IFR_VARSTORE_EFI_OP
:
1192 // Create a EFI variable Storage for this FormSet
1194 Storage
= CreateStorage (FormSet
);
1195 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1197 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1198 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1199 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1205 case EFI_IFR_DEFAULTSTORE_OP
:
1206 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1207 ASSERT (DefaultStore
!= NULL
);
1208 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1210 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1211 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1214 // Insert to DefaultStore list of this Formset
1216 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1222 case EFI_IFR_SUBTITLE_OP
:
1223 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1224 ASSERT (CurrentStatement
!= NULL
);
1226 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1229 mInScopeSubtitle
= TRUE
;
1233 case EFI_IFR_TEXT_OP
:
1234 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1235 ASSERT (CurrentStatement
!= NULL
);
1237 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1240 case EFI_IFR_RESET_BUTTON_OP
:
1241 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1242 ASSERT (CurrentStatement
!= NULL
);
1243 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1249 case EFI_IFR_ACTION_OP
:
1250 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1251 ASSERT (CurrentStatement
!= NULL
);
1252 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1254 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1256 // No QuestionConfig present, so no configuration string will be processed
1258 CurrentStatement
->QuestionConfig
= 0;
1260 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1264 case EFI_IFR_REF_OP
:
1265 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1266 ASSERT (CurrentStatement
!= NULL
);
1267 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_UNDEFINED
;
1268 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1269 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1270 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1272 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1273 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1275 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1276 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1282 case EFI_IFR_ONE_OF_OP
:
1283 case EFI_IFR_NUMERIC_OP
:
1284 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1285 ASSERT(CurrentStatement
!= NULL
);
1287 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1288 Value
= &CurrentStatement
->HiiValue
;
1290 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1291 case EFI_IFR_NUMERIC_SIZE_1
:
1292 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1293 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1294 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1295 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1296 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1299 case EFI_IFR_NUMERIC_SIZE_2
:
1300 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1301 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1302 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1303 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1304 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1307 case EFI_IFR_NUMERIC_SIZE_4
:
1308 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1309 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1310 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1311 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1312 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1315 case EFI_IFR_NUMERIC_SIZE_8
:
1316 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1317 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1318 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1319 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1320 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1327 InitializeRequestElement (FormSet
, CurrentStatement
);
1329 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1330 SuppressForOption
= TRUE
;
1334 case EFI_IFR_ORDERED_LIST_OP
:
1335 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1336 ASSERT(CurrentStatement
!= NULL
);
1338 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1339 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1341 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1344 SuppressForOption
= TRUE
;
1348 case EFI_IFR_CHECKBOX_OP
:
1349 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1350 ASSERT(CurrentStatement
!= NULL
);
1352 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1353 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1354 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1356 InitializeRequestElement (FormSet
, CurrentStatement
);
1360 case EFI_IFR_STRING_OP
:
1361 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1362 ASSERT (CurrentStatement
!= NULL
);
1364 // MinSize is the minimum number of characters that can be accepted for this opcode,
1365 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1366 // The characters are stored as Unicode, so the storage width should multiply 2.
1368 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1369 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1370 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1371 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1373 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1374 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1376 InitializeRequestElement (FormSet
, CurrentStatement
);
1379 case EFI_IFR_PASSWORD_OP
:
1380 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1381 ASSERT (CurrentStatement
!= NULL
);
1383 // MinSize is the minimum number of characters that can be accepted for this opcode,
1384 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1385 // The characters are stored as Unicode, so the storage width should multiply 2.
1387 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1388 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1389 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1391 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1392 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1394 InitializeRequestElement (FormSet
, CurrentStatement
);
1397 case EFI_IFR_DATE_OP
:
1398 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1399 ASSERT(CurrentStatement
!= NULL
);
1401 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1402 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1404 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1405 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1407 InitializeRequestElement (FormSet
, CurrentStatement
);
1410 // Don't assign storage for RTC type of date/time
1412 CurrentStatement
->Storage
= NULL
;
1413 CurrentStatement
->StorageWidth
= 0;
1417 case EFI_IFR_TIME_OP
:
1418 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1419 ASSERT(CurrentStatement
!= NULL
);
1421 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1422 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1424 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1425 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1427 InitializeRequestElement (FormSet
, CurrentStatement
);
1430 // Don't assign storage for RTC type of date/time
1432 CurrentStatement
->Storage
= NULL
;
1433 CurrentStatement
->StorageWidth
= 0;
1440 case EFI_IFR_DEFAULT_OP
:
1442 // EFI_IFR_DEFAULT appear in scope of a Question,
1443 // It creates a default value for the current question.
1444 // A Question may have more than one Default value which have different default types.
1446 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1447 ASSERT (CurrentDefault
!= NULL
);
1448 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1450 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1451 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1452 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1453 ExtendValueToU64 (&CurrentDefault
->Value
);
1456 // Insert to Default Value list of current Question
1458 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1461 InScopeDefault
= TRUE
;
1468 case EFI_IFR_ONE_OF_OPTION_OP
:
1470 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1471 // It create a selection for use in current Question.
1473 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1474 ASSERT (CurrentOption
!= NULL
);
1475 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1477 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1478 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1479 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1480 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1481 ExtendValueToU64 (&CurrentOption
->Value
);
1483 if (InScopeOptionSuppress
) {
1484 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1488 // Insert to Option list of current Question
1490 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1493 // Now we know the Storage width of nested Ordered List
1495 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1497 switch (CurrentOption
->Value
.Type
) {
1498 case EFI_IFR_TYPE_NUM_SIZE_8
:
1502 case EFI_IFR_TYPE_NUM_SIZE_16
:
1506 case EFI_IFR_TYPE_NUM_SIZE_32
:
1510 case EFI_IFR_TYPE_NUM_SIZE_64
:
1516 // Invalid type for Ordered List
1521 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1522 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1523 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1525 InitializeRequestElement (FormSet
, CurrentStatement
);
1532 case EFI_IFR_NO_SUBMIT_IF_OP
:
1533 case EFI_IFR_INCONSISTENT_IF_OP
:
1535 // Create an Expression node
1537 CurrentExpression
= CreateExpression (CurrentForm
);
1538 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1540 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1541 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1542 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1544 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1545 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1549 // Take a look at next OpCode to see whether current expression consists
1552 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1553 SingleOpCodeExpression
= TRUE
;
1557 case EFI_IFR_SUPPRESS_IF_OP
:
1559 // Question and Option will appear in scope of this OpCode
1561 CurrentExpression
= CreateExpression (CurrentForm
);
1562 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1564 if (CurrentForm
== NULL
) {
1565 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1567 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1570 if (SuppressForOption
) {
1571 InScopeOptionSuppress
= TRUE
;
1572 OptionSuppressExpression
= CurrentExpression
;
1573 } else if (SuppressForQuestion
) {
1574 mInScopeSuppress
= TRUE
;
1575 mSuppressExpression
= CurrentExpression
;
1577 InScopeFormSuppress
= TRUE
;
1578 FormSuppressExpression
= CurrentExpression
;
1582 // Take a look at next OpCode to see whether current expression consists
1585 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1586 SingleOpCodeExpression
= TRUE
;
1590 case EFI_IFR_GRAY_OUT_IF_OP
:
1592 // Questions will appear in scope of this OpCode
1594 CurrentExpression
= CreateExpression (CurrentForm
);
1595 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1596 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1598 mInScopeGrayOut
= TRUE
;
1599 mGrayOutExpression
= CurrentExpression
;
1602 // Take a look at next OpCode to see whether current expression consists
1605 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1606 SingleOpCodeExpression
= TRUE
;
1610 case EFI_IFR_DISABLE_IF_OP
:
1612 // The DisableIf expression should only rely on constant, so it could be
1613 // evaluated at initialization and it will not be queued
1615 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1616 ASSERT (CurrentExpression
!= NULL
);
1617 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1618 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1619 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1621 if (CurrentForm
!= NULL
) {
1623 // This is DisableIf for Question, enqueue it to Form expression list
1625 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1628 mDisableExpression
= CurrentExpression
;
1629 mInScopeDisable
= TRUE
;
1630 OpCodeDisabled
= FALSE
;
1633 // Take a look at next OpCode to see whether current expression consists
1636 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1637 SingleOpCodeExpression
= TRUE
;
1644 case EFI_IFR_VALUE_OP
:
1645 CurrentExpression
= CreateExpression (CurrentForm
);
1646 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1647 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1649 if (InScopeDefault
) {
1651 // Used for default (EFI_IFR_DEFAULT)
1653 CurrentDefault
->ValueExpression
= CurrentExpression
;
1656 // If used for a question, then the question will be read-only
1659 // Make sure CurrentStatement is not NULL.
1660 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1661 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1663 ASSERT (CurrentStatement
!= NULL
);
1664 CurrentStatement
->ValueExpression
= CurrentExpression
;
1668 // Take a look at next OpCode to see whether current expression consists
1671 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1672 SingleOpCodeExpression
= TRUE
;
1676 case EFI_IFR_RULE_OP
:
1677 CurrentExpression
= CreateExpression (CurrentForm
);
1678 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1680 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1681 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1684 // Take a look at next OpCode to see whether current expression consists
1687 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1688 SingleOpCodeExpression
= TRUE
;
1695 case EFI_IFR_IMAGE_OP
:
1697 // Get ScopeOpcode from top of stack
1699 PopScope (&ScopeOpCode
);
1700 PushScope (ScopeOpCode
);
1702 switch (ScopeOpCode
) {
1703 case EFI_IFR_FORM_SET_OP
:
1704 ImageId
= &FormSet
->ImageId
;
1707 case EFI_IFR_FORM_OP
:
1708 ASSERT (CurrentForm
!= NULL
);
1709 ImageId
= &CurrentForm
->ImageId
;
1712 case EFI_IFR_ONE_OF_OPTION_OP
:
1713 ImageId
= &CurrentOption
->ImageId
;
1718 // Make sure CurrentStatement is not NULL.
1719 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1720 // file is wrongly generated by tools such as VFR Compiler.
1722 ASSERT (CurrentStatement
!= NULL
);
1723 ImageId
= &CurrentStatement
->ImageId
;
1727 ASSERT (ImageId
!= NULL
);
1728 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1734 case EFI_IFR_REFRESH_OP
:
1735 ASSERT (CurrentStatement
!= NULL
);
1736 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1742 case EFI_IFR_GUID_OP
:
1743 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1745 // Tiano specific GUIDed opcodes
1747 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1748 case EFI_IFR_EXTEND_OP_LABEL
:
1750 // just ignore label
1754 case EFI_IFR_EXTEND_OP_BANNER
:
1756 // By SubClass to get Banner Data from Front Page
1758 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1760 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1761 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1762 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1763 sizeof (EFI_STRING_ID
)
1768 case EFI_IFR_EXTEND_OP_CLASS
:
1769 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1772 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1773 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1786 case EFI_IFR_END_OP
:
1787 Status
= PopScope (&ScopeOpCode
);
1788 if (EFI_ERROR (Status
)) {
1793 switch (ScopeOpCode
) {
1794 case EFI_IFR_FORM_SET_OP
:
1796 // End of FormSet, update FormSet IFR binary length
1797 // to stop parsing substantial OpCodes
1799 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1802 case EFI_IFR_FORM_OP
:
1807 SuppressForQuestion
= FALSE
;
1810 case EFI_IFR_ONE_OF_OPTION_OP
:
1814 CurrentOption
= NULL
;
1817 case EFI_IFR_SUBTITLE_OP
:
1818 mInScopeSubtitle
= FALSE
;
1821 case EFI_IFR_NO_SUBMIT_IF_OP
:
1822 case EFI_IFR_INCONSISTENT_IF_OP
:
1824 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1828 case EFI_IFR_SUPPRESS_IF_OP
:
1829 if (SuppressForOption
) {
1830 InScopeOptionSuppress
= FALSE
;
1831 } else if (SuppressForQuestion
) {
1832 mInScopeSuppress
= FALSE
;
1834 InScopeFormSuppress
= FALSE
;
1838 case EFI_IFR_GRAY_OUT_IF_OP
:
1839 mInScopeGrayOut
= FALSE
;
1842 case EFI_IFR_DISABLE_IF_OP
:
1843 mInScopeDisable
= FALSE
;
1844 OpCodeDisabled
= FALSE
;
1847 case EFI_IFR_ONE_OF_OP
:
1848 case EFI_IFR_ORDERED_LIST_OP
:
1849 SuppressForOption
= FALSE
;
1852 case EFI_IFR_DEFAULT_OP
:
1853 InScopeDefault
= FALSE
;
1857 if (IsExpressionOpCode (ScopeOpCode
)) {
1858 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1860 // This is DisableIf expression for Form, it should be a constant expression
1862 ASSERT (CurrentExpression
!= NULL
);
1863 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1864 if (EFI_ERROR (Status
)) {
1868 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1869 return EFI_INVALID_PARAMETER
;
1872 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1874 // DisableIf Expression is only used once and not quequed, free it
1876 DestroyExpression (CurrentExpression
);
1880 // End of current Expression
1882 CurrentExpression
= NULL
;