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 BOOLEAN mInScopeSubtitle
;
21 extern LIST_ENTRY gBrowserStorageList
;
23 Initialize Statement header members.
25 @param OpCodeData Pointer of the raw OpCode data.
26 @param FormSet Pointer of the current FormSe.
27 @param Form Pointer of the current Form.
29 @return The Statement.
32 FORM_BROWSER_STATEMENT
*
35 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
36 IN OUT FORM_BROWSER_FORM
*Form
39 FORM_BROWSER_STATEMENT
*Statement
;
40 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
41 INTN ConditionalExprCount
;
45 // Only guid op may out side the form level.
47 ASSERT (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_GUID_OP
);
50 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
53 InitializeListHead (&Statement
->DefaultListHead
);
54 InitializeListHead (&Statement
->OptionListHead
);
55 InitializeListHead (&Statement
->InconsistentListHead
);
56 InitializeListHead (&Statement
->NoSubmitListHead
);
57 InitializeListHead (&Statement
->WarningListHead
);
59 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
61 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
62 Statement
->OpCode
= (EFI_IFR_OP_HEADER
*) OpCodeData
;
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
));
82 Statement
->InSubtitle
= mInScopeSubtitle
;
85 // Insert this Statement into current Form
88 InsertTailList (&FormSet
->StatementListOSF
, &Statement
->Link
);
90 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
96 Convert a numeric value to a Unicode String and insert it to String Package.
97 This string is used as the Unicode Name for the EFI Variable. This is to support
98 the deprecated vareqval opcode.
100 @param FormSet The FormSet.
101 @param Statement The numeric question whose VarStoreInfo.VarName is the
102 numeric value which is used to produce the Unicode Name
103 for the EFI Variable.
105 If the Statement is NULL, the ASSERT.
106 If the opcode is not Numeric, then ASSERT.
108 @retval EFI_SUCCESS The funtion always succeeds.
111 UpdateCheckBoxStringToken (
112 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
113 IN FORM_BROWSER_STATEMENT
*Statement
116 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
119 ASSERT (Statement
!= NULL
);
120 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
122 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
124 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
126 return EFI_OUT_OF_RESOURCES
;
129 Statement
->VarStoreInfo
.VarName
= Id
;
135 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
137 @param OpCodeData The current opcode.
143 IsNextOpCodeGuidedVarEqName (
150 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
151 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
152 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
154 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
156 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
166 Initialize Question's members.
168 @param OpCodeData Pointer of the raw OpCode data.
169 @param FormSet Pointer of the current FormSet.
170 @param Form Pointer of the current Form.
172 @return The Question.
175 FORM_BROWSER_STATEMENT
*
177 IN UINT8
*OpCodeData
,
178 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
179 IN OUT FORM_BROWSER_FORM
*Form
182 FORM_BROWSER_STATEMENT
*Statement
;
183 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
185 FORMSET_STORAGE
*Storage
;
186 NAME_VALUE_NODE
*NameValueNode
;
190 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
191 if (Statement
== NULL
) {
195 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
196 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
197 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
198 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
200 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
202 if (Statement
->VarStoreId
== 0) {
204 // VarStoreId of zero indicates no variable storage
210 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
211 // Framework Compatibility
213 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
214 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
215 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
216 if (EFI_ERROR (Status
)) {
223 // Find Storage for this Question
225 Link
= GetFirstNode (&FormSet
->StorageListHead
);
226 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
227 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
229 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
230 Statement
->Storage
= Storage
->BrowserStorage
;
234 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
236 ASSERT (Statement
->Storage
!= NULL
);
239 // Initialilze varname for Name/Value or EFI Variable
241 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
242 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
243 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
244 ASSERT (Statement
->VariableName
!= NULL
);
246 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
248 // Check whether old string node already exist.
251 if (!IsListEmpty(&Statement
->Storage
->NameValueListHead
)) {
252 Link
= GetFirstNode (&Statement
->Storage
->NameValueListHead
);
253 while (!IsNull (&Statement
->Storage
->NameValueListHead
, Link
)) {
254 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
256 if (StrCmp (Statement
->VariableName
, NameValueNode
->Name
) == 0) {
261 Link
= GetNextNode (&Statement
->Storage
->NameValueListHead
, Link
);
267 // Insert to Name/Value varstore list
269 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
270 ASSERT (NameValueNode
!= NULL
);
271 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
272 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
273 ASSERT (NameValueNode
->Name
!= NULL
);
274 NameValueNode
->Value
= AllocateZeroPool (0x10);
275 ASSERT (NameValueNode
->Value
!= NULL
);
276 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
277 ASSERT (NameValueNode
->EditValue
!= NULL
);
279 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
289 Allocate a FORM_EXPRESSION node.
291 @param Form The Form associated with this Expression
293 @return Pointer to a FORM_EXPRESSION data structure.
298 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
);
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
);
383 if ((BrowserStorage
->Type
== StorageType
) && CompareGuid (&BrowserStorage
->Guid
, StorageGuid
)) {
384 if (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
&& BrowserStorage
->HiiHandle
== HiiHandle
) {
385 return BrowserStorage
;
388 if (StrCmp (BrowserStorage
->Name
, StorageName
) == 0) {
389 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE
|| StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
390 return BrowserStorage
;
391 } else if (StorageType
== EFI_HII_VARSTORE_BUFFER
&& BrowserStorage
->HiiHandle
== HiiHandle
) {
392 return BrowserStorage
;
400 Link
= GetNextNode (&gBrowserStorageList
, Link
);
407 Intialize the Global Storage.
409 @param BrowserStorage Pointer to the global storage.
410 @param StorageType Storage type.
411 @param OpCodeData Binary data for this opcode.
415 IntializeBrowserStorage (
416 IN BROWSER_STORAGE
*BrowserStorage
,
417 IN UINT8 StorageType
,
421 switch (StorageType
) {
422 case EFI_HII_VARSTORE_BUFFER
:
423 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
424 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
426 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
427 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
430 case EFI_HII_VARSTORE_EFI_VARIABLE
:
431 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
432 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
433 CopyMem (&BrowserStorage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
434 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
436 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
437 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
438 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
442 case EFI_HII_VARSTORE_NAME_VALUE
:
443 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
445 InitializeListHead (&BrowserStorage
->NameValueListHead
);
454 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
456 @param FormSet Pointer of the current FormSet
457 @param StorageType Storage type.
458 @param OpCodeData Binary data for this opcode.
460 @return Pointer to a FORMSET_STORAGE data structure.
465 IN FORM_BROWSER_FORMSET
*FormSet
,
466 IN UINT8 StorageType
,
470 FORMSET_STORAGE
*Storage
;
471 CHAR16
*UnicodeString
;
473 BROWSER_STORAGE
*BrowserStorage
;
474 EFI_GUID
*StorageGuid
;
477 UnicodeString
= NULL
;
479 switch (StorageType
) {
480 case EFI_HII_VARSTORE_BUFFER
:
481 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
;
482 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
485 case EFI_HII_VARSTORE_EFI_VARIABLE
:
486 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
487 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
;
488 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
492 ASSERT (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
);
493 StorageGuid
= &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
;
497 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
498 ASSERT (StorageName
!= NULL
);
500 UnicodeString
= AllocateZeroPool (AsciiStrSize (StorageName
) * 2);
501 ASSERT (UnicodeString
!= NULL
);
502 for (Index
= 0; StorageName
[Index
] != 0; Index
++) {
503 UnicodeString
[Index
] = (CHAR16
) StorageName
[Index
];
507 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
508 ASSERT (Storage
!= NULL
);
509 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
510 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
512 BrowserStorage
= FindStorageInList(StorageType
, StorageGuid
, UnicodeString
, FormSet
->HiiHandle
);
513 if (BrowserStorage
== NULL
) {
514 BrowserStorage
= AllocateZeroPool (sizeof (BROWSER_STORAGE
));
515 ASSERT (BrowserStorage
!= NULL
);
517 BrowserStorage
->Signature
= BROWSER_STORAGE_SIGNATURE
;
518 InsertTailList (&gBrowserStorageList
, &BrowserStorage
->Link
);
520 IntializeBrowserStorage (BrowserStorage
, StorageType
, OpCodeData
);
521 BrowserStorage
->Type
= StorageType
;
522 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
523 BrowserStorage
->Name
= UnicodeString
;
526 BrowserStorage
->HiiHandle
= FormSet
->HiiHandle
;
527 InitializeConfigHdr (FormSet
, BrowserStorage
);
529 BrowserStorage
->Initialized
= FALSE
;
532 Storage
->BrowserStorage
= BrowserStorage
;
533 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (BrowserStorage
->ConfigHdr
), BrowserStorage
->ConfigHdr
);
534 Storage
->SpareStrLen
= 0;
540 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
542 @param FormSet Pointer of the current FormSet.
543 @param Question The Question to be initialized.
544 @param Form Pointer of the current form.
546 @retval EFI_SUCCESS Function success.
547 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
551 InitializeRequestElement (
552 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
553 IN OUT FORM_BROWSER_STATEMENT
*Question
,
554 IN OUT FORM_BROWSER_FORM
*Form
557 BROWSER_STORAGE
*Storage
;
558 FORMSET_STORAGE
*FormsetStorage
;
562 CHAR16 RequestElement
[30];
565 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
567 Storage
= Question
->Storage
;
568 if (Storage
== NULL
) {
569 return EFI_INVALID_PARAMETER
;
572 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
574 // <ConfigRequest> is unnecessary for EFI variable storage,
575 // GetVariable()/SetVariable() will be used to retrieve/save values
581 // Prepare <RequestElement>
583 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
584 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
585 StrLen
= UnicodeSPrint (
587 30 * sizeof (CHAR16
),
588 L
"&OFFSET=%x&WIDTH=%x",
589 Question
->VarStoreInfo
.VarOffset
,
590 Question
->StorageWidth
592 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
594 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
597 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
599 // Password with CALLBACK flag is stored in encoded format,
600 // so don't need to append it to <ConfigRequest>
606 // Find Formset Storage for this Question
608 FormsetStorage
= NULL
;
609 Link
= GetFirstNode (&FormSet
->StorageListHead
);
610 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
611 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
613 if (FormsetStorage
->VarStoreId
== Question
->VarStoreId
) {
617 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
619 ASSERT (FormsetStorage
!= NULL
);
622 // Append <RequestElement> to <ConfigRequest>
624 if (StrLen
> FormsetStorage
->SpareStrLen
) {
626 // Old String buffer is not sufficient for RequestElement, allocate a new one
628 StringSize
= (FormsetStorage
->ConfigRequest
!= NULL
) ? StrSize (FormsetStorage
->ConfigRequest
) : sizeof (CHAR16
);
629 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
630 ASSERT (NewStr
!= NULL
);
631 if (FormsetStorage
->ConfigRequest
!= NULL
) {
632 CopyMem (NewStr
, FormsetStorage
->ConfigRequest
, StringSize
);
633 FreePool (FormsetStorage
->ConfigRequest
);
635 FormsetStorage
->ConfigRequest
= NewStr
;
636 FormsetStorage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
639 StrCat (FormsetStorage
->ConfigRequest
, RequestElement
);
640 FormsetStorage
->ElementCount
++;
641 FormsetStorage
->SpareStrLen
-= StrLen
;
644 // Update the Config Request info saved in the form.
648 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
649 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
650 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
652 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
== Storage
) {
657 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
661 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
662 ASSERT (ConfigInfo
!= NULL
);
663 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
664 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
665 ConfigInfo
->SpareStrLen
= 0;
666 ConfigInfo
->Storage
= Storage
;
667 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
671 // Append <RequestElement> to <ConfigRequest>
673 if (StrLen
> ConfigInfo
->SpareStrLen
) {
675 // Old String buffer is not sufficient for RequestElement, allocate a new one
677 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
678 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
679 ASSERT (NewStr
!= NULL
);
680 if (ConfigInfo
->ConfigRequest
!= NULL
) {
681 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
682 FreePool (ConfigInfo
->ConfigRequest
);
684 ConfigInfo
->ConfigRequest
= NewStr
;
685 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
688 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
689 ConfigInfo
->ElementCount
++;
690 ConfigInfo
->SpareStrLen
-= StrLen
;
696 Free resources of a Expression.
698 @param FormSet Pointer of the Expression
703 IN FORM_EXPRESSION
*Expression
707 EXPRESSION_OPCODE
*OpCode
;
708 LIST_ENTRY
*SubExpressionLink
;
709 FORM_EXPRESSION
*SubExpression
;
711 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
712 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
713 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
714 RemoveEntryList (&OpCode
->Link
);
716 if (OpCode
->ValueList
!= NULL
) {
717 FreePool (OpCode
->ValueList
);
720 if (OpCode
->ValueName
!= NULL
) {
721 FreePool (OpCode
->ValueName
);
724 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
725 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
726 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
727 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
728 RemoveEntryList(&SubExpression
->Link
);
729 DestroyExpression (SubExpression
);
735 // Free this Expression
737 FreePool (Expression
);
741 Free resources of a storage.
743 @param Storage Pointer of the storage
748 IN FORMSET_STORAGE
*Storage
751 if (Storage
== NULL
) {
755 if (Storage
->ConfigRequest
!= NULL
) {
756 FreePool (Storage
->ConfigRequest
);
764 Free resources of a Statement.
766 @param FormSet Pointer of the FormSet
767 @param Statement Pointer of the Statement
772 IN FORM_BROWSER_FORMSET
*FormSet
,
773 IN OUT FORM_BROWSER_STATEMENT
*Statement
777 QUESTION_DEFAULT
*Default
;
778 QUESTION_OPTION
*Option
;
779 FORM_EXPRESSION
*Expression
;
782 // Free Default value List
784 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
785 Link
= GetFirstNode (&Statement
->DefaultListHead
);
786 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
787 RemoveEntryList (&Default
->Link
);
795 while (!IsListEmpty (&Statement
->OptionListHead
)) {
796 Link
= GetFirstNode (&Statement
->OptionListHead
);
797 Option
= QUESTION_OPTION_FROM_LINK (Link
);
798 if (Option
->SuppressExpression
!= NULL
) {
799 FreePool (Option
->SuppressExpression
);
801 RemoveEntryList (&Option
->Link
);
807 // Free Inconsistent List
809 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
810 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
811 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
812 RemoveEntryList (&Expression
->Link
);
814 DestroyExpression (Expression
);
818 // Free NoSubmit List
820 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
821 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
822 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
823 RemoveEntryList (&Expression
->Link
);
825 DestroyExpression (Expression
);
829 // Free WarningIf List
831 while (!IsListEmpty (&Statement
->WarningListHead
)) {
832 Link
= GetFirstNode (&Statement
->WarningListHead
);
833 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
834 RemoveEntryList (&Expression
->Link
);
836 DestroyExpression (Expression
);
839 if (Statement
->Expression
!= NULL
) {
840 FreePool (Statement
->Expression
);
843 if (Statement
->VariableName
!= NULL
) {
844 FreePool (Statement
->VariableName
);
846 if (Statement
->BlockName
!= NULL
) {
847 FreePool (Statement
->BlockName
);
849 if (Statement
->BufferValue
!= NULL
) {
850 FreePool (Statement
->BufferValue
);
852 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
853 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
859 Free resources of a Form.
861 @param FormSet Pointer of the FormSet
862 @param Form Pointer of the Form.
867 IN FORM_BROWSER_FORMSET
*FormSet
,
868 IN OUT FORM_BROWSER_FORM
*Form
872 FORM_EXPRESSION
*Expression
;
873 FORM_BROWSER_STATEMENT
*Statement
;
874 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
877 // Free Form Expressions
879 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
880 Link
= GetFirstNode (&Form
->ExpressionListHead
);
881 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
882 RemoveEntryList (&Expression
->Link
);
884 DestroyExpression (Expression
);
888 // Free Statements/Questions
890 while (!IsListEmpty (&Form
->StatementListHead
)) {
891 Link
= GetFirstNode (&Form
->StatementListHead
);
892 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
893 RemoveEntryList (&Statement
->Link
);
895 DestroyStatement (FormSet
, Statement
);
899 // Free ConfigRequest string.
901 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
902 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
903 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
904 RemoveEntryList (&ConfigInfo
->Link
);
906 FreePool (ConfigInfo
->ConfigRequest
);
907 FreePool (ConfigInfo
);
910 if (Form
->SuppressExpression
!= NULL
) {
911 FreePool (Form
->SuppressExpression
);
922 Free resources allocated for a FormSet.
924 @param FormSet Pointer of the FormSet
929 IN OUT FORM_BROWSER_FORMSET
*FormSet
933 FORMSET_STORAGE
*Storage
;
934 FORMSET_DEFAULTSTORE
*DefaultStore
;
935 FORM_EXPRESSION
*Expression
;
936 FORM_BROWSER_FORM
*Form
;
938 if (FormSet
->IfrBinaryData
== NULL
) {
940 // Uninitialized FormSet
947 // Free IFR binary buffer
949 FreePool (FormSet
->IfrBinaryData
);
952 // Free FormSet Storage
954 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
955 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
956 Link
= GetFirstNode (&FormSet
->StorageListHead
);
957 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
958 RemoveEntryList (&Storage
->Link
);
960 DestroyStorage (Storage
);
965 // Free FormSet Default Store
967 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
968 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
969 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
970 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
971 RemoveEntryList (&DefaultStore
->Link
);
973 FreePool (DefaultStore
);
978 // Free Formset Expressions
980 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
981 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
982 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
983 RemoveEntryList (&Expression
->Link
);
985 DestroyExpression (Expression
);
991 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
992 while (!IsListEmpty (&FormSet
->FormListHead
)) {
993 Link
= GetFirstNode (&FormSet
->FormListHead
);
994 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
995 RemoveEntryList (&Form
->Link
);
997 DestroyForm (FormSet
, Form
);
1001 if (FormSet
->StatementBuffer
!= NULL
) {
1002 FreePool (FormSet
->StatementBuffer
);
1004 if (FormSet
->ExpressionBuffer
!= NULL
) {
1005 FreePool (FormSet
->ExpressionBuffer
);
1013 Tell whether this Operand is an Expression OpCode or not
1015 @param Operand Operand of an IFR OpCode.
1017 @retval TRUE This is an Expression OpCode.
1018 @retval FALSE Not an Expression OpCode.
1022 IsExpressionOpCode (
1026 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
1027 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
1028 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
1029 (Operand
== EFI_IFR_CATENATE_OP
) ||
1030 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
1031 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
1032 (Operand
== EFI_IFR_MAP_OP
) ||
1033 (Operand
== EFI_IFR_VERSION_OP
) ||
1034 (Operand
== EFI_IFR_SECURITY_OP
)) {
1043 Calculate number of Statemens(Questions) and Expression OpCodes.
1045 @param FormSet The FormSet to be counted.
1046 @param NumberOfStatement Number of Statemens(Questions)
1047 @param NumberOfExpression Number of Expression OpCodes
1052 IN FORM_BROWSER_FORMSET
*FormSet
,
1053 IN OUT UINT16
*NumberOfStatement
,
1054 IN OUT UINT16
*NumberOfExpression
1057 UINT16 StatementCount
;
1058 UINT16 ExpressionCount
;
1065 ExpressionCount
= 0;
1067 while (Offset
< FormSet
->IfrBinaryLength
) {
1068 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
1069 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1070 Offset
+= OpCodeLen
;
1072 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
1079 *NumberOfStatement
= StatementCount
;
1080 *NumberOfExpression
= ExpressionCount
;
1086 Parse opcodes in the formset IFR binary.
1088 @param FormSet Pointer of the FormSet data structure.
1090 @retval EFI_SUCCESS Opcode parse success.
1091 @retval Other Opcode parse fail.
1096 IN FORM_BROWSER_FORMSET
*FormSet
1100 FORM_BROWSER_FORM
*CurrentForm
;
1101 FORM_BROWSER_STATEMENT
*CurrentStatement
;
1102 EXPRESSION_OPCODE
*ExpressionOpCode
;
1103 FORM_EXPRESSION
*CurrentExpression
;
1110 FORMSET_STORAGE
*Storage
;
1111 FORMSET_DEFAULTSTORE
*DefaultStore
;
1112 QUESTION_DEFAULT
*CurrentDefault
;
1113 QUESTION_OPTION
*CurrentOption
;
1115 UINT16 NumberOfStatement
;
1116 UINT16 NumberOfExpression
;
1117 EFI_IMAGE_ID
*ImageId
;
1118 BOOLEAN SuppressForQuestion
;
1119 BOOLEAN SuppressForOption
;
1120 UINT16 DepthOfDisable
;
1121 BOOLEAN OpCodeDisabled
;
1122 BOOLEAN SingleOpCodeExpression
;
1123 BOOLEAN InScopeDefault
;
1124 EFI_HII_VALUE
*Value
;
1125 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
1126 UINT8 MapScopeDepth
;
1128 FORMSET_STORAGE
*VarStorage
;
1129 LIST_ENTRY
*MapExpressionList
;
1130 EFI_VARSTORE_ID TempVarstoreId
;
1131 BOOLEAN InScopeDisable
;
1132 INTN ConditionalExprCount
;
1134 mInScopeSubtitle
= FALSE
;
1135 SuppressForQuestion
= FALSE
;
1136 SuppressForOption
= FALSE
;
1137 InScopeDisable
= FALSE
;
1139 OpCodeDisabled
= FALSE
;
1140 SingleOpCodeExpression
= FALSE
;
1141 InScopeDefault
= FALSE
;
1142 CurrentExpression
= NULL
;
1143 CurrentDefault
= NULL
;
1144 CurrentOption
= NULL
;
1150 MapExpressionList
= NULL
;
1152 ConditionalExprCount
= 0;
1155 // Get the number of Statements and Expressions
1157 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
1159 mStatementIndex
= 0;
1160 mUsedQuestionId
= 1;
1161 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
1162 if (FormSet
->StatementBuffer
== NULL
) {
1163 return EFI_OUT_OF_RESOURCES
;
1166 mExpressionOpCodeIndex
= 0;
1167 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
1168 if (FormSet
->ExpressionBuffer
== NULL
) {
1169 return EFI_OUT_OF_RESOURCES
;
1172 InitializeListHead (&FormSet
->StatementListOSF
);
1173 InitializeListHead (&FormSet
->StorageListHead
);
1174 InitializeListHead (&FormSet
->DefaultStoreListHead
);
1175 InitializeListHead (&FormSet
->FormListHead
);
1176 InitializeListHead (&FormSet
->ExpressionListHead
);
1177 ResetCurrentExpressionStack ();
1178 ResetMapExpressionListStack ();
1181 CurrentStatement
= NULL
;
1186 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1187 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1189 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1190 OpCodeOffset
+= OpCodeLength
;
1191 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1192 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1195 // If scope bit set, push onto scope stack
1198 PushScope (Operand
);
1201 if (OpCodeDisabled
) {
1203 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1204 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1206 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1208 } else if (Operand
== EFI_IFR_END_OP
) {
1209 Status
= PopScope (&ScopeOpCode
);
1210 if (EFI_ERROR (Status
)) {
1214 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1215 if (DepthOfDisable
== 0) {
1216 InScopeDisable
= FALSE
;
1217 OpCodeDisabled
= FALSE
;
1226 if (IsExpressionOpCode (Operand
)) {
1227 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1228 mExpressionOpCodeIndex
++;
1230 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1231 ExpressionOpCode
->Operand
= Operand
;
1232 Value
= &ExpressionOpCode
->Value
;
1235 case EFI_IFR_EQ_ID_VAL_OP
:
1236 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1238 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1239 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1242 case EFI_IFR_EQ_ID_ID_OP
:
1243 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1244 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1247 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1248 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1249 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1250 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1253 case EFI_IFR_TO_STRING_OP
:
1254 case EFI_IFR_FIND_OP
:
1255 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1258 case EFI_IFR_STRING_REF1_OP
:
1259 Value
->Type
= EFI_IFR_TYPE_STRING
;
1260 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1263 case EFI_IFR_RULE_REF_OP
:
1264 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1267 case EFI_IFR_SPAN_OP
:
1268 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1271 case EFI_IFR_THIS_OP
:
1272 ASSERT (CurrentStatement
!= NULL
);
1273 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1276 case EFI_IFR_SECURITY_OP
:
1277 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1280 case EFI_IFR_GET_OP
:
1281 case EFI_IFR_SET_OP
:
1282 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1283 if (TempVarstoreId
!= 0) {
1284 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1285 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1286 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1287 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1288 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1289 ExpressionOpCode
->VarStorage
= VarStorage
->BrowserStorage
;
1292 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1295 if (ExpressionOpCode
->VarStorage
== NULL
) {
1297 // VarStorage is not found.
1299 return EFI_INVALID_PARAMETER
;
1302 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1303 switch (ExpressionOpCode
->ValueType
) {
1304 case EFI_IFR_TYPE_BOOLEAN
:
1305 case EFI_IFR_TYPE_NUM_SIZE_8
:
1306 ExpressionOpCode
->ValueWidth
= 1;
1309 case EFI_IFR_TYPE_NUM_SIZE_16
:
1310 case EFI_IFR_TYPE_STRING
:
1311 ExpressionOpCode
->ValueWidth
= 2;
1314 case EFI_IFR_TYPE_NUM_SIZE_32
:
1315 ExpressionOpCode
->ValueWidth
= 4;
1318 case EFI_IFR_TYPE_NUM_SIZE_64
:
1319 ExpressionOpCode
->ValueWidth
= 8;
1322 case EFI_IFR_TYPE_DATE
:
1323 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1326 case EFI_IFR_TYPE_TIME
:
1327 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1330 case EFI_IFR_TYPE_REF
:
1331 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
1334 case EFI_IFR_TYPE_OTHER
:
1335 case EFI_IFR_TYPE_UNDEFINED
:
1336 case EFI_IFR_TYPE_ACTION
:
1337 case EFI_IFR_TYPE_BUFFER
:
1340 // Invalid value type for Get/Set opcode.
1342 return EFI_INVALID_PARAMETER
;
1344 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1345 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1346 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1347 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1348 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1349 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1350 if (ExpressionOpCode
->ValueName
== NULL
) {
1352 // String ID is invalid.
1354 return EFI_INVALID_PARAMETER
;
1359 case EFI_IFR_QUESTION_REF1_OP
:
1360 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1363 case EFI_IFR_QUESTION_REF3_OP
:
1364 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1365 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1367 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1368 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1376 case EFI_IFR_TRUE_OP
:
1377 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1378 Value
->Value
.b
= TRUE
;
1381 case EFI_IFR_FALSE_OP
:
1382 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1383 Value
->Value
.b
= FALSE
;
1386 case EFI_IFR_ONE_OP
:
1387 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1388 Value
->Value
.u8
= 1;
1391 case EFI_IFR_ZERO_OP
:
1392 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1393 Value
->Value
.u8
= 0;
1396 case EFI_IFR_ONES_OP
:
1397 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1398 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1401 case EFI_IFR_UINT8_OP
:
1402 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1403 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1406 case EFI_IFR_UINT16_OP
:
1407 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1408 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1411 case EFI_IFR_UINT32_OP
:
1412 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1413 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1416 case EFI_IFR_UINT64_OP
:
1417 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1418 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1421 case EFI_IFR_UNDEFINED_OP
:
1422 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1425 case EFI_IFR_VERSION_OP
:
1426 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1427 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1434 // Create sub expression nested in MAP opcode
1436 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1437 CurrentExpression
= CreateExpression (CurrentForm
);
1438 ASSERT (MapExpressionList
!= NULL
);
1439 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1441 SingleOpCodeExpression
= TRUE
;
1444 ASSERT (CurrentExpression
!= NULL
);
1445 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1446 if (Operand
== EFI_IFR_MAP_OP
) {
1448 // Store current Map Expression List.
1450 if (MapExpressionList
!= NULL
) {
1451 PushMapExpressionList (MapExpressionList
);
1454 // Initialize new Map Expression List.
1456 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1457 InitializeListHead (MapExpressionList
);
1459 // Store current expression.
1461 PushCurrentExpression (CurrentExpression
);
1462 CurrentExpression
= NULL
;
1464 } else if (SingleOpCodeExpression
) {
1466 // There are two cases to indicate the end of an Expression:
1467 // for single OpCode expression: one Expression OpCode
1468 // for expression consists of more than one OpCode: EFI_IFR_END
1470 SingleOpCodeExpression
= FALSE
;
1472 if (InScopeDisable
&& CurrentForm
== NULL
) {
1474 // This is DisableIf expression for Form, it should be a constant expression
1476 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1477 if (EFI_ERROR (Status
)) {
1481 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1482 return EFI_INVALID_PARAMETER
;
1485 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1488 CurrentExpression
= NULL
;
1499 case EFI_IFR_FORM_SET_OP
:
1501 // Check the formset GUID
1503 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1504 return EFI_INVALID_PARAMETER
;
1507 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1508 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1510 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1512 // The formset OpCode contains ClassGuid
1514 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1515 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1519 case EFI_IFR_FORM_OP
:
1521 // Create a new Form for this FormSet
1523 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1524 ASSERT (CurrentForm
!= NULL
);
1525 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1526 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1527 InitializeListHead (&CurrentForm
->StatementListHead
);
1528 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1530 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1531 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1532 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1534 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1535 if ( ConditionalExprCount
> 0) {
1537 // Form is inside of suppressif
1539 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1540 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1541 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1542 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1543 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1544 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1549 // Enter scope of a Form, suppressif will be used for Question or Option
1551 SuppressForQuestion
= TRUE
;
1555 // Insert into Form list of this FormSet
1557 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1560 case EFI_IFR_FORM_MAP_OP
:
1562 // Create a new Form for this FormSet
1564 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1565 ASSERT (CurrentForm
!= NULL
);
1566 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1567 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1568 InitializeListHead (&CurrentForm
->StatementListHead
);
1569 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1570 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1572 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1574 // FormMap Form must contain at least one Map Method.
1576 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1577 return EFI_INVALID_PARAMETER
;
1580 // Try to find the standard form map method.
1582 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1583 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1584 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1585 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1591 // If the standard form map method is not found, the first map method title will be used.
1593 if (CurrentForm
->FormTitle
== 0) {
1594 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1595 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1598 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1599 if ( ConditionalExprCount
> 0) {
1601 // Form is inside of suppressif
1603 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1604 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1605 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1606 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1607 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1608 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1613 // Enter scope of a Form, suppressif will be used for Question or Option
1615 SuppressForQuestion
= TRUE
;
1619 // Insert into Form list of this FormSet
1621 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1627 case EFI_IFR_VARSTORE_OP
:
1629 // Create a buffer Storage for this FormSet
1631 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_BUFFER
, OpCodeData
);
1632 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1635 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1637 // Create a name/value Storage for this FormSet
1639 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_NAME_VALUE
, OpCodeData
);
1640 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1643 case EFI_IFR_VARSTORE_EFI_OP
:
1645 // Create a EFI variable Storage for this FormSet
1647 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1649 // Create efi varstore with format follow UEFI spec before 2.3.1.
1651 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE
, OpCodeData
);
1654 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1656 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
, OpCodeData
);
1658 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1664 case EFI_IFR_DEFAULTSTORE_OP
:
1665 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1666 ASSERT (DefaultStore
!= NULL
);
1667 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1669 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1670 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1673 // Insert to DefaultStore list of this Formset
1675 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1681 case EFI_IFR_SUBTITLE_OP
:
1682 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1683 ASSERT (CurrentStatement
!= NULL
);
1685 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1686 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1688 mInScopeSubtitle
= TRUE
;
1692 case EFI_IFR_TEXT_OP
:
1693 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1694 ASSERT (CurrentStatement
!= NULL
);
1695 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1696 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1699 case EFI_IFR_RESET_BUTTON_OP
:
1700 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1701 ASSERT (CurrentStatement
!= NULL
);
1702 CurrentStatement
->FakeQuestionId
= mUsedQuestionId
++;
1703 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1709 case EFI_IFR_ACTION_OP
:
1710 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1711 ASSERT (CurrentStatement
!= NULL
);
1712 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1714 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1716 // No QuestionConfig present, so no configuration string will be processed
1718 CurrentStatement
->QuestionConfig
= 0;
1720 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1724 case EFI_IFR_REF_OP
:
1725 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1726 ASSERT (CurrentStatement
!= NULL
);
1727 Value
= &CurrentStatement
->HiiValue
;
1728 Value
->Type
= EFI_IFR_TYPE_REF
;
1729 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1730 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1732 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1733 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1735 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1736 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1738 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1739 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1744 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
1745 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1748 case EFI_IFR_ONE_OF_OP
:
1749 case EFI_IFR_NUMERIC_OP
:
1750 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1751 ASSERT(CurrentStatement
!= NULL
);
1753 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1754 Value
= &CurrentStatement
->HiiValue
;
1756 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1757 case EFI_IFR_NUMERIC_SIZE_1
:
1758 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1759 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1760 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1761 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1762 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1765 case EFI_IFR_NUMERIC_SIZE_2
:
1766 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1767 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1768 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1769 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1770 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1773 case EFI_IFR_NUMERIC_SIZE_4
:
1774 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1775 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1776 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1777 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1778 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1781 case EFI_IFR_NUMERIC_SIZE_8
:
1782 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1783 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1784 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1785 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1786 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1793 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1795 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1796 SuppressForOption
= TRUE
;
1800 case EFI_IFR_ORDERED_LIST_OP
:
1801 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1802 ASSERT(CurrentStatement
!= NULL
);
1804 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1805 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1807 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1808 CurrentStatement
->BufferValue
= NULL
;
1811 SuppressForOption
= TRUE
;
1815 case EFI_IFR_CHECKBOX_OP
:
1816 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1817 ASSERT(CurrentStatement
!= NULL
);
1819 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1820 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1821 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1823 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1827 case EFI_IFR_STRING_OP
:
1828 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1829 ASSERT (CurrentStatement
!= NULL
);
1831 // MinSize is the minimum number of characters that can be accepted for this opcode,
1832 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1833 // The characters are stored as Unicode, so the storage width should multiply 2.
1835 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1836 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1837 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1838 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1840 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1841 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1842 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1844 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1847 case EFI_IFR_PASSWORD_OP
:
1848 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1849 ASSERT (CurrentStatement
!= NULL
);
1851 // MinSize is the minimum number of characters that can be accepted for this opcode,
1852 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1853 // The characters are stored as Unicode, so the storage width should multiply 2.
1855 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1856 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1857 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1859 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1860 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1861 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1863 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1866 case EFI_IFR_DATE_OP
:
1867 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1868 ASSERT(CurrentStatement
!= NULL
);
1870 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1871 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1873 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1874 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1876 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1879 // Don't assign storage for RTC type of date/time
1881 CurrentStatement
->Storage
= NULL
;
1882 CurrentStatement
->StorageWidth
= 0;
1886 case EFI_IFR_TIME_OP
:
1887 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1888 ASSERT(CurrentStatement
!= NULL
);
1890 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1891 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1893 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1894 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1896 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1899 // Don't assign storage for RTC type of date/time
1901 CurrentStatement
->Storage
= NULL
;
1902 CurrentStatement
->StorageWidth
= 0;
1909 case EFI_IFR_DEFAULT_OP
:
1911 // EFI_IFR_DEFAULT appear in scope of a Question,
1912 // It creates a default value for the current question.
1913 // A Question may have more than one Default value which have different default types.
1915 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1916 ASSERT (CurrentDefault
!= NULL
);
1917 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1919 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1920 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1921 if (OpCodeLength
> OFFSET_OF (EFI_IFR_DEFAULT
, Value
)) {
1922 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
1923 ExtendValueToU64 (&CurrentDefault
->Value
);
1927 // Insert to Default Value list of current Question
1929 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1932 InScopeDefault
= TRUE
;
1939 case EFI_IFR_ONE_OF_OPTION_OP
:
1941 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1942 // It create a selection for use in current Question.
1944 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1945 ASSERT (CurrentOption
!= NULL
);
1946 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1947 CurrentOption
->OpCode
= (EFI_IFR_ONE_OF_OPTION
*) OpCodeData
;
1949 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1950 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1951 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1952 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
1953 ExtendValueToU64 (&CurrentOption
->Value
);
1955 ConditionalExprCount
= GetConditionalExpressionCount(ExpressOption
);
1956 if ( ConditionalExprCount
> 0) {
1958 // Form is inside of suppressif
1960 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1961 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1962 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
1963 CurrentOption
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1964 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1965 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressOption
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1969 // Insert to Option list of current Question
1971 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1974 // Now we know the Storage width of nested Ordered List
1976 ASSERT (CurrentStatement
!= NULL
);
1977 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1979 switch (CurrentOption
->Value
.Type
) {
1980 case EFI_IFR_TYPE_NUM_SIZE_8
:
1984 case EFI_IFR_TYPE_NUM_SIZE_16
:
1988 case EFI_IFR_TYPE_NUM_SIZE_32
:
1992 case EFI_IFR_TYPE_NUM_SIZE_64
:
1998 // Invalid type for Ordered List
2003 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
2004 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
2005 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
2006 if (CurrentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
2007 CurrentStatement
->HiiValue
.Buffer
= CurrentStatement
->BufferValue
;
2008 CurrentStatement
->HiiValue
.BufferLen
= CurrentStatement
->StorageWidth
;
2011 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
2018 case EFI_IFR_NO_SUBMIT_IF_OP
:
2019 case EFI_IFR_INCONSISTENT_IF_OP
:
2021 // Create an Expression node
2023 CurrentExpression
= CreateExpression (CurrentForm
);
2024 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
2026 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
2027 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
2028 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
2030 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
2031 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
2035 // Take a look at next OpCode to see whether current expression consists
2038 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2039 SingleOpCodeExpression
= TRUE
;
2043 case EFI_IFR_WARNING_IF_OP
:
2045 // Create an Expression node
2047 CurrentExpression
= CreateExpression (CurrentForm
);
2048 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_WARNING_IF
*) OpCodeData
)->Warning
, sizeof (EFI_STRING_ID
));
2049 CurrentExpression
->TimeOut
= ((EFI_IFR_WARNING_IF
*) OpCodeData
)->TimeOut
;
2050 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WARNING_IF
;
2051 InsertTailList (&CurrentStatement
->WarningListHead
, &CurrentExpression
->Link
);
2054 // Take a look at next OpCode to see whether current expression consists
2057 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2058 SingleOpCodeExpression
= TRUE
;
2062 case EFI_IFR_SUPPRESS_IF_OP
:
2064 // Question and Option will appear in scope of this OpCode
2066 CurrentExpression
= CreateExpression (CurrentForm
);
2067 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
2069 if (CurrentForm
== NULL
) {
2070 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
2072 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2075 if (SuppressForOption
) {
2076 PushConditionalExpression(CurrentExpression
, ExpressOption
);
2077 } else if (SuppressForQuestion
) {
2078 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2080 PushConditionalExpression(CurrentExpression
, ExpressForm
);
2084 // Take a look at next OpCode to see whether current expression consists
2087 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2088 SingleOpCodeExpression
= TRUE
;
2092 case EFI_IFR_GRAY_OUT_IF_OP
:
2094 // Questions will appear in scope of this OpCode
2096 CurrentExpression
= CreateExpression (CurrentForm
);
2097 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
2098 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2099 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2102 // Take a look at next OpCode to see whether current expression consists
2105 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2106 SingleOpCodeExpression
= TRUE
;
2110 case EFI_IFR_DISABLE_IF_OP
:
2112 // The DisableIf expression should only rely on constant, so it could be
2113 // evaluated at initialization and it will not be queued
2115 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
2116 ASSERT (CurrentExpression
!= NULL
);
2117 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
2118 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
2119 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
2121 if (CurrentForm
!= NULL
) {
2123 // This is DisableIf for Question, enqueue it to Form expression list
2125 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2126 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2129 OpCodeDisabled
= FALSE
;
2130 InScopeDisable
= TRUE
;
2132 // Take a look at next OpCode to see whether current expression consists
2135 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2136 SingleOpCodeExpression
= TRUE
;
2143 case EFI_IFR_VALUE_OP
:
2144 CurrentExpression
= CreateExpression (CurrentForm
);
2145 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
2146 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2148 if (InScopeDefault
) {
2150 // Used for default (EFI_IFR_DEFAULT)
2152 CurrentDefault
->ValueExpression
= CurrentExpression
;
2155 // If used for a question, then the question will be read-only
2158 // Make sure CurrentStatement is not NULL.
2159 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2160 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2162 ASSERT (CurrentStatement
!= NULL
);
2163 CurrentStatement
->ValueExpression
= CurrentExpression
;
2167 // Take a look at next OpCode to see whether current expression consists
2170 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2171 SingleOpCodeExpression
= TRUE
;
2175 case EFI_IFR_RULE_OP
:
2176 CurrentExpression
= CreateExpression (CurrentForm
);
2177 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2179 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2180 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2183 // Take a look at next OpCode to see whether current expression consists
2186 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2187 SingleOpCodeExpression
= TRUE
;
2191 case EFI_IFR_READ_OP
:
2192 CurrentExpression
= CreateExpression (CurrentForm
);
2193 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2194 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2197 // Make sure CurrentStatement is not NULL.
2198 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2199 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2201 ASSERT (CurrentStatement
!= NULL
);
2202 CurrentStatement
->ReadExpression
= CurrentExpression
;
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
;
2213 case EFI_IFR_WRITE_OP
:
2214 CurrentExpression
= CreateExpression (CurrentForm
);
2215 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2216 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2219 // Make sure CurrentStatement is not NULL.
2220 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2221 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2223 ASSERT (CurrentStatement
!= NULL
);
2224 CurrentStatement
->WriteExpression
= CurrentExpression
;
2227 // Take a look at next OpCode to see whether current expression consists
2230 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2231 SingleOpCodeExpression
= TRUE
;
2238 case EFI_IFR_IMAGE_OP
:
2240 // Get ScopeOpcode from top of stack
2242 PopScope (&ScopeOpCode
);
2243 PushScope (ScopeOpCode
);
2245 switch (ScopeOpCode
) {
2246 case EFI_IFR_FORM_SET_OP
:
2247 ImageId
= &FormSet
->ImageId
;
2250 case EFI_IFR_FORM_OP
:
2251 case EFI_IFR_FORM_MAP_OP
:
2252 ASSERT (CurrentForm
!= NULL
);
2253 ImageId
= &CurrentForm
->ImageId
;
2256 case EFI_IFR_ONE_OF_OPTION_OP
:
2257 ImageId
= &CurrentOption
->ImageId
;
2262 // Make sure CurrentStatement is not NULL.
2263 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2264 // file is wrongly generated by tools such as VFR Compiler.
2266 ASSERT (CurrentStatement
!= NULL
);
2267 ImageId
= &CurrentStatement
->ImageId
;
2271 ASSERT (ImageId
!= NULL
);
2272 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2278 case EFI_IFR_REFRESH_OP
:
2279 ASSERT (CurrentStatement
!= NULL
);
2280 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2286 case EFI_IFR_REFRESH_ID_OP
:
2287 ASSERT (CurrentStatement
!= NULL
);
2288 CopyMem (&CurrentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2294 case EFI_IFR_MODAL_TAG_OP
:
2295 ASSERT (CurrentForm
!= NULL
);
2296 CurrentForm
->ModalForm
= TRUE
;
2300 // Lock tag, used by form and statement.
2302 case EFI_IFR_LOCKED_OP
:
2304 // Get ScopeOpcode from top of stack
2306 PopScope (&ScopeOpCode
);
2307 PushScope (ScopeOpCode
);
2308 switch (ScopeOpCode
) {
2309 case EFI_IFR_FORM_OP
:
2310 case EFI_IFR_FORM_MAP_OP
:
2311 ASSERT (CurrentForm
!= NULL
);
2312 CurrentForm
->Locked
= TRUE
;
2316 ASSERT (CurrentStatement
!= NULL
);
2317 CurrentStatement
->Locked
= TRUE
;
2324 case EFI_IFR_GUID_OP
:
2325 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2331 case EFI_IFR_END_OP
:
2332 Status
= PopScope (&ScopeOpCode
);
2333 if (EFI_ERROR (Status
)) {
2338 switch (ScopeOpCode
) {
2339 case EFI_IFR_FORM_SET_OP
:
2341 // End of FormSet, update FormSet IFR binary length
2342 // to stop parsing substantial OpCodes
2344 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2347 case EFI_IFR_FORM_OP
:
2348 case EFI_IFR_FORM_MAP_OP
:
2353 SuppressForQuestion
= FALSE
;
2356 case EFI_IFR_ONE_OF_OPTION_OP
:
2360 CurrentOption
= NULL
;
2363 case EFI_IFR_SUBTITLE_OP
:
2364 mInScopeSubtitle
= FALSE
;
2367 case EFI_IFR_NO_SUBMIT_IF_OP
:
2368 case EFI_IFR_INCONSISTENT_IF_OP
:
2369 case EFI_IFR_WARNING_IF_OP
:
2371 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2375 case EFI_IFR_SUPPRESS_IF_OP
:
2376 if (SuppressForOption
) {
2377 PopConditionalExpression(ExpressOption
);
2378 } else if (SuppressForQuestion
) {
2379 PopConditionalExpression(ExpressStatement
);
2381 PopConditionalExpression(ExpressForm
);
2385 case EFI_IFR_GRAY_OUT_IF_OP
:
2386 PopConditionalExpression(ExpressStatement
);
2389 case EFI_IFR_DISABLE_IF_OP
:
2390 if (CurrentForm
!= NULL
) {
2391 PopConditionalExpression(ExpressStatement
);
2393 InScopeDisable
= FALSE
;
2394 OpCodeDisabled
= FALSE
;
2397 case EFI_IFR_ONE_OF_OP
:
2398 case EFI_IFR_ORDERED_LIST_OP
:
2399 SuppressForOption
= FALSE
;
2402 case EFI_IFR_DEFAULT_OP
:
2403 InScopeDefault
= FALSE
;
2406 case EFI_IFR_MAP_OP
:
2408 // Get current Map Expression List.
2410 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2411 if (Status
== EFI_ACCESS_DENIED
) {
2412 MapExpressionList
= NULL
;
2415 // Get current expression.
2417 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2418 ASSERT_EFI_ERROR (Status
);
2419 ASSERT (MapScopeDepth
> 0);
2424 if (IsExpressionOpCode (ScopeOpCode
)) {
2425 if (InScopeDisable
&& CurrentForm
== NULL
) {
2427 // This is DisableIf expression for Form, it should be a constant expression
2429 ASSERT (CurrentExpression
!= NULL
);
2430 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2431 if (EFI_ERROR (Status
)) {
2435 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2436 return EFI_INVALID_PARAMETER
;
2439 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2441 // DisableIf Expression is only used once and not queued, free it
2443 DestroyExpression (CurrentExpression
);
2447 // End of current Expression
2449 CurrentExpression
= NULL
;