2 Var Check Hii bin generation.
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "VarCheckHiiGen.h"
11 LIST_ENTRY mVarCheckHiiList
= INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList
);
13 #define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V')
18 VAR_CHECK_HII_VARIABLE_HEADER
*HiiVariable
;
19 EFI_VARSTORE_ID VarStoreId
;
21 VAR_CHECK_HII_QUESTION_HEADER
**HiiQuestionArray
;
22 } VAR_CHECK_HII_VARIABLE_NODE
;
24 #define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE)
26 CHAR16
*mVarName
= NULL
;
27 UINTN mMaxVarNameSize
= 0;
30 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mIfrOpCodeStringTable
[] = {
31 {EFI_IFR_VARSTORE_OP
, "EFI_IFR_VARSTORE_OP"},
32 {EFI_IFR_VARSTORE_EFI_OP
, "EFI_IFR_VARSTORE_EFI_OP"},
33 {EFI_IFR_ONE_OF_OP
, "EFI_IFR_ONE_OF_OP"},
34 {EFI_IFR_CHECKBOX_OP
, "EFI_IFR_CHECKBOX_OP"},
35 {EFI_IFR_NUMERIC_OP
, "EFI_IFR_NUMERIC_OP"},
36 {EFI_IFR_ORDERED_LIST_OP
, "EFI_IFR_ORDERED_LIST_OP"},
37 {EFI_IFR_ONE_OF_OPTION_OP
, "EFI_IFR_ONE_OF_OPTION_OP"},
43 @param[in] IfrOpCode Ifr OpCode.
45 @return Pointer to string.
54 for (Index
= 0; Index
< ARRAY_SIZE (mIfrOpCodeStringTable
); Index
++) {
55 if (mIfrOpCodeStringTable
[Index
].HiiOpCode
== IfrOpCode
) {
56 return mIfrOpCodeStringTable
[Index
].HiiOpCodeStr
;
60 return "<UnknownIfrOpCode>";
63 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_PACKAGE_TYPE_STRING mPackageTypeStringTable
[] = {
64 {EFI_HII_PACKAGE_TYPE_ALL
, "EFI_HII_PACKAGE_TYPE_ALL"},
65 {EFI_HII_PACKAGE_TYPE_GUID
, "EFI_HII_PACKAGE_TYPE_GUID"},
66 {EFI_HII_PACKAGE_FORMS
, "EFI_HII_PACKAGE_FORMS"},
67 {EFI_HII_PACKAGE_STRINGS
, "EFI_HII_PACKAGE_STRINGS"},
68 {EFI_HII_PACKAGE_FONTS
, "EFI_HII_PACKAGE_FONTS"},
69 {EFI_HII_PACKAGE_IMAGES
, "EFI_HII_PACKAGE_IMAGES"},
70 {EFI_HII_PACKAGE_SIMPLE_FONTS
, "EFI_HII_PACKAGE_SIMPLE_FONTS"},
71 {EFI_HII_PACKAGE_DEVICE_PATH
, "EFI_HII_PACKAGE_DEVICE_PATH"},
72 {EFI_HII_PACKAGE_KEYBOARD_LAYOUT
, "EFI_HII_PACKAGE_KEYBOARD_LAYOUT"},
73 {EFI_HII_PACKAGE_ANIMATIONS
, "EFI_HII_PACKAGE_ANIMATIONS"},
74 {EFI_HII_PACKAGE_END
, "EFI_HII_PACKAGE_END"},
75 {EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN
, "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN"},
76 {EFI_HII_PACKAGE_TYPE_SYSTEM_END
, "EFI_HII_PACKAGE_TYPE_SYSTEM_END"},
80 Hii Package type to string.
82 @param[in] PackageType Package Type
84 @return Pointer to string.
93 for (Index
= 0; Index
< ARRAY_SIZE (mPackageTypeStringTable
); Index
++) {
94 if (mPackageTypeStringTable
[Index
].PackageType
== PackageType
) {
95 return mPackageTypeStringTable
[Index
].PackageTypeStr
;
99 return "<UnknownPackageType>";
105 @param[in] HiiPackage Pointer to Hii Package.
113 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
114 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
115 EFI_IFR_VARSTORE
*IfrVarStore
;
116 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
117 BOOLEAN QuestionStoredInBitField
;
119 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) HiiPackage
;
120 QuestionStoredInBitField
= FALSE
;
122 DEBUG ((DEBUG_INFO
, " HiiPackageHeader->Type - 0x%02x (%a)\n", HiiPackageHeader
->Type
, HiiPackageTypeToStr ((UINT8
) HiiPackageHeader
->Type
)));
123 DEBUG ((DEBUG_INFO
, " HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader
->Length
));
125 switch (HiiPackageHeader
->Type
) {
126 case EFI_HII_PACKAGE_FORMS
:
127 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) (HiiPackageHeader
+ 1);
129 while ((UINTN
) IfrOpCodeHeader
< ((UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
)) {
130 switch (IfrOpCodeHeader
->OpCode
) {
131 case EFI_IFR_VARSTORE_OP
:
132 IfrVarStore
= (EFI_IFR_VARSTORE
*) IfrOpCodeHeader
;
133 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
134 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
135 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
136 DEBUG ((DEBUG_INFO
, " Guid - %g\n", &IfrVarStore
->Guid
));
137 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", IfrVarStore
->VarStoreId
));
138 DEBUG ((DEBUG_INFO
, " Size - 0x%04x\n", IfrVarStore
->Size
));
139 DEBUG ((DEBUG_INFO
, " Name - %a\n", IfrVarStore
->Name
));
142 case EFI_IFR_VARSTORE_EFI_OP
:
143 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*) IfrOpCodeHeader
;
144 if (IfrEfiVarStore
->Header
.Length
>= sizeof (EFI_IFR_VARSTORE_EFI
)) {
145 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
146 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
147 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
148 DEBUG ((DEBUG_INFO
, " Guid - %g\n", &IfrEfiVarStore
->Guid
));
149 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", IfrEfiVarStore
->VarStoreId
));
150 DEBUG ((DEBUG_INFO
, " Size - 0x%04x\n", IfrEfiVarStore
->Size
));
151 DEBUG ((DEBUG_INFO
, " Attributes - 0x%08x\n", IfrEfiVarStore
->Attributes
));
152 DEBUG ((DEBUG_INFO
, " Name - %a\n", IfrEfiVarStore
->Name
));
156 case EFI_IFR_GUID_OP
:
157 if (CompareGuid ((EFI_GUID
*)((UINTN
)IfrOpCodeHeader
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
158 QuestionStoredInBitField
= TRUE
;
162 case EFI_IFR_ONE_OF_OP
:
163 case EFI_IFR_CHECKBOX_OP
:
164 case EFI_IFR_NUMERIC_OP
:
165 case EFI_IFR_ORDERED_LIST_OP
:
166 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
), (QuestionStoredInBitField
? "bit level": "byte level")));
167 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
168 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
169 DEBUG ((DEBUG_INFO
, " Prompt - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Prompt
));
170 DEBUG ((DEBUG_INFO
, " Help - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Help
));
171 DEBUG ((DEBUG_INFO
, " QuestionId - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.QuestionId
));
172 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.VarStoreId
));
173 DEBUG ((DEBUG_INFO
, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF
* )IfrOpCodeHeader
)->Question
.VarStoreInfo
.VarOffset
, (QuestionStoredInBitField
? "bit level": "byte level")));
175 EFI_IFR_ONE_OF
*IfrOneOf
;
176 EFI_IFR_CHECKBOX
*IfrCheckBox
;
177 EFI_IFR_NUMERIC
*IfrNumeric
;
178 EFI_IFR_ORDERED_LIST
*IfrOrderedList
;
180 switch (IfrOpCodeHeader
->OpCode
) {
181 case EFI_IFR_ONE_OF_OP
:
182 IfrOneOf
= (EFI_IFR_ONE_OF
*) IfrOpCodeHeader
;
183 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrOneOf
->Flags
));
184 if (QuestionStoredInBitField
) {
186 // For OneOf stored in bit field, the option value are saved as UINT32 type.
188 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrOneOf
->data
.u32
.MinValue
));
189 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrOneOf
->data
.u32
.MaxValue
));
190 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrOneOf
->data
.u32
.Step
));
192 switch (IfrOneOf
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
193 case EFI_IFR_NUMERIC_SIZE_1
:
194 DEBUG ((DEBUG_INFO
, " MinValue - 0x%02x\n", IfrOneOf
->data
.u8
.MinValue
));
195 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%02x\n", IfrOneOf
->data
.u8
.MaxValue
));
196 DEBUG ((DEBUG_INFO
, " Step - 0x%02x\n", IfrOneOf
->data
.u8
.Step
));
198 case EFI_IFR_NUMERIC_SIZE_2
:
199 DEBUG ((DEBUG_INFO
, " MinValue - 0x%04x\n", IfrOneOf
->data
.u16
.MinValue
));
200 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%04x\n", IfrOneOf
->data
.u16
.MaxValue
));
201 DEBUG ((DEBUG_INFO
, " Step - 0x%04x\n", IfrOneOf
->data
.u16
.Step
));
203 case EFI_IFR_NUMERIC_SIZE_4
:
204 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrOneOf
->data
.u32
.MinValue
));
205 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrOneOf
->data
.u32
.MaxValue
));
206 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrOneOf
->data
.u32
.Step
));
208 case EFI_IFR_NUMERIC_SIZE_8
:
209 DEBUG ((DEBUG_INFO
, " MinValue - 0x%016lx\n", IfrOneOf
->data
.u64
.MinValue
));
210 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%016lx\n", IfrOneOf
->data
.u64
.MaxValue
));
211 DEBUG ((DEBUG_INFO
, " Step - 0x%016lx\n", IfrOneOf
->data
.u64
.Step
));
216 case EFI_IFR_CHECKBOX_OP
:
217 IfrCheckBox
= (EFI_IFR_CHECKBOX
*) IfrOpCodeHeader
;
218 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrCheckBox
->Flags
));
220 case EFI_IFR_NUMERIC_OP
:
221 IfrNumeric
= (EFI_IFR_NUMERIC
*) IfrOpCodeHeader
;
222 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrNumeric
->Flags
));
223 if (QuestionStoredInBitField
) {
225 // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type.
227 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrNumeric
->data
.u32
.MinValue
));
228 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrNumeric
->data
.u32
.MaxValue
));
229 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrNumeric
->data
.u32
.Step
));
231 switch (IfrNumeric
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
232 case EFI_IFR_NUMERIC_SIZE_1
:
233 DEBUG ((DEBUG_INFO
, " MinValue - 0x%02x\n", IfrNumeric
->data
.u8
.MinValue
));
234 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%02x\n", IfrNumeric
->data
.u8
.MaxValue
));
235 DEBUG ((DEBUG_INFO
, " Step - 0x%02x\n", IfrNumeric
->data
.u8
.Step
));
237 case EFI_IFR_NUMERIC_SIZE_2
:
238 DEBUG ((DEBUG_INFO
, " MinValue - 0x%04x\n", IfrNumeric
->data
.u16
.MinValue
));
239 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%04x\n", IfrNumeric
->data
.u16
.MaxValue
));
240 DEBUG ((DEBUG_INFO
, " Step - 0x%04x\n", IfrNumeric
->data
.u16
.Step
));
242 case EFI_IFR_NUMERIC_SIZE_4
:
243 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrNumeric
->data
.u32
.MinValue
));
244 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrNumeric
->data
.u32
.MaxValue
));
245 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrNumeric
->data
.u32
.Step
));
247 case EFI_IFR_NUMERIC_SIZE_8
:
248 DEBUG ((DEBUG_INFO
, " MinValue - 0x%016lx\n", IfrNumeric
->data
.u64
.MinValue
));
249 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%016lx\n", IfrNumeric
->data
.u64
.MaxValue
));
250 DEBUG ((DEBUG_INFO
, " Step - 0x%016lx\n", IfrNumeric
->data
.u64
.Step
));
255 case EFI_IFR_ORDERED_LIST_OP
:
256 IfrOrderedList
= (EFI_IFR_ORDERED_LIST
*) IfrOpCodeHeader
;
257 DEBUG ((DEBUG_INFO
, " MaxContainers - 0x%02x\n", IfrOrderedList
->MaxContainers
));
258 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrOrderedList
->Flags
));
264 if (IfrOpCodeHeader
->Scope
!= 0) {
266 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
268 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
271 switch (IfrOpCodeHeader
->OpCode
) {
272 case EFI_IFR_ONE_OF_OPTION_OP
:
273 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*)IfrOpCodeHeader
;
274 DEBUG ((DEBUG_INFO
, "!!!! IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", (UINTN
)IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
275 DEBUG ((DEBUG_INFO
, "!!!! IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
276 DEBUG ((DEBUG_INFO
, "!!!! Option - 0x%04x\n", IfrOneOfOption
->Option
));
277 DEBUG ((DEBUG_INFO
, "!!!! Flags - 0x%02x\n", IfrOneOfOption
->Flags
));
278 DEBUG ((DEBUG_INFO
, "!!!! Type - 0x%02x\n", IfrOneOfOption
->Type
));
279 switch (IfrOneOfOption
->Type
) {
280 case EFI_IFR_TYPE_NUM_SIZE_8
:
281 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%02x\n", IfrOneOfOption
->Value
.u8
));
283 case EFI_IFR_TYPE_NUM_SIZE_16
:
284 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%04x\n", IfrOneOfOption
->Value
.u16
));
286 case EFI_IFR_TYPE_NUM_SIZE_32
:
287 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%08x\n", IfrOneOfOption
->Value
.u32
));
289 case EFI_IFR_TYPE_NUM_SIZE_64
:
290 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%016lx\n", IfrOneOfOption
->Value
.u64
));
292 case EFI_IFR_TYPE_BOOLEAN
:
293 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%02x\n", IfrOneOfOption
->Value
.b
));
301 if (IfrOpCodeHeader
->OpCode
== EFI_IFR_END_OP
) {
302 QuestionStoredInBitField
= FALSE
;
308 } else if (IfrOpCodeHeader
->Scope
!= 0) {
311 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
318 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
329 @param[in] HiiDatabase Pointer to Hii Database.
330 @param[in] HiiDatabaseSize Hii Database size.
335 IN VOID
*HiiDatabase
,
336 IN UINTN HiiDatabaseSize
339 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageListHeader
;
340 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
342 DEBUG ((DEBUG_INFO
, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize
));
343 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) HiiDatabase
;
345 while ((UINTN
) HiiPackageListHeader
< ((UINTN
) HiiDatabase
+ HiiDatabaseSize
)) {
346 DEBUG ((DEBUG_INFO
, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader
->PackageListGuid
));
347 DEBUG ((DEBUG_INFO
, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN
)HiiPackageListHeader
->PackageLength
));
348 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)(HiiPackageListHeader
+ 1);
350 while ((UINTN
) HiiPackageHeader
< (UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
) {
352 DumpHiiPackage (HiiPackageHeader
);
354 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) ((UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
);
357 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) ((UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
);
365 Allocates a buffer of a certain pool type.
367 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
368 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
369 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
371 @param MemoryType The type of memory to allocate.
372 @param AllocationSize The number of bytes to allocate.
374 @return A pointer to the allocated buffer or NULL if allocation fails.
378 InternalVarCheckAllocatePool (
379 IN EFI_MEMORY_TYPE MemoryType
,
380 IN UINTN AllocationSize
386 Status
= gBS
->AllocatePool (MemoryType
, AllocationSize
, &Memory
);
387 if (EFI_ERROR (Status
)) {
394 Allocates and zeros a buffer of type EfiBootServicesData.
396 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
397 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
398 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
399 request, then NULL is returned.
401 @param AllocationSize The number of bytes to allocate and zero.
403 @return A pointer to the allocated buffer or NULL if allocation fails.
407 InternalVarCheckAllocateZeroPool (
408 IN UINTN AllocationSize
413 Memory
= InternalVarCheckAllocatePool (EfiBootServicesData
, AllocationSize
);
414 if (Memory
!= NULL
) {
415 Memory
= ZeroMem (Memory
, AllocationSize
);
421 Frees a buffer that was previously allocated with one of the pool allocation functions in the
422 Memory Allocation Library.
424 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
425 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
426 resources, then this function will perform no actions.
428 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
431 @param Buffer The pointer to the buffer to free.
436 InternalVarCheckFreePool (
442 Status
= gBS
->FreePool (Buffer
);
443 ASSERT_EFI_ERROR (Status
);
447 Reallocates a buffer of type EfiBootServicesData.
449 Allocates and zeros the number bytes specified by NewSize from memory of type
450 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
451 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
452 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
453 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
454 enough memory remaining to satisfy the request, then NULL is returned.
456 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
457 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
459 @param OldSize The size, in bytes, of OldBuffer.
460 @param NewSize The size, in bytes, of the buffer to reallocate.
461 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
462 parameter that may be NULL.
464 @return A pointer to the allocated buffer or NULL if allocation fails.
468 InternalVarCheckReallocatePool (
471 IN VOID
*OldBuffer OPTIONAL
476 NewBuffer
= InternalVarCheckAllocateZeroPool (NewSize
);
477 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
478 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
479 InternalVarCheckFreePool (OldBuffer
);
487 @param[in, out] HiiVariableNode Pointer to Hii Variable node.
488 @param[in] HiiQuestion Pointer to Hii Question.
489 @param[in] FromFv Hii Question from FV.
494 IN OUT VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
,
495 IN VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion
,
499 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion1
;
500 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion2
;
501 VAR_CHECK_HII_QUESTION_HEADER
*NewHiiQuestion
;
515 // Hii Question from Hii Database has high priority.
516 // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
519 InternalVarCheckFreePool (HiiQuestion
);
523 if (HiiQuestion
->BitFieldStore
) {
524 ArrayIndex
= HiiQuestion
->VarOffset
;
526 ArrayIndex
= HiiQuestion
->VarOffset
* 8;
529 HiiQuestion1
= HiiVariableNode
->HiiQuestionArray
[ArrayIndex
];
530 HiiQuestion2
= HiiQuestion
;
532 ASSERT ((HiiQuestion1
->OpCode
== HiiQuestion2
->OpCode
) && (HiiQuestion1
->StorageWidth
== HiiQuestion2
->StorageWidth
));
534 switch (HiiQuestion1
->OpCode
) {
535 case EFI_IFR_ONE_OF_OP
:
536 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level": "byte level")));
538 // Get the length of Hii Question 1.
540 NewLength
= HiiQuestion1
->Length
;
543 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
545 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion2
+ 1);
546 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
548 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
550 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion1
+ 1);
551 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
553 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
554 if (OneValue2
== OneValue1
) {
560 Ptr1
+= HiiQuestion1
->StorageWidth
;
562 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
566 NewLength
= (UINT8
) (NewLength
+ HiiQuestion1
->StorageWidth
);
568 Ptr2
+= HiiQuestion2
->StorageWidth
;
571 if (NewLength
> HiiQuestion1
->Length
) {
573 // Merge the one of options of Hii Question 2 and Hii Question 1.
575 NewHiiQuestion
= InternalVarCheckAllocateZeroPool (NewLength
);
576 ASSERT (NewHiiQuestion
!= NULL
);
577 CopyMem (NewHiiQuestion
, HiiQuestion1
, HiiQuestion1
->Length
);
579 // Use the new length.
581 NewHiiQuestion
->Length
= NewLength
;
582 Ptr
= (UINT8
*) NewHiiQuestion
+ HiiQuestion1
->Length
;
584 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion2
+ 1);
585 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
587 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
589 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion1
+ 1);
590 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
592 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
593 if (OneValue2
== OneValue1
) {
599 Ptr1
+= HiiQuestion1
->StorageWidth
;
601 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
605 CopyMem (Ptr
, &OneValue2
, HiiQuestion1
->StorageWidth
);
606 Ptr
+= HiiQuestion1
->StorageWidth
;
608 Ptr2
+= HiiQuestion2
->StorageWidth
;
611 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = NewHiiQuestion
;
612 InternalVarCheckFreePool (HiiQuestion1
);
616 case EFI_IFR_CHECKBOX_OP
:
617 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level": "byte level")));
620 case EFI_IFR_NUMERIC_OP
:
621 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level": "byte level")));
623 // Get minimum and maximum of Hii Question 1.
627 Ptr
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_NUMERIC
*) HiiQuestion1
+ 1);
628 CopyMem (&Minimum1
, Ptr
, HiiQuestion1
->StorageWidth
);
629 Ptr
+= HiiQuestion1
->StorageWidth
;
630 CopyMem (&Maximum1
, Ptr
, HiiQuestion1
->StorageWidth
);
633 // Get minimum and maximum of Hii Question 2.
637 Ptr
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_NUMERIC
*) HiiQuestion2
+ 1);
638 CopyMem (&Minimum2
, Ptr
, HiiQuestion2
->StorageWidth
);
639 Ptr
+= HiiQuestion2
->StorageWidth
;
640 CopyMem (&Maximum2
, Ptr
, HiiQuestion2
->StorageWidth
);
645 Ptr
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_NUMERIC
*) HiiQuestion1
+ 1);
646 if (Minimum2
< Minimum1
) {
648 CopyMem (Ptr
, &Minimum1
, HiiQuestion1
->StorageWidth
);
653 Ptr
+= HiiQuestion1
->StorageWidth
;
654 if (Maximum2
> Maximum1
) {
656 CopyMem (Ptr
, &Maximum1
, HiiQuestion1
->StorageWidth
);
660 case EFI_IFR_ORDERED_LIST_OP
:
661 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1
->VarOffset
));
663 // Get the length of Hii Question 1.
665 NewLength
= HiiQuestion1
->Length
;
668 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
670 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion2
+ 1);
671 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
673 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
675 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion1
+ 1);
676 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
678 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
679 if (OneValue2
== OneValue1
) {
685 Ptr1
+= HiiQuestion1
->StorageWidth
;
687 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
691 NewLength
= (UINT8
) (NewLength
+ HiiQuestion1
->StorageWidth
);
693 Ptr2
+= HiiQuestion2
->StorageWidth
;
696 if (NewLength
> HiiQuestion1
->Length
) {
698 // Merge the one of options of Hii Question 2 and Hii Question 1.
700 NewHiiQuestion
= InternalVarCheckAllocateZeroPool (NewLength
);
701 ASSERT (NewHiiQuestion
!= NULL
);
702 CopyMem (NewHiiQuestion
, HiiQuestion1
, HiiQuestion1
->Length
);
704 // Use the new length.
706 NewHiiQuestion
->Length
= NewLength
;
707 Ptr
= (UINT8
*) NewHiiQuestion
+ HiiQuestion1
->Length
;
709 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion2
+ 1);
710 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
712 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
714 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion1
+ 1);
715 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
717 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
718 if (OneValue2
== OneValue1
) {
724 Ptr1
+= HiiQuestion1
->StorageWidth
;
726 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
730 CopyMem (Ptr
, &OneValue2
, HiiQuestion1
->StorageWidth
);
731 Ptr
+= HiiQuestion1
->StorageWidth
;
733 Ptr2
+= HiiQuestion2
->StorageWidth
;
736 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = NewHiiQuestion
;
737 InternalVarCheckFreePool (HiiQuestion1
);
749 // Hii Question 2 has been merged with Hii Question 1.
751 InternalVarCheckFreePool (HiiQuestion2
);
755 Get OneOf option data.
757 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
758 @param[out] Count Pointer to option count.
759 @param[out] Width Pointer to option width.
760 @param[out] OptionBuffer Pointer to option buffer.
765 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
768 OUT VOID
*OptionBuffer OPTIONAL
772 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
775 // Assume all OPTION has same Width.
779 if (IfrOpCodeHeader
->Scope
!= 0) {
784 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
786 switch (IfrOpCodeHeader
->OpCode
) {
787 case EFI_IFR_ONE_OF_OPTION_OP
:
788 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*) IfrOpCodeHeader
;
789 switch (IfrOneOfOption
->Type
) {
790 case EFI_IFR_TYPE_NUM_SIZE_8
:
792 *Width
= sizeof (UINT8
);
793 if (OptionBuffer
!= NULL
) {
794 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u8
, sizeof (UINT8
));
795 OptionBuffer
= (UINT8
*) OptionBuffer
+ 1;
798 case EFI_IFR_TYPE_NUM_SIZE_16
:
800 *Width
= sizeof (UINT16
);
801 if (OptionBuffer
!= NULL
) {
802 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u16
, sizeof (UINT16
));
803 OptionBuffer
= (UINT16
*) OptionBuffer
+ 1;
806 case EFI_IFR_TYPE_NUM_SIZE_32
:
808 *Width
= sizeof (UINT32
);
809 if (OptionBuffer
!= NULL
) {
810 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u32
, sizeof (UINT32
));
811 OptionBuffer
= (UINT32
*) OptionBuffer
+ 1;
814 case EFI_IFR_TYPE_NUM_SIZE_64
:
816 *Width
= sizeof (UINT64
);
817 if (OptionBuffer
!= NULL
) {
818 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u64
, sizeof (UINT64
));
819 OptionBuffer
= (UINT64
*) OptionBuffer
+ 1;
822 case EFI_IFR_TYPE_BOOLEAN
:
824 *Width
= sizeof (BOOLEAN
);
825 if (OptionBuffer
!= NULL
) {
826 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.b
, sizeof (BOOLEAN
));
827 OptionBuffer
= (BOOLEAN
*) OptionBuffer
+ 1;
839 if (IfrOpCodeHeader
->OpCode
== EFI_IFR_END_OP
) {
845 } else if (IfrOpCodeHeader
->Scope
!= 0) {
851 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
859 Parse Hii Question Oneof.
861 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
862 @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage.
864 return Pointer to Hii Question.
867 VAR_CHECK_HII_QUESTION_HEADER
*
868 ParseHiiQuestionOneOf (
869 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
870 IN BOOLEAN StoredInBitField
873 EFI_IFR_ONE_OF
*IfrOneOf
;
874 VAR_CHECK_HII_QUESTION_ONEOF
*OneOf
;
881 IfrOneOf
= (EFI_IFR_ONE_OF
*) IfrOpCodeHeader
;
884 if (StoredInBitField
) {
886 // When OneOf stored in bit field, the bit width is saved in the lower six bits of the flag.
887 // And the options in the OneOf is saved as UINT32 type.
889 BitWidth
= IfrOneOf
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
890 Width
= sizeof (UINT32
);
892 Width
= (UINT8
) (1 << (IfrOneOf
->Flags
& EFI_IFR_NUMERIC_SIZE
));
895 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, NULL
);
896 ASSERT (Width
== OptionWidth
);
898 Length
= sizeof (*OneOf
) + OptionCount
* Width
;
900 OneOf
= InternalVarCheckAllocateZeroPool (Length
);
901 ASSERT (OneOf
!= NULL
);
902 OneOf
->OpCode
= EFI_IFR_ONE_OF_OP
;
903 OneOf
->Length
= (UINT8
) Length
;
904 OneOf
->VarOffset
= IfrOneOf
->Question
.VarStoreInfo
.VarOffset
;
905 OneOf
->BitFieldStore
= StoredInBitField
;
906 if (StoredInBitField
) {
907 OneOf
->StorageWidth
= BitWidth
;
909 OneOf
->StorageWidth
= Width
;
912 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, OneOf
+ 1);
914 return (VAR_CHECK_HII_QUESTION_HEADER
*) OneOf
;
918 Parse Hii Question CheckBox.
920 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
921 @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage.
923 return Pointer to Hii Question.
926 VAR_CHECK_HII_QUESTION_HEADER
*
927 ParseHiiQuestionCheckBox (
928 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
929 IN BOOLEAN StoredInBitField
932 EFI_IFR_CHECKBOX
*IfrCheckBox
;
933 VAR_CHECK_HII_QUESTION_CHECKBOX
*CheckBox
;
935 IfrCheckBox
= (EFI_IFR_CHECKBOX
*) IfrOpCodeHeader
;
937 CheckBox
= InternalVarCheckAllocateZeroPool (sizeof (*CheckBox
));
938 ASSERT (CheckBox
!= NULL
);
939 CheckBox
->OpCode
= EFI_IFR_CHECKBOX_OP
;
940 CheckBox
->Length
= (UINT8
) sizeof (*CheckBox
);;
941 CheckBox
->VarOffset
= IfrCheckBox
->Question
.VarStoreInfo
.VarOffset
;
942 CheckBox
->BitFieldStore
= StoredInBitField
;
943 if (StoredInBitField
) {
944 CheckBox
->StorageWidth
= 1;
946 CheckBox
->StorageWidth
= (UINT8
) sizeof (BOOLEAN
);
949 return (VAR_CHECK_HII_QUESTION_HEADER
*) CheckBox
;
953 Parse Hii Question Numeric.
955 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
956 @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage.
958 return Pointer to Hii Question.
961 VAR_CHECK_HII_QUESTION_HEADER
*
962 ParseHiiQuestionNumeric (
963 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
964 IN BOOLEAN StoredInBitField
967 EFI_IFR_NUMERIC
*IfrNumeric
;
968 VAR_CHECK_HII_QUESTION_NUMERIC
*Numeric
;
972 IfrNumeric
= (EFI_IFR_NUMERIC
*) IfrOpCodeHeader
;
975 Numeric
= InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC
) + 2 * sizeof (UINT64
));
976 ASSERT (Numeric
!= NULL
);
978 if (StoredInBitField
) {
980 // When Numeric stored in bit field, the bit field width is saved in the lower six bits of the flag.
981 // And the Minimum Maximum of Numeric is saved as UINT32 type.
983 BitWidth
= IfrNumeric
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
984 Width
= sizeof (UINT32
);
986 Width
= (UINT8
) (1 << (IfrNumeric
->Flags
& EFI_IFR_NUMERIC_SIZE
));
989 Numeric
->OpCode
= EFI_IFR_NUMERIC_OP
;
990 Numeric
->Length
= (UINT8
) (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC
) + 2 * Width
);
991 Numeric
->VarOffset
= IfrNumeric
->Question
.VarStoreInfo
.VarOffset
;
992 Numeric
->BitFieldStore
= StoredInBitField
;
993 if (StoredInBitField
) {
994 Numeric
->StorageWidth
= BitWidth
;
996 Numeric
->StorageWidth
= Width
;
999 CopyMem (Numeric
+ 1, &IfrNumeric
->data
, Width
* 2);
1001 return (VAR_CHECK_HII_QUESTION_HEADER
*) Numeric
;
1005 Parse Hii Question OrderedList.
1007 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1009 return Pointer to Hii Question.
1012 VAR_CHECK_HII_QUESTION_HEADER
*
1013 ParseHiiQuestionOrderedList (
1014 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
1017 EFI_IFR_ORDERED_LIST
*IfrOrderedList
;
1018 VAR_CHECK_HII_QUESTION_ORDEREDLIST
*OrderedList
;
1023 IfrOrderedList
= (EFI_IFR_ORDERED_LIST
*) IfrOpCodeHeader
;
1025 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, NULL
);
1027 Length
= sizeof (*OrderedList
) + OptionCount
* OptionWidth
;
1029 OrderedList
= InternalVarCheckAllocateZeroPool (Length
);
1030 ASSERT (OrderedList
!= NULL
);
1031 OrderedList
->OpCode
= EFI_IFR_ORDERED_LIST_OP
;
1032 OrderedList
->Length
= (UINT8
) Length
;
1033 OrderedList
->VarOffset
= IfrOrderedList
->Question
.VarStoreInfo
.VarOffset
;
1034 OrderedList
->StorageWidth
= OptionWidth
;
1035 OrderedList
->MaxContainers
= IfrOrderedList
->MaxContainers
;
1036 OrderedList
->BitFieldStore
= FALSE
;
1038 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, OrderedList
+ 1);
1040 return (VAR_CHECK_HII_QUESTION_HEADER
*) OrderedList
;
1044 Parse and create Hii Question node.
1046 @param[in] HiiVariableNode Pointer to Hii Variable node.
1047 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1048 @param[in] FromFv Hii Question from FV.
1049 @param[in] StoredInBitField Whether the Question is stored in bit field Storage.
1054 IN VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
,
1055 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
1057 IN BOOLEAN StoredInBitField
1060 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion
;
1064 // Currently only OneOf, CheckBox and Numeric can be stored in bit field.
1066 switch (IfrOpCodeHeader
->OpCode
) {
1067 case EFI_IFR_ONE_OF_OP
:
1068 HiiQuestion
= ParseHiiQuestionOneOf (IfrOpCodeHeader
, StoredInBitField
);
1071 case EFI_IFR_CHECKBOX_OP
:
1072 HiiQuestion
= ParseHiiQuestionCheckBox (IfrOpCodeHeader
, StoredInBitField
);
1075 case EFI_IFR_NUMERIC_OP
:
1076 HiiQuestion
= ParseHiiQuestionNumeric (IfrOpCodeHeader
, StoredInBitField
);
1079 case EFI_IFR_ORDERED_LIST_OP
:
1080 HiiQuestion
= ParseHiiQuestionOrderedList (IfrOpCodeHeader
);
1089 if (StoredInBitField
) {
1090 ArrayIndex
= HiiQuestion
->VarOffset
;
1092 ArrayIndex
= HiiQuestion
->VarOffset
* 8;
1094 if (HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] != NULL
) {
1095 MergeHiiQuestion (HiiVariableNode
, HiiQuestion
, FromFv
);
1097 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = HiiQuestion
;
1102 Find Hii variable node by name and GUID.
1104 @param[in] Name Pointer to variable name.
1105 @param[in] Guid Pointer to vendor GUID.
1107 @return Pointer to Hii Variable node.
1110 VAR_CHECK_HII_VARIABLE_NODE
*
1111 FindHiiVariableNode (
1116 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1119 for (Link
= mVarCheckHiiList
.ForwardLink
1120 ;Link
!= &mVarCheckHiiList
1121 ;Link
= Link
->ForwardLink
) {
1122 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1124 if ((StrCmp (Name
, (CHAR16
*) (HiiVariableNode
->HiiVariable
+ 1)) == 0) &&
1125 CompareGuid (Guid
, &HiiVariableNode
->HiiVariable
->Guid
)) {
1126 return HiiVariableNode
;
1134 Find Hii variable node by var store id.
1136 @param[in] VarStoreId Var store id.
1138 @return Pointer to Hii Variable node.
1141 VAR_CHECK_HII_VARIABLE_NODE
*
1142 FindHiiVariableNodeByVarStoreId (
1143 IN EFI_VARSTORE_ID VarStoreId
1146 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1149 if (VarStoreId
== 0) {
1151 // The variable store identifier, which is unique within the current form set.
1152 // A value of zero is invalid.
1157 for (Link
= mVarCheckHiiList
.ForwardLink
1158 ;Link
!= &mVarCheckHiiList
1159 ;Link
= Link
->ForwardLink
) {
1160 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1162 // The variable store identifier, which is unique within the current form set.
1164 if (VarStoreId
== HiiVariableNode
->VarStoreId
) {
1165 return HiiVariableNode
;
1173 Destroy var store id in the Hii Variable node after parsing one Hii Package.
1181 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1184 for (Link
= mVarCheckHiiList
.ForwardLink
1185 ;Link
!= &mVarCheckHiiList
1186 ;Link
= Link
->ForwardLink
) {
1187 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1189 // The variable store identifier, which is unique within the current form set.
1190 // A value of zero is invalid.
1192 HiiVariableNode
->VarStoreId
= 0;
1197 Create Hii Variable node.
1199 @param[in] IfrEfiVarStore Pointer to EFI VARSTORE.
1203 CreateHiiVariableNode (
1204 IN EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
1207 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1208 VAR_CHECK_HII_VARIABLE_HEADER
*HiiVariable
;
1214 // Get variable name.
1216 VarNameSize
= AsciiStrSize ((CHAR8
*) IfrEfiVarStore
->Name
) * sizeof (CHAR16
);
1217 if (VarNameSize
> mMaxVarNameSize
) {
1218 mVarName
= InternalVarCheckReallocatePool (mMaxVarNameSize
, VarNameSize
, mVarName
);
1219 ASSERT (mVarName
!= NULL
);
1220 mMaxVarNameSize
= VarNameSize
;
1222 AsciiStrToUnicodeStrS ((CHAR8
*) IfrEfiVarStore
->Name
, mVarName
, mMaxVarNameSize
/ sizeof (CHAR16
));
1225 HiiVariableNode
= FindHiiVariableNode (
1227 &IfrEfiVarStore
->Guid
1229 if (HiiVariableNode
== NULL
) {
1231 // Not found, then create new.
1233 HeaderLength
= sizeof (*HiiVariable
) + VarNameSize
;
1234 HiiVariable
= InternalVarCheckAllocateZeroPool (HeaderLength
);
1235 ASSERT (HiiVariable
!= NULL
);
1236 HiiVariable
->Revision
= VAR_CHECK_HII_REVISION
;
1237 HiiVariable
->OpCode
= EFI_IFR_VARSTORE_EFI_OP
;
1238 HiiVariable
->HeaderLength
= (UINT16
) HeaderLength
;
1239 HiiVariable
->Size
= IfrEfiVarStore
->Size
;
1240 HiiVariable
->Attributes
= IfrEfiVarStore
->Attributes
;
1241 CopyGuid (&HiiVariable
->Guid
, &IfrEfiVarStore
->Guid
);
1242 StrCpyS ((CHAR16
*) (HiiVariable
+ 1), VarNameSize
/ sizeof (CHAR16
), VarName
);
1244 HiiVariableNode
= InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode
));
1245 ASSERT (HiiVariableNode
!= NULL
);
1246 HiiVariableNode
->Signature
= VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE
;
1247 HiiVariableNode
->HiiVariable
= HiiVariable
;
1249 // The variable store identifier, which is unique within the current form set.
1251 HiiVariableNode
->VarStoreId
= IfrEfiVarStore
->VarStoreId
;
1252 HiiVariableNode
->HiiQuestionArray
= InternalVarCheckAllocateZeroPool (IfrEfiVarStore
->Size
* 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER
*));
1254 InsertTailList (&mVarCheckHiiList
, &HiiVariableNode
->Link
);
1256 HiiVariableNode
->VarStoreId
= IfrEfiVarStore
->VarStoreId
;
1261 Parse and create Hii Variable node list.
1263 @param[in] HiiPackage Pointer to Hii Package.
1271 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1272 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
1273 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
1275 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) HiiPackage
;
1277 switch (HiiPackageHeader
->Type
) {
1278 case EFI_HII_PACKAGE_FORMS
:
1279 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) (HiiPackageHeader
+ 1);
1281 while ((UINTN
) IfrOpCodeHeader
< (UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
) {
1282 switch (IfrOpCodeHeader
->OpCode
) {
1283 case EFI_IFR_VARSTORE_EFI_OP
:
1285 // Come to EFI VARSTORE in Form Package.
1287 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*) IfrOpCodeHeader
;
1288 if ((IfrEfiVarStore
->Header
.Length
>= sizeof (EFI_IFR_VARSTORE_EFI
)) &&
1289 ((IfrEfiVarStore
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) != 0)) {
1291 // Only create node list for Hii Variable with NV attribute.
1293 CreateHiiVariableNode (IfrEfiVarStore
);
1300 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
1310 Var Check Parse Hii Package.
1312 @param[in] HiiPackage Pointer to Hii Package.
1313 @param[in] FromFv Hii Package from FV.
1317 VarCheckParseHiiPackage (
1318 IN VOID
*HiiPackage
,
1322 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1323 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
1324 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1325 BOOLEAN QuestionStoredInBitField
;
1328 // Parse and create Hii Variable node list for this Hii Package.
1330 ParseHiiVariable (HiiPackage
);
1332 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) HiiPackage
;
1334 QuestionStoredInBitField
= FALSE
;
1336 switch (HiiPackageHeader
->Type
) {
1337 case EFI_HII_PACKAGE_FORMS
:
1338 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) (HiiPackageHeader
+ 1);
1340 while ((UINTN
) IfrOpCodeHeader
< (UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
) {
1341 switch (IfrOpCodeHeader
->OpCode
) {
1342 case EFI_IFR_GUID_OP
:
1343 if (CompareGuid ((EFI_GUID
*)((UINTN
)IfrOpCodeHeader
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
1344 QuestionStoredInBitField
= TRUE
;
1348 case EFI_IFR_END_OP
:
1349 QuestionStoredInBitField
= FALSE
;
1352 case EFI_IFR_ONE_OF_OP
:
1353 case EFI_IFR_CHECKBOX_OP
:
1354 case EFI_IFR_NUMERIC_OP
:
1355 case EFI_IFR_ORDERED_LIST_OP
:
1356 HiiVariableNode
= FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.VarStoreId
);
1357 if ((HiiVariableNode
== NULL
) ||
1359 // No related Hii Variable node found.
1361 ((((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Prompt
== 0) && (((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Help
== 0))) {
1363 // meanless IFR item introduced by ECP.
1369 ParseHiiQuestion (HiiVariableNode
, IfrOpCodeHeader
, FromFv
, QuestionStoredInBitField
);
1374 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
1381 DestroyVarStoreId ();
1385 Var Check Parse Hii Database.
1387 @param[in] HiiDatabase Pointer to Hii Database.
1388 @param[in] HiiDatabaseSize Hii Database size.
1392 VarCheckParseHiiDatabase (
1393 IN VOID
*HiiDatabase
,
1394 IN UINTN HiiDatabaseSize
1397 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageListHeader
;
1398 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1400 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) HiiDatabase
;
1402 while ((UINTN
) HiiPackageListHeader
< ((UINTN
) HiiDatabase
+ HiiDatabaseSize
)) {
1403 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) (HiiPackageListHeader
+ 1);
1405 while ((UINTN
) HiiPackageHeader
< ((UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
)) {
1407 // Parse Hii Package.
1409 VarCheckParseHiiPackage (HiiPackageHeader
, FALSE
);
1411 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) ((UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
);
1414 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) ((UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
);
1419 Destroy Hii Variable node.
1423 DestroyHiiVariableNode (
1427 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1428 LIST_ENTRY
*HiiVariableLink
;
1431 while (mVarCheckHiiList
.ForwardLink
!= &mVarCheckHiiList
) {
1432 HiiVariableLink
= mVarCheckHiiList
.ForwardLink
;
1433 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1435 RemoveEntryList (&HiiVariableNode
->Link
);
1438 // Free the allocated buffer.
1440 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
) 8; Index
++) {
1441 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1442 InternalVarCheckFreePool (HiiVariableNode
->HiiQuestionArray
[Index
]);
1445 InternalVarCheckFreePool (HiiVariableNode
->HiiQuestionArray
);
1446 InternalVarCheckFreePool (HiiVariableNode
->HiiVariable
);
1447 InternalVarCheckFreePool (HiiVariableNode
);
1452 Build VarCheckHiiBin.
1454 @param[out] Size Pointer to VarCheckHii size.
1456 @return Pointer to VarCheckHiiBin.
1460 BuildVarCheckHiiBin (
1464 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1465 LIST_ENTRY
*HiiVariableLink
;
1470 UINT32 HiiVariableLength
;
1477 for (HiiVariableLink
= mVarCheckHiiList
.ForwardLink
1478 ;HiiVariableLink
!= &mVarCheckHiiList
1479 ;HiiVariableLink
= HiiVariableLink
->ForwardLink
) {
1481 // For Hii Variable header align.
1483 BinSize
= (UINT32
) HEADER_ALIGN (BinSize
);
1485 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1486 HiiVariableLength
= HiiVariableNode
->HiiVariable
->HeaderLength
;
1488 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
) 8; Index
++) {
1489 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1491 // For Hii Question header align.
1493 HiiVariableLength
= (UINT32
) HEADER_ALIGN (HiiVariableLength
);
1494 HiiVariableLength
+= HiiVariableNode
->HiiQuestionArray
[Index
]->Length
;
1498 HiiVariableNode
->HiiVariable
->Length
= HiiVariableLength
;
1499 BinSize
+= HiiVariableLength
;
1502 DEBUG ((DEBUG_INFO
, "VarCheckHiiBin - size = 0x%x\n", BinSize
));
1509 // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation.
1510 // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
1511 // in SetVariable check handler.
1513 Data
= AllocateRuntimeZeroPool (BinSize
);
1514 ASSERT (Data
!= NULL
);
1516 // Make sure the allocated buffer for VarCheckHiiBin at required alignment.
1518 ASSERT ((((UINTN
) Data
) & (HEADER_ALIGNMENT
- 1)) == 0);
1519 DEBUG ((DEBUG_INFO
, "VarCheckHiiBin - built at 0x%x\n", Data
));
1525 for (HiiVariableLink
= mVarCheckHiiList
.ForwardLink
1526 ;HiiVariableLink
!= &mVarCheckHiiList
1527 ;HiiVariableLink
= HiiVariableLink
->ForwardLink
) {
1529 // For Hii Variable header align.
1531 Ptr
= (UINT8
*) HEADER_ALIGN (Ptr
);
1533 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1534 CopyMem (Ptr
, HiiVariableNode
->HiiVariable
, HiiVariableNode
->HiiVariable
->HeaderLength
);
1535 Ptr
+= HiiVariableNode
->HiiVariable
->HeaderLength
;
1537 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
) 8; Index
++) {
1538 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1540 // For Hii Question header align.
1542 Ptr
= (UINT8
*) HEADER_ALIGN (Ptr
);
1543 CopyMem (Ptr
, HiiVariableNode
->HiiQuestionArray
[Index
], HiiVariableNode
->HiiQuestionArray
[Index
]->Length
);
1544 Ptr
+= HiiVariableNode
->HiiQuestionArray
[Index
]->Length
;
1554 Generate VarCheckHiiBin from Hii Database and FV.
1563 VarCheckHiiGenFromHiiDatabase ();
1564 VarCheckHiiGenFromFv ();
1566 mVarCheckHiiBin
= BuildVarCheckHiiBin (&mVarCheckHiiBinSize
);
1567 if (mVarCheckHiiBin
== NULL
) {
1568 DEBUG ((DEBUG_INFO
, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
1572 DestroyHiiVariableNode ();
1573 if (mVarName
!= NULL
) {
1574 InternalVarCheckFreePool (mVarName
);
1577 #ifdef DUMP_VAR_CHECK_HII
1579 DumpVarCheckHii (mVarCheckHiiBin
, mVarCheckHiiBinSize
);