2 Copyright (c) 2007, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 Parser for IFR binary encoding.
24 //@MT:#include "EfiPrintLib.h"
26 UINT16 mStatementIndex
;
27 UINT16 mExpressionOpCodeIndex
;
29 BOOLEAN mInScopeSubtitle
;
30 BOOLEAN mInScopeSuppress
;
31 BOOLEAN mInScopeGrayOut
;
32 FORM_EXPRESSION
*mSuppressExpression
;
33 FORM_EXPRESSION
*mGrayOutExpression
;
35 EFI_GUID gTianoHiiIfrGuid
= EFI_IFR_TIANO_GUID
;
39 Initialize Statement header members.
41 @param OpCodeData Pointer of the raw OpCode data.
42 @param FormSet Pointer of the current FormSe.
43 @param Form Pointer of the current Form.
45 @return The Statement.
48 FORM_BROWSER_STATEMENT
*
51 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
52 IN OUT FORM_BROWSER_FORM
*Form
55 FORM_BROWSER_STATEMENT
*Statement
;
56 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
60 // We are currently not in a Form Scope, so just skip this Statement
65 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
68 InitializeListHead (&Statement
->DefaultListHead
);
69 InitializeListHead (&Statement
->OptionListHead
);
70 InitializeListHead (&Statement
->InconsistentListHead
);
71 InitializeListHead (&Statement
->NoSubmitListHead
);
73 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
75 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
77 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
78 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
79 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
81 if (mInScopeSuppress
) {
82 Statement
->SuppressExpression
= mSuppressExpression
;
85 if (mInScopeGrayOut
) {
86 Statement
->GrayOutExpression
= mGrayOutExpression
;
89 Statement
->InSubtitle
= mInScopeSubtitle
;
92 // Insert this Statement into current Form
94 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
101 Initialize Question's members.
103 @param OpCodeData Pointer of the raw OpCode data.
104 @param FormSet Pointer of the current FormSet.
105 @param Form Pointer of the current Form.
107 @return The Question.
110 FORM_BROWSER_STATEMENT
*
112 IN UINT8
*OpCodeData
,
113 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
114 IN OUT FORM_BROWSER_FORM
*Form
117 FORM_BROWSER_STATEMENT
*Statement
;
118 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
120 FORMSET_STORAGE
*Storage
;
121 NAME_VALUE_NODE
*NameValueNode
;
123 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
124 if (Statement
== NULL
) {
128 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
129 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
130 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
131 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
133 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
135 if (Statement
->VarStoreId
== 0) {
137 // VarStoreId of zero indicates no variable storage
143 // Find Storage for this Question
145 Link
= GetFirstNode (&FormSet
->StorageListHead
);
146 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
147 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
149 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
150 Statement
->Storage
= Storage
;
154 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
156 ASSERT (Statement
->Storage
!= NULL
);
159 // Initialilze varname for Name/Value or EFI Variable
161 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
162 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
163 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
164 ASSERT (Statement
->VariableName
!= NULL
);
166 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
168 // Insert to Name/Value varstore list
170 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
171 ASSERT (NameValueNode
!= NULL
);
172 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
173 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
174 ASSERT (NameValueNode
->Name
!= NULL
);
175 NameValueNode
->Value
= AllocateZeroPool (0x10);
176 ASSERT (NameValueNode
->Value
!= NULL
);
177 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
178 ASSERT (NameValueNode
->EditValue
!= NULL
);
180 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
189 Allocate a FORM_EXPRESSION node.
191 @param Form The Form associated with this Expression
193 @return Pointer to a FORM_EXPRESSION data structure.
198 IN OUT FORM_BROWSER_FORM
*Form
201 FORM_EXPRESSION
*Expression
;
203 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
204 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
205 InitializeListHead (&Expression
->OpCodeListHead
);
212 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
214 @param FormSet Pointer of the current FormSet
216 @return Pointer to a FORMSET_STORAGE data structure.
221 IN FORM_BROWSER_FORMSET
*FormSet
224 FORMSET_STORAGE
*Storage
;
226 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
227 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
228 InitializeListHead (&Storage
->NameValueListHead
);
229 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
236 Create ConfigHdr string for a storage.
238 @param FormSet Pointer of the current FormSet
239 @param Storage Pointer of the storage
241 @retval EFI_SUCCESS Initialize ConfigHdr success
245 InitializeConfigHdr (
246 IN FORM_BROWSER_FORMSET
*FormSet
,
247 IN OUT FORMSET_STORAGE
*Storage
254 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
255 Name
= Storage
->Name
;
261 Status
= ConstructConfigHdr (
266 FormSet
->DriverHandle
268 if (Status
== EFI_BUFFER_TOO_SMALL
) {
269 Storage
->ConfigHdr
= AllocateZeroPool (StrBufferLen
);
270 Status
= ConstructConfigHdr (
275 FormSet
->DriverHandle
279 if (EFI_ERROR (Status
)) {
283 Storage
->ConfigRequest
= AllocateCopyPool (StrBufferLen
, Storage
->ConfigHdr
);
284 Storage
->SpareStrLen
= 0;
291 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
293 @param FormSet Pointer of the current FormSet.
294 @param Question The Question to be initialized.
296 @retval EFI_SUCCESS Function success.
297 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
301 InitializeRequestElement (
302 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
303 IN OUT FORM_BROWSER_STATEMENT
*Question
306 FORMSET_STORAGE
*Storage
;
310 CHAR16 RequestElement
[30];
312 Storage
= Question
->Storage
;
313 if (Storage
== NULL
) {
314 return EFI_INVALID_PARAMETER
;
317 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
319 // <ConfigRequest> is unnecessary for EFI variable storage,
320 // GetVariable()/SetVariable() will be used to retrieve/save values
326 // Prepare <RequestElement>
328 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
329 StrLen
= UnicodeSPrint (
331 30 * sizeof (CHAR16
),
332 L
"&OFFSET=%x&WIDTH=%x",
333 Question
->VarStoreInfo
.VarOffset
,
334 Question
->StorageWidth
336 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
338 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
341 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && (Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
)) {
343 // Password with CALLBACK flag is stored in encoded format,
344 // so don't need to append it to <ConfigRequest>
350 // Append <RequestElement> to <ConfigRequest>
352 if (StrLen
> Storage
->SpareStrLen
) {
354 // Old String buffer is not sufficient for RequestElement, allocate a new one
356 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
357 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
358 if (Storage
->ConfigRequest
!= NULL
) {
359 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
360 gBS
->FreePool (Storage
->ConfigRequest
);
362 Storage
->ConfigRequest
= NewStr
;
363 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
366 StrCat (Storage
->ConfigRequest
, RequestElement
);
367 Storage
->ElementCount
++;
368 Storage
->SpareStrLen
-= StrLen
;
375 Free resources of a Expression
377 @param FormSet Pointer of the Expression
384 IN FORM_EXPRESSION
*Expression
388 EXPRESSION_OPCODE
*OpCode
;
390 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
391 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
392 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
393 RemoveEntryList (&OpCode
->Link
);
395 SafeFreePool (OpCode
->ValueList
);
399 // Free this Expression
401 gBS
->FreePool (Expression
);
406 Free resources of a storage
408 @param Storage Pointer of the storage
415 IN FORMSET_STORAGE
*Storage
419 NAME_VALUE_NODE
*NameValueNode
;
421 if (Storage
== NULL
) {
425 SafeFreePool (Storage
->Name
);
426 SafeFreePool (Storage
->Buffer
);
427 SafeFreePool (Storage
->EditBuffer
);
429 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
430 Link
= GetFirstNode (&Storage
->NameValueListHead
);
431 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
432 RemoveEntryList (&NameValueNode
->Link
);
434 SafeFreePool (NameValueNode
->Name
);
435 SafeFreePool (NameValueNode
->Value
);
436 SafeFreePool (NameValueNode
->EditValue
);
437 SafeFreePool (NameValueNode
);
440 SafeFreePool (Storage
->ConfigHdr
);
441 SafeFreePool (Storage
->ConfigRequest
);
443 gBS
->FreePool (Storage
);
448 Free resources of a Statement
450 @param Statement Pointer of the Statement
457 IN OUT FORM_BROWSER_STATEMENT
*Statement
461 QUESTION_DEFAULT
*Default
;
462 QUESTION_OPTION
*Option
;
463 FORM_EXPRESSION
*Expression
;
466 // Free Default value List
468 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
469 Link
= GetFirstNode (&Statement
->DefaultListHead
);
470 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
471 RemoveEntryList (&Default
->Link
);
473 gBS
->FreePool (Default
);
479 while (!IsListEmpty (&Statement
->OptionListHead
)) {
480 Link
= GetFirstNode (&Statement
->OptionListHead
);
481 Option
= QUESTION_OPTION_FROM_LINK (Link
);
482 RemoveEntryList (&Option
->Link
);
484 gBS
->FreePool (Option
);
488 // Free Inconsistent List
490 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
491 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
492 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
493 RemoveEntryList (&Expression
->Link
);
495 DestroyExpression (Expression
);
499 // Free NoSubmit List
501 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
502 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
503 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
504 RemoveEntryList (&Expression
->Link
);
506 DestroyExpression (Expression
);
509 SafeFreePool (Statement
->VariableName
);
510 SafeFreePool (Statement
->BlockName
);
515 Free resources of a Form
517 @param Form Pointer of the Form
524 IN OUT FORM_BROWSER_FORM
*Form
528 FORM_EXPRESSION
*Expression
;
529 FORM_BROWSER_STATEMENT
*Statement
;
532 // Free Form Expressions
534 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
535 Link
= GetFirstNode (&Form
->ExpressionListHead
);
536 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
537 RemoveEntryList (&Expression
->Link
);
539 DestroyExpression (Expression
);
543 // Free Statements/Questions
545 while (!IsListEmpty (&Form
->StatementListHead
)) {
546 Link
= GetFirstNode (&Form
->StatementListHead
);
547 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
548 RemoveEntryList (&Statement
->Link
);
550 DestroyStatement (Statement
);
556 gBS
->FreePool (Form
);
561 Free resources allocated for a FormSet
563 @param FormSet Pointer of the FormSet
570 IN OUT FORM_BROWSER_FORMSET
*FormSet
574 FORMSET_STORAGE
*Storage
;
575 FORMSET_DEFAULTSTORE
*DefaultStore
;
576 FORM_BROWSER_FORM
*Form
;
579 // Free IFR binary buffer
581 SafeFreePool (FormSet
->IfrBinaryData
);
584 // Free FormSet Storage
586 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
587 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
588 Link
= GetFirstNode (&FormSet
->StorageListHead
);
589 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
590 RemoveEntryList (&Storage
->Link
);
592 DestroyStorage (Storage
);
597 // Free FormSet Default Store
599 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
600 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
601 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
602 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
603 RemoveEntryList (&DefaultStore
->Link
);
605 gBS
->FreePool (DefaultStore
);
612 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
613 while (!IsListEmpty (&FormSet
->FormListHead
)) {
614 Link
= GetFirstNode (&FormSet
->FormListHead
);
615 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
616 RemoveEntryList (&Form
->Link
);
622 SafeFreePool (FormSet
->StatementBuffer
);
623 SafeFreePool (FormSet
->ExpressionBuffer
);
625 SafeFreePool (FormSet
);
630 Tell whether this Operand is an Expression OpCode or not
632 @param Operand Operand of an IFR OpCode.
634 @retval TRUE This is an Expression OpCode.
635 @retval FALSE Not an Expression OpCode.
643 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
644 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
645 (Operand
== EFI_IFR_CATENATE_OP
)
655 Calculate number of Statemens(Questions) and Expression OpCodes.
657 @param FormSet The FormSet to be counted.
658 @param NumberOfStatement Number of Statemens(Questions)
659 @param NumberOfExpression Number of Expression OpCodes
666 IN FORM_BROWSER_FORMSET
*FormSet
,
667 IN OUT UINT16
*NumberOfStatement
,
668 IN OUT UINT16
*NumberOfExpression
671 UINT16 StatementCount
;
672 UINT16 ExpressionCount
;
681 while (Offset
< FormSet
->IfrBinaryLength
) {
682 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
683 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
686 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
693 *NumberOfStatement
= StatementCount
;
694 *NumberOfExpression
= ExpressionCount
;
699 Parse opcodes in the formset IFR binary.
701 @param FormSet Pointer of the FormSet data structure.
703 @retval EFI_SUCCESS Opcode parse success.
704 @retval Other Opcode parse fail.
709 IN FORM_BROWSER_FORMSET
*FormSet
714 FORM_BROWSER_FORM
*CurrentForm
;
715 FORM_BROWSER_STATEMENT
*CurrentStatement
;
716 EXPRESSION_OPCODE
*ExpressionOpCode
;
717 FORM_EXPRESSION
*CurrentExpression
;
724 FORMSET_STORAGE
*Storage
;
725 FORMSET_DEFAULTSTORE
*DefaultStore
;
726 QUESTION_DEFAULT
*CurrentDefault
;
727 QUESTION_OPTION
*CurrentOption
;
729 UINT16 NumberOfStatement
;
730 UINT16 NumberOfExpression
;
731 EFI_IMAGE_ID
*ImageId
;
732 BOOLEAN SuppressForOption
;
733 BOOLEAN InScopeOptionSuppress
;
734 FORM_EXPRESSION
*OptionSuppressExpression
;
735 BOOLEAN InScopeDisable
;
736 UINT16 DepthOfDisable
;
737 BOOLEAN OpCodeDisabled
;
738 BOOLEAN SingleOpCodeExpression
;
739 BOOLEAN InScopeDefault
;
740 EFI_HII_VALUE
*Value
;
742 mInScopeSubtitle
= FALSE
;
743 SuppressForOption
= FALSE
;
744 mInScopeSuppress
= FALSE
;
745 InScopeOptionSuppress
= FALSE
;
746 mInScopeGrayOut
= FALSE
;
747 InScopeDisable
= FALSE
;
749 OpCodeDisabled
= FALSE
;
750 SingleOpCodeExpression
= FALSE
;
751 InScopeDefault
= FALSE
;
752 CurrentExpression
= NULL
;
753 CurrentDefault
= NULL
;
754 CurrentOption
= NULL
;
755 OptionSuppressExpression
= NULL
;
758 // Get the number of Statements and Expressions
760 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
763 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
764 if (FormSet
->StatementBuffer
== NULL
) {
765 return EFI_OUT_OF_RESOURCES
;
768 mExpressionOpCodeIndex
= 0;
769 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
770 if (FormSet
->ExpressionBuffer
== NULL
) {
771 return EFI_OUT_OF_RESOURCES
;
774 InitializeListHead (&FormSet
->StorageListHead
);
775 InitializeListHead (&FormSet
->DefaultStoreListHead
);
776 InitializeListHead (&FormSet
->FormListHead
);
779 CurrentStatement
= NULL
;
784 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
785 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
787 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
788 OpCodeOffset
+= OpCodeLength
;
789 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
790 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
793 // If scope bit set, push onto scope stack
799 if (OpCodeDisabled
) {
801 // DisableIf Expression is evaluated to be TRUE, try to find its end.
802 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
804 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
806 } else if (Operand
== EFI_IFR_END_OP
) {
807 Status
= PopScope (&ScopeOpCode
);
808 if (EFI_ERROR (Status
)) {
812 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
813 if (DepthOfDisable
== 0) {
814 InScopeDisable
= FALSE
;
815 OpCodeDisabled
= FALSE
;
824 if (IsExpressionOpCode (Operand
)) {
825 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
826 mExpressionOpCodeIndex
++;
828 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
829 ExpressionOpCode
->Operand
= Operand
;
830 Value
= &ExpressionOpCode
->Value
;
833 case EFI_IFR_EQ_ID_VAL_OP
:
834 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
836 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
837 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
840 case EFI_IFR_EQ_ID_ID_OP
:
841 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
842 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
845 case EFI_IFR_EQ_ID_LIST_OP
:
846 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
847 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
848 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->ValueList
);
851 case EFI_IFR_TO_STRING_OP
:
852 case EFI_IFR_FIND_OP
:
853 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
856 case EFI_IFR_STRING_REF1_OP
:
857 Value
->Type
= EFI_IFR_TYPE_STRING
;
858 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
861 case EFI_IFR_RULE_REF_OP
:
862 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
865 case EFI_IFR_SPAN_OP
:
866 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
869 case EFI_IFR_THIS_OP
:
870 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
873 case EFI_IFR_QUESTION_REF1_OP
:
874 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
877 case EFI_IFR_QUESTION_REF3_OP
:
878 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
879 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
881 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
882 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
890 case EFI_IFR_TRUE_OP
:
891 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
892 Value
->Value
.b
= TRUE
;
895 case EFI_IFR_FALSE_OP
:
896 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
897 Value
->Value
.b
= FALSE
;
901 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
905 case EFI_IFR_ZERO_OP
:
906 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
910 case EFI_IFR_ONES_OP
:
911 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
912 Value
->Value
.u64
= 0xffffffffffffffffULL
;
915 case EFI_IFR_UINT8_OP
:
916 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
917 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
920 case EFI_IFR_UINT16_OP
:
921 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
922 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
925 case EFI_IFR_UINT32_OP
:
926 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
927 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
930 case EFI_IFR_UINT64_OP
:
931 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
932 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
935 case EFI_IFR_UNDEFINED_OP
:
936 Value
->Type
= EFI_IFR_TYPE_OTHER
;
939 case EFI_IFR_VERSION_OP
:
940 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
941 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
948 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
950 if (SingleOpCodeExpression
) {
952 // There are two cases to indicate the end of an Expression:
953 // for single OpCode expression: one Expression OpCode
954 // for expression consists of more than one OpCode: EFI_IFR_END
956 SingleOpCodeExpression
= FALSE
;
958 if (InScopeDisable
) {
960 // Evaluate DisableIf expression
962 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
963 if (EFI_ERROR (Status
)) {
966 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
967 return EFI_INVALID_PARAMETER
;
970 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
973 CurrentExpression
= NULL
;
984 case EFI_IFR_FORM_SET_OP
:
986 // check the formset GUID
988 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
989 return EFI_INVALID_PARAMETER
;
992 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
993 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
996 case EFI_IFR_FORM_OP
:
998 // Create a new Form for this FormSet
1000 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1001 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1002 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1003 InitializeListHead (&CurrentForm
->StatementListHead
);
1005 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1006 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1009 // Insert into Form list of this FormSet
1011 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1017 case EFI_IFR_VARSTORE_OP
:
1019 // Create a buffer Storage for this FormSet
1021 Storage
= CreateStorage (FormSet
);
1022 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1024 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1025 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1026 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1028 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1029 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1031 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1032 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1033 ASSERT (Storage
->Name
!= NULL
);
1034 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1035 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1039 // Initialize <ConfigHdr>
1041 InitializeConfigHdr (FormSet
, Storage
);
1044 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1046 // Create a name/value Storage for this FormSet
1048 Storage
= CreateStorage (FormSet
);
1049 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1051 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1052 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1055 // Initialize <ConfigHdr>
1057 InitializeConfigHdr (FormSet
, Storage
);
1060 case EFI_IFR_VARSTORE_EFI_OP
:
1062 // Create a EFI variable Storage for this FormSet
1064 Storage
= CreateStorage (FormSet
);
1065 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1067 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1068 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1069 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1075 case EFI_IFR_DEFAULTSTORE_OP
:
1076 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1077 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1079 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1080 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1083 // Insert to DefaultStore list of this Formset
1085 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1091 case EFI_IFR_SUBTITLE_OP
:
1092 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1093 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1096 mInScopeSubtitle
= TRUE
;
1100 case EFI_IFR_TEXT_OP
:
1101 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1103 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1109 case EFI_IFR_ACTION_OP
:
1110 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1112 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1114 // No QuestionConfig present, so no configuration string will be processed
1116 CurrentStatement
->QuestionConfig
= 0;
1118 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1122 case EFI_IFR_RESET_BUTTON_OP
:
1123 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1125 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1128 case EFI_IFR_REF_OP
:
1129 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1131 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1132 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1133 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1135 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1136 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1138 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1139 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1145 case EFI_IFR_ONE_OF_OP
:
1146 case EFI_IFR_NUMERIC_OP
:
1147 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1149 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1150 Value
= &CurrentStatement
->HiiValue
;
1152 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1153 case EFI_IFR_NUMERIC_SIZE_1
:
1154 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1155 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1156 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1157 CurrentStatement
->StorageWidth
= sizeof (UINT8
);
1158 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1161 case EFI_IFR_NUMERIC_SIZE_2
:
1162 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1163 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1164 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1165 CurrentStatement
->StorageWidth
= sizeof (UINT16
);
1166 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1169 case EFI_IFR_NUMERIC_SIZE_4
:
1170 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1171 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1172 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1173 CurrentStatement
->StorageWidth
= sizeof (UINT32
);
1174 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1177 case EFI_IFR_NUMERIC_SIZE_8
:
1178 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1179 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1180 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1181 CurrentStatement
->StorageWidth
= sizeof (UINT64
);
1182 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1189 InitializeRequestElement (FormSet
, CurrentStatement
);
1191 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
) {
1192 SuppressForOption
= TRUE
;
1196 case EFI_IFR_ORDERED_LIST_OP
:
1197 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1199 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1200 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1201 CurrentStatement
->StorageWidth
= (UINT16
)(CurrentStatement
->MaxContainers
* sizeof (UINT8
));
1202 InitializeRequestElement (FormSet
, CurrentStatement
);
1205 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1206 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1207 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1209 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_OTHER
;
1210 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1213 SuppressForOption
= TRUE
;
1217 case EFI_IFR_CHECKBOX_OP
:
1218 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1220 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1221 CurrentStatement
->StorageWidth
= sizeof (BOOLEAN
);
1222 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1224 InitializeRequestElement (FormSet
, CurrentStatement
);
1227 case EFI_IFR_STRING_OP
:
1228 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1231 // MinSize is the minimum number of characters that can be accepted for this opcode,
1232 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1233 // The characters are stored as Unicode, so the storage width should multiply 2.
1235 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1236 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1237 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (UINT16
));
1238 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1240 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1241 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1243 InitializeRequestElement (FormSet
, CurrentStatement
);
1246 case EFI_IFR_PASSWORD_OP
:
1247 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1250 // MinSize is the minimum number of characters that can be accepted for this opcode,
1251 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1252 // The characters are stored as Unicode, so the storage width should multiply 2.
1254 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1255 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1256 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (UINT16
));
1258 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1259 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1261 InitializeRequestElement (FormSet
, CurrentStatement
);
1264 case EFI_IFR_DATE_OP
:
1265 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1267 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1268 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1270 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1271 CurrentStatement
->StorageWidth
= sizeof (EFI_HII_DATE
);
1273 InitializeRequestElement (FormSet
, CurrentStatement
);
1276 // Don't assign storage for RTC type of date/time
1278 CurrentStatement
->Storage
= NULL
;
1279 CurrentStatement
->StorageWidth
= 0;
1283 case EFI_IFR_TIME_OP
:
1284 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1286 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1287 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1289 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1290 CurrentStatement
->StorageWidth
= sizeof (EFI_IFR_TIME
);
1292 InitializeRequestElement (FormSet
, CurrentStatement
);
1295 // Don't assign storage for RTC type of date/time
1297 CurrentStatement
->Storage
= NULL
;
1298 CurrentStatement
->StorageWidth
= 0;
1305 case EFI_IFR_DEFAULT_OP
:
1307 // EFI_IFR_DEFAULT appear in scope of a Question,
1308 // It creates a default value for the current question.
1309 // A Question may have more than one Default value which have different default types.
1311 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1312 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1314 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1315 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1316 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1317 ExtendValueToU64 (&CurrentDefault
->Value
);
1320 // Insert to Default Value list of current Question
1322 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1325 InScopeDefault
= TRUE
;
1332 case EFI_IFR_ONE_OF_OPTION_OP
:
1334 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1335 // It create a selection for use in current Question.
1337 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1338 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1340 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1341 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1342 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1343 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1344 ExtendValueToU64 (&CurrentOption
->Value
);
1346 if (InScopeOptionSuppress
) {
1347 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1351 // Insert to Option list of current Question
1353 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1359 case EFI_IFR_NO_SUBMIT_IF_OP
:
1360 case EFI_IFR_INCONSISTENT_IF_OP
:
1362 // Create an Expression node
1364 CurrentExpression
= CreateExpression (CurrentForm
);
1365 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1367 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1368 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1369 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1371 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1372 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1376 case EFI_IFR_SUPPRESS_IF_OP
:
1378 // Question and Option will appear in scope of this OpCode
1380 CurrentExpression
= CreateExpression (CurrentForm
);
1381 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1382 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1384 if (SuppressForOption
) {
1385 InScopeOptionSuppress
= TRUE
;
1386 OptionSuppressExpression
= CurrentExpression
;
1388 mInScopeSuppress
= TRUE
;
1389 mSuppressExpression
= CurrentExpression
;
1393 case EFI_IFR_GRAY_OUT_IF_OP
:
1395 // Questions will appear in scope of this OpCode
1397 CurrentExpression
= CreateExpression (CurrentForm
);
1398 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1399 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1401 mInScopeGrayOut
= TRUE
;
1402 mGrayOutExpression
= CurrentExpression
;
1405 case EFI_IFR_DISABLE_IF_OP
:
1407 // The DisableIf expression should only rely on constant, so it could be
1408 // evaluated at initialization and it will not be queued
1410 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1411 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1412 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1413 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1415 InScopeDisable
= TRUE
;
1416 OpCodeDisabled
= FALSE
;
1419 // Take a look at next OpCode to see whether current expression consists
1422 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1423 SingleOpCodeExpression
= TRUE
;
1430 case EFI_IFR_VALUE_OP
:
1431 CurrentExpression
= CreateExpression (CurrentForm
);
1432 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1433 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1435 if (InScopeDefault
) {
1437 // Used for default (EFI_IFR_DEFAULT)
1439 CurrentDefault
->ValueExpression
= CurrentExpression
;
1442 // If used for a question, then the question will be read-only
1444 CurrentStatement
->ValueExpression
= CurrentExpression
;
1448 case EFI_IFR_RULE_OP
:
1449 CurrentExpression
= CreateExpression (CurrentForm
);
1450 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1452 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1453 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1459 case EFI_IFR_IMAGE_OP
:
1461 // Get ScopeOpcode from top of stack
1463 PopScope (&ScopeOpCode
);
1464 PushScope (ScopeOpCode
);
1466 switch (ScopeOpCode
) {
1467 case EFI_IFR_FORM_SET_OP
:
1468 ImageId
= &FormSet
->ImageId
;
1471 case EFI_IFR_FORM_OP
:
1472 ImageId
= &CurrentForm
->ImageId
;
1475 case EFI_IFR_ONE_OF_OPTION_OP
:
1476 ImageId
= &CurrentOption
->ImageId
;
1480 ImageId
= &CurrentStatement
->ImageId
;
1484 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
1490 case EFI_IFR_REFRESH_OP
:
1491 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
1497 case EFI_IFR_GUID_OP
:
1498 if (CompareGuid (&gTianoHiiIfrGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
1500 // Tiano specific GUIDed opcodes
1502 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
1503 case EFI_IFR_EXTEND_OP_LABEL
:
1505 // just ignore label
1509 case EFI_IFR_EXTEND_OP_BANNER
:
1510 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
1512 &BannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
1513 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
1514 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
1515 sizeof (EFI_STRING_ID
)
1520 case EFI_IFR_EXTEND_OP_CLASS
:
1521 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
1524 case EFI_IFR_EXTEND_OP_SUBCLASS
:
1525 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
1537 case EFI_IFR_END_OP
:
1538 Status
= PopScope (&ScopeOpCode
);
1539 if (EFI_ERROR (Status
)) {
1544 switch (ScopeOpCode
) {
1545 case EFI_IFR_FORM_SET_OP
:
1547 // End of FormSet, update FormSet IFR binary length
1548 // to stop parsing substantial OpCodes
1550 FormSet
->IfrBinaryLength
= OpCodeOffset
;
1553 case EFI_IFR_FORM_OP
:
1560 case EFI_IFR_ONE_OF_OPTION_OP
:
1564 CurrentOption
= NULL
;
1567 case EFI_IFR_SUBTITLE_OP
:
1568 mInScopeSubtitle
= FALSE
;
1571 case EFI_IFR_NO_SUBMIT_IF_OP
:
1572 case EFI_IFR_INCONSISTENT_IF_OP
:
1574 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1578 case EFI_IFR_SUPPRESS_IF_OP
:
1579 if (SuppressForOption
) {
1580 InScopeOptionSuppress
= FALSE
;
1582 mInScopeSuppress
= FALSE
;
1586 case EFI_IFR_GRAY_OUT_IF_OP
:
1587 mInScopeGrayOut
= FALSE
;
1590 case EFI_IFR_DISABLE_IF_OP
:
1591 InScopeDisable
= FALSE
;
1592 OpCodeDisabled
= FALSE
;
1595 case EFI_IFR_ONE_OF_OP
:
1596 case EFI_IFR_ORDERED_LIST_OP
:
1597 SuppressForOption
= FALSE
;
1600 case EFI_IFR_DEFAULT_OP
:
1601 InScopeDefault
= FALSE
;
1605 if (IsExpressionOpCode (ScopeOpCode
)) {
1606 if (InScopeDisable
) {
1608 // Evaluate DisableIf expression
1610 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1611 if (EFI_ERROR (Status
)) {
1614 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1615 return EFI_INVALID_PARAMETER
;
1618 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1620 // DisableIf Expression is only used once and not quequed, free it
1622 DestroyExpression (CurrentExpression
);
1626 // End of current Expression
1628 CurrentExpression
= NULL
;