2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2017, 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
;
19 EFI_QUESTION_ID mUsedQuestionId
;
20 extern LIST_ENTRY gBrowserStorageList
;
22 Initialize Statement header members.
24 @param OpCodeData Pointer of the raw OpCode data.
25 @param FormSet Pointer of the current FormSet.
26 @param Form Pointer of the current Form.
28 @return The Statement.
31 FORM_BROWSER_STATEMENT
*
34 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
35 IN OUT FORM_BROWSER_FORM
*Form
38 FORM_BROWSER_STATEMENT
*Statement
;
39 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
40 INTN ConditionalExprCount
;
44 // Only guid op may out side the form level.
46 ASSERT (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_GUID_OP
);
49 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
52 InitializeListHead (&Statement
->DefaultListHead
);
53 InitializeListHead (&Statement
->OptionListHead
);
54 InitializeListHead (&Statement
->InconsistentListHead
);
55 InitializeListHead (&Statement
->NoSubmitListHead
);
56 InitializeListHead (&Statement
->WarningListHead
);
58 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
60 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
61 Statement
->OpCode
= (EFI_IFR_OP_HEADER
*) OpCodeData
;
62 Statement
->QuestionReferToBitField
= FALSE
;
64 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
65 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
66 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
68 ConditionalExprCount
= GetConditionalExpressionCount(ExpressStatement
);
69 if (ConditionalExprCount
> 0) {
71 // Form is inside of suppressif
74 Statement
->Expression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
75 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
76 ASSERT (Statement
->Expression
!= NULL
);
77 Statement
->Expression
->Count
= (UINTN
) ConditionalExprCount
;
78 Statement
->Expression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
79 CopyMem (Statement
->Expression
->Expression
, GetConditionalExpressionList(ExpressStatement
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
83 // Insert this Statement into current Form
86 InsertTailList (&FormSet
->StatementListOSF
, &Statement
->Link
);
88 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
94 Convert a numeric value to a Unicode String and insert it to String Package.
95 This string is used as the Unicode Name for the EFI Variable. This is to support
96 the deprecated vareqval opcode.
98 @param FormSet The FormSet.
99 @param Statement The numeric question whose VarStoreInfo.VarName is the
100 numeric value which is used to produce the Unicode Name
101 for the EFI Variable.
103 If the Statement is NULL, the ASSERT.
104 If the opcode is not Numeric, then ASSERT.
106 @retval EFI_SUCCESS The funtion always succeeds.
109 UpdateCheckBoxStringToken (
110 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
111 IN FORM_BROWSER_STATEMENT
*Statement
114 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
117 ASSERT (Statement
!= NULL
);
118 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
120 UnicodeValueToStringS (Str
, sizeof (Str
), 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
122 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
124 return EFI_OUT_OF_RESOURCES
;
127 Statement
->VarStoreInfo
.VarName
= Id
;
133 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
135 @param OpCodeData The current opcode.
141 IsNextOpCodeGuidedVarEqName (
148 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
149 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
150 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
152 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
154 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
164 Initialize Question's members.
166 @param OpCodeData Pointer of the raw OpCode data.
167 @param FormSet Pointer of the current FormSet.
168 @param Form Pointer of the current Form.
170 @return The Question.
173 FORM_BROWSER_STATEMENT
*
175 IN UINT8
*OpCodeData
,
176 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
177 IN OUT FORM_BROWSER_FORM
*Form
180 FORM_BROWSER_STATEMENT
*Statement
;
181 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
183 FORMSET_STORAGE
*Storage
;
184 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
->BrowserStorage
;
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 // Check whether old string node already exist.
249 if (!IsListEmpty(&Statement
->Storage
->NameValueListHead
)) {
250 Link
= GetFirstNode (&Statement
->Storage
->NameValueListHead
);
251 while (!IsNull (&Statement
->Storage
->NameValueListHead
, Link
)) {
252 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
254 if (StrCmp (Statement
->VariableName
, NameValueNode
->Name
) == 0) {
259 Link
= GetNextNode (&Statement
->Storage
->NameValueListHead
, Link
);
265 // Insert to Name/Value varstore list
267 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
268 ASSERT (NameValueNode
!= NULL
);
269 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
270 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
271 ASSERT (NameValueNode
->Name
!= NULL
);
272 NameValueNode
->Value
= AllocateZeroPool (0x10);
273 ASSERT (NameValueNode
->Value
!= NULL
);
274 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
275 ASSERT (NameValueNode
->EditValue
!= NULL
);
277 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
287 Allocate a FORM_EXPRESSION node.
289 @param Form The Form associated with this Expression
290 @param OpCode The binary opcode data.
292 @return Pointer to a FORM_EXPRESSION data structure.
297 IN OUT FORM_BROWSER_FORM
*Form
,
301 FORM_EXPRESSION
*Expression
;
303 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
304 ASSERT (Expression
!= NULL
);
305 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
306 InitializeListHead (&Expression
->OpCodeListHead
);
307 Expression
->OpCode
= (EFI_IFR_OP_HEADER
*) OpCode
;
313 Create ConfigHdr string for a storage.
315 @param FormSet Pointer of the current FormSet
316 @param Storage Pointer of the storage
318 @retval EFI_SUCCESS Initialize ConfigHdr success
322 InitializeConfigHdr (
323 IN FORM_BROWSER_FORMSET
*FormSet
,
324 IN OUT FORMSET_STORAGE
*Storage
329 if (Storage
->BrowserStorage
->Type
== EFI_HII_VARSTORE_BUFFER
||
330 Storage
->BrowserStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
331 Name
= Storage
->BrowserStorage
->Name
;
336 Storage
->ConfigHdr
= HiiConstructConfigHdr (
337 &Storage
->BrowserStorage
->Guid
,
339 FormSet
->DriverHandle
342 if (Storage
->ConfigHdr
== NULL
) {
343 return EFI_NOT_FOUND
;
350 Find the global storage link base on the input storate type, name and guid.
352 For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
353 same guid + name = same storage
355 For EFI_HII_VARSTORE_NAME_VALUE:
356 same guid + HiiHandle = same storage
358 For EFI_HII_VARSTORE_BUFFER:
359 same guid + name + HiiHandle = same storage
361 @param StorageType Storage type.
362 @param StorageGuid Storage guid.
363 @param StorageName Storage Name.
364 @param HiiHandle HiiHandle for this varstore.
366 @return Pointer to a GLOBAL_STORAGE data structure.
371 IN UINT8 StorageType
,
372 IN EFI_GUID
*StorageGuid
,
373 IN CHAR16
*StorageName
,
374 IN EFI_HII_HANDLE HiiHandle
378 BROWSER_STORAGE
*BrowserStorage
;
380 Link
= GetFirstNode (&gBrowserStorageList
);
381 while (!IsNull (&gBrowserStorageList
, Link
)) {
382 BrowserStorage
= BROWSER_STORAGE_FROM_LINK (Link
);
383 Link
= GetNextNode (&gBrowserStorageList
, Link
);
385 if ((BrowserStorage
->Type
== StorageType
) && CompareGuid (&BrowserStorage
->Guid
, StorageGuid
)) {
386 if (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
) {
387 if (BrowserStorage
->HiiHandle
== HiiHandle
) {
388 return BrowserStorage
;
394 ASSERT (StorageName
!= NULL
);
395 if (StrCmp (BrowserStorage
->Name
, StorageName
) == 0) {
396 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE
|| StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
397 return BrowserStorage
;
398 } else if (StorageType
== EFI_HII_VARSTORE_BUFFER
&& BrowserStorage
->HiiHandle
== HiiHandle
) {
399 return BrowserStorage
;
409 Intialize the Global Storage.
411 @param BrowserStorage Pointer to the global storage.
412 @param StorageType Storage type.
413 @param OpCodeData Binary data for this opcode.
417 IntializeBrowserStorage (
418 IN BROWSER_STORAGE
*BrowserStorage
,
419 IN UINT8 StorageType
,
423 switch (StorageType
) {
424 case EFI_HII_VARSTORE_BUFFER
:
425 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
426 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
428 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
429 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
432 case EFI_HII_VARSTORE_EFI_VARIABLE
:
433 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
434 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
435 CopyMem (&BrowserStorage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
436 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
438 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
439 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
440 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
444 case EFI_HII_VARSTORE_NAME_VALUE
:
445 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
447 InitializeListHead (&BrowserStorage
->NameValueListHead
);
456 Check whether exist device path info in the ConfigHdr string.
458 @param String UEFI configuration string
460 @retval TRUE Device Path exist.
461 @retval FALSE Not exist device path info.
471 for (; (*String
!= 0 && StrnCmp (String
, L
"PATH=", StrLen (L
"PATH=")) != 0); String
++);
476 String
+= StrLen (L
"PATH=");
481 for (Length
= 0; *String
!= 0 && *String
!= L
'&'; String
++, Length
++);
482 if (((Length
+ 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL
)) {
490 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
492 @param FormSet Pointer of the current FormSet
493 @param StorageType Storage type.
494 @param OpCodeData Binary data for this opcode.
496 @return Pointer to a FORMSET_STORAGE data structure.
501 IN FORM_BROWSER_FORMSET
*FormSet
,
502 IN UINT8 StorageType
,
506 FORMSET_STORAGE
*Storage
;
507 CHAR16
*UnicodeString
;
509 BROWSER_STORAGE
*BrowserStorage
;
510 EFI_GUID
*StorageGuid
;
513 UnicodeString
= NULL
;
515 switch (StorageType
) {
516 case EFI_HII_VARSTORE_BUFFER
:
517 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
;
518 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
521 case EFI_HII_VARSTORE_EFI_VARIABLE
:
522 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
523 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
;
524 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
528 ASSERT (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
);
529 StorageGuid
= &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
;
533 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
534 ASSERT (StorageName
!= NULL
);
536 UnicodeString
= AllocateZeroPool (AsciiStrSize (StorageName
) * 2);
537 ASSERT (UnicodeString
!= NULL
);
538 for (Index
= 0; StorageName
[Index
] != 0; Index
++) {
539 UnicodeString
[Index
] = (CHAR16
) StorageName
[Index
];
543 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
544 ASSERT (Storage
!= NULL
);
545 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
546 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
548 BrowserStorage
= FindStorageInList(StorageType
, StorageGuid
, UnicodeString
, FormSet
->HiiHandle
);
549 if (BrowserStorage
== NULL
) {
550 BrowserStorage
= AllocateZeroPool (sizeof (BROWSER_STORAGE
));
551 ASSERT (BrowserStorage
!= NULL
);
553 BrowserStorage
->Signature
= BROWSER_STORAGE_SIGNATURE
;
554 InsertTailList (&gBrowserStorageList
, &BrowserStorage
->Link
);
556 IntializeBrowserStorage (BrowserStorage
, StorageType
, OpCodeData
);
557 BrowserStorage
->Type
= StorageType
;
558 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
559 BrowserStorage
->Name
= UnicodeString
;
562 BrowserStorage
->HiiHandle
= FormSet
->HiiHandle
;
564 BrowserStorage
->Initialized
= FALSE
;
567 Storage
->BrowserStorage
= BrowserStorage
;
568 InitializeConfigHdr (FormSet
, Storage
);
569 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
570 Storage
->SpareStrLen
= 0;
576 Get Formset_storage base on the input varstoreid info.
578 @param FormSet Pointer of the current FormSet.
579 @param VarStoreId Varstore ID info.
581 @return Pointer to a FORMSET_STORAGE data structure.
586 IN FORM_BROWSER_FORMSET
*FormSet
,
587 IN EFI_VARSTORE_ID VarStoreId
590 FORMSET_STORAGE
*FormsetStorage
;
595 FormsetStorage
= NULL
;
597 // Find Formset Storage for this Question
599 Link
= GetFirstNode (&FormSet
->StorageListHead
);
600 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
601 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
603 if (FormsetStorage
->VarStoreId
== VarStoreId
) {
608 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
611 return Found
? FormsetStorage
: NULL
;
615 Get Formset_storage base on the input browser storage.
617 More than one formsets may share the same browser storage,
618 this function just get the first formset storage which
619 share the browser storage.
621 @param Storage browser storage info.
623 @return Pointer to a FORMSET_STORAGE data structure.
628 GetFstStgFromBrsStg (
629 IN BROWSER_STORAGE
*Storage
632 FORMSET_STORAGE
*FormsetStorage
;
634 LIST_ENTRY
*FormsetLink
;
635 FORM_BROWSER_FORMSET
*FormSet
;
639 FormsetStorage
= NULL
;
641 FormsetLink
= GetFirstNode (&gBrowserFormSetList
);
642 while (!IsNull (&gBrowserFormSetList
, FormsetLink
)) {
643 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink
);
644 FormsetLink
= GetNextNode (&gBrowserFormSetList
, FormsetLink
);
646 Link
= GetFirstNode (&FormSet
->StorageListHead
);
647 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
648 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
649 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
651 if (FormsetStorage
->BrowserStorage
== Storage
) {
662 return Found
? FormsetStorage
: NULL
;
666 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
668 @param FormSet Pointer of the current FormSet.
669 @param Question The Question to be initialized.
670 @param Form Pointer of the current form.
672 @retval EFI_SUCCESS Function success.
673 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
677 InitializeRequestElement (
678 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
679 IN OUT FORM_BROWSER_STATEMENT
*Question
,
680 IN OUT FORM_BROWSER_FORM
*Form
683 BROWSER_STORAGE
*Storage
;
684 FORMSET_STORAGE
*FormsetStorage
;
688 CHAR16 RequestElement
[30];
691 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
694 Storage
= Question
->Storage
;
695 if (Storage
== NULL
) {
696 return EFI_INVALID_PARAMETER
;
699 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
701 // <ConfigRequest> is unnecessary for EFI variable storage,
702 // GetVariable()/SetVariable() will be used to retrieve/save values
708 // Prepare <RequestElement>
710 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
711 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
712 StrLen
= UnicodeSPrint (
714 30 * sizeof (CHAR16
),
715 L
"&OFFSET=%04x&WIDTH=%04x",
716 Question
->VarStoreInfo
.VarOffset
,
717 Question
->StorageWidth
719 HiiToLower(RequestElement
);
720 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
722 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
725 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
727 // Password with CALLBACK flag is stored in encoded format,
728 // so don't need to append it to <ConfigRequest>
734 // Find Formset Storage for this Question
736 FormsetStorage
= GetFstStgFromVarId(FormSet
, Question
->VarStoreId
);
737 ASSERT (FormsetStorage
!= NULL
);
738 StringSize
= (FormsetStorage
->ConfigRequest
!= NULL
) ? StrSize (FormsetStorage
->ConfigRequest
) : sizeof (CHAR16
);
739 MaxLen
= StringSize
/ sizeof (CHAR16
) + FormsetStorage
->SpareStrLen
;
742 // Append <RequestElement> to <ConfigRequest>
744 if (StrLen
> FormsetStorage
->SpareStrLen
) {
746 // Old String buffer is not sufficient for RequestElement, allocate a new one
748 MaxLen
= StringSize
/ sizeof (CHAR16
) + CONFIG_REQUEST_STRING_INCREMENTAL
;
749 NewStr
= AllocateZeroPool (MaxLen
* sizeof (CHAR16
));
750 ASSERT (NewStr
!= NULL
);
751 if (FormsetStorage
->ConfigRequest
!= NULL
) {
752 CopyMem (NewStr
, FormsetStorage
->ConfigRequest
, StringSize
);
753 FreePool (FormsetStorage
->ConfigRequest
);
755 FormsetStorage
->ConfigRequest
= NewStr
;
756 FormsetStorage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
759 StrCatS (FormsetStorage
->ConfigRequest
, MaxLen
, RequestElement
);
760 FormsetStorage
->ElementCount
++;
761 FormsetStorage
->SpareStrLen
-= StrLen
;
764 // Update the Config Request info saved in the form.
768 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
769 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
770 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
772 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
== FormsetStorage
->BrowserStorage
) {
777 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
781 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
782 ASSERT (ConfigInfo
!= NULL
);
783 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
784 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (FormsetStorage
->ConfigHdr
), FormsetStorage
->ConfigHdr
);
785 ASSERT (ConfigInfo
->ConfigRequest
!= NULL
);
786 ConfigInfo
->SpareStrLen
= 0;
787 ConfigInfo
->Storage
= FormsetStorage
->BrowserStorage
;
788 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
790 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
791 MaxLen
= StringSize
/ sizeof (CHAR16
) + ConfigInfo
->SpareStrLen
;
794 // Append <RequestElement> to <ConfigRequest>
796 if (StrLen
> ConfigInfo
->SpareStrLen
) {
798 // Old String buffer is not sufficient for RequestElement, allocate a new one
800 MaxLen
= StringSize
/ sizeof (CHAR16
) + CONFIG_REQUEST_STRING_INCREMENTAL
;
801 NewStr
= AllocateZeroPool (MaxLen
* sizeof (CHAR16
));
802 ASSERT (NewStr
!= NULL
);
803 if (ConfigInfo
->ConfigRequest
!= NULL
) {
804 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
805 FreePool (ConfigInfo
->ConfigRequest
);
807 ConfigInfo
->ConfigRequest
= NewStr
;
808 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
811 StrCatS (ConfigInfo
->ConfigRequest
, MaxLen
, RequestElement
);
812 ConfigInfo
->ElementCount
++;
813 ConfigInfo
->SpareStrLen
-= StrLen
;
819 Free resources of a Expression.
821 @param FormSet Pointer of the Expression
826 IN FORM_EXPRESSION
*Expression
830 EXPRESSION_OPCODE
*OpCode
;
831 LIST_ENTRY
*SubExpressionLink
;
832 FORM_EXPRESSION
*SubExpression
;
834 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
835 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
836 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
837 RemoveEntryList (&OpCode
->Link
);
839 if (OpCode
->ValueList
!= NULL
) {
840 FreePool (OpCode
->ValueList
);
843 if (OpCode
->ValueName
!= NULL
) {
844 FreePool (OpCode
->ValueName
);
847 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
848 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
849 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
850 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
851 RemoveEntryList(&SubExpression
->Link
);
852 DestroyExpression (SubExpression
);
858 // Free this Expression
860 FreePool (Expression
);
864 Free resources of a storage.
866 @param Storage Pointer of the storage
871 IN FORMSET_STORAGE
*Storage
874 if (Storage
== NULL
) {
878 if (Storage
->ConfigRequest
!= NULL
) {
879 FreePool (Storage
->ConfigRequest
);
887 Free resources of a Statement.
889 @param FormSet Pointer of the FormSet
890 @param Statement Pointer of the Statement
895 IN FORM_BROWSER_FORMSET
*FormSet
,
896 IN OUT FORM_BROWSER_STATEMENT
*Statement
900 QUESTION_DEFAULT
*Default
;
901 QUESTION_OPTION
*Option
;
902 FORM_EXPRESSION
*Expression
;
905 // Free Default value List
907 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
908 Link
= GetFirstNode (&Statement
->DefaultListHead
);
909 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
910 RemoveEntryList (&Default
->Link
);
912 if (Default
->Value
.Buffer
!= NULL
) {
913 FreePool (Default
->Value
.Buffer
);
921 while (!IsListEmpty (&Statement
->OptionListHead
)) {
922 Link
= GetFirstNode (&Statement
->OptionListHead
);
923 Option
= QUESTION_OPTION_FROM_LINK (Link
);
924 if (Option
->SuppressExpression
!= NULL
) {
925 FreePool (Option
->SuppressExpression
);
927 RemoveEntryList (&Option
->Link
);
933 // Free Inconsistent List
935 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
936 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
937 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
938 RemoveEntryList (&Expression
->Link
);
940 DestroyExpression (Expression
);
944 // Free NoSubmit List
946 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
947 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
948 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
949 RemoveEntryList (&Expression
->Link
);
951 DestroyExpression (Expression
);
955 // Free WarningIf List
957 while (!IsListEmpty (&Statement
->WarningListHead
)) {
958 Link
= GetFirstNode (&Statement
->WarningListHead
);
959 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
960 RemoveEntryList (&Expression
->Link
);
962 DestroyExpression (Expression
);
965 if (Statement
->Expression
!= NULL
) {
966 FreePool (Statement
->Expression
);
969 if (Statement
->VariableName
!= NULL
) {
970 FreePool (Statement
->VariableName
);
972 if (Statement
->BlockName
!= NULL
) {
973 FreePool (Statement
->BlockName
);
975 if (Statement
->BufferValue
!= NULL
) {
976 FreePool (Statement
->BufferValue
);
978 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
979 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
985 Free resources of a Form.
987 @param FormSet Pointer of the FormSet
988 @param Form Pointer of the Form.
993 IN FORM_BROWSER_FORMSET
*FormSet
,
994 IN OUT FORM_BROWSER_FORM
*Form
998 FORM_EXPRESSION
*Expression
;
999 FORM_BROWSER_STATEMENT
*Statement
;
1000 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
1003 // Free Form Expressions
1005 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
1006 Link
= GetFirstNode (&Form
->ExpressionListHead
);
1007 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1008 RemoveEntryList (&Expression
->Link
);
1010 DestroyExpression (Expression
);
1014 // Free Statements/Questions
1016 while (!IsListEmpty (&Form
->StatementListHead
)) {
1017 Link
= GetFirstNode (&Form
->StatementListHead
);
1018 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1019 RemoveEntryList (&Statement
->Link
);
1021 DestroyStatement (FormSet
, Statement
);
1025 // Free ConfigRequest string.
1027 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
1028 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
1029 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
1030 RemoveEntryList (&ConfigInfo
->Link
);
1032 FreePool (ConfigInfo
->ConfigRequest
);
1033 FreePool (ConfigInfo
);
1036 if (Form
->SuppressExpression
!= NULL
) {
1037 FreePool (Form
->SuppressExpression
);
1040 UiFreeMenuList (&Form
->FormViewListHead
);
1050 Free resources allocated for a FormSet.
1052 @param FormSet Pointer of the FormSet
1057 IN OUT FORM_BROWSER_FORMSET
*FormSet
1061 FORMSET_STORAGE
*Storage
;
1062 FORMSET_DEFAULTSTORE
*DefaultStore
;
1063 FORM_EXPRESSION
*Expression
;
1064 FORM_BROWSER_FORM
*Form
;
1066 if (FormSet
->IfrBinaryData
== NULL
) {
1068 // Uninitialized FormSet
1075 // Free IFR binary buffer
1077 FreePool (FormSet
->IfrBinaryData
);
1080 // Free FormSet Storage
1082 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1083 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
1084 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1085 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1086 RemoveEntryList (&Storage
->Link
);
1088 DestroyStorage (Storage
);
1093 // Free FormSet Default Store
1095 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
1096 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
1097 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
1098 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
1099 RemoveEntryList (&DefaultStore
->Link
);
1101 FreePool (DefaultStore
);
1106 // Free Formset Expressions
1108 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
1109 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
1110 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1111 RemoveEntryList (&Expression
->Link
);
1113 DestroyExpression (Expression
);
1119 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
1120 while (!IsListEmpty (&FormSet
->FormListHead
)) {
1121 Link
= GetFirstNode (&FormSet
->FormListHead
);
1122 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1123 RemoveEntryList (&Form
->Link
);
1125 DestroyForm (FormSet
, Form
);
1129 if (FormSet
->StatementBuffer
!= NULL
) {
1130 FreePool (FormSet
->StatementBuffer
);
1132 if (FormSet
->ExpressionBuffer
!= NULL
) {
1133 FreePool (FormSet
->ExpressionBuffer
);
1141 Tell whether this Operand is an Expression OpCode or not
1143 @param Operand Operand of an IFR OpCode.
1145 @retval TRUE This is an Expression OpCode.
1146 @retval FALSE Not an Expression OpCode.
1150 IsExpressionOpCode (
1154 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
1155 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
1156 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
1157 (Operand
== EFI_IFR_CATENATE_OP
) ||
1158 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
1159 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
1160 (Operand
== EFI_IFR_MAP_OP
) ||
1161 (Operand
== EFI_IFR_VERSION_OP
) ||
1162 (Operand
== EFI_IFR_SECURITY_OP
) ||
1163 (Operand
== EFI_IFR_MATCH2_OP
)) {
1171 Tell whether this Operand is an Statement OpCode.
1173 @param Operand Operand of an IFR OpCode.
1175 @retval TRUE This is an Statement OpCode.
1176 @retval FALSE Not an Statement OpCode.
1184 if ((Operand
== EFI_IFR_SUBTITLE_OP
) ||
1185 (Operand
== EFI_IFR_TEXT_OP
) ||
1186 (Operand
== EFI_IFR_RESET_BUTTON_OP
) ||
1187 (Operand
== EFI_IFR_REF_OP
) ||
1188 (Operand
== EFI_IFR_ACTION_OP
) ||
1189 (Operand
== EFI_IFR_NUMERIC_OP
) ||
1190 (Operand
== EFI_IFR_ORDERED_LIST_OP
) ||
1191 (Operand
== EFI_IFR_CHECKBOX_OP
) ||
1192 (Operand
== EFI_IFR_STRING_OP
) ||
1193 (Operand
== EFI_IFR_PASSWORD_OP
) ||
1194 (Operand
== EFI_IFR_DATE_OP
) ||
1195 (Operand
== EFI_IFR_TIME_OP
) ||
1196 (Operand
== EFI_IFR_GUID_OP
) ||
1197 (Operand
== EFI_IFR_ONE_OF_OP
)) {
1205 Tell whether this Operand is an known OpCode.
1207 @param Operand Operand of an IFR OpCode.
1209 @retval TRUE This is an Statement OpCode.
1210 @retval FALSE Not an Statement OpCode.
1218 return Operand
> EFI_IFR_MATCH2_OP
? TRUE
: FALSE
;
1222 Calculate number of Statemens(Questions) and Expression OpCodes.
1224 @param FormSet The FormSet to be counted.
1225 @param NumberOfStatement Number of Statemens(Questions)
1226 @param NumberOfExpression Number of Expression OpCodes
1231 IN FORM_BROWSER_FORMSET
*FormSet
,
1232 IN OUT UINT16
*NumberOfStatement
,
1233 IN OUT UINT16
*NumberOfExpression
1236 UINT16 StatementCount
;
1237 UINT16 ExpressionCount
;
1244 ExpressionCount
= 0;
1246 while (Offset
< FormSet
->IfrBinaryLength
) {
1247 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
1248 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1249 Offset
+= OpCodeLen
;
1251 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
1258 *NumberOfStatement
= StatementCount
;
1259 *NumberOfExpression
= ExpressionCount
;
1265 Parse opcodes in the formset IFR binary.
1267 @param FormSet Pointer of the FormSet data structure.
1269 @retval EFI_SUCCESS Opcode parse success.
1270 @retval Other Opcode parse fail.
1275 IN FORM_BROWSER_FORMSET
*FormSet
1279 FORM_BROWSER_FORM
*CurrentForm
;
1280 FORM_BROWSER_STATEMENT
*CurrentStatement
;
1281 FORM_BROWSER_STATEMENT
*ParentStatement
;
1282 EXPRESSION_OPCODE
*ExpressionOpCode
;
1283 FORM_EXPRESSION
*CurrentExpression
;
1290 FORMSET_STORAGE
*Storage
;
1291 FORMSET_DEFAULTSTORE
*DefaultStore
;
1292 QUESTION_DEFAULT
*CurrentDefault
;
1293 QUESTION_OPTION
*CurrentOption
;
1295 UINT16 NumberOfStatement
;
1296 UINT16 NumberOfExpression
;
1297 EFI_IMAGE_ID
*ImageId
;
1298 BOOLEAN SuppressForQuestion
;
1299 BOOLEAN SuppressForOption
;
1300 UINT16 DepthOfDisable
;
1301 BOOLEAN OpCodeDisabled
;
1302 BOOLEAN SingleOpCodeExpression
;
1303 BOOLEAN InScopeDefault
;
1304 EFI_HII_VALUE
*Value
;
1305 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
1306 UINT8 MapScopeDepth
;
1308 FORMSET_STORAGE
*VarStorage
;
1309 LIST_ENTRY
*MapExpressionList
;
1310 EFI_VARSTORE_ID TempVarstoreId
;
1311 BOOLEAN InScopeDisable
;
1312 INTN ConditionalExprCount
;
1313 BOOLEAN InUnknownScope
;
1315 FORMSET_DEFAULTSTORE
*PreDefaultStore
;
1316 LIST_ENTRY
*DefaultLink
;
1317 BOOLEAN HaveInserted
;
1319 BOOLEAN QuestionReferBitField
;
1321 SuppressForQuestion
= FALSE
;
1322 SuppressForOption
= FALSE
;
1323 InScopeDisable
= FALSE
;
1325 OpCodeDisabled
= FALSE
;
1326 SingleOpCodeExpression
= FALSE
;
1327 InScopeDefault
= FALSE
;
1328 CurrentExpression
= NULL
;
1329 CurrentDefault
= NULL
;
1330 CurrentOption
= NULL
;
1336 MapExpressionList
= NULL
;
1338 ConditionalExprCount
= 0;
1339 InUnknownScope
= FALSE
;
1341 QuestionReferBitField
= FALSE
;
1344 // Get the number of Statements and Expressions
1346 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
1348 mStatementIndex
= 0;
1349 mUsedQuestionId
= 1;
1350 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
1351 if (FormSet
->StatementBuffer
== NULL
) {
1352 return EFI_OUT_OF_RESOURCES
;
1355 mExpressionOpCodeIndex
= 0;
1356 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
1357 if (FormSet
->ExpressionBuffer
== NULL
) {
1358 return EFI_OUT_OF_RESOURCES
;
1361 InitializeListHead (&FormSet
->StatementListOSF
);
1362 InitializeListHead (&FormSet
->StorageListHead
);
1363 InitializeListHead (&FormSet
->SaveFailStorageListHead
);
1364 InitializeListHead (&FormSet
->DefaultStoreListHead
);
1365 InitializeListHead (&FormSet
->FormListHead
);
1366 InitializeListHead (&FormSet
->ExpressionListHead
);
1367 ResetCurrentExpressionStack ();
1368 ResetMapExpressionListStack ();
1371 CurrentStatement
= NULL
;
1372 ParentStatement
= NULL
;
1377 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1378 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1380 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1381 OpCodeOffset
+= OpCodeLength
;
1382 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1383 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1385 if (InUnknownScope
) {
1386 if (Operand
== EFI_IFR_END_OP
) {
1389 if (UnknownDepth
== 0) {
1390 InUnknownScope
= FALSE
;
1401 if (IsUnKnownOpCode(Operand
)) {
1403 InUnknownScope
= TRUE
;
1411 // If scope bit set, push onto scope stack
1414 PushScope (Operand
);
1417 if (OpCodeDisabled
) {
1419 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1420 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1422 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1424 } else if (Operand
== EFI_IFR_END_OP
) {
1425 Status
= PopScope (&ScopeOpCode
);
1426 if (EFI_ERROR (Status
)) {
1430 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1431 if (DepthOfDisable
== 0) {
1432 InScopeDisable
= FALSE
;
1433 OpCodeDisabled
= FALSE
;
1442 if (IsExpressionOpCode (Operand
)) {
1443 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1444 mExpressionOpCodeIndex
++;
1446 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1447 ExpressionOpCode
->Operand
= Operand
;
1448 Value
= &ExpressionOpCode
->Value
;
1451 case EFI_IFR_EQ_ID_VAL_OP
:
1452 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1454 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1455 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1458 case EFI_IFR_EQ_ID_ID_OP
:
1459 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1460 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1463 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1464 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1465 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1466 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1469 case EFI_IFR_TO_STRING_OP
:
1470 case EFI_IFR_FIND_OP
:
1471 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1474 case EFI_IFR_STRING_REF1_OP
:
1475 Value
->Type
= EFI_IFR_TYPE_STRING
;
1476 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1479 case EFI_IFR_RULE_REF_OP
:
1480 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1483 case EFI_IFR_SPAN_OP
:
1484 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1487 case EFI_IFR_THIS_OP
:
1488 ASSERT (ParentStatement
!= NULL
);
1489 ExpressionOpCode
->QuestionId
= ParentStatement
->QuestionId
;
1492 case EFI_IFR_SECURITY_OP
:
1493 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1496 case EFI_IFR_MATCH2_OP
:
1497 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_MATCH2
*) OpCodeData
)->SyntaxType
, sizeof (EFI_GUID
));
1500 case EFI_IFR_GET_OP
:
1501 case EFI_IFR_SET_OP
:
1502 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1503 if (TempVarstoreId
!= 0) {
1504 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1505 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1506 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1507 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1508 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1509 ExpressionOpCode
->VarStorage
= VarStorage
->BrowserStorage
;
1512 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1515 if (ExpressionOpCode
->VarStorage
== NULL
) {
1517 // VarStorage is not found.
1519 return EFI_INVALID_PARAMETER
;
1522 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1523 switch (ExpressionOpCode
->ValueType
) {
1524 case EFI_IFR_TYPE_BOOLEAN
:
1525 case EFI_IFR_TYPE_NUM_SIZE_8
:
1526 ExpressionOpCode
->ValueWidth
= 1;
1529 case EFI_IFR_TYPE_NUM_SIZE_16
:
1530 case EFI_IFR_TYPE_STRING
:
1531 ExpressionOpCode
->ValueWidth
= 2;
1534 case EFI_IFR_TYPE_NUM_SIZE_32
:
1535 ExpressionOpCode
->ValueWidth
= 4;
1538 case EFI_IFR_TYPE_NUM_SIZE_64
:
1539 ExpressionOpCode
->ValueWidth
= 8;
1542 case EFI_IFR_TYPE_DATE
:
1543 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1546 case EFI_IFR_TYPE_TIME
:
1547 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1550 case EFI_IFR_TYPE_REF
:
1551 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
1554 case EFI_IFR_TYPE_OTHER
:
1555 case EFI_IFR_TYPE_UNDEFINED
:
1556 case EFI_IFR_TYPE_ACTION
:
1557 case EFI_IFR_TYPE_BUFFER
:
1560 // Invalid value type for Get/Set opcode.
1562 return EFI_INVALID_PARAMETER
;
1564 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1565 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1566 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1567 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1568 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1569 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1570 if (ExpressionOpCode
->ValueName
== NULL
) {
1572 // String ID is invalid.
1574 return EFI_INVALID_PARAMETER
;
1579 case EFI_IFR_QUESTION_REF1_OP
:
1580 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1583 case EFI_IFR_QUESTION_REF3_OP
:
1584 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1585 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1587 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1588 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1596 case EFI_IFR_TRUE_OP
:
1597 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1598 Value
->Value
.b
= TRUE
;
1601 case EFI_IFR_FALSE_OP
:
1602 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1603 Value
->Value
.b
= FALSE
;
1606 case EFI_IFR_ONE_OP
:
1607 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1608 Value
->Value
.u8
= 1;
1611 case EFI_IFR_ZERO_OP
:
1612 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1613 Value
->Value
.u8
= 0;
1616 case EFI_IFR_ONES_OP
:
1617 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1618 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1621 case EFI_IFR_UINT8_OP
:
1622 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1623 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1626 case EFI_IFR_UINT16_OP
:
1627 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1628 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1631 case EFI_IFR_UINT32_OP
:
1632 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1633 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1636 case EFI_IFR_UINT64_OP
:
1637 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1638 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1641 case EFI_IFR_UNDEFINED_OP
:
1642 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1645 case EFI_IFR_VERSION_OP
:
1646 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1647 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1654 // Create sub expression nested in MAP opcode
1656 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1657 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
1658 ASSERT (MapExpressionList
!= NULL
);
1659 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1661 SingleOpCodeExpression
= TRUE
;
1664 ASSERT (CurrentExpression
!= NULL
);
1665 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1666 if (Operand
== EFI_IFR_MAP_OP
) {
1668 // Store current Map Expression List.
1670 if (MapExpressionList
!= NULL
) {
1671 PushMapExpressionList (MapExpressionList
);
1674 // Initialize new Map Expression List.
1676 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1677 InitializeListHead (MapExpressionList
);
1679 // Store current expression.
1681 PushCurrentExpression (CurrentExpression
);
1682 CurrentExpression
= NULL
;
1684 } else if (SingleOpCodeExpression
) {
1686 // There are two cases to indicate the end of an Expression:
1687 // for single OpCode expression: one Expression OpCode
1688 // for expression consists of more than one OpCode: EFI_IFR_END
1690 SingleOpCodeExpression
= FALSE
;
1692 if (InScopeDisable
&& CurrentForm
== NULL
) {
1694 // This is DisableIf expression for Form, it should be a constant expression
1696 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1697 if (EFI_ERROR (Status
)) {
1701 OpCodeDisabled
= IsTrue(&CurrentExpression
->Result
);
1704 CurrentExpression
= NULL
;
1715 case EFI_IFR_FORM_SET_OP
:
1717 // Check the formset GUID
1719 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1720 return EFI_INVALID_PARAMETER
;
1723 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1724 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1725 FormSet
->OpCode
= (EFI_IFR_OP_HEADER
*) OpCodeData
;//save the opcode address of formset
1727 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1729 // The formset OpCode contains ClassGuid
1731 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1732 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1736 case EFI_IFR_FORM_OP
:
1738 // Create a new Form for this FormSet
1740 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1741 ASSERT (CurrentForm
!= NULL
);
1742 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1743 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1744 InitializeListHead (&CurrentForm
->StatementListHead
);
1745 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1746 InitializeListHead (&CurrentForm
->FormViewListHead
);
1748 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1749 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1750 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1752 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1753 if ( ConditionalExprCount
> 0) {
1755 // Form is inside of suppressif
1757 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1758 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1759 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1760 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1761 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1762 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1767 // Enter scope of a Form, suppressif will be used for Question or Option
1769 SuppressForQuestion
= TRUE
;
1773 // Insert into Form list of this FormSet
1775 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1778 case EFI_IFR_FORM_MAP_OP
:
1780 // Create a new Form for this FormSet
1782 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1783 ASSERT (CurrentForm
!= NULL
);
1784 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1785 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1786 InitializeListHead (&CurrentForm
->StatementListHead
);
1787 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1788 InitializeListHead (&CurrentForm
->FormViewListHead
);
1790 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1792 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1794 // FormMap Form must contain at least one Map Method.
1796 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1797 return EFI_INVALID_PARAMETER
;
1800 // Try to find the standard form map method.
1802 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1803 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1804 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1805 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1811 // If the standard form map method is not found, the first map method title will be used.
1813 if (CurrentForm
->FormTitle
== 0) {
1814 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1815 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1818 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1819 if ( ConditionalExprCount
> 0) {
1821 // Form is inside of suppressif
1823 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1824 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1825 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1826 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1827 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1828 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1833 // Enter scope of a Form, suppressif will be used for Question or Option
1835 SuppressForQuestion
= TRUE
;
1839 // Insert into Form list of this FormSet
1841 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1847 case EFI_IFR_VARSTORE_OP
:
1849 // Create a buffer Storage for this FormSet
1851 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_BUFFER
, OpCodeData
);
1852 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1855 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1857 // Create a name/value Storage for this FormSet
1859 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_NAME_VALUE
, OpCodeData
);
1860 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1863 case EFI_IFR_VARSTORE_EFI_OP
:
1865 // Create a EFI variable Storage for this FormSet
1867 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1869 // Create efi varstore with format follow UEFI spec before 2.3.1.
1871 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE
, OpCodeData
);
1874 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1876 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
, OpCodeData
);
1878 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1884 case EFI_IFR_DEFAULTSTORE_OP
:
1885 HaveInserted
= FALSE
;
1886 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1887 ASSERT (DefaultStore
!= NULL
);
1888 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1890 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1891 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1893 // Insert it to the DefaultStore list of this Formset with ascending order.
1895 if (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
1896 DefaultLink
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
1897 while (!IsNull (&FormSet
->DefaultStoreListHead
, DefaultLink
)) {
1898 PreDefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink
);
1899 DefaultLink
= GetNextNode (&FormSet
->DefaultStoreListHead
, DefaultLink
);
1900 if (DefaultStore
->DefaultId
< PreDefaultStore
->DefaultId
) {
1901 InsertTailList (&PreDefaultStore
->Link
, &DefaultStore
->Link
);
1902 HaveInserted
= TRUE
;
1907 if (!HaveInserted
) {
1908 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1915 case EFI_IFR_SUBTITLE_OP
:
1916 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1917 ASSERT (CurrentStatement
!= NULL
);
1919 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1920 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1923 case EFI_IFR_TEXT_OP
:
1924 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1925 ASSERT (CurrentStatement
!= NULL
);
1926 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1927 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1930 case EFI_IFR_RESET_BUTTON_OP
:
1931 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1932 ASSERT (CurrentStatement
!= NULL
);
1933 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1934 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1940 case EFI_IFR_ACTION_OP
:
1941 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1942 ASSERT (CurrentStatement
!= NULL
);
1943 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1945 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1947 // No QuestionConfig present, so no configuration string will be processed
1949 CurrentStatement
->QuestionConfig
= 0;
1951 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1955 case EFI_IFR_REF_OP
:
1956 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1957 ASSERT (CurrentStatement
!= NULL
);
1958 Value
= &CurrentStatement
->HiiValue
;
1959 Value
->Type
= EFI_IFR_TYPE_REF
;
1960 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1961 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1963 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1964 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1966 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1967 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1969 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1970 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1975 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
1976 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1979 case EFI_IFR_ONE_OF_OP
:
1980 case EFI_IFR_NUMERIC_OP
:
1981 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1982 ASSERT(CurrentStatement
!= NULL
);
1984 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1985 Value
= &CurrentStatement
->HiiValue
;
1987 if (QuestionReferBitField
) {
1989 // Get the bit var store info (bit/byte offset, bit/byte offset)
1991 CurrentStatement
->QuestionReferToBitField
= TRUE
;
1992 CurrentStatement
->BitStorageWidth
= CurrentStatement
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
1993 CurrentStatement
->BitVarOffset
= CurrentStatement
->VarStoreInfo
.VarOffset
;
1994 CurrentStatement
->VarStoreInfo
.VarOffset
= CurrentStatement
->BitVarOffset
/ 8;
1995 TotalBits
= CurrentStatement
->BitVarOffset
% 8 + CurrentStatement
->BitStorageWidth
;
1996 CurrentStatement
->StorageWidth
= (TotalBits
% 8 == 0? TotalBits
/ 8: TotalBits
/ 8 + 1);
1999 // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)
2001 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
;
2002 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
;
2003 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
;
2006 // Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,
2007 // in order to make Browser handle these question with bit varstore correctly.
2009 ((EFI_IFR_NUMERIC
*) OpCodeData
)->Flags
&= EDKII_IFR_DISPLAY_BIT
;
2010 ((EFI_IFR_NUMERIC
*) OpCodeData
)->Flags
>>= 2;
2011 switch (CurrentStatement
->StorageWidth
) {
2013 ((EFI_IFR_NUMERIC
*) OpCodeData
)->Flags
|= EFI_IFR_TYPE_NUM_SIZE_8
;
2014 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
= (UINT8
)CurrentStatement
->Minimum
;
2015 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
= (UINT8
)CurrentStatement
->Maximum
;
2016 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
= (UINT8
)CurrentStatement
->Step
;
2017 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
2020 ((EFI_IFR_NUMERIC
*) OpCodeData
)->Flags
|= EFI_IFR_TYPE_NUM_SIZE_16
;
2021 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
= (UINT16
)CurrentStatement
->Minimum
;
2022 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
= (UINT16
)CurrentStatement
->Maximum
;
2023 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
= (UINT16
)CurrentStatement
->Step
;
2024 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
2028 ((EFI_IFR_NUMERIC
*) OpCodeData
)->Flags
|= EFI_IFR_TYPE_NUM_SIZE_32
;
2029 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
= (UINT32
)CurrentStatement
->Minimum
;
2030 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
= (UINT32
)CurrentStatement
->Maximum
;
2031 ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
= (UINT32
)CurrentStatement
->Step
;
2032 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
2038 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
2039 case EFI_IFR_NUMERIC_SIZE_1
:
2040 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
2041 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
2042 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
2043 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
2044 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
2047 case EFI_IFR_NUMERIC_SIZE_2
:
2048 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
2049 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
2050 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
2051 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
2052 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
2055 case EFI_IFR_NUMERIC_SIZE_4
:
2056 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
2057 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
2058 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
2059 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
2060 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
2063 case EFI_IFR_NUMERIC_SIZE_8
:
2064 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
2065 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
2066 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
2067 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
2068 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
2075 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2077 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
2078 SuppressForOption
= TRUE
;
2082 case EFI_IFR_ORDERED_LIST_OP
:
2083 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2084 ASSERT(CurrentStatement
!= NULL
);
2086 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
2087 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
2089 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
2090 CurrentStatement
->BufferValue
= NULL
;
2093 SuppressForOption
= TRUE
;
2097 case EFI_IFR_CHECKBOX_OP
:
2098 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2099 ASSERT(CurrentStatement
!= NULL
);
2101 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
2102 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
2103 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
2105 if (QuestionReferBitField
) {
2107 // Get the bit var store info (bit/byte offset, bit/byte offset)
2109 CurrentStatement
->QuestionReferToBitField
= TRUE
;
2110 CurrentStatement
->BitStorageWidth
= 1;
2111 CurrentStatement
->BitVarOffset
= CurrentStatement
->VarStoreInfo
.VarOffset
;
2112 CurrentStatement
->VarStoreInfo
.VarOffset
= CurrentStatement
->BitVarOffset
/ 8;
2113 TotalBits
= CurrentStatement
->BitVarOffset
% 8 + CurrentStatement
->BitStorageWidth
;
2114 CurrentStatement
->StorageWidth
= (TotalBits
% 8 == 0? TotalBits
/ 8: TotalBits
/ 8 + 1);
2117 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2121 case EFI_IFR_STRING_OP
:
2122 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2123 ASSERT (CurrentStatement
!= NULL
);
2125 // MinSize is the minimum number of characters that can be accepted for this opcode,
2126 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2127 // The characters are stored as Unicode, so the storage width should multiply 2.
2129 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
2130 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
2131 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
2132 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
2134 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
2135 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
2136 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
2138 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2141 case EFI_IFR_PASSWORD_OP
:
2142 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2143 ASSERT (CurrentStatement
!= NULL
);
2145 // MinSize is the minimum number of characters that can be accepted for this opcode,
2146 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2147 // The characters are stored as Unicode, so the storage width should multiply 2.
2149 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
2150 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
2151 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
2153 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
2154 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
2155 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
2157 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2160 case EFI_IFR_DATE_OP
:
2161 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2162 ASSERT(CurrentStatement
!= NULL
);
2164 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
2165 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
2167 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
2168 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
2170 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2173 // Don't assign storage for RTC type of date/time
2175 CurrentStatement
->Storage
= NULL
;
2176 CurrentStatement
->StorageWidth
= 0;
2180 case EFI_IFR_TIME_OP
:
2181 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2182 ASSERT(CurrentStatement
!= NULL
);
2184 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
2185 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
2187 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
2188 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
2190 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2193 // Don't assign storage for RTC type of date/time
2195 CurrentStatement
->Storage
= NULL
;
2196 CurrentStatement
->StorageWidth
= 0;
2203 case EFI_IFR_DEFAULT_OP
:
2205 // EFI_IFR_DEFAULT appear in scope of a Question,
2206 // It creates a default value for the current question.
2207 // A Question may have more than one Default value which have different default types.
2209 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
2210 ASSERT (CurrentDefault
!= NULL
);
2211 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
2213 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
2214 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
2215 if (CurrentDefault
->Value
.Type
== EFI_IFR_TYPE_BUFFER
) {
2216 CurrentDefault
->Value
.BufferLen
= (UINT16
) (OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
2217 CurrentDefault
->Value
.Buffer
= AllocateCopyPool (CurrentDefault
->Value
.BufferLen
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
);
2218 ASSERT (CurrentDefault
->Value
.Buffer
!= NULL
);
2220 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
2221 ExtendValueToU64 (&CurrentDefault
->Value
);
2225 // Insert to Default Value list of current Question
2227 InsertTailList (&ParentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2230 InScopeDefault
= TRUE
;
2237 case EFI_IFR_ONE_OF_OPTION_OP
:
2238 ASSERT (ParentStatement
!= NULL
);
2239 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)) {
2241 // It's keep the default value for ordered list opcode.
2243 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
2244 ASSERT (CurrentDefault
!= NULL
);
2245 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
2247 CurrentDefault
->Value
.Type
= EFI_IFR_TYPE_BUFFER
;
2248 if ((((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2249 CurrentDefault
->DefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2251 CurrentDefault
->DefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2254 CurrentDefault
->Value
.BufferLen
= (UINT16
) (OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
2255 CurrentDefault
->Value
.Buffer
= AllocateCopyPool (CurrentDefault
->Value
.BufferLen
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
);
2256 ASSERT (CurrentDefault
->Value
.Buffer
!= NULL
);
2259 // Insert to Default Value list of current Question
2261 InsertTailList (&ParentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2266 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
2267 // It create a selection for use in current Question.
2269 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
2270 ASSERT (CurrentOption
!= NULL
);
2271 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
2272 CurrentOption
->OpCode
= (EFI_IFR_ONE_OF_OPTION
*) OpCodeData
;
2274 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
2275 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
2276 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
2277 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
2278 ExtendValueToU64 (&CurrentOption
->Value
);
2280 ConditionalExprCount
= GetConditionalExpressionCount(ExpressOption
);
2281 if ( ConditionalExprCount
> 0) {
2283 // Form is inside of suppressif
2285 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
2286 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
2287 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
2288 CurrentOption
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
2289 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
2290 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressOption
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
2294 // Insert to Option list of current Question
2296 InsertTailList (&ParentStatement
->OptionListHead
, &CurrentOption
->Link
);
2298 // Now we know the Storage width of nested Ordered List
2300 if ((ParentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (ParentStatement
->BufferValue
== NULL
)) {
2302 switch (CurrentOption
->Value
.Type
) {
2303 case EFI_IFR_TYPE_NUM_SIZE_8
:
2307 case EFI_IFR_TYPE_NUM_SIZE_16
:
2311 case EFI_IFR_TYPE_NUM_SIZE_32
:
2315 case EFI_IFR_TYPE_NUM_SIZE_64
:
2321 // Invalid type for Ordered List
2326 ParentStatement
->StorageWidth
= (UINT16
) (ParentStatement
->MaxContainers
* Width
);
2327 ParentStatement
->BufferValue
= AllocateZeroPool (ParentStatement
->StorageWidth
);
2328 ParentStatement
->ValueType
= CurrentOption
->Value
.Type
;
2329 if (ParentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
2330 ParentStatement
->HiiValue
.Buffer
= ParentStatement
->BufferValue
;
2331 ParentStatement
->HiiValue
.BufferLen
= ParentStatement
->StorageWidth
;
2334 InitializeRequestElement (FormSet
, ParentStatement
, CurrentForm
);
2341 case EFI_IFR_NO_SUBMIT_IF_OP
:
2342 case EFI_IFR_INCONSISTENT_IF_OP
:
2344 // Create an Expression node
2346 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2347 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
2349 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
2350 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
2351 InsertTailList (&ParentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
2353 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
2354 InsertTailList (&ParentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
2358 // Take a look at next OpCode to see whether current expression consists
2361 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2362 SingleOpCodeExpression
= TRUE
;
2366 case EFI_IFR_WARNING_IF_OP
:
2368 // Create an Expression node
2370 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2371 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_WARNING_IF
*) OpCodeData
)->Warning
, sizeof (EFI_STRING_ID
));
2372 CurrentExpression
->TimeOut
= ((EFI_IFR_WARNING_IF
*) OpCodeData
)->TimeOut
;
2373 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WARNING_IF
;
2374 InsertTailList (&ParentStatement
->WarningListHead
, &CurrentExpression
->Link
);
2377 // Take a look at next OpCode to see whether current expression consists
2380 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2381 SingleOpCodeExpression
= TRUE
;
2385 case EFI_IFR_SUPPRESS_IF_OP
:
2387 // Question and Option will appear in scope of this OpCode
2389 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2390 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
2392 if (CurrentForm
== NULL
) {
2393 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
2395 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2398 if (SuppressForOption
) {
2399 PushConditionalExpression(CurrentExpression
, ExpressOption
);
2400 } else if (SuppressForQuestion
) {
2401 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2403 PushConditionalExpression(CurrentExpression
, ExpressForm
);
2407 // Take a look at next OpCode to see whether current expression consists
2410 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2411 SingleOpCodeExpression
= TRUE
;
2415 case EFI_IFR_GRAY_OUT_IF_OP
:
2417 // Questions will appear in scope of this OpCode
2419 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2420 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
2421 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2422 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2425 // Take a look at next OpCode to see whether current expression consists
2428 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2429 SingleOpCodeExpression
= TRUE
;
2433 case EFI_IFR_DISABLE_IF_OP
:
2435 // The DisableIf expression should only rely on constant, so it could be
2436 // evaluated at initialization and it will not be queued
2438 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
2439 ASSERT (CurrentExpression
!= NULL
);
2440 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
2441 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
2442 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
2444 if (CurrentForm
!= NULL
) {
2446 // This is DisableIf for Question, enqueue it to Form expression list
2448 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2449 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2452 OpCodeDisabled
= FALSE
;
2453 InScopeDisable
= TRUE
;
2455 // Take a look at next OpCode to see whether current expression consists
2458 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2459 SingleOpCodeExpression
= TRUE
;
2466 case EFI_IFR_VALUE_OP
:
2467 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2468 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
2469 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2471 if (InScopeDefault
) {
2473 // Used for default (EFI_IFR_DEFAULT)
2475 CurrentDefault
->ValueExpression
= CurrentExpression
;
2478 // If used for a question, then the question will be read-only
2481 // Make sure CurrentStatement is not NULL.
2482 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2483 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2485 ASSERT (ParentStatement
!= NULL
);
2486 ParentStatement
->ValueExpression
= CurrentExpression
;
2490 // Take a look at next OpCode to see whether current expression consists
2493 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2494 SingleOpCodeExpression
= TRUE
;
2498 case EFI_IFR_RULE_OP
:
2499 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2500 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2502 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2503 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2506 // Take a look at next OpCode to see whether current expression consists
2509 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2510 SingleOpCodeExpression
= TRUE
;
2514 case EFI_IFR_READ_OP
:
2515 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2516 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2517 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2520 // Make sure CurrentStatement is not NULL.
2521 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2522 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2524 ASSERT (ParentStatement
!= NULL
);
2525 ParentStatement
->ReadExpression
= CurrentExpression
;
2528 // Take a look at next OpCode to see whether current expression consists
2531 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2532 SingleOpCodeExpression
= TRUE
;
2536 case EFI_IFR_WRITE_OP
:
2537 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2538 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2539 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2542 // Make sure CurrentStatement is not NULL.
2543 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2544 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2546 ASSERT (ParentStatement
!= NULL
);
2547 ParentStatement
->WriteExpression
= CurrentExpression
;
2550 // Take a look at next OpCode to see whether current expression consists
2553 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2554 SingleOpCodeExpression
= TRUE
;
2561 case EFI_IFR_IMAGE_OP
:
2563 // Get ScopeOpcode from top of stack
2565 PopScope (&ScopeOpCode
);
2566 PushScope (ScopeOpCode
);
2568 switch (ScopeOpCode
) {
2569 case EFI_IFR_FORM_SET_OP
:
2570 ImageId
= &FormSet
->ImageId
;
2573 case EFI_IFR_FORM_OP
:
2574 case EFI_IFR_FORM_MAP_OP
:
2575 ASSERT (CurrentForm
!= NULL
);
2576 ImageId
= &CurrentForm
->ImageId
;
2579 case EFI_IFR_ONE_OF_OPTION_OP
:
2580 ASSERT (CurrentOption
!= NULL
);
2581 ImageId
= &CurrentOption
->ImageId
;
2586 // Make sure CurrentStatement is not NULL.
2587 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2588 // file is wrongly generated by tools such as VFR Compiler.
2590 ASSERT (ParentStatement
!= NULL
);
2591 ImageId
= &ParentStatement
->ImageId
;
2595 ASSERT (ImageId
!= NULL
);
2596 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2602 case EFI_IFR_REFRESH_OP
:
2603 ASSERT (ParentStatement
!= NULL
);
2604 ParentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2610 case EFI_IFR_REFRESH_ID_OP
:
2612 // Get ScopeOpcode from top of stack
2614 PopScope (&ScopeOpCode
);
2615 PushScope (ScopeOpCode
);
2617 switch (ScopeOpCode
) {
2618 case EFI_IFR_FORM_OP
:
2619 case EFI_IFR_FORM_MAP_OP
:
2620 ASSERT (CurrentForm
!= NULL
);
2621 CopyMem (&CurrentForm
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2625 ASSERT (ParentStatement
!= NULL
);
2626 CopyMem (&ParentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2634 case EFI_IFR_MODAL_TAG_OP
:
2635 ASSERT (CurrentForm
!= NULL
);
2636 CurrentForm
->ModalForm
= TRUE
;
2640 // Lock tag, used by form and statement.
2642 case EFI_IFR_LOCKED_OP
:
2644 // Get ScopeOpcode from top of stack
2646 PopScope (&ScopeOpCode
);
2647 PushScope (ScopeOpCode
);
2648 switch (ScopeOpCode
) {
2649 case EFI_IFR_FORM_OP
:
2650 case EFI_IFR_FORM_MAP_OP
:
2651 ASSERT (CurrentForm
!= NULL
);
2652 CurrentForm
->Locked
= TRUE
;
2656 ASSERT (ParentStatement
!= NULL
);
2657 ParentStatement
->Locked
= TRUE
;
2664 case EFI_IFR_GUID_OP
:
2665 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2666 if (CompareGuid ((EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
2668 QuestionReferBitField
= TRUE
;
2675 case EFI_IFR_END_OP
:
2676 QuestionReferBitField
= FALSE
;
2677 Status
= PopScope (&ScopeOpCode
);
2678 if (EFI_ERROR (Status
)) {
2684 // Parent statement end tag found, update ParentStatement info.
2686 if (IsStatementOpCode(ScopeOpCode
) && (ParentStatement
!= NULL
) && (ParentStatement
->Operand
== ScopeOpCode
)) {
2687 ParentStatement
= ParentStatement
->ParentStatement
;
2690 switch (ScopeOpCode
) {
2691 case EFI_IFR_FORM_SET_OP
:
2693 // End of FormSet, update FormSet IFR binary length
2694 // to stop parsing substantial OpCodes
2696 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2699 case EFI_IFR_FORM_OP
:
2700 case EFI_IFR_FORM_MAP_OP
:
2705 SuppressForQuestion
= FALSE
;
2708 case EFI_IFR_ONE_OF_OPTION_OP
:
2712 CurrentOption
= NULL
;
2715 case EFI_IFR_NO_SUBMIT_IF_OP
:
2716 case EFI_IFR_INCONSISTENT_IF_OP
:
2717 case EFI_IFR_WARNING_IF_OP
:
2719 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2723 case EFI_IFR_SUPPRESS_IF_OP
:
2724 if (SuppressForOption
) {
2725 PopConditionalExpression(ExpressOption
);
2726 } else if (SuppressForQuestion
) {
2727 PopConditionalExpression(ExpressStatement
);
2729 PopConditionalExpression(ExpressForm
);
2733 case EFI_IFR_GRAY_OUT_IF_OP
:
2734 PopConditionalExpression(ExpressStatement
);
2737 case EFI_IFR_DISABLE_IF_OP
:
2738 if (CurrentForm
!= NULL
) {
2739 PopConditionalExpression(ExpressStatement
);
2741 InScopeDisable
= FALSE
;
2742 OpCodeDisabled
= FALSE
;
2745 case EFI_IFR_ONE_OF_OP
:
2746 case EFI_IFR_ORDERED_LIST_OP
:
2747 SuppressForOption
= FALSE
;
2750 case EFI_IFR_DEFAULT_OP
:
2751 InScopeDefault
= FALSE
;
2754 case EFI_IFR_MAP_OP
:
2756 // Get current Map Expression List.
2758 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2759 if (Status
== EFI_ACCESS_DENIED
) {
2760 MapExpressionList
= NULL
;
2763 // Get current expression.
2765 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2766 ASSERT_EFI_ERROR (Status
);
2767 ASSERT (MapScopeDepth
> 0);
2772 if (IsExpressionOpCode (ScopeOpCode
)) {
2773 if (InScopeDisable
&& CurrentForm
== NULL
) {
2775 // This is DisableIf expression for Form, it should be a constant expression
2777 ASSERT (CurrentExpression
!= NULL
);
2778 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2779 if (EFI_ERROR (Status
)) {
2783 OpCodeDisabled
= IsTrue (&CurrentExpression
->Result
);
2786 // DisableIf Expression is only used once and not queued, free it
2788 DestroyExpression (CurrentExpression
);
2792 // End of current Expression
2794 CurrentExpression
= NULL
;
2804 if (IsStatementOpCode(Operand
)) {
2805 CurrentStatement
->ParentStatement
= ParentStatement
;
2808 // Scope != 0, other statements or options may nest in this statement.
2809 // Update the ParentStatement info.
2811 ParentStatement
= CurrentStatement
;