2 Parser for IFR binary encoding.
4 Copyright (c) 2007 - 2013, 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 FormSe.
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
;
63 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
64 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
65 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
67 ConditionalExprCount
= GetConditionalExpressionCount(ExpressStatement
);
68 if (ConditionalExprCount
> 0) {
70 // Form is inside of suppressif
73 Statement
->Expression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
74 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
75 ASSERT (Statement
->Expression
!= NULL
);
76 Statement
->Expression
->Count
= (UINTN
) ConditionalExprCount
;
77 Statement
->Expression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
78 CopyMem (Statement
->Expression
->Expression
, GetConditionalExpressionList(ExpressStatement
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
82 // Insert this Statement into current Form
85 InsertTailList (&FormSet
->StatementListOSF
, &Statement
->Link
);
87 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
93 Convert a numeric value to a Unicode String and insert it to String Package.
94 This string is used as the Unicode Name for the EFI Variable. This is to support
95 the deprecated vareqval opcode.
97 @param FormSet The FormSet.
98 @param Statement The numeric question whose VarStoreInfo.VarName is the
99 numeric value which is used to produce the Unicode Name
100 for the EFI Variable.
102 If the Statement is NULL, the ASSERT.
103 If the opcode is not Numeric, then ASSERT.
105 @retval EFI_SUCCESS The funtion always succeeds.
108 UpdateCheckBoxStringToken (
109 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
110 IN FORM_BROWSER_STATEMENT
*Statement
113 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
116 ASSERT (Statement
!= NULL
);
117 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
119 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
121 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
123 return EFI_OUT_OF_RESOURCES
;
126 Statement
->VarStoreInfo
.VarName
= Id
;
132 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
134 @param OpCodeData The current opcode.
140 IsNextOpCodeGuidedVarEqName (
147 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
148 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
149 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
151 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
153 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
163 Initialize Question's members.
165 @param OpCodeData Pointer of the raw OpCode data.
166 @param FormSet Pointer of the current FormSet.
167 @param Form Pointer of the current Form.
169 @return The Question.
172 FORM_BROWSER_STATEMENT
*
174 IN UINT8
*OpCodeData
,
175 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
176 IN OUT FORM_BROWSER_FORM
*Form
179 FORM_BROWSER_STATEMENT
*Statement
;
180 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
182 FORMSET_STORAGE
*Storage
;
183 NAME_VALUE_NODE
*NameValueNode
;
187 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
188 if (Statement
== NULL
) {
192 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
193 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
194 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
195 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
197 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
199 if (Statement
->VarStoreId
== 0) {
201 // VarStoreId of zero indicates no variable storage
207 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
208 // Framework Compatibility
210 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
211 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
212 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
213 if (EFI_ERROR (Status
)) {
220 // Find Storage for this Question
222 Link
= GetFirstNode (&FormSet
->StorageListHead
);
223 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
224 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
226 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
227 Statement
->Storage
= Storage
->BrowserStorage
;
231 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
233 ASSERT (Statement
->Storage
!= NULL
);
236 // Initialilze varname for Name/Value or EFI Variable
238 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
239 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
240 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
241 ASSERT (Statement
->VariableName
!= NULL
);
243 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
245 // Check whether old string node already exist.
248 if (!IsListEmpty(&Statement
->Storage
->NameValueListHead
)) {
249 Link
= GetFirstNode (&Statement
->Storage
->NameValueListHead
);
250 while (!IsNull (&Statement
->Storage
->NameValueListHead
, Link
)) {
251 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
253 if (StrCmp (Statement
->VariableName
, NameValueNode
->Name
) == 0) {
258 Link
= GetNextNode (&Statement
->Storage
->NameValueListHead
, Link
);
264 // Insert to Name/Value varstore list
266 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
267 ASSERT (NameValueNode
!= NULL
);
268 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
269 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
270 ASSERT (NameValueNode
->Name
!= NULL
);
271 NameValueNode
->Value
= AllocateZeroPool (0x10);
272 ASSERT (NameValueNode
->Value
!= NULL
);
273 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
274 ASSERT (NameValueNode
->EditValue
!= NULL
);
276 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
286 Allocate a FORM_EXPRESSION node.
288 @param Form The Form associated with this Expression
289 @param OpCode The binary opcode data.
291 @return Pointer to a FORM_EXPRESSION data structure.
296 IN OUT FORM_BROWSER_FORM
*Form
,
300 FORM_EXPRESSION
*Expression
;
302 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
303 ASSERT (Expression
!= NULL
);
304 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
305 InitializeListHead (&Expression
->OpCodeListHead
);
306 Expression
->OpCode
= (EFI_IFR_OP_HEADER
*) OpCode
;
312 Create ConfigHdr string for a storage.
314 @param FormSet Pointer of the current FormSet
315 @param Storage Pointer of the storage
317 @retval EFI_SUCCESS Initialize ConfigHdr success
321 InitializeConfigHdr (
322 IN FORM_BROWSER_FORMSET
*FormSet
,
323 IN OUT BROWSER_STORAGE
*Storage
328 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
329 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
330 Name
= Storage
->Name
;
335 Storage
->ConfigHdr
= HiiConstructConfigHdr (
338 FormSet
->DriverHandle
341 if (Storage
->ConfigHdr
== NULL
) {
342 return EFI_NOT_FOUND
;
349 Find the global storage link base on the input storate type, name and guid.
351 For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
352 same guid + name = same storage
354 For EFI_HII_VARSTORE_NAME_VALUE:
355 same guid + HiiHandle = same storage
357 For EFI_HII_VARSTORE_BUFFER:
358 same guid + name + HiiHandle = same storage
360 @param StorageType Storage type.
361 @param StorageGuid Storage guid.
362 @param StorageName Storage Name.
363 @param HiiHandle HiiHandle for this varstore.
365 @return Pointer to a GLOBAL_STORAGE data structure.
370 IN UINT8 StorageType
,
371 IN EFI_GUID
*StorageGuid
,
372 IN CHAR16
*StorageName
,
373 IN EFI_HII_HANDLE HiiHandle
377 BROWSER_STORAGE
*BrowserStorage
;
379 Link
= GetFirstNode (&gBrowserStorageList
);
380 while (!IsNull (&gBrowserStorageList
, Link
)) {
381 BrowserStorage
= BROWSER_STORAGE_FROM_LINK (Link
);
382 Link
= GetNextNode (&gBrowserStorageList
, Link
);
384 if ((BrowserStorage
->Type
== StorageType
) && CompareGuid (&BrowserStorage
->Guid
, StorageGuid
)) {
385 if (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
) {
386 if (BrowserStorage
->HiiHandle
== HiiHandle
) {
387 return BrowserStorage
;
393 ASSERT (StorageName
!= NULL
);
394 if (StrCmp (BrowserStorage
->Name
, StorageName
) == 0) {
395 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE
|| StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
396 return BrowserStorage
;
397 } else if (StorageType
== EFI_HII_VARSTORE_BUFFER
&& BrowserStorage
->HiiHandle
== HiiHandle
) {
398 return BrowserStorage
;
408 Intialize the Global Storage.
410 @param BrowserStorage Pointer to the global storage.
411 @param StorageType Storage type.
412 @param OpCodeData Binary data for this opcode.
416 IntializeBrowserStorage (
417 IN BROWSER_STORAGE
*BrowserStorage
,
418 IN UINT8 StorageType
,
422 switch (StorageType
) {
423 case EFI_HII_VARSTORE_BUFFER
:
424 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
425 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
427 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
428 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
431 case EFI_HII_VARSTORE_EFI_VARIABLE
:
432 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
433 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
434 CopyMem (&BrowserStorage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
435 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
437 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
438 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
439 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
443 case EFI_HII_VARSTORE_NAME_VALUE
:
444 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
446 InitializeListHead (&BrowserStorage
->NameValueListHead
);
455 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
457 @param FormSet Pointer of the current FormSet
458 @param StorageType Storage type.
459 @param OpCodeData Binary data for this opcode.
461 @return Pointer to a FORMSET_STORAGE data structure.
466 IN FORM_BROWSER_FORMSET
*FormSet
,
467 IN UINT8 StorageType
,
471 FORMSET_STORAGE
*Storage
;
472 CHAR16
*UnicodeString
;
474 BROWSER_STORAGE
*BrowserStorage
;
475 EFI_GUID
*StorageGuid
;
478 UnicodeString
= NULL
;
480 switch (StorageType
) {
481 case EFI_HII_VARSTORE_BUFFER
:
482 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
;
483 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
486 case EFI_HII_VARSTORE_EFI_VARIABLE
:
487 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
488 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
;
489 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
493 ASSERT (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
);
494 StorageGuid
= &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
;
498 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
499 ASSERT (StorageName
!= NULL
);
501 UnicodeString
= AllocateZeroPool (AsciiStrSize (StorageName
) * 2);
502 ASSERT (UnicodeString
!= NULL
);
503 for (Index
= 0; StorageName
[Index
] != 0; Index
++) {
504 UnicodeString
[Index
] = (CHAR16
) StorageName
[Index
];
508 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
509 ASSERT (Storage
!= NULL
);
510 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
511 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
513 BrowserStorage
= FindStorageInList(StorageType
, StorageGuid
, UnicodeString
, FormSet
->HiiHandle
);
514 if (BrowserStorage
== NULL
) {
515 BrowserStorage
= AllocateZeroPool (sizeof (BROWSER_STORAGE
));
516 ASSERT (BrowserStorage
!= NULL
);
518 BrowserStorage
->Signature
= BROWSER_STORAGE_SIGNATURE
;
519 InsertTailList (&gBrowserStorageList
, &BrowserStorage
->Link
);
521 IntializeBrowserStorage (BrowserStorage
, StorageType
, OpCodeData
);
522 BrowserStorage
->Type
= StorageType
;
523 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
524 BrowserStorage
->Name
= UnicodeString
;
527 BrowserStorage
->HiiHandle
= FormSet
->HiiHandle
;
528 InitializeConfigHdr (FormSet
, BrowserStorage
);
530 BrowserStorage
->Initialized
= FALSE
;
533 Storage
->BrowserStorage
= BrowserStorage
;
534 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (BrowserStorage
->ConfigHdr
), BrowserStorage
->ConfigHdr
);
535 Storage
->SpareStrLen
= 0;
541 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
543 @param FormSet Pointer of the current FormSet.
544 @param Question The Question to be initialized.
545 @param Form Pointer of the current form.
547 @retval EFI_SUCCESS Function success.
548 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
552 InitializeRequestElement (
553 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
554 IN OUT FORM_BROWSER_STATEMENT
*Question
,
555 IN OUT FORM_BROWSER_FORM
*Form
558 BROWSER_STORAGE
*Storage
;
559 FORMSET_STORAGE
*FormsetStorage
;
563 CHAR16 RequestElement
[30];
566 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
568 Storage
= Question
->Storage
;
569 if (Storage
== NULL
) {
570 return EFI_INVALID_PARAMETER
;
573 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
575 // <ConfigRequest> is unnecessary for EFI variable storage,
576 // GetVariable()/SetVariable() will be used to retrieve/save values
582 // Prepare <RequestElement>
584 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
585 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
586 StrLen
= UnicodeSPrint (
588 30 * sizeof (CHAR16
),
589 L
"&OFFSET=%x&WIDTH=%x",
590 Question
->VarStoreInfo
.VarOffset
,
591 Question
->StorageWidth
593 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
595 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
598 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
600 // Password with CALLBACK flag is stored in encoded format,
601 // so don't need to append it to <ConfigRequest>
607 // Find Formset Storage for this Question
609 FormsetStorage
= NULL
;
610 Link
= GetFirstNode (&FormSet
->StorageListHead
);
611 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
612 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
614 if (FormsetStorage
->VarStoreId
== Question
->VarStoreId
) {
618 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
620 ASSERT (FormsetStorage
!= NULL
);
623 // Append <RequestElement> to <ConfigRequest>
625 if (StrLen
> FormsetStorage
->SpareStrLen
) {
627 // Old String buffer is not sufficient for RequestElement, allocate a new one
629 StringSize
= (FormsetStorage
->ConfigRequest
!= NULL
) ? StrSize (FormsetStorage
->ConfigRequest
) : sizeof (CHAR16
);
630 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
631 ASSERT (NewStr
!= NULL
);
632 if (FormsetStorage
->ConfigRequest
!= NULL
) {
633 CopyMem (NewStr
, FormsetStorage
->ConfigRequest
, StringSize
);
634 FreePool (FormsetStorage
->ConfigRequest
);
636 FormsetStorage
->ConfigRequest
= NewStr
;
637 FormsetStorage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
640 StrCat (FormsetStorage
->ConfigRequest
, RequestElement
);
641 FormsetStorage
->ElementCount
++;
642 FormsetStorage
->SpareStrLen
-= StrLen
;
645 // Update the Config Request info saved in the form.
649 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
650 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
651 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
653 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
== Storage
) {
658 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
662 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
663 ASSERT (ConfigInfo
!= NULL
);
664 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
665 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
666 ConfigInfo
->SpareStrLen
= 0;
667 ConfigInfo
->Storage
= Storage
;
668 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
672 // Append <RequestElement> to <ConfigRequest>
674 if (StrLen
> ConfigInfo
->SpareStrLen
) {
676 // Old String buffer is not sufficient for RequestElement, allocate a new one
678 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
679 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
680 ASSERT (NewStr
!= NULL
);
681 if (ConfigInfo
->ConfigRequest
!= NULL
) {
682 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
683 FreePool (ConfigInfo
->ConfigRequest
);
685 ConfigInfo
->ConfigRequest
= NewStr
;
686 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
689 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
690 ConfigInfo
->ElementCount
++;
691 ConfigInfo
->SpareStrLen
-= StrLen
;
697 Free resources of a Expression.
699 @param FormSet Pointer of the Expression
704 IN FORM_EXPRESSION
*Expression
708 EXPRESSION_OPCODE
*OpCode
;
709 LIST_ENTRY
*SubExpressionLink
;
710 FORM_EXPRESSION
*SubExpression
;
712 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
713 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
714 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
715 RemoveEntryList (&OpCode
->Link
);
717 if (OpCode
->ValueList
!= NULL
) {
718 FreePool (OpCode
->ValueList
);
721 if (OpCode
->ValueName
!= NULL
) {
722 FreePool (OpCode
->ValueName
);
725 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
726 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
727 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
728 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
729 RemoveEntryList(&SubExpression
->Link
);
730 DestroyExpression (SubExpression
);
736 // Free this Expression
738 FreePool (Expression
);
742 Free resources of a storage.
744 @param Storage Pointer of the storage
749 IN FORMSET_STORAGE
*Storage
752 if (Storage
== NULL
) {
756 if (Storage
->ConfigRequest
!= NULL
) {
757 FreePool (Storage
->ConfigRequest
);
765 Free resources of a Statement.
767 @param FormSet Pointer of the FormSet
768 @param Statement Pointer of the Statement
773 IN FORM_BROWSER_FORMSET
*FormSet
,
774 IN OUT FORM_BROWSER_STATEMENT
*Statement
778 QUESTION_DEFAULT
*Default
;
779 QUESTION_OPTION
*Option
;
780 FORM_EXPRESSION
*Expression
;
783 // Free Default value List
785 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
786 Link
= GetFirstNode (&Statement
->DefaultListHead
);
787 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
788 RemoveEntryList (&Default
->Link
);
796 while (!IsListEmpty (&Statement
->OptionListHead
)) {
797 Link
= GetFirstNode (&Statement
->OptionListHead
);
798 Option
= QUESTION_OPTION_FROM_LINK (Link
);
799 if (Option
->SuppressExpression
!= NULL
) {
800 FreePool (Option
->SuppressExpression
);
802 RemoveEntryList (&Option
->Link
);
808 // Free Inconsistent List
810 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
811 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
812 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
813 RemoveEntryList (&Expression
->Link
);
815 DestroyExpression (Expression
);
819 // Free NoSubmit List
821 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
822 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
823 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
824 RemoveEntryList (&Expression
->Link
);
826 DestroyExpression (Expression
);
830 // Free WarningIf List
832 while (!IsListEmpty (&Statement
->WarningListHead
)) {
833 Link
= GetFirstNode (&Statement
->WarningListHead
);
834 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
835 RemoveEntryList (&Expression
->Link
);
837 DestroyExpression (Expression
);
840 if (Statement
->Expression
!= NULL
) {
841 FreePool (Statement
->Expression
);
844 if (Statement
->VariableName
!= NULL
) {
845 FreePool (Statement
->VariableName
);
847 if (Statement
->BlockName
!= NULL
) {
848 FreePool (Statement
->BlockName
);
850 if (Statement
->BufferValue
!= NULL
) {
851 FreePool (Statement
->BufferValue
);
853 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
854 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
860 Free resources of a Form.
862 @param FormSet Pointer of the FormSet
863 @param Form Pointer of the Form.
868 IN FORM_BROWSER_FORMSET
*FormSet
,
869 IN OUT FORM_BROWSER_FORM
*Form
873 FORM_EXPRESSION
*Expression
;
874 FORM_BROWSER_STATEMENT
*Statement
;
875 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
878 // Free Form Expressions
880 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
881 Link
= GetFirstNode (&Form
->ExpressionListHead
);
882 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
883 RemoveEntryList (&Expression
->Link
);
885 DestroyExpression (Expression
);
889 // Free Statements/Questions
891 while (!IsListEmpty (&Form
->StatementListHead
)) {
892 Link
= GetFirstNode (&Form
->StatementListHead
);
893 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
894 RemoveEntryList (&Statement
->Link
);
896 DestroyStatement (FormSet
, Statement
);
900 // Free ConfigRequest string.
902 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
903 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
904 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
905 RemoveEntryList (&ConfigInfo
->Link
);
907 FreePool (ConfigInfo
->ConfigRequest
);
908 FreePool (ConfigInfo
);
911 if (Form
->SuppressExpression
!= NULL
) {
912 FreePool (Form
->SuppressExpression
);
923 Free resources allocated for a FormSet.
925 @param FormSet Pointer of the FormSet
930 IN OUT FORM_BROWSER_FORMSET
*FormSet
934 FORMSET_STORAGE
*Storage
;
935 FORMSET_DEFAULTSTORE
*DefaultStore
;
936 FORM_EXPRESSION
*Expression
;
937 FORM_BROWSER_FORM
*Form
;
939 if (FormSet
->IfrBinaryData
== NULL
) {
941 // Uninitialized FormSet
948 // Free IFR binary buffer
950 FreePool (FormSet
->IfrBinaryData
);
953 // Free FormSet Storage
955 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
956 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
957 Link
= GetFirstNode (&FormSet
->StorageListHead
);
958 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
959 RemoveEntryList (&Storage
->Link
);
961 DestroyStorage (Storage
);
966 // Free FormSet Default Store
968 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
969 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
970 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
971 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
972 RemoveEntryList (&DefaultStore
->Link
);
974 FreePool (DefaultStore
);
979 // Free Formset Expressions
981 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
982 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
983 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
984 RemoveEntryList (&Expression
->Link
);
986 DestroyExpression (Expression
);
992 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
993 while (!IsListEmpty (&FormSet
->FormListHead
)) {
994 Link
= GetFirstNode (&FormSet
->FormListHead
);
995 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
996 RemoveEntryList (&Form
->Link
);
998 DestroyForm (FormSet
, Form
);
1002 if (FormSet
->StatementBuffer
!= NULL
) {
1003 FreePool (FormSet
->StatementBuffer
);
1005 if (FormSet
->ExpressionBuffer
!= NULL
) {
1006 FreePool (FormSet
->ExpressionBuffer
);
1014 Tell whether this Operand is an Expression OpCode or not
1016 @param Operand Operand of an IFR OpCode.
1018 @retval TRUE This is an Expression OpCode.
1019 @retval FALSE Not an Expression OpCode.
1023 IsExpressionOpCode (
1027 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
1028 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
1029 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
1030 (Operand
== EFI_IFR_CATENATE_OP
) ||
1031 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
1032 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
1033 (Operand
== EFI_IFR_MAP_OP
) ||
1034 (Operand
== EFI_IFR_VERSION_OP
) ||
1035 (Operand
== EFI_IFR_SECURITY_OP
)) {
1043 Tell whether this Operand is an Statement OpCode.
1045 @param Operand Operand of an IFR OpCode.
1047 @retval TRUE This is an Statement OpCode.
1048 @retval FALSE Not an Statement OpCode.
1056 if ((Operand
== EFI_IFR_SUBTITLE_OP
) ||
1057 (Operand
== EFI_IFR_TEXT_OP
) ||
1058 (Operand
== EFI_IFR_RESET_BUTTON_OP
) ||
1059 (Operand
== EFI_IFR_REF_OP
) ||
1060 (Operand
== EFI_IFR_ACTION_OP
) ||
1061 (Operand
== EFI_IFR_NUMERIC_OP
) ||
1062 (Operand
== EFI_IFR_ORDERED_LIST_OP
) ||
1063 (Operand
== EFI_IFR_CHECKBOX_OP
) ||
1064 (Operand
== EFI_IFR_STRING_OP
) ||
1065 (Operand
== EFI_IFR_PASSWORD_OP
) ||
1066 (Operand
== EFI_IFR_DATE_OP
) ||
1067 (Operand
== EFI_IFR_TIME_OP
) ||
1068 (Operand
== EFI_IFR_GUID_OP
) ||
1069 (Operand
== EFI_IFR_ONE_OF_OP
)) {
1077 Tell whether this Operand is an known OpCode.
1079 @param Operand Operand of an IFR OpCode.
1081 @retval TRUE This is an Statement OpCode.
1082 @retval FALSE Not an Statement OpCode.
1090 return Operand
> EFI_IFR_WARNING_IF_OP
? TRUE
: FALSE
;
1094 Calculate number of Statemens(Questions) and Expression OpCodes.
1096 @param FormSet The FormSet to be counted.
1097 @param NumberOfStatement Number of Statemens(Questions)
1098 @param NumberOfExpression Number of Expression OpCodes
1103 IN FORM_BROWSER_FORMSET
*FormSet
,
1104 IN OUT UINT16
*NumberOfStatement
,
1105 IN OUT UINT16
*NumberOfExpression
1108 UINT16 StatementCount
;
1109 UINT16 ExpressionCount
;
1116 ExpressionCount
= 0;
1118 while (Offset
< FormSet
->IfrBinaryLength
) {
1119 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
1120 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1121 Offset
+= OpCodeLen
;
1123 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
1130 *NumberOfStatement
= StatementCount
;
1131 *NumberOfExpression
= ExpressionCount
;
1137 Parse opcodes in the formset IFR binary.
1139 @param FormSet Pointer of the FormSet data structure.
1141 @retval EFI_SUCCESS Opcode parse success.
1142 @retval Other Opcode parse fail.
1147 IN FORM_BROWSER_FORMSET
*FormSet
1151 FORM_BROWSER_FORM
*CurrentForm
;
1152 FORM_BROWSER_STATEMENT
*CurrentStatement
;
1153 FORM_BROWSER_STATEMENT
*ParentStatement
;
1154 EXPRESSION_OPCODE
*ExpressionOpCode
;
1155 FORM_EXPRESSION
*CurrentExpression
;
1162 FORMSET_STORAGE
*Storage
;
1163 FORMSET_DEFAULTSTORE
*DefaultStore
;
1164 QUESTION_DEFAULT
*CurrentDefault
;
1165 QUESTION_OPTION
*CurrentOption
;
1167 UINT16 NumberOfStatement
;
1168 UINT16 NumberOfExpression
;
1169 EFI_IMAGE_ID
*ImageId
;
1170 BOOLEAN SuppressForQuestion
;
1171 BOOLEAN SuppressForOption
;
1172 UINT16 DepthOfDisable
;
1173 BOOLEAN OpCodeDisabled
;
1174 BOOLEAN SingleOpCodeExpression
;
1175 BOOLEAN InScopeDefault
;
1176 EFI_HII_VALUE
*Value
;
1177 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
1178 UINT8 MapScopeDepth
;
1180 FORMSET_STORAGE
*VarStorage
;
1181 LIST_ENTRY
*MapExpressionList
;
1182 EFI_VARSTORE_ID TempVarstoreId
;
1183 BOOLEAN InScopeDisable
;
1184 INTN ConditionalExprCount
;
1185 BOOLEAN InUnknownScope
;
1188 SuppressForQuestion
= FALSE
;
1189 SuppressForOption
= FALSE
;
1190 InScopeDisable
= FALSE
;
1192 OpCodeDisabled
= FALSE
;
1193 SingleOpCodeExpression
= FALSE
;
1194 InScopeDefault
= FALSE
;
1195 CurrentExpression
= NULL
;
1196 CurrentDefault
= NULL
;
1197 CurrentOption
= NULL
;
1203 MapExpressionList
= NULL
;
1205 ConditionalExprCount
= 0;
1206 InUnknownScope
= FALSE
;
1210 // Get the number of Statements and Expressions
1212 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
1214 mStatementIndex
= 0;
1215 mUsedQuestionId
= 1;
1216 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
1217 if (FormSet
->StatementBuffer
== NULL
) {
1218 return EFI_OUT_OF_RESOURCES
;
1221 mExpressionOpCodeIndex
= 0;
1222 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
1223 if (FormSet
->ExpressionBuffer
== NULL
) {
1224 return EFI_OUT_OF_RESOURCES
;
1227 InitializeListHead (&FormSet
->StatementListOSF
);
1228 InitializeListHead (&FormSet
->StorageListHead
);
1229 InitializeListHead (&FormSet
->DefaultStoreListHead
);
1230 InitializeListHead (&FormSet
->FormListHead
);
1231 InitializeListHead (&FormSet
->ExpressionListHead
);
1232 ResetCurrentExpressionStack ();
1233 ResetMapExpressionListStack ();
1236 CurrentStatement
= NULL
;
1237 ParentStatement
= NULL
;
1242 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1243 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1245 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1246 OpCodeOffset
+= OpCodeLength
;
1247 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1248 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1250 if (InUnknownScope
) {
1251 if (Operand
== EFI_IFR_END_OP
) {
1254 if (UnknownDepth
== 0) {
1255 InUnknownScope
= FALSE
;
1266 if (IsUnKnownOpCode(Operand
)) {
1268 InUnknownScope
= TRUE
;
1276 // If scope bit set, push onto scope stack
1279 PushScope (Operand
);
1282 if (OpCodeDisabled
) {
1284 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1285 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1287 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1289 } else if (Operand
== EFI_IFR_END_OP
) {
1290 Status
= PopScope (&ScopeOpCode
);
1291 if (EFI_ERROR (Status
)) {
1295 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1296 if (DepthOfDisable
== 0) {
1297 InScopeDisable
= FALSE
;
1298 OpCodeDisabled
= FALSE
;
1307 if (IsExpressionOpCode (Operand
)) {
1308 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1309 mExpressionOpCodeIndex
++;
1311 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1312 ExpressionOpCode
->Operand
= Operand
;
1313 Value
= &ExpressionOpCode
->Value
;
1316 case EFI_IFR_EQ_ID_VAL_OP
:
1317 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1319 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1320 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1323 case EFI_IFR_EQ_ID_ID_OP
:
1324 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1325 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1328 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1329 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1330 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1331 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1334 case EFI_IFR_TO_STRING_OP
:
1335 case EFI_IFR_FIND_OP
:
1336 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1339 case EFI_IFR_STRING_REF1_OP
:
1340 Value
->Type
= EFI_IFR_TYPE_STRING
;
1341 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1344 case EFI_IFR_RULE_REF_OP
:
1345 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1348 case EFI_IFR_SPAN_OP
:
1349 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1352 case EFI_IFR_THIS_OP
:
1353 ASSERT (ParentStatement
!= NULL
);
1354 ExpressionOpCode
->QuestionId
= ParentStatement
->QuestionId
;
1357 case EFI_IFR_SECURITY_OP
:
1358 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1361 case EFI_IFR_GET_OP
:
1362 case EFI_IFR_SET_OP
:
1363 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1364 if (TempVarstoreId
!= 0) {
1365 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1366 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1367 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1368 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1369 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1370 ExpressionOpCode
->VarStorage
= VarStorage
->BrowserStorage
;
1373 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1376 if (ExpressionOpCode
->VarStorage
== NULL
) {
1378 // VarStorage is not found.
1380 return EFI_INVALID_PARAMETER
;
1383 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1384 switch (ExpressionOpCode
->ValueType
) {
1385 case EFI_IFR_TYPE_BOOLEAN
:
1386 case EFI_IFR_TYPE_NUM_SIZE_8
:
1387 ExpressionOpCode
->ValueWidth
= 1;
1390 case EFI_IFR_TYPE_NUM_SIZE_16
:
1391 case EFI_IFR_TYPE_STRING
:
1392 ExpressionOpCode
->ValueWidth
= 2;
1395 case EFI_IFR_TYPE_NUM_SIZE_32
:
1396 ExpressionOpCode
->ValueWidth
= 4;
1399 case EFI_IFR_TYPE_NUM_SIZE_64
:
1400 ExpressionOpCode
->ValueWidth
= 8;
1403 case EFI_IFR_TYPE_DATE
:
1404 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1407 case EFI_IFR_TYPE_TIME
:
1408 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1411 case EFI_IFR_TYPE_REF
:
1412 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
1415 case EFI_IFR_TYPE_OTHER
:
1416 case EFI_IFR_TYPE_UNDEFINED
:
1417 case EFI_IFR_TYPE_ACTION
:
1418 case EFI_IFR_TYPE_BUFFER
:
1421 // Invalid value type for Get/Set opcode.
1423 return EFI_INVALID_PARAMETER
;
1425 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1426 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1427 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1428 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1429 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1430 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1431 if (ExpressionOpCode
->ValueName
== NULL
) {
1433 // String ID is invalid.
1435 return EFI_INVALID_PARAMETER
;
1440 case EFI_IFR_QUESTION_REF1_OP
:
1441 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1444 case EFI_IFR_QUESTION_REF3_OP
:
1445 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1446 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1448 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1449 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1457 case EFI_IFR_TRUE_OP
:
1458 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1459 Value
->Value
.b
= TRUE
;
1462 case EFI_IFR_FALSE_OP
:
1463 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1464 Value
->Value
.b
= FALSE
;
1467 case EFI_IFR_ONE_OP
:
1468 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1469 Value
->Value
.u8
= 1;
1472 case EFI_IFR_ZERO_OP
:
1473 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1474 Value
->Value
.u8
= 0;
1477 case EFI_IFR_ONES_OP
:
1478 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1479 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1482 case EFI_IFR_UINT8_OP
:
1483 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1484 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1487 case EFI_IFR_UINT16_OP
:
1488 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1489 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1492 case EFI_IFR_UINT32_OP
:
1493 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1494 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1497 case EFI_IFR_UINT64_OP
:
1498 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1499 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1502 case EFI_IFR_UNDEFINED_OP
:
1503 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1506 case EFI_IFR_VERSION_OP
:
1507 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1508 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1515 // Create sub expression nested in MAP opcode
1517 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1518 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
1519 ASSERT (MapExpressionList
!= NULL
);
1520 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1522 SingleOpCodeExpression
= TRUE
;
1525 ASSERT (CurrentExpression
!= NULL
);
1526 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1527 if (Operand
== EFI_IFR_MAP_OP
) {
1529 // Store current Map Expression List.
1531 if (MapExpressionList
!= NULL
) {
1532 PushMapExpressionList (MapExpressionList
);
1535 // Initialize new Map Expression List.
1537 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1538 InitializeListHead (MapExpressionList
);
1540 // Store current expression.
1542 PushCurrentExpression (CurrentExpression
);
1543 CurrentExpression
= NULL
;
1545 } else if (SingleOpCodeExpression
) {
1547 // There are two cases to indicate the end of an Expression:
1548 // for single OpCode expression: one Expression OpCode
1549 // for expression consists of more than one OpCode: EFI_IFR_END
1551 SingleOpCodeExpression
= FALSE
;
1553 if (InScopeDisable
&& CurrentForm
== NULL
) {
1555 // This is DisableIf expression for Form, it should be a constant expression
1557 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1558 if (EFI_ERROR (Status
)) {
1562 OpCodeDisabled
= IsTrue(&CurrentExpression
->Result
);
1565 CurrentExpression
= NULL
;
1576 case EFI_IFR_FORM_SET_OP
:
1578 // Check the formset GUID
1580 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1581 return EFI_INVALID_PARAMETER
;
1584 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1585 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1587 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1589 // The formset OpCode contains ClassGuid
1591 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1592 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1596 case EFI_IFR_FORM_OP
:
1598 // Create a new Form for this FormSet
1600 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1601 ASSERT (CurrentForm
!= NULL
);
1602 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1603 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1604 InitializeListHead (&CurrentForm
->StatementListHead
);
1605 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1607 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1608 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1609 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1611 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1612 if ( ConditionalExprCount
> 0) {
1614 // Form is inside of suppressif
1616 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1617 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1618 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1619 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1620 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1621 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1626 // Enter scope of a Form, suppressif will be used for Question or Option
1628 SuppressForQuestion
= TRUE
;
1632 // Insert into Form list of this FormSet
1634 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1637 case EFI_IFR_FORM_MAP_OP
:
1639 // Create a new Form for this FormSet
1641 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1642 ASSERT (CurrentForm
!= NULL
);
1643 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1644 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1645 InitializeListHead (&CurrentForm
->StatementListHead
);
1646 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1647 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1649 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1651 // FormMap Form must contain at least one Map Method.
1653 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1654 return EFI_INVALID_PARAMETER
;
1657 // Try to find the standard form map method.
1659 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1660 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1661 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1662 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1668 // If the standard form map method is not found, the first map method title will be used.
1670 if (CurrentForm
->FormTitle
== 0) {
1671 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1672 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1675 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1676 if ( ConditionalExprCount
> 0) {
1678 // Form is inside of suppressif
1680 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1681 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1682 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1683 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1684 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1685 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1690 // Enter scope of a Form, suppressif will be used for Question or Option
1692 SuppressForQuestion
= TRUE
;
1696 // Insert into Form list of this FormSet
1698 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1704 case EFI_IFR_VARSTORE_OP
:
1706 // Create a buffer Storage for this FormSet
1708 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_BUFFER
, OpCodeData
);
1709 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1712 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1714 // Create a name/value Storage for this FormSet
1716 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_NAME_VALUE
, OpCodeData
);
1717 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1720 case EFI_IFR_VARSTORE_EFI_OP
:
1722 // Create a EFI variable Storage for this FormSet
1724 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1726 // Create efi varstore with format follow UEFI spec before 2.3.1.
1728 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE
, OpCodeData
);
1731 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1733 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
, OpCodeData
);
1735 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1741 case EFI_IFR_DEFAULTSTORE_OP
:
1742 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1743 ASSERT (DefaultStore
!= NULL
);
1744 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1746 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1747 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1750 // Insert to DefaultStore list of this Formset
1752 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1758 case EFI_IFR_SUBTITLE_OP
:
1759 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1760 ASSERT (CurrentStatement
!= NULL
);
1762 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1763 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1766 case EFI_IFR_TEXT_OP
:
1767 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1768 ASSERT (CurrentStatement
!= NULL
);
1769 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1770 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1773 case EFI_IFR_RESET_BUTTON_OP
:
1774 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1775 ASSERT (CurrentStatement
!= NULL
);
1776 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1777 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1783 case EFI_IFR_ACTION_OP
:
1784 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1785 ASSERT (CurrentStatement
!= NULL
);
1786 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1788 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1790 // No QuestionConfig present, so no configuration string will be processed
1792 CurrentStatement
->QuestionConfig
= 0;
1794 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1798 case EFI_IFR_REF_OP
:
1799 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1800 ASSERT (CurrentStatement
!= NULL
);
1801 Value
= &CurrentStatement
->HiiValue
;
1802 Value
->Type
= EFI_IFR_TYPE_REF
;
1803 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1804 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1806 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1807 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1809 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1810 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1812 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1813 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1818 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
1819 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1822 case EFI_IFR_ONE_OF_OP
:
1823 case EFI_IFR_NUMERIC_OP
:
1824 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1825 ASSERT(CurrentStatement
!= NULL
);
1827 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1828 Value
= &CurrentStatement
->HiiValue
;
1830 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1831 case EFI_IFR_NUMERIC_SIZE_1
:
1832 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1833 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1834 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1835 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1836 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1839 case EFI_IFR_NUMERIC_SIZE_2
:
1840 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1841 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1842 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1843 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1844 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1847 case EFI_IFR_NUMERIC_SIZE_4
:
1848 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1849 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1850 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1851 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1852 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1855 case EFI_IFR_NUMERIC_SIZE_8
:
1856 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1857 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1858 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1859 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1860 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1867 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1869 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1870 SuppressForOption
= TRUE
;
1874 case EFI_IFR_ORDERED_LIST_OP
:
1875 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1876 ASSERT(CurrentStatement
!= NULL
);
1878 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1879 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1881 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1882 CurrentStatement
->BufferValue
= NULL
;
1885 SuppressForOption
= TRUE
;
1889 case EFI_IFR_CHECKBOX_OP
:
1890 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1891 ASSERT(CurrentStatement
!= NULL
);
1893 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1894 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1895 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1897 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1901 case EFI_IFR_STRING_OP
:
1902 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1903 ASSERT (CurrentStatement
!= NULL
);
1905 // MinSize is the minimum number of characters that can be accepted for this opcode,
1906 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1907 // The characters are stored as Unicode, so the storage width should multiply 2.
1909 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1910 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1911 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1912 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1914 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1915 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1916 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1918 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1921 case EFI_IFR_PASSWORD_OP
:
1922 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1923 ASSERT (CurrentStatement
!= NULL
);
1925 // MinSize is the minimum number of characters that can be accepted for this opcode,
1926 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1927 // The characters are stored as Unicode, so the storage width should multiply 2.
1929 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1930 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1931 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1933 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1934 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1935 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1937 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1940 case EFI_IFR_DATE_OP
:
1941 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1942 ASSERT(CurrentStatement
!= NULL
);
1944 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1945 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1947 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1948 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1950 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1953 // Don't assign storage for RTC type of date/time
1955 CurrentStatement
->Storage
= NULL
;
1956 CurrentStatement
->StorageWidth
= 0;
1960 case EFI_IFR_TIME_OP
:
1961 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1962 ASSERT(CurrentStatement
!= NULL
);
1964 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1965 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1967 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1968 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1970 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1973 // Don't assign storage for RTC type of date/time
1975 CurrentStatement
->Storage
= NULL
;
1976 CurrentStatement
->StorageWidth
= 0;
1983 case EFI_IFR_DEFAULT_OP
:
1985 // EFI_IFR_DEFAULT appear in scope of a Question,
1986 // It creates a default value for the current question.
1987 // A Question may have more than one Default value which have different default types.
1989 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1990 ASSERT (CurrentDefault
!= NULL
);
1991 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1993 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1994 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1995 if (OpCodeLength
> OFFSET_OF (EFI_IFR_DEFAULT
, Value
)) {
1996 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
1997 ExtendValueToU64 (&CurrentDefault
->Value
);
2001 // Insert to Default Value list of current Question
2003 InsertTailList (&ParentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2006 InScopeDefault
= TRUE
;
2013 case EFI_IFR_ONE_OF_OPTION_OP
:
2015 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
2016 // It create a selection for use in current Question.
2018 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
2019 ASSERT (CurrentOption
!= NULL
);
2020 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
2021 CurrentOption
->OpCode
= (EFI_IFR_ONE_OF_OPTION
*) OpCodeData
;
2023 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
2024 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
2025 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
2026 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
2027 ExtendValueToU64 (&CurrentOption
->Value
);
2029 ConditionalExprCount
= GetConditionalExpressionCount(ExpressOption
);
2030 if ( ConditionalExprCount
> 0) {
2032 // Form is inside of suppressif
2034 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
2035 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
2036 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
2037 CurrentOption
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
2038 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
2039 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressOption
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
2042 ASSERT (ParentStatement
!= NULL
);
2044 // Insert to Option list of current Question
2046 InsertTailList (&ParentStatement
->OptionListHead
, &CurrentOption
->Link
);
2048 // Now we know the Storage width of nested Ordered List
2050 if ((ParentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (ParentStatement
->BufferValue
== NULL
)) {
2052 switch (CurrentOption
->Value
.Type
) {
2053 case EFI_IFR_TYPE_NUM_SIZE_8
:
2057 case EFI_IFR_TYPE_NUM_SIZE_16
:
2061 case EFI_IFR_TYPE_NUM_SIZE_32
:
2065 case EFI_IFR_TYPE_NUM_SIZE_64
:
2071 // Invalid type for Ordered List
2076 ParentStatement
->StorageWidth
= (UINT16
) (ParentStatement
->MaxContainers
* Width
);
2077 ParentStatement
->BufferValue
= AllocateZeroPool (ParentStatement
->StorageWidth
);
2078 ParentStatement
->ValueType
= CurrentOption
->Value
.Type
;
2079 if (ParentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
2080 ParentStatement
->HiiValue
.Buffer
= ParentStatement
->BufferValue
;
2081 ParentStatement
->HiiValue
.BufferLen
= ParentStatement
->StorageWidth
;
2084 InitializeRequestElement (FormSet
, ParentStatement
, CurrentForm
);
2091 case EFI_IFR_NO_SUBMIT_IF_OP
:
2092 case EFI_IFR_INCONSISTENT_IF_OP
:
2094 // Create an Expression node
2096 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2097 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
2099 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
2100 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
2101 InsertTailList (&ParentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
2103 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
2104 InsertTailList (&ParentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
2108 // Take a look at next OpCode to see whether current expression consists
2111 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2112 SingleOpCodeExpression
= TRUE
;
2116 case EFI_IFR_WARNING_IF_OP
:
2118 // Create an Expression node
2120 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2121 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_WARNING_IF
*) OpCodeData
)->Warning
, sizeof (EFI_STRING_ID
));
2122 CurrentExpression
->TimeOut
= ((EFI_IFR_WARNING_IF
*) OpCodeData
)->TimeOut
;
2123 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WARNING_IF
;
2124 InsertTailList (&ParentStatement
->WarningListHead
, &CurrentExpression
->Link
);
2127 // Take a look at next OpCode to see whether current expression consists
2130 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2131 SingleOpCodeExpression
= TRUE
;
2135 case EFI_IFR_SUPPRESS_IF_OP
:
2137 // Question and Option will appear in scope of this OpCode
2139 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2140 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
2142 if (CurrentForm
== NULL
) {
2143 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
2145 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2148 if (SuppressForOption
) {
2149 PushConditionalExpression(CurrentExpression
, ExpressOption
);
2150 } else if (SuppressForQuestion
) {
2151 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2153 PushConditionalExpression(CurrentExpression
, ExpressForm
);
2157 // Take a look at next OpCode to see whether current expression consists
2160 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2161 SingleOpCodeExpression
= TRUE
;
2165 case EFI_IFR_GRAY_OUT_IF_OP
:
2167 // Questions will appear in scope of this OpCode
2169 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2170 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
2171 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2172 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2175 // Take a look at next OpCode to see whether current expression consists
2178 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2179 SingleOpCodeExpression
= TRUE
;
2183 case EFI_IFR_DISABLE_IF_OP
:
2185 // The DisableIf expression should only rely on constant, so it could be
2186 // evaluated at initialization and it will not be queued
2188 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
2189 ASSERT (CurrentExpression
!= NULL
);
2190 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
2191 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
2192 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
2194 if (CurrentForm
!= NULL
) {
2196 // This is DisableIf for Question, enqueue it to Form expression list
2198 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2199 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2202 OpCodeDisabled
= FALSE
;
2203 InScopeDisable
= TRUE
;
2205 // Take a look at next OpCode to see whether current expression consists
2208 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2209 SingleOpCodeExpression
= TRUE
;
2216 case EFI_IFR_VALUE_OP
:
2217 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2218 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
2219 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2221 if (InScopeDefault
) {
2223 // Used for default (EFI_IFR_DEFAULT)
2225 CurrentDefault
->ValueExpression
= CurrentExpression
;
2228 // If used for a question, then the question will be read-only
2231 // Make sure CurrentStatement is not NULL.
2232 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2233 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2235 ASSERT (ParentStatement
!= NULL
);
2236 ParentStatement
->ValueExpression
= CurrentExpression
;
2240 // Take a look at next OpCode to see whether current expression consists
2243 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2244 SingleOpCodeExpression
= TRUE
;
2248 case EFI_IFR_RULE_OP
:
2249 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2250 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2252 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2253 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2256 // Take a look at next OpCode to see whether current expression consists
2259 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2260 SingleOpCodeExpression
= TRUE
;
2264 case EFI_IFR_READ_OP
:
2265 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2266 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2267 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2270 // Make sure CurrentStatement is not NULL.
2271 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2272 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2274 ASSERT (ParentStatement
!= NULL
);
2275 ParentStatement
->ReadExpression
= CurrentExpression
;
2278 // Take a look at next OpCode to see whether current expression consists
2281 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2282 SingleOpCodeExpression
= TRUE
;
2286 case EFI_IFR_WRITE_OP
:
2287 CurrentExpression
= CreateExpression (CurrentForm
, OpCodeData
);
2288 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2289 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2292 // Make sure CurrentStatement is not NULL.
2293 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2294 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2296 ASSERT (ParentStatement
!= NULL
);
2297 ParentStatement
->WriteExpression
= CurrentExpression
;
2300 // Take a look at next OpCode to see whether current expression consists
2303 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2304 SingleOpCodeExpression
= TRUE
;
2311 case EFI_IFR_IMAGE_OP
:
2313 // Get ScopeOpcode from top of stack
2315 PopScope (&ScopeOpCode
);
2316 PushScope (ScopeOpCode
);
2318 switch (ScopeOpCode
) {
2319 case EFI_IFR_FORM_SET_OP
:
2320 ImageId
= &FormSet
->ImageId
;
2323 case EFI_IFR_FORM_OP
:
2324 case EFI_IFR_FORM_MAP_OP
:
2325 ASSERT (CurrentForm
!= NULL
);
2326 ImageId
= &CurrentForm
->ImageId
;
2329 case EFI_IFR_ONE_OF_OPTION_OP
:
2330 ImageId
= &CurrentOption
->ImageId
;
2335 // Make sure CurrentStatement is not NULL.
2336 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2337 // file is wrongly generated by tools such as VFR Compiler.
2339 ASSERT (ParentStatement
!= NULL
);
2340 ImageId
= &ParentStatement
->ImageId
;
2344 ASSERT (ImageId
!= NULL
);
2345 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2351 case EFI_IFR_REFRESH_OP
:
2352 ASSERT (ParentStatement
!= NULL
);
2353 ParentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2359 case EFI_IFR_REFRESH_ID_OP
:
2360 ASSERT (ParentStatement
!= NULL
);
2361 CopyMem (&ParentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2367 case EFI_IFR_MODAL_TAG_OP
:
2368 ASSERT (CurrentForm
!= NULL
);
2369 CurrentForm
->ModalForm
= TRUE
;
2373 // Lock tag, used by form and statement.
2375 case EFI_IFR_LOCKED_OP
:
2377 // Get ScopeOpcode from top of stack
2379 PopScope (&ScopeOpCode
);
2380 PushScope (ScopeOpCode
);
2381 switch (ScopeOpCode
) {
2382 case EFI_IFR_FORM_OP
:
2383 case EFI_IFR_FORM_MAP_OP
:
2384 ASSERT (CurrentForm
!= NULL
);
2385 CurrentForm
->Locked
= TRUE
;
2389 ASSERT (ParentStatement
!= NULL
);
2390 ParentStatement
->Locked
= TRUE
;
2397 case EFI_IFR_GUID_OP
:
2398 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2404 case EFI_IFR_END_OP
:
2405 Status
= PopScope (&ScopeOpCode
);
2406 if (EFI_ERROR (Status
)) {
2412 // Parent statement end tag found, update ParentStatement info.
2414 if (IsStatementOpCode(ScopeOpCode
) && (ParentStatement
!= NULL
) && (ParentStatement
->Operand
== ScopeOpCode
)) {
2415 ParentStatement
= ParentStatement
->ParentStatement
;
2418 switch (ScopeOpCode
) {
2419 case EFI_IFR_FORM_SET_OP
:
2421 // End of FormSet, update FormSet IFR binary length
2422 // to stop parsing substantial OpCodes
2424 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2427 case EFI_IFR_FORM_OP
:
2428 case EFI_IFR_FORM_MAP_OP
:
2433 SuppressForQuestion
= FALSE
;
2436 case EFI_IFR_ONE_OF_OPTION_OP
:
2440 CurrentOption
= NULL
;
2443 case EFI_IFR_NO_SUBMIT_IF_OP
:
2444 case EFI_IFR_INCONSISTENT_IF_OP
:
2445 case EFI_IFR_WARNING_IF_OP
:
2447 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2451 case EFI_IFR_SUPPRESS_IF_OP
:
2452 if (SuppressForOption
) {
2453 PopConditionalExpression(ExpressOption
);
2454 } else if (SuppressForQuestion
) {
2455 PopConditionalExpression(ExpressStatement
);
2457 PopConditionalExpression(ExpressForm
);
2461 case EFI_IFR_GRAY_OUT_IF_OP
:
2462 PopConditionalExpression(ExpressStatement
);
2465 case EFI_IFR_DISABLE_IF_OP
:
2466 if (CurrentForm
!= NULL
) {
2467 PopConditionalExpression(ExpressStatement
);
2469 InScopeDisable
= FALSE
;
2470 OpCodeDisabled
= FALSE
;
2473 case EFI_IFR_ONE_OF_OP
:
2474 case EFI_IFR_ORDERED_LIST_OP
:
2475 SuppressForOption
= FALSE
;
2478 case EFI_IFR_DEFAULT_OP
:
2479 InScopeDefault
= FALSE
;
2482 case EFI_IFR_MAP_OP
:
2484 // Get current Map Expression List.
2486 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2487 if (Status
== EFI_ACCESS_DENIED
) {
2488 MapExpressionList
= NULL
;
2491 // Get current expression.
2493 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2494 ASSERT_EFI_ERROR (Status
);
2495 ASSERT (MapScopeDepth
> 0);
2500 if (IsExpressionOpCode (ScopeOpCode
)) {
2501 if (InScopeDisable
&& CurrentForm
== NULL
) {
2503 // This is DisableIf expression for Form, it should be a constant expression
2505 ASSERT (CurrentExpression
!= NULL
);
2506 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2507 if (EFI_ERROR (Status
)) {
2511 OpCodeDisabled
= IsTrue (&CurrentExpression
->Result
);
2514 // DisableIf Expression is only used once and not queued, free it
2516 DestroyExpression (CurrentExpression
);
2520 // End of current Expression
2522 CurrentExpression
= NULL
;
2532 if (IsStatementOpCode(Operand
)) {
2533 CurrentStatement
->ParentStatement
= ParentStatement
;
2536 // Scope != 0, other statements or options may nest in this statement.
2537 // Update the ParentStatement info.
2539 ParentStatement
= CurrentStatement
;