2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2008, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 UINT16 mStatementIndex
;
19 UINT16 mExpressionOpCodeIndex
;
21 BOOLEAN mInScopeSubtitle
;
22 BOOLEAN mInScopeSuppress
;
23 BOOLEAN mInScopeGrayOut
;
24 FORM_EXPRESSION
*mSuppressExpression
;
25 FORM_EXPRESSION
*mGrayOutExpression
;
27 EFI_GUID gTianoHiiIfrGuid
= EFI_IFR_TIANO_GUID
;
28 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID mFrameworkHiiCompatibilityGuid
= EFI_IFR_FRAMEWORK_GUID
;
32 Initialize Statement header members.
34 @param OpCodeData Pointer of the raw OpCode data.
35 @param FormSet Pointer of the current FormSe.
36 @param Form Pointer of the current Form.
38 @return The Statement.
41 FORM_BROWSER_STATEMENT
*
44 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
45 IN OUT FORM_BROWSER_FORM
*Form
48 FORM_BROWSER_STATEMENT
*Statement
;
49 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
53 // We are currently not in a Form Scope, so just skip this Statement
58 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
61 InitializeListHead (&Statement
->DefaultListHead
);
62 InitializeListHead (&Statement
->OptionListHead
);
63 InitializeListHead (&Statement
->InconsistentListHead
);
64 InitializeListHead (&Statement
->NoSubmitListHead
);
66 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
68 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
70 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
71 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
72 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
74 if (mInScopeSuppress
) {
75 Statement
->SuppressExpression
= mSuppressExpression
;
78 if (mInScopeGrayOut
) {
79 Statement
->GrayOutExpression
= mGrayOutExpression
;
82 Statement
->InSubtitle
= mInScopeSubtitle
;
85 // Insert this Statement into current Form
87 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
93 Convert a numeric value to a Unicode String and insert it to String Package.
94 This string is used as the Unicode Name for the EFI Variable. This is to support
95 the deprecated vareqval opcode.
97 @param FormSet The FormSet.
98 @param Statement The numeric question whose VarStoreInfo.VarName is the
99 numeric value which is used to produce the Unicode Name
100 for the EFI Variable.
102 If the Statement is NULL, the ASSERT.
103 If the opcode is not Numeric, then ASSERT.
105 @retval EFI_SUCCESS The funtion always succeeds.
108 UpdateCheckBoxStringToken (
109 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
110 IN FORM_BROWSER_STATEMENT
*Statement
113 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
117 ASSERT (Statement
!= NULL
);
118 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
120 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
122 Status
= HiiLibNewString (FormSet
->HiiHandle
, &Id
, Str
);
124 if (EFI_ERROR (Status
)) {
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 (&mFrameworkHiiCompatibilityGuid
, (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 (PcdFrameworkHiiCompatibilitySupport
)) {
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
334 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
335 Name
= Storage
->Name
;
341 Status
= ConstructConfigHdr (
346 FormSet
->DriverHandle
348 if (Status
== EFI_BUFFER_TOO_SMALL
) {
349 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
350 Status
= ConstructConfigHdr (
355 FormSet
->DriverHandle
359 if (EFI_ERROR (Status
)) {
363 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
364 Storage
->SpareStrLen
= 0;
371 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
373 @param FormSet Pointer of the current FormSet.
374 @param Question The Question to be initialized.
376 @retval EFI_SUCCESS Function success.
377 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
381 InitializeRequestElement (
382 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
383 IN OUT FORM_BROWSER_STATEMENT
*Question
386 FORMSET_STORAGE
*Storage
;
390 CHAR16 RequestElement
[30];
392 Storage
= Question
->Storage
;
393 if (Storage
== NULL
) {
394 return EFI_INVALID_PARAMETER
;
397 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
399 // <ConfigRequest> is unnecessary for EFI variable storage,
400 // GetVariable()/SetVariable() will be used to retrieve/save values
406 // Prepare <RequestElement>
408 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
409 StrLen
= UnicodeSPrint (
411 30 * sizeof (CHAR16
),
412 L
"&OFFSET=%x&WIDTH=%x",
413 Question
->VarStoreInfo
.VarOffset
,
414 Question
->StorageWidth
416 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
418 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
421 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
423 // Password with CALLBACK flag is stored in encoded format,
424 // so don't need to append it to <ConfigRequest>
430 // Append <RequestElement> to <ConfigRequest>
432 if (StrLen
> Storage
->SpareStrLen
) {
434 // Old String buffer is not sufficient for RequestElement, allocate a new one
436 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
437 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
438 ASSERT (NewStr
!= NULL
);
439 if (Storage
->ConfigRequest
!= NULL
) {
440 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
441 FreePool (Storage
->ConfigRequest
);
443 Storage
->ConfigRequest
= NewStr
;
444 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
447 StrCat (Storage
->ConfigRequest
, RequestElement
);
448 Storage
->ElementCount
++;
449 Storage
->SpareStrLen
-= StrLen
;
456 Free resources of a Expression.
458 @param FormSet Pointer of the Expression
463 IN FORM_EXPRESSION
*Expression
467 EXPRESSION_OPCODE
*OpCode
;
469 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
470 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
471 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
472 RemoveEntryList (&OpCode
->Link
);
474 if (OpCode
->ValueList
!= NULL
) {
475 FreePool (OpCode
->ValueList
);
480 // Free this Expression
482 FreePool (Expression
);
487 Free resources of a storage.
489 @param Storage Pointer of the storage
494 IN FORMSET_STORAGE
*Storage
498 NAME_VALUE_NODE
*NameValueNode
;
500 if (Storage
== NULL
) {
504 if (Storage
->Name
!= NULL
) {
505 FreePool (Storage
->Name
);
507 if (Storage
->Buffer
!= NULL
) {
508 FreePool (Storage
->Buffer
);
510 if (Storage
->EditBuffer
!= NULL
) {
511 FreePool (Storage
->EditBuffer
);
514 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
515 Link
= GetFirstNode (&Storage
->NameValueListHead
);
516 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
517 RemoveEntryList (&NameValueNode
->Link
);
519 if (NameValueNode
->Name
!= NULL
) {
520 FreePool (NameValueNode
->Name
);
522 if (NameValueNode
->Value
!= NULL
) {
523 FreePool (NameValueNode
->Value
);
525 if (NameValueNode
->EditValue
!= NULL
) {
526 FreePool (NameValueNode
->EditValue
);
528 FreePool (NameValueNode
);
531 if (Storage
->ConfigHdr
!= NULL
) {
532 FreePool (Storage
->ConfigHdr
);
534 if (Storage
->ConfigRequest
!= NULL
) {
535 FreePool (Storage
->ConfigRequest
);
543 Free resources of a Statement.
545 @param Statement Pointer of the Statement
550 IN OUT FORM_BROWSER_STATEMENT
*Statement
554 QUESTION_DEFAULT
*Default
;
555 QUESTION_OPTION
*Option
;
556 FORM_EXPRESSION
*Expression
;
559 // Free Default value List
561 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
562 Link
= GetFirstNode (&Statement
->DefaultListHead
);
563 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
564 RemoveEntryList (&Default
->Link
);
572 while (!IsListEmpty (&Statement
->OptionListHead
)) {
573 Link
= GetFirstNode (&Statement
->OptionListHead
);
574 Option
= QUESTION_OPTION_FROM_LINK (Link
);
575 RemoveEntryList (&Option
->Link
);
581 // Free Inconsistent List
583 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
584 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
585 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
586 RemoveEntryList (&Expression
->Link
);
588 DestroyExpression (Expression
);
592 // Free NoSubmit List
594 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
595 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
596 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
597 RemoveEntryList (&Expression
->Link
);
599 DestroyExpression (Expression
);
602 if (Statement
->VariableName
!= NULL
) {
603 FreePool (Statement
->VariableName
);
605 if (Statement
->BlockName
!= NULL
) {
606 FreePool (Statement
->BlockName
);
612 Free resources of a Form.
614 @param Form Pointer of the Form.
619 IN OUT FORM_BROWSER_FORM
*Form
623 FORM_EXPRESSION
*Expression
;
624 FORM_BROWSER_STATEMENT
*Statement
;
627 // Free Form Expressions
629 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
630 Link
= GetFirstNode (&Form
->ExpressionListHead
);
631 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
632 RemoveEntryList (&Expression
->Link
);
634 DestroyExpression (Expression
);
638 // Free Statements/Questions
640 while (!IsListEmpty (&Form
->StatementListHead
)) {
641 Link
= GetFirstNode (&Form
->StatementListHead
);
642 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
643 RemoveEntryList (&Statement
->Link
);
645 DestroyStatement (Statement
);
656 Free resources allocated for a FormSet.
658 @param FormSet Pointer of the FormSet
663 IN OUT FORM_BROWSER_FORMSET
*FormSet
667 FORMSET_STORAGE
*Storage
;
668 FORMSET_DEFAULTSTORE
*DefaultStore
;
669 FORM_BROWSER_FORM
*Form
;
672 // Free IFR binary buffer
674 FreePool (FormSet
->IfrBinaryData
);
677 // Free FormSet Storage
679 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
680 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
681 Link
= GetFirstNode (&FormSet
->StorageListHead
);
682 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
683 RemoveEntryList (&Storage
->Link
);
685 DestroyStorage (Storage
);
690 // Free FormSet Default Store
692 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
693 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
694 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
695 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
696 RemoveEntryList (&DefaultStore
->Link
);
698 FreePool (DefaultStore
);
705 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
706 while (!IsListEmpty (&FormSet
->FormListHead
)) {
707 Link
= GetFirstNode (&FormSet
->FormListHead
);
708 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
709 RemoveEntryList (&Form
->Link
);
715 if (FormSet
->StatementBuffer
!= NULL
) {
716 FreePool (FormSet
->StatementBuffer
);
718 if (FormSet
->ExpressionBuffer
!= NULL
) {
719 FreePool (FormSet
->ExpressionBuffer
);
727 Tell whether this Operand is an Expression OpCode or not
729 @param Operand Operand of an IFR OpCode.
731 @retval TRUE This is an Expression OpCode.
732 @retval FALSE Not an Expression OpCode.
740 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
741 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
742 (Operand
== EFI_IFR_CATENATE_OP
) ||
743 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
744 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
745 (Operand
== EFI_IFR_VERSION_OP
)
755 Calculate number of Statemens(Questions) and Expression OpCodes.
757 @param FormSet The FormSet to be counted.
758 @param NumberOfStatement Number of Statemens(Questions)
759 @param NumberOfExpression Number of Expression OpCodes
764 IN FORM_BROWSER_FORMSET
*FormSet
,
765 IN OUT UINT16
*NumberOfStatement
,
766 IN OUT UINT16
*NumberOfExpression
769 UINT16 StatementCount
;
770 UINT16 ExpressionCount
;
779 while (Offset
< FormSet
->IfrBinaryLength
) {
780 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
781 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
784 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
791 *NumberOfStatement
= StatementCount
;
792 *NumberOfExpression
= ExpressionCount
;
798 Parse opcodes in the formset IFR binary.
800 @param FormSet Pointer of the FormSet data structure.
802 @retval EFI_SUCCESS Opcode parse success.
803 @retval Other Opcode parse fail.
808 IN FORM_BROWSER_FORMSET
*FormSet
813 FORM_BROWSER_FORM
*CurrentForm
;
814 FORM_BROWSER_STATEMENT
*CurrentStatement
;
815 EXPRESSION_OPCODE
*ExpressionOpCode
;
816 FORM_EXPRESSION
*CurrentExpression
;
823 FORMSET_STORAGE
*Storage
;
824 FORMSET_DEFAULTSTORE
*DefaultStore
;
825 QUESTION_DEFAULT
*CurrentDefault
;
826 QUESTION_OPTION
*CurrentOption
;
828 UINT16 NumberOfStatement
;
829 UINT16 NumberOfExpression
;
830 EFI_IMAGE_ID
*ImageId
;
831 BOOLEAN SuppressForOption
;
832 BOOLEAN InScopeOptionSuppress
;
833 FORM_EXPRESSION
*OptionSuppressExpression
;
834 BOOLEAN InScopeDisable
;
835 UINT16 DepthOfDisable
;
836 BOOLEAN OpCodeDisabled
;
837 BOOLEAN SingleOpCodeExpression
;
838 BOOLEAN InScopeDefault
;
839 EFI_HII_VALUE
*Value
;
841 mInScopeSubtitle
= FALSE
;
842 SuppressForOption
= FALSE
;
843 mInScopeSuppress
= FALSE
;
844 InScopeOptionSuppress
= FALSE
;
845 mInScopeGrayOut
= FALSE
;
846 InScopeDisable
= FALSE
;
848 OpCodeDisabled
= FALSE
;
849 SingleOpCodeExpression
= FALSE
;
850 InScopeDefault
= FALSE
;
851 CurrentExpression
= NULL
;
852 CurrentDefault
= NULL
;
853 CurrentOption
= NULL
;
854 OptionSuppressExpression
= NULL
;
857 // Get the number of Statements and Expressions
859 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
862 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
863 if (FormSet
->StatementBuffer
== NULL
) {
864 return EFI_OUT_OF_RESOURCES
;
867 mExpressionOpCodeIndex
= 0;
868 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
869 if (FormSet
->ExpressionBuffer
== NULL
) {
870 return EFI_OUT_OF_RESOURCES
;
873 InitializeListHead (&FormSet
->StorageListHead
);
874 InitializeListHead (&FormSet
->DefaultStoreListHead
);
875 InitializeListHead (&FormSet
->FormListHead
);
878 CurrentStatement
= NULL
;
883 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
884 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
886 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
887 OpCodeOffset
+= OpCodeLength
;
888 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
889 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
892 // If scope bit set, push onto scope stack
898 if (OpCodeDisabled
) {
900 // DisableIf Expression is evaluated to be TRUE, try to find its end.
901 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
903 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
905 } else if (Operand
== EFI_IFR_END_OP
) {
906 Status
= PopScope (&ScopeOpCode
);
907 if (EFI_ERROR (Status
)) {
911 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
912 if (DepthOfDisable
== 0) {
913 InScopeDisable
= FALSE
;
914 OpCodeDisabled
= FALSE
;
923 if (IsExpressionOpCode (Operand
)) {
924 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
925 mExpressionOpCodeIndex
++;
927 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
928 ExpressionOpCode
->Operand
= Operand
;
929 Value
= &ExpressionOpCode
->Value
;
932 case EFI_IFR_EQ_ID_VAL_OP
:
933 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
935 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
936 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
939 case EFI_IFR_EQ_ID_ID_OP
:
940 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
941 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
944 case EFI_IFR_EQ_ID_LIST_OP
:
945 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
946 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
947 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
950 case EFI_IFR_TO_STRING_OP
:
951 case EFI_IFR_FIND_OP
:
952 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
955 case EFI_IFR_STRING_REF1_OP
:
956 Value
->Type
= EFI_IFR_TYPE_STRING
;
957 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
960 case EFI_IFR_RULE_REF_OP
:
961 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
964 case EFI_IFR_SPAN_OP
:
965 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
968 case EFI_IFR_THIS_OP
:
969 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
972 case EFI_IFR_QUESTION_REF1_OP
:
973 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
976 case EFI_IFR_QUESTION_REF3_OP
:
977 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
978 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
980 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
981 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
989 case EFI_IFR_TRUE_OP
:
990 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
991 Value
->Value
.b
= TRUE
;
994 case EFI_IFR_FALSE_OP
:
995 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
996 Value
->Value
.b
= FALSE
;
1000 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1001 Value
->Value
.u8
= 1;
1004 case EFI_IFR_ZERO_OP
:
1005 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1006 Value
->Value
.u8
= 0;
1009 case EFI_IFR_ONES_OP
:
1010 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1011 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1014 case EFI_IFR_UINT8_OP
:
1015 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1016 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1019 case EFI_IFR_UINT16_OP
:
1020 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1021 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1024 case EFI_IFR_UINT32_OP
:
1025 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1026 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1029 case EFI_IFR_UINT64_OP
:
1030 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1031 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1034 case EFI_IFR_UNDEFINED_OP
:
1035 Value
->Type
= EFI_IFR_TYPE_OTHER
;
1038 case EFI_IFR_VERSION_OP
:
1039 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1040 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1047 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1049 if (SingleOpCodeExpression
) {
1051 // There are two cases to indicate the end of an Expression:
1052 // for single OpCode expression: one Expression OpCode
1053 // for expression consists of more than one OpCode: EFI_IFR_END
1055 SingleOpCodeExpression
= FALSE
;
1057 if (InScopeDisable
) {
1059 // Evaluate DisableIf expression
1061 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1062 if (EFI_ERROR (Status
)) {
1065 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1066 return EFI_INVALID_PARAMETER
;
1069 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1072 CurrentExpression
= NULL
;
1083 case EFI_IFR_FORM_SET_OP
:
1085 // check the formset GUID
1087 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1088 return EFI_INVALID_PARAMETER
;
1091 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1092 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1095 case EFI_IFR_FORM_OP
:
1097 // Create a new Form for this FormSet
1099 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1100 ASSERT (CurrentForm
!= NULL
);
1101 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1102 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1103 InitializeListHead (&CurrentForm
->StatementListHead
);
1105 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1106 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1109 // Insert into Form list of this FormSet
1111 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1117 case EFI_IFR_VARSTORE_OP
:
1119 // Create a buffer Storage for this FormSet
1121 Storage
= CreateStorage (FormSet
);
1122 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1124 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1125 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1126 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1128 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1129 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1131 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1132 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1133 ASSERT (Storage
->Name
!= NULL
);
1134 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1135 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1139 // Initialize <ConfigHdr>
1141 InitializeConfigHdr (FormSet
, Storage
);
1144 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1146 // Create a name/value Storage for this FormSet
1148 Storage
= CreateStorage (FormSet
);
1149 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1151 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1152 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1155 // Initialize <ConfigHdr>
1157 InitializeConfigHdr (FormSet
, Storage
);
1160 case EFI_IFR_VARSTORE_EFI_OP
:
1162 // Create a EFI variable Storage for this FormSet
1164 Storage
= CreateStorage (FormSet
);
1165 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1167 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1168 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1169 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1175 case EFI_IFR_DEFAULTSTORE_OP
:
1176 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1177 ASSERT (DefaultStore
!= NULL
);
1178 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1180 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1181 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1184 // Insert to DefaultStore list of this Formset
1186 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1192 case EFI_IFR_SUBTITLE_OP
:
1193 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1194 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1197 mInScopeSubtitle
= TRUE
;
1201 case EFI_IFR_TEXT_OP
:
1202 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1204 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1210 case EFI_IFR_ACTION_OP
:
1211 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1213 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1215 // No QuestionConfig present, so no configuration string will be processed
1217 CurrentStatement
->QuestionConfig
= 0;
1219 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1223 case EFI_IFR_RESET_BUTTON_OP
:
1224 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1226 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1229 case EFI_IFR_REF_OP
:
1230 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1232 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1233 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1234 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1236 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1237 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1239 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1240 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1246 case EFI_IFR_ONE_OF_OP
:
1247 case EFI_IFR_NUMERIC_OP
:
1248 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1250 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1251 Value
= &CurrentStatement
->HiiValue
;
1253 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1254 case EFI_IFR_NUMERIC_SIZE_1
:
1255 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1256 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1257 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1258 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1259 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1262 case EFI_IFR_NUMERIC_SIZE_2
:
1263 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1264 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1265 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1266 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1267 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1270 case EFI_IFR_NUMERIC_SIZE_4
:
1271 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1272 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1273 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1274 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1275 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1278 case EFI_IFR_NUMERIC_SIZE_8
:
1279 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1280 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1281 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1282 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1283 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1290 InitializeRequestElement (FormSet
, CurrentStatement
);
1292 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1293 SuppressForOption
= TRUE
;
1297 case EFI_IFR_ORDERED_LIST_OP
:
1298 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1300 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1301 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1302 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1303 InitializeRequestElement (FormSet
, CurrentStatement
);
1306 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1307 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1308 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1310 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1311 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1314 SuppressForOption
= TRUE
;
1318 case EFI_IFR_CHECKBOX_OP
:
1319 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1321 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1322 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1323 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1325 InitializeRequestElement (FormSet
, CurrentStatement
);
1329 case EFI_IFR_STRING_OP
:
1330 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1333 // MinSize is the minimum number of characters that can be accepted for this opcode,
1334 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1335 // The characters are stored as Unicode, so the storage width should multiply 2.
1337 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1338 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1339 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1340 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1342 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1343 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1345 InitializeRequestElement (FormSet
, CurrentStatement
);
1348 case EFI_IFR_PASSWORD_OP
:
1349 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1352 // MinSize is the minimum number of characters that can be accepted for this opcode,
1353 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1354 // The characters are stored as Unicode, so the storage width should multiply 2.
1356 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1357 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1358 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1360 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1361 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1363 InitializeRequestElement (FormSet
, CurrentStatement
);
1366 case EFI_IFR_DATE_OP
:
1367 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1369 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1370 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1372 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1373 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1375 InitializeRequestElement (FormSet
, CurrentStatement
);
1378 // Don't assign storage for RTC type of date/time
1380 CurrentStatement
->Storage
= NULL
;
1381 CurrentStatement
->StorageWidth
= 0;
1385 case EFI_IFR_TIME_OP
:
1386 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1388 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1389 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1391 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1392 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1394 InitializeRequestElement (FormSet
, CurrentStatement
);
1397 // Don't assign storage for RTC type of date/time
1399 CurrentStatement
->Storage
= NULL
;
1400 CurrentStatement
->StorageWidth
= 0;
1407 case EFI_IFR_DEFAULT_OP
:
1409 // EFI_IFR_DEFAULT appear in scope of a Question,
1410 // It creates a default value for the current question.
1411 // A Question may have more than one Default value which have different default types.
1413 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1414 ASSERT (CurrentDefault
!= NULL
);
1415 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1417 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1418 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1419 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1420 ExtendValueToU64 (&CurrentDefault
->Value
);
1423 // Insert to Default Value list of current Question
1425 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1428 InScopeDefault
= TRUE
;
1435 case EFI_IFR_ONE_OF_OPTION_OP
:
1437 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1438 // It create a selection for use in current Question.
1440 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1441 ASSERT (CurrentOption
!= NULL
);
1442 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1444 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1445 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1446 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1447 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1448 ExtendValueToU64 (&CurrentOption
->Value
);
1450 if (InScopeOptionSuppress
) {
1451 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1455 // Insert to Option list of current Question
1457 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1463 case EFI_IFR_NO_SUBMIT_IF_OP
:
1464 case EFI_IFR_INCONSISTENT_IF_OP
:
1466 // Create an Expression node
1468 CurrentExpression
= CreateExpression (CurrentForm
);
1469 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1471 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1472 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1473 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1475 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1476 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1480 case EFI_IFR_SUPPRESS_IF_OP
:
1482 // Question and Option will appear in scope of this OpCode
1484 CurrentExpression
= CreateExpression (CurrentForm
);
1485 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1486 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1488 if (SuppressForOption
) {
1489 InScopeOptionSuppress
= TRUE
;
1490 OptionSuppressExpression
= CurrentExpression
;
1492 mInScopeSuppress
= TRUE
;
1493 mSuppressExpression
= CurrentExpression
;
1497 case EFI_IFR_GRAY_OUT_IF_OP
:
1499 // Questions will appear in scope of this OpCode
1501 CurrentExpression
= CreateExpression (CurrentForm
);
1502 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1503 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1505 mInScopeGrayOut
= TRUE
;
1506 mGrayOutExpression
= CurrentExpression
;
1509 case EFI_IFR_DISABLE_IF_OP
:
1511 // The DisableIf expression should only rely on constant, so it could be
1512 // evaluated at initialization and it will not be queued
1514 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1515 ASSERT (CurrentExpression
!= NULL
);
1516 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1517 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1518 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1520 InScopeDisable
= TRUE
;
1521 OpCodeDisabled
= FALSE
;
1524 // Take a look at next OpCode to see whether current expression consists
1527 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1528 SingleOpCodeExpression
= TRUE
;
1535 case EFI_IFR_VALUE_OP
:
1536 CurrentExpression
= CreateExpression (CurrentForm
);
1537 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1538 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1540 if (InScopeDefault
) {
1542 // Used for default (EFI_IFR_DEFAULT)
1544 CurrentDefault
->ValueExpression
= CurrentExpression
;
1547 // If used for a question, then the question will be read-only
1549 CurrentStatement
->ValueExpression
= CurrentExpression
;
1553 case EFI_IFR_RULE_OP
:
1554 CurrentExpression
= CreateExpression (CurrentForm
);
1555 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1557 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1558 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1564 case EFI_IFR_IMAGE_OP
:
1566 // Get ScopeOpcode from top of stack
1568 PopScope (&ScopeOpCode
);
1569 PushScope (ScopeOpCode
);
1571 switch (ScopeOpCode
) {
1572 case EFI_IFR_FORM_SET_OP
:
1573 ImageId
= &FormSet
->ImageId
;
1576 case EFI_IFR_FORM_OP
:
1577 ImageId
= &CurrentForm
->ImageId
;
1580 case EFI_IFR_ONE_OF_OPTION_OP
:
1581 ImageId
= &CurrentOption
->ImageId
;
1585 ImageId
= &CurrentStatement
->ImageId
;
1589 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1595 case EFI_IFR_REFRESH_OP
:
1596 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1602 case EFI_IFR_GUID_OP
:
1603 if (CompareGuid (&gTianoHiiIfrGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1605 // Tiano specific GUIDed opcodes
1607 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1608 case EFI_IFR_EXTEND_OP_LABEL
:
1610 // just ignore label
1614 case EFI_IFR_EXTEND_OP_BANNER
:
1615 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1617 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1618 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1619 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1620 sizeof (EFI_STRING_ID
)
1625 case EFI_IFR_EXTEND_OP_CLASS
:
1626 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1629 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1630 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1643 case EFI_IFR_END_OP
:
1644 Status
= PopScope (&ScopeOpCode
);
1645 if (EFI_ERROR (Status
)) {
1650 switch (ScopeOpCode
) {
1651 case EFI_IFR_FORM_SET_OP
:
1653 // End of FormSet, update FormSet IFR binary length
1654 // to stop parsing substantial OpCodes
1656 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1659 case EFI_IFR_FORM_OP
:
1666 case EFI_IFR_ONE_OF_OPTION_OP
:
1670 CurrentOption
= NULL
;
1673 case EFI_IFR_SUBTITLE_OP
:
1674 mInScopeSubtitle
= FALSE
;
1677 case EFI_IFR_NO_SUBMIT_IF_OP
:
1678 case EFI_IFR_INCONSISTENT_IF_OP
:
1680 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1684 case EFI_IFR_SUPPRESS_IF_OP
:
1685 if (SuppressForOption
) {
1686 InScopeOptionSuppress
= FALSE
;
1688 mInScopeSuppress
= FALSE
;
1692 case EFI_IFR_GRAY_OUT_IF_OP
:
1693 mInScopeGrayOut
= FALSE
;
1696 case EFI_IFR_DISABLE_IF_OP
:
1697 InScopeDisable
= FALSE
;
1698 OpCodeDisabled
= FALSE
;
1701 case EFI_IFR_ONE_OF_OP
:
1702 case EFI_IFR_ORDERED_LIST_OP
:
1703 SuppressForOption
= FALSE
;
1706 case EFI_IFR_DEFAULT_OP
:
1707 InScopeDefault
= FALSE
;
1711 if (IsExpressionOpCode (ScopeOpCode
)) {
1712 if (InScopeDisable
) {
1714 // Evaluate DisableIf expression
1716 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1717 if (EFI_ERROR (Status
)) {
1720 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1721 return EFI_INVALID_PARAMETER
;
1724 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1726 // DisableIf Expression is only used once and not quequed, free it
1728 DestroyExpression (CurrentExpression
);
1732 // End of current Expression
1734 CurrentExpression
= NULL
;