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 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
461 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
462 ConfigInfo
->SpareStrLen
= 0;
463 ConfigInfo
->Storage
= Storage
;
464 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
468 // Append <RequestElement> to <ConfigRequest>
470 if (StrLen
> ConfigInfo
->SpareStrLen
) {
472 // Old String buffer is not sufficient for RequestElement, allocate a new one
474 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
475 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
476 ASSERT (NewStr
!= NULL
);
477 if (ConfigInfo
->ConfigRequest
!= NULL
) {
478 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
479 FreePool (ConfigInfo
->ConfigRequest
);
481 ConfigInfo
->ConfigRequest
= NewStr
;
482 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
485 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
486 ConfigInfo
->ElementCount
++;
487 ConfigInfo
->SpareStrLen
-= StrLen
;
493 Free resources of a Expression.
495 @param FormSet Pointer of the Expression
500 IN FORM_EXPRESSION
*Expression
504 EXPRESSION_OPCODE
*OpCode
;
505 LIST_ENTRY
*SubExpressionLink
;
506 FORM_EXPRESSION
*SubExpression
;
508 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
509 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
510 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
511 RemoveEntryList (&OpCode
->Link
);
513 if (OpCode
->ValueList
!= NULL
) {
514 FreePool (OpCode
->ValueList
);
517 if (OpCode
->ValueName
!= NULL
) {
518 FreePool (OpCode
->ValueName
);
521 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
522 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
523 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
524 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
525 RemoveEntryList(&SubExpression
->Link
);
526 DestroyExpression (SubExpression
);
532 // Free this Expression
534 FreePool (Expression
);
539 Free resources of a storage.
541 @param Storage Pointer of the storage
546 IN FORMSET_STORAGE
*Storage
550 NAME_VALUE_NODE
*NameValueNode
;
552 if (Storage
== NULL
) {
556 if (Storage
->Name
!= NULL
) {
557 FreePool (Storage
->Name
);
559 if (Storage
->Buffer
!= NULL
) {
560 FreePool (Storage
->Buffer
);
562 if (Storage
->EditBuffer
!= NULL
) {
563 FreePool (Storage
->EditBuffer
);
566 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
567 Link
= GetFirstNode (&Storage
->NameValueListHead
);
568 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
569 RemoveEntryList (&NameValueNode
->Link
);
571 if (NameValueNode
->Name
!= NULL
) {
572 FreePool (NameValueNode
->Name
);
574 if (NameValueNode
->Value
!= NULL
) {
575 FreePool (NameValueNode
->Value
);
577 if (NameValueNode
->EditValue
!= NULL
) {
578 FreePool (NameValueNode
->EditValue
);
580 FreePool (NameValueNode
);
583 if (Storage
->ConfigHdr
!= NULL
) {
584 FreePool (Storage
->ConfigHdr
);
586 if (Storage
->ConfigRequest
!= NULL
) {
587 FreePool (Storage
->ConfigRequest
);
595 Free resources of a Statement.
597 @param FormSet Pointer of the FormSet
598 @param Statement Pointer of the Statement
603 IN FORM_BROWSER_FORMSET
*FormSet
,
604 IN OUT FORM_BROWSER_STATEMENT
*Statement
608 QUESTION_DEFAULT
*Default
;
609 QUESTION_OPTION
*Option
;
610 FORM_EXPRESSION
*Expression
;
613 // Free Default value List
615 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
616 Link
= GetFirstNode (&Statement
->DefaultListHead
);
617 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
618 RemoveEntryList (&Default
->Link
);
626 while (!IsListEmpty (&Statement
->OptionListHead
)) {
627 Link
= GetFirstNode (&Statement
->OptionListHead
);
628 Option
= QUESTION_OPTION_FROM_LINK (Link
);
629 RemoveEntryList (&Option
->Link
);
635 // Free Inconsistent List
637 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
638 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
639 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
640 RemoveEntryList (&Expression
->Link
);
642 DestroyExpression (Expression
);
646 // Free NoSubmit List
648 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
649 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
650 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
651 RemoveEntryList (&Expression
->Link
);
653 DestroyExpression (Expression
);
656 if (Statement
->VariableName
!= NULL
) {
657 FreePool (Statement
->VariableName
);
659 if (Statement
->BlockName
!= NULL
) {
660 FreePool (Statement
->BlockName
);
662 if (Statement
->BufferValue
!= NULL
) {
663 FreePool (Statement
->BufferValue
);
665 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
666 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
672 Free resources of a Form.
674 @param FormSet Pointer of the FormSet
675 @param Form Pointer of the Form.
680 IN FORM_BROWSER_FORMSET
*FormSet
,
681 IN OUT FORM_BROWSER_FORM
*Form
685 FORM_EXPRESSION
*Expression
;
686 FORM_BROWSER_STATEMENT
*Statement
;
687 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
690 // Free Form Expressions
692 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
693 Link
= GetFirstNode (&Form
->ExpressionListHead
);
694 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
695 RemoveEntryList (&Expression
->Link
);
697 DestroyExpression (Expression
);
701 // Free Statements/Questions
703 while (!IsListEmpty (&Form
->StatementListHead
)) {
704 Link
= GetFirstNode (&Form
->StatementListHead
);
705 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
706 RemoveEntryList (&Statement
->Link
);
708 DestroyStatement (FormSet
, Statement
);
712 // Free ConfigRequest string.
714 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
715 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
716 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
717 RemoveEntryList (&ConfigInfo
->Link
);
719 FreePool (ConfigInfo
->ConfigRequest
);
720 FreePool (ConfigInfo
);
731 Free resources allocated for a FormSet.
733 @param FormSet Pointer of the FormSet
738 IN OUT FORM_BROWSER_FORMSET
*FormSet
742 FORMSET_STORAGE
*Storage
;
743 FORMSET_DEFAULTSTORE
*DefaultStore
;
744 FORM_EXPRESSION
*Expression
;
745 FORM_BROWSER_FORM
*Form
;
747 if (FormSet
->IfrBinaryData
== NULL
) {
749 // Uninitialized FormSet
756 // Free IFR binary buffer
758 FreePool (FormSet
->IfrBinaryData
);
761 // Free FormSet Storage
763 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
764 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
765 Link
= GetFirstNode (&FormSet
->StorageListHead
);
766 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
767 RemoveEntryList (&Storage
->Link
);
769 DestroyStorage (Storage
);
774 // Free FormSet Default Store
776 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
777 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
778 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
779 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
780 RemoveEntryList (&DefaultStore
->Link
);
782 FreePool (DefaultStore
);
787 // Free Formset Expressions
789 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
790 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
791 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
792 RemoveEntryList (&Expression
->Link
);
794 DestroyExpression (Expression
);
800 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
801 while (!IsListEmpty (&FormSet
->FormListHead
)) {
802 Link
= GetFirstNode (&FormSet
->FormListHead
);
803 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
804 RemoveEntryList (&Form
->Link
);
806 DestroyForm (FormSet
, Form
);
810 if (FormSet
->StatementBuffer
!= NULL
) {
811 FreePool (FormSet
->StatementBuffer
);
813 if (FormSet
->ExpressionBuffer
!= NULL
) {
814 FreePool (FormSet
->ExpressionBuffer
);
822 Tell whether this Operand is an Expression OpCode or not
824 @param Operand Operand of an IFR OpCode.
826 @retval TRUE This is an Expression OpCode.
827 @retval FALSE Not an Expression OpCode.
835 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
836 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
837 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
838 (Operand
== EFI_IFR_CATENATE_OP
) ||
839 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
840 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
841 (Operand
== EFI_IFR_MAP_OP
) ||
842 (Operand
== EFI_IFR_VERSION_OP
) ||
843 (Operand
== EFI_IFR_SECURITY_OP
)) {
852 Calculate number of Statemens(Questions) and Expression OpCodes.
854 @param FormSet The FormSet to be counted.
855 @param NumberOfStatement Number of Statemens(Questions)
856 @param NumberOfExpression Number of Expression OpCodes
861 IN FORM_BROWSER_FORMSET
*FormSet
,
862 IN OUT UINT16
*NumberOfStatement
,
863 IN OUT UINT16
*NumberOfExpression
866 UINT16 StatementCount
;
867 UINT16 ExpressionCount
;
876 while (Offset
< FormSet
->IfrBinaryLength
) {
877 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
878 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
881 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
888 *NumberOfStatement
= StatementCount
;
889 *NumberOfExpression
= ExpressionCount
;
895 Parse opcodes in the formset IFR binary.
897 @param FormSet Pointer of the FormSet data structure.
899 @retval EFI_SUCCESS Opcode parse success.
900 @retval Other Opcode parse fail.
905 IN FORM_BROWSER_FORMSET
*FormSet
910 FORM_BROWSER_FORM
*CurrentForm
;
911 FORM_BROWSER_STATEMENT
*CurrentStatement
;
912 EXPRESSION_OPCODE
*ExpressionOpCode
;
913 FORM_EXPRESSION
*CurrentExpression
;
920 FORMSET_STORAGE
*Storage
;
921 FORMSET_DEFAULTSTORE
*DefaultStore
;
922 QUESTION_DEFAULT
*CurrentDefault
;
923 QUESTION_OPTION
*CurrentOption
;
926 UINT16 NumberOfStatement
;
927 UINT16 NumberOfExpression
;
928 EFI_IMAGE_ID
*ImageId
;
929 BOOLEAN SuppressForQuestion
;
930 BOOLEAN SuppressForOption
;
931 BOOLEAN InScopeOptionSuppress
;
932 FORM_EXPRESSION
*OptionSuppressExpression
;
933 BOOLEAN InScopeFormSuppress
;
934 FORM_EXPRESSION
*FormSuppressExpression
;
935 UINT16 DepthOfDisable
;
936 BOOLEAN OpCodeDisabled
;
937 BOOLEAN SingleOpCodeExpression
;
938 BOOLEAN InScopeDefault
;
939 EFI_HII_VALUE
*Value
;
940 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
943 FORMSET_STORAGE
*VarStorage
;
944 LIST_ENTRY
*MapExpressionList
;
945 EFI_VARSTORE_ID TempVarstoreId
;
947 mInScopeSubtitle
= FALSE
;
948 SuppressForQuestion
= FALSE
;
949 SuppressForOption
= FALSE
;
950 InScopeFormSuppress
= FALSE
;
951 mInScopeSuppress
= FALSE
;
952 InScopeOptionSuppress
= FALSE
;
953 mInScopeGrayOut
= FALSE
;
954 mInScopeDisable
= FALSE
;
956 OpCodeDisabled
= FALSE
;
957 SingleOpCodeExpression
= FALSE
;
958 InScopeDefault
= FALSE
;
959 CurrentExpression
= NULL
;
960 CurrentDefault
= NULL
;
961 CurrentOption
= NULL
;
962 OptionSuppressExpression
= NULL
;
963 FormSuppressExpression
= NULL
;
969 MapExpressionList
= NULL
;
973 // Get the number of Statements and Expressions
975 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
978 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
979 if (FormSet
->StatementBuffer
== NULL
) {
980 return EFI_OUT_OF_RESOURCES
;
983 mExpressionOpCodeIndex
= 0;
984 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
985 if (FormSet
->ExpressionBuffer
== NULL
) {
986 return EFI_OUT_OF_RESOURCES
;
989 InitializeListHead (&FormSet
->StorageListHead
);
990 InitializeListHead (&FormSet
->DefaultStoreListHead
);
991 InitializeListHead (&FormSet
->FormListHead
);
992 ResetCurrentExpressionStack ();
993 ResetMapExpressionListStack ();
996 CurrentStatement
= NULL
;
1001 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1002 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1004 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1005 OpCodeOffset
+= OpCodeLength
;
1006 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1007 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1010 // If scope bit set, push onto scope stack
1013 PushScope (Operand
);
1016 if (OpCodeDisabled
) {
1018 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1019 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1021 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1023 } else if (Operand
== EFI_IFR_END_OP
) {
1024 Status
= PopScope (&ScopeOpCode
);
1025 if (EFI_ERROR (Status
)) {
1029 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1030 if (DepthOfDisable
== 0) {
1031 mInScopeDisable
= FALSE
;
1032 OpCodeDisabled
= FALSE
;
1041 if (IsExpressionOpCode (Operand
)) {
1042 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1043 mExpressionOpCodeIndex
++;
1045 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1046 ExpressionOpCode
->Operand
= Operand
;
1047 Value
= &ExpressionOpCode
->Value
;
1050 case EFI_IFR_EQ_ID_VAL_OP
:
1051 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1053 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1054 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1057 case EFI_IFR_EQ_ID_ID_OP
:
1058 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1059 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1062 case EFI_IFR_EQ_ID_LIST_OP
:
1063 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1064 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1065 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1068 case EFI_IFR_TO_STRING_OP
:
1069 case EFI_IFR_FIND_OP
:
1070 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1073 case EFI_IFR_STRING_REF1_OP
:
1074 Value
->Type
= EFI_IFR_TYPE_STRING
;
1075 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1078 case EFI_IFR_RULE_REF_OP
:
1079 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1082 case EFI_IFR_SPAN_OP
:
1083 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1086 case EFI_IFR_THIS_OP
:
1087 ASSERT (CurrentStatement
!= NULL
);
1088 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1091 case EFI_IFR_SECURITY_OP
:
1092 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1095 case EFI_IFR_GET_OP
:
1096 case EFI_IFR_SET_OP
:
1097 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1098 if (TempVarstoreId
!= 0) {
1099 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1100 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1101 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1102 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1103 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1104 ExpressionOpCode
->VarStorage
= VarStorage
;
1107 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1110 if (ExpressionOpCode
->VarStorage
== NULL
) {
1112 // VarStorage is not found.
1114 return EFI_INVALID_PARAMETER
;
1117 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1118 switch (ExpressionOpCode
->ValueType
) {
1119 case EFI_IFR_TYPE_BOOLEAN
:
1120 case EFI_IFR_TYPE_NUM_SIZE_8
:
1121 ExpressionOpCode
->ValueWidth
= 1;
1124 case EFI_IFR_TYPE_NUM_SIZE_16
:
1125 case EFI_IFR_TYPE_STRING
:
1126 ExpressionOpCode
->ValueWidth
= 2;
1129 case EFI_IFR_TYPE_NUM_SIZE_32
:
1130 ExpressionOpCode
->ValueWidth
= 4;
1133 case EFI_IFR_TYPE_NUM_SIZE_64
:
1134 ExpressionOpCode
->ValueWidth
= 8;
1137 case EFI_IFR_TYPE_DATE
:
1138 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1141 case EFI_IFR_TYPE_TIME
:
1142 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1145 case EFI_IFR_TYPE_OTHER
:
1146 case EFI_IFR_TYPE_UNDEFINED
:
1147 case EFI_IFR_TYPE_ACTION
:
1148 case EFI_IFR_TYPE_BUFFER
:
1151 // Invalid value type for Get/Set opcode.
1153 return EFI_INVALID_PARAMETER
;
1155 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1156 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1157 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1158 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1159 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1160 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1161 if (ExpressionOpCode
->ValueName
== NULL
) {
1163 // String ID is invalid.
1165 return EFI_INVALID_PARAMETER
;
1170 case EFI_IFR_QUESTION_REF1_OP
:
1171 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1174 case EFI_IFR_QUESTION_REF3_OP
:
1175 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1176 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1178 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1179 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1187 case EFI_IFR_TRUE_OP
:
1188 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1189 Value
->Value
.b
= TRUE
;
1192 case EFI_IFR_FALSE_OP
:
1193 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1194 Value
->Value
.b
= FALSE
;
1197 case EFI_IFR_ONE_OP
:
1198 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1199 Value
->Value
.u8
= 1;
1202 case EFI_IFR_ZERO_OP
:
1203 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1204 Value
->Value
.u8
= 0;
1207 case EFI_IFR_ONES_OP
:
1208 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1209 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1212 case EFI_IFR_UINT8_OP
:
1213 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1214 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1217 case EFI_IFR_UINT16_OP
:
1218 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1219 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1222 case EFI_IFR_UINT32_OP
:
1223 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1224 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1227 case EFI_IFR_UINT64_OP
:
1228 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1229 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1232 case EFI_IFR_UNDEFINED_OP
:
1233 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1236 case EFI_IFR_VERSION_OP
:
1237 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1238 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1245 // Create sub expression nested in MAP opcode
1247 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1248 CurrentExpression
= CreateExpression (CurrentForm
);
1249 ASSERT (MapExpressionList
!= NULL
);
1250 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1252 SingleOpCodeExpression
= TRUE
;
1255 ASSERT (CurrentExpression
!= NULL
);
1256 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1257 if (Operand
== EFI_IFR_MAP_OP
) {
1259 // Store current Map Expression List.
1261 if (MapExpressionList
!= NULL
) {
1262 PushMapExpressionList (MapExpressionList
);
1265 // Initialize new Map Expression List.
1267 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1268 InitializeListHead (MapExpressionList
);
1270 // Store current expression.
1272 PushCurrentExpression (CurrentExpression
);
1273 CurrentExpression
= NULL
;
1275 } else if (SingleOpCodeExpression
) {
1277 // There are two cases to indicate the end of an Expression:
1278 // for single OpCode expression: one Expression OpCode
1279 // for expression consists of more than one OpCode: EFI_IFR_END
1281 SingleOpCodeExpression
= FALSE
;
1283 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1285 // This is DisableIf expression for Form, it should be a constant expression
1287 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1288 if (EFI_ERROR (Status
)) {
1292 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1293 return EFI_INVALID_PARAMETER
;
1296 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1299 CurrentExpression
= NULL
;
1310 case EFI_IFR_FORM_SET_OP
:
1312 // Check the formset GUID
1314 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1315 return EFI_INVALID_PARAMETER
;
1318 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1319 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1321 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1323 // The formset OpCode contains ClassGuid
1325 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1326 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1329 InitializeListHead (&FormSet
->ExpressionListHead
);
1332 case EFI_IFR_FORM_OP
:
1334 // Create a new Form for this FormSet
1336 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1337 ASSERT (CurrentForm
!= NULL
);
1338 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1339 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1340 InitializeListHead (&CurrentForm
->StatementListHead
);
1341 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1343 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1344 CurrentForm
->NvUpdateRequired
= FALSE
;
1345 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1346 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1348 if (InScopeFormSuppress
) {
1350 // Form is inside of suppressif
1352 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1357 // Enter scope of a Form, suppressif will be used for Question or Option
1359 SuppressForQuestion
= TRUE
;
1363 // Insert into Form list of this FormSet
1365 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1368 case EFI_IFR_FORM_MAP_OP
:
1370 // Create a new Form for this FormSet
1372 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1373 ASSERT (CurrentForm
!= NULL
);
1374 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1375 CurrentForm
->NvUpdateRequired
= FALSE
;
1376 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1377 InitializeListHead (&CurrentForm
->StatementListHead
);
1378 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1379 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1381 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1383 // FormMap Form must contain at least one Map Method.
1385 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1386 return EFI_INVALID_PARAMETER
;
1389 // Try to find the standard form map method.
1391 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1392 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1393 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1394 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1400 // If the standard form map method is not found, the first map method title will be used.
1402 if (CurrentForm
->FormTitle
== 0) {
1403 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1404 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1407 if (InScopeFormSuppress
) {
1409 // Form is inside of suppressif
1411 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1416 // Enter scope of a Form, suppressif will be used for Question or Option
1418 SuppressForQuestion
= TRUE
;
1422 // Insert into Form list of this FormSet
1424 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1430 case EFI_IFR_VARSTORE_OP
:
1432 // Create a buffer Storage for this FormSet
1434 Storage
= CreateStorage (FormSet
);
1435 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1437 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1438 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1439 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1441 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1442 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1444 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1445 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1446 ASSERT (Storage
->Name
!= NULL
);
1447 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1448 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1452 // Initialize <ConfigHdr>
1454 InitializeConfigHdr (FormSet
, Storage
);
1457 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1459 // Create a name/value Storage for this FormSet
1461 Storage
= CreateStorage (FormSet
);
1462 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1464 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1465 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1468 // Initialize <ConfigHdr>
1470 InitializeConfigHdr (FormSet
, Storage
);
1473 case EFI_IFR_VARSTORE_EFI_OP
:
1475 // Create a EFI variable Storage for this FormSet
1477 Storage
= CreateStorage (FormSet
);
1478 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1480 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1481 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1482 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1488 case EFI_IFR_DEFAULTSTORE_OP
:
1489 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1490 ASSERT (DefaultStore
!= NULL
);
1491 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1493 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1494 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1497 // Insert to DefaultStore list of this Formset
1499 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1505 case EFI_IFR_SUBTITLE_OP
:
1506 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1507 ASSERT (CurrentStatement
!= NULL
);
1509 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1512 mInScopeSubtitle
= TRUE
;
1516 case EFI_IFR_TEXT_OP
:
1517 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1518 ASSERT (CurrentStatement
!= NULL
);
1520 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1523 case EFI_IFR_RESET_BUTTON_OP
:
1524 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1525 ASSERT (CurrentStatement
!= NULL
);
1526 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1532 case EFI_IFR_ACTION_OP
:
1533 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1534 ASSERT (CurrentStatement
!= NULL
);
1535 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1537 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1539 // No QuestionConfig present, so no configuration string will be processed
1541 CurrentStatement
->QuestionConfig
= 0;
1543 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1547 case EFI_IFR_REF_OP
:
1548 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1549 ASSERT (CurrentStatement
!= NULL
);
1550 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_UNDEFINED
;
1551 CopyMem (&CurrentStatement
->RefFormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1552 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1553 CopyMem (&CurrentStatement
->RefQuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1555 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1556 CopyMem (&CurrentStatement
->RefFormSetId
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1558 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1559 CopyMem (&CurrentStatement
->RefDevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1565 case EFI_IFR_ONE_OF_OP
:
1566 case EFI_IFR_NUMERIC_OP
:
1567 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1568 ASSERT(CurrentStatement
!= NULL
);
1570 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1571 Value
= &CurrentStatement
->HiiValue
;
1573 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1574 case EFI_IFR_NUMERIC_SIZE_1
:
1575 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1576 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1577 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1578 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1579 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1582 case EFI_IFR_NUMERIC_SIZE_2
:
1583 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1584 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1585 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1586 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1587 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1590 case EFI_IFR_NUMERIC_SIZE_4
:
1591 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1592 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1593 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1594 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1595 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1598 case EFI_IFR_NUMERIC_SIZE_8
:
1599 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1600 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1601 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1602 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1603 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1610 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1612 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1613 SuppressForOption
= TRUE
;
1617 case EFI_IFR_ORDERED_LIST_OP
:
1618 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1619 ASSERT(CurrentStatement
!= NULL
);
1621 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1622 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1624 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1625 CurrentStatement
->BufferValue
= NULL
;
1628 SuppressForOption
= TRUE
;
1632 case EFI_IFR_CHECKBOX_OP
:
1633 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1634 ASSERT(CurrentStatement
!= NULL
);
1636 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1637 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1638 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1640 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1644 case EFI_IFR_STRING_OP
:
1645 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1646 ASSERT (CurrentStatement
!= NULL
);
1648 // MinSize is the minimum number of characters that can be accepted for this opcode,
1649 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1650 // The characters are stored as Unicode, so the storage width should multiply 2.
1652 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1653 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1654 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1655 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1657 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1658 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1659 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1661 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1664 case EFI_IFR_PASSWORD_OP
:
1665 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1666 ASSERT (CurrentStatement
!= NULL
);
1668 // MinSize is the minimum number of characters that can be accepted for this opcode,
1669 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1670 // The characters are stored as Unicode, so the storage width should multiply 2.
1672 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1673 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1674 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1676 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1677 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1678 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1680 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1683 case EFI_IFR_DATE_OP
:
1684 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1685 ASSERT(CurrentStatement
!= NULL
);
1687 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1688 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1690 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1691 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1693 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1696 // Don't assign storage for RTC type of date/time
1698 CurrentStatement
->Storage
= NULL
;
1699 CurrentStatement
->StorageWidth
= 0;
1703 case EFI_IFR_TIME_OP
:
1704 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1705 ASSERT(CurrentStatement
!= NULL
);
1707 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1708 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1710 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1711 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1713 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1716 // Don't assign storage for RTC type of date/time
1718 CurrentStatement
->Storage
= NULL
;
1719 CurrentStatement
->StorageWidth
= 0;
1726 case EFI_IFR_DEFAULT_OP
:
1728 // EFI_IFR_DEFAULT appear in scope of a Question,
1729 // It creates a default value for the current question.
1730 // A Question may have more than one Default value which have different default types.
1732 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1733 ASSERT (CurrentDefault
!= NULL
);
1734 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1736 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1737 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1738 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1739 ExtendValueToU64 (&CurrentDefault
->Value
);
1742 // Insert to Default Value list of current Question
1744 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1747 InScopeDefault
= TRUE
;
1754 case EFI_IFR_ONE_OF_OPTION_OP
:
1756 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1757 // It create a selection for use in current Question.
1759 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1760 ASSERT (CurrentOption
!= NULL
);
1761 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1763 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1764 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1765 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1766 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1767 ExtendValueToU64 (&CurrentOption
->Value
);
1769 if (InScopeOptionSuppress
) {
1770 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1774 // Insert to Option list of current Question
1776 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1779 // Now we know the Storage width of nested Ordered List
1781 ASSERT (CurrentStatement
!= NULL
);
1782 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1784 switch (CurrentOption
->Value
.Type
) {
1785 case EFI_IFR_TYPE_NUM_SIZE_8
:
1789 case EFI_IFR_TYPE_NUM_SIZE_16
:
1793 case EFI_IFR_TYPE_NUM_SIZE_32
:
1797 case EFI_IFR_TYPE_NUM_SIZE_64
:
1803 // Invalid type for Ordered List
1808 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1809 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1810 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1812 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1819 case EFI_IFR_NO_SUBMIT_IF_OP
:
1820 case EFI_IFR_INCONSISTENT_IF_OP
:
1822 // Create an Expression node
1824 CurrentExpression
= CreateExpression (CurrentForm
);
1825 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1827 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1828 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1829 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1831 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1832 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1836 // Take a look at next OpCode to see whether current expression consists
1839 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1840 SingleOpCodeExpression
= TRUE
;
1844 case EFI_IFR_SUPPRESS_IF_OP
:
1846 // Question and Option will appear in scope of this OpCode
1848 CurrentExpression
= CreateExpression (CurrentForm
);
1849 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1851 if (CurrentForm
== NULL
) {
1852 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1854 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1857 if (SuppressForOption
) {
1858 InScopeOptionSuppress
= TRUE
;
1859 OptionSuppressExpression
= CurrentExpression
;
1860 } else if (SuppressForQuestion
) {
1861 mInScopeSuppress
= TRUE
;
1862 mSuppressExpression
= CurrentExpression
;
1864 InScopeFormSuppress
= TRUE
;
1865 FormSuppressExpression
= CurrentExpression
;
1869 // Take a look at next OpCode to see whether current expression consists
1872 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1873 SingleOpCodeExpression
= TRUE
;
1877 case EFI_IFR_GRAY_OUT_IF_OP
:
1879 // Questions will appear in scope of this OpCode
1881 CurrentExpression
= CreateExpression (CurrentForm
);
1882 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1883 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1885 mInScopeGrayOut
= TRUE
;
1886 mGrayOutExpression
= CurrentExpression
;
1889 // Take a look at next OpCode to see whether current expression consists
1892 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1893 SingleOpCodeExpression
= TRUE
;
1897 case EFI_IFR_DISABLE_IF_OP
:
1899 // The DisableIf expression should only rely on constant, so it could be
1900 // evaluated at initialization and it will not be queued
1902 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1903 ASSERT (CurrentExpression
!= NULL
);
1904 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1905 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1906 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1908 if (CurrentForm
!= NULL
) {
1910 // This is DisableIf for Question, enqueue it to Form expression list
1912 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1915 mDisableExpression
= CurrentExpression
;
1916 mInScopeDisable
= TRUE
;
1917 OpCodeDisabled
= FALSE
;
1920 // Take a look at next OpCode to see whether current expression consists
1923 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1924 SingleOpCodeExpression
= TRUE
;
1931 case EFI_IFR_VALUE_OP
:
1932 CurrentExpression
= CreateExpression (CurrentForm
);
1933 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1934 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1936 if (InScopeDefault
) {
1938 // Used for default (EFI_IFR_DEFAULT)
1940 CurrentDefault
->ValueExpression
= CurrentExpression
;
1943 // If used for a question, then the question will be read-only
1946 // Make sure CurrentStatement is not NULL.
1947 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1948 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1950 ASSERT (CurrentStatement
!= NULL
);
1951 CurrentStatement
->ValueExpression
= CurrentExpression
;
1955 // Take a look at next OpCode to see whether current expression consists
1958 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1959 SingleOpCodeExpression
= TRUE
;
1963 case EFI_IFR_RULE_OP
:
1964 CurrentExpression
= CreateExpression (CurrentForm
);
1965 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
1967 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
1968 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1971 // Take a look at next OpCode to see whether current expression consists
1974 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1975 SingleOpCodeExpression
= TRUE
;
1979 case EFI_IFR_READ_OP
:
1980 CurrentExpression
= CreateExpression (CurrentForm
);
1981 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
1982 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1985 // Make sure CurrentStatement is not NULL.
1986 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1987 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1989 ASSERT (CurrentStatement
!= NULL
);
1990 CurrentStatement
->ReadExpression
= CurrentExpression
;
1993 // Take a look at next OpCode to see whether current expression consists
1996 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1997 SingleOpCodeExpression
= TRUE
;
2001 case EFI_IFR_WRITE_OP
:
2002 CurrentExpression
= CreateExpression (CurrentForm
);
2003 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2004 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2007 // Make sure CurrentStatement is not NULL.
2008 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2009 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2011 ASSERT (CurrentStatement
!= NULL
);
2012 CurrentStatement
->WriteExpression
= CurrentExpression
;
2015 // Take a look at next OpCode to see whether current expression consists
2018 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2019 SingleOpCodeExpression
= TRUE
;
2026 case EFI_IFR_IMAGE_OP
:
2028 // Get ScopeOpcode from top of stack
2030 PopScope (&ScopeOpCode
);
2031 PushScope (ScopeOpCode
);
2033 switch (ScopeOpCode
) {
2034 case EFI_IFR_FORM_SET_OP
:
2035 ImageId
= &FormSet
->ImageId
;
2038 case EFI_IFR_FORM_OP
:
2039 case EFI_IFR_FORM_MAP_OP
:
2040 ASSERT (CurrentForm
!= NULL
);
2041 ImageId
= &CurrentForm
->ImageId
;
2044 case EFI_IFR_ONE_OF_OPTION_OP
:
2045 ImageId
= &CurrentOption
->ImageId
;
2050 // Make sure CurrentStatement is not NULL.
2051 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2052 // file is wrongly generated by tools such as VFR Compiler.
2054 ASSERT (CurrentStatement
!= NULL
);
2055 ImageId
= &CurrentStatement
->ImageId
;
2059 ASSERT (ImageId
!= NULL
);
2060 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2066 case EFI_IFR_REFRESH_OP
:
2067 ASSERT (CurrentStatement
!= NULL
);
2068 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2074 case EFI_IFR_GUID_OP
:
2075 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2077 // Tiano specific GUIDed opcodes
2079 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2080 case EFI_IFR_EXTEND_OP_LABEL
:
2082 // just ignore label
2086 case EFI_IFR_EXTEND_OP_BANNER
:
2088 // By SubClass to get Banner Data from Front Page
2090 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2092 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2093 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2094 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2095 sizeof (EFI_STRING_ID
)
2100 case EFI_IFR_EXTEND_OP_CLASS
:
2101 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2104 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2105 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2118 case EFI_IFR_END_OP
:
2119 Status
= PopScope (&ScopeOpCode
);
2120 if (EFI_ERROR (Status
)) {
2125 switch (ScopeOpCode
) {
2126 case EFI_IFR_FORM_SET_OP
:
2128 // End of FormSet, update FormSet IFR binary length
2129 // to stop parsing substantial OpCodes
2131 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2134 case EFI_IFR_FORM_OP
:
2135 case EFI_IFR_FORM_MAP_OP
:
2140 SuppressForQuestion
= FALSE
;
2143 case EFI_IFR_ONE_OF_OPTION_OP
:
2147 CurrentOption
= NULL
;
2150 case EFI_IFR_SUBTITLE_OP
:
2151 mInScopeSubtitle
= FALSE
;
2154 case EFI_IFR_NO_SUBMIT_IF_OP
:
2155 case EFI_IFR_INCONSISTENT_IF_OP
:
2157 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2161 case EFI_IFR_SUPPRESS_IF_OP
:
2162 if (SuppressForOption
) {
2163 InScopeOptionSuppress
= FALSE
;
2164 } else if (SuppressForQuestion
) {
2165 mInScopeSuppress
= FALSE
;
2167 InScopeFormSuppress
= FALSE
;
2171 case EFI_IFR_GRAY_OUT_IF_OP
:
2172 mInScopeGrayOut
= FALSE
;
2175 case EFI_IFR_DISABLE_IF_OP
:
2176 mInScopeDisable
= FALSE
;
2177 OpCodeDisabled
= FALSE
;
2180 case EFI_IFR_ONE_OF_OP
:
2181 case EFI_IFR_ORDERED_LIST_OP
:
2182 SuppressForOption
= FALSE
;
2185 case EFI_IFR_DEFAULT_OP
:
2186 InScopeDefault
= FALSE
;
2189 case EFI_IFR_MAP_OP
:
2191 // Get current Map Expression List.
2193 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2194 if (Status
== EFI_ACCESS_DENIED
) {
2195 MapExpressionList
= NULL
;
2198 // Get current expression.
2200 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2201 ASSERT_EFI_ERROR (Status
);
2202 ASSERT (MapScopeDepth
> 0);
2207 if (IsExpressionOpCode (ScopeOpCode
)) {
2208 if (mInScopeDisable
&& CurrentForm
== NULL
) {
2210 // This is DisableIf expression for Form, it should be a constant expression
2212 ASSERT (CurrentExpression
!= NULL
);
2213 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2214 if (EFI_ERROR (Status
)) {
2218 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2219 return EFI_INVALID_PARAMETER
;
2222 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2224 // DisableIf Expression is only used once and not queued, free it
2226 DestroyExpression (CurrentExpression
);
2230 // End of current Expression
2232 CurrentExpression
= NULL
;