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
;
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 // We are currently not in a Form Scope, so just skip this Statement
50 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
53 InitializeListHead (&Statement
->DefaultListHead
);
54 InitializeListHead (&Statement
->OptionListHead
);
55 InitializeListHead (&Statement
->InconsistentListHead
);
56 InitializeListHead (&Statement
->NoSubmitListHead
);
58 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
60 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
62 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
63 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
64 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
66 ConditionalExprCount
= GetConditionalExpressionCount(ExpressStatement
);
67 if (ConditionalExprCount
> 0) {
69 // Form is inside of suppressif
72 Statement
->Expression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
73 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
74 ASSERT (Statement
->Expression
!= NULL
);
75 Statement
->Expression
->Count
= (UINTN
) ConditionalExprCount
;
76 Statement
->Expression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
77 CopyMem (Statement
->Expression
->Expression
, GetConditionalExpressionList(ExpressStatement
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
80 Statement
->InSubtitle
= mInScopeSubtitle
;
83 // Insert this Statement into current Form
85 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
91 Convert a numeric value to a Unicode String and insert it to String Package.
92 This string is used as the Unicode Name for the EFI Variable. This is to support
93 the deprecated vareqval opcode.
95 @param FormSet The FormSet.
96 @param Statement The numeric question whose VarStoreInfo.VarName is the
97 numeric value which is used to produce the Unicode Name
100 If the Statement is NULL, the ASSERT.
101 If the opcode is not Numeric, then ASSERT.
103 @retval EFI_SUCCESS The funtion always succeeds.
106 UpdateCheckBoxStringToken (
107 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
108 IN FORM_BROWSER_STATEMENT
*Statement
111 CHAR16 Str
[MAXIMUM_VALUE_CHARACTERS
];
114 ASSERT (Statement
!= NULL
);
115 ASSERT (Statement
->Operand
== EFI_IFR_NUMERIC_OP
);
117 UnicodeValueToString (Str
, 0, Statement
->VarStoreInfo
.VarName
, MAXIMUM_VALUE_CHARACTERS
- 1);
119 Id
= HiiSetString (FormSet
->HiiHandle
, 0, Str
, NULL
);
121 return EFI_OUT_OF_RESOURCES
;
124 Statement
->VarStoreInfo
.VarName
= Id
;
130 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
132 @param OpCodeData The current opcode.
138 IsNextOpCodeGuidedVarEqName (
145 OpCodeData
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
146 if (*OpCodeData
== EFI_IFR_GUID_OP
) {
147 if (CompareGuid (&gEfiIfrFrameworkGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
149 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
151 if ((((EFI_IFR_GUID_VAREQNAME
*) OpCodeData
)->ExtendOpCode
) == EFI_IFR_EXTEND_OP_VAREQNAME
) {
161 Initialize Question's members.
163 @param OpCodeData Pointer of the raw OpCode data.
164 @param FormSet Pointer of the current FormSet.
165 @param Form Pointer of the current Form.
167 @return The Question.
170 FORM_BROWSER_STATEMENT
*
172 IN UINT8
*OpCodeData
,
173 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
174 IN OUT FORM_BROWSER_FORM
*Form
177 FORM_BROWSER_STATEMENT
*Statement
;
178 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
180 FORMSET_STORAGE
*Storage
;
181 NAME_VALUE_NODE
*NameValueNode
;
185 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
186 if (Statement
== NULL
) {
190 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
191 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
192 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
193 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
195 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
197 if (Statement
->VarStoreId
== 0) {
199 // VarStoreId of zero indicates no variable storage
205 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
206 // Framework Compatibility
208 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
209 if ((*OpCodeData
== EFI_IFR_NUMERIC_OP
) && IsNextOpCodeGuidedVarEqName (OpCodeData
)) {
210 Status
= UpdateCheckBoxStringToken (FormSet
, Statement
);
211 if (EFI_ERROR (Status
)) {
218 // Find Storage for this Question
220 Link
= GetFirstNode (&FormSet
->StorageListHead
);
221 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
222 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
224 if (Storage
->VarStoreId
== Statement
->VarStoreId
) {
225 Statement
->Storage
= Storage
->BrowserStorage
;
229 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
231 ASSERT (Statement
->Storage
!= NULL
);
234 // Initialilze varname for Name/Value or EFI Variable
236 if ((Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) ||
237 (Statement
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
238 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
239 ASSERT (Statement
->VariableName
!= NULL
);
241 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
243 // Check whether old string node already exist.
246 if (!IsListEmpty(&Statement
->Storage
->NameValueListHead
)) {
247 Link
= GetFirstNode (&Statement
->Storage
->NameValueListHead
);
248 while (!IsNull (&Statement
->Storage
->NameValueListHead
, Link
)) {
249 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
251 if (StrCmp (Statement
->VariableName
, NameValueNode
->Name
) == 0) {
256 Link
= GetNextNode (&Statement
->Storage
->NameValueListHead
, Link
);
262 // Insert to Name/Value varstore list
264 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
265 ASSERT (NameValueNode
!= NULL
);
266 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
267 NameValueNode
->Name
= AllocateCopyPool (StrSize (Statement
->VariableName
), Statement
->VariableName
);
268 ASSERT (NameValueNode
->Name
!= NULL
);
269 NameValueNode
->Value
= AllocateZeroPool (0x10);
270 ASSERT (NameValueNode
->Value
!= NULL
);
271 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
272 ASSERT (NameValueNode
->EditValue
!= NULL
);
274 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
284 Allocate a FORM_EXPRESSION node.
286 @param Form The Form associated with this Expression
288 @return Pointer to a FORM_EXPRESSION data structure.
293 IN OUT FORM_BROWSER_FORM
*Form
296 FORM_EXPRESSION
*Expression
;
298 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
299 ASSERT (Expression
!= NULL
);
300 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
301 InitializeListHead (&Expression
->OpCodeListHead
);
307 Create ConfigHdr string for a storage.
309 @param FormSet Pointer of the current FormSet
310 @param Storage Pointer of the storage
312 @retval EFI_SUCCESS Initialize ConfigHdr success
316 InitializeConfigHdr (
317 IN FORM_BROWSER_FORMSET
*FormSet
,
318 IN OUT BROWSER_STORAGE
*Storage
323 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
324 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
325 Name
= Storage
->Name
;
330 Storage
->ConfigHdr
= HiiConstructConfigHdr (
333 FormSet
->DriverHandle
336 if (Storage
->ConfigHdr
== NULL
) {
337 return EFI_NOT_FOUND
;
344 Find the global storage link base on the input storate type, name and guid.
346 @param StorageType Storage type.
347 @param StorageGuid Storage guid.
348 @param StorageName Storage Name.
350 @return Pointer to a GLOBAL_STORAGE data structure.
355 IN UINT8 StorageType
,
356 IN EFI_GUID
*StorageGuid
,
357 IN CHAR16
*StorageName
361 BROWSER_STORAGE
*BrowserStorage
;
363 Link
= GetFirstNode (&gBrowserStorageList
);
364 while (!IsNull (&gBrowserStorageList
, Link
)) {
365 BrowserStorage
= BROWSER_STORAGE_FROM_LINK (Link
);
367 if ((BrowserStorage
->Type
== StorageType
) && CompareGuid (&BrowserStorage
->Guid
, StorageGuid
)) {
368 if (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
) {
369 return BrowserStorage
;
372 if (StrCmp (BrowserStorage
->Name
, StorageName
) == 0) {
373 return BrowserStorage
;
380 Link
= GetNextNode (&gBrowserStorageList
, Link
);
387 Intialize the Global Storage.
389 @param BrowserStorage Pointer to the global storage.
390 @param StorageType Storage type.
391 @param OpCodeData Binary data for this opcode.
395 IntializeBrowserStorage (
396 IN BROWSER_STORAGE
*BrowserStorage
,
397 IN UINT8 StorageType
,
401 switch (StorageType
) {
402 case EFI_HII_VARSTORE_BUFFER
:
403 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
404 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
406 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
407 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
410 case EFI_HII_VARSTORE_EFI_VARIABLE
:
411 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
412 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
413 CopyMem (&BrowserStorage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
414 CopyMem (&BrowserStorage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
416 if (StorageType
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
417 BrowserStorage
->Buffer
= AllocateZeroPool (BrowserStorage
->Size
);
418 BrowserStorage
->EditBuffer
= AllocateZeroPool (BrowserStorage
->Size
);
422 case EFI_HII_VARSTORE_NAME_VALUE
:
423 CopyMem (&BrowserStorage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
425 InitializeListHead (&BrowserStorage
->NameValueListHead
);
434 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
436 @param FormSet Pointer of the current FormSet
437 @param StorageType Storage type.
438 @param OpCodeData Binary data for this opcode.
440 @return Pointer to a FORMSET_STORAGE data structure.
445 IN FORM_BROWSER_FORMSET
*FormSet
,
446 IN UINT8 StorageType
,
450 FORMSET_STORAGE
*Storage
;
451 CHAR16
*UnicodeString
;
453 BROWSER_STORAGE
*BrowserStorage
;
454 EFI_GUID
*StorageGuid
;
457 UnicodeString
= NULL
;
459 switch (StorageType
) {
460 case EFI_HII_VARSTORE_BUFFER
:
461 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
;
462 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
465 case EFI_HII_VARSTORE_EFI_VARIABLE
:
466 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
467 StorageGuid
= (EFI_GUID
*) (CHAR8
*) &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
;
468 StorageName
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
472 ASSERT (StorageType
== EFI_HII_VARSTORE_NAME_VALUE
);
473 StorageGuid
= &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
;
477 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
478 ASSERT (StorageName
!= NULL
);
480 UnicodeString
= AllocateZeroPool (AsciiStrSize (StorageName
) * 2);
481 ASSERT (UnicodeString
!= NULL
);
482 for (Index
= 0; StorageName
[Index
] != 0; Index
++) {
483 UnicodeString
[Index
] = (CHAR16
) StorageName
[Index
];
487 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
488 ASSERT (Storage
!= NULL
);
489 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
490 InsertTailList (&FormSet
->StorageListHead
, &Storage
->Link
);
492 BrowserStorage
= FindStorageInList(StorageType
, StorageGuid
, UnicodeString
);
493 if (BrowserStorage
== NULL
) {
494 BrowserStorage
= AllocateZeroPool (sizeof (BROWSER_STORAGE
));
495 ASSERT (BrowserStorage
!= NULL
);
497 BrowserStorage
->Signature
= BROWSER_STORAGE_SIGNATURE
;
498 InsertTailList (&gBrowserStorageList
, &BrowserStorage
->Link
);
500 IntializeBrowserStorage (BrowserStorage
, StorageType
, OpCodeData
);
501 BrowserStorage
->Type
= StorageType
;
502 if (StorageType
!= EFI_HII_VARSTORE_NAME_VALUE
) {
503 BrowserStorage
->Name
= UnicodeString
;
506 InitializeConfigHdr (FormSet
, BrowserStorage
);
509 // Add count because one formset storage use this global storage.
511 BrowserStorage
->ReferenceCount
++;
513 Storage
->BrowserStorage
= BrowserStorage
;
514 Storage
->ConfigRequest
= AllocateCopyPool (StrSize (BrowserStorage
->ConfigHdr
), BrowserStorage
->ConfigHdr
);
515 Storage
->SpareStrLen
= 0;
521 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
523 @param FormSet Pointer of the current FormSet.
524 @param Question The Question to be initialized.
525 @param Form Pointer of the current form.
527 @retval EFI_SUCCESS Function success.
528 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
532 InitializeRequestElement (
533 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
534 IN OUT FORM_BROWSER_STATEMENT
*Question
,
535 IN OUT FORM_BROWSER_FORM
*Form
538 BROWSER_STORAGE
*Storage
;
539 FORMSET_STORAGE
*FormsetStorage
;
543 CHAR16 RequestElement
[30];
546 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
548 Storage
= Question
->Storage
;
549 if (Storage
== NULL
) {
550 return EFI_INVALID_PARAMETER
;
553 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
555 // <ConfigRequest> is unnecessary for EFI variable storage,
556 // GetVariable()/SetVariable() will be used to retrieve/save values
562 // Prepare <RequestElement>
564 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
565 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
566 StrLen
= UnicodeSPrint (
568 30 * sizeof (CHAR16
),
569 L
"&OFFSET=%x&WIDTH=%x",
570 Question
->VarStoreInfo
.VarOffset
,
571 Question
->StorageWidth
573 Question
->BlockName
= AllocateCopyPool ((StrLen
+ 1) * sizeof (CHAR16
), RequestElement
);
575 StrLen
= UnicodeSPrint (RequestElement
, 30 * sizeof (CHAR16
), L
"&%s", Question
->VariableName
);
578 if ((Question
->Operand
== EFI_IFR_PASSWORD_OP
) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
580 // Password with CALLBACK flag is stored in encoded format,
581 // so don't need to append it to <ConfigRequest>
587 // Find Formset Storage for this Question
589 FormsetStorage
= NULL
;
590 Link
= GetFirstNode (&FormSet
->StorageListHead
);
591 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
592 FormsetStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
594 if (FormsetStorage
->VarStoreId
== Question
->VarStoreId
) {
598 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
600 ASSERT (FormsetStorage
!= NULL
);
603 // Append <RequestElement> to <ConfigRequest>
605 if (StrLen
> FormsetStorage
->SpareStrLen
) {
607 // Old String buffer is not sufficient for RequestElement, allocate a new one
609 StringSize
= (FormsetStorage
->ConfigRequest
!= NULL
) ? StrSize (FormsetStorage
->ConfigRequest
) : sizeof (CHAR16
);
610 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
611 ASSERT (NewStr
!= NULL
);
612 if (FormsetStorage
->ConfigRequest
!= NULL
) {
613 CopyMem (NewStr
, FormsetStorage
->ConfigRequest
, StringSize
);
614 FreePool (FormsetStorage
->ConfigRequest
);
616 FormsetStorage
->ConfigRequest
= NewStr
;
617 FormsetStorage
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
620 StrCat (FormsetStorage
->ConfigRequest
, RequestElement
);
621 FormsetStorage
->ElementCount
++;
622 FormsetStorage
->SpareStrLen
-= StrLen
;
625 // Update the Config Request info saved in the form.
629 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
630 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
631 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
633 if (ConfigInfo
!= NULL
&& ConfigInfo
->Storage
== Storage
) {
638 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
642 ConfigInfo
= AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST
));
643 ASSERT (ConfigInfo
!= NULL
);
644 ConfigInfo
->Signature
= FORM_BROWSER_CONFIG_REQUEST_SIGNATURE
;
645 ConfigInfo
->ConfigRequest
= AllocateCopyPool (StrSize (Storage
->ConfigHdr
), Storage
->ConfigHdr
);
646 ConfigInfo
->SpareStrLen
= 0;
647 ConfigInfo
->Storage
= Storage
;
648 InsertTailList(&Form
->ConfigRequestHead
, &ConfigInfo
->Link
);
652 // Append <RequestElement> to <ConfigRequest>
654 if (StrLen
> ConfigInfo
->SpareStrLen
) {
656 // Old String buffer is not sufficient for RequestElement, allocate a new one
658 StringSize
= (ConfigInfo
->ConfigRequest
!= NULL
) ? StrSize (ConfigInfo
->ConfigRequest
) : sizeof (CHAR16
);
659 NewStr
= AllocateZeroPool (StringSize
+ CONFIG_REQUEST_STRING_INCREMENTAL
* sizeof (CHAR16
));
660 ASSERT (NewStr
!= NULL
);
661 if (ConfigInfo
->ConfigRequest
!= NULL
) {
662 CopyMem (NewStr
, ConfigInfo
->ConfigRequest
, StringSize
);
663 FreePool (ConfigInfo
->ConfigRequest
);
665 ConfigInfo
->ConfigRequest
= NewStr
;
666 ConfigInfo
->SpareStrLen
= CONFIG_REQUEST_STRING_INCREMENTAL
;
669 StrCat (ConfigInfo
->ConfigRequest
, RequestElement
);
670 ConfigInfo
->ElementCount
++;
671 ConfigInfo
->SpareStrLen
-= StrLen
;
677 Free resources of a Expression.
679 @param FormSet Pointer of the Expression
684 IN FORM_EXPRESSION
*Expression
688 EXPRESSION_OPCODE
*OpCode
;
689 LIST_ENTRY
*SubExpressionLink
;
690 FORM_EXPRESSION
*SubExpression
;
692 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
693 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
694 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
695 RemoveEntryList (&OpCode
->Link
);
697 if (OpCode
->ValueList
!= NULL
) {
698 FreePool (OpCode
->ValueList
);
701 if (OpCode
->ValueName
!= NULL
) {
702 FreePool (OpCode
->ValueName
);
705 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
706 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
707 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
708 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
709 RemoveEntryList(&SubExpression
->Link
);
710 DestroyExpression (SubExpression
);
716 // Free this Expression
718 FreePool (Expression
);
722 Free resources of a storage.
724 @param Storage Pointer of the storage
729 IN FORMSET_STORAGE
*Storage
732 if (Storage
== NULL
) {
736 if (Storage
->ConfigRequest
!= NULL
) {
737 FreePool (Storage
->ConfigRequest
);
741 // Minus the reference to the global storage.
743 ASSERT (Storage
->BrowserStorage
->ReferenceCount
> 0);
744 Storage
->BrowserStorage
->ReferenceCount
--;
751 Free resources of a Statement.
753 @param FormSet Pointer of the FormSet
754 @param Statement Pointer of the Statement
759 IN FORM_BROWSER_FORMSET
*FormSet
,
760 IN OUT FORM_BROWSER_STATEMENT
*Statement
764 QUESTION_DEFAULT
*Default
;
765 QUESTION_OPTION
*Option
;
766 FORM_EXPRESSION
*Expression
;
769 // Free Default value List
771 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
772 Link
= GetFirstNode (&Statement
->DefaultListHead
);
773 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
774 RemoveEntryList (&Default
->Link
);
782 while (!IsListEmpty (&Statement
->OptionListHead
)) {
783 Link
= GetFirstNode (&Statement
->OptionListHead
);
784 Option
= QUESTION_OPTION_FROM_LINK (Link
);
785 if (Option
->SuppressExpression
!= NULL
) {
786 FreePool (Option
->SuppressExpression
);
788 RemoveEntryList (&Option
->Link
);
794 // Free Inconsistent List
796 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
797 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
798 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
799 RemoveEntryList (&Expression
->Link
);
801 DestroyExpression (Expression
);
805 // Free NoSubmit List
807 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
808 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
809 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
810 RemoveEntryList (&Expression
->Link
);
812 DestroyExpression (Expression
);
815 if (Statement
->Expression
!= NULL
) {
816 FreePool (Statement
->Expression
);
819 if (Statement
->VariableName
!= NULL
) {
820 FreePool (Statement
->VariableName
);
822 if (Statement
->BlockName
!= NULL
) {
823 FreePool (Statement
->BlockName
);
825 if (Statement
->BufferValue
!= NULL
) {
826 FreePool (Statement
->BufferValue
);
828 if (Statement
->Operand
== EFI_IFR_STRING_OP
|| Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
829 DeleteString(Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
835 Free resources of a Form.
837 @param FormSet Pointer of the FormSet
838 @param Form Pointer of the Form.
843 IN FORM_BROWSER_FORMSET
*FormSet
,
844 IN OUT FORM_BROWSER_FORM
*Form
848 FORM_EXPRESSION
*Expression
;
849 FORM_BROWSER_STATEMENT
*Statement
;
850 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
853 // Free Form Expressions
855 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
856 Link
= GetFirstNode (&Form
->ExpressionListHead
);
857 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
858 RemoveEntryList (&Expression
->Link
);
860 DestroyExpression (Expression
);
864 // Free Statements/Questions
866 while (!IsListEmpty (&Form
->StatementListHead
)) {
867 Link
= GetFirstNode (&Form
->StatementListHead
);
868 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
869 RemoveEntryList (&Statement
->Link
);
871 DestroyStatement (FormSet
, Statement
);
875 // Free ConfigRequest string.
877 while (!IsListEmpty (&Form
->ConfigRequestHead
)) {
878 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
879 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
880 RemoveEntryList (&ConfigInfo
->Link
);
882 FreePool (ConfigInfo
->ConfigRequest
);
883 FreePool (ConfigInfo
);
886 if (Form
->SuppressExpression
!= NULL
) {
887 FreePool (Form
->SuppressExpression
);
898 Free resources allocated for a FormSet.
900 @param FormSet Pointer of the FormSet
905 IN OUT FORM_BROWSER_FORMSET
*FormSet
909 FORMSET_STORAGE
*Storage
;
910 FORMSET_DEFAULTSTORE
*DefaultStore
;
911 FORM_EXPRESSION
*Expression
;
912 FORM_BROWSER_FORM
*Form
;
914 if (FormSet
->IfrBinaryData
== NULL
) {
916 // Uninitialized FormSet
923 // Free IFR binary buffer
925 FreePool (FormSet
->IfrBinaryData
);
928 // Free FormSet Storage
930 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
931 while (!IsListEmpty (&FormSet
->StorageListHead
)) {
932 Link
= GetFirstNode (&FormSet
->StorageListHead
);
933 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
934 RemoveEntryList (&Storage
->Link
);
936 DestroyStorage (Storage
);
941 // Free FormSet Default Store
943 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
944 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
945 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
946 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
947 RemoveEntryList (&DefaultStore
->Link
);
949 FreePool (DefaultStore
);
954 // Free Formset Expressions
956 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
957 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
958 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
959 RemoveEntryList (&Expression
->Link
);
961 DestroyExpression (Expression
);
967 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
968 while (!IsListEmpty (&FormSet
->FormListHead
)) {
969 Link
= GetFirstNode (&FormSet
->FormListHead
);
970 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
971 RemoveEntryList (&Form
->Link
);
973 DestroyForm (FormSet
, Form
);
977 if (FormSet
->StatementBuffer
!= NULL
) {
978 FreePool (FormSet
->StatementBuffer
);
980 if (FormSet
->ExpressionBuffer
!= NULL
) {
981 FreePool (FormSet
->ExpressionBuffer
);
989 Tell whether this Operand is an Expression OpCode or not
991 @param Operand Operand of an IFR OpCode.
993 @retval TRUE This is an Expression OpCode.
994 @retval FALSE Not an Expression OpCode.
1002 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
1003 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
1004 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
1005 (Operand
== EFI_IFR_CATENATE_OP
) ||
1006 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
1007 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
1008 (Operand
== EFI_IFR_MAP_OP
) ||
1009 (Operand
== EFI_IFR_VERSION_OP
) ||
1010 (Operand
== EFI_IFR_SECURITY_OP
)) {
1019 Calculate number of Statemens(Questions) and Expression OpCodes.
1021 @param FormSet The FormSet to be counted.
1022 @param NumberOfStatement Number of Statemens(Questions)
1023 @param NumberOfExpression Number of Expression OpCodes
1028 IN FORM_BROWSER_FORMSET
*FormSet
,
1029 IN OUT UINT16
*NumberOfStatement
,
1030 IN OUT UINT16
*NumberOfExpression
1033 UINT16 StatementCount
;
1034 UINT16 ExpressionCount
;
1041 ExpressionCount
= 0;
1043 while (Offset
< FormSet
->IfrBinaryLength
) {
1044 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
1045 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1046 Offset
+= OpCodeLen
;
1048 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
1055 *NumberOfStatement
= StatementCount
;
1056 *NumberOfExpression
= ExpressionCount
;
1062 Parse opcodes in the formset IFR binary.
1064 @param FormSet Pointer of the FormSet data structure.
1066 @retval EFI_SUCCESS Opcode parse success.
1067 @retval Other Opcode parse fail.
1072 IN FORM_BROWSER_FORMSET
*FormSet
1076 FORM_BROWSER_FORM
*CurrentForm
;
1077 FORM_BROWSER_STATEMENT
*CurrentStatement
;
1078 EXPRESSION_OPCODE
*ExpressionOpCode
;
1079 FORM_EXPRESSION
*CurrentExpression
;
1086 FORMSET_STORAGE
*Storage
;
1087 FORMSET_DEFAULTSTORE
*DefaultStore
;
1088 QUESTION_DEFAULT
*CurrentDefault
;
1089 QUESTION_OPTION
*CurrentOption
;
1091 UINT16 NumberOfStatement
;
1092 UINT16 NumberOfExpression
;
1093 EFI_IMAGE_ID
*ImageId
;
1094 BOOLEAN SuppressForQuestion
;
1095 BOOLEAN SuppressForOption
;
1096 UINT16 DepthOfDisable
;
1097 BOOLEAN OpCodeDisabled
;
1098 BOOLEAN SingleOpCodeExpression
;
1099 BOOLEAN InScopeDefault
;
1100 EFI_HII_VALUE
*Value
;
1101 EFI_IFR_FORM_MAP_METHOD
*MapMethod
;
1102 UINT8 MapScopeDepth
;
1104 FORMSET_STORAGE
*VarStorage
;
1105 LIST_ENTRY
*MapExpressionList
;
1106 EFI_VARSTORE_ID TempVarstoreId
;
1107 BOOLEAN InScopeDisable
;
1108 INTN ConditionalExprCount
;
1110 mInScopeSubtitle
= FALSE
;
1111 SuppressForQuestion
= FALSE
;
1112 SuppressForOption
= FALSE
;
1113 InScopeDisable
= FALSE
;
1115 OpCodeDisabled
= FALSE
;
1116 SingleOpCodeExpression
= FALSE
;
1117 InScopeDefault
= FALSE
;
1118 CurrentExpression
= NULL
;
1119 CurrentDefault
= NULL
;
1120 CurrentOption
= NULL
;
1126 MapExpressionList
= NULL
;
1128 ConditionalExprCount
= 0;
1131 // Get the number of Statements and Expressions
1133 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
1135 mStatementIndex
= 0;
1136 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
1137 if (FormSet
->StatementBuffer
== NULL
) {
1138 return EFI_OUT_OF_RESOURCES
;
1141 mExpressionOpCodeIndex
= 0;
1142 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
1143 if (FormSet
->ExpressionBuffer
== NULL
) {
1144 return EFI_OUT_OF_RESOURCES
;
1147 InitializeListHead (&FormSet
->StorageListHead
);
1148 InitializeListHead (&FormSet
->DefaultStoreListHead
);
1149 InitializeListHead (&FormSet
->FormListHead
);
1150 InitializeListHead (&FormSet
->ExpressionListHead
);
1151 ResetCurrentExpressionStack ();
1152 ResetMapExpressionListStack ();
1155 CurrentStatement
= NULL
;
1160 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1161 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1163 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1164 OpCodeOffset
+= OpCodeLength
;
1165 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1166 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1169 // If scope bit set, push onto scope stack
1172 PushScope (Operand
);
1175 if (OpCodeDisabled
) {
1177 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1178 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1180 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1182 } else if (Operand
== EFI_IFR_END_OP
) {
1183 Status
= PopScope (&ScopeOpCode
);
1184 if (EFI_ERROR (Status
)) {
1188 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1189 if (DepthOfDisable
== 0) {
1190 InScopeDisable
= FALSE
;
1191 OpCodeDisabled
= FALSE
;
1200 if (IsExpressionOpCode (Operand
)) {
1201 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1202 mExpressionOpCodeIndex
++;
1204 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1205 ExpressionOpCode
->Operand
= Operand
;
1206 Value
= &ExpressionOpCode
->Value
;
1209 case EFI_IFR_EQ_ID_VAL_OP
:
1210 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1212 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1213 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1216 case EFI_IFR_EQ_ID_ID_OP
:
1217 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1218 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1221 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1222 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1223 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1224 ExpressionOpCode
->ValueList
= AllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1227 case EFI_IFR_TO_STRING_OP
:
1228 case EFI_IFR_FIND_OP
:
1229 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1232 case EFI_IFR_STRING_REF1_OP
:
1233 Value
->Type
= EFI_IFR_TYPE_STRING
;
1234 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1237 case EFI_IFR_RULE_REF_OP
:
1238 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
1241 case EFI_IFR_SPAN_OP
:
1242 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
1245 case EFI_IFR_THIS_OP
:
1246 ASSERT (CurrentStatement
!= NULL
);
1247 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
1250 case EFI_IFR_SECURITY_OP
:
1251 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
1254 case EFI_IFR_GET_OP
:
1255 case EFI_IFR_SET_OP
:
1256 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
1257 if (TempVarstoreId
!= 0) {
1258 if (FormSet
->StorageListHead
.ForwardLink
!= NULL
) {
1259 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1260 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1261 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
1262 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
1263 ExpressionOpCode
->VarStorage
= VarStorage
->BrowserStorage
;
1266 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1269 if (ExpressionOpCode
->VarStorage
== NULL
) {
1271 // VarStorage is not found.
1273 return EFI_INVALID_PARAMETER
;
1276 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
1277 switch (ExpressionOpCode
->ValueType
) {
1278 case EFI_IFR_TYPE_BOOLEAN
:
1279 case EFI_IFR_TYPE_NUM_SIZE_8
:
1280 ExpressionOpCode
->ValueWidth
= 1;
1283 case EFI_IFR_TYPE_NUM_SIZE_16
:
1284 case EFI_IFR_TYPE_STRING
:
1285 ExpressionOpCode
->ValueWidth
= 2;
1288 case EFI_IFR_TYPE_NUM_SIZE_32
:
1289 ExpressionOpCode
->ValueWidth
= 4;
1292 case EFI_IFR_TYPE_NUM_SIZE_64
:
1293 ExpressionOpCode
->ValueWidth
= 8;
1296 case EFI_IFR_TYPE_DATE
:
1297 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
1300 case EFI_IFR_TYPE_TIME
:
1301 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
1304 case EFI_IFR_TYPE_REF
:
1305 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
1308 case EFI_IFR_TYPE_OTHER
:
1309 case EFI_IFR_TYPE_UNDEFINED
:
1310 case EFI_IFR_TYPE_ACTION
:
1311 case EFI_IFR_TYPE_BUFFER
:
1314 // Invalid value type for Get/Set opcode.
1316 return EFI_INVALID_PARAMETER
;
1318 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
1319 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1320 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
1321 (ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
||
1322 ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1323 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->HiiHandle
);
1324 if (ExpressionOpCode
->ValueName
== NULL
) {
1326 // String ID is invalid.
1328 return EFI_INVALID_PARAMETER
;
1333 case EFI_IFR_QUESTION_REF1_OP
:
1334 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1337 case EFI_IFR_QUESTION_REF3_OP
:
1338 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
1339 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1341 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
1342 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
1350 case EFI_IFR_TRUE_OP
:
1351 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1352 Value
->Value
.b
= TRUE
;
1355 case EFI_IFR_FALSE_OP
:
1356 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
1357 Value
->Value
.b
= FALSE
;
1360 case EFI_IFR_ONE_OP
:
1361 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1362 Value
->Value
.u8
= 1;
1365 case EFI_IFR_ZERO_OP
:
1366 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1367 Value
->Value
.u8
= 0;
1370 case EFI_IFR_ONES_OP
:
1371 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1372 Value
->Value
.u64
= 0xffffffffffffffffULL
;
1375 case EFI_IFR_UINT8_OP
:
1376 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1377 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
1380 case EFI_IFR_UINT16_OP
:
1381 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1382 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
1385 case EFI_IFR_UINT32_OP
:
1386 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1387 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
1390 case EFI_IFR_UINT64_OP
:
1391 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1392 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
1395 case EFI_IFR_UNDEFINED_OP
:
1396 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
1399 case EFI_IFR_VERSION_OP
:
1400 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1401 Value
->Value
.u16
= EFI_IFR_SPECIFICATION_VERSION
;
1408 // Create sub expression nested in MAP opcode
1410 if (CurrentExpression
== NULL
&& MapScopeDepth
> 0) {
1411 CurrentExpression
= CreateExpression (CurrentForm
);
1412 ASSERT (MapExpressionList
!= NULL
);
1413 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
1415 SingleOpCodeExpression
= TRUE
;
1418 ASSERT (CurrentExpression
!= NULL
);
1419 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
1420 if (Operand
== EFI_IFR_MAP_OP
) {
1422 // Store current Map Expression List.
1424 if (MapExpressionList
!= NULL
) {
1425 PushMapExpressionList (MapExpressionList
);
1428 // Initialize new Map Expression List.
1430 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
1431 InitializeListHead (MapExpressionList
);
1433 // Store current expression.
1435 PushCurrentExpression (CurrentExpression
);
1436 CurrentExpression
= NULL
;
1438 } else if (SingleOpCodeExpression
) {
1440 // There are two cases to indicate the end of an Expression:
1441 // for single OpCode expression: one Expression OpCode
1442 // for expression consists of more than one OpCode: EFI_IFR_END
1444 SingleOpCodeExpression
= FALSE
;
1446 if (InScopeDisable
&& CurrentForm
== NULL
) {
1448 // This is DisableIf expression for Form, it should be a constant expression
1450 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
1451 if (EFI_ERROR (Status
)) {
1455 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
1456 return EFI_INVALID_PARAMETER
;
1459 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
1462 CurrentExpression
= NULL
;
1473 case EFI_IFR_FORM_SET_OP
:
1475 // Check the formset GUID
1477 if (CompareMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
)) != 0) {
1478 return EFI_INVALID_PARAMETER
;
1481 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1482 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1484 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1486 // The formset OpCode contains ClassGuid
1488 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1489 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
1493 case EFI_IFR_FORM_OP
:
1495 // Create a new Form for this FormSet
1497 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1498 ASSERT (CurrentForm
!= NULL
);
1499 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1500 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1501 InitializeListHead (&CurrentForm
->StatementListHead
);
1502 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1504 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1505 CurrentForm
->NvUpdateRequired
= FALSE
;
1506 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1507 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
1509 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1510 if ( ConditionalExprCount
> 0) {
1512 // Form is inside of suppressif
1514 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1515 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1516 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1517 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1518 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1519 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1524 // Enter scope of a Form, suppressif will be used for Question or Option
1526 SuppressForQuestion
= TRUE
;
1530 // Insert into Form list of this FormSet
1532 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1535 case EFI_IFR_FORM_MAP_OP
:
1537 // Create a new Form for this FormSet
1539 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
1540 ASSERT (CurrentForm
!= NULL
);
1541 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
1542 CurrentForm
->NvUpdateRequired
= FALSE
;
1543 InitializeListHead (&CurrentForm
->ExpressionListHead
);
1544 InitializeListHead (&CurrentForm
->StatementListHead
);
1545 InitializeListHead (&CurrentForm
->ConfigRequestHead
);
1546 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
1548 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1550 // FormMap Form must contain at least one Map Method.
1552 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
< ((UINTN
) (UINT8
*) (MapMethod
+ 1) - (UINTN
) OpCodeData
)) {
1553 return EFI_INVALID_PARAMETER
;
1556 // Try to find the standard form map method.
1558 while (((UINTN
) (UINT8
*) MapMethod
- (UINTN
) OpCodeData
) < ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
) {
1559 if (CompareGuid ((EFI_GUID
*) (VOID
*) &MapMethod
->MethodIdentifier
, &gEfiHiiStandardFormGuid
)) {
1560 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1561 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
1567 // If the standard form map method is not found, the first map method title will be used.
1569 if (CurrentForm
->FormTitle
== 0) {
1570 MapMethod
= (EFI_IFR_FORM_MAP_METHOD
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_MAP
));
1571 CopyMem (&CurrentForm
->FormTitle
, &MapMethod
->MethodTitle
, sizeof (EFI_STRING_ID
));
1574 ConditionalExprCount
= GetConditionalExpressionCount(ExpressForm
);
1575 if ( ConditionalExprCount
> 0) {
1577 // Form is inside of suppressif
1579 CurrentForm
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1580 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1581 ASSERT (CurrentForm
->SuppressExpression
!= NULL
);
1582 CurrentForm
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1583 CurrentForm
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1584 CopyMem (CurrentForm
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressForm
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1589 // Enter scope of a Form, suppressif will be used for Question or Option
1591 SuppressForQuestion
= TRUE
;
1595 // Insert into Form list of this FormSet
1597 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
1603 case EFI_IFR_VARSTORE_OP
:
1605 // Create a buffer Storage for this FormSet
1607 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_BUFFER
, OpCodeData
);
1608 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1611 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
1613 // Create a name/value Storage for this FormSet
1615 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_NAME_VALUE
, OpCodeData
);
1616 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1619 case EFI_IFR_VARSTORE_EFI_OP
:
1621 // Create a EFI variable Storage for this FormSet
1623 if (OpCodeLength
< sizeof (EFI_IFR_VARSTORE_EFI
)) {
1624 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE
, OpCodeData
);
1626 Storage
= CreateStorage (FormSet
, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
, OpCodeData
);
1628 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1634 case EFI_IFR_DEFAULTSTORE_OP
:
1635 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
1636 ASSERT (DefaultStore
!= NULL
);
1637 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
1639 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1640 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
1643 // Insert to DefaultStore list of this Formset
1645 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
1651 case EFI_IFR_SUBTITLE_OP
:
1652 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1653 ASSERT (CurrentStatement
!= NULL
);
1655 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
1658 mInScopeSubtitle
= TRUE
;
1662 case EFI_IFR_TEXT_OP
:
1663 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1664 ASSERT (CurrentStatement
!= NULL
);
1666 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
1669 case EFI_IFR_RESET_BUTTON_OP
:
1670 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
1671 ASSERT (CurrentStatement
!= NULL
);
1672 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
1678 case EFI_IFR_ACTION_OP
:
1679 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1680 ASSERT (CurrentStatement
!= NULL
);
1681 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
1683 if (OpCodeLength
== sizeof (EFI_IFR_ACTION_1
)) {
1685 // No QuestionConfig present, so no configuration string will be processed
1687 CurrentStatement
->QuestionConfig
= 0;
1689 CopyMem (&CurrentStatement
->QuestionConfig
, &((EFI_IFR_ACTION
*) OpCodeData
)->QuestionConfig
, sizeof (EFI_STRING_ID
));
1693 case EFI_IFR_REF_OP
:
1694 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1695 ASSERT (CurrentStatement
!= NULL
);
1696 Value
= &CurrentStatement
->HiiValue
;
1697 Value
->Type
= EFI_IFR_TYPE_REF
;
1698 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
1699 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
1701 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
1702 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1704 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
1705 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
1707 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
1708 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
1713 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
1714 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1717 case EFI_IFR_ONE_OF_OP
:
1718 case EFI_IFR_NUMERIC_OP
:
1719 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1720 ASSERT(CurrentStatement
!= NULL
);
1722 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
1723 Value
= &CurrentStatement
->HiiValue
;
1725 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
1726 case EFI_IFR_NUMERIC_SIZE_1
:
1727 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
1728 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
1729 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
1730 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
1731 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
1734 case EFI_IFR_NUMERIC_SIZE_2
:
1735 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
1736 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
1737 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
1738 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
1739 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1742 case EFI_IFR_NUMERIC_SIZE_4
:
1743 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
1744 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
1745 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
1746 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
1747 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
1750 case EFI_IFR_NUMERIC_SIZE_8
:
1751 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
1752 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
1753 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
1754 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
1755 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
1762 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1764 if ((Operand
== EFI_IFR_ONE_OF_OP
) && Scope
!= 0) {
1765 SuppressForOption
= TRUE
;
1769 case EFI_IFR_ORDERED_LIST_OP
:
1770 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1771 ASSERT(CurrentStatement
!= NULL
);
1773 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
1774 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
1776 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
1777 CurrentStatement
->BufferValue
= NULL
;
1780 SuppressForOption
= TRUE
;
1784 case EFI_IFR_CHECKBOX_OP
:
1785 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1786 ASSERT(CurrentStatement
!= NULL
);
1788 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
1789 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
1790 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
1792 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1796 case EFI_IFR_STRING_OP
:
1797 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1798 ASSERT (CurrentStatement
!= NULL
);
1800 // MinSize is the minimum number of characters that can be accepted for this opcode,
1801 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1802 // The characters are stored as Unicode, so the storage width should multiply 2.
1804 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
1805 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
1806 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1807 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
1809 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1810 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
1811 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1813 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1816 case EFI_IFR_PASSWORD_OP
:
1817 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1818 ASSERT (CurrentStatement
!= NULL
);
1820 // MinSize is the minimum number of characters that can be accepted for this opcode,
1821 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1822 // The characters are stored as Unicode, so the storage width should multiply 2.
1824 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
1825 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
1826 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
1828 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
1829 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
1830 CurrentStatement
->HiiValue
.Value
.string
= NewString ((CHAR16
*) CurrentStatement
->BufferValue
, FormSet
->HiiHandle
);
1832 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1835 case EFI_IFR_DATE_OP
:
1836 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1837 ASSERT(CurrentStatement
!= NULL
);
1839 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
1840 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
1842 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
1843 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
1845 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1848 // Don't assign storage for RTC type of date/time
1850 CurrentStatement
->Storage
= NULL
;
1851 CurrentStatement
->StorageWidth
= 0;
1855 case EFI_IFR_TIME_OP
:
1856 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
1857 ASSERT(CurrentStatement
!= NULL
);
1859 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
1860 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
1862 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
1863 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
1865 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1868 // Don't assign storage for RTC type of date/time
1870 CurrentStatement
->Storage
= NULL
;
1871 CurrentStatement
->StorageWidth
= 0;
1878 case EFI_IFR_DEFAULT_OP
:
1880 // EFI_IFR_DEFAULT appear in scope of a Question,
1881 // It creates a default value for the current question.
1882 // A Question may have more than one Default value which have different default types.
1884 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
1885 ASSERT (CurrentDefault
!= NULL
);
1886 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
1888 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
1889 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
1890 if (OpCodeLength
> OFFSET_OF (EFI_IFR_DEFAULT
, Value
)) {
1891 CopyMem (&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
));
1892 ExtendValueToU64 (&CurrentDefault
->Value
);
1896 // Insert to Default Value list of current Question
1898 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
1901 InScopeDefault
= TRUE
;
1908 case EFI_IFR_ONE_OF_OPTION_OP
:
1910 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1911 // It create a selection for use in current Question.
1913 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
1914 ASSERT (CurrentOption
!= NULL
);
1915 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
1917 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
1918 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
1919 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
1920 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
1921 ExtendValueToU64 (&CurrentOption
->Value
);
1923 ConditionalExprCount
= GetConditionalExpressionCount(ExpressOption
);
1924 if ( ConditionalExprCount
> 0) {
1926 // Form is inside of suppressif
1928 CurrentOption
->SuppressExpression
= (FORM_EXPRESSION_LIST
*) AllocatePool(
1929 (UINTN
) (sizeof(FORM_EXPRESSION_LIST
) + ((ConditionalExprCount
-1) * sizeof(FORM_EXPRESSION
*))));
1930 ASSERT (CurrentOption
->SuppressExpression
!= NULL
);
1931 CurrentOption
->SuppressExpression
->Count
= (UINTN
) ConditionalExprCount
;
1932 CurrentOption
->SuppressExpression
->Signature
= FORM_EXPRESSION_LIST_SIGNATURE
;
1933 CopyMem (CurrentOption
->SuppressExpression
->Expression
, GetConditionalExpressionList(ExpressOption
), (UINTN
) (sizeof (FORM_EXPRESSION
*) * ConditionalExprCount
));
1937 // Insert to Option list of current Question
1939 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
1942 // Now we know the Storage width of nested Ordered List
1944 ASSERT (CurrentStatement
!= NULL
);
1945 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
1947 switch (CurrentOption
->Value
.Type
) {
1948 case EFI_IFR_TYPE_NUM_SIZE_8
:
1952 case EFI_IFR_TYPE_NUM_SIZE_16
:
1956 case EFI_IFR_TYPE_NUM_SIZE_32
:
1960 case EFI_IFR_TYPE_NUM_SIZE_64
:
1966 // Invalid type for Ordered List
1971 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
1972 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
1973 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
1974 if (CurrentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
1975 CurrentStatement
->HiiValue
.Buffer
= CurrentStatement
->BufferValue
;
1976 CurrentStatement
->HiiValue
.BufferLen
= CurrentStatement
->StorageWidth
;
1979 InitializeRequestElement (FormSet
, CurrentStatement
, CurrentForm
);
1986 case EFI_IFR_NO_SUBMIT_IF_OP
:
1987 case EFI_IFR_INCONSISTENT_IF_OP
:
1989 // Create an Expression node
1991 CurrentExpression
= CreateExpression (CurrentForm
);
1992 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
1994 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
1995 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
1996 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
1998 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
1999 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
2003 // Take a look at next OpCode to see whether current expression consists
2006 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2007 SingleOpCodeExpression
= TRUE
;
2011 case EFI_IFR_SUPPRESS_IF_OP
:
2013 // Question and Option will appear in scope of this OpCode
2015 CurrentExpression
= CreateExpression (CurrentForm
);
2016 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
2018 if (CurrentForm
== NULL
) {
2019 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
2021 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2024 if (SuppressForOption
) {
2025 PushConditionalExpression(CurrentExpression
, ExpressOption
);
2026 } else if (SuppressForQuestion
) {
2027 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2029 PushConditionalExpression(CurrentExpression
, ExpressForm
);
2033 // Take a look at next OpCode to see whether current expression consists
2036 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2037 SingleOpCodeExpression
= TRUE
;
2041 case EFI_IFR_GRAY_OUT_IF_OP
:
2043 // Questions will appear in scope of this OpCode
2045 CurrentExpression
= CreateExpression (CurrentForm
);
2046 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
2047 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2048 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2051 // Take a look at next OpCode to see whether current expression consists
2054 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2055 SingleOpCodeExpression
= TRUE
;
2059 case EFI_IFR_DISABLE_IF_OP
:
2061 // The DisableIf expression should only rely on constant, so it could be
2062 // evaluated at initialization and it will not be queued
2064 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
2065 ASSERT (CurrentExpression
!= NULL
);
2066 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
2067 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
2068 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
2070 if (CurrentForm
!= NULL
) {
2072 // This is DisableIf for Question, enqueue it to Form expression list
2074 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2075 PushConditionalExpression(CurrentExpression
, ExpressStatement
);
2078 OpCodeDisabled
= FALSE
;
2079 InScopeDisable
= TRUE
;
2081 // Take a look at next OpCode to see whether current expression consists
2084 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2085 SingleOpCodeExpression
= TRUE
;
2092 case EFI_IFR_VALUE_OP
:
2093 CurrentExpression
= CreateExpression (CurrentForm
);
2094 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
2095 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2097 if (InScopeDefault
) {
2099 // Used for default (EFI_IFR_DEFAULT)
2101 CurrentDefault
->ValueExpression
= CurrentExpression
;
2104 // If used for a question, then the question will be read-only
2107 // Make sure CurrentStatement is not NULL.
2108 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2109 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2111 ASSERT (CurrentStatement
!= NULL
);
2112 CurrentStatement
->ValueExpression
= CurrentExpression
;
2116 // Take a look at next OpCode to see whether current expression consists
2119 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2120 SingleOpCodeExpression
= TRUE
;
2124 case EFI_IFR_RULE_OP
:
2125 CurrentExpression
= CreateExpression (CurrentForm
);
2126 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
2128 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
2129 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
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
;
2140 case EFI_IFR_READ_OP
:
2141 CurrentExpression
= CreateExpression (CurrentForm
);
2142 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
2143 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2146 // Make sure CurrentStatement is not NULL.
2147 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2148 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2150 ASSERT (CurrentStatement
!= NULL
);
2151 CurrentStatement
->ReadExpression
= CurrentExpression
;
2154 // Take a look at next OpCode to see whether current expression consists
2157 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2158 SingleOpCodeExpression
= TRUE
;
2162 case EFI_IFR_WRITE_OP
:
2163 CurrentExpression
= CreateExpression (CurrentForm
);
2164 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
2165 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2168 // Make sure CurrentStatement is not NULL.
2169 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2170 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2172 ASSERT (CurrentStatement
!= NULL
);
2173 CurrentStatement
->WriteExpression
= CurrentExpression
;
2176 // Take a look at next OpCode to see whether current expression consists
2179 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2180 SingleOpCodeExpression
= TRUE
;
2187 case EFI_IFR_IMAGE_OP
:
2189 // Get ScopeOpcode from top of stack
2191 PopScope (&ScopeOpCode
);
2192 PushScope (ScopeOpCode
);
2194 switch (ScopeOpCode
) {
2195 case EFI_IFR_FORM_SET_OP
:
2196 ImageId
= &FormSet
->ImageId
;
2199 case EFI_IFR_FORM_OP
:
2200 case EFI_IFR_FORM_MAP_OP
:
2201 ASSERT (CurrentForm
!= NULL
);
2202 ImageId
= &CurrentForm
->ImageId
;
2205 case EFI_IFR_ONE_OF_OPTION_OP
:
2206 ImageId
= &CurrentOption
->ImageId
;
2211 // Make sure CurrentStatement is not NULL.
2212 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2213 // file is wrongly generated by tools such as VFR Compiler.
2215 ASSERT (CurrentStatement
!= NULL
);
2216 ImageId
= &CurrentStatement
->ImageId
;
2220 ASSERT (ImageId
!= NULL
);
2221 CopyMem (ImageId
, &((EFI_IFR_IMAGE
*) OpCodeData
)->Id
, sizeof (EFI_IMAGE_ID
));
2227 case EFI_IFR_REFRESH_OP
:
2228 ASSERT (CurrentStatement
!= NULL
);
2229 CurrentStatement
->RefreshInterval
= ((EFI_IFR_REFRESH
*) OpCodeData
)->RefreshInterval
;
2235 case EFI_IFR_REFRESH_ID_OP
:
2236 ASSERT (CurrentStatement
!= NULL
);
2237 CopyMem (&CurrentStatement
->RefreshGuid
, &((EFI_IFR_REFRESH_ID
*) OpCodeData
)->RefreshEventGroupId
, sizeof (EFI_GUID
));
2243 case EFI_IFR_MODAL_TAG_OP
:
2244 ASSERT (CurrentForm
!= NULL
);
2245 CurrentForm
->ModalForm
= TRUE
;
2249 // Lock tag, used by form and statement.
2251 case EFI_IFR_LOCKED_OP
:
2253 // Get ScopeOpcode from top of stack
2255 PopScope (&ScopeOpCode
);
2256 PushScope (ScopeOpCode
);
2257 switch (ScopeOpCode
) {
2258 case EFI_IFR_FORM_OP
:
2259 case EFI_IFR_FORM_MAP_OP
:
2260 ASSERT (CurrentForm
!= NULL
);
2261 CurrentForm
->Locked
= TRUE
;
2265 ASSERT (CurrentStatement
!= NULL
);
2266 CurrentStatement
->Locked
= TRUE
;
2273 case EFI_IFR_GUID_OP
:
2274 if (CompareGuid (&gEfiIfrTianoGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2276 // Tiano specific GUIDed opcodes
2278 switch (((EFI_IFR_GUID_LABEL
*) OpCodeData
)->ExtendOpCode
) {
2279 case EFI_IFR_EXTEND_OP_LABEL
:
2281 // just ignore label
2285 case EFI_IFR_EXTEND_OP_BANNER
:
2287 // By SubClass to get Banner Data from Front Page
2289 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2291 &gBannerData
->Banner
[((EFI_IFR_GUID_BANNER
*) OpCodeData
)->LineNumber
][
2292 ((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Alignment
],
2293 &((EFI_IFR_GUID_BANNER
*) OpCodeData
)->Title
,
2294 sizeof (EFI_STRING_ID
)
2299 case EFI_IFR_EXTEND_OP_CLASS
:
2300 CopyMem (&FormSet
->Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
2303 case EFI_IFR_EXTEND_OP_SUBCLASS
:
2304 CopyMem (&FormSet
->SubClass
, &((EFI_IFR_GUID_SUBCLASS
*) OpCodeData
)->SubClass
, sizeof (UINT16
));
2317 case EFI_IFR_END_OP
:
2318 Status
= PopScope (&ScopeOpCode
);
2319 if (EFI_ERROR (Status
)) {
2324 switch (ScopeOpCode
) {
2325 case EFI_IFR_FORM_SET_OP
:
2327 // End of FormSet, update FormSet IFR binary length
2328 // to stop parsing substantial OpCodes
2330 FormSet
->IfrBinaryLength
= OpCodeOffset
;
2333 case EFI_IFR_FORM_OP
:
2334 case EFI_IFR_FORM_MAP_OP
:
2339 SuppressForQuestion
= FALSE
;
2342 case EFI_IFR_ONE_OF_OPTION_OP
:
2346 CurrentOption
= NULL
;
2349 case EFI_IFR_SUBTITLE_OP
:
2350 mInScopeSubtitle
= FALSE
;
2353 case EFI_IFR_NO_SUBMIT_IF_OP
:
2354 case EFI_IFR_INCONSISTENT_IF_OP
:
2356 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2360 case EFI_IFR_SUPPRESS_IF_OP
:
2361 if (SuppressForOption
) {
2362 PopConditionalExpression(ExpressOption
);
2363 } else if (SuppressForQuestion
) {
2364 PopConditionalExpression(ExpressStatement
);
2366 PopConditionalExpression(ExpressForm
);
2370 case EFI_IFR_GRAY_OUT_IF_OP
:
2371 PopConditionalExpression(ExpressStatement
);
2374 case EFI_IFR_DISABLE_IF_OP
:
2375 if (CurrentForm
!= NULL
) {
2376 PopConditionalExpression(ExpressStatement
);
2378 InScopeDisable
= FALSE
;
2379 OpCodeDisabled
= FALSE
;
2382 case EFI_IFR_ONE_OF_OP
:
2383 case EFI_IFR_ORDERED_LIST_OP
:
2384 SuppressForOption
= FALSE
;
2387 case EFI_IFR_DEFAULT_OP
:
2388 InScopeDefault
= FALSE
;
2391 case EFI_IFR_MAP_OP
:
2393 // Get current Map Expression List.
2395 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
2396 if (Status
== EFI_ACCESS_DENIED
) {
2397 MapExpressionList
= NULL
;
2400 // Get current expression.
2402 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
2403 ASSERT_EFI_ERROR (Status
);
2404 ASSERT (MapScopeDepth
> 0);
2409 if (IsExpressionOpCode (ScopeOpCode
)) {
2410 if (InScopeDisable
&& CurrentForm
== NULL
) {
2412 // This is DisableIf expression for Form, it should be a constant expression
2414 ASSERT (CurrentExpression
!= NULL
);
2415 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
);
2416 if (EFI_ERROR (Status
)) {
2420 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2421 return EFI_INVALID_PARAMETER
;
2424 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2426 // DisableIf Expression is only used once and not queued, free it
2428 DestroyExpression (CurrentExpression
);
2432 // End of current Expression
2434 CurrentExpression
= NULL
;