2 Parser for IFR binary encoding.
4 Copyright (c) 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.
15 #include "UefiIfrParser.h"
16 #include "UefiIfrParserExpression.h"
17 #include "UefiIfrParserInternal.h"
18 #include "UefiIfrParserCommon.h"
21 UINT16 mStatementIndex
;
22 UINT16 mExpressionOpCodeIndex
;
24 BOOLEAN mInScopeSubtitle
;
25 BOOLEAN mInScopeSuppress
;
26 BOOLEAN mInScopeGrayOut
;
27 FORM_EXPRESSION
*mSuppressExpression
;
28 FORM_EXPRESSION
*mGrayOutExpression
;
30 EFI_GUID gZeroGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
33 Initialize Statement header members.
35 @param OpCodeData Pointer of the raw OpCode data.
36 @param FormSet Pointer of the current FormSe.
37 @param Form Pointer of the current Form.
39 @return The Statement.
42 FORM_BROWSER_STATEMENT
*
45 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
46 IN OUT FORM_BROWSER_FORM
*Form
49 FORM_BROWSER_STATEMENT
*Statement
;
50 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
54 // We are currently not in a Form Scope, so just skip this Statement
59 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
62 InitializeListHead (&Statement
->DefaultListHead
);
63 InitializeListHead (&Statement
->OptionListHead
);
64 InitializeListHead (&Statement
->InconsistentListHead
);
65 InitializeListHead (&Statement
->NoSubmitListHead
);
67 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
69 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
71 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
72 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
73 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
75 if (mInScopeSuppress
) {
76 Statement
->SuppressExpression
= mSuppressExpression
;
79 if (mInScopeGrayOut
) {
80 Statement
->GrayOutExpression
= mGrayOutExpression
;
83 Statement
->InSubtitle
= mInScopeSubtitle
;
86 // Insert this Statement into current Form
88 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
95 Initialize Question's members.
97 @param OpCodeData Pointer of the raw OpCode data.
98 @param FormSet Pointer of the current FormSet.
99 @param Form Pointer of the current Form.
101 @return The Question.
104 FORM_BROWSER_STATEMENT
*
106 IN UINT8
*OpCodeData
,
107 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
108 IN OUT FORM_BROWSER_FORM
*Form
111 FORM_BROWSER_STATEMENT
*Statement
;
112 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
114 FORMSET_STORAGE
*Storage
;
115 NAME_VALUE_NODE
*NameValueNode
;
117 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
118 if (Statement
== NULL
) {
122 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
123 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
124 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
125 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
127 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
129 if (Statement
->VarStoreId
== 0) {
131 // VarStoreId of zero indicates no variable storage
137 // Find Storage for this Question
139 Link
= GetFirstNode (&FormSet
->StorageListHead
);
140 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
141 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
143 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
144 Statement
->Storage
= Storage
;
148 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
150 ASSERT (Statement
->Storage
!= NULL
);
153 // Initialilze varname for Name/Value or EFI Variable
155 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
156 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
157 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
158 ASSERT (Statement
->VariableName
!= NULL
);
160 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
162 // Insert to Name/Value varstore list
164 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
165 ASSERT (NameValueNode
!= NULL
);
166 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
167 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
168 ASSERT (NameValueNode
->Name
!= NULL
);
169 NameValueNode
->Value
= AllocateZeroPool (0x10);
170 ASSERT (NameValueNode
->Value
!= NULL
);
171 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
172 ASSERT (NameValueNode
->EditValue
!= NULL
);
174 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
183 Allocate a FORM_EXPRESSION node.
185 @param Form The Form associated with this Expression
187 @return Pointer to a FORM_EXPRESSION data structure.
192 IN OUT FORM_BROWSER_FORM
*Form
195 FORM_EXPRESSION
*Expression
;
197 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
198 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
199 InitializeListHead (&Expression
->OpCodeListHead
);
206 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
208 @param FormSet Pointer of the current FormSet
210 @return Pointer to a FORMSET_STORAGE data structure.
215 IN FORM_BROWSER_FORMSET
*FormSet
218 FORMSET_STORAGE
*Storage
;
220 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
221 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
222 InitializeListHead (&Storage
->NameValueListHead
);
223 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
230 Create ConfigHdr string for a storage.
232 @param FormSet Pointer of the current FormSet
233 @param Storage Pointer of the storage
235 @retval EFI_SUCCESS Initialize ConfigHdr success
239 InitializeConfigHdr (
240 IN FORM_BROWSER_FORMSET
*FormSet
,
241 IN OUT FORMSET_STORAGE
*Storage
248 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
249 Name
= Storage
->Name
;
255 Status
= ConstructConfigHdr (
260 FormSet
->DriverHandle
262 if (Status
== EFI_BUFFER_TOO_SMALL
) {
263 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
264 Status
= ConstructConfigHdr (
269 FormSet
->DriverHandle
273 if (EFI_ERROR (Status
)) {
277 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
278 Storage
->SpareStrLen
= 0;
285 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
287 @param FormSet Pointer of the current FormSet.
288 @param Question The Question to be initialized.
290 @retval EFI_SUCCESS Function success.
291 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
295 InitializeRequestElement (
296 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
297 IN OUT FORM_BROWSER_STATEMENT
*Question
300 FORMSET_STORAGE
*Storage
;
304 CHAR16 RequestElement
[30];
306 Storage
= Question
->Storage
;
307 if (Storage
== NULL
) {
308 return EFI_INVALID_PARAMETER
;
311 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
313 // <ConfigRequest> is unnecessary for EFI variable storage,
314 // GetVariable()/SetVariable() will be used to retrieve/save values
320 // Prepare <RequestElement>
322 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
323 StrLen
= UnicodeSPrint (
325 30 * sizeof (CHAR16
),
326 L
"&OFFSET=%x&WIDTH=%x",
327 Question
->VarStoreInfo
.VarOffset
,
328 Question
->StorageWidth
330 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
332 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
335 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && (Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
)) {
337 // Password with CALLBACK flag is stored in encoded format,
338 // so don't need to append it to <ConfigRequest>
344 // Append <RequestElement> to <ConfigRequest>
346 if (StrLen
> Storage
->SpareStrLen
) {
348 // Old String buffer is not sufficient for RequestElement, allocate a new one
350 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
351 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
352 if (Storage
->ConfigRequest
!= NULL
) {
353 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
354 gBS
->FreePool (Storage
->ConfigRequest
);
356 Storage
->ConfigRequest
= NewStr
;
357 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
360 StrCat (Storage
->ConfigRequest
, RequestElement
);
361 Storage
->ElementCount
++;
362 Storage
->SpareStrLen
-= StrLen
;
369 Free resources of a Expression
371 @param FormSet Pointer of the Expression
378 IN FORM_EXPRESSION
*Expression
382 EXPRESSION_OPCODE
*OpCode
;
384 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
385 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
386 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
387 RemoveEntryList (&OpCode
->Link
);
389 SafeFreePool (OpCode
->ValueList
);
393 // Free this Expression
395 gBS
->FreePool (Expression
);
400 Free resources of a storage
402 @param Storage Pointer of the storage
409 IN FORMSET_STORAGE
*Storage
413 NAME_VALUE_NODE
*NameValueNode
;
415 if (Storage
== NULL
) {
419 SafeFreePool (Storage
->Name
);
420 SafeFreePool (Storage
->Buffer
);
421 SafeFreePool (Storage
->EditBuffer
);
423 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
424 Link
= GetFirstNode (&Storage
->NameValueListHead
);
425 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
426 RemoveEntryList (&NameValueNode
->Link
);
428 SafeFreePool (NameValueNode
->Name
);
429 SafeFreePool (NameValueNode
->Value
);
430 SafeFreePool (NameValueNode
->EditValue
);
431 SafeFreePool (NameValueNode
);
434 SafeFreePool (Storage
->ConfigHdr
);
435 SafeFreePool (Storage
->ConfigRequest
);
437 gBS
->FreePool (Storage
);
442 Free resources of a Statement
444 @param Statement Pointer of the Statement
451 IN OUT FORM_BROWSER_STATEMENT
*Statement
455 QUESTION_DEFAULT
*Default
;
456 QUESTION_OPTION
*Option
;
457 FORM_EXPRESSION
*Expression
;
460 // Free Default value List
462 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
463 Link
= GetFirstNode (&Statement
->DefaultListHead
);
464 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
465 RemoveEntryList (&Default
->Link
);
467 gBS
->FreePool (Default
);
473 while (!IsListEmpty (&Statement
->OptionListHead
)) {
474 Link
= GetFirstNode (&Statement
->OptionListHead
);
475 Option
= QUESTION_OPTION_FROM_LINK (Link
);
476 RemoveEntryList (&Option
->Link
);
478 gBS
->FreePool (Option
);
482 // Free Inconsistent List
484 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
485 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
486 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
487 RemoveEntryList (&Expression
->Link
);
489 DestroyExpression (Expression
);
493 // Free NoSubmit List
495 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
496 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
497 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
498 RemoveEntryList (&Expression
->Link
);
500 DestroyExpression (Expression
);
503 SafeFreePool (Statement
->VariableName
);
504 SafeFreePool (Statement
->BlockName
);
509 Free resources of a Form
511 @param Form Pointer of the Form
518 IN OUT FORM_BROWSER_FORM
*Form
522 FORM_EXPRESSION
*Expression
;
523 FORM_BROWSER_STATEMENT
*Statement
;
526 // Free Form Expressions
528 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
529 Link
= GetFirstNode (&Form
->ExpressionListHead
);
530 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
531 RemoveEntryList (&Expression
->Link
);
533 DestroyExpression (Expression
);
537 // Free Statements/Questions
539 while (!IsListEmpty (&Form
->StatementListHead
)) {
540 Link
= GetFirstNode (&Form
->StatementListHead
);
541 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
542 RemoveEntryList (&Statement
->Link
);
544 DestroyStatement (Statement
);
550 gBS
->FreePool (Form
);
555 Free resources allocated for a FormSet
557 @param FormSet Pointer of the FormSet
564 IN OUT FORM_BROWSER_FORMSET
*FormSet
568 FORMSET_STORAGE
*Storage
;
569 FORMSET_DEFAULTSTORE
*DefaultStore
;
570 FORM_BROWSER_FORM
*Form
;
573 // Free IFR binary buffer
575 SafeFreePool (FormSet
->IfrBinaryData
);
578 // Free FormSet Storage
580 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
581 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
582 Link
= GetFirstNode (&FormSet
->StorageListHead
);
583 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
584 RemoveEntryList (&Storage
->Link
);
586 DestroyStorage (Storage
);
591 // Free FormSet Default Store
593 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
594 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
595 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
596 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
597 RemoveEntryList (&DefaultStore
->Link
);
599 gBS
->FreePool (DefaultStore
);
606 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
607 while (!IsListEmpty (&FormSet
->FormListHead
)) {
608 Link
= GetFirstNode (&FormSet
->FormListHead
);
609 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
610 RemoveEntryList (&Form
->Link
);
616 SafeFreePool (FormSet
->StatementBuffer
);
617 SafeFreePool (FormSet
->ExpressionBuffer
);
619 SafeFreePool (FormSet
);
624 Tell whether this Operand is an Expression OpCode or not
626 @param Operand Operand of an IFR OpCode.
628 @retval TRUE This is an Expression OpCode.
629 @retval FALSE Not an Expression OpCode.
637 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
638 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
639 (Operand
== EFI_IFR_CATENATE_OP
)
649 Calculate number of Statemens(Questions) and Expression OpCodes.
651 @param FormSet The FormSet to be counted.
652 @param NumberOfStatement Number of Statemens(Questions)
653 @param NumberOfExpression Number of Expression OpCodes
660 IN FORM_BROWSER_FORMSET
*FormSet
,
661 IN OUT UINT16
*NumberOfStatement
,
662 IN OUT UINT16
*NumberOfExpression
665 UINT16 StatementCount
;
666 UINT16 ExpressionCount
;
675 while (Offset
< FormSet
->IfrBinaryLength
) {
676 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
677 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
680 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
687 *NumberOfStatement
= StatementCount
;
688 *NumberOfExpression
= ExpressionCount
;
693 Parse opcodes in the formset IFR binary.
695 @param FormSet Pointer of the FormSet data structure.
697 @retval EFI_SUCCESS Opcode parse success.
698 @retval Other Opcode parse fail.
703 IN FORM_BROWSER_FORMSET
*FormSet
708 FORM_BROWSER_FORM
*CurrentForm
;
709 FORM_BROWSER_STATEMENT
*CurrentStatement
;
710 EXPRESSION_OPCODE
*ExpressionOpCode
;
711 FORM_EXPRESSION
*CurrentExpression
;
718 FORMSET_STORAGE
*Storage
;
719 FORMSET_DEFAULTSTORE
*DefaultStore
;
720 QUESTION_DEFAULT
*CurrentDefault
;
721 QUESTION_OPTION
*CurrentOption
;
723 UINT16 NumberOfStatement
;
724 UINT16 NumberOfExpression
;
725 EFI_IMAGE_ID
*ImageId
;
726 BOOLEAN SuppressForOption
;
727 BOOLEAN InScopeOptionSuppress
;
728 FORM_EXPRESSION
*OptionSuppressExpression
;
729 BOOLEAN InScopeDisable
;
730 UINT16 DepthOfDisable
;
731 BOOLEAN OpCodeDisabled
;
732 BOOLEAN SingleOpCodeExpression
;
733 BOOLEAN InScopeDefault
;
734 EFI_HII_VALUE
*Value
;
736 mInScopeSubtitle
= FALSE
;
737 SuppressForOption
= FALSE
;
738 mInScopeSuppress
= FALSE
;
739 InScopeOptionSuppress
= FALSE
;
740 mInScopeGrayOut
= FALSE
;
741 InScopeDisable
= FALSE
;
743 OpCodeDisabled
= FALSE
;
744 SingleOpCodeExpression
= FALSE
;
745 InScopeDefault
= FALSE
;
746 CurrentExpression
= NULL
;
747 CurrentDefault
= NULL
;
748 CurrentOption
= NULL
;
749 OptionSuppressExpression
= NULL
;
752 // Get the number of Statements and Expressions
754 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
757 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
758 if (FormSet
->StatementBuffer
== NULL
) {
759 return EFI_OUT_OF_RESOURCES
;
762 mExpressionOpCodeIndex
= 0;
763 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
764 if (FormSet
->ExpressionBuffer
== NULL
) {
765 return EFI_OUT_OF_RESOURCES
;
768 InitializeListHead (&FormSet
->StorageListHead
);
769 InitializeListHead (&FormSet
->DefaultStoreListHead
);
770 InitializeListHead (&FormSet
->FormListHead
);
773 CurrentStatement
= NULL
;
778 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
779 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
781 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
782 OpCodeOffset
+= OpCodeLength
;
783 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
784 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
787 // If scope bit set, push onto scope stack
793 if (OpCodeDisabled
) {
795 // DisableIf Expression is evaluated to be TRUE, try to find its end.
796 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
798 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
800 } else if (Operand
== EFI_IFR_END_OP
) {
801 Status
= PopScope (&ScopeOpCode
);
802 if (EFI_ERROR (Status
)) {
806 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
807 if (DepthOfDisable
== 0) {
808 InScopeDisable
= FALSE
;
809 OpCodeDisabled
= FALSE
;
818 if (IsExpressionOpCode (Operand
)) {
819 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
820 mExpressionOpCodeIndex
++;
822 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
823 ExpressionOpCode
->Operand
= Operand
;
824 Value
= &ExpressionOpCode
->Value
;
827 case EFI_IFR_EQ_ID_VAL_OP
:
828 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
830 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
831 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
834 case EFI_IFR_EQ_ID_ID_OP
:
835 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
836 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
839 case EFI_IFR_EQ_ID_LIST_OP
:
840 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
841 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
842 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
845 case EFI_IFR_TO_STRING_OP
:
846 case EFI_IFR_FIND_OP
:
847 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
850 case EFI_IFR_STRING_REF1_OP
:
851 Value
->Type
= EFI_IFR_TYPE_STRING
;
852 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
855 case EFI_IFR_RULE_REF_OP
:
856 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
859 case EFI_IFR_SPAN_OP
:
860 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
863 case EFI_IFR_THIS_OP
:
864 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
867 case EFI_IFR_QUESTION_REF1_OP
:
868 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
871 case EFI_IFR_QUESTION_REF3_OP
:
872 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
873 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
875 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
876 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
884 case EFI_IFR_TRUE_OP
:
885 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
886 Value
->Value
.b
= TRUE
;
889 case EFI_IFR_FALSE_OP
:
890 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
891 Value
->Value
.b
= FALSE
;
895 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
899 case EFI_IFR_ZERO_OP
:
900 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
904 case EFI_IFR_ONES_OP
:
905 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
906 Value
->Value
.u64
= 0xffffffffffffffffULL
;
909 case EFI_IFR_UINT8_OP
:
910 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
911 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
914 case EFI_IFR_UINT16_OP
:
915 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
916 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
919 case EFI_IFR_UINT32_OP
:
920 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
921 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
924 case EFI_IFR_UINT64_OP
:
925 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
926 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
929 case EFI_IFR_UNDEFINED_OP
:
930 Value
->Type
= EFI_IFR_TYPE_OTHER
;
933 case EFI_IFR_VERSION_OP
:
934 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
935 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
942 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
944 if (SingleOpCodeExpression
) {
946 // There are two cases to indicate the end of an Expression:
947 // for single OpCode expression: one Expression OpCode
948 // for expression consists of more than one OpCode: EFI_IFR_END
950 SingleOpCodeExpression
= FALSE
;
952 if (InScopeDisable
) {
954 // Evaluate DisableIf expression
956 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
957 if (EFI_ERROR (Status
)) {
960 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
961 return EFI_INVALID_PARAMETER
;
964 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
967 CurrentExpression
= NULL
;
978 case EFI_IFR_FORM_SET_OP
:
980 // check the formset GUID
982 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
983 return EFI_INVALID_PARAMETER
;
986 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
987 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
990 case EFI_IFR_FORM_OP
:
992 // Create a new Form for this FormSet
994 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
995 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
996 InitializeListHead (&CurrentForm
->ExpressionListHead
);
997 InitializeListHead (&CurrentForm
->StatementListHead
);
999 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1000 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1003 // Insert into Form list of this FormSet
1005 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1011 case EFI_IFR_VARSTORE_OP
:
1013 // Create a buffer Storage for this FormSet
1015 Storage
= CreateStorage (FormSet
);
1016 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1018 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1019 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1020 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1022 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1023 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1025 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1026 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1027 ASSERT (Storage
->Name
!= NULL
);
1028 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1029 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1033 // Initialize <ConfigHdr>
1035 InitializeConfigHdr (FormSet
, Storage
);
1038 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1040 // Create a name/value Storage for this FormSet
1042 Storage
= CreateStorage (FormSet
);
1043 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1045 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1046 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1049 // Initialize <ConfigHdr>
1051 InitializeConfigHdr (FormSet
, Storage
);
1054 case EFI_IFR_VARSTORE_EFI_OP
:
1056 // Create a EFI variable Storage for this FormSet
1058 Storage
= CreateStorage (FormSet
);
1059 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1061 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1062 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1063 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1069 case EFI_IFR_DEFAULTSTORE_OP
:
1070 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1071 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1073 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1074 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1077 // Insert to DefaultStore list of this Formset
1079 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1085 case EFI_IFR_SUBTITLE_OP
:
1086 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1087 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1090 mInScopeSubtitle
= TRUE
;
1094 case EFI_IFR_TEXT_OP
:
1095 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1097 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1103 case EFI_IFR_ACTION_OP
:
1104 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1106 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1108 // No QuestionConfig present, so no configuration string will be processed
1110 CurrentStatement
->QuestionConfig
= 0;
1112 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1116 case EFI_IFR_RESET_BUTTON_OP
:
1117 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1119 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1122 case EFI_IFR_REF_OP
:
1123 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1125 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1126 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1127 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1129 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1130 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1132 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1133 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1139 case EFI_IFR_ONE_OF_OP
:
1140 case EFI_IFR_NUMERIC_OP
:
1141 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1143 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1144 Value
= &CurrentStatement
->HiiValue
;
1146 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1147 case EFI_IFR_NUMERIC_SIZE_1
:
1148 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1149 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1150 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1151 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1152 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1155 case EFI_IFR_NUMERIC_SIZE_2
:
1156 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1157 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1158 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1159 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1160 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1163 case EFI_IFR_NUMERIC_SIZE_4
:
1164 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1165 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1166 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1167 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1168 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1171 case EFI_IFR_NUMERIC_SIZE_8
:
1172 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1173 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1174 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1175 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1176 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1183 InitializeRequestElement (FormSet
, CurrentStatement
);
1185 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
) {
1186 SuppressForOption
= TRUE
;
1190 case EFI_IFR_ORDERED_LIST_OP
:
1191 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1193 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1194 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1195 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1196 InitializeRequestElement (FormSet
, CurrentStatement
);
1199 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1200 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1201 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1203 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1204 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1207 SuppressForOption
= TRUE
;
1211 case EFI_IFR_CHECKBOX_OP
:
1212 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1214 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1215 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1216 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1218 InitializeRequestElement (FormSet
, CurrentStatement
);
1221 case EFI_IFR_STRING_OP
:
1222 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1225 // MinSize is the minimum number of characters that can be accepted for this opcode,
1226 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1227 // The characters are stored as Unicode, so the storage width should multiply 2.
1229 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1230 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1231 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (UINT16
));
1232 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1234 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1235 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1237 InitializeRequestElement (FormSet
, CurrentStatement
);
1240 case EFI_IFR_PASSWORD_OP
:
1241 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1244 // MinSize is the minimum number of characters that can be accepted for this opcode,
1245 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1246 // The characters are stored as Unicode, so the storage width should multiply 2.
1248 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1249 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1250 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (UINT16
));
1252 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1253 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1255 InitializeRequestElement (FormSet
, CurrentStatement
);
1258 case EFI_IFR_DATE_OP
:
1259 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1261 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1262 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1264 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1265 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1267 InitializeRequestElement (FormSet
, CurrentStatement
);
1270 // Don't assign storage for RTC type of date/time
1272 CurrentStatement
->Storage
= NULL
;
1273 CurrentStatement
->StorageWidth
= 0;
1277 case EFI_IFR_TIME_OP
:
1278 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1280 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1281 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1283 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1284 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1286 InitializeRequestElement (FormSet
, CurrentStatement
);
1289 // Don't assign storage for RTC type of date/time
1291 CurrentStatement
->Storage
= NULL
;
1292 CurrentStatement
->StorageWidth
= 0;
1299 case EFI_IFR_DEFAULT_OP
:
1301 // EFI_IFR_DEFAULT appear in scope of a Question,
1302 // It creates a default value for the current question.
1303 // A Question may have more than one Default value which have different default types.
1305 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1306 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1308 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1309 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1310 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1311 ExtendValueToU64 (&CurrentDefault
->Value
);
1314 // Insert to Default Value list of current Question
1316 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1319 InScopeDefault
= TRUE
;
1326 case EFI_IFR_ONE_OF_OPTION_OP
:
1328 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1329 // It create a selection for use in current Question.
1331 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1332 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1334 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1335 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1336 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1337 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1338 ExtendValueToU64 (&CurrentOption
->Value
);
1340 if (InScopeOptionSuppress
) {
1341 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1345 // Insert to Option list of current Question
1347 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1353 case EFI_IFR_NO_SUBMIT_IF_OP
:
1354 case EFI_IFR_INCONSISTENT_IF_OP
:
1356 // Create an Expression node
1358 CurrentExpression
= CreateExpression (CurrentForm
);
1359 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1361 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1362 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1363 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1365 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1366 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1370 case EFI_IFR_SUPPRESS_IF_OP
:
1372 // Question and Option will appear in scope of this OpCode
1374 CurrentExpression
= CreateExpression (CurrentForm
);
1375 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1376 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1378 if (SuppressForOption
) {
1379 InScopeOptionSuppress
= TRUE
;
1380 OptionSuppressExpression
= CurrentExpression
;
1382 mInScopeSuppress
= TRUE
;
1383 mSuppressExpression
= CurrentExpression
;
1387 case EFI_IFR_GRAY_OUT_IF_OP
:
1389 // Questions will appear in scope of this OpCode
1391 CurrentExpression
= CreateExpression (CurrentForm
);
1392 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1393 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1395 mInScopeGrayOut
= TRUE
;
1396 mGrayOutExpression
= CurrentExpression
;
1399 case EFI_IFR_DISABLE_IF_OP
:
1401 // The DisableIf expression should only rely on constant, so it could be
1402 // evaluated at initialization and it will not be queued
1404 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1405 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1406 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1407 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1409 InScopeDisable
= TRUE
;
1410 OpCodeDisabled
= FALSE
;
1413 // Take a look at next OpCode to see whether current expression consists
1416 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1417 SingleOpCodeExpression
= TRUE
;
1424 case EFI_IFR_VALUE_OP
:
1425 CurrentExpression
= CreateExpression (CurrentForm
);
1426 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1427 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1429 if (InScopeDefault
) {
1431 // Used for default (EFI_IFR_DEFAULT)
1433 CurrentDefault
->ValueExpression
= CurrentExpression
;
1436 // If used for a question, then the question will be read-only
1438 CurrentStatement
->ValueExpression
= CurrentExpression
;
1442 case EFI_IFR_RULE_OP
:
1443 CurrentExpression
= CreateExpression (CurrentForm
);
1444 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1446 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1447 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1453 case EFI_IFR_IMAGE_OP
:
1455 // Get ScopeOpcode from top of stack
1457 PopScope (&ScopeOpCode
);
1458 PushScope (ScopeOpCode
);
1460 switch (ScopeOpCode
) {
1461 case EFI_IFR_FORM_SET_OP
:
1462 ImageId
= &FormSet
->ImageId
;
1465 case EFI_IFR_FORM_OP
:
1466 ImageId
= &CurrentForm
->ImageId
;
1469 case EFI_IFR_ONE_OF_OPTION_OP
:
1470 ImageId
= &CurrentOption
->ImageId
;
1474 ImageId
= &CurrentStatement
->ImageId
;
1478 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1484 case EFI_IFR_REFRESH_OP
:
1485 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1491 case EFI_IFR_GUID_OP
:
1492 if (CompareGuid (&gTianoHiiIfrGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1494 // Tiano specific GUIDed opcodes
1496 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1497 case EFI_IFR_EXTEND_OP_LABEL
:
1499 // just ignore label
1504 case EFI_IFR_EXTEND_OP_BANNER
:
1505 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1507 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1508 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1509 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1510 sizeof (EFI_STRING_ID
)
1516 case EFI_IFR_EXTEND_OP_CLASS
:
1517 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1520 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1521 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1533 case EFI_IFR_END_OP
:
1534 Status
= PopScope (&ScopeOpCode
);
1535 if (EFI_ERROR (Status
)) {
1540 switch (ScopeOpCode
) {
1541 case EFI_IFR_FORM_SET_OP
:
1543 // End of FormSet, update FormSet IFR binary length
1544 // to stop parsing substantial OpCodes
1546 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1549 case EFI_IFR_FORM_OP
:
1556 case EFI_IFR_ONE_OF_OPTION_OP
:
1560 CurrentOption
= NULL
;
1563 case EFI_IFR_SUBTITLE_OP
:
1564 mInScopeSubtitle
= FALSE
;
1567 case EFI_IFR_NO_SUBMIT_IF_OP
:
1568 case EFI_IFR_INCONSISTENT_IF_OP
:
1570 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1574 case EFI_IFR_SUPPRESS_IF_OP
:
1575 if (SuppressForOption
) {
1576 InScopeOptionSuppress
= FALSE
;
1578 mInScopeSuppress
= FALSE
;
1582 case EFI_IFR_GRAY_OUT_IF_OP
:
1583 mInScopeGrayOut
= FALSE
;
1586 case EFI_IFR_DISABLE_IF_OP
:
1587 InScopeDisable
= FALSE
;
1588 OpCodeDisabled
= FALSE
;
1591 case EFI_IFR_ONE_OF_OP
:
1592 case EFI_IFR_ORDERED_LIST_OP
:
1593 SuppressForOption
= FALSE
;
1596 case EFI_IFR_DEFAULT_OP
:
1597 InScopeDefault
= FALSE
;
1601 if (IsExpressionOpCode (ScopeOpCode
)) {
1602 if (InScopeDisable
) {
1604 // Evaluate DisableIf expression
1606 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1607 if (EFI_ERROR (Status
)) {
1610 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1611 return EFI_INVALID_PARAMETER
;
1614 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1616 // DisableIf Expression is only used once and not quequed, free it
1618 DestroyExpression (CurrentExpression
);
1622 // End of current Expression
1624 CurrentExpression
= NULL
;