2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 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.
17 UINT16 mStatementIndex
;
18 UINT16 mExpressionOpCodeIndex
;
20 BOOLEAN mInScopeSubtitle
;
21 BOOLEAN mInScopeSuppress
;
22 BOOLEAN mInScopeGrayOut
;
23 BOOLEAN mInScopeDisable
;
24 FORM_EXPRESSION
*mSuppressExpression
;
25 FORM_EXPRESSION
*mGrayOutExpression
;
26 FORM_EXPRESSION
*mDisableExpression
;
29 Initialize Statement header members.
31 @param OpCodeData Pointer of the raw OpCode data.
32 @param FormSet Pointer of the current FormSe.
33 @param Form Pointer of the current Form.
35 @return The Statement.
38 FORM_BROWSER_STATEMENT
*
41 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
42 IN OUT FORM_BROWSER_FORM
*Form
45 FORM_BROWSER_STATEMENT
*Statement
;
46 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
50 // We are currently not in a Form Scope, so just skip this Statement
55 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
58 InitializeListHead (&Statement
->DefaultListHead
);
59 InitializeListHead (&Statement
->OptionListHead
);
60 InitializeListHead (&Statement
->InconsistentListHead
);
61 InitializeListHead (&Statement
->NoSubmitListHead
);
63 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
65 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
67 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
68 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
69 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
71 if (mInScopeSuppress
) {
72 Statement
->SuppressExpression
= mSuppressExpression
;
75 if (mInScopeGrayOut
) {
76 Statement
->GrayOutExpression
= mGrayOutExpression
;
80 if (mInScopeDisable
) {
81 Statement
->DisableExpression
= mDisableExpression
;
84 Statement
->InSubtitle
= mInScopeSubtitle
;
87 // Insert this Statement into current Form
89 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
95 Convert a numeric value to a Unicode String and insert it to String Package.
96 This string is used as the Unicode Name for the EFI Variable. This is to support
97 the deprecated vareqval opcode.
99 @param FormSet The FormSet.
100 @param Statement The numeric question whose VarStoreInfo.VarName is the
101 numeric value which is used to produce the Unicode Name
102 for the EFI Variable.
104 If the Statement is NULL, the ASSERT.
105 If the opcode is not Numeric, then ASSERT.
107 @retval EFI_SUCCESS The funtion always succeeds.
110 UpdateCheckBoxStringToken (
111 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
112 IN FORM_BROWSER_STATEMENT
*Statement
115 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
118 ASSERT (Statement
!= NULL
);
119 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
121 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
123 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
125 return EFI_OUT_OF_RESOURCES
;
128 Statement
->VarStoreInfo
.VarName
= Id
;
134 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
136 @param OpCodeData The current opcode.
142 IsNextOpCodeGuidedVarEqName (
149 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
150 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
151 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
153 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
155 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
165 Initialize Question's members.
167 @param OpCodeData Pointer of the raw OpCode data.
168 @param FormSet Pointer of the current FormSet.
169 @param Form Pointer of the current Form.
171 @return The Question.
174 FORM_BROWSER_STATEMENT
*
176 IN UINT8
*OpCodeData
,
177 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
178 IN OUT FORM_BROWSER_FORM
*Form
181 FORM_BROWSER_STATEMENT
*Statement
;
182 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
184 FORMSET_STORAGE
*Storage
;
185 NAME_VALUE_NODE
*NameValueNode
;
188 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
189 if (Statement
== NULL
) {
193 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
194 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
195 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
196 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
198 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
200 if (Statement
->VarStoreId
== 0) {
202 // VarStoreId of zero indicates no variable storage
208 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
209 // Framework Compatibility
211 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
212 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
213 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
214 if (EFI_ERROR (Status
)) {
221 // Find Storage for this Question
223 Link
= GetFirstNode (&FormSet
->StorageListHead
);
224 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
225 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
227 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
228 Statement
->Storage
= Storage
;
232 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
234 ASSERT (Statement
->Storage
!= NULL
);
237 // Initialilze varname for Name/Value or EFI Variable
239 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
240 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
241 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
242 ASSERT (Statement
->VariableName
!= NULL
);
244 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
246 // Insert to Name/Value varstore list
248 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
249 ASSERT (NameValueNode
!= NULL
);
250 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
251 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
252 ASSERT (NameValueNode
->Name
!= NULL
);
253 NameValueNode
->Value
= AllocateZeroPool (0x10);
254 ASSERT (NameValueNode
->Value
!= NULL
);
255 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
256 ASSERT (NameValueNode
->EditValue
!= NULL
);
258 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
267 Allocate a FORM_EXPRESSION node.
269 @param Form The Form associated with this Expression
271 @return Pointer to a FORM_EXPRESSION data structure.
276 IN OUT FORM_BROWSER_FORM
*Form
279 FORM_EXPRESSION
*Expression
;
281 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
282 ASSERT (Expression
!= NULL
);
283 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
284 InitializeListHead (&Expression
->OpCodeListHead
);
291 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
293 @param FormSet Pointer of the current FormSet
295 @return Pointer to a FORMSET_STORAGE data structure.
300 IN FORM_BROWSER_FORMSET
*FormSet
303 FORMSET_STORAGE
*Storage
;
305 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
306 ASSERT (Storage
!= NULL
);
307 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
308 InitializeListHead (&Storage
->NameValueListHead
);
309 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
316 Create ConfigHdr string for a storage.
318 @param FormSet Pointer of the current FormSet
319 @param Storage Pointer of the storage
321 @retval EFI_SUCCESS Initialize ConfigHdr success
325 InitializeConfigHdr (
326 IN FORM_BROWSER_FORMSET
*FormSet
,
327 IN OUT FORMSET_STORAGE
*Storage
332 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
333 Name
= Storage
->Name
;
338 Storage
->ConfigHdr
= HiiConstructConfigHdr (
341 FormSet
->DriverHandle
344 if (Storage
->ConfigHdr
== NULL
) {
345 return EFI_NOT_FOUND
;
348 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
349 Storage
->SpareStrLen
= 0;
356 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
358 @param FormSet Pointer of the current FormSet.
359 @param Question The Question to be initialized.
360 @param Form Pointer of the current form.
362 @retval EFI_SUCCESS Function success.
363 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
367 InitializeRequestElement (
368 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
369 IN OUT FORM_BROWSER_STATEMENT
*Question
,
370 IN OUT FORM_BROWSER_FORM
*Form
373 FORMSET_STORAGE
*Storage
;
377 CHAR16 RequestElement
[30];
380 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
382 Storage
= Question
->Storage
;
383 if (Storage
== NULL
) {
384 return EFI_INVALID_PARAMETER
;
387 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
389 // <ConfigRequest> is unnecessary for EFI variable storage,
390 // GetVariable()/SetVariable() will be used to retrieve/save values
396 // Prepare <RequestElement>
398 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
399 StrLen
= UnicodeSPrint (
401 30 * sizeof (CHAR16
),
402 L
"&OFFSET=%x&WIDTH=%x",
403 Question
->VarStoreInfo
.VarOffset
,
404 Question
->StorageWidth
406 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
408 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
411 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
413 // Password with CALLBACK flag is stored in encoded format,
414 // so don't need to append it to <ConfigRequest>
420 // Append <RequestElement> to <ConfigRequest>
422 if (StrLen
> Storage
->SpareStrLen
) {
424 // Old String buffer is not sufficient for RequestElement, allocate a new one
426 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
427 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
428 ASSERT (NewStr
!= NULL
);
429 if (Storage
->ConfigRequest
!= NULL
) {
430 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
431 FreePool (Storage
->ConfigRequest
);
433 Storage
->ConfigRequest
= NewStr
;
434 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
437 StrCat (Storage
->ConfigRequest
, RequestElement
);
438 Storage
->ElementCount
++;
439 Storage
->SpareStrLen
-= StrLen
;
442 // Update the Config Request info saved in the form.
446 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
447 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
448 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
450 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
->VarStoreId
== Storage
->VarStoreId
) {
455 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
459 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
460 ASSERT (ConfigInfo
!= NULL
);
461 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
462 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
463 ConfigInfo
->SpareStrLen
= 0;
464 ConfigInfo
->Storage
= Storage
;
465 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
469 // Append <RequestElement> to <ConfigRequest>
471 if (StrLen
> ConfigInfo
->SpareStrLen
) {
473 // Old String buffer is not sufficient for RequestElement, allocate a new one
475 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
476 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
477 ASSERT (NewStr
!= NULL
);
478 if (ConfigInfo
->ConfigRequest
!= NULL
) {
479 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
480 FreePool (ConfigInfo
->ConfigRequest
);
482 ConfigInfo
->ConfigRequest
= NewStr
;
483 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
486 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
487 ConfigInfo
->ElementCount
++;
488 ConfigInfo
->SpareStrLen
-= StrLen
;
494 Free resources of a Expression.
496 @param FormSet Pointer of the Expression
501 IN FORM_EXPRESSION
*Expression
505 EXPRESSION_OPCODE
*OpCode
;
506 LIST_ENTRY
*SubExpressionLink
;
507 FORM_EXPRESSION
*SubExpression
;
509 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
510 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
511 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
512 RemoveEntryList (&OpCode
->Link
);
514 if (OpCode
->ValueList
!= NULL
) {
515 FreePool (OpCode
->ValueList
);
518 if (OpCode
->ValueName
!= NULL
) {
519 FreePool (OpCode
->ValueName
);
522 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
523 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
524 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
525 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
526 RemoveEntryList(&SubExpression
->Link
);
527 DestroyExpression (SubExpression
);
533 // Free this Expression
535 FreePool (Expression
);
540 Free resources of a storage.
542 @param Storage Pointer of the storage
547 IN FORMSET_STORAGE
*Storage
551 NAME_VALUE_NODE
*NameValueNode
;
553 if (Storage
== NULL
) {
557 if (Storage
->Name
!= NULL
) {
558 FreePool (Storage
->Name
);
560 if (Storage
->Buffer
!= NULL
) {
561 FreePool (Storage
->Buffer
);
563 if (Storage
->EditBuffer
!= NULL
) {
564 FreePool (Storage
->EditBuffer
);
567 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
568 Link
= GetFirstNode (&Storage
->NameValueListHead
);
569 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
570 RemoveEntryList (&NameValueNode
->Link
);
572 if (NameValueNode
->Name
!= NULL
) {
573 FreePool (NameValueNode
->Name
);
575 if (NameValueNode
->Value
!= NULL
) {
576 FreePool (NameValueNode
->Value
);
578 if (NameValueNode
->EditValue
!= NULL
) {
579 FreePool (NameValueNode
->EditValue
);
581 FreePool (NameValueNode
);
584 if (Storage
->ConfigHdr
!= NULL
) {
585 FreePool (Storage
->ConfigHdr
);
587 if (Storage
->ConfigRequest
!= NULL
) {
588 FreePool (Storage
->ConfigRequest
);
596 Free resources of a Statement.
598 @param FormSet Pointer of the FormSet
599 @param Statement Pointer of the Statement
604 IN FORM_BROWSER_FORMSET
*FormSet
,
605 IN OUT FORM_BROWSER_STATEMENT
*Statement
609 QUESTION_DEFAULT
*Default
;
610 QUESTION_OPTION
*Option
;
611 FORM_EXPRESSION
*Expression
;
614 // Free Default value List
616 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
617 Link
= GetFirstNode (&Statement
->DefaultListHead
);
618 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
619 RemoveEntryList (&Default
->Link
);
627 while (!IsListEmpty (&Statement
->OptionListHead
)) {
628 Link
= GetFirstNode (&Statement
->OptionListHead
);
629 Option
= QUESTION_OPTION_FROM_LINK (Link
);
630 RemoveEntryList (&Option
->Link
);
636 // Free Inconsistent List
638 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
639 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
640 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
641 RemoveEntryList (&Expression
->Link
);
643 DestroyExpression (Expression
);
647 // Free NoSubmit List
649 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
650 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
651 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
652 RemoveEntryList (&Expression
->Link
);
654 DestroyExpression (Expression
);
657 if (Statement
->VariableName
!= NULL
) {
658 FreePool (Statement
->VariableName
);
660 if (Statement
->BlockName
!= NULL
) {
661 FreePool (Statement
->BlockName
);
663 if (Statement
->BufferValue
!= NULL
) {
664 FreePool (Statement
->BufferValue
);
666 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
667 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
673 Free resources of a Form.
675 @param FormSet Pointer of the FormSet
676 @param Form Pointer of the Form.
681 IN FORM_BROWSER_FORMSET
*FormSet
,
682 IN OUT FORM_BROWSER_FORM
*Form
686 FORM_EXPRESSION
*Expression
;
687 FORM_BROWSER_STATEMENT
*Statement
;
688 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
691 // Free Form Expressions
693 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
694 Link
= GetFirstNode (&Form
->ExpressionListHead
);
695 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
696 RemoveEntryList (&Expression
->Link
);
698 DestroyExpression (Expression
);
702 // Free Statements/Questions
704 while (!IsListEmpty (&Form
->StatementListHead
)) {
705 Link
= GetFirstNode (&Form
->StatementListHead
);
706 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
707 RemoveEntryList (&Statement
->Link
);
709 DestroyStatement (FormSet
, Statement
);
713 // Free ConfigRequest string.
715 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
716 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
717 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
718 RemoveEntryList (&ConfigInfo
->Link
);
720 FreePool (ConfigInfo
->ConfigRequest
);
721 FreePool (ConfigInfo
);
732 Free resources allocated for a FormSet.
734 @param FormSet Pointer of the FormSet
739 IN OUT FORM_BROWSER_FORMSET
*FormSet
743 FORMSET_STORAGE
*Storage
;
744 FORMSET_DEFAULTSTORE
*DefaultStore
;
745 FORM_EXPRESSION
*Expression
;
746 FORM_BROWSER_FORM
*Form
;
748 if (FormSet
->IfrBinaryData
== NULL
) {
750 // Uninitialized FormSet
757 // Free IFR binary buffer
759 FreePool (FormSet
->IfrBinaryData
);
762 // Free FormSet Storage
764 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
765 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
766 Link
= GetFirstNode (&FormSet
->StorageListHead
);
767 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
768 RemoveEntryList (&Storage
->Link
);
770 DestroyStorage (Storage
);
775 // Free FormSet Default Store
777 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
778 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
779 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
780 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
781 RemoveEntryList (&DefaultStore
->Link
);
783 FreePool (DefaultStore
);
788 // Free Formset Expressions
790 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
791 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
792 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
793 RemoveEntryList (&Expression
->Link
);
795 DestroyExpression (Expression
);
801 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
802 while (!IsListEmpty (&FormSet
->FormListHead
)) {
803 Link
= GetFirstNode (&FormSet
->FormListHead
);
804 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
805 RemoveEntryList (&Form
->Link
);
807 DestroyForm (FormSet
, Form
);
811 if (FormSet
->StatementBuffer
!= NULL
) {
812 FreePool (FormSet
->StatementBuffer
);
814 if (FormSet
->ExpressionBuffer
!= NULL
) {
815 FreePool (FormSet
->ExpressionBuffer
);
823 Tell whether this Operand is an Expression OpCode or not
825 @param Operand Operand of an IFR OpCode.
827 @retval TRUE This is an Expression OpCode.
828 @retval FALSE Not an Expression OpCode.
836 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
837 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
838 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
839 (Operand
== EFI_IFR_CATENATE_OP
) ||
840 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
841 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
842 (Operand
== EFI_IFR_MAP_OP
) ||
843 (Operand
== EFI_IFR_VERSION_OP
) ||
844 (Operand
== EFI_IFR_SECURITY_OP
)) {
853 Calculate number of Statemens(Questions) and Expression OpCodes.
855 @param FormSet The FormSet to be counted.
856 @param NumberOfStatement Number of Statemens(Questions)
857 @param NumberOfExpression Number of Expression OpCodes
862 IN FORM_BROWSER_FORMSET
*FormSet
,
863 IN OUT UINT16
*NumberOfStatement
,
864 IN OUT UINT16
*NumberOfExpression
867 UINT16 StatementCount
;
868 UINT16 ExpressionCount
;
877 while (Offset
< FormSet
->IfrBinaryLength
) {
878 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
879 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
882 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
889 *NumberOfStatement
= StatementCount
;
890 *NumberOfExpression
= ExpressionCount
;
896 Parse opcodes in the formset IFR binary.
898 @param FormSet Pointer of the FormSet data structure.
900 @retval EFI_SUCCESS Opcode parse success.
901 @retval Other Opcode parse fail.
906 IN FORM_BROWSER_FORMSET
*FormSet
911 FORM_BROWSER_FORM
*CurrentForm
;
912 FORM_BROWSER_STATEMENT
*CurrentStatement
;
913 EXPRESSION_OPCODE
*ExpressionOpCode
;
914 FORM_EXPRESSION
*CurrentExpression
;
921 FORMSET_STORAGE
*Storage
;
922 FORMSET_DEFAULTSTORE
*DefaultStore
;
923 QUESTION_DEFAULT
*CurrentDefault
;
924 QUESTION_OPTION
*CurrentOption
;
927 UINT16 NumberOfStatement
;
928 UINT16 NumberOfExpression
;
929 EFI_IMAGE_ID
*ImageId
;
930 BOOLEAN SuppressForQuestion
;
931 BOOLEAN SuppressForOption
;
932 BOOLEAN InScopeOptionSuppress
;
933 FORM_EXPRESSION
*OptionSuppressExpression
;
934 BOOLEAN InScopeFormSuppress
;
935 FORM_EXPRESSION
*FormSuppressExpression
;
936 UINT16 DepthOfDisable
;
937 BOOLEAN OpCodeDisabled
;
938 BOOLEAN SingleOpCodeExpression
;
939 BOOLEAN InScopeDefault
;
940 EFI_HII_VALUE
*Value
;
941 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
944 FORMSET_STORAGE
*VarStorage
;
945 LIST_ENTRY
*MapExpressionList
;
946 EFI_VARSTORE_ID TempVarstoreId
;
948 mInScopeSubtitle
= FALSE
;
949 SuppressForQuestion
= FALSE
;
950 SuppressForOption
= FALSE
;
951 InScopeFormSuppress
= FALSE
;
952 mInScopeSuppress
= FALSE
;
953 InScopeOptionSuppress
= FALSE
;
954 mInScopeGrayOut
= FALSE
;
955 mInScopeDisable
= FALSE
;
957 OpCodeDisabled
= FALSE
;
958 SingleOpCodeExpression
= FALSE
;
959 InScopeDefault
= FALSE
;
960 CurrentExpression
= NULL
;
961 CurrentDefault
= NULL
;
962 CurrentOption
= NULL
;
963 OptionSuppressExpression
= NULL
;
964 FormSuppressExpression
= NULL
;
970 MapExpressionList
= NULL
;
974 // Get the number of Statements and Expressions
976 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
979 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
980 if (FormSet
->StatementBuffer
== NULL
) {
981 return EFI_OUT_OF_RESOURCES
;
984 mExpressionOpCodeIndex
= 0;
985 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
986 if (FormSet
->ExpressionBuffer
== NULL
) {
987 return EFI_OUT_OF_RESOURCES
;
990 InitializeListHead (&FormSet
->StorageListHead
);
991 InitializeListHead (&FormSet
->DefaultStoreListHead
);
992 InitializeListHead (&FormSet
->FormListHead
);
993 ResetCurrentExpressionStack ();
994 ResetMapExpressionListStack ();
997 CurrentStatement
= NULL
;
1002 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1003 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1005 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1006 OpCodeOffset
+= OpCodeLength
;
1007 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1008 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1011 // If scope bit set, push onto scope stack
1014 PushScope (Operand
);
1017 if (OpCodeDisabled
) {
1019 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1020 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1022 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1024 } else if (Operand
== EFI_IFR_END_OP
) {
1025 Status
= PopScope (&ScopeOpCode
);
1026 if (EFI_ERROR (Status
)) {
1030 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1031 if (DepthOfDisable
== 0) {
1032 mInScopeDisable
= FALSE
;
1033 OpCodeDisabled
= FALSE
;
1042 if (IsExpressionOpCode (Operand
)) {
1043 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1044 mExpressionOpCodeIndex
++;
1046 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1047 ExpressionOpCode
->Operand
= Operand
;
1048 Value
= &ExpressionOpCode
->Value
;
1051 case EFI_IFR_EQ_ID_VAL_OP
:
1052 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1054 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1055 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1058 case EFI_IFR_EQ_ID_ID_OP
:
1059 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1060 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1063 case EFI_IFR_EQ_ID_LIST_OP
:
1064 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1065 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1066 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1069 case EFI_IFR_TO_STRING_OP
:
1070 case EFI_IFR_FIND_OP
:
1071 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1074 case EFI_IFR_STRING_REF1_OP
:
1075 Value
->Type
= EFI_IFR_TYPE_STRING
;
1076 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1079 case EFI_IFR_RULE_REF_OP
:
1080 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1083 case EFI_IFR_SPAN_OP
:
1084 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1087 case EFI_IFR_THIS_OP
:
1088 ASSERT (CurrentStatement
!= NULL
);
1089 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1092 case EFI_IFR_SECURITY_OP
:
1093 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1096 case EFI_IFR_GET_OP
:
1097 case EFI_IFR_SET_OP
:
1098 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1099 if (TempVarstoreId
!= 0) {
1100 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1101 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1102 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1103 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1104 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1105 ExpressionOpCode
->VarStorage
= VarStorage
;
1108 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1111 if (ExpressionOpCode
->VarStorage
== NULL
) {
1113 // VarStorage is not found.
1115 return EFI_INVALID_PARAMETER
;
1118 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1119 switch (ExpressionOpCode
->ValueType
) {
1120 case EFI_IFR_TYPE_BOOLEAN
:
1121 case EFI_IFR_TYPE_NUM_SIZE_8
:
1122 ExpressionOpCode
->ValueWidth
= 1;
1125 case EFI_IFR_TYPE_NUM_SIZE_16
:
1126 case EFI_IFR_TYPE_STRING
:
1127 ExpressionOpCode
->ValueWidth
= 2;
1130 case EFI_IFR_TYPE_NUM_SIZE_32
:
1131 ExpressionOpCode
->ValueWidth
= 4;
1134 case EFI_IFR_TYPE_NUM_SIZE_64
:
1135 ExpressionOpCode
->ValueWidth
= 8;
1138 case EFI_IFR_TYPE_DATE
:
1139 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1142 case EFI_IFR_TYPE_TIME
:
1143 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1146 case EFI_IFR_TYPE_OTHER
:
1147 case EFI_IFR_TYPE_UNDEFINED
:
1148 case EFI_IFR_TYPE_ACTION
:
1149 case EFI_IFR_TYPE_BUFFER
:
1152 // Invalid value type for Get/Set opcode.
1154 return EFI_INVALID_PARAMETER
;
1156 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1157 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1158 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1159 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1160 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1161 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1162 if (ExpressionOpCode
->ValueName
== NULL
) {
1164 // String ID is invalid.
1166 return EFI_INVALID_PARAMETER
;
1171 case EFI_IFR_QUESTION_REF1_OP
:
1172 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1175 case EFI_IFR_QUESTION_REF3_OP
:
1176 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1177 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1179 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1180 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1188 case EFI_IFR_TRUE_OP
:
1189 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1190 Value
->Value
.b
= TRUE
;
1193 case EFI_IFR_FALSE_OP
:
1194 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1195 Value
->Value
.b
= FALSE
;
1198 case EFI_IFR_ONE_OP
:
1199 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1200 Value
->Value
.u8
= 1;
1203 case EFI_IFR_ZERO_OP
:
1204 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1205 Value
->Value
.u8
= 0;
1208 case EFI_IFR_ONES_OP
:
1209 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1210 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1213 case EFI_IFR_UINT8_OP
:
1214 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1215 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1218 case EFI_IFR_UINT16_OP
:
1219 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1220 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1223 case EFI_IFR_UINT32_OP
:
1224 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1225 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1228 case EFI_IFR_UINT64_OP
:
1229 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1230 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1233 case EFI_IFR_UNDEFINED_OP
:
1234 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1237 case EFI_IFR_VERSION_OP
:
1238 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1239 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1246 // Create sub expression nested in MAP opcode
1248 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1249 CurrentExpression
= CreateExpression (CurrentForm
);
1250 ASSERT (MapExpressionList
!= NULL
);
1251 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1253 SingleOpCodeExpression
= TRUE
;
1256 ASSERT (CurrentExpression
!= NULL
);
1257 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1258 if (Operand
== EFI_IFR_MAP_OP
) {
1260 // Store current Map Expression List.
1262 if (MapExpressionList
!= NULL
) {
1263 PushMapExpressionList (MapExpressionList
);
1266 // Initialize new Map Expression List.
1268 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1269 InitializeListHead (MapExpressionList
);
1271 // Store current expression.
1273 PushCurrentExpression (CurrentExpression
);
1274 CurrentExpression
= NULL
;
1276 } else if (SingleOpCodeExpression
) {
1278 // There are two cases to indicate the end of an Expression:
1279 // for single OpCode expression: one Expression OpCode
1280 // for expression consists of more than one OpCode: EFI_IFR_END
1282 SingleOpCodeExpression
= FALSE
;
1284 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1286 // This is DisableIf expression for Form, it should be a constant expression
1288 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1289 if (EFI_ERROR (Status
)) {
1293 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1294 return EFI_INVALID_PARAMETER
;
1297 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1300 CurrentExpression
= NULL
;
1311 case EFI_IFR_FORM_SET_OP
:
1313 // Check the formset GUID
1315 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1316 return EFI_INVALID_PARAMETER
;
1319 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1320 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1322 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1324 // The formset OpCode contains ClassGuid
1326 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1327 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1330 InitializeListHead (&FormSet
->ExpressionListHead
);
1333 case EFI_IFR_FORM_OP
:
1335 // Create a new Form for this FormSet
1337 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1338 ASSERT (CurrentForm
!= NULL
);
1339 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1340 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1341 InitializeListHead (&CurrentForm
->StatementListHead
);
1342 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1344 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1345 CurrentForm
->NvUpdateRequired
= FALSE
;
1346 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1347 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1349 if (InScopeFormSuppress
) {
1351 // Form is inside of suppressif
1353 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1358 // Enter scope of a Form, suppressif will be used for Question or Option
1360 SuppressForQuestion
= TRUE
;
1364 // Insert into Form list of this FormSet
1366 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1369 case EFI_IFR_FORM_MAP_OP
:
1371 // Create a new Form for this FormSet
1373 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1374 ASSERT (CurrentForm
!= NULL
);
1375 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1376 CurrentForm
->NvUpdateRequired
= FALSE
;
1377 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1378 InitializeListHead (&CurrentForm
->StatementListHead
);
1379 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1380 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1382 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1384 // FormMap Form must contain at least one Map Method.
1386 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1387 return EFI_INVALID_PARAMETER
;
1390 // Try to find the standard form map method.
1392 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1393 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1394 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1395 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1401 // If the standard form map method is not found, the first map method title will be used.
1403 if (CurrentForm
->FormTitle
== 0) {
1404 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1405 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1408 if (InScopeFormSuppress
) {
1410 // Form is inside of suppressif
1412 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1417 // Enter scope of a Form, suppressif will be used for Question or Option
1419 SuppressForQuestion
= TRUE
;
1423 // Insert into Form list of this FormSet
1425 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1431 case EFI_IFR_VARSTORE_OP
:
1433 // Create a buffer Storage for this FormSet
1435 Storage
= CreateStorage (FormSet
);
1436 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1438 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1439 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1440 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1442 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1443 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1445 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1446 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1447 ASSERT (Storage
->Name
!= NULL
);
1448 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1449 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1453 // Initialize <ConfigHdr>
1455 InitializeConfigHdr (FormSet
, Storage
);
1458 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1460 // Create a name/value Storage for this FormSet
1462 Storage
= CreateStorage (FormSet
);
1463 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1465 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1466 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1469 // Initialize <ConfigHdr>
1471 InitializeConfigHdr (FormSet
, Storage
);
1474 case EFI_IFR_VARSTORE_EFI_OP
:
1476 // Create a EFI variable Storage for this FormSet
1478 Storage
= CreateStorage (FormSet
);
1479 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1481 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1482 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1483 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1489 case EFI_IFR_DEFAULTSTORE_OP
:
1490 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1491 ASSERT (DefaultStore
!= NULL
);
1492 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1494 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1495 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1498 // Insert to DefaultStore list of this Formset
1500 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1506 case EFI_IFR_SUBTITLE_OP
:
1507 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1508 ASSERT (CurrentStatement
!= NULL
);
1510 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1513 mInScopeSubtitle
= TRUE
;
1517 case EFI_IFR_TEXT_OP
:
1518 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1519 ASSERT (CurrentStatement
!= NULL
);
1521 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1524 case EFI_IFR_RESET_BUTTON_OP
:
1525 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1526 ASSERT (CurrentStatement
!= NULL
);
1527 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1533 case EFI_IFR_ACTION_OP
:
1534 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1535 ASSERT (CurrentStatement
!= NULL
);
1536 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1538 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1540 // No QuestionConfig present, so no configuration string will be processed
1542 CurrentStatement
->QuestionConfig
= 0;
1544 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1548 case EFI_IFR_REF_OP
:
1549 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1550 ASSERT (CurrentStatement
!= NULL
);
1551 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_UNDEFINED
;
1552 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1553 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1554 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1556 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1557 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1559 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1560 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1566 case EFI_IFR_ONE_OF_OP
:
1567 case EFI_IFR_NUMERIC_OP
:
1568 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1569 ASSERT(CurrentStatement
!= NULL
);
1571 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1572 Value
= &CurrentStatement
->HiiValue
;
1574 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1575 case EFI_IFR_NUMERIC_SIZE_1
:
1576 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1577 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1578 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1579 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1580 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1583 case EFI_IFR_NUMERIC_SIZE_2
:
1584 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1585 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1586 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1587 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1588 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1591 case EFI_IFR_NUMERIC_SIZE_4
:
1592 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1593 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1594 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1595 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1596 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1599 case EFI_IFR_NUMERIC_SIZE_8
:
1600 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1601 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1602 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1603 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1604 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1611 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1613 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1614 SuppressForOption
= TRUE
;
1618 case EFI_IFR_ORDERED_LIST_OP
:
1619 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1620 ASSERT(CurrentStatement
!= NULL
);
1622 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1623 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1625 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1626 CurrentStatement
->BufferValue
= NULL
;
1629 SuppressForOption
= TRUE
;
1633 case EFI_IFR_CHECKBOX_OP
:
1634 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1635 ASSERT(CurrentStatement
!= NULL
);
1637 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1638 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1639 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1641 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1645 case EFI_IFR_STRING_OP
:
1646 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1647 ASSERT (CurrentStatement
!= NULL
);
1649 // MinSize is the minimum number of characters that can be accepted for this opcode,
1650 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1651 // The characters are stored as Unicode, so the storage width should multiply 2.
1653 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1654 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1655 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1656 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1658 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1659 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1660 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1662 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1665 case EFI_IFR_PASSWORD_OP
:
1666 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1667 ASSERT (CurrentStatement
!= NULL
);
1669 // MinSize is the minimum number of characters that can be accepted for this opcode,
1670 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1671 // The characters are stored as Unicode, so the storage width should multiply 2.
1673 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1674 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1675 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1677 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1678 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1679 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1681 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1684 case EFI_IFR_DATE_OP
:
1685 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1686 ASSERT(CurrentStatement
!= NULL
);
1688 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1689 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1691 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1692 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1694 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1697 // Don't assign storage for RTC type of date/time
1699 CurrentStatement
->Storage
= NULL
;
1700 CurrentStatement
->StorageWidth
= 0;
1704 case EFI_IFR_TIME_OP
:
1705 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1706 ASSERT(CurrentStatement
!= NULL
);
1708 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1709 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1711 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1712 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1714 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1717 // Don't assign storage for RTC type of date/time
1719 CurrentStatement
->Storage
= NULL
;
1720 CurrentStatement
->StorageWidth
= 0;
1727 case EFI_IFR_DEFAULT_OP
:
1729 // EFI_IFR_DEFAULT appear in scope of a Question,
1730 // It creates a default value for the current question.
1731 // A Question may have more than one Default value which have different default types.
1733 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1734 ASSERT (CurrentDefault
!= NULL
);
1735 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1737 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1738 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1739 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1740 ExtendValueToU64 (&CurrentDefault
->Value
);
1743 // Insert to Default Value list of current Question
1745 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1748 InScopeDefault
= TRUE
;
1755 case EFI_IFR_ONE_OF_OPTION_OP
:
1757 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1758 // It create a selection for use in current Question.
1760 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1761 ASSERT (CurrentOption
!= NULL
);
1762 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1764 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1765 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1766 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1767 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1768 ExtendValueToU64 (&CurrentOption
->Value
);
1770 if (InScopeOptionSuppress
) {
1771 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1775 // Insert to Option list of current Question
1777 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1780 // Now we know the Storage width of nested Ordered List
1782 ASSERT (CurrentStatement
!= NULL
);
1783 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1785 switch (CurrentOption
->Value
.Type
) {
1786 case EFI_IFR_TYPE_NUM_SIZE_8
:
1790 case EFI_IFR_TYPE_NUM_SIZE_16
:
1794 case EFI_IFR_TYPE_NUM_SIZE_32
:
1798 case EFI_IFR_TYPE_NUM_SIZE_64
:
1804 // Invalid type for Ordered List
1809 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1810 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1811 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1813 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1820 case EFI_IFR_NO_SUBMIT_IF_OP
:
1821 case EFI_IFR_INCONSISTENT_IF_OP
:
1823 // Create an Expression node
1825 CurrentExpression
= CreateExpression (CurrentForm
);
1826 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1828 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1829 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1830 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1832 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1833 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1837 // Take a look at next OpCode to see whether current expression consists
1840 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1841 SingleOpCodeExpression
= TRUE
;
1845 case EFI_IFR_SUPPRESS_IF_OP
:
1847 // Question and Option will appear in scope of this OpCode
1849 CurrentExpression
= CreateExpression (CurrentForm
);
1850 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1852 if (CurrentForm
== NULL
) {
1853 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1855 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1858 if (SuppressForOption
) {
1859 InScopeOptionSuppress
= TRUE
;
1860 OptionSuppressExpression
= CurrentExpression
;
1861 } else if (SuppressForQuestion
) {
1862 mInScopeSuppress
= TRUE
;
1863 mSuppressExpression
= CurrentExpression
;
1865 InScopeFormSuppress
= TRUE
;
1866 FormSuppressExpression
= CurrentExpression
;
1870 // Take a look at next OpCode to see whether current expression consists
1873 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1874 SingleOpCodeExpression
= TRUE
;
1878 case EFI_IFR_GRAY_OUT_IF_OP
:
1880 // Questions will appear in scope of this OpCode
1882 CurrentExpression
= CreateExpression (CurrentForm
);
1883 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1884 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1886 mInScopeGrayOut
= TRUE
;
1887 mGrayOutExpression
= CurrentExpression
;
1890 // Take a look at next OpCode to see whether current expression consists
1893 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1894 SingleOpCodeExpression
= TRUE
;
1898 case EFI_IFR_DISABLE_IF_OP
:
1900 // The DisableIf expression should only rely on constant, so it could be
1901 // evaluated at initialization and it will not be queued
1903 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1904 ASSERT (CurrentExpression
!= NULL
);
1905 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1906 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1907 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1909 if (CurrentForm
!= NULL
) {
1911 // This is DisableIf for Question, enqueue it to Form expression list
1913 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1916 mDisableExpression
= CurrentExpression
;
1917 mInScopeDisable
= TRUE
;
1918 OpCodeDisabled
= FALSE
;
1921 // Take a look at next OpCode to see whether current expression consists
1924 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1925 SingleOpCodeExpression
= TRUE
;
1932 case EFI_IFR_VALUE_OP
:
1933 CurrentExpression
= CreateExpression (CurrentForm
);
1934 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1935 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1937 if (InScopeDefault
) {
1939 // Used for default (EFI_IFR_DEFAULT)
1941 CurrentDefault
->ValueExpression
= CurrentExpression
;
1944 // If used for a question, then the question will be read-only
1947 // Make sure CurrentStatement is not NULL.
1948 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1949 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1951 ASSERT (CurrentStatement
!= NULL
);
1952 CurrentStatement
->ValueExpression
= CurrentExpression
;
1956 // Take a look at next OpCode to see whether current expression consists
1959 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1960 SingleOpCodeExpression
= TRUE
;
1964 case EFI_IFR_RULE_OP
:
1965 CurrentExpression
= CreateExpression (CurrentForm
);
1966 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1968 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1969 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1972 // Take a look at next OpCode to see whether current expression consists
1975 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1976 SingleOpCodeExpression
= TRUE
;
1980 case EFI_IFR_READ_OP
:
1981 CurrentExpression
= CreateExpression (CurrentForm
);
1982 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
1983 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1986 // Make sure CurrentStatement is not NULL.
1987 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1988 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1990 ASSERT (CurrentStatement
!= NULL
);
1991 CurrentStatement
->ReadExpression
= CurrentExpression
;
1994 // Take a look at next OpCode to see whether current expression consists
1997 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1998 SingleOpCodeExpression
= TRUE
;
2002 case EFI_IFR_WRITE_OP
:
2003 CurrentExpression
= CreateExpression (CurrentForm
);
2004 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2005 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2008 // Make sure CurrentStatement is not NULL.
2009 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2010 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2012 ASSERT (CurrentStatement
!= NULL
);
2013 CurrentStatement
->WriteExpression
= CurrentExpression
;
2016 // Take a look at next OpCode to see whether current expression consists
2019 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2020 SingleOpCodeExpression
= TRUE
;
2027 case EFI_IFR_IMAGE_OP
:
2029 // Get ScopeOpcode from top of stack
2031 PopScope (&ScopeOpCode
);
2032 PushScope (ScopeOpCode
);
2034 switch (ScopeOpCode
) {
2035 case EFI_IFR_FORM_SET_OP
:
2036 ImageId
= &FormSet
->ImageId
;
2039 case EFI_IFR_FORM_OP
:
2040 case EFI_IFR_FORM_MAP_OP
:
2041 ASSERT (CurrentForm
!= NULL
);
2042 ImageId
= &CurrentForm
->ImageId
;
2045 case EFI_IFR_ONE_OF_OPTION_OP
:
2046 ImageId
= &CurrentOption
->ImageId
;
2051 // Make sure CurrentStatement is not NULL.
2052 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2053 // file is wrongly generated by tools such as VFR Compiler.
2055 ASSERT (CurrentStatement
!= NULL
);
2056 ImageId
= &CurrentStatement
->ImageId
;
2060 ASSERT (ImageId
!= NULL
);
2061 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2067 case EFI_IFR_REFRESH_OP
:
2068 ASSERT (CurrentStatement
!= NULL
);
2069 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2075 case EFI_IFR_REFRESH_ID_OP
:
2076 ASSERT (CurrentStatement
!= NULL
);
2077 CopyMem (&CurrentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2083 case EFI_IFR_MODAL_TAG_OP
:
2084 ASSERT (CurrentForm
!= NULL
);
2085 CurrentForm
->ModalForm
= TRUE
;
2091 case EFI_IFR_GUID_OP
:
2092 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2094 // Tiano specific GUIDed opcodes
2096 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2097 case EFI_IFR_EXTEND_OP_LABEL
:
2099 // just ignore label
2103 case EFI_IFR_EXTEND_OP_BANNER
:
2105 // By SubClass to get Banner Data from Front Page
2107 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2109 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2110 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2111 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2112 sizeof (EFI_STRING_ID
)
2117 case EFI_IFR_EXTEND_OP_CLASS
:
2118 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2121 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2122 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2135 case EFI_IFR_END_OP
:
2136 Status
= PopScope (&ScopeOpCode
);
2137 if (EFI_ERROR (Status
)) {
2142 switch (ScopeOpCode
) {
2143 case EFI_IFR_FORM_SET_OP
:
2145 // End of FormSet, update FormSet IFR binary length
2146 // to stop parsing substantial OpCodes
2148 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2151 case EFI_IFR_FORM_OP
:
2152 case EFI_IFR_FORM_MAP_OP
:
2157 SuppressForQuestion
= FALSE
;
2160 case EFI_IFR_ONE_OF_OPTION_OP
:
2164 CurrentOption
= NULL
;
2167 case EFI_IFR_SUBTITLE_OP
:
2168 mInScopeSubtitle
= FALSE
;
2171 case EFI_IFR_NO_SUBMIT_IF_OP
:
2172 case EFI_IFR_INCONSISTENT_IF_OP
:
2174 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2178 case EFI_IFR_SUPPRESS_IF_OP
:
2179 if (SuppressForOption
) {
2180 InScopeOptionSuppress
= FALSE
;
2181 } else if (SuppressForQuestion
) {
2182 mInScopeSuppress
= FALSE
;
2184 InScopeFormSuppress
= FALSE
;
2188 case EFI_IFR_GRAY_OUT_IF_OP
:
2189 mInScopeGrayOut
= FALSE
;
2192 case EFI_IFR_DISABLE_IF_OP
:
2193 mInScopeDisable
= FALSE
;
2194 OpCodeDisabled
= FALSE
;
2197 case EFI_IFR_ONE_OF_OP
:
2198 case EFI_IFR_ORDERED_LIST_OP
:
2199 SuppressForOption
= FALSE
;
2202 case EFI_IFR_DEFAULT_OP
:
2203 InScopeDefault
= FALSE
;
2206 case EFI_IFR_MAP_OP
:
2208 // Get current Map Expression List.
2210 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2211 if (Status
== EFI_ACCESS_DENIED
) {
2212 MapExpressionList
= NULL
;
2215 // Get current expression.
2217 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2218 ASSERT_EFI_ERROR (Status
);
2219 ASSERT (MapScopeDepth
> 0);
2224 if (IsExpressionOpCode (ScopeOpCode
)) {
2225 if (mInScopeDisable
&& CurrentForm
== NULL
) {
2227 // This is DisableIf expression for Form, it should be a constant expression
2229 ASSERT (CurrentExpression
!= NULL
);
2230 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2231 if (EFI_ERROR (Status
)) {
2235 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2236 return EFI_INVALID_PARAMETER
;
2239 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2241 // DisableIf Expression is only used once and not queued, free it
2243 DestroyExpression (CurrentExpression
);
2247 // End of current Expression
2249 CurrentExpression
= NULL
;