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 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
283 InitializeListHead (&Expression
->OpCodeListHead
);
290 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
292 @param FormSet Pointer of the current FormSet
294 @return Pointer to a FORMSET_STORAGE data structure.
299 IN FORM_BROWSER_FORMSET
*FormSet
302 FORMSET_STORAGE
*Storage
;
304 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
305 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
306 InitializeListHead (&Storage
->NameValueListHead
);
307 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
314 Create ConfigHdr string for a storage.
316 @param FormSet Pointer of the current FormSet
317 @param Storage Pointer of the storage
319 @retval EFI_SUCCESS Initialize ConfigHdr success
323 InitializeConfigHdr (
324 IN FORM_BROWSER_FORMSET
*FormSet
,
325 IN OUT FORMSET_STORAGE
*Storage
332 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
333 Name
= Storage
->Name
;
339 Status
= ConstructConfigHdr (
344 FormSet
->DriverHandle
346 if (Status
== EFI_BUFFER_TOO_SMALL
) {
347 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
348 Status
= ConstructConfigHdr (
353 FormSet
->DriverHandle
357 if (EFI_ERROR (Status
)) {
361 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
362 Storage
->SpareStrLen
= 0;
369 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
371 @param FormSet Pointer of the current FormSet.
372 @param Question The Question to be initialized.
374 @retval EFI_SUCCESS Function success.
375 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
379 InitializeRequestElement (
380 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
381 IN OUT FORM_BROWSER_STATEMENT
*Question
384 FORMSET_STORAGE
*Storage
;
388 CHAR16 RequestElement
[30];
390 Storage
= Question
->Storage
;
391 if (Storage
== NULL
) {
392 return EFI_INVALID_PARAMETER
;
395 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
397 // <ConfigRequest> is unnecessary for EFI variable storage,
398 // GetVariable()/SetVariable() will be used to retrieve/save values
404 // Prepare <RequestElement>
406 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
407 StrLen
= UnicodeSPrint (
409 30 * sizeof (CHAR16
),
410 L
"&OFFSET=%x&WIDTH=%x",
411 Question
->VarStoreInfo
.VarOffset
,
412 Question
->StorageWidth
414 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
416 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
419 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
421 // Password with CALLBACK flag is stored in encoded format,
422 // so don't need to append it to <ConfigRequest>
428 // Append <RequestElement> to <ConfigRequest>
430 if (StrLen
> Storage
->SpareStrLen
) {
432 // Old String buffer is not sufficient for RequestElement, allocate a new one
434 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
435 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
436 if (Storage
->ConfigRequest
!= NULL
) {
437 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
438 gBS
->FreePool (Storage
->ConfigRequest
);
440 Storage
->ConfigRequest
= NewStr
;
441 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
444 StrCat (Storage
->ConfigRequest
, RequestElement
);
445 Storage
->ElementCount
++;
446 Storage
->SpareStrLen
-= StrLen
;
453 Free resources of a Expression.
455 @param FormSet Pointer of the Expression
460 IN FORM_EXPRESSION
*Expression
464 EXPRESSION_OPCODE
*OpCode
;
466 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
467 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
468 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
469 RemoveEntryList (&OpCode
->Link
);
471 if (OpCode
->ValueList
!= NULL
) {
472 FreePool (OpCode
->ValueList
);
477 // Free this Expression
479 gBS
->FreePool (Expression
);
484 Free resources of a storage.
486 @param Storage Pointer of the storage
491 IN FORMSET_STORAGE
*Storage
495 NAME_VALUE_NODE
*NameValueNode
;
497 if (Storage
== NULL
) {
501 if (Storage
->Name
!= NULL
) {
502 FreePool (Storage
->Name
);
504 if (Storage
->Buffer
!= NULL
) {
505 FreePool (Storage
->Buffer
);
507 if (Storage
->EditBuffer
!= NULL
) {
508 FreePool (Storage
->EditBuffer
);
511 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
512 Link
= GetFirstNode (&Storage
->NameValueListHead
);
513 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
514 RemoveEntryList (&NameValueNode
->Link
);
516 if (NameValueNode
->Name
!= NULL
) {
517 FreePool (NameValueNode
->Name
);
519 if (NameValueNode
->Value
!= NULL
) {
520 FreePool (NameValueNode
->Value
);
522 if (NameValueNode
->EditValue
!= NULL
) {
523 FreePool (NameValueNode
->EditValue
);
525 FreePool (NameValueNode
);
528 if (Storage
->ConfigHdr
!= NULL
) {
529 FreePool (Storage
->ConfigHdr
);
531 if (Storage
->ConfigRequest
!= NULL
) {
532 FreePool (Storage
->ConfigRequest
);
540 Free resources of a Statement.
542 @param Statement Pointer of the Statement
547 IN OUT FORM_BROWSER_STATEMENT
*Statement
551 QUESTION_DEFAULT
*Default
;
552 QUESTION_OPTION
*Option
;
553 FORM_EXPRESSION
*Expression
;
556 // Free Default value List
558 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
559 Link
= GetFirstNode (&Statement
->DefaultListHead
);
560 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
561 RemoveEntryList (&Default
->Link
);
563 gBS
->FreePool (Default
);
569 while (!IsListEmpty (&Statement
->OptionListHead
)) {
570 Link
= GetFirstNode (&Statement
->OptionListHead
);
571 Option
= QUESTION_OPTION_FROM_LINK (Link
);
572 RemoveEntryList (&Option
->Link
);
574 gBS
->FreePool (Option
);
578 // Free Inconsistent List
580 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
581 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
582 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
583 RemoveEntryList (&Expression
->Link
);
585 DestroyExpression (Expression
);
589 // Free NoSubmit List
591 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
592 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
593 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
594 RemoveEntryList (&Expression
->Link
);
596 DestroyExpression (Expression
);
599 if (Statement
->VariableName
!= NULL
) {
600 FreePool (Statement
->VariableName
);
602 if (Statement
->BlockName
!= NULL
) {
603 FreePool (Statement
->BlockName
);
609 Free resources of a Form.
611 @param Form Pointer of the Form.
616 IN OUT FORM_BROWSER_FORM
*Form
620 FORM_EXPRESSION
*Expression
;
621 FORM_BROWSER_STATEMENT
*Statement
;
624 // Free Form Expressions
626 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
627 Link
= GetFirstNode (&Form
->ExpressionListHead
);
628 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
629 RemoveEntryList (&Expression
->Link
);
631 DestroyExpression (Expression
);
635 // Free Statements/Questions
637 while (!IsListEmpty (&Form
->StatementListHead
)) {
638 Link
= GetFirstNode (&Form
->StatementListHead
);
639 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
640 RemoveEntryList (&Statement
->Link
);
642 DestroyStatement (Statement
);
648 gBS
->FreePool (Form
);
653 Free resources allocated for a FormSet.
655 @param FormSet Pointer of the FormSet
660 IN OUT FORM_BROWSER_FORMSET
*FormSet
664 FORMSET_STORAGE
*Storage
;
665 FORMSET_DEFAULTSTORE
*DefaultStore
;
666 FORM_BROWSER_FORM
*Form
;
669 // Free IFR binary buffer
671 FreePool (FormSet
->IfrBinaryData
);
674 // Free FormSet Storage
676 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
677 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
678 Link
= GetFirstNode (&FormSet
->StorageListHead
);
679 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
680 RemoveEntryList (&Storage
->Link
);
682 DestroyStorage (Storage
);
687 // Free FormSet Default Store
689 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
690 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
691 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
692 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
693 RemoveEntryList (&DefaultStore
->Link
);
695 gBS
->FreePool (DefaultStore
);
702 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
703 while (!IsListEmpty (&FormSet
->FormListHead
)) {
704 Link
= GetFirstNode (&FormSet
->FormListHead
);
705 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
706 RemoveEntryList (&Form
->Link
);
712 if (FormSet
->StatementBuffer
!= NULL
) {
713 FreePool (FormSet
->StatementBuffer
);
715 if (FormSet
->ExpressionBuffer
!= NULL
) {
716 FreePool (FormSet
->ExpressionBuffer
);
724 Tell whether this Operand is an Expression OpCode or not
726 @param Operand Operand of an IFR OpCode.
728 @retval TRUE This is an Expression OpCode.
729 @retval FALSE Not an Expression OpCode.
737 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
738 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
739 (Operand
== EFI_IFR_CATENATE_OP
) ||
740 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
741 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
742 (Operand
== EFI_IFR_VERSION_OP
)
752 Calculate number of Statemens(Questions) and Expression OpCodes.
754 @param FormSet The FormSet to be counted.
755 @param NumberOfStatement Number of Statemens(Questions)
756 @param NumberOfExpression Number of Expression OpCodes
761 IN FORM_BROWSER_FORMSET
*FormSet
,
762 IN OUT UINT16
*NumberOfStatement
,
763 IN OUT UINT16
*NumberOfExpression
766 UINT16 StatementCount
;
767 UINT16 ExpressionCount
;
776 while (Offset
< FormSet
->IfrBinaryLength
) {
777 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
778 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
781 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
788 *NumberOfStatement
= StatementCount
;
789 *NumberOfExpression
= ExpressionCount
;
795 Parse opcodes in the formset IFR binary.
797 @param FormSet Pointer of the FormSet data structure.
799 @retval EFI_SUCCESS Opcode parse success.
800 @retval Other Opcode parse fail.
805 IN FORM_BROWSER_FORMSET
*FormSet
810 FORM_BROWSER_FORM
*CurrentForm
;
811 FORM_BROWSER_STATEMENT
*CurrentStatement
;
812 EXPRESSION_OPCODE
*ExpressionOpCode
;
813 FORM_EXPRESSION
*CurrentExpression
;
820 FORMSET_STORAGE
*Storage
;
821 FORMSET_DEFAULTSTORE
*DefaultStore
;
822 QUESTION_DEFAULT
*CurrentDefault
;
823 QUESTION_OPTION
*CurrentOption
;
825 UINT16 NumberOfStatement
;
826 UINT16 NumberOfExpression
;
827 EFI_IMAGE_ID
*ImageId
;
828 BOOLEAN SuppressForOption
;
829 BOOLEAN InScopeOptionSuppress
;
830 FORM_EXPRESSION
*OptionSuppressExpression
;
831 BOOLEAN InScopeDisable
;
832 UINT16 DepthOfDisable
;
833 BOOLEAN OpCodeDisabled
;
834 BOOLEAN SingleOpCodeExpression
;
835 BOOLEAN InScopeDefault
;
836 EFI_HII_VALUE
*Value
;
838 mInScopeSubtitle
= FALSE
;
839 SuppressForOption
= FALSE
;
840 mInScopeSuppress
= FALSE
;
841 InScopeOptionSuppress
= FALSE
;
842 mInScopeGrayOut
= FALSE
;
843 InScopeDisable
= FALSE
;
845 OpCodeDisabled
= FALSE
;
846 SingleOpCodeExpression
= FALSE
;
847 InScopeDefault
= FALSE
;
848 CurrentExpression
= NULL
;
849 CurrentDefault
= NULL
;
850 CurrentOption
= NULL
;
851 OptionSuppressExpression
= NULL
;
854 // Get the number of Statements and Expressions
856 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
859 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
860 if (FormSet
->StatementBuffer
== NULL
) {
861 return EFI_OUT_OF_RESOURCES
;
864 mExpressionOpCodeIndex
= 0;
865 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
866 if (FormSet
->ExpressionBuffer
== NULL
) {
867 return EFI_OUT_OF_RESOURCES
;
870 InitializeListHead (&FormSet
->StorageListHead
);
871 InitializeListHead (&FormSet
->DefaultStoreListHead
);
872 InitializeListHead (&FormSet
->FormListHead
);
875 CurrentStatement
= NULL
;
880 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
881 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
883 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
884 OpCodeOffset
+= OpCodeLength
;
885 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
886 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
889 // If scope bit set, push onto scope stack
895 if (OpCodeDisabled
) {
897 // DisableIf Expression is evaluated to be TRUE, try to find its end.
898 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
900 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
902 } else if (Operand
== EFI_IFR_END_OP
) {
903 Status
= PopScope (&ScopeOpCode
);
904 if (EFI_ERROR (Status
)) {
908 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
909 if (DepthOfDisable
== 0) {
910 InScopeDisable
= FALSE
;
911 OpCodeDisabled
= FALSE
;
920 if (IsExpressionOpCode (Operand
)) {
921 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
922 mExpressionOpCodeIndex
++;
924 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
925 ExpressionOpCode
->Operand
= Operand
;
926 Value
= &ExpressionOpCode
->Value
;
929 case EFI_IFR_EQ_ID_VAL_OP
:
930 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
932 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
933 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
936 case EFI_IFR_EQ_ID_ID_OP
:
937 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
938 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
941 case EFI_IFR_EQ_ID_LIST_OP
:
942 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
943 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
944 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
947 case EFI_IFR_TO_STRING_OP
:
948 case EFI_IFR_FIND_OP
:
949 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
952 case EFI_IFR_STRING_REF1_OP
:
953 Value
->Type
= EFI_IFR_TYPE_STRING
;
954 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
957 case EFI_IFR_RULE_REF_OP
:
958 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
961 case EFI_IFR_SPAN_OP
:
962 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
965 case EFI_IFR_THIS_OP
:
966 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
969 case EFI_IFR_QUESTION_REF1_OP
:
970 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
973 case EFI_IFR_QUESTION_REF3_OP
:
974 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
975 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
977 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
978 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
986 case EFI_IFR_TRUE_OP
:
987 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
988 Value
->Value
.b
= TRUE
;
991 case EFI_IFR_FALSE_OP
:
992 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
993 Value
->Value
.b
= FALSE
;
997 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1001 case EFI_IFR_ZERO_OP
:
1002 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1003 Value
->Value
.u8
= 0;
1006 case EFI_IFR_ONES_OP
:
1007 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1008 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1011 case EFI_IFR_UINT8_OP
:
1012 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1013 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1016 case EFI_IFR_UINT16_OP
:
1017 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1018 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1021 case EFI_IFR_UINT32_OP
:
1022 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1023 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1026 case EFI_IFR_UINT64_OP
:
1027 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1028 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1031 case EFI_IFR_UNDEFINED_OP
:
1032 Value
->Type
= EFI_IFR_TYPE_OTHER
;
1035 case EFI_IFR_VERSION_OP
:
1036 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1037 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1044 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1046 if (SingleOpCodeExpression
) {
1048 // There are two cases to indicate the end of an Expression:
1049 // for single OpCode expression: one Expression OpCode
1050 // for expression consists of more than one OpCode: EFI_IFR_END
1052 SingleOpCodeExpression
= FALSE
;
1054 if (InScopeDisable
) {
1056 // Evaluate DisableIf expression
1058 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1059 if (EFI_ERROR (Status
)) {
1062 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1063 return EFI_INVALID_PARAMETER
;
1066 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1069 CurrentExpression
= NULL
;
1080 case EFI_IFR_FORM_SET_OP
:
1082 // check the formset GUID
1084 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1085 return EFI_INVALID_PARAMETER
;
1088 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1089 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1092 case EFI_IFR_FORM_OP
:
1094 // Create a new Form for this FormSet
1096 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1097 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1098 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1099 InitializeListHead (&CurrentForm
->StatementListHead
);
1101 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1102 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1105 // Insert into Form list of this FormSet
1107 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1113 case EFI_IFR_VARSTORE_OP
:
1115 // Create a buffer Storage for this FormSet
1117 Storage
= CreateStorage (FormSet
);
1118 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1120 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1121 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1122 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1124 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1125 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1127 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1128 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1129 ASSERT (Storage
->Name
!= NULL
);
1130 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1131 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1135 // Initialize <ConfigHdr>
1137 InitializeConfigHdr (FormSet
, Storage
);
1140 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1142 // Create a name/value Storage for this FormSet
1144 Storage
= CreateStorage (FormSet
);
1145 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1147 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1148 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1151 // Initialize <ConfigHdr>
1153 InitializeConfigHdr (FormSet
, Storage
);
1156 case EFI_IFR_VARSTORE_EFI_OP
:
1158 // Create a EFI variable Storage for this FormSet
1160 Storage
= CreateStorage (FormSet
);
1161 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1163 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1164 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1165 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1171 case EFI_IFR_DEFAULTSTORE_OP
:
1172 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1173 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1175 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1176 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1179 // Insert to DefaultStore list of this Formset
1181 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1187 case EFI_IFR_SUBTITLE_OP
:
1188 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1189 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1192 mInScopeSubtitle
= TRUE
;
1196 case EFI_IFR_TEXT_OP
:
1197 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1199 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1205 case EFI_IFR_ACTION_OP
:
1206 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1208 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1210 // No QuestionConfig present, so no configuration string will be processed
1212 CurrentStatement
->QuestionConfig
= 0;
1214 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1218 case EFI_IFR_RESET_BUTTON_OP
:
1219 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1221 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1224 case EFI_IFR_REF_OP
:
1225 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1227 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1228 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1229 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1231 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1232 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1234 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1235 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1241 case EFI_IFR_ONE_OF_OP
:
1242 case EFI_IFR_NUMERIC_OP
:
1243 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1245 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1246 Value
= &CurrentStatement
->HiiValue
;
1248 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1249 case EFI_IFR_NUMERIC_SIZE_1
:
1250 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1251 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1252 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1253 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1254 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1257 case EFI_IFR_NUMERIC_SIZE_2
:
1258 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1259 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1260 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1261 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1262 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1265 case EFI_IFR_NUMERIC_SIZE_4
:
1266 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1267 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1268 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1269 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1270 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1273 case EFI_IFR_NUMERIC_SIZE_8
:
1274 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1275 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1276 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1277 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1278 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1285 InitializeRequestElement (FormSet
, CurrentStatement
);
1287 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1288 SuppressForOption
= TRUE
;
1292 case EFI_IFR_ORDERED_LIST_OP
:
1293 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1295 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1296 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1297 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1298 InitializeRequestElement (FormSet
, CurrentStatement
);
1301 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1302 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1303 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1305 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1306 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1309 SuppressForOption
= TRUE
;
1313 case EFI_IFR_CHECKBOX_OP
:
1314 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1316 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1317 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1318 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1320 InitializeRequestElement (FormSet
, CurrentStatement
);
1324 case EFI_IFR_STRING_OP
:
1325 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1328 // MinSize is the minimum number of characters that can be accepted for this opcode,
1329 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1330 // The characters are stored as Unicode, so the storage width should multiply 2.
1332 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1333 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1334 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1335 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1337 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1338 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1340 InitializeRequestElement (FormSet
, CurrentStatement
);
1343 case EFI_IFR_PASSWORD_OP
:
1344 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1347 // MinSize is the minimum number of characters that can be accepted for this opcode,
1348 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1349 // The characters are stored as Unicode, so the storage width should multiply 2.
1351 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1352 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1353 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1355 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1356 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1358 InitializeRequestElement (FormSet
, CurrentStatement
);
1361 case EFI_IFR_DATE_OP
:
1362 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1364 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1365 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1367 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1368 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1370 InitializeRequestElement (FormSet
, CurrentStatement
);
1373 // Don't assign storage for RTC type of date/time
1375 CurrentStatement
->Storage
= NULL
;
1376 CurrentStatement
->StorageWidth
= 0;
1380 case EFI_IFR_TIME_OP
:
1381 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1383 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1384 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1386 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1387 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1389 InitializeRequestElement (FormSet
, CurrentStatement
);
1392 // Don't assign storage for RTC type of date/time
1394 CurrentStatement
->Storage
= NULL
;
1395 CurrentStatement
->StorageWidth
= 0;
1402 case EFI_IFR_DEFAULT_OP
:
1404 // EFI_IFR_DEFAULT appear in scope of a Question,
1405 // It creates a default value for the current question.
1406 // A Question may have more than one Default value which have different default types.
1408 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1409 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1411 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1412 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1413 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1414 ExtendValueToU64 (&CurrentDefault
->Value
);
1417 // Insert to Default Value list of current Question
1419 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1422 InScopeDefault
= TRUE
;
1429 case EFI_IFR_ONE_OF_OPTION_OP
:
1431 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1432 // It create a selection for use in current Question.
1434 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1435 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1437 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1438 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1439 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1440 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1441 ExtendValueToU64 (&CurrentOption
->Value
);
1443 if (InScopeOptionSuppress
) {
1444 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1448 // Insert to Option list of current Question
1450 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1456 case EFI_IFR_NO_SUBMIT_IF_OP
:
1457 case EFI_IFR_INCONSISTENT_IF_OP
:
1459 // Create an Expression node
1461 CurrentExpression
= CreateExpression (CurrentForm
);
1462 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1464 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1465 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1466 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1468 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1469 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1473 case EFI_IFR_SUPPRESS_IF_OP
:
1475 // Question and Option will appear in scope of this OpCode
1477 CurrentExpression
= CreateExpression (CurrentForm
);
1478 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1479 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1481 if (SuppressForOption
) {
1482 InScopeOptionSuppress
= TRUE
;
1483 OptionSuppressExpression
= CurrentExpression
;
1485 mInScopeSuppress
= TRUE
;
1486 mSuppressExpression
= CurrentExpression
;
1490 case EFI_IFR_GRAY_OUT_IF_OP
:
1492 // Questions will appear in scope of this OpCode
1494 CurrentExpression
= CreateExpression (CurrentForm
);
1495 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1496 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1498 mInScopeGrayOut
= TRUE
;
1499 mGrayOutExpression
= CurrentExpression
;
1502 case EFI_IFR_DISABLE_IF_OP
:
1504 // The DisableIf expression should only rely on constant, so it could be
1505 // evaluated at initialization and it will not be queued
1507 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1508 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1509 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1510 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1512 InScopeDisable
= TRUE
;
1513 OpCodeDisabled
= FALSE
;
1516 // Take a look at next OpCode to see whether current expression consists
1519 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1520 SingleOpCodeExpression
= TRUE
;
1527 case EFI_IFR_VALUE_OP
:
1528 CurrentExpression
= CreateExpression (CurrentForm
);
1529 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1530 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1532 if (InScopeDefault
) {
1534 // Used for default (EFI_IFR_DEFAULT)
1536 CurrentDefault
->ValueExpression
= CurrentExpression
;
1539 // If used for a question, then the question will be read-only
1541 CurrentStatement
->ValueExpression
= CurrentExpression
;
1545 case EFI_IFR_RULE_OP
:
1546 CurrentExpression
= CreateExpression (CurrentForm
);
1547 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1549 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1550 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1556 case EFI_IFR_IMAGE_OP
:
1558 // Get ScopeOpcode from top of stack
1560 PopScope (&ScopeOpCode
);
1561 PushScope (ScopeOpCode
);
1563 switch (ScopeOpCode
) {
1564 case EFI_IFR_FORM_SET_OP
:
1565 ImageId
= &FormSet
->ImageId
;
1568 case EFI_IFR_FORM_OP
:
1569 ImageId
= &CurrentForm
->ImageId
;
1572 case EFI_IFR_ONE_OF_OPTION_OP
:
1573 ImageId
= &CurrentOption
->ImageId
;
1577 ImageId
= &CurrentStatement
->ImageId
;
1581 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1587 case EFI_IFR_REFRESH_OP
:
1588 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1594 case EFI_IFR_GUID_OP
:
1595 if (CompareGuid (&gTianoHiiIfrGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1597 // Tiano specific GUIDed opcodes
1599 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1600 case EFI_IFR_EXTEND_OP_LABEL
:
1602 // just ignore label
1606 case EFI_IFR_EXTEND_OP_BANNER
:
1607 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1609 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1610 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1611 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1612 sizeof (EFI_STRING_ID
)
1617 case EFI_IFR_EXTEND_OP_CLASS
:
1618 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1621 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1622 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1635 case EFI_IFR_END_OP
:
1636 Status
= PopScope (&ScopeOpCode
);
1637 if (EFI_ERROR (Status
)) {
1642 switch (ScopeOpCode
) {
1643 case EFI_IFR_FORM_SET_OP
:
1645 // End of FormSet, update FormSet IFR binary length
1646 // to stop parsing substantial OpCodes
1648 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1651 case EFI_IFR_FORM_OP
:
1658 case EFI_IFR_ONE_OF_OPTION_OP
:
1662 CurrentOption
= NULL
;
1665 case EFI_IFR_SUBTITLE_OP
:
1666 mInScopeSubtitle
= FALSE
;
1669 case EFI_IFR_NO_SUBMIT_IF_OP
:
1670 case EFI_IFR_INCONSISTENT_IF_OP
:
1672 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1676 case EFI_IFR_SUPPRESS_IF_OP
:
1677 if (SuppressForOption
) {
1678 InScopeOptionSuppress
= FALSE
;
1680 mInScopeSuppress
= FALSE
;
1684 case EFI_IFR_GRAY_OUT_IF_OP
:
1685 mInScopeGrayOut
= FALSE
;
1688 case EFI_IFR_DISABLE_IF_OP
:
1689 InScopeDisable
= FALSE
;
1690 OpCodeDisabled
= FALSE
;
1693 case EFI_IFR_ONE_OF_OP
:
1694 case EFI_IFR_ORDERED_LIST_OP
:
1695 SuppressForOption
= FALSE
;
1698 case EFI_IFR_DEFAULT_OP
:
1699 InScopeDefault
= FALSE
;
1703 if (IsExpressionOpCode (ScopeOpCode
)) {
1704 if (InScopeDisable
) {
1706 // Evaluate DisableIf expression
1708 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1709 if (EFI_ERROR (Status
)) {
1712 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1713 return EFI_INVALID_PARAMETER
;
1716 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1718 // DisableIf Expression is only used once and not quequed, free it
1720 DestroyExpression (CurrentExpression
);
1724 // End of current Expression
1726 CurrentExpression
= NULL
;