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
;
31 Initialize Statement header members.
33 @param OpCodeData Pointer of the raw OpCode data.
34 @param FormSet Pointer of the current FormSe.
35 @param Form Pointer of the current Form.
37 @return The Statement.
40 FORM_BROWSER_STATEMENT
*
43 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
44 IN OUT FORM_BROWSER_FORM
*Form
47 FORM_BROWSER_STATEMENT
*Statement
;
48 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
52 // We are currently not in a Form Scope, so just skip this Statement
57 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
60 InitializeListHead (&Statement
->DefaultListHead
);
61 InitializeListHead (&Statement
->OptionListHead
);
62 InitializeListHead (&Statement
->InconsistentListHead
);
63 InitializeListHead (&Statement
->NoSubmitListHead
);
65 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
67 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
69 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
70 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
71 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
73 if (mInScopeSuppress
) {
74 Statement
->SuppressExpression
= mSuppressExpression
;
77 if (mInScopeGrayOut
) {
78 Statement
->GrayOutExpression
= mGrayOutExpression
;
81 Statement
->InSubtitle
= mInScopeSubtitle
;
84 // Insert this Statement into current Form
86 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
93 Initialize Question's members.
95 @param OpCodeData Pointer of the raw OpCode data.
96 @param FormSet Pointer of the current FormSet.
97 @param Form Pointer of the current Form.
102 FORM_BROWSER_STATEMENT
*
104 IN UINT8
*OpCodeData
,
105 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
106 IN OUT FORM_BROWSER_FORM
*Form
109 FORM_BROWSER_STATEMENT
*Statement
;
110 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
112 FORMSET_STORAGE
*Storage
;
113 NAME_VALUE_NODE
*NameValueNode
;
115 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
116 if (Statement
== NULL
) {
120 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
121 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
122 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
123 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
125 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
127 if (Statement
->VarStoreId
== 0) {
129 // VarStoreId of zero indicates no variable storage
135 // Find Storage for this Question
137 Link
= GetFirstNode (&FormSet
->StorageListHead
);
138 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
139 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
141 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
142 Statement
->Storage
= Storage
;
146 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
148 ASSERT (Statement
->Storage
!= NULL
);
151 // Initialilze varname for Name/Value or EFI Variable
153 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
154 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
155 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
156 ASSERT (Statement
->VariableName
!= NULL
);
158 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
160 // Insert to Name/Value varstore list
162 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
163 ASSERT (NameValueNode
!= NULL
);
164 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
165 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
166 ASSERT (NameValueNode
->Name
!= NULL
);
167 NameValueNode
->Value
= AllocateZeroPool (0x10);
168 ASSERT (NameValueNode
->Value
!= NULL
);
169 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
170 ASSERT (NameValueNode
->EditValue
!= NULL
);
172 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
181 Allocate a FORM_EXPRESSION node.
183 @param Form The Form associated with this Expression
185 @return Pointer to a FORM_EXPRESSION data structure.
190 IN OUT FORM_BROWSER_FORM
*Form
193 FORM_EXPRESSION
*Expression
;
195 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
196 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
197 InitializeListHead (&Expression
->OpCodeListHead
);
204 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
206 @param FormSet Pointer of the current FormSet
208 @return Pointer to a FORMSET_STORAGE data structure.
213 IN FORM_BROWSER_FORMSET
*FormSet
216 FORMSET_STORAGE
*Storage
;
218 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
219 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
220 InitializeListHead (&Storage
->NameValueListHead
);
221 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
228 Create ConfigHdr string for a storage.
230 @param FormSet Pointer of the current FormSet
231 @param Storage Pointer of the storage
233 @retval EFI_SUCCESS Initialize ConfigHdr success
237 InitializeConfigHdr (
238 IN FORM_BROWSER_FORMSET
*FormSet
,
239 IN OUT FORMSET_STORAGE
*Storage
246 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
247 Name
= Storage
->Name
;
253 Status
= ConstructConfigHdr (
258 FormSet
->DriverHandle
260 if (Status
== EFI_BUFFER_TOO_SMALL
) {
261 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
262 Status
= ConstructConfigHdr (
267 FormSet
->DriverHandle
271 if (EFI_ERROR (Status
)) {
275 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
276 Storage
->SpareStrLen
= 0;
283 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
285 @param FormSet Pointer of the current FormSet.
286 @param Question The Question to be initialized.
288 @retval EFI_SUCCESS Function success.
289 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
293 InitializeRequestElement (
294 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
295 IN OUT FORM_BROWSER_STATEMENT
*Question
298 FORMSET_STORAGE
*Storage
;
302 CHAR16 RequestElement
[30];
304 Storage
= Question
->Storage
;
305 if (Storage
== NULL
) {
306 return EFI_INVALID_PARAMETER
;
309 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
311 // <ConfigRequest> is unnecessary for EFI variable storage,
312 // GetVariable()/SetVariable() will be used to retrieve/save values
318 // Prepare <RequestElement>
320 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
321 StrLen
= UnicodeSPrint (
323 30 * sizeof (CHAR16
),
324 L
"&OFFSET=%x&WIDTH=%x",
325 Question
->VarStoreInfo
.VarOffset
,
326 Question
->StorageWidth
328 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
330 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
333 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
335 // Password with CALLBACK flag is stored in encoded format,
336 // so don't need to append it to <ConfigRequest>
342 // Append <RequestElement> to <ConfigRequest>
344 if (StrLen
> Storage
->SpareStrLen
) {
346 // Old String buffer is not sufficient for RequestElement, allocate a new one
348 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
349 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
350 if (Storage
->ConfigRequest
!= NULL
) {
351 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
352 gBS
->FreePool (Storage
->ConfigRequest
);
354 Storage
->ConfigRequest
= NewStr
;
355 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
358 StrCat (Storage
->ConfigRequest
, RequestElement
);
359 Storage
->ElementCount
++;
360 Storage
->SpareStrLen
-= StrLen
;
367 Free resources of a Expression.
369 @param FormSet Pointer of the Expression
374 IN FORM_EXPRESSION
*Expression
378 EXPRESSION_OPCODE
*OpCode
;
380 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
381 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
382 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
383 RemoveEntryList (&OpCode
->Link
);
385 SafeFreePool (OpCode
->ValueList
);
389 // Free this Expression
391 gBS
->FreePool (Expression
);
396 Free resources of a storage.
398 @param Storage Pointer of the storage
403 IN FORMSET_STORAGE
*Storage
407 NAME_VALUE_NODE
*NameValueNode
;
409 if (Storage
== NULL
) {
413 SafeFreePool (Storage
->Name
);
414 SafeFreePool (Storage
->Buffer
);
415 SafeFreePool (Storage
->EditBuffer
);
417 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
418 Link
= GetFirstNode (&Storage
->NameValueListHead
);
419 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
420 RemoveEntryList (&NameValueNode
->Link
);
422 SafeFreePool (NameValueNode
->Name
);
423 SafeFreePool (NameValueNode
->Value
);
424 SafeFreePool (NameValueNode
->EditValue
);
425 SafeFreePool (NameValueNode
);
428 SafeFreePool (Storage
->ConfigHdr
);
429 SafeFreePool (Storage
->ConfigRequest
);
431 gBS
->FreePool (Storage
);
436 Free resources of a Statement.
438 @param Statement Pointer of the Statement
443 IN OUT FORM_BROWSER_STATEMENT
*Statement
447 QUESTION_DEFAULT
*Default
;
448 QUESTION_OPTION
*Option
;
449 FORM_EXPRESSION
*Expression
;
452 // Free Default value List
454 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
455 Link
= GetFirstNode (&Statement
->DefaultListHead
);
456 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
457 RemoveEntryList (&Default
->Link
);
459 gBS
->FreePool (Default
);
465 while (!IsListEmpty (&Statement
->OptionListHead
)) {
466 Link
= GetFirstNode (&Statement
->OptionListHead
);
467 Option
= QUESTION_OPTION_FROM_LINK (Link
);
468 RemoveEntryList (&Option
->Link
);
470 gBS
->FreePool (Option
);
474 // Free Inconsistent List
476 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
477 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
478 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
479 RemoveEntryList (&Expression
->Link
);
481 DestroyExpression (Expression
);
485 // Free NoSubmit List
487 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
488 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
489 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
490 RemoveEntryList (&Expression
->Link
);
492 DestroyExpression (Expression
);
495 SafeFreePool (Statement
->VariableName
);
496 SafeFreePool (Statement
->BlockName
);
501 Free resources of a Form.
503 @param Form Pointer of the Form.
508 IN OUT FORM_BROWSER_FORM
*Form
512 FORM_EXPRESSION
*Expression
;
513 FORM_BROWSER_STATEMENT
*Statement
;
516 // Free Form Expressions
518 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
519 Link
= GetFirstNode (&Form
->ExpressionListHead
);
520 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
521 RemoveEntryList (&Expression
->Link
);
523 DestroyExpression (Expression
);
527 // Free Statements/Questions
529 while (!IsListEmpty (&Form
->StatementListHead
)) {
530 Link
= GetFirstNode (&Form
->StatementListHead
);
531 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
532 RemoveEntryList (&Statement
->Link
);
534 DestroyStatement (Statement
);
540 gBS
->FreePool (Form
);
545 Free resources allocated for a FormSet.
547 @param FormSet Pointer of the FormSet
552 IN OUT FORM_BROWSER_FORMSET
*FormSet
556 FORMSET_STORAGE
*Storage
;
557 FORMSET_DEFAULTSTORE
*DefaultStore
;
558 FORM_BROWSER_FORM
*Form
;
561 // Free IFR binary buffer
563 SafeFreePool (FormSet
->IfrBinaryData
);
566 // Free FormSet Storage
568 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
569 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
570 Link
= GetFirstNode (&FormSet
->StorageListHead
);
571 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
572 RemoveEntryList (&Storage
->Link
);
574 DestroyStorage (Storage
);
579 // Free FormSet Default Store
581 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
582 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
583 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
584 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
585 RemoveEntryList (&DefaultStore
->Link
);
587 gBS
->FreePool (DefaultStore
);
594 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
595 while (!IsListEmpty (&FormSet
->FormListHead
)) {
596 Link
= GetFirstNode (&FormSet
->FormListHead
);
597 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
598 RemoveEntryList (&Form
->Link
);
604 SafeFreePool (FormSet
->StatementBuffer
);
605 SafeFreePool (FormSet
->ExpressionBuffer
);
607 SafeFreePool (FormSet
);
612 Tell whether this Operand is an Expression OpCode or not
614 @param Operand Operand of an IFR OpCode.
616 @retval TRUE This is an Expression OpCode.
617 @retval FALSE Not an Expression OpCode.
625 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
626 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
627 (Operand
== EFI_IFR_CATENATE_OP
)
637 Calculate number of Statemens(Questions) and Expression OpCodes.
639 @param FormSet The FormSet to be counted.
640 @param NumberOfStatement Number of Statemens(Questions)
641 @param NumberOfExpression Number of Expression OpCodes
646 IN FORM_BROWSER_FORMSET
*FormSet
,
647 IN OUT UINT16
*NumberOfStatement
,
648 IN OUT UINT16
*NumberOfExpression
651 UINT16 StatementCount
;
652 UINT16 ExpressionCount
;
661 while (Offset
< FormSet
->IfrBinaryLength
) {
662 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
663 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
666 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
673 *NumberOfStatement
= StatementCount
;
674 *NumberOfExpression
= ExpressionCount
;
679 Parse opcodes in the formset IFR binary.
681 @param FormSet Pointer of the FormSet data structure.
683 @retval EFI_SUCCESS Opcode parse success.
684 @retval Other Opcode parse fail.
689 IN FORM_BROWSER_FORMSET
*FormSet
694 FORM_BROWSER_FORM
*CurrentForm
;
695 FORM_BROWSER_STATEMENT
*CurrentStatement
;
696 EXPRESSION_OPCODE
*ExpressionOpCode
;
697 FORM_EXPRESSION
*CurrentExpression
;
704 FORMSET_STORAGE
*Storage
;
705 FORMSET_DEFAULTSTORE
*DefaultStore
;
706 QUESTION_DEFAULT
*CurrentDefault
;
707 QUESTION_OPTION
*CurrentOption
;
709 UINT16 NumberOfStatement
;
710 UINT16 NumberOfExpression
;
711 EFI_IMAGE_ID
*ImageId
;
712 BOOLEAN SuppressForOption
;
713 BOOLEAN InScopeOptionSuppress
;
714 FORM_EXPRESSION
*OptionSuppressExpression
;
715 BOOLEAN InScopeDisable
;
716 UINT16 DepthOfDisable
;
717 BOOLEAN OpCodeDisabled
;
718 BOOLEAN SingleOpCodeExpression
;
719 BOOLEAN InScopeDefault
;
720 EFI_HII_VALUE
*Value
;
722 mInScopeSubtitle
= FALSE
;
723 SuppressForOption
= FALSE
;
724 mInScopeSuppress
= FALSE
;
725 InScopeOptionSuppress
= FALSE
;
726 mInScopeGrayOut
= FALSE
;
727 InScopeDisable
= FALSE
;
729 OpCodeDisabled
= FALSE
;
730 SingleOpCodeExpression
= FALSE
;
731 InScopeDefault
= FALSE
;
732 CurrentExpression
= NULL
;
733 CurrentDefault
= NULL
;
734 CurrentOption
= NULL
;
735 OptionSuppressExpression
= NULL
;
738 // Get the number of Statements and Expressions
740 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
743 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
744 if (FormSet
->StatementBuffer
== NULL
) {
745 return EFI_OUT_OF_RESOURCES
;
748 mExpressionOpCodeIndex
= 0;
749 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
750 if (FormSet
->ExpressionBuffer
== NULL
) {
751 return EFI_OUT_OF_RESOURCES
;
754 InitializeListHead (&FormSet
->StorageListHead
);
755 InitializeListHead (&FormSet
->DefaultStoreListHead
);
756 InitializeListHead (&FormSet
->FormListHead
);
759 CurrentStatement
= NULL
;
764 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
765 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
767 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
768 OpCodeOffset
+= OpCodeLength
;
769 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
770 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
773 // If scope bit set, push onto scope stack
779 if (OpCodeDisabled
) {
781 // DisableIf Expression is evaluated to be TRUE, try to find its end.
782 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
784 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
786 } else if (Operand
== EFI_IFR_END_OP
) {
787 Status
= PopScope (&ScopeOpCode
);
788 if (EFI_ERROR (Status
)) {
792 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
793 if (DepthOfDisable
== 0) {
794 InScopeDisable
= FALSE
;
795 OpCodeDisabled
= FALSE
;
804 if (IsExpressionOpCode (Operand
)) {
805 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
806 mExpressionOpCodeIndex
++;
808 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
809 ExpressionOpCode
->Operand
= Operand
;
810 Value
= &ExpressionOpCode
->Value
;
813 case EFI_IFR_EQ_ID_VAL_OP
:
814 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
816 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
817 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
820 case EFI_IFR_EQ_ID_ID_OP
:
821 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
822 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
825 case EFI_IFR_EQ_ID_LIST_OP
:
826 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
827 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
828 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
831 case EFI_IFR_TO_STRING_OP
:
832 case EFI_IFR_FIND_OP
:
833 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
836 case EFI_IFR_STRING_REF1_OP
:
837 Value
->Type
= EFI_IFR_TYPE_STRING
;
838 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
841 case EFI_IFR_RULE_REF_OP
:
842 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
845 case EFI_IFR_SPAN_OP
:
846 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
849 case EFI_IFR_THIS_OP
:
850 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
853 case EFI_IFR_QUESTION_REF1_OP
:
854 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
857 case EFI_IFR_QUESTION_REF3_OP
:
858 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
859 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
861 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
862 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
870 case EFI_IFR_TRUE_OP
:
871 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
872 Value
->Value
.b
= TRUE
;
875 case EFI_IFR_FALSE_OP
:
876 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
877 Value
->Value
.b
= FALSE
;
881 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
885 case EFI_IFR_ZERO_OP
:
886 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
890 case EFI_IFR_ONES_OP
:
891 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
892 Value
->Value
.u64
= 0xffffffffffffffffULL
;
895 case EFI_IFR_UINT8_OP
:
896 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
897 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
900 case EFI_IFR_UINT16_OP
:
901 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
902 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
905 case EFI_IFR_UINT32_OP
:
906 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
907 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
910 case EFI_IFR_UINT64_OP
:
911 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
912 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
915 case EFI_IFR_UNDEFINED_OP
:
916 Value
->Type
= EFI_IFR_TYPE_OTHER
;
919 case EFI_IFR_VERSION_OP
:
920 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
921 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
928 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
930 if (SingleOpCodeExpression
) {
932 // There are two cases to indicate the end of an Expression:
933 // for single OpCode expression: one Expression OpCode
934 // for expression consists of more than one OpCode: EFI_IFR_END
936 SingleOpCodeExpression
= FALSE
;
938 if (InScopeDisable
) {
940 // Evaluate DisableIf expression
942 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
943 if (EFI_ERROR (Status
)) {
946 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
947 return EFI_INVALID_PARAMETER
;
950 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
953 CurrentExpression
= NULL
;
964 case EFI_IFR_FORM_SET_OP
:
966 // check the formset GUID
968 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
969 return EFI_INVALID_PARAMETER
;
972 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
973 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
976 case EFI_IFR_FORM_OP
:
978 // Create a new Form for this FormSet
980 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
981 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
982 InitializeListHead (&CurrentForm
->ExpressionListHead
);
983 InitializeListHead (&CurrentForm
->StatementListHead
);
985 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
986 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
989 // Insert into Form list of this FormSet
991 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
997 case EFI_IFR_VARSTORE_OP
:
999 // Create a buffer Storage for this FormSet
1001 Storage
= CreateStorage (FormSet
);
1002 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1004 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1005 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1006 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1008 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1009 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1011 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1012 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1013 ASSERT (Storage
->Name
!= NULL
);
1014 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1015 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1019 // Initialize <ConfigHdr>
1021 InitializeConfigHdr (FormSet
, Storage
);
1024 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1026 // Create a name/value Storage for this FormSet
1028 Storage
= CreateStorage (FormSet
);
1029 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1031 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1032 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1035 // Initialize <ConfigHdr>
1037 InitializeConfigHdr (FormSet
, Storage
);
1040 case EFI_IFR_VARSTORE_EFI_OP
:
1042 // Create a EFI variable Storage for this FormSet
1044 Storage
= CreateStorage (FormSet
);
1045 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1047 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1048 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1049 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1055 case EFI_IFR_DEFAULTSTORE_OP
:
1056 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1057 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1059 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1060 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1063 // Insert to DefaultStore list of this Formset
1065 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1071 case EFI_IFR_SUBTITLE_OP
:
1072 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1073 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1076 mInScopeSubtitle
= TRUE
;
1080 case EFI_IFR_TEXT_OP
:
1081 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1083 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1089 case EFI_IFR_ACTION_OP
:
1090 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1092 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1094 // No QuestionConfig present, so no configuration string will be processed
1096 CurrentStatement
->QuestionConfig
= 0;
1098 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1102 case EFI_IFR_RESET_BUTTON_OP
:
1103 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1105 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1108 case EFI_IFR_REF_OP
:
1109 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1111 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1112 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1113 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1115 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1116 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1118 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1119 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1125 case EFI_IFR_ONE_OF_OP
:
1126 case EFI_IFR_NUMERIC_OP
:
1127 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1129 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1130 Value
= &CurrentStatement
->HiiValue
;
1132 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1133 case EFI_IFR_NUMERIC_SIZE_1
:
1134 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1135 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1136 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1137 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1138 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1141 case EFI_IFR_NUMERIC_SIZE_2
:
1142 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1143 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1144 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1145 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1146 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1149 case EFI_IFR_NUMERIC_SIZE_4
:
1150 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1151 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1152 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1153 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1154 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1157 case EFI_IFR_NUMERIC_SIZE_8
:
1158 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1159 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1160 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1161 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1162 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1169 InitializeRequestElement (FormSet
, CurrentStatement
);
1171 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1172 SuppressForOption
= TRUE
;
1176 case EFI_IFR_ORDERED_LIST_OP
:
1177 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1179 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1180 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1181 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1182 InitializeRequestElement (FormSet
, CurrentStatement
);
1185 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1186 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1187 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1189 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1190 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1193 SuppressForOption
= TRUE
;
1197 case EFI_IFR_CHECKBOX_OP
:
1198 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1200 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1201 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1202 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1204 InitializeRequestElement (FormSet
, CurrentStatement
);
1207 case EFI_IFR_STRING_OP
:
1208 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1211 // MinSize is the minimum number of characters that can be accepted for this opcode,
1212 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1213 // The characters are stored as Unicode, so the storage width should multiply 2.
1215 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1216 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1217 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1218 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1220 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1221 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1223 InitializeRequestElement (FormSet
, CurrentStatement
);
1226 case EFI_IFR_PASSWORD_OP
:
1227 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1230 // MinSize is the minimum number of characters that can be accepted for this opcode,
1231 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1232 // The characters are stored as Unicode, so the storage width should multiply 2.
1234 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1235 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1236 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1238 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1239 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1241 InitializeRequestElement (FormSet
, CurrentStatement
);
1244 case EFI_IFR_DATE_OP
:
1245 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1247 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1248 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1250 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1251 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1253 InitializeRequestElement (FormSet
, CurrentStatement
);
1256 // Don't assign storage for RTC type of date/time
1258 CurrentStatement
->Storage
= NULL
;
1259 CurrentStatement
->StorageWidth
= 0;
1263 case EFI_IFR_TIME_OP
:
1264 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1266 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1267 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1269 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1270 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1272 InitializeRequestElement (FormSet
, CurrentStatement
);
1275 // Don't assign storage for RTC type of date/time
1277 CurrentStatement
->Storage
= NULL
;
1278 CurrentStatement
->StorageWidth
= 0;
1285 case EFI_IFR_DEFAULT_OP
:
1287 // EFI_IFR_DEFAULT appear in scope of a Question,
1288 // It creates a default value for the current question.
1289 // A Question may have more than one Default value which have different default types.
1291 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1292 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1294 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1295 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1296 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1297 ExtendValueToU64 (&CurrentDefault
->Value
);
1300 // Insert to Default Value list of current Question
1302 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1305 InScopeDefault
= TRUE
;
1312 case EFI_IFR_ONE_OF_OPTION_OP
:
1314 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1315 // It create a selection for use in current Question.
1317 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1318 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1320 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1321 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1322 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1323 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1324 ExtendValueToU64 (&CurrentOption
->Value
);
1326 if (InScopeOptionSuppress
) {
1327 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1331 // Insert to Option list of current Question
1333 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1339 case EFI_IFR_NO_SUBMIT_IF_OP
:
1340 case EFI_IFR_INCONSISTENT_IF_OP
:
1342 // Create an Expression node
1344 CurrentExpression
= CreateExpression (CurrentForm
);
1345 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1347 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1348 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1349 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1351 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1352 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1356 case EFI_IFR_SUPPRESS_IF_OP
:
1358 // Question and Option will appear in scope of this OpCode
1360 CurrentExpression
= CreateExpression (CurrentForm
);
1361 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1362 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1364 if (SuppressForOption
) {
1365 InScopeOptionSuppress
= TRUE
;
1366 OptionSuppressExpression
= CurrentExpression
;
1368 mInScopeSuppress
= TRUE
;
1369 mSuppressExpression
= CurrentExpression
;
1373 case EFI_IFR_GRAY_OUT_IF_OP
:
1375 // Questions will appear in scope of this OpCode
1377 CurrentExpression
= CreateExpression (CurrentForm
);
1378 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1379 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1381 mInScopeGrayOut
= TRUE
;
1382 mGrayOutExpression
= CurrentExpression
;
1385 case EFI_IFR_DISABLE_IF_OP
:
1387 // The DisableIf expression should only rely on constant, so it could be
1388 // evaluated at initialization and it will not be queued
1390 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1391 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1392 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1393 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1395 InScopeDisable
= TRUE
;
1396 OpCodeDisabled
= FALSE
;
1399 // Take a look at next OpCode to see whether current expression consists
1402 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1403 SingleOpCodeExpression
= TRUE
;
1410 case EFI_IFR_VALUE_OP
:
1411 CurrentExpression
= CreateExpression (CurrentForm
);
1412 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1413 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1415 if (InScopeDefault
) {
1417 // Used for default (EFI_IFR_DEFAULT)
1419 CurrentDefault
->ValueExpression
= CurrentExpression
;
1422 // If used for a question, then the question will be read-only
1424 CurrentStatement
->ValueExpression
= CurrentExpression
;
1428 case EFI_IFR_RULE_OP
:
1429 CurrentExpression
= CreateExpression (CurrentForm
);
1430 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1432 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1433 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1439 case EFI_IFR_IMAGE_OP
:
1441 // Get ScopeOpcode from top of stack
1443 PopScope (&ScopeOpCode
);
1444 PushScope (ScopeOpCode
);
1446 switch (ScopeOpCode
) {
1447 case EFI_IFR_FORM_SET_OP
:
1448 ImageId
= &FormSet
->ImageId
;
1451 case EFI_IFR_FORM_OP
:
1452 ImageId
= &CurrentForm
->ImageId
;
1455 case EFI_IFR_ONE_OF_OPTION_OP
:
1456 ImageId
= &CurrentOption
->ImageId
;
1460 ImageId
= &CurrentStatement
->ImageId
;
1464 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1470 case EFI_IFR_REFRESH_OP
:
1471 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1477 case EFI_IFR_GUID_OP
:
1478 if (CompareGuid (&gTianoHiiIfrGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1480 // Tiano specific GUIDed opcodes
1482 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1483 case EFI_IFR_EXTEND_OP_LABEL
:
1485 // just ignore label
1489 case EFI_IFR_EXTEND_OP_BANNER
:
1490 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1492 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1493 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1494 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1495 sizeof (EFI_STRING_ID
)
1500 case EFI_IFR_EXTEND_OP_CLASS
:
1501 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1504 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1505 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1517 case EFI_IFR_END_OP
:
1518 Status
= PopScope (&ScopeOpCode
);
1519 if (EFI_ERROR (Status
)) {
1524 switch (ScopeOpCode
) {
1525 case EFI_IFR_FORM_SET_OP
:
1527 // End of FormSet, update FormSet IFR binary length
1528 // to stop parsing substantial OpCodes
1530 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1533 case EFI_IFR_FORM_OP
:
1540 case EFI_IFR_ONE_OF_OPTION_OP
:
1544 CurrentOption
= NULL
;
1547 case EFI_IFR_SUBTITLE_OP
:
1548 mInScopeSubtitle
= FALSE
;
1551 case EFI_IFR_NO_SUBMIT_IF_OP
:
1552 case EFI_IFR_INCONSISTENT_IF_OP
:
1554 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1558 case EFI_IFR_SUPPRESS_IF_OP
:
1559 if (SuppressForOption
) {
1560 InScopeOptionSuppress
= FALSE
;
1562 mInScopeSuppress
= FALSE
;
1566 case EFI_IFR_GRAY_OUT_IF_OP
:
1567 mInScopeGrayOut
= FALSE
;
1570 case EFI_IFR_DISABLE_IF_OP
:
1571 InScopeDisable
= FALSE
;
1572 OpCodeDisabled
= FALSE
;
1575 case EFI_IFR_ONE_OF_OP
:
1576 case EFI_IFR_ORDERED_LIST_OP
:
1577 SuppressForOption
= FALSE
;
1580 case EFI_IFR_DEFAULT_OP
:
1581 InScopeDefault
= FALSE
;
1585 if (IsExpressionOpCode (ScopeOpCode
)) {
1586 if (InScopeDisable
) {
1588 // Evaluate DisableIf expression
1590 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1591 if (EFI_ERROR (Status
)) {
1594 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1595 return EFI_INVALID_PARAMETER
;
1598 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1600 // DisableIf Expression is only used once and not quequed, free it
1602 DestroyExpression (CurrentExpression
);
1606 // End of current Expression
1608 CurrentExpression
= NULL
;