2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 UINTN mStatementIndex
;
12 UINTN mExpressionOpCodeIndex
;
13 EFI_QUESTION_ID mUsedQuestionId
;
14 extern LIST_ENTRY gBrowserStorageList
;
17 Initialize Statement header members.
19 @param OpCodeData Pointer of the raw OpCode data.
20 @param FormSet Pointer of the current FormSet.
21 @param Form Pointer of the current Form.
23 @return The Statement.
26 FORM_BROWSER_STATEMENT
*
29 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
30 IN OUT FORM_BROWSER_FORM
*Form
33 FORM_BROWSER_STATEMENT
*Statement
;
34 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
35 INTN ConditionalExprCount
;
39 // Only guid op may out side the form level.
41 ASSERT (((EFI_IFR_OP_HEADER
*)OpCodeData
)->OpCode
== EFI_IFR_GUID_OP
);
44 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
47 InitializeListHead (&Statement
->DefaultListHead
);
48 InitializeListHead (&Statement
->OptionListHead
);
49 InitializeListHead (&Statement
->InconsistentListHead
);
50 InitializeListHead (&Statement
->NoSubmitListHead
);
51 InitializeListHead (&Statement
->WarningListHead
);
53 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
55 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*)OpCodeData
)->OpCode
;
56 Statement
->OpCode
= (EFI_IFR_OP_HEADER
*)OpCodeData
;
57 Statement
->QuestionReferToBitField
= FALSE
;
59 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
60 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
61 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
63 ConditionalExprCount
= GetConditionalExpressionCount (ExpressStatement
);
64 if (ConditionalExprCount
> 0) {
66 // Form is inside of suppressif
69 Statement
->Expression
= (FORM_EXPRESSION_LIST
*)AllocatePool (
70 (UINTN
)(sizeof (FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof (FORM_EXPRESSION
*)))
72 ASSERT (Statement
->Expression
!= NULL
);
73 Statement
->Expression
->Count
= (UINTN
)ConditionalExprCount
;
74 Statement
->Expression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
75 CopyMem (Statement
->Expression
->Expression
, GetConditionalExpressionList (ExpressStatement
), (UINTN
)(sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
79 // Insert this Statement into current Form
82 InsertTailList (&FormSet
->StatementListOSF
, &Statement
->Link
);
84 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
91 Initialize Question's members.
93 @param OpCodeData Pointer of the raw OpCode data.
94 @param FormSet Pointer of the current FormSet.
95 @param Form Pointer of the current Form.
100 FORM_BROWSER_STATEMENT
*
102 IN UINT8
*OpCodeData
,
103 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
104 IN OUT FORM_BROWSER_FORM
*Form
107 FORM_BROWSER_STATEMENT
*Statement
;
108 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
110 FORMSET_STORAGE
*Storage
;
111 NAME_VALUE_NODE
*NameValueNode
;
114 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
115 if (Statement
== NULL
) {
119 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
120 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
121 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
122 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
124 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
126 if (Statement
->VarStoreId
== 0) {
128 // VarStoreId of zero indicates no variable storage
134 // Find Storage for this Question
136 Link
= GetFirstNode (&FormSet
->StorageListHead
);
137 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
138 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
140 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
141 Statement
->Storage
= Storage
->BrowserStorage
;
145 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
148 ASSERT (Statement
->Storage
!= NULL
);
151 // Initialilze varname for Name/Value or EFI Variable
153 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
154 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
))
156 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
157 ASSERT (Statement
->VariableName
!= NULL
);
159 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
161 // Check whether old string node already exist.
164 if (!IsListEmpty (&Statement
->Storage
->NameValueListHead
)) {
165 Link
= GetFirstNode (&Statement
->Storage
->NameValueListHead
);
166 while (!IsNull (&Statement
->Storage
->NameValueListHead
, Link
)) {
167 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
169 if (StrCmp (Statement
->VariableName
, NameValueNode
->Name
) == 0) {
174 Link
= GetNextNode (&Statement
->Storage
->NameValueListHead
, Link
);
180 // Insert to Name/Value varstore list
182 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
183 ASSERT (NameValueNode
!= NULL
);
184 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
185 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
186 ASSERT (NameValueNode
->Name
!= NULL
);
187 NameValueNode
->Value
= AllocateZeroPool (0x10);
188 ASSERT (NameValueNode
->Value
!= NULL
);
189 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
190 ASSERT (NameValueNode
->EditValue
!= NULL
);
192 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
201 Allocate a FORM_EXPRESSION node.
203 @param Form The Form associated with this Expression
204 @param OpCode The binary opcode data.
206 @return Pointer to a FORM_EXPRESSION data structure.
211 IN OUT FORM_BROWSER_FORM
*Form
,
215 FORM_EXPRESSION
*Expression
;
217 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
218 ASSERT (Expression
!= NULL
);
219 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
220 InitializeListHead (&Expression
->OpCodeListHead
);
221 Expression
->OpCode
= (EFI_IFR_OP_HEADER
*)OpCode
;
227 Create ConfigHdr string for a storage.
229 @param FormSet Pointer of the current FormSet
230 @param Storage Pointer of the storage
232 @retval EFI_SUCCESS Initialize ConfigHdr success
236 InitializeConfigHdr (
237 IN FORM_BROWSER_FORMSET
*FormSet
,
238 IN OUT FORMSET_STORAGE
*Storage
243 if ((Storage
->BrowserStorage
->Type
== EFI_HII_VARSTORE_BUFFER
) ||
244 (Storage
->BrowserStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
))
246 Name
= Storage
->BrowserStorage
->Name
;
251 Storage
->ConfigHdr
= HiiConstructConfigHdr (
252 &Storage
->BrowserStorage
->Guid
,
254 FormSet
->DriverHandle
257 if (Storage
->ConfigHdr
== NULL
) {
258 return EFI_NOT_FOUND
;
265 Find the global storage link base on the input storate type, name and guid.
267 For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
268 same guid + name = same storage
270 For EFI_HII_VARSTORE_NAME_VALUE:
271 same guid + HiiHandle = same storage
273 For EFI_HII_VARSTORE_BUFFER:
274 same guid + name + HiiHandle = same storage
276 @param StorageType Storage type.
277 @param StorageGuid Storage guid.
278 @param StorageName Storage Name.
279 @param HiiHandle HiiHandle for this varstore.
281 @return Pointer to a GLOBAL_STORAGE data structure.
286 IN UINT8 StorageType
,
287 IN EFI_GUID
*StorageGuid
,
288 IN CHAR16
*StorageName
,
289 IN EFI_HII_HANDLE HiiHandle
293 BROWSER_STORAGE
*BrowserStorage
;
295 Link
= GetFirstNode (&gBrowserStorageList
);
296 while (!IsNull (&gBrowserStorageList
, Link
)) {
297 BrowserStorage
= BROWSER_STORAGE_FROM_LINK (Link
);
298 Link
= GetNextNode (&gBrowserStorageList
, Link
);
300 if ((BrowserStorage
->Type
== StorageType
) && CompareGuid (&BrowserStorage
->Guid
, StorageGuid
)) {
301 if (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
) {
302 if (BrowserStorage
->HiiHandle
== HiiHandle
) {
303 return BrowserStorage
;
309 ASSERT (StorageName
!= NULL
);
310 if (StrCmp (BrowserStorage
->Name
, StorageName
) == 0) {
311 if ((StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE
) || (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
)) {
312 return BrowserStorage
;
313 } else if ((StorageType
== EFI_HII_VARSTORE_BUFFER
) && (BrowserStorage
->HiiHandle
== HiiHandle
)) {
314 return BrowserStorage
;
324 Intialize the Global Storage.
326 @param BrowserStorage Pointer to the global storage.
327 @param StorageType Storage type.
328 @param OpCodeData Binary data for this opcode.
332 IntializeBrowserStorage (
333 IN BROWSER_STORAGE
*BrowserStorage
,
334 IN UINT8 StorageType
,
338 switch (StorageType
) {
339 case EFI_HII_VARSTORE_BUFFER
:
340 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE
*)OpCodeData
)->Guid
, sizeof (EFI_GUID
));
341 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE
*)OpCodeData
)->Size
, sizeof (UINT16
));
343 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
344 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
347 case EFI_HII_VARSTORE_EFI_VARIABLE
:
348 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
349 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*)OpCodeData
)->Guid
, sizeof (EFI_GUID
));
350 CopyMem (&BrowserStorage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*)OpCodeData
)->Attributes
, sizeof (UINT32
));
351 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE_EFI
*)OpCodeData
)->Size
, sizeof (UINT16
));
353 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
354 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
355 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
360 case EFI_HII_VARSTORE_NAME_VALUE
:
361 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*)OpCodeData
)->Guid
, sizeof (EFI_GUID
));
363 InitializeListHead (&BrowserStorage
->NameValueListHead
);
372 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
374 @param FormSet Pointer of the current FormSet
375 @param StorageType Storage type.
376 @param OpCodeData Binary data for this opcode.
378 @return Pointer to a FORMSET_STORAGE data structure.
383 IN FORM_BROWSER_FORMSET
*FormSet
,
384 IN UINT8 StorageType
,
388 FORMSET_STORAGE
*Storage
;
389 CHAR16
*UnicodeString
;
391 BROWSER_STORAGE
*BrowserStorage
;
392 EFI_GUID
*StorageGuid
;
395 UnicodeString
= NULL
;
397 switch (StorageType
) {
398 case EFI_HII_VARSTORE_BUFFER
:
399 StorageGuid
= (EFI_GUID
*)(CHAR8
*)&((EFI_IFR_VARSTORE
*)OpCodeData
)->Guid
;
400 StorageName
= (CHAR8
*)((EFI_IFR_VARSTORE
*)OpCodeData
)->Name
;
403 case EFI_HII_VARSTORE_EFI_VARIABLE
:
404 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
405 StorageGuid
= (EFI_GUID
*)(CHAR8
*)&((EFI_IFR_VARSTORE_EFI
*)OpCodeData
)->Guid
;
406 StorageName
= (CHAR8
*)((EFI_IFR_VARSTORE_EFI
*)OpCodeData
)->Name
;
410 ASSERT (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
);
411 StorageGuid
= &((EFI_IFR_VARSTORE_NAME_VALUE
*)OpCodeData
)->Guid
;
415 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
416 ASSERT (StorageName
!= NULL
);
418 UnicodeString
= AllocateZeroPool (AsciiStrSize (StorageName
) * 2);
419 ASSERT (UnicodeString
!= NULL
);
420 for (Index
= 0; StorageName
[Index
] != 0; Index
++) {
421 UnicodeString
[Index
] = (CHAR16
)StorageName
[Index
];
425 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
426 ASSERT (Storage
!= NULL
);
427 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
428 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
430 BrowserStorage
= FindStorageInList (StorageType
, StorageGuid
, UnicodeString
, FormSet
->HiiHandle
);
431 if (BrowserStorage
== NULL
) {
432 BrowserStorage
= AllocateZeroPool (sizeof (BROWSER_STORAGE
));
433 ASSERT (BrowserStorage
!= NULL
);
435 BrowserStorage
->Signature
= BROWSER_STORAGE_SIGNATURE
;
436 InsertTailList (&gBrowserStorageList
, &BrowserStorage
->Link
);
438 IntializeBrowserStorage (BrowserStorage
, StorageType
, OpCodeData
);
439 BrowserStorage
->Type
= StorageType
;
440 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
441 BrowserStorage
->Name
= UnicodeString
;
444 BrowserStorage
->HiiHandle
= FormSet
->HiiHandle
;
446 BrowserStorage
->Initialized
= FALSE
;
449 Storage
->BrowserStorage
= BrowserStorage
;
450 InitializeConfigHdr (FormSet
, Storage
);
451 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
452 Storage
->SpareStrLen
= 0;
458 Get Formset_storage base on the input varstoreid info.
460 @param FormSet Pointer of the current FormSet.
461 @param VarStoreId Varstore ID info.
463 @return Pointer to a FORMSET_STORAGE data structure.
468 IN FORM_BROWSER_FORMSET
*FormSet
,
469 IN EFI_VARSTORE_ID VarStoreId
472 FORMSET_STORAGE
*FormsetStorage
;
477 FormsetStorage
= NULL
;
479 // Find Formset Storage for this Question
481 Link
= GetFirstNode (&FormSet
->StorageListHead
);
482 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
483 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
485 if (FormsetStorage
->VarStoreId
== VarStoreId
) {
490 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
493 return Found
? FormsetStorage
: NULL
;
497 Get Formset_storage base on the input browser storage.
499 More than one formsets may share the same browser storage,
500 this function just get the first formset storage which
501 share the browser storage.
503 @param Storage browser storage info.
505 @return Pointer to a FORMSET_STORAGE data structure.
510 GetFstStgFromBrsStg (
511 IN BROWSER_STORAGE
*Storage
514 FORMSET_STORAGE
*FormsetStorage
;
516 LIST_ENTRY
*FormsetLink
;
517 FORM_BROWSER_FORMSET
*FormSet
;
521 FormsetStorage
= NULL
;
523 FormsetLink
= GetFirstNode (&gBrowserFormSetList
);
524 while (!IsNull (&gBrowserFormSetList
, FormsetLink
)) {
525 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink
);
526 FormsetLink
= GetNextNode (&gBrowserFormSetList
, FormsetLink
);
528 Link
= GetFirstNode (&FormSet
->StorageListHead
);
529 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
530 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
531 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
533 if (FormsetStorage
->BrowserStorage
== Storage
) {
544 return Found
? FormsetStorage
: NULL
;
548 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
550 @param FormSet Pointer of the current FormSet.
551 @param Question The Question to be initialized.
552 @param Form Pointer of the current form.
554 @retval EFI_SUCCESS Function success.
555 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
559 InitializeRequestElement (
560 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
561 IN OUT FORM_BROWSER_STATEMENT
*Question
,
562 IN OUT FORM_BROWSER_FORM
*Form
565 BROWSER_STORAGE
*Storage
;
566 FORMSET_STORAGE
*FormsetStorage
;
570 CHAR16 RequestElement
[30];
573 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
576 Storage
= Question
->Storage
;
577 if (Storage
== NULL
) {
578 return EFI_INVALID_PARAMETER
;
581 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
583 // <ConfigRequest> is unnecessary for EFI variable storage,
584 // GetVariable()/SetVariable() will be used to retrieve/save values
590 // Prepare <RequestElement>
592 if ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ||
593 (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
))
595 StrLen
= UnicodeSPrint (
597 30 * sizeof (CHAR16
),
598 L
"&OFFSET=%04x&WIDTH=%04x",
599 Question
->VarStoreInfo
.VarOffset
,
600 Question
->StorageWidth
602 HiiToLower (RequestElement
);
603 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
605 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
608 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
610 // Password with CALLBACK flag is stored in encoded format,
611 // so don't need to append it to <ConfigRequest>
617 // Find Formset Storage for this Question
619 FormsetStorage
= GetFstStgFromVarId (FormSet
, Question
->VarStoreId
);
620 ASSERT (FormsetStorage
!= NULL
);
621 StringSize
= (FormsetStorage
->ConfigRequest
!= NULL
) ? StrSize (FormsetStorage
->ConfigRequest
) : sizeof (CHAR16
);
622 MaxLen
= StringSize
/ sizeof (CHAR16
) + FormsetStorage
->SpareStrLen
;
625 // Append <RequestElement> to <ConfigRequest>
627 if (StrLen
> FormsetStorage
->SpareStrLen
) {
629 // Old String buffer is not sufficient for RequestElement, allocate a new one
631 MaxLen
= StringSize
/ sizeof (CHAR16
) + CONFIG_REQUEST_STRING_INCREMENTAL
;
632 NewStr
= AllocateZeroPool (MaxLen
* sizeof (CHAR16
));
633 ASSERT (NewStr
!= NULL
);
634 if (FormsetStorage
->ConfigRequest
!= NULL
) {
635 CopyMem (NewStr
, FormsetStorage
->ConfigRequest
, StringSize
);
636 FreePool (FormsetStorage
->ConfigRequest
);
639 FormsetStorage
->ConfigRequest
= NewStr
;
640 FormsetStorage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
643 StrCatS (FormsetStorage
->ConfigRequest
, MaxLen
, RequestElement
);
644 FormsetStorage
->ElementCount
++;
645 FormsetStorage
->SpareStrLen
-= StrLen
;
648 // Update the Config Request info saved in the form.
652 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
653 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
654 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
656 if ((ConfigInfo
!= NULL
) && (ConfigInfo
->Storage
== FormsetStorage
->BrowserStorage
)) {
661 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
665 ConfigInfo
= AllocateZeroPool (sizeof (FORM_BROWSER_CONFIG_REQUEST
));
666 ASSERT (ConfigInfo
!= NULL
);
667 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
668 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (FormsetStorage
->ConfigHdr
), FormsetStorage
->ConfigHdr
);
669 ASSERT (ConfigInfo
->ConfigRequest
!= NULL
);
670 ConfigInfo
->SpareStrLen
= 0;
671 ConfigInfo
->Storage
= FormsetStorage
->BrowserStorage
;
672 InsertTailList (&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
675 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
676 MaxLen
= StringSize
/ sizeof (CHAR16
) + ConfigInfo
->SpareStrLen
;
679 // Append <RequestElement> to <ConfigRequest>
681 if (StrLen
> ConfigInfo
->SpareStrLen
) {
683 // Old String buffer is not sufficient for RequestElement, allocate a new one
685 MaxLen
= StringSize
/ sizeof (CHAR16
) + CONFIG_REQUEST_STRING_INCREMENTAL
;
686 NewStr
= AllocateZeroPool (MaxLen
* sizeof (CHAR16
));
687 ASSERT (NewStr
!= NULL
);
688 if (ConfigInfo
->ConfigRequest
!= NULL
) {
689 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
690 FreePool (ConfigInfo
->ConfigRequest
);
693 ConfigInfo
->ConfigRequest
= NewStr
;
694 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
697 StrCatS (ConfigInfo
->ConfigRequest
, MaxLen
, RequestElement
);
698 ConfigInfo
->ElementCount
++;
699 ConfigInfo
->SpareStrLen
-= StrLen
;
704 Free resources of a Expression.
706 @param FormSet Pointer of the Expression
711 IN FORM_EXPRESSION
*Expression
715 EXPRESSION_OPCODE
*OpCode
;
716 LIST_ENTRY
*SubExpressionLink
;
717 FORM_EXPRESSION
*SubExpression
;
719 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
720 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
721 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
722 RemoveEntryList (&OpCode
->Link
);
724 if (OpCode
->ValueList
!= NULL
) {
725 FreePool (OpCode
->ValueList
);
728 if (OpCode
->ValueName
!= NULL
) {
729 FreePool (OpCode
->ValueName
);
732 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
733 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
734 SubExpressionLink
= GetFirstNode (&OpCode
->MapExpressionList
);
735 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
736 RemoveEntryList (&SubExpression
->Link
);
737 DestroyExpression (SubExpression
);
743 // Free this Expression
745 FreePool (Expression
);
749 Free resources of a storage.
751 @param Storage Pointer of the storage
756 IN FORMSET_STORAGE
*Storage
759 if (Storage
== NULL
) {
763 if (Storage
->ConfigRequest
!= NULL
) {
764 FreePool (Storage
->ConfigRequest
);
771 Free resources of a Statement.
773 @param FormSet Pointer of the FormSet
774 @param Statement Pointer of the Statement
779 IN FORM_BROWSER_FORMSET
*FormSet
,
780 IN OUT FORM_BROWSER_STATEMENT
*Statement
784 QUESTION_DEFAULT
*Default
;
785 QUESTION_OPTION
*Option
;
786 FORM_EXPRESSION
*Expression
;
789 // Free Default value List
791 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
792 Link
= GetFirstNode (&Statement
->DefaultListHead
);
793 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
794 RemoveEntryList (&Default
->Link
);
796 if (Default
->Value
.Buffer
!= NULL
) {
797 FreePool (Default
->Value
.Buffer
);
806 while (!IsListEmpty (&Statement
->OptionListHead
)) {
807 Link
= GetFirstNode (&Statement
->OptionListHead
);
808 Option
= QUESTION_OPTION_FROM_LINK (Link
);
809 if (Option
->SuppressExpression
!= NULL
) {
810 FreePool (Option
->SuppressExpression
);
813 RemoveEntryList (&Option
->Link
);
819 // Free Inconsistent List
821 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
822 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
823 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
824 RemoveEntryList (&Expression
->Link
);
826 DestroyExpression (Expression
);
830 // Free NoSubmit List
832 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
833 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
834 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
835 RemoveEntryList (&Expression
->Link
);
837 DestroyExpression (Expression
);
841 // Free WarningIf List
843 while (!IsListEmpty (&Statement
->WarningListHead
)) {
844 Link
= GetFirstNode (&Statement
->WarningListHead
);
845 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
846 RemoveEntryList (&Expression
->Link
);
848 DestroyExpression (Expression
);
851 if (Statement
->Expression
!= NULL
) {
852 FreePool (Statement
->Expression
);
855 if (Statement
->VariableName
!= NULL
) {
856 FreePool (Statement
->VariableName
);
859 if (Statement
->BlockName
!= NULL
) {
860 FreePool (Statement
->BlockName
);
863 if (Statement
->BufferValue
!= NULL
) {
864 FreePool (Statement
->BufferValue
);
867 if ((Statement
->Operand
== EFI_IFR_STRING_OP
) || (Statement
->Operand
== EFI_IFR_PASSWORD_OP
)) {
868 DeleteString (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
873 Free resources of a Form.
875 @param FormSet Pointer of the FormSet
876 @param Form Pointer of the Form.
881 IN FORM_BROWSER_FORMSET
*FormSet
,
882 IN OUT FORM_BROWSER_FORM
*Form
886 FORM_EXPRESSION
*Expression
;
887 FORM_BROWSER_STATEMENT
*Statement
;
888 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
891 // Free Form Expressions
893 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
894 Link
= GetFirstNode (&Form
->ExpressionListHead
);
895 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
896 RemoveEntryList (&Expression
->Link
);
898 DestroyExpression (Expression
);
902 // Free Statements/Questions
904 while (!IsListEmpty (&Form
->StatementListHead
)) {
905 Link
= GetFirstNode (&Form
->StatementListHead
);
906 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
907 RemoveEntryList (&Statement
->Link
);
909 DestroyStatement (FormSet
, Statement
);
913 // Free ConfigRequest string.
915 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
916 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
917 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
918 RemoveEntryList (&ConfigInfo
->Link
);
920 FreePool (ConfigInfo
->ConfigRequest
);
921 FreePool (ConfigInfo
);
924 if (Form
->SuppressExpression
!= NULL
) {
925 FreePool (Form
->SuppressExpression
);
928 UiFreeMenuList (&Form
->FormViewListHead
);
937 Free resources allocated for a FormSet.
939 @param FormSet Pointer of the FormSet
944 IN OUT FORM_BROWSER_FORMSET
*FormSet
948 FORMSET_STORAGE
*Storage
;
949 FORMSET_DEFAULTSTORE
*DefaultStore
;
950 FORM_EXPRESSION
*Expression
;
951 FORM_BROWSER_FORM
*Form
;
953 if (FormSet
->IfrBinaryData
== NULL
) {
955 // Uninitialized FormSet
962 // Free IFR binary buffer
964 FreePool (FormSet
->IfrBinaryData
);
967 // Free FormSet Storage
969 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
970 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
971 Link
= GetFirstNode (&FormSet
->StorageListHead
);
972 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
973 RemoveEntryList (&Storage
->Link
);
975 DestroyStorage (Storage
);
980 // Free FormSet Default Store
982 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
983 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
984 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
985 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
986 RemoveEntryList (&DefaultStore
->Link
);
988 FreePool (DefaultStore
);
993 // Free Formset Expressions
995 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
996 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
997 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
998 RemoveEntryList (&Expression
->Link
);
1000 DestroyExpression (Expression
);
1006 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
1007 while (!IsListEmpty (&FormSet
->FormListHead
)) {
1008 Link
= GetFirstNode (&FormSet
->FormListHead
);
1009 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1010 RemoveEntryList (&Form
->Link
);
1012 DestroyForm (FormSet
, Form
);
1016 if (FormSet
->StatementBuffer
!= NULL
) {
1017 FreePool (FormSet
->StatementBuffer
);
1020 if (FormSet
->ExpressionBuffer
!= NULL
) {
1021 FreePool (FormSet
->ExpressionBuffer
);
1028 Tell whether this Operand is an Expression OpCode or not
1030 @param Operand Operand of an IFR OpCode.
1032 @retval TRUE This is an Expression OpCode.
1033 @retval FALSE Not an Expression OpCode.
1037 IsExpressionOpCode (
1041 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
1042 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
1043 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
1044 (Operand
== EFI_IFR_CATENATE_OP
) ||
1045 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
1046 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
1047 (Operand
== EFI_IFR_MAP_OP
) ||
1048 (Operand
== EFI_IFR_VERSION_OP
) ||
1049 (Operand
== EFI_IFR_SECURITY_OP
) ||
1050 (Operand
== EFI_IFR_MATCH2_OP
))
1059 Tell whether this Operand is an Statement OpCode.
1061 @param Operand Operand of an IFR OpCode.
1063 @retval TRUE This is an Statement OpCode.
1064 @retval FALSE Not an Statement OpCode.
1072 if ((Operand
== EFI_IFR_SUBTITLE_OP
) ||
1073 (Operand
== EFI_IFR_TEXT_OP
) ||
1074 (Operand
== EFI_IFR_RESET_BUTTON_OP
) ||
1075 (Operand
== EFI_IFR_REF_OP
) ||
1076 (Operand
== EFI_IFR_ACTION_OP
) ||
1077 (Operand
== EFI_IFR_NUMERIC_OP
) ||
1078 (Operand
== EFI_IFR_ORDERED_LIST_OP
) ||
1079 (Operand
== EFI_IFR_CHECKBOX_OP
) ||
1080 (Operand
== EFI_IFR_STRING_OP
) ||
1081 (Operand
== EFI_IFR_PASSWORD_OP
) ||
1082 (Operand
== EFI_IFR_DATE_OP
) ||
1083 (Operand
== EFI_IFR_TIME_OP
) ||
1084 (Operand
== EFI_IFR_GUID_OP
) ||
1085 (Operand
== EFI_IFR_ONE_OF_OP
))
1094 Tell whether this Operand is an known OpCode.
1096 @param Operand Operand of an IFR OpCode.
1098 @retval TRUE This is an Statement OpCode.
1099 @retval FALSE Not an Statement OpCode.
1107 return Operand
> EFI_IFR_MATCH2_OP
? TRUE
: FALSE
;
1111 Calculate number of Statemens(Questions) and Expression OpCodes.
1113 @param FormSet The FormSet to be counted.
1114 @param NumberOfStatement Number of Statemens(Questions)
1115 @param NumberOfExpression Number of Expression OpCodes
1120 IN FORM_BROWSER_FORMSET
*FormSet
,
1121 OUT UINTN
*NumberOfStatement
,
1122 OUT UINTN
*NumberOfExpression
1125 UINTN StatementCount
;
1126 UINTN ExpressionCount
;
1133 ExpressionCount
= 0;
1135 while (Offset
< FormSet
->IfrBinaryLength
) {
1136 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
1137 OpCodeLen
= ((EFI_IFR_OP_HEADER
*)OpCodeData
)->Length
;
1138 Offset
+= OpCodeLen
;
1140 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*)OpCodeData
)->OpCode
)) {
1147 *NumberOfStatement
= StatementCount
;
1148 *NumberOfExpression
= ExpressionCount
;
1152 Parse opcodes in the formset IFR binary.
1154 @param FormSet Pointer of the FormSet data structure.
1156 @retval EFI_SUCCESS Opcode parse success.
1157 @retval Other Opcode parse fail.
1162 IN FORM_BROWSER_FORMSET
*FormSet
1166 FORM_BROWSER_FORM
*CurrentForm
;
1167 FORM_BROWSER_STATEMENT
*CurrentStatement
;
1168 FORM_BROWSER_STATEMENT
*ParentStatement
;
1169 EXPRESSION_OPCODE
*ExpressionOpCode
;
1170 FORM_EXPRESSION
*CurrentExpression
;
1177 FORMSET_STORAGE
*Storage
;
1178 FORMSET_DEFAULTSTORE
*DefaultStore
;
1179 QUESTION_DEFAULT
*CurrentDefault
;
1180 QUESTION_OPTION
*CurrentOption
;
1182 UINTN NumberOfStatement
;
1183 UINTN NumberOfExpression
;
1184 EFI_IMAGE_ID
*ImageId
;
1185 BOOLEAN SuppressForQuestion
;
1186 BOOLEAN SuppressForOption
;
1187 UINT16 DepthOfDisable
;
1188 BOOLEAN OpCodeDisabled
;
1189 BOOLEAN SingleOpCodeExpression
;
1190 BOOLEAN InScopeDefault
;
1191 EFI_HII_VALUE
*Value
;
1192 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
1193 UINT8 MapScopeDepth
;
1195 FORMSET_STORAGE
*VarStorage
;
1196 LIST_ENTRY
*MapExpressionList
;
1197 EFI_VARSTORE_ID TempVarstoreId
;
1198 BOOLEAN InScopeDisable
;
1199 INTN ConditionalExprCount
;
1200 BOOLEAN InUnknownScope
;
1202 FORMSET_DEFAULTSTORE
*PreDefaultStore
;
1203 LIST_ENTRY
*DefaultLink
;
1204 BOOLEAN HaveInserted
;
1206 BOOLEAN QuestionReferBitField
;
1208 SuppressForQuestion
= FALSE
;
1209 SuppressForOption
= FALSE
;
1210 InScopeDisable
= FALSE
;
1212 OpCodeDisabled
= FALSE
;
1213 SingleOpCodeExpression
= FALSE
;
1214 InScopeDefault
= FALSE
;
1215 CurrentExpression
= NULL
;
1216 CurrentDefault
= NULL
;
1217 CurrentOption
= NULL
;
1223 MapExpressionList
= NULL
;
1225 ConditionalExprCount
= 0;
1226 InUnknownScope
= FALSE
;
1228 QuestionReferBitField
= FALSE
;
1231 // Get the number of Statements and Expressions
1233 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
1235 mStatementIndex
= 0;
1236 mUsedQuestionId
= 1;
1237 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
1238 if (FormSet
->StatementBuffer
== NULL
) {
1239 return EFI_OUT_OF_RESOURCES
;
1242 mExpressionOpCodeIndex
= 0;
1243 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
1244 if (FormSet
->ExpressionBuffer
== NULL
) {
1245 return EFI_OUT_OF_RESOURCES
;
1248 InitializeListHead (&FormSet
->StatementListOSF
);
1249 InitializeListHead (&FormSet
->StorageListHead
);
1250 InitializeListHead (&FormSet
->SaveFailStorageListHead
);
1251 InitializeListHead (&FormSet
->DefaultStoreListHead
);
1252 InitializeListHead (&FormSet
->FormListHead
);
1253 InitializeListHead (&FormSet
->ExpressionListHead
);
1254 ResetCurrentExpressionStack ();
1255 ResetMapExpressionListStack ();
1258 CurrentStatement
= NULL
;
1259 ParentStatement
= NULL
;
1264 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1265 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1267 OpCodeLength
= ((EFI_IFR_OP_HEADER
*)OpCodeData
)->Length
;
1268 OpCodeOffset
+= OpCodeLength
;
1269 Operand
= ((EFI_IFR_OP_HEADER
*)OpCodeData
)->OpCode
;
1270 Scope
= ((EFI_IFR_OP_HEADER
*)OpCodeData
)->Scope
;
1272 if (InUnknownScope
) {
1273 if (Operand
== EFI_IFR_END_OP
) {
1276 if (UnknownDepth
== 0) {
1277 InUnknownScope
= FALSE
;
1288 if (IsUnKnownOpCode (Operand
)) {
1290 InUnknownScope
= TRUE
;
1298 // If scope bit set, push onto scope stack
1301 PushScope (Operand
);
1304 if (OpCodeDisabled
) {
1306 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1307 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1309 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1311 } else if (Operand
== EFI_IFR_END_OP
) {
1312 Status
= PopScope (&ScopeOpCode
);
1313 if (EFI_ERROR (Status
)) {
1317 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1318 if (DepthOfDisable
== 0) {
1319 InScopeDisable
= FALSE
;
1320 OpCodeDisabled
= FALSE
;
1330 if (IsExpressionOpCode (Operand
)) {
1331 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1332 mExpressionOpCodeIndex
++;
1334 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1335 ExpressionOpCode
->Operand
= Operand
;
1336 Value
= &ExpressionOpCode
->Value
;
1339 case EFI_IFR_EQ_ID_VAL_OP
:
1340 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*)OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1342 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1343 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*)OpCodeData
)->Value
, sizeof (UINT16
));
1346 case EFI_IFR_EQ_ID_ID_OP
:
1347 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*)OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1348 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*)OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1351 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1352 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*)OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1353 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*)OpCodeData
)->ListLength
, sizeof (UINT16
));
1354 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*)OpCodeData
)->ValueList
);
1357 case EFI_IFR_TO_STRING_OP
:
1358 case EFI_IFR_FIND_OP
:
1359 ExpressionOpCode
->Format
= ((EFI_IFR_TO_STRING
*)OpCodeData
)->Format
;
1362 case EFI_IFR_STRING_REF1_OP
:
1363 Value
->Type
= EFI_IFR_TYPE_STRING
;
1364 CopyMem (&Value
->Value
.string
, &((EFI_IFR_STRING_REF1
*)OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1367 case EFI_IFR_RULE_REF_OP
:
1368 ExpressionOpCode
->RuleId
= ((EFI_IFR_RULE_REF
*)OpCodeData
)->RuleId
;
1371 case EFI_IFR_SPAN_OP
:
1372 ExpressionOpCode
->Flags
= ((EFI_IFR_SPAN
*)OpCodeData
)->Flags
;
1375 case EFI_IFR_THIS_OP
:
1376 ASSERT (ParentStatement
!= NULL
);
1377 ExpressionOpCode
->QuestionId
= ParentStatement
->QuestionId
;
1380 case EFI_IFR_SECURITY_OP
:
1381 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*)OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1384 case EFI_IFR_MATCH2_OP
:
1385 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_MATCH2
*)OpCodeData
)->SyntaxType
, sizeof (EFI_GUID
));
1388 case EFI_IFR_GET_OP
:
1389 case EFI_IFR_SET_OP
:
1390 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*)OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1391 if (TempVarstoreId
!= 0) {
1392 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1393 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1394 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1395 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1396 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*)OpCodeData
)->VarStoreId
) {
1397 ExpressionOpCode
->VarStorage
= VarStorage
->BrowserStorage
;
1401 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1405 if (ExpressionOpCode
->VarStorage
== NULL
) {
1407 // VarStorage is not found.
1409 return EFI_INVALID_PARAMETER
;
1413 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*)OpCodeData
)->VarStoreType
;
1414 switch (ExpressionOpCode
->ValueType
) {
1415 case EFI_IFR_TYPE_BOOLEAN
:
1416 case EFI_IFR_TYPE_NUM_SIZE_8
:
1417 ExpressionOpCode
->ValueWidth
= 1;
1420 case EFI_IFR_TYPE_NUM_SIZE_16
:
1421 case EFI_IFR_TYPE_STRING
:
1422 ExpressionOpCode
->ValueWidth
= 2;
1425 case EFI_IFR_TYPE_NUM_SIZE_32
:
1426 ExpressionOpCode
->ValueWidth
= 4;
1429 case EFI_IFR_TYPE_NUM_SIZE_64
:
1430 ExpressionOpCode
->ValueWidth
= 8;
1433 case EFI_IFR_TYPE_DATE
:
1434 ExpressionOpCode
->ValueWidth
= (UINT8
)sizeof (EFI_IFR_DATE
);
1437 case EFI_IFR_TYPE_TIME
:
1438 ExpressionOpCode
->ValueWidth
= (UINT8
)sizeof (EFI_IFR_TIME
);
1441 case EFI_IFR_TYPE_REF
:
1442 ExpressionOpCode
->ValueWidth
= (UINT8
)sizeof (EFI_IFR_REF
);
1445 case EFI_IFR_TYPE_OTHER
:
1446 case EFI_IFR_TYPE_UNDEFINED
:
1447 case EFI_IFR_TYPE_ACTION
:
1448 case EFI_IFR_TYPE_BUFFER
:
1451 // Invalid value type for Get/Set opcode.
1453 return EFI_INVALID_PARAMETER
;
1456 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*)OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1457 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*)OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1458 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1459 ((ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
1460 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)))
1462 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1463 if (ExpressionOpCode
->ValueName
== NULL
) {
1465 // String ID is invalid.
1467 return EFI_INVALID_PARAMETER
;
1473 case EFI_IFR_QUESTION_REF1_OP
:
1474 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*)OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1477 case EFI_IFR_QUESTION_REF3_OP
:
1478 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1479 CopyMem (&ExpressionOpCode
->DevicePath
, &((EFI_IFR_QUESTION_REF3_2
*)OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1481 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1482 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_QUESTION_REF3_3
*)OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1491 case EFI_IFR_TRUE_OP
:
1492 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1493 Value
->Value
.b
= TRUE
;
1496 case EFI_IFR_FALSE_OP
:
1497 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1498 Value
->Value
.b
= FALSE
;
1501 case EFI_IFR_ONE_OP
:
1502 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1503 Value
->Value
.u8
= 1;
1506 case EFI_IFR_ZERO_OP
:
1507 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1508 Value
->Value
.u8
= 0;
1511 case EFI_IFR_ONES_OP
:
1512 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1513 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1516 case EFI_IFR_UINT8_OP
:
1517 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1518 Value
->Value
.u8
= ((EFI_IFR_UINT8
*)OpCodeData
)->Value
;
1521 case EFI_IFR_UINT16_OP
:
1522 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1523 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_UINT16
*)OpCodeData
)->Value
, sizeof (UINT16
));
1526 case EFI_IFR_UINT32_OP
:
1527 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1528 CopyMem (&Value
->Value
.u32
, &((EFI_IFR_UINT32
*)OpCodeData
)->Value
, sizeof (UINT32
));
1531 case EFI_IFR_UINT64_OP
:
1532 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1533 CopyMem (&Value
->Value
.u64
, &((EFI_IFR_UINT64
*)OpCodeData
)->Value
, sizeof (UINT64
));
1536 case EFI_IFR_UNDEFINED_OP
:
1537 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1540 case EFI_IFR_VERSION_OP
:
1541 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1542 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1550 // Create sub expression nested in MAP opcode
1552 if ((CurrentExpression
== NULL
) && (MapScopeDepth
> 0)) {
1553 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
1554 ASSERT (MapExpressionList
!= NULL
);
1555 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1557 SingleOpCodeExpression
= TRUE
;
1561 ASSERT (CurrentExpression
!= NULL
);
1562 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1563 if (Operand
== EFI_IFR_MAP_OP
) {
1565 // Store current Map Expression List.
1567 if (MapExpressionList
!= NULL
) {
1568 PushMapExpressionList (MapExpressionList
);
1572 // Initialize new Map Expression List.
1574 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1575 InitializeListHead (MapExpressionList
);
1577 // Store current expression.
1579 PushCurrentExpression (CurrentExpression
);
1580 CurrentExpression
= NULL
;
1582 } else if (SingleOpCodeExpression
) {
1584 // There are two cases to indicate the end of an Expression:
1585 // for single OpCode expression: one Expression OpCode
1586 // for expression consists of more than one OpCode: EFI_IFR_END
1588 SingleOpCodeExpression
= FALSE
;
1590 if (InScopeDisable
&& (CurrentForm
== NULL
)) {
1592 // This is DisableIf expression for Form, it should be a constant expression
1594 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1595 if (EFI_ERROR (Status
)) {
1599 OpCodeDisabled
= IsTrue (&CurrentExpression
->Result
);
1602 CurrentExpression
= NULL
;
1612 case EFI_IFR_FORM_SET_OP
:
1614 // Check the formset GUID
1616 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*)OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1617 return EFI_INVALID_PARAMETER
;
1620 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*)OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1621 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*)OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1622 FormSet
->OpCode
= (EFI_IFR_OP_HEADER
*)OpCodeData
;// save the opcode address of formset
1624 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1626 // The formset OpCode contains ClassGuid
1628 FormSet
->NumberOfClassGuid
= (UINT8
)(((EFI_IFR_FORM_SET
*)OpCodeData
)->Flags
& 0x3);
1629 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1634 case EFI_IFR_FORM_OP
:
1636 // Create a new Form for this FormSet
1638 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1639 ASSERT (CurrentForm
!= NULL
);
1640 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1641 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1642 InitializeListHead (&CurrentForm
->StatementListHead
);
1643 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1644 InitializeListHead (&CurrentForm
->FormViewListHead
);
1646 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1647 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*)OpCodeData
)->FormId
, sizeof (UINT16
));
1648 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*)OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1650 ConditionalExprCount
= GetConditionalExpressionCount (ExpressForm
);
1651 if ( ConditionalExprCount
> 0) {
1653 // Form is inside of suppressif
1655 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*)AllocatePool (
1656 (UINTN
)(sizeof (FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof (FORM_EXPRESSION
*)))
1658 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1659 CurrentForm
->SuppressExpression
->Count
= (UINTN
)ConditionalExprCount
;
1660 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1661 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList (ExpressForm
), (UINTN
)(sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1666 // Enter scope of a Form, suppressif will be used for Question or Option
1668 SuppressForQuestion
= TRUE
;
1672 // Insert into Form list of this FormSet
1674 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1677 case EFI_IFR_FORM_MAP_OP
:
1679 // Create a new Form for this FormSet
1681 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1682 ASSERT (CurrentForm
!= NULL
);
1683 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1684 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1685 InitializeListHead (&CurrentForm
->StatementListHead
);
1686 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1687 InitializeListHead (&CurrentForm
->FormViewListHead
);
1689 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*)OpCodeData
)->FormId
, sizeof (UINT16
));
1691 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1693 // FormMap Form must contain at least one Map Method.
1695 if (((EFI_IFR_OP_HEADER
*)OpCodeData
)->Length
< ((UINTN
)(UINT8
*)(MapMethod
+ 1) - (UINTN
)OpCodeData
)) {
1696 return EFI_INVALID_PARAMETER
;
1700 // Try to find the standard form map method.
1702 while (((UINTN
)(UINT8
*)MapMethod
- (UINTN
)OpCodeData
) < ((EFI_IFR_OP_HEADER
*)OpCodeData
)->Length
) {
1703 if (CompareGuid ((EFI_GUID
*)(VOID
*)&MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1704 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1705 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1713 // If the standard form map method is not found, the first map method title will be used.
1715 if (CurrentForm
->FormTitle
== 0) {
1716 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1717 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1720 ConditionalExprCount
= GetConditionalExpressionCount (ExpressForm
);
1721 if ( ConditionalExprCount
> 0) {
1723 // Form is inside of suppressif
1725 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*)AllocatePool (
1726 (UINTN
)(sizeof (FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof (FORM_EXPRESSION
*)))
1728 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1729 CurrentForm
->SuppressExpression
->Count
= (UINTN
)ConditionalExprCount
;
1730 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1731 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList (ExpressForm
), (UINTN
)(sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1736 // Enter scope of a Form, suppressif will be used for Question or Option
1738 SuppressForQuestion
= TRUE
;
1742 // Insert into Form list of this FormSet
1744 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1750 case EFI_IFR_VARSTORE_OP
:
1752 // Create a buffer Storage for this FormSet
1754 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_BUFFER
, OpCodeData
);
1755 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*)OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1758 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1760 // Create a name/value Storage for this FormSet
1762 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_NAME_VALUE
, OpCodeData
);
1763 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*)OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1766 case EFI_IFR_VARSTORE_EFI_OP
:
1768 // Create a EFI variable Storage for this FormSet
1770 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1772 // Create efi varstore with format follow UEFI spec before 2.3.1.
1774 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE
, OpCodeData
);
1777 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1779 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
, OpCodeData
);
1782 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*)OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1788 case EFI_IFR_DEFAULTSTORE_OP
:
1789 HaveInserted
= FALSE
;
1790 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1791 ASSERT (DefaultStore
!= NULL
);
1792 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1794 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*)OpCodeData
)->DefaultId
, sizeof (UINT16
));
1795 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*)OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1797 // Insert it to the DefaultStore list of this Formset with ascending order.
1799 if (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
1800 DefaultLink
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
1801 while (!IsNull (&FormSet
->DefaultStoreListHead
, DefaultLink
)) {
1802 PreDefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink
);
1803 DefaultLink
= GetNextNode (&FormSet
->DefaultStoreListHead
, DefaultLink
);
1804 if (DefaultStore
->DefaultId
< PreDefaultStore
->DefaultId
) {
1805 InsertTailList (&PreDefaultStore
->Link
, &DefaultStore
->Link
);
1806 HaveInserted
= TRUE
;
1812 if (!HaveInserted
) {
1813 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1821 case EFI_IFR_SUBTITLE_OP
:
1822 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1823 ASSERT (CurrentStatement
!= NULL
);
1825 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*)OpCodeData
)->Flags
;
1826 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1829 case EFI_IFR_TEXT_OP
:
1830 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1831 ASSERT (CurrentStatement
!= NULL
);
1832 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1833 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*)OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1836 case EFI_IFR_RESET_BUTTON_OP
:
1837 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1838 ASSERT (CurrentStatement
!= NULL
);
1839 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1840 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*)OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1846 case EFI_IFR_ACTION_OP
:
1847 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1848 ASSERT (CurrentStatement
!= NULL
);
1849 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1851 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1853 // No QuestionConfig present, so no configuration string will be processed
1855 CurrentStatement
->QuestionConfig
= 0;
1857 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*)OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1862 case EFI_IFR_REF_OP
:
1863 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1864 ASSERT (CurrentStatement
!= NULL
);
1865 Value
= &CurrentStatement
->HiiValue
;
1866 Value
->Type
= EFI_IFR_TYPE_REF
;
1867 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1868 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*)OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1870 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1871 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*)OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1873 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1874 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*)OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1876 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1877 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*)OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1883 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (EFI_HII_REF
);
1884 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1887 case EFI_IFR_ONE_OF_OP
:
1888 case EFI_IFR_NUMERIC_OP
:
1889 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1890 ASSERT (CurrentStatement
!= NULL
);
1892 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*)OpCodeData
)->Flags
;
1893 Value
= &CurrentStatement
->HiiValue
;
1895 if (QuestionReferBitField
) {
1897 // Get the bit var store info (bit/byte offset, bit/byte offset)
1899 CurrentStatement
->QuestionReferToBitField
= TRUE
;
1900 CurrentStatement
->BitStorageWidth
= CurrentStatement
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
1901 CurrentStatement
->BitVarOffset
= CurrentStatement
->VarStoreInfo
.VarOffset
;
1902 CurrentStatement
->VarStoreInfo
.VarOffset
= CurrentStatement
->BitVarOffset
/ 8;
1903 TotalBits
= CurrentStatement
->BitVarOffset
% 8 + CurrentStatement
->BitStorageWidth
;
1904 CurrentStatement
->StorageWidth
= (TotalBits
% 8 == 0 ? TotalBits
/ 8 : TotalBits
/ 8 + 1);
1907 // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)
1909 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.MinValue
;
1910 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.MaxValue
;
1911 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.Step
;
1914 // Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,
1915 // in order to make Browser handle these question with bit varstore correctly.
1917 ((EFI_IFR_NUMERIC
*)OpCodeData
)->Flags
&= EDKII_IFR_DISPLAY_BIT
;
1918 ((EFI_IFR_NUMERIC
*)OpCodeData
)->Flags
>>= 2;
1919 switch (CurrentStatement
->StorageWidth
) {
1921 ((EFI_IFR_NUMERIC
*)OpCodeData
)->Flags
|= EFI_IFR_TYPE_NUM_SIZE_8
;
1922 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u8
.MinValue
= (UINT8
)CurrentStatement
->Minimum
;
1923 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u8
.MaxValue
= (UINT8
)CurrentStatement
->Maximum
;
1924 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u8
.Step
= (UINT8
)CurrentStatement
->Step
;
1925 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1928 ((EFI_IFR_NUMERIC
*)OpCodeData
)->Flags
|= EFI_IFR_TYPE_NUM_SIZE_16
;
1929 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u16
.MinValue
= (UINT16
)CurrentStatement
->Minimum
;
1930 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u16
.MaxValue
= (UINT16
)CurrentStatement
->Maximum
;
1931 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u16
.Step
= (UINT16
)CurrentStatement
->Step
;
1932 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1936 ((EFI_IFR_NUMERIC
*)OpCodeData
)->Flags
|= EFI_IFR_TYPE_NUM_SIZE_32
;
1937 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.MinValue
= (UINT32
)CurrentStatement
->Minimum
;
1938 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.MaxValue
= (UINT32
)CurrentStatement
->Maximum
;
1939 ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.Step
= (UINT32
)CurrentStatement
->Step
;
1940 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1946 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1947 case EFI_IFR_NUMERIC_SIZE_1
:
1948 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u8
.MinValue
;
1949 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u8
.MaxValue
;
1950 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u8
.Step
;
1951 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (UINT8
);
1952 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1955 case EFI_IFR_NUMERIC_SIZE_2
:
1956 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1957 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1958 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1959 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (UINT16
);
1960 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1963 case EFI_IFR_NUMERIC_SIZE_4
:
1964 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1965 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1966 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1967 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (UINT32
);
1968 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1971 case EFI_IFR_NUMERIC_SIZE_8
:
1972 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1973 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1974 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*)OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1975 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (UINT64
);
1976 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1984 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1986 if ((Operand
== EFI_IFR_ONE_OF_OP
) && (Scope
!= 0)) {
1987 SuppressForOption
= TRUE
;
1992 case EFI_IFR_ORDERED_LIST_OP
:
1993 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1994 ASSERT (CurrentStatement
!= NULL
);
1996 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*)OpCodeData
)->Flags
;
1997 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*)OpCodeData
)->MaxContainers
;
1999 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
2000 CurrentStatement
->BufferValue
= NULL
;
2003 SuppressForOption
= TRUE
;
2008 case EFI_IFR_CHECKBOX_OP
:
2009 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2010 ASSERT (CurrentStatement
!= NULL
);
2012 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*)OpCodeData
)->Flags
;
2013 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (BOOLEAN
);
2014 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
2016 if (QuestionReferBitField
) {
2018 // Get the bit var store info (bit/byte offset, bit/byte offset)
2020 CurrentStatement
->QuestionReferToBitField
= TRUE
;
2021 CurrentStatement
->BitStorageWidth
= 1;
2022 CurrentStatement
->BitVarOffset
= CurrentStatement
->VarStoreInfo
.VarOffset
;
2023 CurrentStatement
->VarStoreInfo
.VarOffset
= CurrentStatement
->BitVarOffset
/ 8;
2024 TotalBits
= CurrentStatement
->BitVarOffset
% 8 + CurrentStatement
->BitStorageWidth
;
2025 CurrentStatement
->StorageWidth
= (TotalBits
% 8 == 0 ? TotalBits
/ 8 : TotalBits
/ 8 + 1);
2028 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2032 case EFI_IFR_STRING_OP
:
2033 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2034 ASSERT (CurrentStatement
!= NULL
);
2036 // MinSize is the minimum number of characters that can be accepted for this opcode,
2037 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2038 // The characters are stored as Unicode, so the storage width should multiply 2.
2040 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*)OpCodeData
)->MinSize
;
2041 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*)OpCodeData
)->MaxSize
;
2042 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
)CurrentStatement
->Maximum
* sizeof (CHAR16
));
2043 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*)OpCodeData
)->Flags
;
2045 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
2046 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
2047 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*)CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
2049 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2052 case EFI_IFR_PASSWORD_OP
:
2053 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2054 ASSERT (CurrentStatement
!= NULL
);
2056 // MinSize is the minimum number of characters that can be accepted for this opcode,
2057 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2058 // The characters are stored as Unicode, so the storage width should multiply 2.
2060 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*)OpCodeData
)->MinSize
, sizeof (UINT16
));
2061 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*)OpCodeData
)->MaxSize
, sizeof (UINT16
));
2062 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
)CurrentStatement
->Maximum
* sizeof (CHAR16
));
2064 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
2065 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
2066 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*)CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
2068 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2071 case EFI_IFR_DATE_OP
:
2072 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2073 ASSERT (CurrentStatement
!= NULL
);
2075 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*)OpCodeData
)->Flags
;
2076 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
2078 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
2079 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (EFI_HII_DATE
);
2081 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2084 // Don't assign storage for RTC type of date/time
2086 CurrentStatement
->Storage
= NULL
;
2087 CurrentStatement
->StorageWidth
= 0;
2092 case EFI_IFR_TIME_OP
:
2093 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2094 ASSERT (CurrentStatement
!= NULL
);
2096 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*)OpCodeData
)->Flags
;
2097 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
2099 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
2100 CurrentStatement
->StorageWidth
= (UINT16
)sizeof (EFI_HII_TIME
);
2102 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2105 // Don't assign storage for RTC type of date/time
2107 CurrentStatement
->Storage
= NULL
;
2108 CurrentStatement
->StorageWidth
= 0;
2116 case EFI_IFR_DEFAULT_OP
:
2118 // EFI_IFR_DEFAULT appear in scope of a Question,
2119 // It creates a default value for the current question.
2120 // A Question may have more than one Default value which have different default types.
2122 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
2123 ASSERT (CurrentDefault
!= NULL
);
2124 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
2126 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*)OpCodeData
)->Type
;
2127 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*)OpCodeData
)->DefaultId
, sizeof (UINT16
));
2128 if (CurrentDefault
->Value
.Type
== EFI_IFR_TYPE_BUFFER
) {
2129 CurrentDefault
->Value
.BufferLen
= (UINT16
)(OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
2130 CurrentDefault
->Value
.Buffer
= AllocateCopyPool (CurrentDefault
->Value
.BufferLen
, &((EFI_IFR_DEFAULT
*)OpCodeData
)->Value
);
2131 ASSERT (CurrentDefault
->Value
.Buffer
!= NULL
);
2133 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*)OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
2134 ExtendValueToU64 (&CurrentDefault
->Value
);
2138 // Insert to Default Value list of current Question
2140 InsertTailList (&ParentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2143 InScopeDefault
= TRUE
;
2151 case EFI_IFR_ONE_OF_OPTION_OP
:
2152 ASSERT (ParentStatement
!= NULL
);
2153 if ((ParentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && ((((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Flags
& (EFI_IFR_OPTION_DEFAULT
| EFI_IFR_OPTION_DEFAULT_MFG
)) != 0)) {
2155 // It's keep the default value for ordered list opcode.
2157 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
2158 ASSERT (CurrentDefault
!= NULL
);
2159 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
2161 CurrentDefault
->Value
.Type
= EFI_IFR_TYPE_BUFFER
;
2162 if ((((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2163 CurrentDefault
->DefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2165 CurrentDefault
->DefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2168 CurrentDefault
->Value
.BufferLen
= (UINT16
)(OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
2169 CurrentDefault
->Value
.Buffer
= AllocateCopyPool (CurrentDefault
->Value
.BufferLen
, &((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Value
);
2170 ASSERT (CurrentDefault
->Value
.Buffer
!= NULL
);
2173 // Insert to Default Value list of current Question
2175 InsertTailList (&ParentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2180 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
2181 // It create a selection for use in current Question.
2183 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
2184 ASSERT (CurrentOption
!= NULL
);
2185 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
2186 CurrentOption
->OpCode
= (EFI_IFR_ONE_OF_OPTION
*)OpCodeData
;
2188 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Flags
;
2189 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Type
;
2190 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
2191 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
2192 ExtendValueToU64 (&CurrentOption
->Value
);
2194 ConditionalExprCount
= GetConditionalExpressionCount (ExpressOption
);
2195 if ( ConditionalExprCount
> 0) {
2197 // Form is inside of suppressif
2199 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*)AllocatePool (
2200 (UINTN
)(sizeof (FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof (FORM_EXPRESSION
*)))
2202 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
2203 CurrentOption
->SuppressExpression
->Count
= (UINTN
)ConditionalExprCount
;
2204 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
2205 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList (ExpressOption
), (UINTN
)(sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
2209 // Insert to Option list of current Question
2211 InsertTailList (&ParentStatement
->OptionListHead
, &CurrentOption
->Link
);
2213 // Now we know the Storage width of nested Ordered List
2215 if ((ParentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (ParentStatement
->BufferValue
== NULL
)) {
2217 switch (CurrentOption
->Value
.Type
) {
2218 case EFI_IFR_TYPE_NUM_SIZE_8
:
2222 case EFI_IFR_TYPE_NUM_SIZE_16
:
2226 case EFI_IFR_TYPE_NUM_SIZE_32
:
2230 case EFI_IFR_TYPE_NUM_SIZE_64
:
2236 // Invalid type for Ordered List
2241 ParentStatement
->StorageWidth
= (UINT16
)(ParentStatement
->MaxContainers
* Width
);
2242 ParentStatement
->BufferValue
= AllocateZeroPool (ParentStatement
->StorageWidth
);
2243 ParentStatement
->ValueType
= CurrentOption
->Value
.Type
;
2244 if (ParentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
2245 ParentStatement
->HiiValue
.Buffer
= ParentStatement
->BufferValue
;
2246 ParentStatement
->HiiValue
.BufferLen
= ParentStatement
->StorageWidth
;
2249 InitializeRequestElement (FormSet
, ParentStatement
, CurrentForm
);
2257 case EFI_IFR_NO_SUBMIT_IF_OP
:
2258 case EFI_IFR_INCONSISTENT_IF_OP
:
2260 // Create an Expression node
2262 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2263 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*)OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
2265 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
2266 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
2267 InsertTailList (&ParentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
2269 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
2270 InsertTailList (&ParentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
2274 // Take a look at next OpCode to see whether current expression consists
2277 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2278 SingleOpCodeExpression
= TRUE
;
2283 case EFI_IFR_WARNING_IF_OP
:
2285 // Create an Expression node
2287 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2288 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_WARNING_IF
*)OpCodeData
)->Warning
, sizeof (EFI_STRING_ID
));
2289 CurrentExpression
->TimeOut
= ((EFI_IFR_WARNING_IF
*)OpCodeData
)->TimeOut
;
2290 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WARNING_IF
;
2291 InsertTailList (&ParentStatement
->WarningListHead
, &CurrentExpression
->Link
);
2294 // Take a look at next OpCode to see whether current expression consists
2297 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2298 SingleOpCodeExpression
= TRUE
;
2303 case EFI_IFR_SUPPRESS_IF_OP
:
2305 // Question and Option will appear in scope of this OpCode
2307 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2308 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
2310 if (CurrentForm
== NULL
) {
2311 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
2313 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2316 if (SuppressForOption
) {
2317 PushConditionalExpression (CurrentExpression
, ExpressOption
);
2318 } else if (SuppressForQuestion
) {
2319 PushConditionalExpression (CurrentExpression
, ExpressStatement
);
2321 PushConditionalExpression (CurrentExpression
, ExpressForm
);
2325 // Take a look at next OpCode to see whether current expression consists
2328 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2329 SingleOpCodeExpression
= TRUE
;
2334 case EFI_IFR_GRAY_OUT_IF_OP
:
2336 // Questions will appear in scope of this OpCode
2338 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2339 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
2340 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2341 PushConditionalExpression (CurrentExpression
, ExpressStatement
);
2344 // Take a look at next OpCode to see whether current expression consists
2347 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2348 SingleOpCodeExpression
= TRUE
;
2353 case EFI_IFR_DISABLE_IF_OP
:
2355 // The DisableIf expression should only rely on constant, so it could be
2356 // evaluated at initialization and it will not be queued
2358 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
2359 ASSERT (CurrentExpression
!= NULL
);
2360 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
2361 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
2362 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
2364 if (CurrentForm
!= NULL
) {
2366 // This is DisableIf for Question, enqueue it to Form expression list
2368 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2369 PushConditionalExpression (CurrentExpression
, ExpressStatement
);
2372 OpCodeDisabled
= FALSE
;
2373 InScopeDisable
= TRUE
;
2375 // Take a look at next OpCode to see whether current expression consists
2378 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2379 SingleOpCodeExpression
= TRUE
;
2387 case EFI_IFR_VALUE_OP
:
2388 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2389 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
2390 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2392 if (InScopeDefault
) {
2394 // Used for default (EFI_IFR_DEFAULT)
2396 CurrentDefault
->ValueExpression
= CurrentExpression
;
2399 // If used for a question, then the question will be read-only
2402 // Make sure CurrentStatement is not NULL.
2403 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2404 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2406 ASSERT (ParentStatement
!= NULL
);
2407 ParentStatement
->ValueExpression
= CurrentExpression
;
2411 // Take a look at next OpCode to see whether current expression consists
2414 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2415 SingleOpCodeExpression
= TRUE
;
2420 case EFI_IFR_RULE_OP
:
2421 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2422 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2424 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*)OpCodeData
)->RuleId
;
2425 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2428 // Take a look at next OpCode to see whether current expression consists
2431 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2432 SingleOpCodeExpression
= TRUE
;
2437 case EFI_IFR_READ_OP
:
2438 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2439 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2440 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2443 // Make sure CurrentStatement is not NULL.
2444 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2445 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2447 ASSERT (ParentStatement
!= NULL
);
2448 ParentStatement
->ReadExpression
= CurrentExpression
;
2451 // Take a look at next OpCode to see whether current expression consists
2454 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2455 SingleOpCodeExpression
= TRUE
;
2460 case EFI_IFR_WRITE_OP
:
2461 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2462 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2463 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2466 // Make sure CurrentStatement is not NULL.
2467 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2468 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2470 ASSERT (ParentStatement
!= NULL
);
2471 ParentStatement
->WriteExpression
= CurrentExpression
;
2474 // Take a look at next OpCode to see whether current expression consists
2477 if (((EFI_IFR_OP_HEADER
*)(OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2478 SingleOpCodeExpression
= TRUE
;
2486 case EFI_IFR_IMAGE_OP
:
2488 // Get ScopeOpcode from top of stack
2490 PopScope (&ScopeOpCode
);
2491 PushScope (ScopeOpCode
);
2493 switch (ScopeOpCode
) {
2494 case EFI_IFR_FORM_SET_OP
:
2495 ImageId
= &FormSet
->ImageId
;
2498 case EFI_IFR_FORM_OP
:
2499 case EFI_IFR_FORM_MAP_OP
:
2500 ASSERT (CurrentForm
!= NULL
);
2501 ImageId
= &CurrentForm
->ImageId
;
2504 case EFI_IFR_ONE_OF_OPTION_OP
:
2505 ASSERT (CurrentOption
!= NULL
);
2506 ImageId
= &CurrentOption
->ImageId
;
2511 // Make sure CurrentStatement is not NULL.
2512 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2513 // file is wrongly generated by tools such as VFR Compiler.
2515 ASSERT (ParentStatement
!= NULL
);
2516 ImageId
= &ParentStatement
->ImageId
;
2520 ASSERT (ImageId
!= NULL
);
2521 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*)OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2527 case EFI_IFR_REFRESH_OP
:
2528 ASSERT (ParentStatement
!= NULL
);
2529 ParentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*)OpCodeData
)->RefreshInterval
;
2535 case EFI_IFR_REFRESH_ID_OP
:
2537 // Get ScopeOpcode from top of stack
2539 PopScope (&ScopeOpCode
);
2540 PushScope (ScopeOpCode
);
2542 switch (ScopeOpCode
) {
2543 case EFI_IFR_FORM_OP
:
2544 case EFI_IFR_FORM_MAP_OP
:
2545 ASSERT (CurrentForm
!= NULL
);
2546 CopyMem (&CurrentForm
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*)OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2550 ASSERT (ParentStatement
!= NULL
);
2551 CopyMem (&ParentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*)OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2560 case EFI_IFR_MODAL_TAG_OP
:
2561 ASSERT (CurrentForm
!= NULL
);
2562 CurrentForm
->ModalForm
= TRUE
;
2566 // Lock tag, used by form and statement.
2568 case EFI_IFR_LOCKED_OP
:
2570 // Get ScopeOpcode from top of stack
2572 PopScope (&ScopeOpCode
);
2573 PushScope (ScopeOpCode
);
2574 switch (ScopeOpCode
) {
2575 case EFI_IFR_FORM_OP
:
2576 case EFI_IFR_FORM_MAP_OP
:
2577 ASSERT (CurrentForm
!= NULL
);
2578 CurrentForm
->Locked
= TRUE
;
2582 ASSERT (ParentStatement
!= NULL
);
2583 ParentStatement
->Locked
= TRUE
;
2591 case EFI_IFR_GUID_OP
:
2592 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2593 if (CompareGuid ((EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
2595 QuestionReferBitField
= TRUE
;
2603 case EFI_IFR_END_OP
:
2604 QuestionReferBitField
= FALSE
;
2605 Status
= PopScope (&ScopeOpCode
);
2606 if (EFI_ERROR (Status
)) {
2612 // Parent statement end tag found, update ParentStatement info.
2614 if (IsStatementOpCode (ScopeOpCode
) && (ParentStatement
!= NULL
) && (ParentStatement
->Operand
== ScopeOpCode
)) {
2615 ParentStatement
= ParentStatement
->ParentStatement
;
2618 switch (ScopeOpCode
) {
2619 case EFI_IFR_FORM_SET_OP
:
2621 // End of FormSet, update FormSet IFR binary length
2622 // to stop parsing substantial OpCodes
2624 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2627 case EFI_IFR_FORM_OP
:
2628 case EFI_IFR_FORM_MAP_OP
:
2633 SuppressForQuestion
= FALSE
;
2636 case EFI_IFR_ONE_OF_OPTION_OP
:
2640 CurrentOption
= NULL
;
2643 case EFI_IFR_NO_SUBMIT_IF_OP
:
2644 case EFI_IFR_INCONSISTENT_IF_OP
:
2645 case EFI_IFR_WARNING_IF_OP
:
2647 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2651 case EFI_IFR_SUPPRESS_IF_OP
:
2652 if (SuppressForOption
) {
2653 PopConditionalExpression (ExpressOption
);
2654 } else if (SuppressForQuestion
) {
2655 PopConditionalExpression (ExpressStatement
);
2657 PopConditionalExpression (ExpressForm
);
2662 case EFI_IFR_GRAY_OUT_IF_OP
:
2663 PopConditionalExpression (ExpressStatement
);
2666 case EFI_IFR_DISABLE_IF_OP
:
2667 if (CurrentForm
!= NULL
) {
2668 PopConditionalExpression (ExpressStatement
);
2671 InScopeDisable
= FALSE
;
2672 OpCodeDisabled
= FALSE
;
2675 case EFI_IFR_ONE_OF_OP
:
2676 case EFI_IFR_ORDERED_LIST_OP
:
2677 SuppressForOption
= FALSE
;
2680 case EFI_IFR_DEFAULT_OP
:
2681 InScopeDefault
= FALSE
;
2684 case EFI_IFR_MAP_OP
:
2686 // Get current Map Expression List.
2688 Status
= PopMapExpressionList ((VOID
**)&MapExpressionList
);
2689 if (Status
== EFI_ACCESS_DENIED
) {
2690 MapExpressionList
= NULL
;
2694 // Get current expression.
2696 Status
= PopCurrentExpression ((VOID
**)&CurrentExpression
);
2697 ASSERT_EFI_ERROR (Status
);
2698 ASSERT (MapScopeDepth
> 0);
2703 if (IsExpressionOpCode (ScopeOpCode
)) {
2704 if (InScopeDisable
&& (CurrentForm
== NULL
)) {
2706 // This is DisableIf expression for Form, it should be a constant expression
2708 ASSERT (CurrentExpression
!= NULL
);
2709 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2710 if (EFI_ERROR (Status
)) {
2714 OpCodeDisabled
= IsTrue (&CurrentExpression
->Result
);
2717 // DisableIf Expression is only used once and not queued, free it
2719 DestroyExpression (CurrentExpression
);
2723 // End of current Expression
2725 CurrentExpression
= NULL
;
2737 if (IsStatementOpCode (Operand
)) {
2738 CurrentStatement
->ParentStatement
= ParentStatement
;
2741 // Scope != 0, other statements or options may nest in this statement.
2742 // Update the ParentStatement info.
2744 ParentStatement
= CurrentStatement
;