2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2012, 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 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
334 Name
= Storage
->Name
;
339 Storage
->ConfigHdr
= HiiConstructConfigHdr (
342 FormSet
->DriverHandle
345 if (Storage
->ConfigHdr
== NULL
) {
346 return EFI_NOT_FOUND
;
349 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
350 Storage
->SpareStrLen
= 0;
357 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
359 @param FormSet Pointer of the current FormSet.
360 @param Question The Question to be initialized.
361 @param Form Pointer of the current form.
363 @retval EFI_SUCCESS Function success.
364 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
368 InitializeRequestElement (
369 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
370 IN OUT FORM_BROWSER_STATEMENT
*Question
,
371 IN OUT FORM_BROWSER_FORM
*Form
374 FORMSET_STORAGE
*Storage
;
378 CHAR16 RequestElement
[30];
381 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
383 Storage
= Question
->Storage
;
384 if (Storage
== NULL
) {
385 return EFI_INVALID_PARAMETER
;
388 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
390 // <ConfigRequest> is unnecessary for EFI variable storage,
391 // GetVariable()/SetVariable() will be used to retrieve/save values
397 // Prepare <RequestElement>
399 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
400 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
401 StrLen
= UnicodeSPrint (
403 30 * sizeof (CHAR16
),
404 L
"&OFFSET=%x&WIDTH=%x",
405 Question
->VarStoreInfo
.VarOffset
,
406 Question
->StorageWidth
408 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
410 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
413 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
415 // Password with CALLBACK flag is stored in encoded format,
416 // so don't need to append it to <ConfigRequest>
422 // Append <RequestElement> to <ConfigRequest>
424 if (StrLen
> Storage
->SpareStrLen
) {
426 // Old String buffer is not sufficient for RequestElement, allocate a new one
428 StringSize
= (Storage
->ConfigRequest
!= NULL
) ? StrSize (Storage
->ConfigRequest
) : sizeof (CHAR16
);
429 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
430 ASSERT (NewStr
!= NULL
);
431 if (Storage
->ConfigRequest
!= NULL
) {
432 CopyMem (NewStr
, Storage
->ConfigRequest
, StringSize
);
433 FreePool (Storage
->ConfigRequest
);
435 Storage
->ConfigRequest
= NewStr
;
436 Storage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
439 StrCat (Storage
->ConfigRequest
, RequestElement
);
440 Storage
->ElementCount
++;
441 Storage
->SpareStrLen
-= StrLen
;
444 // Update the Config Request info saved in the form.
448 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
449 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
450 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
452 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
->VarStoreId
== Storage
->VarStoreId
) {
457 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
461 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
462 ASSERT (ConfigInfo
!= NULL
);
463 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
464 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
465 ConfigInfo
->SpareStrLen
= 0;
466 ConfigInfo
->Storage
= Storage
;
467 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
471 // Append <RequestElement> to <ConfigRequest>
473 if (StrLen
> ConfigInfo
->SpareStrLen
) {
475 // Old String buffer is not sufficient for RequestElement, allocate a new one
477 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
478 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
479 ASSERT (NewStr
!= NULL
);
480 if (ConfigInfo
->ConfigRequest
!= NULL
) {
481 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
482 FreePool (ConfigInfo
->ConfigRequest
);
484 ConfigInfo
->ConfigRequest
= NewStr
;
485 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
488 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
489 ConfigInfo
->ElementCount
++;
490 ConfigInfo
->SpareStrLen
-= StrLen
;
496 Free resources of a Expression.
498 @param FormSet Pointer of the Expression
503 IN FORM_EXPRESSION
*Expression
507 EXPRESSION_OPCODE
*OpCode
;
508 LIST_ENTRY
*SubExpressionLink
;
509 FORM_EXPRESSION
*SubExpression
;
511 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
512 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
513 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
514 RemoveEntryList (&OpCode
->Link
);
516 if (OpCode
->ValueList
!= NULL
) {
517 FreePool (OpCode
->ValueList
);
520 if (OpCode
->ValueName
!= NULL
) {
521 FreePool (OpCode
->ValueName
);
524 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
525 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
526 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
527 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
528 RemoveEntryList(&SubExpression
->Link
);
529 DestroyExpression (SubExpression
);
535 // Free this Expression
537 FreePool (Expression
);
542 Free resources of a storage.
544 @param Storage Pointer of the storage
549 IN FORMSET_STORAGE
*Storage
553 NAME_VALUE_NODE
*NameValueNode
;
555 if (Storage
== NULL
) {
559 if (Storage
->Name
!= NULL
) {
560 FreePool (Storage
->Name
);
562 if (Storage
->Buffer
!= NULL
) {
563 FreePool (Storage
->Buffer
);
565 if (Storage
->EditBuffer
!= NULL
) {
566 FreePool (Storage
->EditBuffer
);
569 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
570 Link
= GetFirstNode (&Storage
->NameValueListHead
);
571 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
572 RemoveEntryList (&NameValueNode
->Link
);
574 if (NameValueNode
->Name
!= NULL
) {
575 FreePool (NameValueNode
->Name
);
577 if (NameValueNode
->Value
!= NULL
) {
578 FreePool (NameValueNode
->Value
);
580 if (NameValueNode
->EditValue
!= NULL
) {
581 FreePool (NameValueNode
->EditValue
);
583 FreePool (NameValueNode
);
586 if (Storage
->ConfigHdr
!= NULL
) {
587 FreePool (Storage
->ConfigHdr
);
589 if (Storage
->ConfigRequest
!= NULL
) {
590 FreePool (Storage
->ConfigRequest
);
598 Free resources of a Statement.
600 @param FormSet Pointer of the FormSet
601 @param Statement Pointer of the Statement
606 IN FORM_BROWSER_FORMSET
*FormSet
,
607 IN OUT FORM_BROWSER_STATEMENT
*Statement
611 QUESTION_DEFAULT
*Default
;
612 QUESTION_OPTION
*Option
;
613 FORM_EXPRESSION
*Expression
;
616 // Free Default value List
618 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
619 Link
= GetFirstNode (&Statement
->DefaultListHead
);
620 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
621 RemoveEntryList (&Default
->Link
);
629 while (!IsListEmpty (&Statement
->OptionListHead
)) {
630 Link
= GetFirstNode (&Statement
->OptionListHead
);
631 Option
= QUESTION_OPTION_FROM_LINK (Link
);
632 RemoveEntryList (&Option
->Link
);
638 // Free Inconsistent List
640 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
641 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
642 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
643 RemoveEntryList (&Expression
->Link
);
645 DestroyExpression (Expression
);
649 // Free NoSubmit List
651 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
652 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
653 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
654 RemoveEntryList (&Expression
->Link
);
656 DestroyExpression (Expression
);
659 if (Statement
->VariableName
!= NULL
) {
660 FreePool (Statement
->VariableName
);
662 if (Statement
->BlockName
!= NULL
) {
663 FreePool (Statement
->BlockName
);
665 if (Statement
->BufferValue
!= NULL
) {
666 FreePool (Statement
->BufferValue
);
668 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
669 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
675 Free resources of a Form.
677 @param FormSet Pointer of the FormSet
678 @param Form Pointer of the Form.
683 IN FORM_BROWSER_FORMSET
*FormSet
,
684 IN OUT FORM_BROWSER_FORM
*Form
688 FORM_EXPRESSION
*Expression
;
689 FORM_BROWSER_STATEMENT
*Statement
;
690 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
693 // Free Form Expressions
695 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
696 Link
= GetFirstNode (&Form
->ExpressionListHead
);
697 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
698 RemoveEntryList (&Expression
->Link
);
700 DestroyExpression (Expression
);
704 // Free Statements/Questions
706 while (!IsListEmpty (&Form
->StatementListHead
)) {
707 Link
= GetFirstNode (&Form
->StatementListHead
);
708 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
709 RemoveEntryList (&Statement
->Link
);
711 DestroyStatement (FormSet
, Statement
);
715 // Free ConfigRequest string.
717 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
718 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
719 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
720 RemoveEntryList (&ConfigInfo
->Link
);
722 FreePool (ConfigInfo
->ConfigRequest
);
723 FreePool (ConfigInfo
);
734 Free resources allocated for a FormSet.
736 @param FormSet Pointer of the FormSet
741 IN OUT FORM_BROWSER_FORMSET
*FormSet
745 FORMSET_STORAGE
*Storage
;
746 FORMSET_DEFAULTSTORE
*DefaultStore
;
747 FORM_EXPRESSION
*Expression
;
748 FORM_BROWSER_FORM
*Form
;
750 if (FormSet
->IfrBinaryData
== NULL
) {
752 // Uninitialized FormSet
759 // Free IFR binary buffer
761 FreePool (FormSet
->IfrBinaryData
);
764 // Free FormSet Storage
766 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
767 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
768 Link
= GetFirstNode (&FormSet
->StorageListHead
);
769 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
770 RemoveEntryList (&Storage
->Link
);
772 DestroyStorage (Storage
);
777 // Free FormSet Default Store
779 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
780 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
781 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
782 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
783 RemoveEntryList (&DefaultStore
->Link
);
785 FreePool (DefaultStore
);
790 // Free Formset Expressions
792 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
793 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
794 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
795 RemoveEntryList (&Expression
->Link
);
797 DestroyExpression (Expression
);
803 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
804 while (!IsListEmpty (&FormSet
->FormListHead
)) {
805 Link
= GetFirstNode (&FormSet
->FormListHead
);
806 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
807 RemoveEntryList (&Form
->Link
);
809 DestroyForm (FormSet
, Form
);
813 if (FormSet
->StatementBuffer
!= NULL
) {
814 FreePool (FormSet
->StatementBuffer
);
816 if (FormSet
->ExpressionBuffer
!= NULL
) {
817 FreePool (FormSet
->ExpressionBuffer
);
825 Tell whether this Operand is an Expression OpCode or not
827 @param Operand Operand of an IFR OpCode.
829 @retval TRUE This is an Expression OpCode.
830 @retval FALSE Not an Expression OpCode.
838 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
839 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
840 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
841 (Operand
== EFI_IFR_CATENATE_OP
) ||
842 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
843 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
844 (Operand
== EFI_IFR_MAP_OP
) ||
845 (Operand
== EFI_IFR_VERSION_OP
) ||
846 (Operand
== EFI_IFR_SECURITY_OP
)) {
855 Calculate number of Statemens(Questions) and Expression OpCodes.
857 @param FormSet The FormSet to be counted.
858 @param NumberOfStatement Number of Statemens(Questions)
859 @param NumberOfExpression Number of Expression OpCodes
864 IN FORM_BROWSER_FORMSET
*FormSet
,
865 IN OUT UINT16
*NumberOfStatement
,
866 IN OUT UINT16
*NumberOfExpression
869 UINT16 StatementCount
;
870 UINT16 ExpressionCount
;
879 while (Offset
< FormSet
->IfrBinaryLength
) {
880 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
881 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
884 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
891 *NumberOfStatement
= StatementCount
;
892 *NumberOfExpression
= ExpressionCount
;
898 Parse opcodes in the formset IFR binary.
900 @param FormSet Pointer of the FormSet data structure.
902 @retval EFI_SUCCESS Opcode parse success.
903 @retval Other Opcode parse fail.
908 IN FORM_BROWSER_FORMSET
*FormSet
913 FORM_BROWSER_FORM
*CurrentForm
;
914 FORM_BROWSER_STATEMENT
*CurrentStatement
;
915 EXPRESSION_OPCODE
*ExpressionOpCode
;
916 FORM_EXPRESSION
*CurrentExpression
;
923 FORMSET_STORAGE
*Storage
;
924 FORMSET_DEFAULTSTORE
*DefaultStore
;
925 QUESTION_DEFAULT
*CurrentDefault
;
926 QUESTION_OPTION
*CurrentOption
;
929 UINT16 NumberOfStatement
;
930 UINT16 NumberOfExpression
;
931 EFI_IMAGE_ID
*ImageId
;
932 BOOLEAN SuppressForQuestion
;
933 BOOLEAN SuppressForOption
;
934 BOOLEAN InScopeOptionSuppress
;
935 FORM_EXPRESSION
*OptionSuppressExpression
;
936 BOOLEAN InScopeFormSuppress
;
937 FORM_EXPRESSION
*FormSuppressExpression
;
938 UINT16 DepthOfDisable
;
939 BOOLEAN OpCodeDisabled
;
940 BOOLEAN SingleOpCodeExpression
;
941 BOOLEAN InScopeDefault
;
942 EFI_HII_VALUE
*Value
;
943 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
946 FORMSET_STORAGE
*VarStorage
;
947 LIST_ENTRY
*MapExpressionList
;
948 EFI_VARSTORE_ID TempVarstoreId
;
950 mInScopeSubtitle
= FALSE
;
951 SuppressForQuestion
= FALSE
;
952 SuppressForOption
= FALSE
;
953 InScopeFormSuppress
= FALSE
;
954 mInScopeSuppress
= FALSE
;
955 InScopeOptionSuppress
= FALSE
;
956 mInScopeGrayOut
= FALSE
;
957 mInScopeDisable
= FALSE
;
959 OpCodeDisabled
= FALSE
;
960 SingleOpCodeExpression
= FALSE
;
961 InScopeDefault
= FALSE
;
962 CurrentExpression
= NULL
;
963 CurrentDefault
= NULL
;
964 CurrentOption
= NULL
;
965 OptionSuppressExpression
= NULL
;
966 FormSuppressExpression
= NULL
;
972 MapExpressionList
= NULL
;
976 // Get the number of Statements and Expressions
978 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
981 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
982 if (FormSet
->StatementBuffer
== NULL
) {
983 return EFI_OUT_OF_RESOURCES
;
986 mExpressionOpCodeIndex
= 0;
987 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
988 if (FormSet
->ExpressionBuffer
== NULL
) {
989 return EFI_OUT_OF_RESOURCES
;
992 InitializeListHead (&FormSet
->StorageListHead
);
993 InitializeListHead (&FormSet
->DefaultStoreListHead
);
994 InitializeListHead (&FormSet
->FormListHead
);
995 InitializeListHead (&FormSet
->ExpressionListHead
);
996 ResetCurrentExpressionStack ();
997 ResetMapExpressionListStack ();
1000 CurrentStatement
= NULL
;
1005 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1006 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1008 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1009 OpCodeOffset
+= OpCodeLength
;
1010 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1011 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1014 // If scope bit set, push onto scope stack
1017 PushScope (Operand
);
1020 if (OpCodeDisabled
) {
1022 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1023 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1025 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1027 } else if (Operand
== EFI_IFR_END_OP
) {
1028 Status
= PopScope (&ScopeOpCode
);
1029 if (EFI_ERROR (Status
)) {
1033 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1034 if (DepthOfDisable
== 0) {
1035 mInScopeDisable
= FALSE
;
1036 OpCodeDisabled
= FALSE
;
1045 if (IsExpressionOpCode (Operand
)) {
1046 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1047 mExpressionOpCodeIndex
++;
1049 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1050 ExpressionOpCode
->Operand
= Operand
;
1051 Value
= &ExpressionOpCode
->Value
;
1054 case EFI_IFR_EQ_ID_VAL_OP
:
1055 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1057 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1058 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1061 case EFI_IFR_EQ_ID_ID_OP
:
1062 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1063 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1066 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1067 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1068 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1069 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1072 case EFI_IFR_TO_STRING_OP
:
1073 case EFI_IFR_FIND_OP
:
1074 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1077 case EFI_IFR_STRING_REF1_OP
:
1078 Value
->Type
= EFI_IFR_TYPE_STRING
;
1079 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1082 case EFI_IFR_RULE_REF_OP
:
1083 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1086 case EFI_IFR_SPAN_OP
:
1087 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1090 case EFI_IFR_THIS_OP
:
1091 ASSERT (CurrentStatement
!= NULL
);
1092 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1095 case EFI_IFR_SECURITY_OP
:
1096 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1099 case EFI_IFR_GET_OP
:
1100 case EFI_IFR_SET_OP
:
1101 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1102 if (TempVarstoreId
!= 0) {
1103 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1104 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1105 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1106 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1107 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1108 ExpressionOpCode
->VarStorage
= VarStorage
;
1111 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1114 if (ExpressionOpCode
->VarStorage
== NULL
) {
1116 // VarStorage is not found.
1118 return EFI_INVALID_PARAMETER
;
1121 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1122 switch (ExpressionOpCode
->ValueType
) {
1123 case EFI_IFR_TYPE_BOOLEAN
:
1124 case EFI_IFR_TYPE_NUM_SIZE_8
:
1125 ExpressionOpCode
->ValueWidth
= 1;
1128 case EFI_IFR_TYPE_NUM_SIZE_16
:
1129 case EFI_IFR_TYPE_STRING
:
1130 ExpressionOpCode
->ValueWidth
= 2;
1133 case EFI_IFR_TYPE_NUM_SIZE_32
:
1134 ExpressionOpCode
->ValueWidth
= 4;
1137 case EFI_IFR_TYPE_NUM_SIZE_64
:
1138 ExpressionOpCode
->ValueWidth
= 8;
1141 case EFI_IFR_TYPE_DATE
:
1142 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1145 case EFI_IFR_TYPE_TIME
:
1146 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1149 case EFI_IFR_TYPE_REF
:
1150 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
1153 case EFI_IFR_TYPE_OTHER
:
1154 case EFI_IFR_TYPE_UNDEFINED
:
1155 case EFI_IFR_TYPE_ACTION
:
1156 case EFI_IFR_TYPE_BUFFER
:
1159 // Invalid value type for Get/Set opcode.
1161 return EFI_INVALID_PARAMETER
;
1163 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1164 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1165 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1166 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1167 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1168 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1169 if (ExpressionOpCode
->ValueName
== NULL
) {
1171 // String ID is invalid.
1173 return EFI_INVALID_PARAMETER
;
1178 case EFI_IFR_QUESTION_REF1_OP
:
1179 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1182 case EFI_IFR_QUESTION_REF3_OP
:
1183 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1184 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1186 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1187 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1195 case EFI_IFR_TRUE_OP
:
1196 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1197 Value
->Value
.b
= TRUE
;
1200 case EFI_IFR_FALSE_OP
:
1201 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1202 Value
->Value
.b
= FALSE
;
1205 case EFI_IFR_ONE_OP
:
1206 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1207 Value
->Value
.u8
= 1;
1210 case EFI_IFR_ZERO_OP
:
1211 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1212 Value
->Value
.u8
= 0;
1215 case EFI_IFR_ONES_OP
:
1216 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1217 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1220 case EFI_IFR_UINT8_OP
:
1221 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1222 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1225 case EFI_IFR_UINT16_OP
:
1226 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1227 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1230 case EFI_IFR_UINT32_OP
:
1231 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1232 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1235 case EFI_IFR_UINT64_OP
:
1236 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1237 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1240 case EFI_IFR_UNDEFINED_OP
:
1241 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1244 case EFI_IFR_VERSION_OP
:
1245 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1246 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1253 // Create sub expression nested in MAP opcode
1255 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1256 CurrentExpression
= CreateExpression (CurrentForm
);
1257 ASSERT (MapExpressionList
!= NULL
);
1258 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1260 SingleOpCodeExpression
= TRUE
;
1263 ASSERT (CurrentExpression
!= NULL
);
1264 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1265 if (Operand
== EFI_IFR_MAP_OP
) {
1267 // Store current Map Expression List.
1269 if (MapExpressionList
!= NULL
) {
1270 PushMapExpressionList (MapExpressionList
);
1273 // Initialize new Map Expression List.
1275 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1276 InitializeListHead (MapExpressionList
);
1278 // Store current expression.
1280 PushCurrentExpression (CurrentExpression
);
1281 CurrentExpression
= NULL
;
1283 } else if (SingleOpCodeExpression
) {
1285 // There are two cases to indicate the end of an Expression:
1286 // for single OpCode expression: one Expression OpCode
1287 // for expression consists of more than one OpCode: EFI_IFR_END
1289 SingleOpCodeExpression
= FALSE
;
1291 if (mInScopeDisable
&& CurrentForm
== NULL
) {
1293 // This is DisableIf expression for Form, it should be a constant expression
1295 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1296 if (EFI_ERROR (Status
)) {
1300 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1301 return EFI_INVALID_PARAMETER
;
1304 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1307 CurrentExpression
= NULL
;
1318 case EFI_IFR_FORM_SET_OP
:
1320 // Check the formset GUID
1322 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1323 return EFI_INVALID_PARAMETER
;
1326 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1327 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1329 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1331 // The formset OpCode contains ClassGuid
1333 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1334 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1338 case EFI_IFR_FORM_OP
:
1340 // Create a new Form for this FormSet
1342 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1343 ASSERT (CurrentForm
!= NULL
);
1344 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1345 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1346 InitializeListHead (&CurrentForm
->StatementListHead
);
1347 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1349 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1350 CurrentForm
->NvUpdateRequired
= FALSE
;
1351 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1352 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1354 if (InScopeFormSuppress
) {
1356 // Form is inside of suppressif
1358 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1363 // Enter scope of a Form, suppressif will be used for Question or Option
1365 SuppressForQuestion
= TRUE
;
1369 // Insert into Form list of this FormSet
1371 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1374 case EFI_IFR_FORM_MAP_OP
:
1376 // Create a new Form for this FormSet
1378 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1379 ASSERT (CurrentForm
!= NULL
);
1380 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1381 CurrentForm
->NvUpdateRequired
= FALSE
;
1382 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1383 InitializeListHead (&CurrentForm
->StatementListHead
);
1384 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1385 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1387 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1389 // FormMap Form must contain at least one Map Method.
1391 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1392 return EFI_INVALID_PARAMETER
;
1395 // Try to find the standard form map method.
1397 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1398 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1399 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1400 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1406 // If the standard form map method is not found, the first map method title will be used.
1408 if (CurrentForm
->FormTitle
== 0) {
1409 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1410 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1413 if (InScopeFormSuppress
) {
1415 // Form is inside of suppressif
1417 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
1422 // Enter scope of a Form, suppressif will be used for Question or Option
1424 SuppressForQuestion
= TRUE
;
1428 // Insert into Form list of this FormSet
1430 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1436 case EFI_IFR_VARSTORE_OP
:
1438 // Create a buffer Storage for this FormSet
1440 Storage
= CreateStorage (FormSet
);
1441 Storage
->Type
= EFI_HII_VARSTORE_BUFFER
;
1443 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1444 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1445 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
1447 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1448 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1450 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
1451 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1452 ASSERT (Storage
->Name
!= NULL
);
1453 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1454 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1458 // Initialize <ConfigHdr>
1460 InitializeConfigHdr (FormSet
, Storage
);
1463 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1465 // Create a name/value Storage for this FormSet
1467 Storage
= CreateStorage (FormSet
);
1468 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
1470 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1471 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1474 // Initialize <ConfigHdr>
1476 InitializeConfigHdr (FormSet
, Storage
);
1479 case EFI_IFR_VARSTORE_EFI_OP
:
1481 // Create a EFI variable Storage for this FormSet
1483 Storage
= CreateStorage (FormSet
);
1485 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1486 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1487 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
1488 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
1490 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1491 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE
;
1495 Storage
->Type
= EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
;
1496 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
1497 Storage
->EditBuffer
= AllocateZeroPool (Storage
->Size
);
1499 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
1500 Storage
->Name
= AllocateZeroPool (AsciiStrSize (AsciiString
) * 2);
1501 ASSERT (Storage
->Name
!= NULL
);
1502 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
1503 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
1507 // Initialize <ConfigHdr>
1509 InitializeConfigHdr (FormSet
, Storage
);
1515 case EFI_IFR_DEFAULTSTORE_OP
:
1516 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1517 ASSERT (DefaultStore
!= NULL
);
1518 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1520 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1521 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1524 // Insert to DefaultStore list of this Formset
1526 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1532 case EFI_IFR_SUBTITLE_OP
:
1533 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1534 ASSERT (CurrentStatement
!= NULL
);
1536 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1539 mInScopeSubtitle
= TRUE
;
1543 case EFI_IFR_TEXT_OP
:
1544 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1545 ASSERT (CurrentStatement
!= NULL
);
1547 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1550 case EFI_IFR_RESET_BUTTON_OP
:
1551 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1552 ASSERT (CurrentStatement
!= NULL
);
1553 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1559 case EFI_IFR_ACTION_OP
:
1560 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1561 ASSERT (CurrentStatement
!= NULL
);
1562 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1564 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1566 // No QuestionConfig present, so no configuration string will be processed
1568 CurrentStatement
->QuestionConfig
= 0;
1570 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1574 case EFI_IFR_REF_OP
:
1575 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1576 ASSERT (CurrentStatement
!= NULL
);
1577 Value
= &CurrentStatement
->HiiValue
;
1578 Value
->Type
= EFI_IFR_TYPE_REF
;
1579 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1580 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1582 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1583 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1585 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1586 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1588 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1589 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1594 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
1595 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1598 case EFI_IFR_ONE_OF_OP
:
1599 case EFI_IFR_NUMERIC_OP
:
1600 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1601 ASSERT(CurrentStatement
!= NULL
);
1603 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1604 Value
= &CurrentStatement
->HiiValue
;
1606 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1607 case EFI_IFR_NUMERIC_SIZE_1
:
1608 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1609 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1610 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1611 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1612 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1615 case EFI_IFR_NUMERIC_SIZE_2
:
1616 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1617 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1618 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1619 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1620 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1623 case EFI_IFR_NUMERIC_SIZE_4
:
1624 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1625 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1626 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1627 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1628 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1631 case EFI_IFR_NUMERIC_SIZE_8
:
1632 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1633 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1634 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1635 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1636 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1643 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1645 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1646 SuppressForOption
= TRUE
;
1650 case EFI_IFR_ORDERED_LIST_OP
:
1651 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1652 ASSERT(CurrentStatement
!= NULL
);
1654 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1655 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1657 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1658 CurrentStatement
->BufferValue
= NULL
;
1661 SuppressForOption
= TRUE
;
1665 case EFI_IFR_CHECKBOX_OP
:
1666 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1667 ASSERT(CurrentStatement
!= NULL
);
1669 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1670 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1671 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1673 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1677 case EFI_IFR_STRING_OP
:
1678 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1679 ASSERT (CurrentStatement
!= NULL
);
1681 // MinSize is the minimum number of characters that can be accepted for this opcode,
1682 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1683 // The characters are stored as Unicode, so the storage width should multiply 2.
1685 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1686 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1687 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1688 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1690 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1691 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1692 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1694 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1697 case EFI_IFR_PASSWORD_OP
:
1698 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1699 ASSERT (CurrentStatement
!= NULL
);
1701 // MinSize is the minimum number of characters that can be accepted for this opcode,
1702 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1703 // The characters are stored as Unicode, so the storage width should multiply 2.
1705 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1706 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1707 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1709 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1710 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1711 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1713 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1716 case EFI_IFR_DATE_OP
:
1717 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1718 ASSERT(CurrentStatement
!= NULL
);
1720 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1721 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1723 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1724 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1726 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1729 // Don't assign storage for RTC type of date/time
1731 CurrentStatement
->Storage
= NULL
;
1732 CurrentStatement
->StorageWidth
= 0;
1736 case EFI_IFR_TIME_OP
:
1737 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1738 ASSERT(CurrentStatement
!= NULL
);
1740 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1741 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1743 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1744 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1746 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1749 // Don't assign storage for RTC type of date/time
1751 CurrentStatement
->Storage
= NULL
;
1752 CurrentStatement
->StorageWidth
= 0;
1759 case EFI_IFR_DEFAULT_OP
:
1761 // EFI_IFR_DEFAULT appear in scope of a Question,
1762 // It creates a default value for the current question.
1763 // A Question may have more than one Default value which have different default types.
1765 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1766 ASSERT (CurrentDefault
!= NULL
);
1767 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1769 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1770 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1771 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1772 ExtendValueToU64 (&CurrentDefault
->Value
);
1775 // Insert to Default Value list of current Question
1777 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1780 InScopeDefault
= TRUE
;
1787 case EFI_IFR_ONE_OF_OPTION_OP
:
1789 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1790 // It create a selection for use in current Question.
1792 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1793 ASSERT (CurrentOption
!= NULL
);
1794 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1796 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1797 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1798 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1799 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1800 ExtendValueToU64 (&CurrentOption
->Value
);
1802 if (InScopeOptionSuppress
) {
1803 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
1807 // Insert to Option list of current Question
1809 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1812 // Now we know the Storage width of nested Ordered List
1814 ASSERT (CurrentStatement
!= NULL
);
1815 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1817 switch (CurrentOption
->Value
.Type
) {
1818 case EFI_IFR_TYPE_NUM_SIZE_8
:
1822 case EFI_IFR_TYPE_NUM_SIZE_16
:
1826 case EFI_IFR_TYPE_NUM_SIZE_32
:
1830 case EFI_IFR_TYPE_NUM_SIZE_64
:
1836 // Invalid type for Ordered List
1841 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1842 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1843 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1844 if (CurrentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
1845 CurrentStatement
->HiiValue
.Buffer
= CurrentStatement
->BufferValue
;
1846 CurrentStatement
->HiiValue
.BufferLen
= CurrentStatement
->StorageWidth
;
1849 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1856 case EFI_IFR_NO_SUBMIT_IF_OP
:
1857 case EFI_IFR_INCONSISTENT_IF_OP
:
1859 // Create an Expression node
1861 CurrentExpression
= CreateExpression (CurrentForm
);
1862 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1864 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1865 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1866 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1868 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1869 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
1873 // Take a look at next OpCode to see whether current expression consists
1876 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1877 SingleOpCodeExpression
= TRUE
;
1881 case EFI_IFR_SUPPRESS_IF_OP
:
1883 // Question and Option will appear in scope of this OpCode
1885 CurrentExpression
= CreateExpression (CurrentForm
);
1886 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
1888 if (CurrentForm
== NULL
) {
1889 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
1891 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1894 if (SuppressForOption
) {
1895 InScopeOptionSuppress
= TRUE
;
1896 OptionSuppressExpression
= CurrentExpression
;
1897 } else if (SuppressForQuestion
) {
1898 mInScopeSuppress
= TRUE
;
1899 mSuppressExpression
= CurrentExpression
;
1901 InScopeFormSuppress
= TRUE
;
1902 FormSuppressExpression
= CurrentExpression
;
1906 // Take a look at next OpCode to see whether current expression consists
1909 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1910 SingleOpCodeExpression
= TRUE
;
1914 case EFI_IFR_GRAY_OUT_IF_OP
:
1916 // Questions will appear in scope of this OpCode
1918 CurrentExpression
= CreateExpression (CurrentForm
);
1919 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
1920 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1922 mInScopeGrayOut
= TRUE
;
1923 mGrayOutExpression
= CurrentExpression
;
1926 // Take a look at next OpCode to see whether current expression consists
1929 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1930 SingleOpCodeExpression
= TRUE
;
1934 case EFI_IFR_DISABLE_IF_OP
:
1936 // The DisableIf expression should only rely on constant, so it could be
1937 // evaluated at initialization and it will not be queued
1939 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1940 ASSERT (CurrentExpression
!= NULL
);
1941 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1942 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
1943 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
1945 if (CurrentForm
!= NULL
) {
1947 // This is DisableIf for Question, enqueue it to Form expression list
1949 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1952 mDisableExpression
= CurrentExpression
;
1953 mInScopeDisable
= TRUE
;
1954 OpCodeDisabled
= FALSE
;
1957 // Take a look at next OpCode to see whether current expression consists
1960 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1961 SingleOpCodeExpression
= TRUE
;
1968 case EFI_IFR_VALUE_OP
:
1969 CurrentExpression
= CreateExpression (CurrentForm
);
1970 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
1971 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
1973 if (InScopeDefault
) {
1975 // Used for default (EFI_IFR_DEFAULT)
1977 CurrentDefault
->ValueExpression
= CurrentExpression
;
1980 // If used for a question, then the question will be read-only
1983 // Make sure CurrentStatement is not NULL.
1984 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1985 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1987 ASSERT (CurrentStatement
!= NULL
);
1988 CurrentStatement
->ValueExpression
= CurrentExpression
;
1992 // Take a look at next OpCode to see whether current expression consists
1995 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
1996 SingleOpCodeExpression
= TRUE
;
2000 case EFI_IFR_RULE_OP
:
2001 CurrentExpression
= CreateExpression (CurrentForm
);
2002 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2004 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2005 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2008 // Take a look at next OpCode to see whether current expression consists
2011 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2012 SingleOpCodeExpression
= TRUE
;
2016 case EFI_IFR_READ_OP
:
2017 CurrentExpression
= CreateExpression (CurrentForm
);
2018 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2019 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2022 // Make sure CurrentStatement is not NULL.
2023 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2024 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2026 ASSERT (CurrentStatement
!= NULL
);
2027 CurrentStatement
->ReadExpression
= CurrentExpression
;
2030 // Take a look at next OpCode to see whether current expression consists
2033 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2034 SingleOpCodeExpression
= TRUE
;
2038 case EFI_IFR_WRITE_OP
:
2039 CurrentExpression
= CreateExpression (CurrentForm
);
2040 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2041 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2044 // Make sure CurrentStatement is not NULL.
2045 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2046 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2048 ASSERT (CurrentStatement
!= NULL
);
2049 CurrentStatement
->WriteExpression
= CurrentExpression
;
2052 // Take a look at next OpCode to see whether current expression consists
2055 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2056 SingleOpCodeExpression
= TRUE
;
2063 case EFI_IFR_IMAGE_OP
:
2065 // Get ScopeOpcode from top of stack
2067 PopScope (&ScopeOpCode
);
2068 PushScope (ScopeOpCode
);
2070 switch (ScopeOpCode
) {
2071 case EFI_IFR_FORM_SET_OP
:
2072 ImageId
= &FormSet
->ImageId
;
2075 case EFI_IFR_FORM_OP
:
2076 case EFI_IFR_FORM_MAP_OP
:
2077 ASSERT (CurrentForm
!= NULL
);
2078 ImageId
= &CurrentForm
->ImageId
;
2081 case EFI_IFR_ONE_OF_OPTION_OP
:
2082 ImageId
= &CurrentOption
->ImageId
;
2087 // Make sure CurrentStatement is not NULL.
2088 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2089 // file is wrongly generated by tools such as VFR Compiler.
2091 ASSERT (CurrentStatement
!= NULL
);
2092 ImageId
= &CurrentStatement
->ImageId
;
2096 ASSERT (ImageId
!= NULL
);
2097 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2103 case EFI_IFR_REFRESH_OP
:
2104 ASSERT (CurrentStatement
!= NULL
);
2105 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2111 case EFI_IFR_REFRESH_ID_OP
:
2112 ASSERT (CurrentStatement
!= NULL
);
2113 CopyMem (&CurrentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2119 case EFI_IFR_MODAL_TAG_OP
:
2120 ASSERT (CurrentForm
!= NULL
);
2121 CurrentForm
->ModalForm
= TRUE
;
2125 // Lock tag, used by form and statement.
2127 case EFI_IFR_LOCKED_OP
:
2129 // Get ScopeOpcode from top of stack
2131 PopScope (&ScopeOpCode
);
2132 PushScope (ScopeOpCode
);
2133 switch (ScopeOpCode
) {
2134 case EFI_IFR_FORM_OP
:
2135 case EFI_IFR_FORM_MAP_OP
:
2136 ASSERT (CurrentForm
!= NULL
);
2137 CurrentForm
->Locked
= TRUE
;
2141 ASSERT (CurrentStatement
!= NULL
);
2142 CurrentStatement
->Locked
= TRUE
;
2149 case EFI_IFR_GUID_OP
:
2150 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2152 // Tiano specific GUIDed opcodes
2154 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2155 case EFI_IFR_EXTEND_OP_LABEL
:
2157 // just ignore label
2161 case EFI_IFR_EXTEND_OP_BANNER
:
2163 // By SubClass to get Banner Data from Front Page
2165 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2167 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2168 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2169 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2170 sizeof (EFI_STRING_ID
)
2175 case EFI_IFR_EXTEND_OP_CLASS
:
2176 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2179 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2180 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2193 case EFI_IFR_END_OP
:
2194 Status
= PopScope (&ScopeOpCode
);
2195 if (EFI_ERROR (Status
)) {
2200 switch (ScopeOpCode
) {
2201 case EFI_IFR_FORM_SET_OP
:
2203 // End of FormSet, update FormSet IFR binary length
2204 // to stop parsing substantial OpCodes
2206 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2209 case EFI_IFR_FORM_OP
:
2210 case EFI_IFR_FORM_MAP_OP
:
2215 SuppressForQuestion
= FALSE
;
2218 case EFI_IFR_ONE_OF_OPTION_OP
:
2222 CurrentOption
= NULL
;
2225 case EFI_IFR_SUBTITLE_OP
:
2226 mInScopeSubtitle
= FALSE
;
2229 case EFI_IFR_NO_SUBMIT_IF_OP
:
2230 case EFI_IFR_INCONSISTENT_IF_OP
:
2232 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2236 case EFI_IFR_SUPPRESS_IF_OP
:
2237 if (SuppressForOption
) {
2238 InScopeOptionSuppress
= FALSE
;
2239 } else if (SuppressForQuestion
) {
2240 mInScopeSuppress
= FALSE
;
2242 InScopeFormSuppress
= FALSE
;
2246 case EFI_IFR_GRAY_OUT_IF_OP
:
2247 mInScopeGrayOut
= FALSE
;
2250 case EFI_IFR_DISABLE_IF_OP
:
2251 mInScopeDisable
= FALSE
;
2252 OpCodeDisabled
= FALSE
;
2255 case EFI_IFR_ONE_OF_OP
:
2256 case EFI_IFR_ORDERED_LIST_OP
:
2257 SuppressForOption
= FALSE
;
2260 case EFI_IFR_DEFAULT_OP
:
2261 InScopeDefault
= FALSE
;
2264 case EFI_IFR_MAP_OP
:
2266 // Get current Map Expression List.
2268 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2269 if (Status
== EFI_ACCESS_DENIED
) {
2270 MapExpressionList
= NULL
;
2273 // Get current expression.
2275 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2276 ASSERT_EFI_ERROR (Status
);
2277 ASSERT (MapScopeDepth
> 0);
2282 if (IsExpressionOpCode (ScopeOpCode
)) {
2283 if (mInScopeDisable
&& CurrentForm
== NULL
) {
2285 // This is DisableIf expression for Form, it should be a constant expression
2287 ASSERT (CurrentExpression
!= NULL
);
2288 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2289 if (EFI_ERROR (Status
)) {
2293 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2294 return EFI_INVALID_PARAMETER
;
2297 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2299 // DisableIf Expression is only used once and not queued, free it
2301 DestroyExpression (CurrentExpression
);
2305 // End of current Expression
2307 CurrentExpression
= NULL
;