3 Parser for IFR binary encoding.
5 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #ifndef EDKII_IFR_BIT_VARSTORE_GUID
13 #define EDKII_IFR_BIT_VARSTORE_GUID \
14 {0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60 ,0xA7, 0x1D}}
17 #ifndef EDKII_IFR_NUMERIC_SIZE_BIT
18 #define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F
21 UINT16 mStatementIndex
;
22 UINT16 mExpressionOpCodeIndex
;
24 BOOLEAN mInScopeSubtitle
;
25 BOOLEAN mInScopeSuppress
;
26 BOOLEAN mInScopeGrayOut
;
27 BOOLEAN mInScopeDisable
;
28 FORM_EXPRESSION
*mSuppressExpression
;
29 FORM_EXPRESSION
*mGrayOutExpression
;
30 FORM_EXPRESSION
*mDisableExpression
;
32 extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam
;
33 extern LIST_ENTRY mVarListEntry
;
34 extern LIST_ENTRY mFormSetListEntry
;
35 extern UINT32 mFormSetOrderParse
;
37 #define FORM_SET_GUID_PREFIX "Form Set GUID: "
38 #define EFI_GUID_FORMAT "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
40 UINT32 mMaxCount
= 0x100000;
42 CHAR8
*mStringBuffer
= NULL
;
43 static EFI_GUID gEdkiiIfrBitVarGuid
= EDKII_IFR_BIT_VARSTORE_GUID
;
46 Produces a Null-terminated ASCII string in mStringBuffer based on a Null-terminated
47 ASCII format string and variable argument list.
49 @param FormatString A null-terminated ASCII format string.
50 @param ... The variable argument list whose contents are accessed based on the
51 format string specified by FormatString.
62 va_start (Marker
, FormatString
);
63 Count
= vsprintf (mStringBuffer
+ mCount
, FormatString
, Marker
);
64 mCount
= mCount
+ Count
;
66 if (mCount
+ 0x400 > mMaxCount
) {
67 mStringBuffer
[mCount
] = '\0';
68 fwrite (mStringBuffer
, sizeof (CHAR8
), mCount
, stdout
);
74 Print the information of questions.
76 @param FormSet The pointer to the formset.
77 @param FormSet The pointer to the form.
78 @param Question The pointer to the question.
79 @param PrintOrNot Decide whether print or not.
87 IN FORM_BROWSER_FORMSET
*FormSet
,
88 IN FORM_BROWSER_FORM
*Form
,
89 IN FORM_BROWSER_STATEMENT
*Question
,
94 Writes a Unicode string specified by iStringToken and iLanguage to the script file (converted to ASCII).
96 @param Package A pointer to the Unicode string.
109 if (pcString
== NULL
) {
113 // replace the 0x0D to 0x20, because if the pcString has 0D 0A, then after print it,
114 // different editor may have different format
116 for (Index
= 0; pcString
[Index
] != 0; Index
++) {
117 if (pcString
[Index
] == 0x0D) {
118 pcString
[Index
] = 0x20;
121 StringPrint("%c", pcString
[Index
] & 0x00FF);
126 Writes a UQIL Unicode string specified by iStringToken to the script file as an array of 16-bit integers in ASCII.
128 @param Package A pointer to the Unicode string.
141 // Find the UNICODE string length (in CHAR16)
143 for (Index
= 0; pcString
[Index
] != 0; Index
++);
145 // Write each word as a hex integer
147 for (Index
= 0; pcString
[Index
] != 0; Index
++) {
148 StringPrint("%04X ", pcString
[Index
]);
153 Get the question value with bit field from the buffer.
155 @param Question The question refer to bit field.
156 @param Buffer The buffer which the question value get from.
157 @param Value Retun the value.
161 GetBitsQuestionValue(
162 IN FORM_BROWSER_STATEMENT
*Question
,
170 PreBits
= Question
->BitVarOffset
- Question
->VarStoreInfo
.VarOffset
* 8;
171 Mask
= (1<< Question
->BitStorageWidth
) -1;
173 *Value
= *(UINT32
*)Buffer
;
174 (*Value
) >>= PreBits
;
179 Set the question value with bit field to the buffer.
181 @param Question The question refer to bit field.
182 @param Buffer The buffer which the question value set to.
183 @param Value The value need to set.
187 SetBitsQuestionValue (
188 IN FORM_BROWSER_STATEMENT
*Question
,
189 IN OUT UINT8
*Buffer
,
197 PreBits
= Question
->BitVarOffset
- Question
->VarStoreInfo
.VarOffset
* 8;
199 Mask
= (1<< Question
->BitStorageWidth
) -1;
202 TmpValue
= *(UINT32
*)(Buffer
);
203 TmpValue
= (TmpValue
& (~Mask
)) | Value
;
204 CopyMem ((UINT32
*)Buffer
, &TmpValue
, sizeof (UINT32
));
208 Print the current value of the specified question.
210 @param Question The pointer to question
217 IN FORM_BROWSER_FORMSET
*FormSet
,
218 IN FORM_BROWSER_STATEMENT
*Question
222 FORMSET_STORAGE
*VarList
;
228 Status
= SearchVarStorage (
231 Question
->VarStoreInfo
.VarOffset
,
232 FormSet
->StorageListHead
,
233 (CHAR8
**)&VarBuffer
,
237 if (EFI_ERROR (Status
)) {
238 StringPrint("\nCouldn't read current variable data.");
245 (Question
->VarStoreInfo
.VarOffset
> VarList
->Size
) \
246 && (VarList
->Type
== EFI_IFR_VARSTORE_OP
)
248 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
250 (Question
->VarStoreInfo
.VarOffset
> VarList
->Size
) \
251 && (VarList
->Type
== EFI_IFR_VARSTORE_EFI_OP
) \
252 && VarList
->NewEfiVarstore
254 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
256 (Question
->StorageWidth
> VarList
->Size
) \
257 && (VarList
->Type
== EFI_IFR_VARSTORE_EFI_OP
) \
258 && !VarList
->NewEfiVarstore
260 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
262 if (Question
->QuestionReferToBitField
) {
263 GetBitsQuestionValue (Question
, VarBuffer
, &Value
);
264 VarBuffer
= (UINT8
*)(&Value
);
266 switch (Question
->StorageWidth
) {
269 StringPrint("%02X", (*(UINT8
*)VarBuffer
) & 0xFF);
272 case sizeof (UINT16
):
273 StringPrint("%04X", (*(UINT16
*)VarBuffer
) & 0xFFFF);
276 case sizeof (UINT32
):
277 StringPrint("%08X", (*(UINT32
*)VarBuffer
) & 0xFFFFFFFF);
280 case sizeof (UINT64
):
281 StringPrint("%016llX", *((UINT64
*)VarBuffer
));
285 StringPrint("0000 // Width > 16 is not supported -- FAILURE");
293 Print the current value of the STRING question.
295 @param Question The pointer to question
302 IN FORM_BROWSER_FORMSET
*FormSet
,
303 IN FORM_BROWSER_STATEMENT
*Question
307 FORMSET_STORAGE
*VarList
;
311 Status
= SearchVarStorage (
314 Question
->VarStoreInfo
.VarOffset
,
315 FormSet
->StorageListHead
,
316 (CHAR8
**)&VarBuffer
,
320 if (EFI_ERROR (Status
)) {
321 StringPrint("\nCouldn't read current variable data.");
329 (Question
->VarStoreInfo
.VarOffset
> VarList
->Size
) \
330 && (VarList
->Type
== EFI_IFR_VARSTORE_OP
)
332 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
334 (Question
->VarStoreInfo
.VarOffset
> VarList
->Size
) \
335 && (VarList
->Type
== EFI_IFR_VARSTORE_EFI_OP
) \
336 && VarList
->NewEfiVarstore
338 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
340 (Question
->StorageWidth
> VarList
->Size
) \
341 && (VarList
->Type
== EFI_IFR_VARSTORE_EFI_OP
) \
342 && !VarList
->NewEfiVarstore
344 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
347 LogUnicodeString((CHAR16
*)VarBuffer
);
354 Print the current values of an Ordered List question.
356 @param Question The pointer to question
357 @param MaxEntries The max number of options
358 @param VarList The dual pointer to the Node of VarList
365 IN FORM_BROWSER_FORMSET
*FormSet
,
366 IN FORM_BROWSER_STATEMENT
*Question
370 FORMSET_STORAGE
*VarList
;
377 Status
= SearchVarStorage (
380 Question
->VarStoreInfo
.VarOffset
,
381 FormSet
->StorageListHead
,
382 (CHAR8
**)&VarBuffer
,
386 if (EFI_ERROR (Status
)) {
387 StringPrint("\nCouldn't read current variable data.");
394 ((Question
->VarStoreInfo
.VarOffset
+ Question
->MaxContainers
) > VarList
->Size
) \
395 && (VarList
->Type
== EFI_IFR_VARSTORE_OP
)
397 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
399 (Question
->MaxContainers
> VarList
->Size
) \
400 && (VarList
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
402 StringPrint("0000 // Offset larger than Variable Size -- FAILURE");
404 for (CurrentEntry
= 0; CurrentEntry
< Question
->MaxContainers
; CurrentEntry
++) {
406 switch (Question
->StorageWidth
/Question
->MaxContainers
){
409 StringPrint("%02X ", VarBuffer
[CurrentEntry
]);
413 StringPrint("%04X ", *((UINT16
*)VarBuffer
+ CurrentEntry
));
417 StringPrint("%08X ", *((UINT32
*)VarBuffer
+ CurrentEntry
));
421 StringPrint("%016llX ", *((UINT64
*)VarBuffer
+ CurrentEntry
));
425 StringPrint("%02X ", VarBuffer
[CurrentEntry
]);
433 Compare two Uqi parameters
435 @param UqiParm1 The pointer to the first Uqi parameter.
436 @param UqiParm2 The pointer to the second Uqi parameter.
438 @retval TRUE If these two Uqi parameters are the same, return TRUE;
439 @return FALSE Otherwise, return FALSE;
443 IN CONST UQI_HEADER
*UqiParm1
,
444 IN CONST UQI_HEADER
*UqiParm2
449 if (UqiParm1
->HexNum
!= UqiParm2
->HexNum
) {
453 for (Index
= UqiParm1
->HexNum
- 1; Index
>= 0; Index
--) {
454 if (UqiParm1
->Data
[Index
] != UqiParm2
->Data
[Index
]) {
464 Check whether existed a same variable in the LIST_ENTRY.
466 @param CurVarList A pointer to a variable node.
468 @return Pointer If existed the same variable, return the pointer to the Node.
469 @return NULL Otherwise, return FALSE
474 NotSameVariableInVarList (
475 IN LIST_ENTRY
*VariableListEntry
,
476 IN FORMSET_STORAGE
*StorageNode
479 FORMSET_STORAGE
*CurNode
;
481 LIST_ENTRY
*StorageListHead
;
483 StorageListHead
= VariableListEntry
;
487 // Find Storage for this Question
489 Link
= GetFirstNode (StorageListHead
);
490 while (!IsNull (StorageListHead
, Link
)) {
491 CurNode
= FORMSET_STORAGE_FROM_LINK (Link
);
493 if (!CompareGuid (&StorageNode
->Guid
, &CurNode
->Guid
) \
494 && (CurNode
->Name
!= NULL
) \
495 && (StorageNode
->Name
!= NULL
) \
496 && !FceStrCmp (StorageNode
->Name
, CurNode
->Name
) \
497 && (StorageNode
- CurNode
!= 0)
500 // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are
501 // two variables with same guid same name, but different type, we will take as the same
504 if (mMultiPlatformParam
.MultiPlatformOrNot
&& (CurNode
->Type
== StorageNode
->Type
)) {
506 // If matched, get the address of EFI_IFR_VARSTORE data.
510 } else if (!mMultiPlatformParam
.MultiPlatformOrNot
) {
515 Link
= GetNextNode (StorageListHead
, Link
);
521 Get the UniString by the offset.
523 @param UniPackge A pointer to the beginning of Null-terminated Unicode string Array.
524 @param CurUniPackge A pointer to the current position of Null-terminated Unicode string Array.
525 @param VarDefaultNameId The string ID.
526 @param CurOrDefaultLang Use the current language or the default language.
527 @param VarDefaultName return the name string.
530 @return EFI_INVALID_PARAMETER
531 @return EFI_NOT_FOUND
537 IN UINT8
*CurUniPackge
,
538 IN UINT16 VarDefaultNameId
,
539 IN BOOLEAN CurOrDefaultLang
,
540 IN OUT CHAR16
**VarDefaultName
543 UINT8
*HiiStringHeader
;
547 EFI_HII_STRING_BLOCK
*Block
;
550 assert ((UniPackge
!= NULL
) && (CurUniPackge
!= NULL
));
552 HiiStringHeader
= NULL
;
558 if (VarDefaultNameId
== 0) {
559 return EFI_INVALID_PARAMETER
;
561 if (CurOrDefaultLang
) {
562 HiiStringHeader
= CurUniPackge
;
564 HiiStringHeader
= UniPackge
+ 4;
567 Block
= (EFI_HII_STRING_BLOCK
*)((UINT8
*)HiiStringHeader
+ ((EFI_HII_STRING_PACKAGE_HDR
*)HiiStringHeader
)->HdrSize
);
569 // Search the matched String in specificated language package by the Offset
571 while( Block
->BlockType
!= EFI_HII_SIBT_END
) {
572 switch (Block
->BlockType
) {
573 case EFI_HII_SIBT_STRING_SCSU
:
574 ThisBlock
= (VOID
*)Block
;
575 for (Index
= 0 ; ((EFI_HII_SIBT_STRING_SCSU_BLOCK
*)ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
576 Block
= (EFI_HII_STRING_BLOCK
*)&((EFI_HII_SIBT_STRING_SCSU_BLOCK
*)ThisBlock
)->StringText
[Index
+ 1];
579 case EFI_HII_SIBT_STRING_SCSU_FONT
:
580 ThisBlock
= (VOID
*)Block
;
581 for (Index
= 0 ; ((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
*)ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
582 Block
= (EFI_HII_STRING_BLOCK
*)(((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK
*)ThisBlock
) + 1);
585 case EFI_HII_SIBT_STRINGS_SCSU
:
586 ThisBlock
= (VOID
*)Block
;
587 for( Count
= ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK
*)ThisBlock
)->StringCount
, Index
= 0 ; Count
; Count
--, Index
++ ) {
588 for ( ; ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK
*)ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
590 Block
= (EFI_HII_STRING_BLOCK
*)&((EFI_HII_SIBT_STRINGS_SCSU_BLOCK
*)ThisBlock
)->StringText
[Index
];
593 case EFI_HII_SIBT_STRINGS_SCSU_FONT
:
594 ThisBlock
= (VOID
*)Block
;
595 for( Count
= ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
*)ThisBlock
)->StringCount
, Index
= 0 ; Count
; Count
--, Index
++ ) ;
596 Block
= (EFI_HII_STRING_BLOCK
*) & ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK
*)ThisBlock
)->StringText
[Index
];
599 case EFI_HII_SIBT_STRING_UCS2
:
600 ThisBlock
= (VOID
*)Block
;
601 if (Offset
== VarDefaultNameId
) {
602 *VarDefaultName
= malloc ((FceStrLen ((CHAR16
*) ((EFI_HII_SIBT_STRING_UCS2_BLOCK
*)ThisBlock
)->StringText
) + 1) * sizeof (CHAR16
));
603 if (*VarDefaultName
== NULL
) {
604 printf ("Fail to allocate memory");
605 return EFI_OUT_OF_RESOURCES
;
610 (FceStrLen ((CHAR16
*) ((EFI_HII_SIBT_STRING_UCS2_BLOCK
*)ThisBlock
)->StringText
) + 1) * sizeof (CHAR16
)
614 (CHAR16
*) ((EFI_HII_SIBT_STRING_UCS2_BLOCK
*) ThisBlock
)->StringText
619 for (Index
= 0 ; ((EFI_HII_SIBT_STRING_UCS2_BLOCK
*)ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
620 Block
= (EFI_HII_STRING_BLOCK
*) & ((EFI_HII_SIBT_STRING_UCS2_BLOCK
*) ThisBlock
)->StringText
[Index
+ 1];
624 case EFI_HII_SIBT_STRING_UCS2_FONT
:
625 ThisBlock
= (VOID
*)Block
;
626 for (Index
= 0 ; ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
*) ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
627 Block
= (EFI_HII_STRING_BLOCK
*)& ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
*) ThisBlock
)->StringText
[Index
+ 1];
630 case EFI_HII_SIBT_STRINGS_UCS2
:
631 ThisBlock
= (VOID
*)Block
;
632 for( Count
= ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK
*)ThisBlock
)->StringCount
, Index
= 0 ; Count
; Count
--, Index
++ ) {
633 for ( ; ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK
*) ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
635 Block
= (EFI_HII_STRING_BLOCK
*) & ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK
*) ThisBlock
)->StringText
[Index
];
638 case EFI_HII_SIBT_STRINGS_UCS2_FONT
:
639 ThisBlock
= (VOID
*)Block
;
640 for( Count
= ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
*) ThisBlock
)->StringCount
, Index
= 0 ; Count
; Count
--, Index
++ ) {
641 for ( ; ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
*) ThisBlock
)->StringText
[Index
] != 0 ; Index
++) ;
643 Block
= (EFI_HII_STRING_BLOCK
*) & ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK
*)ThisBlock
)->StringText
[Index
];
646 case EFI_HII_SIBT_DUPLICATE
:
647 ThisBlock
= (VOID
*)Block
;
648 Block
= (EFI_HII_STRING_BLOCK
*)((EFI_HII_SIBT_DUPLICATE_BLOCK
*) ThisBlock
+ 1);
651 case EFI_HII_SIBT_SKIP2
:
652 ThisBlock
= (VOID
*)Block
;
653 Offset
+= ((EFI_HII_SIBT_SKIP2_BLOCK
*) ThisBlock
)->SkipCount
;
654 Block
= (EFI_HII_STRING_BLOCK
*)( (EFI_HII_SIBT_SKIP2_BLOCK
*) ThisBlock
+ 1);
657 case EFI_HII_SIBT_SKIP1
:
658 ThisBlock
= (VOID
*)Block
;
659 Offset
+= ((EFI_HII_SIBT_SKIP1_BLOCK
*) ThisBlock
)->SkipCount
;
660 Block
= (EFI_HII_STRING_BLOCK
*)((EFI_HII_SIBT_SKIP1_BLOCK
*)ThisBlock
+ 1);
663 case EFI_HII_SIBT_EXT1
:
664 ThisBlock
= (VOID
*)Block
;
665 Block
= (EFI_HII_STRING_BLOCK
*)((UINT8
*)ThisBlock
+ ((EFI_HII_SIBT_EXT1_BLOCK
*) ThisBlock
)->Length
);
668 case EFI_HII_SIBT_EXT2
:
669 ThisBlock
= (VOID
*)Block
;
670 Block
= (EFI_HII_STRING_BLOCK
*)((UINT8
*)ThisBlock
+ ((EFI_HII_SIBT_EXT2_BLOCK
*) ThisBlock
)->Length
);
673 case EFI_HII_SIBT_EXT4
:
674 ThisBlock
= (VOID
*)Block
;
675 Block
= (EFI_HII_STRING_BLOCK
*)((UINT8
*)ThisBlock
+ ((EFI_HII_SIBT_EXT4_BLOCK
*)ThisBlock
)->Length
);
678 case EFI_HII_SIBT_FONT
:
679 ThisBlock
= (VOID
*)Block
;
680 for (Index
= 0 ; ((EFI_HII_SIBT_FONT_BLOCK
*) ThisBlock
)->FontName
[Index
] != 0 ; Index
++) ;
681 Block
= (EFI_HII_STRING_BLOCK
*)& ((EFI_HII_SIBT_FONT_BLOCK
*) ThisBlock
)->FontName
[Index
+ 1];
685 StringPrint("Unhandled type = 0x%x\n", Block
->BlockType
);
689 return EFI_NOT_FOUND
;
693 Parse the UniString to get the string information.
695 @param CachedStringList A pointer to cached string list
696 @param UniPackge A pointer to a Null-terminated Unicode string Array.
697 @param VarDefaultNameId The string ID.
698 @param Language The language, en-US UQI or eng.
699 @param VarDefaultName return the name string.
701 @return EFI_SUCCESS If get the name string successfully
702 @return EFI_NOT_FOUND An error occurred.
703 @return EFI_INVALID_PARAMETER
708 IN FORMSET_STRING_LIST
*CachedStringList
,
710 IN UINT16 VarDefaultNameId
,
711 IN LANGUAGE Language
,
712 IN OUT CHAR16
**VarDefaultName
721 STRING_INFO
*TempBuffer
;
725 Status
= EFI_NOT_FOUND
;
727 UniBin
= (CHAR8
*) UniPackge
+ 4;
728 UniPackgeEnd
= (CHAR8
*) UniPackge
+ *(UINT32
*)UniPackge
;
731 //Handle with the invalid usage "STRING_TOKEN(0)"
733 if (VarDefaultNameId
== 0) {
734 *VarDefaultName
= L
"";
738 if (CachedStringList
!= NULL
) {
739 for (Index
= 0; Index
< CachedStringList
->CachedIdNum
; Index
++) {
740 if (VarDefaultNameId
== CachedStringList
->StringInfoList
[Index
].StringId
) {
741 *VarDefaultName
= CachedStringList
->StringInfoList
[Index
].String
;
750 strcpy (LangStr
, "uqi");
754 strcpy (LangStr
, "en-US");
758 strcpy (LangStr
, "eng");
762 strcpy (LangStr
, "en-US");
767 if (((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
769 // Search the specified language package
771 while ((UniBin
< UniPackgeEnd
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
772 if (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, LangStr
) == 0) {
776 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
779 //If not find the string ID, use the en eng or en-US instead.
782 UniBin
= (CHAR8
*) UniPackge
+ 4;
784 while ((UniBin
< UniPackgeEnd
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
785 if ((strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "en") == 0) \
786 || (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "en-US") == 0) \
787 || (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "eng") == 0) \
792 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
796 //If not still find the string ID, use the first one instead.
798 Status
= GetStringByOffset (
805 if (!EFI_ERROR (Status
)) {
809 //If not find the specified string in UQI package, we use the en en-us eng or uqi insteadly
812 UniBin
= (CHAR8
*) UniPackge
+ 4;
814 while ((UniBin
< UniPackgeEnd
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
815 if (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "en") == 0) {
819 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
821 Status
= GetStringByOffset (
828 if (!EFI_ERROR (Status
)) {
833 UniBin
= (CHAR8
*) UniPackge
+ 4;
835 while ((UniBin
< UniPackgeEnd
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
836 if (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "en-US") == 0) {
840 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
842 Status
= GetStringByOffset (
849 if (!EFI_ERROR (Status
)) {
854 UniBin
= (CHAR8
*) UniPackge
+ 4;
856 while ((UniBin
< UniPackgeEnd
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
857 if (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "eng") == 0) {
861 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
863 Status
= GetStringByOffset (
870 if (!EFI_ERROR (Status
)) {
875 UniBin
= (CHAR8
*) UniPackge
+ 4;
877 while ((UniBin
< UniPackgeEnd
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
878 if (strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "uqi") == 0) {
882 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
884 Status
= GetStringByOffset (
891 if (!EFI_ERROR (Status
)) {
897 if (EFI_ERROR (Status
)) {
898 *VarDefaultName
= NULL
;
899 return EFI_NOT_FOUND
;
902 if (CachedStringList
!= NULL
) {
903 if (CachedStringList
->CachedIdNum
>= CachedStringList
->MaxIdNum
) {
904 TempBuffer
= calloc (sizeof (STRING_INFO
), CachedStringList
->MaxIdNum
+ STRING_NUMBER
);
905 if (TempBuffer
== NULL
) {
906 printf ("Fail to allocate memory! \n");
907 free (*VarDefaultName
);
908 *VarDefaultName
= NULL
;
909 return EFI_OUT_OF_RESOURCES
;
911 CopyMem (TempBuffer
, CachedStringList
->StringInfoList
, sizeof (STRING_INFO
) * CachedStringList
->MaxIdNum
);
912 FreePool (CachedStringList
->StringInfoList
);
913 CachedStringList
->StringInfoList
= TempBuffer
;
914 CachedStringList
->MaxIdNum
= CachedStringList
->MaxIdNum
+ STRING_NUMBER
;
916 CachedStringList
->StringInfoList
[CachedStringList
->CachedIdNum
].StringId
= VarDefaultNameId
;
917 CachedStringList
->StringInfoList
[CachedStringList
->CachedIdNum
].String
= *VarDefaultName
;
918 CachedStringList
->CachedIdNum
++;
924 Get the variable Guid and Name by the variableId and FormSetOrder.
926 @param FormSet The pointer to the formset.
927 @param FormSet The pointer to the form.
928 @param ListEntry The pointer to the LIST_ENTRY.
931 @return EFI_NOT_FOUND If not find the the variable, or the variable doesn't belong to EfiVarStore or VarStore.
935 GetGuidNameByVariableId (
936 IN FORM_BROWSER_FORMSET
*FormSet
,
937 IN OUT FORM_BROWSER_STATEMENT
*Question
,
938 IN LIST_ENTRY
*ListEntry
941 FORMSET_STORAGE
*CurNode
;
943 LIST_ENTRY
*StorageListHead
;
945 CHAR16
*EfiVariableName
;
947 StorageListHead
= ListEntry
;
949 Status
= EFI_SUCCESS
;
950 EfiVariableName
= NULL
;
952 Link
= GetFirstNode (StorageListHead
);
953 while (!IsNull (StorageListHead
, Link
)) {
954 CurNode
= FORMSET_STORAGE_FROM_LINK (Link
);
956 if ((FormSet
->FormSetOrder
== CurNode
->FormSetOrder
) \
957 && (Question
->VarStoreId
== CurNode
->VarStoreId
)
960 // Copy type to question to avoid the case that EfiVarStore and VarStore have the same Guid and name.
962 Question
->Type
= CurNode
->Type
;
963 Question
->NewEfiVarstore
= CurNode
->NewEfiVarstore
;
964 Question
->Attributes
= CurNode
->Attributes
;
966 if (CurNode
->Type
== EFI_IFR_VARSTORE_EFI_OP
) {
967 CopyMem (&Question
->Guid
, &CurNode
->Guid
, sizeof (EFI_GUID
));
969 // If the first time to access the old EfiVarStore, need to sync the variable name
971 if (!CurNode
->NewEfiVarstore
) {
972 if (CurNode
->Buffer
== NULL
) {
973 CurNode
->Buffer
= malloc (Question
->StorageWidth
);
975 if (CurNode
->Name
== NULL
) {
976 Status
= FindDefaultName (
977 &(FormSet
->EnUsStringList
),
978 FormSet
->UnicodeBinary
,
979 Question
->VarStoreInfo
.VarName
,
983 if (EFI_ERROR(Status
)) {
986 CurNode
->Name
= EfiVariableName
;
988 if (CurNode
->Size
== 0) {
989 CurNode
->Size
= Question
->StorageWidth
;
993 // Check whether the Efivariable variable name is valid.
995 if ((CurNode
->Name
== NULL
) || (FceStrLen (CurNode
->Name
) == 0)) {
996 StringPrint ("Error. The variable name of question is NULL. Its UQI is: ");
997 StringPrint("Q %04X ", Question
->Uqi
.HexNum
);
998 LogUqi (Question
->Uqi
.Data
);
1002 if (Question
->VariableName
== NULL
) {
1003 Question
->VariableName
= (CHAR16
*) malloc (2 * (FceStrLen ((CONST CHAR16
*)CurNode
->Name
) + 1));
1004 if (Question
->VariableName
== NULL
) {
1008 StrCpy (Question
->VariableName
, CurNode
->Name
);
1012 } else if (CurNode
->Type
== EFI_IFR_VARSTORE_OP
) {
1013 CopyMem (&Question
->Guid
, &CurNode
->Guid
, sizeof (EFI_GUID
));
1014 if (Question
->VariableName
== NULL
) {
1015 Question
->VariableName
= (CHAR16
*) malloc (2 * (FceStrLen ((CONST CHAR16
*)CurNode
->Name
) + 1));
1016 if (Question
->VariableName
== NULL
) {
1021 // Check whether the variable variable name is valid.
1023 if ((CurNode
->Name
== NULL
) || (FceStrLen (CurNode
->Name
) == 0)) {
1024 StringPrint ("Error. The variable name of question is NULL. UQI:");
1025 StringPrint("Q %04X ", Question
->Uqi
.HexNum
);
1026 LogUqi (Question
->Uqi
.Data
);
1030 StrCpy (Question
->VariableName
, CurNode
->Name
);
1034 Link
= GetNextNode (StorageListHead
, Link
);
1036 return EFI_NOT_FOUND
;
1040 Search the variable list according to the variable Guid and name, and return the pointer
1043 @param HiiObjList The pointer to the Question
1044 @param VarName The EFI variable name need to be updated to VarList
1045 @param Offset The offset of the variable
1046 @param StorageListHead The pointer to the LIST_ENTRY of Storage
1047 @param Vaue The value in that value offset of the variable
1048 @param VarList The dual pointer of Varlist
1051 @return EFI_NOT_FOUND
1055 IN FORM_BROWSER_STATEMENT
*Question
,
1058 IN LIST_ENTRY
*StorageListHead
,
1059 IN OUT CHAR8
**Value
,
1060 IN OUT FORMSET_STORAGE
**VarList
1063 FORMSET_STORAGE
*CurNode
;
1071 // Find Storage for this Question
1073 Link
= GetFirstNode (StorageListHead
);
1074 while (!IsNull (StorageListHead
, Link
)) {
1075 CurNode
= FORMSET_STORAGE_FROM_LINK (Link
);
1077 // Deal with the old EfiVarstore before UEFI2.31
1079 if (!CompareGuid (&Question
->Guid
, &CurNode
->Guid
) \
1080 && (CurNode
->Type
== EFI_IFR_VARSTORE_EFI_OP
) \
1081 && !CurNode
->NewEfiVarstore \
1082 && (Question
->VariableName
!= NULL
) \
1083 && (CurNode
->Name
!= NULL
) \
1084 && !FceStrCmp(Question
->VariableName
, CurNode
->Name
)
1087 // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are
1088 // two variables with same guid same name, but different type, we will take as the same
1091 if (mMultiPlatformParam
.MultiPlatformOrNot
&& (CurNode
->Type
== Question
->Type
)) {
1093 // check whether exist a old EFI_IFR_VARSTORE_EFI or not.
1095 *Value
= (CHAR8
*)CurNode
->Buffer
;
1099 } else if (!mMultiPlatformParam
.MultiPlatformOrNot
) {
1101 // check whether exist a old EFI_IFR_VARSTORE_EFI or not.
1103 *Value
= (CHAR8
*)CurNode
->Buffer
;
1110 if (!CompareGuid (&Question
->Guid
, &CurNode
->Guid
) \
1111 && (CurNode
->Name
!= NULL
) \
1112 && (Question
->VariableName
!= NULL
) \
1113 && !FceStrCmp(Question
->VariableName
, CurNode
->Name
)
1116 // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are
1117 // two variables with same guid same name, but different type, we will take as the same
1120 if (mMultiPlatformParam
.MultiPlatformOrNot
&& (CurNode
->Type
== Question
->Type
)) {
1122 // If matched, get the address of EFI_IFR_VARSTORE data.
1124 *Value
= (CHAR8
*)(CurNode
->Buffer
+ Offset
);
1128 } else if (!mMultiPlatformParam
.MultiPlatformOrNot
) {
1130 // If matched, get the address of EFI_IFR_VARSTORE data.
1132 *Value
= (CHAR8
*)(CurNode
->Buffer
+ Offset
);
1138 Link
= GetNextNode (StorageListHead
, Link
);
1141 return EFI_NOT_FOUND
;
1147 Get the string based on the StringId and HII Package List Handle.
1149 @param Token The String's ID.
1150 @param HiiHandle The package list in the HII database to search for
1151 the specified string.
1153 @return The output string.
1158 IN EFI_STRING_ID Token
,
1162 CHAR16
*VarDefaultName
;
1165 Status
= EFI_SUCCESS
;
1167 if (UniPackge
== NULL
) {
1171 Status
= FindDefaultName (
1178 if (EFI_ERROR (Status
)) {
1182 return VarDefaultName
;
1186 Initialize Statement header members.
1188 @param OpCodeData Pointer of the raw OpCode data.
1189 @param FormSet Pointer of the current FormSe.
1190 @param Form Pointer of the current Form.
1192 @return The Statement.
1195 FORM_BROWSER_STATEMENT
*
1197 IN UINT8
*OpCodeData
,
1198 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
1199 IN OUT FORM_BROWSER_FORM
*Form
1202 FORM_BROWSER_STATEMENT
*Statement
;
1203 EFI_IFR_STATEMENT_HEADER
*StatementHdr
;
1207 // We are currently not in a Form Scope, so just skip this Statement
1212 Statement
= &FormSet
->StatementBuffer
[mStatementIndex
];
1215 InitializeListHead (&Statement
->DefaultListHead
);
1216 InitializeListHead (&Statement
->OptionListHead
);
1217 InitializeListHead (&Statement
->InconsistentListHead
);
1218 InitializeListHead (&Statement
->NoSubmitListHead
);
1219 InitializeListHead (&Statement
->WarningListHead
);
1221 Statement
->Signature
= FORM_BROWSER_STATEMENT_SIGNATURE
;
1223 Statement
->Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1224 Statement
->QuestionReferToBitField
= FALSE
;
1226 StatementHdr
= (EFI_IFR_STATEMENT_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
1227 CopyMem (&Statement
->Prompt
, &StatementHdr
->Prompt
, sizeof (EFI_STRING_ID
));
1228 CopyMem (&Statement
->Help
, &StatementHdr
->Help
, sizeof (EFI_STRING_ID
));
1230 if (mInScopeSuppress
) {
1231 Statement
->SuppressExpression
= mSuppressExpression
;
1234 if (mInScopeGrayOut
) {
1235 Statement
->GrayOutExpression
= mGrayOutExpression
;
1239 if (mInScopeDisable
) {
1240 Statement
->DisableExpression
= mDisableExpression
;
1243 Statement
->InSubtitle
= mInScopeSubtitle
;
1246 // Insert this Statement into current Form
1248 InsertTailList (&Form
->StatementListHead
, &Statement
->Link
);
1254 Initialize Question's members.
1256 @param OpCodeData Pointer of the raw OpCode data.
1257 @param FormSet Pointer of the current FormSet.
1258 @param Form Pointer of the current Form.
1260 @return The Question.
1263 FORM_BROWSER_STATEMENT
*
1265 IN UINT8
*OpCodeData
,
1266 IN OUT FORM_BROWSER_FORMSET
*FormSet
,
1267 IN OUT FORM_BROWSER_FORM
*Form
1270 FORM_BROWSER_STATEMENT
*Statement
;
1271 EFI_IFR_QUESTION_HEADER
*QuestionHdr
;
1273 FORMSET_STORAGE
*Storage
;
1274 NAME_VALUE_NODE
*NameValueNode
;
1276 Statement
= CreateStatement (OpCodeData
, FormSet
, Form
);
1277 if (Statement
== NULL
) {
1281 QuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
));
1282 CopyMem (&Statement
->QuestionId
, &QuestionHdr
->QuestionId
, sizeof (EFI_QUESTION_ID
));
1283 CopyMem (&Statement
->VarStoreId
, &QuestionHdr
->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
1284 CopyMem (&Statement
->VarStoreInfo
.VarOffset
, &QuestionHdr
->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
1286 Statement
->QuestionFlags
= QuestionHdr
->Flags
;
1288 Statement
->FormSetOrder
= mFormSetOrderParse
;
1290 if (Statement
->VarStoreId
== 0) {
1292 // VarStoreId of zero indicates no variable storage
1298 // Find Storage for this Question
1300 Link
= GetFirstNode (FormSet
->StorageListHead
);
1301 while (!IsNull (FormSet
->StorageListHead
, Link
)) {
1302 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1304 if ((Storage
->VarStoreId
== Statement
->VarStoreId
)
1305 && (Storage
->FormSetOrder
== Statement
->FormSetOrder
)) {
1306 Statement
->Storage
= Storage
;
1310 Link
= GetNextNode (FormSet
->StorageListHead
, Link
);
1312 ASSERT (Statement
->Storage
!= NULL
);
1314 if (Statement
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
1315 Statement
->VariableName
= GetToken (Statement
->VarStoreInfo
.VarName
, FormSet
->UnicodeBinary
);
1316 ASSERT (Statement
->VariableName
!= NULL
);
1318 // Insert to Name/Value varstore list
1320 NameValueNode
= AllocateZeroPool (sizeof (NAME_VALUE_NODE
));
1321 ASSERT (NameValueNode
!= NULL
);
1322 NameValueNode
->Signature
= NAME_VALUE_NODE_SIGNATURE
;
1323 NameValueNode
->Name
= FceAllocateCopyPool (FceStrSize (Statement
->VariableName
), Statement
->VariableName
);
1324 ASSERT (NameValueNode
->Name
!= NULL
);
1325 NameValueNode
->Value
= AllocateZeroPool (0x10);
1326 ASSERT (NameValueNode
->Value
!= NULL
);
1327 NameValueNode
->EditValue
= AllocateZeroPool (0x10);
1328 ASSERT (NameValueNode
->EditValue
!= NULL
);
1330 InsertTailList (&Statement
->Storage
->NameValueListHead
, &NameValueNode
->Link
);
1338 Allocate a FORM_EXPRESSION node.
1340 @param Form The Form associated with this Expression
1342 @return Pointer to a FORM_EXPRESSION data structure.
1347 IN OUT FORM_BROWSER_FORM
*Form
1350 FORM_EXPRESSION
*Expression
;
1352 Expression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
1353 ASSERT (Expression
!= NULL
);
1354 Expression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
1355 InitializeListHead (&Expression
->OpCodeListHead
);
1362 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
1364 @param FormSet Pointer of the current FormSet
1366 @return Pointer to a FORMSET_STORAGE data structure.
1371 IN FORM_BROWSER_FORMSET
*FormSet
1374 FORMSET_STORAGE
*Storage
;
1376 Storage
= AllocateZeroPool (sizeof (FORMSET_STORAGE
));
1377 ASSERT (Storage
!= NULL
);
1378 Storage
->Signature
= FORMSET_STORAGE_SIGNATURE
;
1379 InitializeListHead (&Storage
->NameValueListHead
);
1380 InsertTailList (FormSet
->StorageListHead
, &Storage
->Link
);
1386 Free resources of a Expression.
1388 @param FormSet Pointer of the Expression
1393 IN FORM_EXPRESSION
*Expression
1397 EXPRESSION_OPCODE
*OpCode
;
1398 LIST_ENTRY
*SubExpressionLink
;
1399 FORM_EXPRESSION
*SubExpression
;
1401 while (!IsListEmpty (&Expression
->OpCodeListHead
)) {
1402 Link
= GetFirstNode (&Expression
->OpCodeListHead
);
1403 OpCode
= EXPRESSION_OPCODE_FROM_LINK (Link
);
1404 RemoveEntryList (&OpCode
->Link
);
1406 if (OpCode
->ValueList
!= NULL
) {
1407 FreePool (OpCode
->ValueList
);
1410 if (OpCode
->ValueName
!= NULL
) {
1411 FreePool (OpCode
->ValueName
);
1414 if (OpCode
->MapExpressionList
.ForwardLink
!= NULL
) {
1415 while (!IsListEmpty (&OpCode
->MapExpressionList
)) {
1416 SubExpressionLink
= GetFirstNode(&OpCode
->MapExpressionList
);
1417 SubExpression
= FORM_EXPRESSION_FROM_LINK (SubExpressionLink
);
1418 RemoveEntryList(&SubExpression
->Link
);
1419 DestroyExpression (SubExpression
);
1425 // Free this Expression
1427 FreePool (Expression
);
1432 Free resources of a storage.
1434 @param Storage Pointer of the storage
1439 IN FORMSET_STORAGE
*Storage
1443 NAME_VALUE_NODE
*NameValueNode
;
1445 if (Storage
== NULL
) {
1449 if (Storage
->Name
!= NULL
) {
1450 FreePool (Storage
->Name
);
1452 if (Storage
->Buffer
!= NULL
) {
1453 FreePool (Storage
->Buffer
);
1456 while (!IsListEmpty (&Storage
->NameValueListHead
)) {
1457 Link
= GetFirstNode (&Storage
->NameValueListHead
);
1458 NameValueNode
= NAME_VALUE_NODE_FROM_LINK (Link
);
1459 RemoveEntryList (&NameValueNode
->Link
);
1461 if (NameValueNode
->Name
!= NULL
) {
1462 FreePool (NameValueNode
->Name
);
1464 if (NameValueNode
->Value
!= NULL
) {
1465 FreePool (NameValueNode
->Value
);
1467 if (NameValueNode
->EditValue
!= NULL
) {
1468 FreePool (NameValueNode
->EditValue
);
1470 FreePool (NameValueNode
);
1478 Free resources allocated for all Storage in an LIST_ENTRY.
1480 @param FormSet Pointer of the FormSet
1485 IN LIST_ENTRY
*StorageEntryListHead
1489 FORMSET_STORAGE
*Storage
;
1491 // Parse Fromset one by one
1493 if (StorageEntryListHead
->ForwardLink
!= NULL
) {
1494 while (!IsListEmpty (StorageEntryListHead
)) {
1495 Link
= GetFirstNode (StorageEntryListHead
);
1496 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1497 RemoveEntryList (&Storage
->Link
);
1499 DestroyStorage (Storage
);
1502 StorageEntryListHead
= NULL
;
1506 Free resources of a Statement.
1508 @param FormSet Pointer of the FormSet
1509 @param Statement Pointer of the Statement
1514 IN FORM_BROWSER_FORMSET
*FormSet
,
1515 IN OUT FORM_BROWSER_STATEMENT
*Statement
1519 QUESTION_DEFAULT
*Default
;
1520 QUESTION_OPTION
*Option
;
1521 FORM_EXPRESSION
*Expression
;
1524 // Free Default value List
1526 while (!IsListEmpty (&Statement
->DefaultListHead
)) {
1527 Link
= GetFirstNode (&Statement
->DefaultListHead
);
1528 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1529 RemoveEntryList (&Default
->Link
);
1531 if (Default
->Value
.Buffer
!= NULL
) {
1532 FreePool(Default
->Value
.Buffer
);
1538 // Free Options List
1540 while (!IsListEmpty (&Statement
->OptionListHead
)) {
1541 Link
= GetFirstNode (&Statement
->OptionListHead
);
1542 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1543 RemoveEntryList (&Option
->Link
);
1549 // Free Inconsistent List
1551 while (!IsListEmpty (&Statement
->InconsistentListHead
)) {
1552 Link
= GetFirstNode (&Statement
->InconsistentListHead
);
1553 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1554 RemoveEntryList (&Expression
->Link
);
1556 DestroyExpression (Expression
);
1560 // Free NoSubmit List
1562 while (!IsListEmpty (&Statement
->NoSubmitListHead
)) {
1563 Link
= GetFirstNode (&Statement
->NoSubmitListHead
);
1564 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1565 RemoveEntryList (&Expression
->Link
);
1567 DestroyExpression (Expression
);
1571 // Free WarningIf List
1573 while (!IsListEmpty (&Statement
->WarningListHead
)) {
1574 Link
= GetFirstNode (&Statement
->WarningListHead
);
1575 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1576 RemoveEntryList (&Expression
->Link
);
1578 DestroyExpression (Expression
);
1580 if (Statement
->VariableName
!= NULL
) {
1581 FreePool (Statement
->VariableName
);
1583 if (Statement
->BufferValue
!= NULL
) {
1584 FreePool (Statement
->BufferValue
);
1589 Free resources of a Form.
1591 @param FormSet Pointer of the FormSet
1592 @param Form Pointer of the Form.
1597 IN FORM_BROWSER_FORMSET
*FormSet
,
1598 IN OUT FORM_BROWSER_FORM
*Form
1602 FORM_EXPRESSION
*Expression
;
1603 FORM_BROWSER_STATEMENT
*Statement
;
1606 // Free Form Expressions
1608 while (!IsListEmpty (&Form
->ExpressionListHead
)) {
1609 Link
= GetFirstNode (&Form
->ExpressionListHead
);
1610 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1611 RemoveEntryList (&Expression
->Link
);
1613 DestroyExpression (Expression
);
1617 // Free Statements/Questions
1619 while (!IsListEmpty (&Form
->StatementListHead
)) {
1620 Link
= GetFirstNode (&Form
->StatementListHead
);
1621 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1622 RemoveEntryList (&Statement
->Link
);
1624 DestroyStatement (FormSet
, Statement
);
1635 Free resources allocated for a FormSet.
1637 @param FormSet Pointer of the FormSet
1642 IN FORM_BROWSER_FORMSET
*FormSet
1646 FORMSET_DEFAULTSTORE
*DefaultStore
;
1647 FORM_EXPRESSION
*Expression
;
1648 FORM_BROWSER_FORM
*Form
;
1652 // Free FormSet Default Store
1654 if (FormSet
->DefaultStoreListHead
.ForwardLink
!= NULL
) {
1655 while (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
1656 Link
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
1657 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK (Link
);
1658 RemoveEntryList (&DefaultStore
->Link
);
1660 FreePool (DefaultStore
);
1665 // Free Formset Expressions
1667 while (!IsListEmpty (&FormSet
->ExpressionListHead
)) {
1668 Link
= GetFirstNode (&FormSet
->ExpressionListHead
);
1669 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1670 RemoveEntryList (&Expression
->Link
);
1672 DestroyExpression (Expression
);
1678 if (FormSet
->FormListHead
.ForwardLink
!= NULL
) {
1679 while (!IsListEmpty (&FormSet
->FormListHead
)) {
1680 Link
= GetFirstNode (&FormSet
->FormListHead
);
1681 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1682 RemoveEntryList (&Form
->Link
);
1684 DestroyForm (FormSet
, Form
);
1688 if (FormSet
->StatementBuffer
!= NULL
) {
1689 FreePool (FormSet
->StatementBuffer
);
1691 if (FormSet
->ExpressionBuffer
!= NULL
) {
1692 FreePool (FormSet
->ExpressionBuffer
);
1694 if (FormSet
->EnUsStringList
.StringInfoList
!= NULL
) {
1695 for (Index
= 0; Index
< FormSet
->EnUsStringList
.CachedIdNum
; Index
++) {
1696 FreePool (FormSet
->EnUsStringList
.StringInfoList
[Index
].String
);
1698 FreePool (FormSet
->EnUsStringList
.StringInfoList
);
1700 if (FormSet
->UqiStringList
.StringInfoList
!= NULL
) {
1701 for (Index
= 0; Index
< FormSet
->UqiStringList
.CachedIdNum
; Index
++) {
1702 FreePool (FormSet
->UqiStringList
.StringInfoList
[Index
].String
);
1704 FreePool (FormSet
->UqiStringList
.StringInfoList
);
1711 Free resources allocated for all FormSet in an LIST_ENTRY.
1713 @param FormSet Pointer of the FormSet
1718 IN LIST_ENTRY
*FormSetEntryListHead
1722 FORM_BROWSER_FORMSET
*FormSet
;
1724 // Parse Fromset one by one
1726 if (FormSetEntryListHead
->ForwardLink
!= NULL
) {
1727 while (!IsListEmpty (FormSetEntryListHead
)) {
1728 Link
= GetFirstNode (FormSetEntryListHead
);
1729 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
1730 RemoveEntryList (&FormSet
->Link
);
1731 DestroyFormSet (FormSet
);
1737 Tell whether this Operand is an Expression OpCode or not
1739 @param Operand Operand of an IFR OpCode.
1741 @retval TRUE This is an Expression OpCode.
1742 @retval FALSE Not an Expression OpCode.
1746 IsExpressionOpCode (
1750 if (((Operand
>= EFI_IFR_EQ_ID_VAL_OP
) && (Operand
<= EFI_IFR_NOT_OP
)) ||
1751 ((Operand
>= EFI_IFR_MATCH_OP
) && (Operand
<= EFI_IFR_SET_OP
)) ||
1752 ((Operand
>= EFI_IFR_EQUAL_OP
) && (Operand
<= EFI_IFR_SPAN_OP
)) ||
1753 (Operand
== EFI_IFR_CATENATE_OP
) ||
1754 (Operand
== EFI_IFR_TO_LOWER_OP
) ||
1755 (Operand
== EFI_IFR_TO_UPPER_OP
) ||
1756 (Operand
== EFI_IFR_MAP_OP
) ||
1757 (Operand
== EFI_IFR_VERSION_OP
) ||
1758 (Operand
== EFI_IFR_SECURITY_OP
)) {
1767 Calculate number of Statemens(Questions) and Expression OpCodes.
1769 @param FormSet The FormSet to be counted.
1770 @param NumberOfStatement Number of Statemens(Questions)
1771 @param NumberOfExpression Number of Expression OpCodes
1776 IN FORM_BROWSER_FORMSET
*FormSet
,
1777 IN OUT UINT16
*NumberOfStatement
,
1778 IN OUT UINT16
*NumberOfExpression
1781 UINT16 StatementCount
;
1782 UINT16 ExpressionCount
;
1789 ExpressionCount
= 0;
1791 while (Offset
< FormSet
->IfrBinaryLength
) {
1792 OpCodeData
= FormSet
->IfrBinaryData
+ Offset
;
1793 OpCodeLen
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1794 Offset
+= OpCodeLen
;
1796 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
)) {
1803 *NumberOfStatement
= StatementCount
;
1804 *NumberOfExpression
= ExpressionCount
;
1810 Parse opcodes in the formset IFR binary.
1812 @param FormSet Pointer of the FormSet data structure.
1814 @retval EFI_SUCCESS Opcode parse success.
1815 @retval Other Opcode parse fail.
1820 IN FORM_BROWSER_FORMSET
*FormSet
1825 FORM_BROWSER_FORM
*CurrentForm
;
1826 FORM_BROWSER_STATEMENT
*CurrentStatement
;
1827 EXPRESSION_OPCODE
*ExpressionOpCode
;
1828 FORM_EXPRESSION
*CurrentExpression
;
1835 FORMSET_STORAGE
*Storage
;
1836 FORMSET_STORAGE
*TempStorage
;
1837 FORMSET_DEFAULTSTORE
*DefaultStore
;
1838 QUESTION_DEFAULT
*CurrentDefault
;
1839 QUESTION_OPTION
*CurrentOption
;
1842 UINT16 NumberOfStatement
;
1843 UINT16 NumberOfExpression
;
1844 BOOLEAN SuppressForQuestion
;
1845 BOOLEAN SuppressForOption
;
1846 BOOLEAN InScopeOptionSuppress
;
1847 FORM_EXPRESSION
*OptionSuppressExpression
;
1848 BOOLEAN InScopeFormSuppress
;
1849 FORM_EXPRESSION
*FormSuppressExpression
;
1850 UINT16 DepthOfDisable
;
1851 BOOLEAN OpCodeDisabled
;
1852 BOOLEAN SingleOpCodeExpression
;
1853 BOOLEAN InScopeDefault
;
1854 EFI_HII_VALUE
*Value
;
1855 UINT8 MapScopeDepth
;
1857 FORMSET_STORAGE
*VarStorage
;
1858 LIST_ENTRY
*MapExpressionList
;
1859 EFI_VARSTORE_ID TempVarstoreId
;
1860 BOOLEAN ConstantFlag
;
1861 FORMSET_DEFAULTSTORE
*PreDefaultStore
;
1862 LIST_ENTRY
*DefaultLink
;
1863 BOOLEAN HaveInserted
;
1864 BOOLEAN BitFieldStorage
;
1867 mInScopeSubtitle
= FALSE
;
1868 SuppressForQuestion
= FALSE
;
1869 SuppressForOption
= FALSE
;
1870 InScopeFormSuppress
= FALSE
;
1871 mInScopeSuppress
= FALSE
;
1872 InScopeOptionSuppress
= FALSE
;
1873 mInScopeGrayOut
= FALSE
;
1874 mInScopeDisable
= FALSE
;
1876 OpCodeDisabled
= FALSE
;
1877 SingleOpCodeExpression
= FALSE
;
1878 InScopeDefault
= FALSE
;
1879 CurrentExpression
= NULL
;
1880 CurrentDefault
= NULL
;
1881 CurrentOption
= NULL
;
1882 OptionSuppressExpression
= NULL
;
1883 FormSuppressExpression
= NULL
;
1887 MapExpressionList
= NULL
;
1889 ConstantFlag
= TRUE
;
1890 BitFieldStorage
= FALSE
;
1893 // Get the number of Statements and Expressions
1895 CountOpCodes (FormSet
, &NumberOfStatement
, &NumberOfExpression
);
1897 mStatementIndex
= 0;
1898 FormSet
->StatementBuffer
= AllocateZeroPool (NumberOfStatement
* sizeof (FORM_BROWSER_STATEMENT
));
1899 if (FormSet
->StatementBuffer
== NULL
) {
1900 return EFI_OUT_OF_RESOURCES
;
1903 mExpressionOpCodeIndex
= 0;
1904 FormSet
->ExpressionBuffer
= AllocateZeroPool (NumberOfExpression
* sizeof (EXPRESSION_OPCODE
));
1905 if (FormSet
->ExpressionBuffer
== NULL
) {
1906 return EFI_OUT_OF_RESOURCES
;
1909 FormSet
->StorageListHead
= &mVarListEntry
;
1910 InitializeListHead (&FormSet
->DefaultStoreListHead
);
1911 InitializeListHead (&FormSet
->FormListHead
);
1912 InitializeListHead (&FormSet
->ExpressionListHead
);
1913 ResetCurrentExpressionStack ();
1914 ResetMapExpressionListStack ();
1917 CurrentStatement
= NULL
;
1922 while (OpCodeOffset
< FormSet
->IfrBinaryLength
) {
1923 OpCodeData
= FormSet
->IfrBinaryData
+ OpCodeOffset
;
1925 OpCodeLength
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1926 OpCodeOffset
+= OpCodeLength
;
1927 Operand
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
;
1928 Scope
= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Scope
;
1931 // If scope bit set, push onto scope stack
1934 PushScope (Operand
);
1937 if (OpCodeDisabled
) {
1939 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1940 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1942 if (Operand
== EFI_IFR_DISABLE_IF_OP
) {
1944 } else if (Operand
== EFI_IFR_END_OP
) {
1945 Status
= PopScope (&ScopeOpCode
);
1946 if (EFI_ERROR (Status
)) {
1950 if (ScopeOpCode
== EFI_IFR_DISABLE_IF_OP
) {
1951 if (DepthOfDisable
== 0) {
1952 mInScopeDisable
= FALSE
;
1953 OpCodeDisabled
= FALSE
;
1962 if (IsExpressionOpCode (Operand
)) {
1963 ExpressionOpCode
= &FormSet
->ExpressionBuffer
[mExpressionOpCodeIndex
];
1964 mExpressionOpCodeIndex
++;
1966 ExpressionOpCode
->Signature
= EXPRESSION_OPCODE_SIGNATURE
;
1967 ExpressionOpCode
->Operand
= Operand
;
1968 Value
= &ExpressionOpCode
->Value
;
1971 case EFI_IFR_EQ_ID_VAL_OP
:
1972 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1974 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
1975 CopyMem (&Value
->Value
.u16
, &((EFI_IFR_EQ_ID_VAL
*) OpCodeData
)->Value
, sizeof (UINT16
));
1978 case EFI_IFR_EQ_ID_ID_OP
:
1979 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId1
, sizeof (EFI_QUESTION_ID
));
1980 CopyMem (&ExpressionOpCode
->QuestionId2
, &((EFI_IFR_EQ_ID_ID
*) OpCodeData
)->QuestionId2
, sizeof (EFI_QUESTION_ID
));
1983 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1984 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
1985 CopyMem (&ExpressionOpCode
->ListLength
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ListLength
, sizeof (UINT16
));
1986 ExpressionOpCode
->ValueList
= FceAllocateCopyPool (ExpressionOpCode
->ListLength
* sizeof (UINT16
), &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->ValueList
);
1989 case EFI_IFR_TO_STRING_OP
:
1990 case EFI_IFR_FIND_OP
:
1991 ExpressionOpCode
->Format
= (( EFI_IFR_TO_STRING
*) OpCodeData
)->Format
;
1994 case EFI_IFR_STRING_REF1_OP
:
1995 Value
->Type
= EFI_IFR_TYPE_STRING
;
1996 CopyMem (&Value
->Value
.string
, &(( EFI_IFR_STRING_REF1
*) OpCodeData
)->StringId
, sizeof (EFI_STRING_ID
));
1999 case EFI_IFR_RULE_REF_OP
:
2000 ExpressionOpCode
->RuleId
= (( EFI_IFR_RULE_REF
*) OpCodeData
)->RuleId
;
2003 case EFI_IFR_SPAN_OP
:
2004 ExpressionOpCode
->Flags
= (( EFI_IFR_SPAN
*) OpCodeData
)->Flags
;
2007 case EFI_IFR_THIS_OP
:
2008 ASSERT (CurrentStatement
!= NULL
);
2009 ExpressionOpCode
->QuestionId
= CurrentStatement
->QuestionId
;
2012 case EFI_IFR_SECURITY_OP
:
2013 CopyMem (&ExpressionOpCode
->Guid
, &((EFI_IFR_SECURITY
*) OpCodeData
)->Permissions
, sizeof (EFI_GUID
));
2016 case EFI_IFR_GET_OP
:
2017 case EFI_IFR_SET_OP
:
2018 CopyMem (&TempVarstoreId
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
, sizeof (TempVarstoreId
));
2019 if (TempVarstoreId
!= 0) {
2020 if (FormSet
->StorageListHead
->ForwardLink
!= NULL
) {
2021 Link
= GetFirstNode (FormSet
->StorageListHead
);
2022 while (!IsNull (FormSet
->StorageListHead
, Link
)) {
2023 VarStorage
= FORMSET_STORAGE_FROM_LINK (Link
);
2024 if (VarStorage
->VarStoreId
== ((EFI_IFR_GET
*) OpCodeData
)->VarStoreId
) {
2025 ExpressionOpCode
->VarStorage
= VarStorage
;
2028 Link
= GetNextNode (FormSet
->StorageListHead
, Link
);
2031 if (ExpressionOpCode
->VarStorage
== NULL
) {
2033 // VarStorage is not found.
2035 return EFI_INVALID_PARAMETER
;
2038 ExpressionOpCode
->ValueType
= ((EFI_IFR_GET
*) OpCodeData
)->VarStoreType
;
2039 switch (ExpressionOpCode
->ValueType
) {
2040 case EFI_IFR_TYPE_BOOLEAN
:
2041 case EFI_IFR_TYPE_NUM_SIZE_8
:
2042 ExpressionOpCode
->ValueWidth
= 1;
2045 case EFI_IFR_TYPE_NUM_SIZE_16
:
2046 case EFI_IFR_TYPE_STRING
:
2047 ExpressionOpCode
->ValueWidth
= 2;
2050 case EFI_IFR_TYPE_NUM_SIZE_32
:
2051 ExpressionOpCode
->ValueWidth
= 4;
2054 case EFI_IFR_TYPE_NUM_SIZE_64
:
2055 ExpressionOpCode
->ValueWidth
= 8;
2058 case EFI_IFR_TYPE_DATE
:
2059 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_DATE
);
2062 case EFI_IFR_TYPE_TIME
:
2063 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_TIME
);
2066 case EFI_IFR_TYPE_REF
:
2067 ExpressionOpCode
->ValueWidth
= (UINT8
) sizeof (EFI_IFR_REF
);
2070 case EFI_IFR_TYPE_OTHER
:
2071 case EFI_IFR_TYPE_UNDEFINED
:
2072 case EFI_IFR_TYPE_ACTION
:
2073 case EFI_IFR_TYPE_BUFFER
:
2076 // Invalid value type for Get/Set opcode.
2078 return EFI_INVALID_PARAMETER
;
2080 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarName
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarName
, sizeof (EFI_STRING_ID
));
2081 CopyMem (&ExpressionOpCode
->VarStoreInfo
.VarOffset
, &((EFI_IFR_GET
*) OpCodeData
)->VarStoreInfo
.VarOffset
, sizeof (UINT16
));
2082 if ((ExpressionOpCode
->VarStorage
!= NULL
) &&
2083 ((ExpressionOpCode
->VarStorage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
)
2084 || ((ExpressionOpCode
->VarStorage
->Type
== EFI_IFR_VARSTORE_EFI_OP
) && !ExpressionOpCode
->VarStorage
->NewEfiVarstore
))
2086 ExpressionOpCode
->ValueName
= GetToken (ExpressionOpCode
->VarStoreInfo
.VarName
, FormSet
->UnicodeBinary
);
2087 if (ExpressionOpCode
->ValueName
== NULL
) {
2089 // String ID is invalid.
2091 return EFI_INVALID_PARAMETER
;
2096 case EFI_IFR_QUESTION_REF1_OP
:
2097 CopyMem (&ExpressionOpCode
->QuestionId
, &((EFI_IFR_EQ_ID_VAL_LIST
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
2100 case EFI_IFR_QUESTION_REF3_OP
:
2101 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_2
)) {
2102 CopyMem (&ExpressionOpCode
->DevicePath
, &(( EFI_IFR_QUESTION_REF3_2
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
2104 if (OpCodeLength
>= sizeof (EFI_IFR_QUESTION_REF3_3
)) {
2105 CopyMem (&ExpressionOpCode
->Guid
, &(( EFI_IFR_QUESTION_REF3_3
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2113 case EFI_IFR_TRUE_OP
:
2114 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
2115 Value
->Value
.b
= TRUE
;
2118 case EFI_IFR_FALSE_OP
:
2119 Value
->Type
= EFI_IFR_TYPE_BOOLEAN
;
2120 Value
->Value
.b
= FALSE
;
2123 case EFI_IFR_ONE_OP
:
2124 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
2125 Value
->Value
.u8
= 1;
2128 case EFI_IFR_ZERO_OP
:
2129 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
2130 Value
->Value
.u8
= 0;
2133 case EFI_IFR_ONES_OP
:
2134 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
2135 Value
->Value
.u64
= 0xffffffffffffffffULL
;
2138 case EFI_IFR_UINT8_OP
:
2139 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
2140 Value
->Value
.u8
= (( EFI_IFR_UINT8
*) OpCodeData
)->Value
;
2143 case EFI_IFR_UINT16_OP
:
2144 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
2145 CopyMem (&Value
->Value
.u16
, &(( EFI_IFR_UINT16
*) OpCodeData
)->Value
, sizeof (UINT16
));
2148 case EFI_IFR_UINT32_OP
:
2149 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
2150 CopyMem (&Value
->Value
.u32
, &(( EFI_IFR_UINT32
*) OpCodeData
)->Value
, sizeof (UINT32
));
2153 case EFI_IFR_UINT64_OP
:
2154 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
2155 CopyMem (&Value
->Value
.u64
, &(( EFI_IFR_UINT64
*) OpCodeData
)->Value
, sizeof (UINT64
));
2158 case EFI_IFR_UNDEFINED_OP
:
2159 Value
->Type
= EFI_IFR_TYPE_UNDEFINED
;
2162 case EFI_IFR_VERSION_OP
:
2163 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
2170 // Create sub expression nested in MAP opcode
2172 if ((CurrentExpression
== NULL
) && (MapScopeDepth
> 0)) {
2173 CurrentExpression
= CreateExpression (CurrentForm
);
2174 ASSERT (MapExpressionList
!= NULL
);
2175 InsertTailList (MapExpressionList
, &CurrentExpression
->Link
);
2177 SingleOpCodeExpression
= TRUE
;
2180 ASSERT (CurrentExpression
!= NULL
);
2181 InsertTailList (&CurrentExpression
->OpCodeListHead
, &ExpressionOpCode
->Link
);
2182 if (Operand
== EFI_IFR_MAP_OP
) {
2184 // Store current Map Expression List.
2186 if (MapExpressionList
!= NULL
) {
2187 PushMapExpressionList (MapExpressionList
);
2190 // Initialize new Map Expression List.
2192 MapExpressionList
= &ExpressionOpCode
->MapExpressionList
;
2193 InitializeListHead (MapExpressionList
);
2195 // Store current expression.
2197 PushCurrentExpression (CurrentExpression
);
2198 CurrentExpression
= NULL
;
2200 } else if (SingleOpCodeExpression
) {
2202 // There are two cases to indicate the end of an Expression:
2203 // for single OpCode expression: one Expression OpCode
2204 // for expression consists of more than one OpCode: EFI_IFR_END
2206 SingleOpCodeExpression
= FALSE
;
2208 if (mInScopeDisable
&& (CurrentForm
== NULL
)) {
2210 // This is DisableIf expression for Form, it should be a constant expression
2212 ConstantFlag
= TRUE
;
2213 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
, &ConstantFlag
);
2214 if (EFI_ERROR (Status
)) {
2218 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
2219 return EFI_INVALID_PARAMETER
;
2221 if (!ConstantFlag
) {
2222 StringPrint ("WARNING. The DisableIf expression for Form should be a constant expression.\n");
2224 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
2227 CurrentExpression
= NULL
;
2238 case EFI_IFR_FORM_SET_OP
:
2240 CopyMem (&FormSet
->FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
2241 CopyMem (&FormSet
->Help
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
2242 CopyMem (&FormSet
->Guid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2244 if (OpCodeLength
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
2246 // The formset OpCode contains ClassGuid
2248 FormSet
->NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2249 CopyMem (FormSet
->ClassGuid
, OpCodeData
+ sizeof (EFI_IFR_FORM_SET
), FormSet
->NumberOfClassGuid
* sizeof (EFI_GUID
));
2251 FormSet
->FormSetOrder
= ++mFormSetOrderParse
;
2254 case EFI_IFR_FORM_OP
:
2255 case EFI_IFR_FORM_MAP_OP
:
2257 // Create a new Form for this FormSet
2259 CurrentForm
= AllocateZeroPool (sizeof (FORM_BROWSER_FORM
));
2260 ASSERT (CurrentForm
!= NULL
);
2261 CurrentForm
->Signature
= FORM_BROWSER_FORM_SIGNATURE
;
2262 InitializeListHead (&CurrentForm
->ExpressionListHead
);
2263 InitializeListHead (&CurrentForm
->StatementListHead
);
2265 CurrentForm
->FormType
= STANDARD_MAP_FORM_TYPE
;
2266 CopyMem (&CurrentForm
->FormId
, &((EFI_IFR_FORM
*) OpCodeData
)->FormId
, sizeof (UINT16
));
2267 CopyMem (&CurrentForm
->FormTitle
, &((EFI_IFR_FORM
*) OpCodeData
)->FormTitle
, sizeof (EFI_STRING_ID
));
2269 if (InScopeFormSuppress
) {
2271 // Form is inside of suppressif
2273 CurrentForm
->SuppressExpression
= FormSuppressExpression
;
2278 // Enter scope of a Form, suppressif will be used for Question or Option
2280 SuppressForQuestion
= TRUE
;
2284 // Insert into Form list of this FormSet
2286 InsertTailList (&FormSet
->FormListHead
, &CurrentForm
->Link
);
2291 case EFI_IFR_VARSTORE_OP
:
2293 // Create a buffer Storage for this FormSet
2296 Storage
= CreateStorage (FormSet
);
2297 Storage
->Type
= EFI_IFR_VARSTORE_OP
;
2299 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
2300 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2301 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE
*) OpCodeData
)->Size
, sizeof (UINT16
));
2303 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
2305 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE
*) OpCodeData
)->Name
;
2306 Storage
->Name
= AllocateZeroPool ((strlen (AsciiString
) + 1) * 2);
2307 ASSERT (Storage
->Name
!= NULL
);
2308 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
2309 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
2311 Storage
->FormSetOrder
= mFormSetOrderParse
;
2314 // If not existed the same variable in StorageList, insert the new one. Or else, use the old one.
2315 // If these two variales have the same Guid name but different size, report an error.
2317 if ((TempStorage
= NotSameVariableInVarList (FormSet
->StorageListHead
, Storage
)) != NULL
) {
2318 if (Storage
->Size
!= TempStorage
->Size
) {
2319 StringPrint ("Error. Two modules found with VarStore variables with same name %S and GUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x, but with different sizes %d and %d.\n",
2321 Storage
->Guid
.Data1
,
2322 Storage
->Guid
.Data2
,
2323 Storage
->Guid
.Data3
,
2324 Storage
->Guid
.Data4
[0],
2325 Storage
->Guid
.Data4
[1],
2326 Storage
->Guid
.Data4
[2],
2327 Storage
->Guid
.Data4
[3],
2328 Storage
->Guid
.Data4
[4],
2329 Storage
->Guid
.Data4
[5],
2330 Storage
->Guid
.Data4
[6],
2331 Storage
->Guid
.Data4
[7],
2338 // Update the VarStoreId for current question to get the variable guid and name information
2340 TempStorage
->VarStoreId
= Storage
->VarStoreId
;
2341 TempStorage
->FormSetOrder
= Storage
->FormSetOrder
;
2342 RemoveEntryList (&Storage
->Link
);
2343 DestroyStorage(Storage
);
2347 case EFI_IFR_VARSTORE_NAME_VALUE_OP
:
2349 // Create a name/value Storage for this FormSet
2351 Storage
= CreateStorage (FormSet
);
2352 Storage
->Type
= EFI_HII_VARSTORE_NAME_VALUE
;
2354 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
2355 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_NAME_VALUE
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2357 Storage
->FormSetOrder
= mFormSetOrderParse
;
2360 case EFI_IFR_VARSTORE_EFI_OP
:
2362 // Create a EFI variable Storage for this FormSet
2364 Storage
= CreateStorage (FormSet
);
2365 Storage
->Type
= EFI_IFR_VARSTORE_EFI_OP
;
2366 CopyMem (&Storage
->VarStoreId
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->VarStoreId
, sizeof (EFI_VARSTORE_ID
));
2367 CopyMem (&Storage
->Guid
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2368 CopyMem (&Storage
->Attributes
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Attributes
, sizeof (UINT32
));
2370 // Check whether the EfiVarStore before UEFI2.31 or not
2372 Storage
->Size
= sizeof (EFI_IFR_VARSTORE_EFI_OLD
);
2373 if (((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Header
.Length
== sizeof (EFI_IFR_VARSTORE_EFI_OLD
)) {
2374 Storage
->NewEfiVarstore
= FALSE
;
2376 Storage
->Buffer
= NULL
;
2377 Storage
->Name
= NULL
;
2381 // EfiVarStore structure for UEFI2.31
2383 Storage
->NewEfiVarstore
= TRUE
;
2384 CopyMem (&Storage
->Size
, &((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Size
, sizeof (UINT16
));
2386 Storage
->Buffer
= AllocateZeroPool (Storage
->Size
);
2387 AsciiString
= (CHAR8
*) ((EFI_IFR_VARSTORE_EFI
*) OpCodeData
)->Name
;
2388 Storage
->Name
= AllocateZeroPool ((strlen (AsciiString
) + 1) * 2);
2389 ASSERT (Storage
->Name
!= NULL
);
2390 for (Index
= 0; AsciiString
[Index
] != 0; Index
++) {
2391 Storage
->Name
[Index
] = (CHAR16
) AsciiString
[Index
];
2394 Storage
->FormSetOrder
= mFormSetOrderParse
;
2396 // If not existed the same variable in StorageList, insert the new one. Or else, use the old one.
2397 // If these two variales have the same Guid name but different size, report an error.
2399 if ((TempStorage
= NotSameVariableInVarList (FormSet
->StorageListHead
, Storage
)) != NULL
) {
2400 if (Storage
->Size
!= TempStorage
->Size
) {
2401 StringPrint ("Error. Two modules found with EfiVarStore variables with same name %S and GUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x, but different sizes %d and %d.\n",
2403 Storage
->Guid
.Data1
,
2404 Storage
->Guid
.Data2
,
2405 Storage
->Guid
.Data3
,
2406 Storage
->Guid
.Data4
[0],
2407 Storage
->Guid
.Data4
[1],
2408 Storage
->Guid
.Data4
[2],
2409 Storage
->Guid
.Data4
[3],
2410 Storage
->Guid
.Data4
[4],
2411 Storage
->Guid
.Data4
[5],
2412 Storage
->Guid
.Data4
[6],
2413 Storage
->Guid
.Data4
[7],
2420 // Update the VarStoreId for current question to get the variable guid and name information
2422 TempStorage
->VarStoreId
= Storage
->VarStoreId
;
2423 TempStorage
->FormSetOrder
= Storage
->FormSetOrder
;
2424 RemoveEntryList (&Storage
->Link
);
2425 DestroyStorage( Storage
);
2432 case EFI_IFR_DEFAULTSTORE_OP
:
2433 HaveInserted
= FALSE
;
2434 DefaultStore
= AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE
));
2435 ASSERT (DefaultStore
!= NULL
);
2436 DefaultStore
->Signature
= FORMSET_DEFAULTSTORE_SIGNATURE
;
2438 CopyMem (&DefaultStore
->DefaultId
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
2439 CopyMem (&DefaultStore
->DefaultName
, &((EFI_IFR_DEFAULTSTORE
*) OpCodeData
)->DefaultName
, sizeof (EFI_STRING_ID
));
2442 // Insert it to the DefaultStore list of this Formset with ascending order.
2444 if (!IsListEmpty (&FormSet
->DefaultStoreListHead
)) {
2445 DefaultLink
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
2446 while (!IsNull (&FormSet
->DefaultStoreListHead
, DefaultLink
)) {
2447 PreDefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink
);
2448 DefaultLink
= GetNextNode (&FormSet
->DefaultStoreListHead
, DefaultLink
);
2449 if (DefaultStore
->DefaultId
< PreDefaultStore
->DefaultId
) {
2450 InsertTailList (&PreDefaultStore
->Link
, &DefaultStore
->Link
);
2451 HaveInserted
= TRUE
;
2456 if (!HaveInserted
) {
2457 InsertTailList (&FormSet
->DefaultStoreListHead
, &DefaultStore
->Link
);
2464 case EFI_IFR_SUBTITLE_OP
:
2465 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2466 ASSERT (CurrentStatement
!= NULL
);
2468 CurrentStatement
->Flags
= ((EFI_IFR_SUBTITLE
*) OpCodeData
)->Flags
;
2471 mInScopeSubtitle
= TRUE
;
2475 case EFI_IFR_TEXT_OP
:
2476 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2477 ASSERT (CurrentStatement
!= NULL
);
2479 CopyMem (&CurrentStatement
->TextTwo
, &((EFI_IFR_TEXT
*) OpCodeData
)->TextTwo
, sizeof (EFI_STRING_ID
));
2482 case EFI_IFR_RESET_BUTTON_OP
:
2483 CurrentStatement
= CreateStatement (OpCodeData
, FormSet
, CurrentForm
);
2484 ASSERT (CurrentStatement
!= NULL
);
2485 CopyMem (&CurrentStatement
->DefaultId
, &((EFI_IFR_RESET_BUTTON
*) OpCodeData
)->DefaultId
, sizeof (EFI_DEFAULT_ID
));
2491 case EFI_IFR_ACTION_OP
:
2492 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2493 ASSERT (CurrentStatement
!= NULL
);
2494 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_ACTION
;
2496 // No need to deal with the EFI_IFR_ACTION
2500 case EFI_IFR_REF_OP
:
2501 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2502 ASSERT (CurrentStatement
!= NULL
);
2503 Value
= &CurrentStatement
->HiiValue
;
2504 Value
->Type
= EFI_IFR_TYPE_REF
;
2505 if (OpCodeLength
>= sizeof (EFI_IFR_REF
)) {
2506 CopyMem (&Value
->Value
.ref
.FormId
, &((EFI_IFR_REF
*) OpCodeData
)->FormId
, sizeof (EFI_FORM_ID
));
2508 if (OpCodeLength
>= sizeof (EFI_IFR_REF2
)) {
2509 CopyMem (&Value
->Value
.ref
.QuestionId
, &((EFI_IFR_REF2
*) OpCodeData
)->QuestionId
, sizeof (EFI_QUESTION_ID
));
2511 if (OpCodeLength
>= sizeof (EFI_IFR_REF3
)) {
2512 CopyMem (&Value
->Value
.ref
.FormSetGuid
, &((EFI_IFR_REF3
*) OpCodeData
)->FormSetId
, sizeof (EFI_GUID
));
2514 if (OpCodeLength
>= sizeof (EFI_IFR_REF4
)) {
2515 CopyMem (&Value
->Value
.ref
.DevicePath
, &((EFI_IFR_REF4
*) OpCodeData
)->DevicePath
, sizeof (EFI_STRING_ID
));
2520 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_REF
);
2523 case EFI_IFR_ONE_OF_OP
:
2524 case EFI_IFR_NUMERIC_OP
:
2525 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2526 ASSERT(CurrentStatement
!= NULL
);
2528 CurrentStatement
->Flags
= ((EFI_IFR_ONE_OF
*) OpCodeData
)->Flags
;
2529 Value
= &CurrentStatement
->HiiValue
;
2531 if (BitFieldStorage
) {
2533 // Get the bit var store info (bit/byte offset, bit/byte offset)
2535 CurrentStatement
->QuestionReferToBitField
= TRUE
;
2536 CurrentStatement
->BitStorageWidth
= CurrentStatement
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
2537 CurrentStatement
->BitVarOffset
= CurrentStatement
->VarStoreInfo
.VarOffset
;
2538 CurrentStatement
->VarStoreInfo
.VarOffset
= CurrentStatement
->BitVarOffset
/ 8;
2539 TotalBits
= CurrentStatement
->BitVarOffset
% 8 + CurrentStatement
->BitStorageWidth
;
2540 CurrentStatement
->StorageWidth
= (TotalBits
% 8 == 0? TotalBits
/ 8: TotalBits
/ 8 + 1);
2542 // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)
2544 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
;
2545 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
;
2546 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
;
2548 switch (CurrentStatement
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
2549 case EFI_IFR_NUMERIC_SIZE_1
:
2550 CurrentStatement
->Minimum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MinValue
;
2551 CurrentStatement
->Maximum
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.MaxValue
;
2552 CurrentStatement
->Step
= ((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u8
.Step
;
2553 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT8
);
2554 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
2557 case EFI_IFR_NUMERIC_SIZE_2
:
2558 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MinValue
, sizeof (UINT16
));
2559 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.MaxValue
, sizeof (UINT16
));
2560 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u16
.Step
, sizeof (UINT16
));
2561 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT16
);
2562 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
2565 case EFI_IFR_NUMERIC_SIZE_4
:
2566 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MinValue
, sizeof (UINT32
));
2567 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.MaxValue
, sizeof (UINT32
));
2568 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u32
.Step
, sizeof (UINT32
));
2569 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT32
);
2570 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
2573 case EFI_IFR_NUMERIC_SIZE_8
:
2574 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MinValue
, sizeof (UINT64
));
2575 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.MaxValue
, sizeof (UINT64
));
2576 CopyMem (&CurrentStatement
->Step
, &((EFI_IFR_NUMERIC
*) OpCodeData
)->data
.u64
.Step
, sizeof (UINT64
));
2577 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (UINT64
);
2578 Value
->Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
2585 if ((Operand
== EFI_IFR_ONE_OF_OP
) && (Scope
!= 0)) {
2586 SuppressForOption
= TRUE
;
2589 // Get the UQI information
2591 PrintQuestion(FormSet
, CurrentForm
, CurrentStatement
, FALSE
);
2593 // Exchange the Guid and name information between VarList and Question List
2595 Status
= GetGuidNameByVariableId (FormSet
, CurrentStatement
, FormSet
->StorageListHead
);
2597 // Remove the question which isn't stored by EfiVarStore or VarStore
2599 if (EFI_ERROR (Status
)) {
2600 RemoveEntryList (&CurrentStatement
->Link
);
2601 DestroyStatement (FormSet
, CurrentStatement
);
2605 case EFI_IFR_ORDERED_LIST_OP
:
2606 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2607 ASSERT(CurrentStatement
!= NULL
);
2609 CurrentStatement
->Flags
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->Flags
;
2610 CurrentStatement
->MaxContainers
= ((EFI_IFR_ORDERED_LIST
*) OpCodeData
)->MaxContainers
;
2612 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BUFFER
;
2613 CurrentStatement
->BufferValue
= NULL
;
2615 SuppressForOption
= TRUE
;
2618 // Get the UQI information
2620 PrintQuestion(FormSet
, CurrentForm
, CurrentStatement
, FALSE
);
2622 // Exchange the Guid and name information between VarList and Question List
2624 Status
= GetGuidNameByVariableId (FormSet
, CurrentStatement
, FormSet
->StorageListHead
);
2626 // Remove the question which isn't stored by EfiVarStore or VarStore
2628 if (EFI_ERROR (Status
)) {
2629 RemoveEntryList (&CurrentStatement
->Link
);
2630 DestroyStatement (FormSet
, CurrentStatement
);
2635 case EFI_IFR_CHECKBOX_OP
:
2636 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2637 ASSERT(CurrentStatement
!= NULL
);
2639 CurrentStatement
->Flags
= ((EFI_IFR_CHECKBOX
*) OpCodeData
)->Flags
;
2640 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (BOOLEAN
);
2641 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_BOOLEAN
;
2643 if (BitFieldStorage
) {
2645 // Get the bit var store info (bit/byte offset, bit/byte width)
2647 CurrentStatement
->QuestionReferToBitField
= TRUE
;
2648 CurrentStatement
->BitStorageWidth
= 1;
2649 CurrentStatement
->BitVarOffset
= CurrentStatement
->VarStoreInfo
.VarOffset
;
2650 CurrentStatement
->VarStoreInfo
.VarOffset
= CurrentStatement
->BitVarOffset
/ 8;
2651 TotalBits
= CurrentStatement
->BitVarOffset
% 8 + CurrentStatement
->BitStorageWidth
;
2652 CurrentStatement
->StorageWidth
= (TotalBits
% 8 == 0? TotalBits
/ 8: TotalBits
/ 8 + 1);
2655 // Get the UQI information
2657 PrintQuestion(FormSet
, CurrentForm
, CurrentStatement
, FALSE
);
2659 // Exchange the Guid and name information between VarList and Question List
2661 Status
= GetGuidNameByVariableId (FormSet
, CurrentStatement
, FormSet
->StorageListHead
);
2663 // Remove the question which isn't stored by EfiVarStore or VarStore
2665 if (EFI_ERROR (Status
)) {
2666 RemoveEntryList (&CurrentStatement
->Link
);
2667 DestroyStatement (FormSet
, CurrentStatement
);
2672 case EFI_IFR_STRING_OP
:
2673 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2674 ASSERT (CurrentStatement
!= NULL
);
2676 // MinSize is the minimum number of characters that can be accepted for this opcode,
2677 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2678 // The characters are stored as Unicode, so the storage width should multiply 2.
2680 CurrentStatement
->Minimum
= ((EFI_IFR_STRING
*) OpCodeData
)->MinSize
;
2681 CurrentStatement
->Maximum
= ((EFI_IFR_STRING
*) OpCodeData
)->MaxSize
;
2682 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
2683 CurrentStatement
->Flags
= ((EFI_IFR_STRING
*) OpCodeData
)->Flags
;
2685 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
2686 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
+ sizeof (CHAR16
));
2688 // Get the UQI information
2690 PrintQuestion(FormSet
, CurrentForm
, CurrentStatement
, FALSE
);
2692 // Exchange the Guid and name information between VarList and Question List
2694 Status
= GetGuidNameByVariableId (FormSet
, CurrentStatement
, FormSet
->StorageListHead
);
2696 // Remove the question which isn't stored by EfiVarStore or VarStore
2698 if (EFI_ERROR (Status
)) {
2699 RemoveEntryList (&CurrentStatement
->Link
);
2700 DestroyStatement (FormSet
, CurrentStatement
);
2705 case EFI_IFR_PASSWORD_OP
:
2706 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2707 ASSERT (CurrentStatement
!= NULL
);
2709 // MinSize is the minimum number of characters that can be accepted for this opcode,
2710 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2711 // The characters are stored as Unicode, so the storage width should multiply 2.
2713 CopyMem (&CurrentStatement
->Minimum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MinSize
, sizeof (UINT16
));
2714 CopyMem (&CurrentStatement
->Maximum
, &((EFI_IFR_PASSWORD
*) OpCodeData
)->MaxSize
, sizeof (UINT16
));
2715 CurrentStatement
->StorageWidth
= (UINT16
)((UINTN
) CurrentStatement
->Maximum
* sizeof (CHAR16
));
2717 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_STRING
;
2718 CurrentStatement
->BufferValue
= AllocateZeroPool ((CurrentStatement
->StorageWidth
+ sizeof (CHAR16
)));
2721 case EFI_IFR_DATE_OP
:
2722 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2723 ASSERT(CurrentStatement
!= NULL
);
2725 CurrentStatement
->Flags
= ((EFI_IFR_DATE
*) OpCodeData
)->Flags
;
2726 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_DATE
;
2728 if ((CurrentStatement
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_NORMAL
) {
2729 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_DATE
);
2732 // Don't assign storage for RTC type of date/time
2734 CurrentStatement
->Storage
= NULL
;
2735 CurrentStatement
->StorageWidth
= 0;
2739 case EFI_IFR_TIME_OP
:
2740 CurrentStatement
= CreateQuestion (OpCodeData
, FormSet
, CurrentForm
);
2741 ASSERT(CurrentStatement
!= NULL
);
2743 CurrentStatement
->Flags
= ((EFI_IFR_TIME
*) OpCodeData
)->Flags
;
2744 CurrentStatement
->HiiValue
.Type
= EFI_IFR_TYPE_TIME
;
2746 if ((CurrentStatement
->Flags
& QF_TIME_STORAGE
) == QF_TIME_STORAGE_NORMAL
) {
2747 CurrentStatement
->StorageWidth
= (UINT16
) sizeof (EFI_HII_TIME
);
2750 // Don't assign storage for RTC type of date/time
2752 CurrentStatement
->Storage
= NULL
;
2753 CurrentStatement
->StorageWidth
= 0;
2760 case EFI_IFR_DEFAULT_OP
:
2762 // EFI_IFR_DEFAULT appear in scope of a Question,
2763 // It creates a default value for the current question.
2764 // A Question may have more than one Default value which have different default types.
2766 CurrentDefault
= AllocateZeroPool (sizeof (QUESTION_DEFAULT
));
2767 ASSERT (CurrentDefault
!= NULL
);
2768 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
2770 CurrentDefault
->Value
.Type
= ((EFI_IFR_DEFAULT
*) OpCodeData
)->Type
;
2771 CopyMem (&CurrentDefault
->DefaultId
, &((EFI_IFR_DEFAULT
*) OpCodeData
)->DefaultId
, sizeof (UINT16
));
2772 if (CurrentDefault
->Value
.Type
== EFI_IFR_TYPE_BUFFER
) {
2773 CurrentDefault
->Value
.BufferLen
= (UINT16
)(OpCodeLength
- OFFSET_OF(EFI_IFR_DEFAULT
, Value
));
2774 CurrentDefault
->Value
.Buffer
= FceAllocateCopyPool(CurrentDefault
->Value
.BufferLen
, &((EFI_IFR_DEFAULT
*)OpCodeData
)->Value
);
2775 ASSERT(CurrentDefault
->Value
.Buffer
!= NULL
);
2777 CopyMem(&CurrentDefault
->Value
.Value
, &((EFI_IFR_DEFAULT
*)OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF(EFI_IFR_DEFAULT
, Value
));
2778 ExtendValueToU64(&CurrentDefault
->Value
);
2782 // Insert to Default Value list of current Question
2784 InsertTailList (&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2787 InScopeDefault
= TRUE
;
2794 case EFI_IFR_ONE_OF_OPTION_OP
:
2795 ASSERT (CurrentStatement
!= NULL
);
2796 if (CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
&&
2797 ((((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Flags
& (EFI_IFR_OPTION_DEFAULT
| EFI_IFR_OPTION_DEFAULT_MFG
)) != 0)) {
2799 // It's keep the default value for ordered list opcode.
2801 CurrentDefault
= AllocateZeroPool(sizeof (QUESTION_DEFAULT
));
2802 ASSERT(CurrentDefault
!= NULL
);
2803 CurrentDefault
->Signature
= QUESTION_DEFAULT_SIGNATURE
;
2805 CurrentDefault
->Value
.Type
= EFI_IFR_TYPE_BUFFER
;
2806 if ((((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2807 CurrentDefault
->DefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2809 CurrentDefault
->DefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2812 CurrentDefault
->Value
.BufferLen
= (UINT16
)(OpCodeLength
- OFFSET_OF(EFI_IFR_ONE_OF_OPTION
, Value
));
2813 CurrentDefault
->Value
.Buffer
= FceAllocateCopyPool(CurrentDefault
->Value
.BufferLen
, &((EFI_IFR_ONE_OF_OPTION
*)OpCodeData
)->Value
);
2814 ASSERT(CurrentDefault
->Value
.Buffer
!= NULL
);
2817 // Insert to Default Value list of current Question
2819 InsertTailList(&CurrentStatement
->DefaultListHead
, &CurrentDefault
->Link
);
2823 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
2824 // It create a selection for use in current Question.
2826 CurrentOption
= AllocateZeroPool (sizeof (QUESTION_OPTION
));
2827 ASSERT (CurrentOption
!= NULL
);
2828 CurrentOption
->Signature
= QUESTION_OPTION_SIGNATURE
;
2830 CurrentOption
->Flags
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Flags
;
2831 CurrentOption
->Value
.Type
= ((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Type
;
2832 CopyMem (&CurrentOption
->Text
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Option
, sizeof (EFI_STRING_ID
));
2833 CopyMem (&CurrentOption
->Value
.Value
, &((EFI_IFR_ONE_OF_OPTION
*) OpCodeData
)->Value
, OpCodeLength
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
));
2834 ExtendValueToU64 (&CurrentOption
->Value
);
2836 if (InScopeOptionSuppress
) {
2837 CurrentOption
->SuppressExpression
= OptionSuppressExpression
;
2841 // Insert to Option list of current Question
2843 InsertTailList (&CurrentStatement
->OptionListHead
, &CurrentOption
->Link
);
2846 // Now we know the Storage width of nested Ordered List
2848 if ((CurrentStatement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) && (CurrentStatement
->BufferValue
== NULL
)) {
2850 switch (CurrentOption
->Value
.Type
) {
2851 case EFI_IFR_TYPE_NUM_SIZE_8
:
2855 case EFI_IFR_TYPE_NUM_SIZE_16
:
2859 case EFI_IFR_TYPE_NUM_SIZE_32
:
2863 case EFI_IFR_TYPE_NUM_SIZE_64
:
2869 // Invalid type for Ordered List
2874 CurrentStatement
->StorageWidth
= (UINT16
) (CurrentStatement
->MaxContainers
* Width
);
2875 CurrentStatement
->BufferValue
= AllocateZeroPool (CurrentStatement
->StorageWidth
);
2876 CurrentStatement
->ValueType
= CurrentOption
->Value
.Type
;
2877 if (CurrentStatement
->HiiValue
.Type
== EFI_IFR_TYPE_BUFFER
) {
2878 CurrentStatement
->HiiValue
.Buffer
= CurrentStatement
->BufferValue
;
2879 CurrentStatement
->HiiValue
.BufferLen
= CurrentStatement
->StorageWidth
;
2887 case EFI_IFR_NO_SUBMIT_IF_OP
:
2888 case EFI_IFR_INCONSISTENT_IF_OP
:
2890 // Create an Expression node
2892 CurrentExpression
= CreateExpression (CurrentForm
);
2893 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_INCONSISTENT_IF
*) OpCodeData
)->Error
, sizeof (EFI_STRING_ID
));
2895 if (Operand
== EFI_IFR_NO_SUBMIT_IF_OP
) {
2896 CurrentExpression
->Type
= EFI_HII_EXPRESSION_NO_SUBMIT_IF
;
2897 InsertTailList (&CurrentStatement
->NoSubmitListHead
, &CurrentExpression
->Link
);
2899 CurrentExpression
->Type
= EFI_HII_EXPRESSION_INCONSISTENT_IF
;
2900 InsertTailList (&CurrentStatement
->InconsistentListHead
, &CurrentExpression
->Link
);
2903 // Take a look at next OpCode to see whether current expression consists
2906 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2907 SingleOpCodeExpression
= TRUE
;
2911 case EFI_IFR_WARNING_IF_OP
:
2913 // Create an Expression node
2915 CurrentExpression
= CreateExpression (CurrentForm
);
2916 CopyMem (&CurrentExpression
->Error
, &((EFI_IFR_WARNING_IF
*) OpCodeData
)->Warning
, sizeof (EFI_STRING_ID
));
2917 CurrentExpression
->TimeOut
= ((EFI_IFR_WARNING_IF
*) OpCodeData
)->TimeOut
;
2918 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WARNING_IF
;
2919 InsertTailList (&CurrentStatement
->WarningListHead
, &CurrentExpression
->Link
);
2922 // Take a look at next OpCode to see whether current expression consists
2925 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2926 SingleOpCodeExpression
= TRUE
;
2930 case EFI_IFR_SUPPRESS_IF_OP
:
2932 // Question and Option will appear in scope of this OpCode
2934 CurrentExpression
= CreateExpression (CurrentForm
);
2935 CurrentExpression
->Type
= EFI_HII_EXPRESSION_SUPPRESS_IF
;
2937 if (CurrentForm
== NULL
) {
2938 InsertTailList (&FormSet
->ExpressionListHead
, &CurrentExpression
->Link
);
2940 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2943 if (SuppressForOption
) {
2944 InScopeOptionSuppress
= TRUE
;
2945 OptionSuppressExpression
= CurrentExpression
;
2946 } else if (SuppressForQuestion
) {
2947 mInScopeSuppress
= TRUE
;
2948 mSuppressExpression
= CurrentExpression
;
2950 InScopeFormSuppress
= TRUE
;
2951 FormSuppressExpression
= CurrentExpression
;
2954 // Take a look at next OpCode to see whether current expression consists
2957 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2958 SingleOpCodeExpression
= TRUE
;
2962 case EFI_IFR_GRAY_OUT_IF_OP
:
2964 // Questions will appear in scope of this OpCode
2966 CurrentExpression
= CreateExpression (CurrentForm
);
2967 CurrentExpression
->Type
= EFI_HII_EXPRESSION_GRAY_OUT_IF
;
2968 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
2970 mInScopeGrayOut
= TRUE
;
2971 mGrayOutExpression
= CurrentExpression
;
2974 // Take a look at next OpCode to see whether current expression consists
2977 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
2978 SingleOpCodeExpression
= TRUE
;
2982 case EFI_IFR_DISABLE_IF_OP
:
2984 // The DisableIf expression should only rely on constant, so it could be
2985 // evaluated at initialization and it will not be queued
2987 CurrentExpression
= AllocateZeroPool (sizeof (FORM_EXPRESSION
));
2988 ASSERT (CurrentExpression
!= NULL
);
2989 CurrentExpression
->Signature
= FORM_EXPRESSION_SIGNATURE
;
2990 CurrentExpression
->Type
= EFI_HII_EXPRESSION_DISABLE_IF
;
2991 InitializeListHead (&CurrentExpression
->OpCodeListHead
);
2993 if (CurrentForm
!= NULL
) {
2995 // This is DisableIf for Question, enqueue it to Form expression list
2997 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
3000 mDisableExpression
= CurrentExpression
;
3001 mInScopeDisable
= TRUE
;
3002 OpCodeDisabled
= FALSE
;
3005 // Take a look at next OpCode to see whether current expression consists
3008 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
3009 SingleOpCodeExpression
= TRUE
;
3016 case EFI_IFR_VALUE_OP
:
3017 CurrentExpression
= CreateExpression (CurrentForm
);
3018 CurrentExpression
->Type
= EFI_HII_EXPRESSION_VALUE
;
3019 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
3021 if (InScopeDefault
) {
3023 // Used for default (EFI_IFR_DEFAULT)
3025 CurrentDefault
->ValueExpression
= CurrentExpression
;
3028 // If used for a question, then the question will be read-only
3031 // Make sure CurrentStatement is not NULL.
3032 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
3033 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
3035 ASSERT (CurrentStatement
!= NULL
);
3036 CurrentStatement
->ValueExpression
= CurrentExpression
;
3040 // Take a look at next OpCode to see whether current expression consists
3043 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
3044 SingleOpCodeExpression
= TRUE
;
3048 case EFI_IFR_RULE_OP
:
3049 CurrentExpression
= CreateExpression (CurrentForm
);
3050 CurrentExpression
->Type
= EFI_HII_EXPRESSION_RULE
;
3052 CurrentExpression
->RuleId
= ((EFI_IFR_RULE
*) OpCodeData
)->RuleId
;
3053 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
3056 // Take a look at next OpCode to see whether current expression consists
3059 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
3060 SingleOpCodeExpression
= TRUE
;
3064 case EFI_IFR_READ_OP
:
3065 CurrentExpression
= CreateExpression (CurrentForm
);
3066 CurrentExpression
->Type
= EFI_HII_EXPRESSION_READ
;
3067 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
3070 // Make sure CurrentStatement is not NULL.
3071 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
3072 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
3074 ASSERT (CurrentStatement
!= NULL
);
3075 CurrentStatement
->ReadExpression
= CurrentExpression
;
3078 // Take a look at next OpCode to see whether current expression consists
3081 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
3082 SingleOpCodeExpression
= TRUE
;
3086 case EFI_IFR_WRITE_OP
:
3087 CurrentExpression
= CreateExpression (CurrentForm
);
3088 CurrentExpression
->Type
= EFI_HII_EXPRESSION_WRITE
;
3089 InsertTailList (&CurrentForm
->ExpressionListHead
, &CurrentExpression
->Link
);
3092 // Make sure CurrentStatement is not NULL.
3093 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
3094 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
3096 ASSERT (CurrentStatement
!= NULL
);
3097 CurrentStatement
->WriteExpression
= CurrentExpression
;
3100 // Take a look at next OpCode to see whether current expression consists
3103 if (((EFI_IFR_OP_HEADER
*) (OpCodeData
+ OpCodeLength
))->Scope
== 0) {
3104 SingleOpCodeExpression
= TRUE
;
3111 case EFI_IFR_IMAGE_OP
:
3113 // Get ScopeOpcode from top of stack
3115 PopScope (&ScopeOpCode
);
3116 PushScope (ScopeOpCode
);
3118 switch (ScopeOpCode
) {
3119 case EFI_IFR_FORM_SET_OP
:
3122 case EFI_IFR_FORM_OP
:
3123 case EFI_IFR_FORM_MAP_OP
:
3124 ASSERT (CurrentForm
!= NULL
);
3127 case EFI_IFR_ONE_OF_OPTION_OP
:
3132 // Make sure CurrentStatement is not NULL.
3133 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
3134 // file is wrongly generated by tools such as VFR Compiler.
3136 ASSERT (CurrentStatement
!= NULL
);
3144 case EFI_IFR_REFRESH_OP
:
3150 case EFI_IFR_REFRESH_ID_OP
:
3156 case EFI_IFR_MODAL_TAG_OP
:
3162 case EFI_IFR_GUID_OP
:
3163 if (CompareGuid ((EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarGuid
)==0) {
3165 BitFieldStorage
= TRUE
;
3172 case EFI_IFR_END_OP
:
3173 BitFieldStorage
= FALSE
;
3174 Status
= PopScope (&ScopeOpCode
);
3175 if (EFI_ERROR (Status
)) {
3180 switch (ScopeOpCode
) {
3181 case EFI_IFR_FORM_SET_OP
:
3183 // End of FormSet, update FormSet IFR binary length
3184 // to stop parsing substantial OpCodes
3186 FormSet
->IfrBinaryLength
= OpCodeOffset
;
3189 case EFI_IFR_FORM_OP
:
3190 case EFI_IFR_FORM_MAP_OP
:
3195 SuppressForQuestion
= FALSE
;
3198 case EFI_IFR_ONE_OF_OPTION_OP
:
3202 CurrentOption
= NULL
;
3205 case EFI_IFR_SUBTITLE_OP
:
3206 mInScopeSubtitle
= FALSE
;
3209 case EFI_IFR_NO_SUBMIT_IF_OP
:
3210 case EFI_IFR_INCONSISTENT_IF_OP
:
3211 case EFI_IFR_WARNING_IF_OP
:
3213 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
3217 case EFI_IFR_SUPPRESS_IF_OP
:
3218 if (SuppressForOption
) {
3219 InScopeOptionSuppress
= FALSE
;
3220 } else if (SuppressForQuestion
) {
3221 mInScopeSuppress
= FALSE
;
3223 InScopeFormSuppress
= FALSE
;
3227 case EFI_IFR_GRAY_OUT_IF_OP
:
3228 mInScopeGrayOut
= FALSE
;
3231 case EFI_IFR_DISABLE_IF_OP
:
3232 mInScopeDisable
= FALSE
;
3233 OpCodeDisabled
= FALSE
;
3236 case EFI_IFR_ONE_OF_OP
:
3237 case EFI_IFR_ORDERED_LIST_OP
:
3238 SuppressForOption
= FALSE
;
3241 case EFI_IFR_DEFAULT_OP
:
3242 InScopeDefault
= FALSE
;
3245 case EFI_IFR_MAP_OP
:
3247 // Get current Map Expression List.
3249 Status
= PopMapExpressionList ((VOID
**) &MapExpressionList
);
3250 if (Status
== EFI_ACCESS_DENIED
) {
3251 MapExpressionList
= NULL
;
3254 // Get current expression.
3256 Status
= PopCurrentExpression ((VOID
**) &CurrentExpression
);
3257 ASSERT (!EFI_ERROR (Status
));
3258 ASSERT (MapScopeDepth
> 0);
3263 if (IsExpressionOpCode (ScopeOpCode
)) {
3264 if (mInScopeDisable
&& (CurrentForm
== NULL
)) {
3266 // This is DisableIf expression for Form, it should be a constant expression
3268 ASSERT (CurrentExpression
!= NULL
);
3269 ConstantFlag
= TRUE
;
3270 Status
= EvaluateExpression (FormSet
, CurrentForm
, CurrentExpression
, &ConstantFlag
);
3271 if (EFI_ERROR (Status
)) {
3274 if (CurrentExpression
->Result
.Type
!= EFI_IFR_TYPE_BOOLEAN
) {
3275 return EFI_INVALID_PARAMETER
;
3277 if (!ConstantFlag
) {
3278 StringPrint ("WARNING. The DisableIf expression for Form should be a constant expression.\n");
3280 OpCodeDisabled
= CurrentExpression
->Result
.Value
.b
;
3282 // DisableIf Expression is only used once and not queued, free it
3284 DestroyExpression (CurrentExpression
);
3288 // End of current Expression
3290 CurrentExpression
= NULL
;
3305 Search an Option of a Question by its value.
3307 @param Question The Question
3308 @param OptionValue Value for Option to be searched.
3310 @retval Pointer Pointer to the found Option.
3311 @retval NULL Option not found.
3316 IN FORM_BROWSER_FORMSET
*FormSet
,
3317 IN FORM_BROWSER_STATEMENT
*Question
,
3318 IN EFI_HII_VALUE
*OptionValue
3322 QUESTION_OPTION
*Option
;
3324 Link
= GetFirstNode (&Question
->OptionListHead
);
3325 while (!IsNull (&Question
->OptionListHead
, Link
)) {
3326 Option
= QUESTION_OPTION_FROM_LINK (Link
);
3328 if (CompareHiiValue (&Option
->Value
, OptionValue
, FormSet
) == 0) {
3332 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
3339 Set value of a data element in an Array by its Index.
3341 @param Array The data array.
3342 @param Type Type of the data in this array.
3343 @param Index Zero based index for data in this array.
3344 @param Value The value to be set.
3356 ASSERT (Array
!= NULL
);
3359 case EFI_IFR_TYPE_NUM_SIZE_8
:
3360 *(((UINT8
*) Array
) + Index
) = (UINT8
) Value
;
3363 case EFI_IFR_TYPE_NUM_SIZE_16
:
3364 *(((UINT16
*) Array
) + Index
) = (UINT16
) Value
;
3367 case EFI_IFR_TYPE_NUM_SIZE_32
:
3368 *(((UINT32
*) Array
) + Index
) = (UINT32
) Value
;
3371 case EFI_IFR_TYPE_NUM_SIZE_64
:
3372 *(((UINT64
*) Array
) + Index
) = (UINT64
) Value
;
3381 Reset Question of five kinds to its default value.
3383 @param FormSet The form set.
3384 @param Form The form.
3385 @param Question The question.
3386 @param DefaultId The default Id.
3387 @param DefaultId The platform Id.
3389 @retval EFI_SUCCESS Question is reset to default value.
3393 GetQuestionDefault (
3394 IN FORM_BROWSER_FORMSET
*FormSet
,
3395 IN FORM_BROWSER_FORM
*Form
,
3396 IN FORM_BROWSER_STATEMENT
*Question
,
3397 IN UINT16 DefaultId
,
3398 IN UINT64 PlatformId
3403 QUESTION_DEFAULT
*Default
;
3404 QUESTION_OPTION
*Option
;
3405 EFI_HII_VALUE
*HiiValue
;
3407 FORMSET_STORAGE
*VarList
;
3409 BOOLEAN ConstantFlag
;
3410 UINT16 OriginalDefaultId
;
3411 FORMSET_DEFAULTSTORE
*DefaultStore
;
3412 LIST_ENTRY
*DefaultLink
;
3413 CHAR16
*VarDefaultName
;
3415 VarDefaultName
= NULL
;
3416 Status
= EFI_SUCCESS
;
3417 ConstantFlag
= TRUE
;
3418 OriginalDefaultId
= DefaultId
;
3419 DefaultLink
= GetFirstNode (&FormSet
->DefaultStoreListHead
);
3422 // Statement don't have storage, skip them
3424 if (Question
->QuestionId
== 0) {
3425 return EFI_NOT_FOUND
;
3428 // Return if no any kinds of
3430 if ((Question
->Operand
!= EFI_IFR_CHECKBOX_OP
)
3431 && (Question
->Operand
!= EFI_IFR_ONE_OF_OP
)
3432 && (Question
->Operand
!= EFI_IFR_ORDERED_LIST_OP
)
3433 && (Question
->Operand
!= EFI_IFR_NUMERIC_OP
)
3434 && (Question
->Operand
!= EFI_IFR_STRING_OP
)
3439 // Search the variable for this question (Compatible with the old EfiVarStore before UEFI2.31)
3443 //VarStoreInfoDepending on the type of variable store selected,
3444 //this contains either a 16-bit Buffer Storage offset (VarOffset)
3445 //or a Name/Value or EFI Variable name (VarName).
3447 Status
= SearchVarStorage (
3450 Question
->VarStoreInfo
.VarOffset
,
3451 FormSet
->StorageListHead
,
3452 (CHAR8
**)&VarBuffer
,
3455 if (EFI_ERROR(Status
)) {
3459 // There are three ways to specify default value for a Question:
3460 // 1, use nested EFI_IFR_DEFAULT
3461 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
3462 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
3465 HiiValue
= &Question
->HiiValue
;
3467 // EFI_IFR_DEFAULT has highest priority
3469 if (!IsListEmpty (&Question
->DefaultListHead
)) {
3470 Link
= GetFirstNode (&Question
->DefaultListHead
);
3471 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
3472 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
3474 if (Default
->DefaultId
== DefaultId
) {
3475 if (Default
->ValueExpression
!= NULL
) {
3477 // Default is provided by an Expression, evaluate it
3479 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
, &ConstantFlag
);
3480 if (EFI_ERROR (Status
)) {
3484 if (Default
->ValueExpression
->Result
.Type
== EFI_IFR_TYPE_BUFFER
) {
3485 if (Question
->StorageWidth
> Default
->ValueExpression
->Result
.BufferLen
) {
3486 CopyMem(Question
->HiiValue
.Buffer
, Default
->ValueExpression
->Result
.Buffer
, Default
->ValueExpression
->Result
.BufferLen
);
3487 Question
->HiiValue
.BufferLen
= Default
->ValueExpression
->Result
.BufferLen
;
3489 CopyMem(Question
->HiiValue
.Buffer
, Default
->ValueExpression
->Result
.Buffer
, Question
->StorageWidth
);
3490 Question
->HiiValue
.BufferLen
= Question
->StorageWidth
;
3492 FreePool(Default
->ValueExpression
->Result
.Buffer
);
3494 HiiValue
->Type
= Default
->ValueExpression
->Result
.Type
;
3495 CopyMem(&HiiValue
->Value
, &Default
->ValueExpression
->Result
.Value
, sizeof (EFI_IFR_TYPE_VALUE
));
3498 // Default value is embedded in EFI_IFR_DEFAULT
3500 if (Default
->Value
.Type
== EFI_IFR_TYPE_BUFFER
) {
3501 CopyMem(HiiValue
->Buffer
, Default
->Value
.Buffer
, Default
->Value
.BufferLen
);
3503 CopyMem(HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
3506 if (Default
->Value
.Type
== EFI_IFR_TYPE_BUFFER
) {
3507 CopyMem(VarBuffer
, HiiValue
->Buffer
, HiiValue
->BufferLen
);
3508 } else if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
){
3509 Status
= FindDefaultName (
3510 &(FormSet
->EnUsStringList
),
3511 FormSet
->UnicodeBinary
,
3512 HiiValue
->Value
.string
,
3516 if (VarDefaultName
== NULL
) {
3517 return EFI_NOT_FOUND
;
3519 if (Question
->StorageWidth
> FceStrSize(VarDefaultName
)) {
3520 ZeroMem (VarBuffer
, Question
->StorageWidth
);
3521 CopyMem (VarBuffer
, VarDefaultName
, FceStrSize(VarDefaultName
));
3523 CopyMem (VarBuffer
, VarDefaultName
, Question
->StorageWidth
);
3526 if (Question
->QuestionReferToBitField
) {
3527 SetBitsQuestionValue(Question
, VarBuffer
, HiiValue
->Value
.u32
);
3529 CopyMem(VarBuffer
, &HiiValue
->Value
.u64
, Question
->StorageWidth
);
3534 if (Default
->DefaultId
== DefaultId
) {
3537 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
3541 if (HiiValue
->Buffer
== NULL
) {
3542 ZeroMem (HiiValue
, sizeof (EFI_HII_VALUE
));
3546 // EFI_ONE_OF_OPTION
3548 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
3549 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
3551 // OneOfOption could only provide Standard and Manufacturing default
3553 Link
= GetFirstNode (&Question
->OptionListHead
);
3554 while (!IsNull (&Question
->OptionListHead
, Link
)) {
3555 Option
= QUESTION_OPTION_FROM_LINK (Link
);
3557 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
3558 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
3560 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
3561 if (Question
->QuestionReferToBitField
) {
3562 SetBitsQuestionValue(Question
, VarBuffer
, HiiValue
->Value
.u32
);
3564 CopyMem (VarBuffer
, &HiiValue
->Value
.u64
, Question
->StorageWidth
);
3569 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
3575 // EFI_IFR_CHECKBOX - lowest priority
3577 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
3578 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
3580 // Checkbox could only provide Standard and Manufacturing default
3582 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
3583 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
3585 HiiValue
->Value
.b
= TRUE
;
3586 if (Question
->QuestionReferToBitField
) {
3587 SetBitsQuestionValue(Question
, VarBuffer
, HiiValue
->Value
.u32
);
3589 CopyMem (VarBuffer
, &HiiValue
->Value
.u64
, Question
->StorageWidth
);
3597 // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.
3598 // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.
3599 // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.
3601 while (!IsNull(&FormSet
->DefaultStoreListHead
, DefaultLink
)) {
3602 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink
);
3603 DefaultLink
= GetNextNode (&FormSet
->DefaultStoreListHead
,DefaultLink
);
3604 DefaultId
= DefaultStore
->DefaultId
;
3605 if (DefaultId
== OriginalDefaultId
) {
3612 // For Questions without default
3614 Status
= EFI_NOT_FOUND
;
3615 switch (Question
->Operand
) {
3616 case EFI_IFR_CHECKBOX_OP
:
3617 HiiValue
->Value
.b
= FALSE
;
3618 if (Question
->QuestionReferToBitField
) {
3619 SetBitsQuestionValue(Question
, VarBuffer
, HiiValue
->Value
.u32
);
3621 CopyMem (VarBuffer
, &HiiValue
->Value
.u64
, Question
->StorageWidth
);
3625 case EFI_IFR_NUMERIC_OP
:
3627 // Take minimum value as numeric default value
3629 if ((HiiValue
->Value
.u64
< Question
->Minimum
) || (HiiValue
->Value
.u64
> Question
->Maximum
)) {
3630 HiiValue
->Value
.u64
= Question
->Minimum
;
3631 if (Question
->QuestionReferToBitField
) {
3632 SetBitsQuestionValue(Question
, VarBuffer
, HiiValue
->Value
.u32
);
3634 CopyMem (VarBuffer
, &HiiValue
->Value
.u64
, Question
->StorageWidth
);
3640 case EFI_IFR_ONE_OF_OP
:
3642 // Take first oneof option as oneof's default value
3644 if (ValueToOption (FormSet
, Question
, HiiValue
) == NULL
) {
3645 Link
= GetFirstNode (&Question
->OptionListHead
);
3646 if (!IsNull (&Question
->OptionListHead
, Link
)) {
3647 Option
= QUESTION_OPTION_FROM_LINK (Link
);
3648 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
3649 if (Question
->QuestionReferToBitField
) {
3650 SetBitsQuestionValue(Question
, VarBuffer
, HiiValue
->Value
.u32
);
3652 CopyMem (VarBuffer
, &HiiValue
->Value
.u64
, Question
->StorageWidth
);
3659 case EFI_IFR_ORDERED_LIST_OP
:
3661 // Take option sequence in IFR as ordered list's default value
3664 Link
= GetFirstNode (&Question
->OptionListHead
);
3665 while (!IsNull (&Question
->OptionListHead
, Link
)) {
3666 Option
= QUESTION_OPTION_FROM_LINK (Link
);
3668 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
3669 SetArrayData (VarBuffer
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
3672 if (Index
>= Question
->MaxContainers
) {
3676 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
3688 Set the value to the variable of platformId question.
3690 @param PlatformId The form set.
3692 @retval EFI_SUCCESS Set successfully.
3696 AssignThePlatformId (
3697 IN UINT64 PlatformId
3701 FORMSET_STORAGE
*VarList
;
3704 Status
= EFI_SUCCESS
;
3709 Status
= SearchVarStorage (
3710 &mMultiPlatformParam
.PlatformIdQuestion
,
3712 mMultiPlatformParam
.PlatformIdQuestion
.VarStoreInfo
.VarOffset
,
3714 (CHAR8
**)&VarBuffer
,
3717 if (EFI_ERROR(Status
)) {
3720 CopyMem (VarBuffer
, &PlatformId
, mMultiPlatformParam
.PlatformIdWidth
);
3722 // Set the HIIvalue of this questions
3724 CopyMem (&mMultiPlatformParam
.Question
->HiiValue
.Value
.u64
, &PlatformId
, mMultiPlatformParam
.PlatformIdWidth
);
3726 switch (mMultiPlatformParam
.PlatformIdWidth
) {
3727 case sizeof (UINT8
):
3728 mMultiPlatformParam
.Question
->HiiValue
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
3731 case sizeof (UINT16
):
3732 mMultiPlatformParam
.Question
->HiiValue
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
3735 case sizeof (UINT32
):
3736 mMultiPlatformParam
.Question
->HiiValue
.Type
= EFI_IFR_TYPE_NUM_SIZE_32
;
3739 case sizeof (UINT64
):
3740 mMultiPlatformParam
.Question
->HiiValue
.Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
3744 mMultiPlatformParam
.Question
->HiiValue
.Type
= EFI_IFR_TYPE_NUM_SIZE_64
;
3749 Reset Questions to their default value in a Form, Formset or System.
3751 @param FormSet FormSet data structure.
3752 @param Form Form data structure.
3753 @param DefaultId The default Id
3754 @param PlatformId The platform Id
3755 @param SettingScope Setting Scope for Default action.
3757 @retval EFI_SUCCESS The function completed successfully.
3758 @retval EFI_UNSUPPORTED Unsupport SettingScope.
3763 IN FORM_BROWSER_FORMSET
*FormSet
,
3764 IN FORM_BROWSER_FORM
*Form
,
3765 IN UINT16 DefaultId
,
3766 IN UINT64 PlatformId
,
3767 IN BROWSER_SETTING_SCOPE SettingScope
3771 LIST_ENTRY
*FormLink
;
3773 LIST_ENTRY
*FormSetEntryListHead
;
3774 FORM_BROWSER_STATEMENT
*Question
;
3776 // Check the supported setting level.
3778 if (SettingScope
>= MaxLevel
) {
3779 return EFI_UNSUPPORTED
;
3782 if (SettingScope
== FormLevel
) {
3784 // Extract Form default
3786 Link
= GetFirstNode (&Form
->StatementListHead
);
3787 while (!IsNull (&Form
->StatementListHead
, Link
)) {
3788 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
3789 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
3791 // Re-set the platformId before calcuate the platformId of every question to avoid over-written.
3793 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
3794 Status
= AssignThePlatformId (PlatformId
);
3795 if (EFI_ERROR (Status
)) {
3796 StringPrint ("Error. Failed to assign the platformId.\n");
3801 // Reset Question to its default value, and store the default to variable
3803 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
, PlatformId
);
3804 if (EFI_ERROR (Status
)) {
3808 } else if (SettingScope
== FormSetLevel
) {
3809 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
3810 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
3811 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
3812 ExtractDefault (FormSet
, Form
, DefaultId
, PlatformId
, FormLevel
);
3813 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
3815 } else if (SettingScope
== SystemLevel
) {
3817 // Parse Fromset one by one
3819 FormSetEntryListHead
= &mFormSetListEntry
;
3821 FormLink
= GetFirstNode (FormSetEntryListHead
);
3822 while (!IsNull (FormSetEntryListHead
, FormLink
)) {
3823 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormLink
);
3824 ExtractDefault (FormSet
, NULL
, DefaultId
, PlatformId
, FormSetLevel
);
3825 FormLink
= GetNextNode (FormSetEntryListHead
, FormLink
);
3833 Check whether existed the UQI in Current Unicode String.
3835 @param UniPackge A pointer to a Null-terminated Unicode string Array.
3837 @return TRUE If find the uqi, return TRUE
3838 @return FALSE Otherwise, return FALSE
3852 UniBin
= (CHAR8
*) UniPackge
+ 4;
3855 UniLength
= *(UINT32
*) UniPackge
;
3857 if (((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
) {
3859 // Search the uqi language
3861 while ((Index
< UniLength
) && ((EFI_HII_PACKAGE_HEADER
*)UniBin
)->Type
== EFI_HII_PACKAGE_STRINGS
){
3862 if (!strcmp (((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Language
, "uqi")) {
3866 Index
= Index
+ ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
3867 UniBin
+= ((EFI_HII_STRING_PACKAGE_HDR
*)UniBin
)->Header
.Length
;
3874 Returns Length of UQI string (in CHAR16) (not including null termination).
3876 @param UniPackge A pointer to a UQI string.
3878 @return Number Length of UQIL string (in words) or 0
3884 IN CHAR16
*UniString
3889 if (UniString
== NULL
) {
3892 for (Number
= 0; UniString
[Number
] != 0; Number
++) {
3899 Print the formset title information.
3901 @param FormSet The pointer to the formset.
3908 StringPrintormSetTitle (
3909 IN FORM_BROWSER_FORMSET
*FormSet
3912 CHAR16
*VarDefaultName
;
3915 VarDefaultName
= NULL
;
3917 StringPrint("\n\n// Form Set: ");
3919 Status
= FindDefaultName (
3920 &(FormSet
->EnUsStringList
),
3921 FormSet
->UnicodeBinary
,
3922 FormSet
->FormSetTitle
,
3926 assert (!EFI_ERROR (Status
));
3927 LogUnicodeString (VarDefaultName
);
3929 StringPrint("\n// %s",FORM_SET_GUID_PREFIX
);
3932 FormSet
->Guid
.Data1
, FormSet
->Guid
.Data2
,
3933 FormSet
->Guid
.Data3
, FormSet
->Guid
.Data4
[0],
3934 FormSet
->Guid
.Data4
[1],FormSet
->Guid
.Data4
[2],
3935 FormSet
->Guid
.Data4
[3],FormSet
->Guid
.Data4
[4],
3936 FormSet
->Guid
.Data4
[5],FormSet
->Guid
.Data4
[6],
3937 FormSet
->Guid
.Data4
[7]);
3940 if (&(FormSet
->EnUsStringList
) == NULL
&& VarDefaultName
!= NULL
&& FormSet
->FormSetTitle
!= 0) {
3941 free (VarDefaultName
);
3942 VarDefaultName
= NULL
;
3947 Print the formset title information.
3949 @param FormSet The pointer to the formset.
3950 @param Question The pointer to the question of ONE_OF.
3958 IN FORM_BROWSER_FORMSET
*FormSet
,
3959 IN FORM_BROWSER_STATEMENT
*Question
3963 QUESTION_OPTION
*Option
;
3964 CHAR16
*VarDefaultName
;
3967 Status
= EFI_SUCCESS
;
3968 VarDefaultName
= NULL
;
3970 if ((Question
->Operand
!= EFI_IFR_ONE_OF_OP
)
3971 && (Question
->Operand
!= EFI_IFR_ORDERED_LIST_OP
)
3976 Link
= GetFirstNode (&Question
->OptionListHead
);
3977 while (!IsNull (&Question
->OptionListHead
, Link
)) {
3978 Option
= QUESTION_OPTION_FROM_LINK (Link
);
3979 if (Question
->QuestionReferToBitField
) {
3980 StringPrint("// %08X = ", Option
->Value
.Value
.u32
);
3982 switch(Option
->Value
.Type
) {
3984 case EFI_IFR_TYPE_NUM_SIZE_8
:
3985 StringPrint("// %02X = ", Option
->Value
.Value
.u8
);
3988 case EFI_IFR_TYPE_NUM_SIZE_16
:
3989 StringPrint("// %04X = ", Option
->Value
.Value
.u16
);
3992 case EFI_IFR_TYPE_NUM_SIZE_32
:
3993 StringPrint("// %08X = ", Option
->Value
.Value
.u32
);
3996 case EFI_IFR_TYPE_NUM_SIZE_64
:
3997 StringPrint("// %016llX = ", Option
->Value
.Value
.u64
);
4000 case EFI_IFR_TYPE_BOOLEAN
:
4001 StringPrint("// %X = ", Option
->Value
.Value
.b
);
4004 case EFI_IFR_TYPE_STRING
:
4005 StringPrint("// %X = ", Option
->Value
.Value
.string
);
4012 Status
= FindDefaultName (
4013 &(FormSet
->EnUsStringList
),
4014 FormSet
->UnicodeBinary
,
4020 LogUnicodeString (VarDefaultName
);
4022 if (&(FormSet
->EnUsStringList
) == NULL
&& VarDefaultName
!= NULL
&& Option
->Text
!= 0) {
4023 free (VarDefaultName
);
4024 VarDefaultName
= NULL
;
4026 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
4032 Print the form title information.
4034 @param FormSet The pointer to the formset.
4035 @param FormSet The pointer to the form.
4042 StringPrintormTitle (
4043 IN FORM_BROWSER_FORMSET
*FormSet
,
4044 IN FORM_BROWSER_FORM
*Form
4047 CHAR16
*VarDefaultName
;
4050 VarDefaultName
= NULL
;
4052 StringPrint("\n// Form: ");
4053 Status
= FindDefaultName (
4054 &(FormSet
->EnUsStringList
),
4055 FormSet
->UnicodeBinary
,
4060 assert (!EFI_ERROR (Status
));
4062 LogUnicodeString (VarDefaultName
);
4065 if (&(FormSet
->EnUsStringList
) == NULL
&& VarDefaultName
!= NULL
&& Form
->FormTitle
!= 0) {
4066 free (VarDefaultName
);
4067 VarDefaultName
= NULL
;
4073 Print the information of questions.
4075 @param FormSet The pointer to the formset.
4076 @param FormSet The pointer to the form.
4077 @param Question The pointer to the question.
4078 @param PrintOrNot Decide whether print or not.
4086 IN FORM_BROWSER_FORMSET
*FormSet
,
4087 IN FORM_BROWSER_FORM
*Form
,
4088 IN FORM_BROWSER_STATEMENT
*Question
,
4089 IN BOOLEAN PrintOrNot
4093 CHAR16
*VarDefaultName
;
4094 UINT16 UqiStringLength
;
4095 BOOLEAN HaveUQIlanguage
;
4097 Status
= EFI_SUCCESS
;
4098 VarDefaultName
= NULL
;
4099 UqiStringLength
= 0;
4101 HaveUQIlanguage
= IsUqiOrNot (FormSet
->UnicodeBinary
);
4103 switch (Question
->Operand
) {
4105 case EFI_IFR_SUBTITLE_OP
:
4107 Status
= FindDefaultName (
4108 &(FormSet
->EnUsStringList
),
4109 FormSet
->UnicodeBinary
,
4114 assert (!EFI_ERROR (Status
));
4115 if ((VarDefaultName
!= NULL
) && (FceStrCmp (VarDefaultName
, L
"") != 0)) {
4116 StringPrint("// Subtitle: ");
4118 LogUnicodeString (VarDefaultName
);
4124 case EFI_IFR_ONE_OF_OP
:
4126 if( HaveUQIlanguage
) {
4127 Status
= FindDefaultName (
4128 &(FormSet
->UqiStringList
),
4129 FormSet
->UnicodeBinary
,
4134 assert (!EFI_ERROR (Status
));
4136 UqiStringLength
= GetUqiNum (VarDefaultName
);
4138 if (UqiStringLength
> 0) {
4139 StringPrint("\nQ %04X ", UqiStringLength
);
4140 LogUqi(VarDefaultName
);
4142 StringPrint("\n// [No UQI] ");
4146 Status
= FindDefaultName (
4147 &(FormSet
->EnUsStringList
),
4148 FormSet
->UnicodeBinary
,
4153 assert (!EFI_ERROR (Status
));
4154 UqiStringLength
= GetUqiNum (VarDefaultName
);
4157 if (UqiStringLength
> 0) {
4158 StringPrint("\nQ %04X ", UqiStringLength
);
4159 LogUqi(VarDefaultName
);
4161 StringPrint("\n// [No UQI] ");
4166 //Record the UQi to the Question
4168 Question
->Uqi
.HexNum
= UqiStringLength
;
4169 Question
->Uqi
.Data
= VarDefaultName
;
4170 Question
->Uqi
.Type
= ONE_OF
;
4173 StringPrint("ONE_OF ");
4179 StringPrint(" // ");
4180 Status
= FindDefaultName (
4181 &(FormSet
->EnUsStringList
),
4182 FormSet
->UnicodeBinary
,
4187 assert (!EFI_ERROR (Status
));
4188 LogUnicodeString (VarDefaultName
);
4191 // Print ONE_OF_OPTION
4193 PrintOneOfOptions (FormSet
, Question
);
4197 case EFI_IFR_CHECKBOX_OP
:
4199 if( HaveUQIlanguage
) {
4200 Status
= FindDefaultName (
4201 &(FormSet
->UqiStringList
),
4202 FormSet
->UnicodeBinary
,
4207 assert (!EFI_ERROR (Status
));
4209 UqiStringLength
= GetUqiNum (VarDefaultName
);
4211 if (UqiStringLength
> 0) {
4212 StringPrint("\nQ %04X ", UqiStringLength
);
4213 LogUqi(VarDefaultName
);
4215 StringPrint("\n// [No UQI] ");
4219 Status
= FindDefaultName (
4220 &(FormSet
->EnUsStringList
),
4221 FormSet
->UnicodeBinary
,
4226 assert (!EFI_ERROR (Status
));
4228 UqiStringLength
= GetUqiNum (VarDefaultName
);
4231 if (UqiStringLength
> 0) {
4232 StringPrint("\nQ %04X ", UqiStringLength
);
4233 LogUqi(VarDefaultName
);
4235 StringPrint("\n// [No UQI] ");
4240 //Record the UQi to the HiiObjList
4242 Question
->Uqi
.HexNum
= UqiStringLength
;
4243 Question
->Uqi
.Data
= VarDefaultName
;
4244 Question
->Uqi
.Type
= CHECKBOX
;
4246 StringPrint("CHECKBOX ");
4251 StringPrint(" // ");
4252 Status
= FindDefaultName (
4253 &(FormSet
->EnUsStringList
),
4254 FormSet
->UnicodeBinary
,
4259 assert (!EFI_ERROR (Status
));
4260 LogUnicodeString (VarDefaultName
);
4262 StringPrint("// 0 = Unchecked\n");
4263 StringPrint("// 1 = Checked\n");
4267 case EFI_IFR_STRING_OP
:
4268 if( HaveUQIlanguage
) {
4269 Status
= FindDefaultName (
4270 &(FormSet
->UqiStringList
),
4271 FormSet
->UnicodeBinary
,
4276 assert (!EFI_ERROR (Status
));
4278 UqiStringLength
= GetUqiNum (VarDefaultName
);
4280 if (UqiStringLength
> 0) {
4281 StringPrint("\nQ %04X ", UqiStringLength
);
4282 LogUqi(VarDefaultName
);
4284 StringPrint("\n// [No UQI] ");
4288 Status
= FindDefaultName (
4289 &(FormSet
->EnUsStringList
),
4290 FormSet
->UnicodeBinary
,
4295 assert (!EFI_ERROR (Status
));
4297 UqiStringLength
= GetUqiNum (VarDefaultName
);
4300 if (UqiStringLength
> 0) {
4301 StringPrint("\nQ %04X ", UqiStringLength
);
4302 LogUqi(VarDefaultName
);
4304 StringPrint("\n// [No UQI] ");
4309 //Record the UQi to the HiiObjList
4311 Question
->Uqi
.HexNum
= UqiStringLength
;
4312 Question
->Uqi
.Data
= VarDefaultName
;
4313 Question
->Uqi
.Type
= STRING
;
4315 StringPrint("STRING ");
4320 StringPrint(" // ");
4321 Status
= FindDefaultName (
4322 &(FormSet
->EnUsStringList
),
4323 FormSet
->UnicodeBinary
,
4328 assert (!EFI_ERROR (Status
));
4329 LogUnicodeString (VarDefaultName
);
4334 case EFI_IFR_NUMERIC_OP
:
4336 if( HaveUQIlanguage
) {
4337 Status
= FindDefaultName (
4338 &(FormSet
->UqiStringList
),
4339 FormSet
->UnicodeBinary
,
4344 assert (!EFI_ERROR (Status
));
4346 UqiStringLength
= GetUqiNum (VarDefaultName
);
4348 if (UqiStringLength
> 0) {
4349 StringPrint("\nQ %04X ", UqiStringLength
);
4350 LogUqi(VarDefaultName
);
4352 StringPrint("\n// [No UQI] ");
4356 Status
= FindDefaultName (
4357 &(FormSet
->EnUsStringList
),
4358 FormSet
->UnicodeBinary
,
4363 assert (!EFI_ERROR (Status
));
4365 UqiStringLength
= GetUqiNum (VarDefaultName
);
4367 if (UqiStringLength
> 0) {
4368 StringPrint("\nQ %04X ", UqiStringLength
);
4369 LogUqi(VarDefaultName
);
4371 StringPrint("\n// [No UQI] ");
4376 //Record the UQi to the HiiObjList
4378 Question
->Uqi
.HexNum
= UqiStringLength
;
4379 Question
->Uqi
.Data
= VarDefaultName
;
4380 Question
->Uqi
.Type
= NUMERIC
;
4382 StringPrint("NUMERIC ");
4387 StringPrint(" // ");
4388 Status
= FindDefaultName (
4389 &(FormSet
->EnUsStringList
),
4390 FormSet
->UnicodeBinary
,
4395 assert (!EFI_ERROR (Status
));
4396 LogUnicodeString (VarDefaultName
);
4399 if (Question
->QuestionReferToBitField
) {
4400 StringPrint("// Minimum = %08llX \n", Question
->Minimum
);
4401 StringPrint("// Maximum = %08llX \n", Question
->Maximum
);
4402 StringPrint("// Step = %08llX \n", Question
->Step
);
4404 switch (Question
->StorageWidth
) {
4406 case sizeof (UINT8
):
4407 StringPrint("// Minimum = %02llX \n", Question
->Minimum
);
4408 StringPrint("// Maximum = %02llX \n", Question
->Maximum
);
4409 StringPrint("// Step = %02llX \n", Question
->Step
);
4412 case sizeof (UINT16
):
4413 StringPrint("// Minimum = %04llX \n", Question
->Minimum
);
4414 StringPrint("// Maximum = %04llX \n", Question
->Maximum
);
4415 StringPrint("// Step = %04llX \n", Question
->Step
);
4418 case sizeof (UINT32
):
4419 StringPrint("// Minimum = %08llX \n", Question
->Minimum
);
4420 StringPrint("// Maximum = %08llX \n", Question
->Maximum
);
4421 StringPrint("// Step = %08llX \n", Question
->Step
);
4424 case sizeof (UINT64
):
4425 StringPrint("// Minimum = %016llX \n", Question
->Minimum
);
4426 StringPrint("// Maximum = %016llX \n", Question
->Maximum
);
4427 StringPrint("// Step = %016llX \n", Question
->Step
);
4431 StringPrint("0000 // Width > 16 is not supported -- FAILURE");
4438 case EFI_IFR_ORDERED_LIST_OP
:
4440 if( HaveUQIlanguage
) {
4441 Status
= FindDefaultName (
4442 &(FormSet
->UqiStringList
),
4443 FormSet
->UnicodeBinary
,
4448 assert (!EFI_ERROR (Status
));
4449 UqiStringLength
= GetUqiNum (VarDefaultName
);
4452 if (UqiStringLength
> 0) {
4453 StringPrint("\nQ %04X ", UqiStringLength
);
4454 LogUqi(VarDefaultName
);
4456 StringPrint("\n// [No UQI] ");
4460 Status
= FindDefaultName (
4461 &(FormSet
->EnUsStringList
),
4462 FormSet
->UnicodeBinary
,
4468 assert (!EFI_ERROR (Status
));
4470 UqiStringLength
= GetUqiNum (VarDefaultName
);
4472 if (UqiStringLength
> 0) {
4473 StringPrint("\nQ %04X ", UqiStringLength
);
4474 LogUqi(VarDefaultName
);
4476 StringPrint("\n// [No UQI] ");
4481 //Record the UQi to the HiiObjList
4483 Question
->Uqi
.HexNum
= UqiStringLength
;
4484 Question
->Uqi
.Data
= VarDefaultName
;
4485 Question
->Uqi
.Type
= ORDERED_LIST
;
4488 StringPrint("ORDERED_LIST %04X ", Question
->MaxContainers
);
4494 StringPrint(" // ");
4495 Status
= FindDefaultName (
4496 &(FormSet
->EnUsStringList
),
4497 FormSet
->UnicodeBinary
,
4502 assert (!EFI_ERROR (Status
));
4503 LogUnicodeString (VarDefaultName
);
4507 // Print ONE_OF_OPTION
4509 PrintOneOfOptions (FormSet
, Question
);
4516 if (&(FormSet
->EnUsStringList
) == NULL
&&VarDefaultName
!= NULL
&& Question
->Prompt
!= 0) {
4517 free (VarDefaultName
);
4518 VarDefaultName
= NULL
;
4521 if (PrintOrNot
&& Question
->Storage
) {
4522 StringPrint("// size = 0x%x", Question
->StorageWidth
);
4523 StringPrint("\n// offset = 0x%x", Question
->VarStoreInfo
.VarOffset
);
4524 StringPrint("\n// name = ");
4525 LogUnicodeString(Question
->VariableName
);
4526 StringPrint("\n// guid = ");
4529 Question
->Guid
.Data1
, Question
->Guid
.Data2
,
4530 Question
->Guid
.Data3
, Question
->Guid
.Data4
[0],
4531 Question
->Guid
.Data4
[1],Question
->Guid
.Data4
[2],
4532 Question
->Guid
.Data4
[3],Question
->Guid
.Data4
[4],
4533 Question
->Guid
.Data4
[5],Question
->Guid
.Data4
[6],
4534 Question
->Guid
.Data4
[7]
4536 StringPrint("\n// attribute = 0x%x", Question
->Attributes
);
4537 StringPrint("\n// help = ");
4538 Status
= FindDefaultName (
4539 &(FormSet
->EnUsStringList
),
4540 FormSet
->UnicodeBinary
,
4545 assert (!EFI_ERROR (Status
));
4546 LogUnicodeString (VarDefaultName
);
4548 if (&(FormSet
->EnUsStringList
) == NULL
&&VarDefaultName
!= NULL
&& Question
->Help
!= 0) {
4549 free (VarDefaultName
);
4550 VarDefaultName
= NULL
;
4557 Check whether current Formset or Form is NULL. If no valid questions, return FASLE.
4559 @param FormSet The pointer to the formset.
4560 @param FormSet The pointer to the form.
4561 @param IsFormSet FormSet or Form.
4567 CheckFormSetOrFormNull (
4568 IN FORM_BROWSER_FORMSET
*FormSet
,
4569 IN FORM_BROWSER_FORM
*Form
,
4570 IN BOOLEAN IsFormSet
4573 LIST_ENTRY
*FormLink
;
4574 FORM_BROWSER_STATEMENT
*Question
;
4575 LIST_ENTRY
*QuestionLink
;
4579 QuestionLink
= NULL
;
4582 // Parse all forms in formset
4585 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
4587 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
4588 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
4590 // Parse five kinds of Questions in Form
4592 QuestionLink
= GetFirstNode (&Form
->StatementListHead
);
4594 while (!IsNull (&Form
->StatementListHead
, QuestionLink
)) {
4595 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink
);
4597 // Parse five kinds of Questions in Form
4599 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
)
4600 || (Question
->Operand
== EFI_IFR_NUMERIC_OP
)
4601 || (Question
->Operand
== EFI_IFR_CHECKBOX_OP
)
4602 || (Question
->Operand
== EFI_IFR_ORDERED_LIST_OP
)
4603 || (Question
->Operand
== EFI_IFR_STRING_OP
)
4605 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
4607 // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode
4609 if (Question
->Type
!= EFI_IFR_VARSTORE_EFI_OP
) {
4610 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4613 if (Question
->Type
== EFI_IFR_VARSTORE_EFI_OP
4614 && Question
->NewEfiVarstore
4615 && ((Question
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)) {
4616 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4621 //If invalid variable type, skip it.
4623 if ((Question
->Type
!= EFI_IFR_VARSTORE_EFI_OP
)
4624 && (Question
->Type
!= EFI_IFR_VARSTORE_OP
)) {
4625 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4630 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4633 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
4637 // Parse five kinds of Questions in Form
4639 QuestionLink
= GetFirstNode (&Form
->StatementListHead
);
4641 while (!IsNull (&Form
->StatementListHead
, QuestionLink
)) {
4642 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink
);
4644 // Parse five kinds of Questions in Form
4646 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
)
4647 || (Question
->Operand
== EFI_IFR_NUMERIC_OP
)
4648 || (Question
->Operand
== EFI_IFR_CHECKBOX_OP
)
4649 || (Question
->Operand
== EFI_IFR_ORDERED_LIST_OP
)
4650 || (Question
->Operand
== EFI_IFR_STRING_OP
)
4652 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
4654 // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode
4656 if (Question
->Type
!= EFI_IFR_VARSTORE_EFI_OP
) {
4657 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4660 if ((Question
->Type
== EFI_IFR_VARSTORE_EFI_OP
)
4661 && Question
->NewEfiVarstore
4662 && ((Question
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)) {
4663 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4668 //If invalid variable type, skip it.
4670 if ((Question
->Type
!= EFI_IFR_VARSTORE_EFI_OP
)
4671 && (Question
->Type
!= EFI_IFR_VARSTORE_OP
)) {
4672 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4677 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4684 Print all ONE_OF ORDER_LIST NUMERIC STRING and CHECKBOX in all fromsets.
4686 @param Formset The pointer to the entry of the fromset list
4687 @param Formset The pointer to the entry of the storage list
4689 @retval EFI_SUCCESS It was complete successfully
4690 @return EFI_ABORTED An error occurred
4693 PrintInfoInAllFormset (
4694 IN LIST_ENTRY
*FormSetEntryListHead
,
4695 IN LIST_ENTRY
*StorageEntryListHead
4699 FORM_BROWSER_FORMSET
*FormSet
;
4700 LIST_ENTRY
*FormSetLink
;
4701 LIST_ENTRY
*FormLink
;
4702 FORM_BROWSER_FORM
*Form
;
4703 FORM_BROWSER_STATEMENT
*Question
;
4704 LIST_ENTRY
*QuestionLink
;
4705 FORMSET_STORAGE
*Storage
;
4707 LIST_ENTRY
*TempStorageLink
;
4710 BOOLEAN ConstantFlag
;
4712 Status
= EFI_SUCCESS
;
4718 QuestionLink
= NULL
;
4721 TempStorageLink
= NULL
;
4724 ConstantFlag
= TRUE
;
4726 // Print platformId, defaultId and platformIdUqi
4728 if (mMultiPlatformParam
.MultiPlatformOrNot
) {
4729 StringPrint("\n\n// FCEKEY DEFAULT_ID:");
4730 TempStorageLink
= GetFirstNode (StorageEntryListHead
);
4731 Storage
= FORMSET_STORAGE_FROM_LINK (TempStorageLink
);
4732 for (Index
= 0; Index
<= Storage
->DefaultPlatformIdNum
; Index
++) {
4733 StringPrint (" %4d", Storage
->DefaultId
[Index
]);
4735 StringPrint("\n\n//FCEKEY PLATFORM_ID:");
4736 for (Index
= 0; Index
<= Storage
->DefaultPlatformIdNum
; Index
++) {
4737 StringPrint (" %4lld", Storage
->PlatformId
[Index
]);
4739 if (mMultiPlatformParam
.Uqi
.Data
!= NULL
) {
4740 StringPrint("\n\n//FCEKEY PLATFORM_UQI:");
4741 StringPrint(" %04X ", mMultiPlatformParam
.Uqi
.HexNum
);
4742 LogUqi(mMultiPlatformParam
.Uqi
.Data
);
4745 FormSetLink
= GetFirstNode (FormSetEntryListHead
);
4746 while (!IsNull (FormSetEntryListHead
, FormSetLink
)) {
4747 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink
);
4749 //Assign the new storage list
4751 FormSet
->StorageListHead
= StorageEntryListHead
;
4753 if (CheckFormSetOrFormNull (FormSet
, NULL
, TRUE
)) {
4754 StringPrintormSetTitle (FormSet
);
4756 FormSetLink
= GetNextNode (FormSetEntryListHead
, FormSetLink
);
4760 // Parse all forms in formset
4762 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
4764 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
4765 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
4767 if (CheckFormSetOrFormNull (NULL
, Form
, FALSE
)) {
4768 StringPrintormTitle(FormSet
,Form
);
4770 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
4774 // Parse five kinds of Questions in Form
4776 QuestionLink
= GetFirstNode (&Form
->StatementListHead
);
4778 while (!IsNull (&Form
->StatementListHead
, QuestionLink
)) {
4779 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink
);
4781 // Parse five kinds of Questions in Form
4783 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
)
4784 || (Question
->Operand
== EFI_IFR_NUMERIC_OP
)
4785 || (Question
->Operand
== EFI_IFR_CHECKBOX_OP
)
4786 || (Question
->Operand
== EFI_IFR_ORDERED_LIST_OP
)
4787 || (Question
->Operand
== EFI_IFR_SUBTITLE_OP
)
4788 || (Question
->Operand
== EFI_IFR_STRING_OP
)
4793 //Only output the questions stored by EFI_IFR_VARSTORE_EFI_OP.
4795 if (mMultiPlatformParam
.MultiPlatformOrNot
4796 && (Question
->Operand
!= EFI_IFR_SUBTITLE_OP
)
4798 Status
= SearchVarStorage (
4801 Question
->VarStoreInfo
.VarOffset
,
4802 StorageEntryListHead
,
4803 (CHAR8
**)&VarBuffer
,
4807 if (EFI_ERROR (Status
)) {
4812 // If Question is constant expression and "disabledIf True", don't output it.
4814 ConstantFlag
= TRUE
;
4815 if (!Skip
&& (Question
->DisableExpression
!= NULL
)) {
4816 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
, &ConstantFlag
);
4817 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
&& ConstantFlag
) {
4823 PrintQuestion(FormSet
, Form
, Question
, TRUE
);
4826 QuestionLink
= GetNextNode (&Form
->StatementListHead
, QuestionLink
);
4829 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
4831 FormSetLink
= GetNextNode (FormSetEntryListHead
, FormSetLink
);