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.
55 for (Index
= 0; Index
< ARRAY_SIZE (mIfrOpCodeStringTable
); Index
++) {
56 if (mIfrOpCodeStringTable
[Index
].HiiOpCode
== IfrOpCode
) {
57 return mIfrOpCodeStringTable
[Index
].HiiOpCodeStr
;
61 return "<UnknownIfrOpCode>";
64 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_PACKAGE_TYPE_STRING mPackageTypeStringTable
[] = {
65 { EFI_HII_PACKAGE_TYPE_ALL
, "EFI_HII_PACKAGE_TYPE_ALL" },
66 { EFI_HII_PACKAGE_TYPE_GUID
, "EFI_HII_PACKAGE_TYPE_GUID" },
67 { EFI_HII_PACKAGE_FORMS
, "EFI_HII_PACKAGE_FORMS" },
68 { EFI_HII_PACKAGE_STRINGS
, "EFI_HII_PACKAGE_STRINGS" },
69 { EFI_HII_PACKAGE_FONTS
, "EFI_HII_PACKAGE_FONTS" },
70 { EFI_HII_PACKAGE_IMAGES
, "EFI_HII_PACKAGE_IMAGES" },
71 { EFI_HII_PACKAGE_SIMPLE_FONTS
, "EFI_HII_PACKAGE_SIMPLE_FONTS" },
72 { EFI_HII_PACKAGE_DEVICE_PATH
, "EFI_HII_PACKAGE_DEVICE_PATH" },
73 { EFI_HII_PACKAGE_KEYBOARD_LAYOUT
, "EFI_HII_PACKAGE_KEYBOARD_LAYOUT" },
74 { EFI_HII_PACKAGE_ANIMATIONS
, "EFI_HII_PACKAGE_ANIMATIONS" },
75 { EFI_HII_PACKAGE_END
, "EFI_HII_PACKAGE_END" },
76 { EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN
, "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN" },
77 { EFI_HII_PACKAGE_TYPE_SYSTEM_END
, "EFI_HII_PACKAGE_TYPE_SYSTEM_END" },
81 Hii Package type to string.
83 @param[in] PackageType Package Type
85 @return Pointer to string.
95 for (Index
= 0; Index
< ARRAY_SIZE (mPackageTypeStringTable
); Index
++) {
96 if (mPackageTypeStringTable
[Index
].PackageType
== PackageType
) {
97 return mPackageTypeStringTable
[Index
].PackageTypeStr
;
101 return "<UnknownPackageType>";
107 @param[in] HiiPackage Pointer to Hii Package.
115 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
116 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
117 EFI_IFR_VARSTORE
*IfrVarStore
;
118 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
119 BOOLEAN QuestionStoredInBitField
;
121 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)HiiPackage
;
122 QuestionStoredInBitField
= FALSE
;
124 DEBUG ((DEBUG_INFO
, " HiiPackageHeader->Type - 0x%02x (%a)\n", HiiPackageHeader
->Type
, HiiPackageTypeToStr ((UINT8
)HiiPackageHeader
->Type
)));
125 DEBUG ((DEBUG_INFO
, " HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader
->Length
));
127 switch (HiiPackageHeader
->Type
) {
128 case EFI_HII_PACKAGE_FORMS
:
129 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)(HiiPackageHeader
+ 1);
131 while ((UINTN
)IfrOpCodeHeader
< ((UINTN
)HiiPackageHeader
+ HiiPackageHeader
->Length
)) {
132 switch (IfrOpCodeHeader
->OpCode
) {
133 case EFI_IFR_VARSTORE_OP
:
134 IfrVarStore
= (EFI_IFR_VARSTORE
*)IfrOpCodeHeader
;
135 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
136 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
137 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
138 DEBUG ((DEBUG_INFO
, " Guid - %g\n", &IfrVarStore
->Guid
));
139 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", IfrVarStore
->VarStoreId
));
140 DEBUG ((DEBUG_INFO
, " Size - 0x%04x\n", IfrVarStore
->Size
));
141 DEBUG ((DEBUG_INFO
, " Name - %a\n", IfrVarStore
->Name
));
144 case EFI_IFR_VARSTORE_EFI_OP
:
145 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*)IfrOpCodeHeader
;
146 if (IfrEfiVarStore
->Header
.Length
>= sizeof (EFI_IFR_VARSTORE_EFI
)) {
147 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
148 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
149 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
150 DEBUG ((DEBUG_INFO
, " Guid - %g\n", &IfrEfiVarStore
->Guid
));
151 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", IfrEfiVarStore
->VarStoreId
));
152 DEBUG ((DEBUG_INFO
, " Size - 0x%04x\n", IfrEfiVarStore
->Size
));
153 DEBUG ((DEBUG_INFO
, " Attributes - 0x%08x\n", IfrEfiVarStore
->Attributes
));
154 DEBUG ((DEBUG_INFO
, " Name - %a\n", IfrEfiVarStore
->Name
));
159 case EFI_IFR_GUID_OP
:
160 if (CompareGuid ((EFI_GUID
*)((UINTN
)IfrOpCodeHeader
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
161 QuestionStoredInBitField
= TRUE
;
166 case EFI_IFR_ONE_OF_OP
:
167 case EFI_IFR_CHECKBOX_OP
:
168 case EFI_IFR_NUMERIC_OP
:
169 case EFI_IFR_ORDERED_LIST_OP
:
170 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
), (QuestionStoredInBitField
? "bit level" : "byte level")));
171 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
172 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
173 DEBUG ((DEBUG_INFO
, " Prompt - 0x%04x\n", ((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.Header
.Prompt
));
174 DEBUG ((DEBUG_INFO
, " Help - 0x%04x\n", ((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.Header
.Help
));
175 DEBUG ((DEBUG_INFO
, " QuestionId - 0x%04x\n", ((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.QuestionId
));
176 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", ((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.VarStoreId
));
177 DEBUG ((DEBUG_INFO
, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.VarStoreInfo
.VarOffset
, (QuestionStoredInBitField
? "bit level" : "byte level")));
179 EFI_IFR_ONE_OF
*IfrOneOf
;
180 EFI_IFR_CHECKBOX
*IfrCheckBox
;
181 EFI_IFR_NUMERIC
*IfrNumeric
;
182 EFI_IFR_ORDERED_LIST
*IfrOrderedList
;
184 switch (IfrOpCodeHeader
->OpCode
) {
185 case EFI_IFR_ONE_OF_OP
:
186 IfrOneOf
= (EFI_IFR_ONE_OF
*)IfrOpCodeHeader
;
187 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrOneOf
->Flags
));
188 if (QuestionStoredInBitField
) {
190 // For OneOf stored in bit field, the option value are saved as UINT32 type.
192 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrOneOf
->data
.u32
.MinValue
));
193 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrOneOf
->data
.u32
.MaxValue
));
194 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrOneOf
->data
.u32
.Step
));
196 switch (IfrOneOf
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
197 case EFI_IFR_NUMERIC_SIZE_1
:
198 DEBUG ((DEBUG_INFO
, " MinValue - 0x%02x\n", IfrOneOf
->data
.u8
.MinValue
));
199 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%02x\n", IfrOneOf
->data
.u8
.MaxValue
));
200 DEBUG ((DEBUG_INFO
, " Step - 0x%02x\n", IfrOneOf
->data
.u8
.Step
));
202 case EFI_IFR_NUMERIC_SIZE_2
:
203 DEBUG ((DEBUG_INFO
, " MinValue - 0x%04x\n", IfrOneOf
->data
.u16
.MinValue
));
204 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%04x\n", IfrOneOf
->data
.u16
.MaxValue
));
205 DEBUG ((DEBUG_INFO
, " Step - 0x%04x\n", IfrOneOf
->data
.u16
.Step
));
207 case EFI_IFR_NUMERIC_SIZE_4
:
208 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrOneOf
->data
.u32
.MinValue
));
209 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrOneOf
->data
.u32
.MaxValue
));
210 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrOneOf
->data
.u32
.Step
));
212 case EFI_IFR_NUMERIC_SIZE_8
:
213 DEBUG ((DEBUG_INFO
, " MinValue - 0x%016lx\n", IfrOneOf
->data
.u64
.MinValue
));
214 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%016lx\n", IfrOneOf
->data
.u64
.MaxValue
));
215 DEBUG ((DEBUG_INFO
, " Step - 0x%016lx\n", IfrOneOf
->data
.u64
.Step
));
221 case EFI_IFR_CHECKBOX_OP
:
222 IfrCheckBox
= (EFI_IFR_CHECKBOX
*)IfrOpCodeHeader
;
223 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrCheckBox
->Flags
));
225 case EFI_IFR_NUMERIC_OP
:
226 IfrNumeric
= (EFI_IFR_NUMERIC
*)IfrOpCodeHeader
;
227 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrNumeric
->Flags
));
228 if (QuestionStoredInBitField
) {
230 // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type.
232 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrNumeric
->data
.u32
.MinValue
));
233 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrNumeric
->data
.u32
.MaxValue
));
234 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrNumeric
->data
.u32
.Step
));
236 switch (IfrNumeric
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
237 case EFI_IFR_NUMERIC_SIZE_1
:
238 DEBUG ((DEBUG_INFO
, " MinValue - 0x%02x\n", IfrNumeric
->data
.u8
.MinValue
));
239 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%02x\n", IfrNumeric
->data
.u8
.MaxValue
));
240 DEBUG ((DEBUG_INFO
, " Step - 0x%02x\n", IfrNumeric
->data
.u8
.Step
));
242 case EFI_IFR_NUMERIC_SIZE_2
:
243 DEBUG ((DEBUG_INFO
, " MinValue - 0x%04x\n", IfrNumeric
->data
.u16
.MinValue
));
244 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%04x\n", IfrNumeric
->data
.u16
.MaxValue
));
245 DEBUG ((DEBUG_INFO
, " Step - 0x%04x\n", IfrNumeric
->data
.u16
.Step
));
247 case EFI_IFR_NUMERIC_SIZE_4
:
248 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrNumeric
->data
.u32
.MinValue
));
249 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrNumeric
->data
.u32
.MaxValue
));
250 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrNumeric
->data
.u32
.Step
));
252 case EFI_IFR_NUMERIC_SIZE_8
:
253 DEBUG ((DEBUG_INFO
, " MinValue - 0x%016lx\n", IfrNumeric
->data
.u64
.MinValue
));
254 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%016lx\n", IfrNumeric
->data
.u64
.MaxValue
));
255 DEBUG ((DEBUG_INFO
, " Step - 0x%016lx\n", IfrNumeric
->data
.u64
.Step
));
261 case EFI_IFR_ORDERED_LIST_OP
:
262 IfrOrderedList
= (EFI_IFR_ORDERED_LIST
*)IfrOpCodeHeader
;
263 DEBUG ((DEBUG_INFO
, " MaxContainers - 0x%02x\n", IfrOrderedList
->MaxContainers
));
264 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrOrderedList
->Flags
));
270 if (IfrOpCodeHeader
->Scope
!= 0) {
272 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
274 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
277 switch (IfrOpCodeHeader
->OpCode
) {
278 case EFI_IFR_ONE_OF_OPTION_OP
:
279 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*)IfrOpCodeHeader
;
280 DEBUG ((DEBUG_INFO
, "!!!! IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", (UINTN
)IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
281 DEBUG ((DEBUG_INFO
, "!!!! IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
282 DEBUG ((DEBUG_INFO
, "!!!! Option - 0x%04x\n", IfrOneOfOption
->Option
));
283 DEBUG ((DEBUG_INFO
, "!!!! Flags - 0x%02x\n", IfrOneOfOption
->Flags
));
284 DEBUG ((DEBUG_INFO
, "!!!! Type - 0x%02x\n", IfrOneOfOption
->Type
));
285 switch (IfrOneOfOption
->Type
) {
286 case EFI_IFR_TYPE_NUM_SIZE_8
:
287 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%02x\n", IfrOneOfOption
->Value
.u8
));
289 case EFI_IFR_TYPE_NUM_SIZE_16
:
290 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%04x\n", IfrOneOfOption
->Value
.u16
));
292 case EFI_IFR_TYPE_NUM_SIZE_32
:
293 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%08x\n", IfrOneOfOption
->Value
.u32
));
295 case EFI_IFR_TYPE_NUM_SIZE_64
:
296 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%016lx\n", IfrOneOfOption
->Value
.u64
));
298 case EFI_IFR_TYPE_BOOLEAN
:
299 DEBUG ((DEBUG_INFO
, "!!!! Value - 0x%02x\n", IfrOneOfOption
->Value
.b
));
308 if (IfrOpCodeHeader
->OpCode
== EFI_IFR_END_OP
) {
309 QuestionStoredInBitField
= FALSE
;
315 } else if (IfrOpCodeHeader
->Scope
!= 0) {
319 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
327 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
339 @param[in] HiiDatabase Pointer to Hii Database.
340 @param[in] HiiDatabaseSize Hii Database size.
345 IN VOID
*HiiDatabase
,
346 IN UINTN HiiDatabaseSize
349 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageListHeader
;
350 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
352 DEBUG ((DEBUG_INFO
, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize
));
353 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*)HiiDatabase
;
355 while ((UINTN
)HiiPackageListHeader
< ((UINTN
)HiiDatabase
+ HiiDatabaseSize
)) {
356 DEBUG ((DEBUG_INFO
, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader
->PackageListGuid
));
357 DEBUG ((DEBUG_INFO
, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN
)HiiPackageListHeader
->PackageLength
));
358 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)(HiiPackageListHeader
+ 1);
360 while ((UINTN
)HiiPackageHeader
< (UINTN
)HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
) {
361 DumpHiiPackage (HiiPackageHeader
);
363 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)((UINTN
)HiiPackageHeader
+ HiiPackageHeader
->Length
);
366 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*)((UINTN
)HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
);
375 Allocates a buffer of a certain pool type.
377 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
378 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
379 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
381 @param MemoryType The type of memory to allocate.
382 @param AllocationSize The number of bytes to allocate.
384 @return A pointer to the allocated buffer or NULL if allocation fails.
388 InternalVarCheckAllocatePool (
389 IN EFI_MEMORY_TYPE MemoryType
,
390 IN UINTN AllocationSize
396 Status
= gBS
->AllocatePool (MemoryType
, AllocationSize
, &Memory
);
397 if (EFI_ERROR (Status
)) {
405 Allocates and zeros a buffer of type EfiBootServicesData.
407 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
408 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
409 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
410 request, then NULL is returned.
412 @param AllocationSize The number of bytes to allocate and zero.
414 @return A pointer to the allocated buffer or NULL if allocation fails.
418 InternalVarCheckAllocateZeroPool (
419 IN UINTN AllocationSize
424 Memory
= InternalVarCheckAllocatePool (EfiBootServicesData
, AllocationSize
);
425 if (Memory
!= NULL
) {
426 Memory
= ZeroMem (Memory
, AllocationSize
);
433 Frees a buffer that was previously allocated with one of the pool allocation functions in the
434 Memory Allocation Library.
436 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
437 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
438 resources, then this function will perform no actions.
440 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
443 @param Buffer The pointer to the buffer to free.
448 InternalVarCheckFreePool (
454 Status
= gBS
->FreePool (Buffer
);
455 ASSERT_EFI_ERROR (Status
);
459 Reallocates a buffer of type EfiBootServicesData.
461 Allocates and zeros the number bytes specified by NewSize from memory of type
462 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
463 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
464 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
465 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
466 enough memory remaining to satisfy the request, then NULL is returned.
468 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
469 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
471 @param OldSize The size, in bytes, of OldBuffer.
472 @param NewSize The size, in bytes, of the buffer to reallocate.
473 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
474 parameter that may be NULL.
476 @return A pointer to the allocated buffer or NULL if allocation fails.
480 InternalVarCheckReallocatePool (
483 IN VOID
*OldBuffer OPTIONAL
488 NewBuffer
= InternalVarCheckAllocateZeroPool (NewSize
);
489 if ((NewBuffer
!= NULL
) && (OldBuffer
!= NULL
)) {
490 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
491 InternalVarCheckFreePool (OldBuffer
);
500 @param[in, out] HiiVariableNode Pointer to Hii Variable node.
501 @param[in] HiiQuestion Pointer to Hii Question.
502 @param[in] FromFv Hii Question from FV.
507 IN OUT VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
,
508 IN VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion
,
512 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion1
;
513 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion2
;
514 VAR_CHECK_HII_QUESTION_HEADER
*NewHiiQuestion
;
528 // Hii Question from Hii Database has high priority.
529 // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
532 InternalVarCheckFreePool (HiiQuestion
);
536 if (HiiQuestion
->BitFieldStore
) {
537 ArrayIndex
= HiiQuestion
->VarOffset
;
539 ArrayIndex
= HiiQuestion
->VarOffset
* 8;
542 HiiQuestion1
= HiiVariableNode
->HiiQuestionArray
[ArrayIndex
];
543 HiiQuestion2
= HiiQuestion
;
545 ASSERT ((HiiQuestion1
->OpCode
== HiiQuestion2
->OpCode
) && (HiiQuestion1
->StorageWidth
== HiiQuestion2
->StorageWidth
));
547 switch (HiiQuestion1
->OpCode
) {
548 case EFI_IFR_ONE_OF_OP
:
549 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level" : "byte level")));
551 // Get the length of Hii Question 1.
553 NewLength
= HiiQuestion1
->Length
;
556 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
558 Ptr2
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ONEOF
*)HiiQuestion2
+ 1);
559 while ((UINTN
)Ptr2
< (UINTN
)HiiQuestion2
+ HiiQuestion2
->Length
) {
561 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
563 Ptr1
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ONEOF
*)HiiQuestion1
+ 1);
564 while ((UINTN
)Ptr1
< (UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
) {
566 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
567 if (OneValue2
== OneValue1
) {
574 Ptr1
+= HiiQuestion1
->StorageWidth
;
577 if ((UINTN
)Ptr1
>= ((UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
)) {
581 NewLength
= (UINT8
)(NewLength
+ HiiQuestion1
->StorageWidth
);
584 Ptr2
+= HiiQuestion2
->StorageWidth
;
587 if (NewLength
> HiiQuestion1
->Length
) {
589 // Merge the one of options of Hii Question 2 and Hii Question 1.
591 NewHiiQuestion
= InternalVarCheckAllocateZeroPool (NewLength
);
592 ASSERT (NewHiiQuestion
!= NULL
);
593 CopyMem (NewHiiQuestion
, HiiQuestion1
, HiiQuestion1
->Length
);
595 // Use the new length.
597 NewHiiQuestion
->Length
= NewLength
;
598 Ptr
= (UINT8
*)NewHiiQuestion
+ HiiQuestion1
->Length
;
600 Ptr2
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ONEOF
*)HiiQuestion2
+ 1);
601 while ((UINTN
)Ptr2
< (UINTN
)HiiQuestion2
+ HiiQuestion2
->Length
) {
603 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
605 Ptr1
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ONEOF
*)HiiQuestion1
+ 1);
606 while ((UINTN
)Ptr1
< (UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
) {
608 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
609 if (OneValue2
== OneValue1
) {
616 Ptr1
+= HiiQuestion1
->StorageWidth
;
619 if ((UINTN
)Ptr1
>= ((UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
)) {
623 CopyMem (Ptr
, &OneValue2
, HiiQuestion1
->StorageWidth
);
624 Ptr
+= HiiQuestion1
->StorageWidth
;
627 Ptr2
+= HiiQuestion2
->StorageWidth
;
630 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = NewHiiQuestion
;
631 InternalVarCheckFreePool (HiiQuestion1
);
636 case EFI_IFR_CHECKBOX_OP
:
637 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level" : "byte level")));
640 case EFI_IFR_NUMERIC_OP
:
641 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level" : "byte level")));
643 // Get minimum and maximum of Hii Question 1.
647 Ptr
= (UINT8
*)((VAR_CHECK_HII_QUESTION_NUMERIC
*)HiiQuestion1
+ 1);
648 CopyMem (&Minimum1
, Ptr
, HiiQuestion1
->StorageWidth
);
649 Ptr
+= HiiQuestion1
->StorageWidth
;
650 CopyMem (&Maximum1
, Ptr
, HiiQuestion1
->StorageWidth
);
653 // Get minimum and maximum of Hii Question 2.
657 Ptr
= (UINT8
*)((VAR_CHECK_HII_QUESTION_NUMERIC
*)HiiQuestion2
+ 1);
658 CopyMem (&Minimum2
, Ptr
, HiiQuestion2
->StorageWidth
);
659 Ptr
+= HiiQuestion2
->StorageWidth
;
660 CopyMem (&Maximum2
, Ptr
, HiiQuestion2
->StorageWidth
);
665 Ptr
= (UINT8
*)((VAR_CHECK_HII_QUESTION_NUMERIC
*)HiiQuestion1
+ 1);
666 if (Minimum2
< Minimum1
) {
668 CopyMem (Ptr
, &Minimum1
, HiiQuestion1
->StorageWidth
);
674 Ptr
+= HiiQuestion1
->StorageWidth
;
675 if (Maximum2
> Maximum1
) {
677 CopyMem (Ptr
, &Maximum1
, HiiQuestion1
->StorageWidth
);
682 case EFI_IFR_ORDERED_LIST_OP
:
683 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1
->VarOffset
));
685 // Get the length of Hii Question 1.
687 NewLength
= HiiQuestion1
->Length
;
690 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
692 Ptr2
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*)HiiQuestion2
+ 1);
693 while ((UINTN
)Ptr2
< (UINTN
)HiiQuestion2
+ HiiQuestion2
->Length
) {
695 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
697 Ptr1
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*)HiiQuestion1
+ 1);
698 while ((UINTN
)Ptr1
< (UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
) {
700 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
701 if (OneValue2
== OneValue1
) {
708 Ptr1
+= HiiQuestion1
->StorageWidth
;
711 if ((UINTN
)Ptr1
>= ((UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
)) {
715 NewLength
= (UINT8
)(NewLength
+ HiiQuestion1
->StorageWidth
);
718 Ptr2
+= HiiQuestion2
->StorageWidth
;
721 if (NewLength
> HiiQuestion1
->Length
) {
723 // Merge the one of options of Hii Question 2 and Hii Question 1.
725 NewHiiQuestion
= InternalVarCheckAllocateZeroPool (NewLength
);
726 ASSERT (NewHiiQuestion
!= NULL
);
727 CopyMem (NewHiiQuestion
, HiiQuestion1
, HiiQuestion1
->Length
);
729 // Use the new length.
731 NewHiiQuestion
->Length
= NewLength
;
732 Ptr
= (UINT8
*)NewHiiQuestion
+ HiiQuestion1
->Length
;
734 Ptr2
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*)HiiQuestion2
+ 1);
735 while ((UINTN
)Ptr2
< (UINTN
)HiiQuestion2
+ HiiQuestion2
->Length
) {
737 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
739 Ptr1
= (UINT8
*)((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*)HiiQuestion1
+ 1);
740 while ((UINTN
)Ptr1
< (UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
) {
742 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
743 if (OneValue2
== OneValue1
) {
750 Ptr1
+= HiiQuestion1
->StorageWidth
;
753 if ((UINTN
)Ptr1
>= ((UINTN
)HiiQuestion1
+ HiiQuestion1
->Length
)) {
757 CopyMem (Ptr
, &OneValue2
, HiiQuestion1
->StorageWidth
);
758 Ptr
+= HiiQuestion1
->StorageWidth
;
761 Ptr2
+= HiiQuestion2
->StorageWidth
;
764 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = NewHiiQuestion
;
765 InternalVarCheckFreePool (HiiQuestion1
);
778 // Hii Question 2 has been merged with Hii Question 1.
780 InternalVarCheckFreePool (HiiQuestion2
);
784 Get OneOf option data.
786 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
787 @param[out] Count Pointer to option count.
788 @param[out] Width Pointer to option width.
789 @param[out] OptionBuffer Pointer to option buffer.
794 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
797 OUT VOID
*OptionBuffer OPTIONAL
801 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
804 // Assume all OPTION has same Width.
808 if (IfrOpCodeHeader
->Scope
!= 0) {
813 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
815 switch (IfrOpCodeHeader
->OpCode
) {
816 case EFI_IFR_ONE_OF_OPTION_OP
:
817 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*)IfrOpCodeHeader
;
818 switch (IfrOneOfOption
->Type
) {
819 case EFI_IFR_TYPE_NUM_SIZE_8
:
821 *Width
= sizeof (UINT8
);
822 if (OptionBuffer
!= NULL
) {
823 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u8
, sizeof (UINT8
));
824 OptionBuffer
= (UINT8
*)OptionBuffer
+ 1;
828 case EFI_IFR_TYPE_NUM_SIZE_16
:
830 *Width
= sizeof (UINT16
);
831 if (OptionBuffer
!= NULL
) {
832 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u16
, sizeof (UINT16
));
833 OptionBuffer
= (UINT16
*)OptionBuffer
+ 1;
837 case EFI_IFR_TYPE_NUM_SIZE_32
:
839 *Width
= sizeof (UINT32
);
840 if (OptionBuffer
!= NULL
) {
841 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u32
, sizeof (UINT32
));
842 OptionBuffer
= (UINT32
*)OptionBuffer
+ 1;
846 case EFI_IFR_TYPE_NUM_SIZE_64
:
848 *Width
= sizeof (UINT64
);
849 if (OptionBuffer
!= NULL
) {
850 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u64
, sizeof (UINT64
));
851 OptionBuffer
= (UINT64
*)OptionBuffer
+ 1;
855 case EFI_IFR_TYPE_BOOLEAN
:
857 *Width
= sizeof (BOOLEAN
);
858 if (OptionBuffer
!= NULL
) {
859 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.b
, sizeof (BOOLEAN
));
860 OptionBuffer
= (BOOLEAN
*)OptionBuffer
+ 1;
874 if (IfrOpCodeHeader
->OpCode
== EFI_IFR_END_OP
) {
880 } else if (IfrOpCodeHeader
->Scope
!= 0) {
887 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
895 Parse Hii Question Oneof.
897 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
898 @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage.
900 return Pointer to Hii Question.
903 VAR_CHECK_HII_QUESTION_HEADER
*
904 ParseHiiQuestionOneOf (
905 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
906 IN BOOLEAN StoredInBitField
909 EFI_IFR_ONE_OF
*IfrOneOf
;
910 VAR_CHECK_HII_QUESTION_ONEOF
*OneOf
;
917 IfrOneOf
= (EFI_IFR_ONE_OF
*)IfrOpCodeHeader
;
920 if (StoredInBitField
) {
922 // When OneOf stored in bit field, the bit width is saved in the lower six bits of the flag.
923 // And the options in the OneOf is saved as UINT32 type.
925 BitWidth
= IfrOneOf
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
926 Width
= sizeof (UINT32
);
928 Width
= (UINT8
)(1 << (IfrOneOf
->Flags
& EFI_IFR_NUMERIC_SIZE
));
931 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, NULL
);
932 ASSERT (Width
== OptionWidth
);
934 Length
= sizeof (*OneOf
) + OptionCount
* Width
;
936 OneOf
= InternalVarCheckAllocateZeroPool (Length
);
937 ASSERT (OneOf
!= NULL
);
938 OneOf
->OpCode
= EFI_IFR_ONE_OF_OP
;
939 OneOf
->Length
= (UINT8
)Length
;
940 OneOf
->VarOffset
= IfrOneOf
->Question
.VarStoreInfo
.VarOffset
;
941 OneOf
->BitFieldStore
= StoredInBitField
;
942 if (StoredInBitField
) {
943 OneOf
->StorageWidth
= BitWidth
;
945 OneOf
->StorageWidth
= Width
;
948 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, OneOf
+ 1);
950 return (VAR_CHECK_HII_QUESTION_HEADER
*)OneOf
;
954 Parse Hii Question CheckBox.
956 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
957 @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage.
959 return Pointer to Hii Question.
962 VAR_CHECK_HII_QUESTION_HEADER
*
963 ParseHiiQuestionCheckBox (
964 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
965 IN BOOLEAN StoredInBitField
968 EFI_IFR_CHECKBOX
*IfrCheckBox
;
969 VAR_CHECK_HII_QUESTION_CHECKBOX
*CheckBox
;
971 IfrCheckBox
= (EFI_IFR_CHECKBOX
*)IfrOpCodeHeader
;
973 CheckBox
= InternalVarCheckAllocateZeroPool (sizeof (*CheckBox
));
974 ASSERT (CheckBox
!= NULL
);
975 CheckBox
->OpCode
= EFI_IFR_CHECKBOX_OP
;
976 CheckBox
->Length
= (UINT8
)sizeof (*CheckBox
);
977 CheckBox
->VarOffset
= IfrCheckBox
->Question
.VarStoreInfo
.VarOffset
;
978 CheckBox
->BitFieldStore
= StoredInBitField
;
979 if (StoredInBitField
) {
980 CheckBox
->StorageWidth
= 1;
982 CheckBox
->StorageWidth
= (UINT8
)sizeof (BOOLEAN
);
985 return (VAR_CHECK_HII_QUESTION_HEADER
*)CheckBox
;
989 Parse Hii Question Numeric.
991 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
992 @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage.
994 return Pointer to Hii Question.
997 VAR_CHECK_HII_QUESTION_HEADER
*
998 ParseHiiQuestionNumeric (
999 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
1000 IN BOOLEAN StoredInBitField
1003 EFI_IFR_NUMERIC
*IfrNumeric
;
1004 VAR_CHECK_HII_QUESTION_NUMERIC
*Numeric
;
1008 IfrNumeric
= (EFI_IFR_NUMERIC
*)IfrOpCodeHeader
;
1011 Numeric
= InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC
) + 2 * sizeof (UINT64
));
1012 ASSERT (Numeric
!= NULL
);
1014 if (StoredInBitField
) {
1016 // When Numeric stored in bit field, the bit field width is saved in the lower six bits of the flag.
1017 // And the Minimum Maximum of Numeric is saved as UINT32 type.
1019 BitWidth
= IfrNumeric
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
1020 Width
= sizeof (UINT32
);
1022 Width
= (UINT8
)(1 << (IfrNumeric
->Flags
& EFI_IFR_NUMERIC_SIZE
));
1025 Numeric
->OpCode
= EFI_IFR_NUMERIC_OP
;
1026 Numeric
->Length
= (UINT8
)(sizeof (VAR_CHECK_HII_QUESTION_NUMERIC
) + 2 * Width
);
1027 Numeric
->VarOffset
= IfrNumeric
->Question
.VarStoreInfo
.VarOffset
;
1028 Numeric
->BitFieldStore
= StoredInBitField
;
1029 if (StoredInBitField
) {
1030 Numeric
->StorageWidth
= BitWidth
;
1032 Numeric
->StorageWidth
= Width
;
1035 CopyMem (Numeric
+ 1, &IfrNumeric
->data
, Width
* 2);
1037 return (VAR_CHECK_HII_QUESTION_HEADER
*)Numeric
;
1041 Parse Hii Question OrderedList.
1043 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1045 return Pointer to Hii Question.
1048 VAR_CHECK_HII_QUESTION_HEADER
*
1049 ParseHiiQuestionOrderedList (
1050 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
1053 EFI_IFR_ORDERED_LIST
*IfrOrderedList
;
1054 VAR_CHECK_HII_QUESTION_ORDEREDLIST
*OrderedList
;
1059 IfrOrderedList
= (EFI_IFR_ORDERED_LIST
*)IfrOpCodeHeader
;
1061 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, NULL
);
1063 Length
= sizeof (*OrderedList
) + OptionCount
* OptionWidth
;
1065 OrderedList
= InternalVarCheckAllocateZeroPool (Length
);
1066 ASSERT (OrderedList
!= NULL
);
1067 OrderedList
->OpCode
= EFI_IFR_ORDERED_LIST_OP
;
1068 OrderedList
->Length
= (UINT8
)Length
;
1069 OrderedList
->VarOffset
= IfrOrderedList
->Question
.VarStoreInfo
.VarOffset
;
1070 OrderedList
->StorageWidth
= OptionWidth
;
1071 OrderedList
->MaxContainers
= IfrOrderedList
->MaxContainers
;
1072 OrderedList
->BitFieldStore
= FALSE
;
1074 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, OrderedList
+ 1);
1076 return (VAR_CHECK_HII_QUESTION_HEADER
*)OrderedList
;
1080 Parse and create Hii Question node.
1082 @param[in] HiiVariableNode Pointer to Hii Variable node.
1083 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1084 @param[in] FromFv Hii Question from FV.
1085 @param[in] StoredInBitField Whether the Question is stored in bit field Storage.
1090 IN VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
,
1091 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
1093 IN BOOLEAN StoredInBitField
1096 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion
;
1100 // Currently only OneOf, CheckBox and Numeric can be stored in bit field.
1102 switch (IfrOpCodeHeader
->OpCode
) {
1103 case EFI_IFR_ONE_OF_OP
:
1104 HiiQuestion
= ParseHiiQuestionOneOf (IfrOpCodeHeader
, StoredInBitField
);
1107 case EFI_IFR_CHECKBOX_OP
:
1108 HiiQuestion
= ParseHiiQuestionCheckBox (IfrOpCodeHeader
, StoredInBitField
);
1111 case EFI_IFR_NUMERIC_OP
:
1112 HiiQuestion
= ParseHiiQuestionNumeric (IfrOpCodeHeader
, StoredInBitField
);
1115 case EFI_IFR_ORDERED_LIST_OP
:
1116 HiiQuestion
= ParseHiiQuestionOrderedList (IfrOpCodeHeader
);
1125 if (StoredInBitField
) {
1126 ArrayIndex
= HiiQuestion
->VarOffset
;
1128 ArrayIndex
= HiiQuestion
->VarOffset
* 8;
1131 if (HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] != NULL
) {
1132 MergeHiiQuestion (HiiVariableNode
, HiiQuestion
, FromFv
);
1134 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = HiiQuestion
;
1139 Find Hii variable node by name and GUID.
1141 @param[in] Name Pointer to variable name.
1142 @param[in] Guid Pointer to vendor GUID.
1144 @return Pointer to Hii Variable node.
1147 VAR_CHECK_HII_VARIABLE_NODE
*
1148 FindHiiVariableNode (
1153 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1156 for (Link
= mVarCheckHiiList
.ForwardLink
1157 ; Link
!= &mVarCheckHiiList
1158 ; Link
= Link
->ForwardLink
)
1160 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1162 if ((StrCmp (Name
, (CHAR16
*)(HiiVariableNode
->HiiVariable
+ 1)) == 0) &&
1163 CompareGuid (Guid
, &HiiVariableNode
->HiiVariable
->Guid
))
1165 return HiiVariableNode
;
1173 Find Hii variable node by var store id.
1175 @param[in] VarStoreId Var store id.
1177 @return Pointer to Hii Variable node.
1180 VAR_CHECK_HII_VARIABLE_NODE
*
1181 FindHiiVariableNodeByVarStoreId (
1182 IN EFI_VARSTORE_ID VarStoreId
1185 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1188 if (VarStoreId
== 0) {
1190 // The variable store identifier, which is unique within the current form set.
1191 // A value of zero is invalid.
1196 for (Link
= mVarCheckHiiList
.ForwardLink
1197 ; Link
!= &mVarCheckHiiList
1198 ; Link
= Link
->ForwardLink
)
1200 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1202 // The variable store identifier, which is unique within the current form set.
1204 if (VarStoreId
== HiiVariableNode
->VarStoreId
) {
1205 return HiiVariableNode
;
1213 Destroy var store id in the Hii Variable node after parsing one Hii Package.
1221 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1224 for (Link
= mVarCheckHiiList
.ForwardLink
1225 ; Link
!= &mVarCheckHiiList
1226 ; Link
= Link
->ForwardLink
)
1228 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1230 // The variable store identifier, which is unique within the current form set.
1231 // A value of zero is invalid.
1233 HiiVariableNode
->VarStoreId
= 0;
1238 Create Hii Variable node.
1240 @param[in] IfrEfiVarStore Pointer to EFI VARSTORE.
1244 CreateHiiVariableNode (
1245 IN EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
1248 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1249 VAR_CHECK_HII_VARIABLE_HEADER
*HiiVariable
;
1255 // Get variable name.
1257 VarNameSize
= AsciiStrSize ((CHAR8
*)IfrEfiVarStore
->Name
) * sizeof (CHAR16
);
1258 if (VarNameSize
> mMaxVarNameSize
) {
1259 mVarName
= InternalVarCheckReallocatePool (mMaxVarNameSize
, VarNameSize
, mVarName
);
1260 ASSERT (mVarName
!= NULL
);
1261 mMaxVarNameSize
= VarNameSize
;
1264 AsciiStrToUnicodeStrS ((CHAR8
*)IfrEfiVarStore
->Name
, mVarName
, mMaxVarNameSize
/ sizeof (CHAR16
));
1267 HiiVariableNode
= FindHiiVariableNode (
1269 &IfrEfiVarStore
->Guid
1271 if (HiiVariableNode
== NULL
) {
1273 // Not found, then create new.
1275 HeaderLength
= sizeof (*HiiVariable
) + VarNameSize
;
1276 HiiVariable
= InternalVarCheckAllocateZeroPool (HeaderLength
);
1277 ASSERT (HiiVariable
!= NULL
);
1278 HiiVariable
->Revision
= VAR_CHECK_HII_REVISION
;
1279 HiiVariable
->OpCode
= EFI_IFR_VARSTORE_EFI_OP
;
1280 HiiVariable
->HeaderLength
= (UINT16
)HeaderLength
;
1281 HiiVariable
->Size
= IfrEfiVarStore
->Size
;
1282 HiiVariable
->Attributes
= IfrEfiVarStore
->Attributes
;
1283 CopyGuid (&HiiVariable
->Guid
, &IfrEfiVarStore
->Guid
);
1284 StrCpyS ((CHAR16
*)(HiiVariable
+ 1), VarNameSize
/ sizeof (CHAR16
), VarName
);
1286 HiiVariableNode
= InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode
));
1287 ASSERT (HiiVariableNode
!= NULL
);
1288 HiiVariableNode
->Signature
= VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE
;
1289 HiiVariableNode
->HiiVariable
= HiiVariable
;
1291 // The variable store identifier, which is unique within the current form set.
1293 HiiVariableNode
->VarStoreId
= IfrEfiVarStore
->VarStoreId
;
1294 HiiVariableNode
->HiiQuestionArray
= InternalVarCheckAllocateZeroPool (IfrEfiVarStore
->Size
* 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER
*));
1296 InsertTailList (&mVarCheckHiiList
, &HiiVariableNode
->Link
);
1298 HiiVariableNode
->VarStoreId
= IfrEfiVarStore
->VarStoreId
;
1303 Parse and create Hii Variable node list.
1305 @param[in] HiiPackage Pointer to Hii Package.
1313 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1314 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
1315 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
1317 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)HiiPackage
;
1319 switch (HiiPackageHeader
->Type
) {
1320 case EFI_HII_PACKAGE_FORMS
:
1321 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)(HiiPackageHeader
+ 1);
1323 while ((UINTN
)IfrOpCodeHeader
< (UINTN
)HiiPackageHeader
+ HiiPackageHeader
->Length
) {
1324 switch (IfrOpCodeHeader
->OpCode
) {
1325 case EFI_IFR_VARSTORE_EFI_OP
:
1327 // Come to EFI VARSTORE in Form Package.
1329 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*)IfrOpCodeHeader
;
1330 if ((IfrEfiVarStore
->Header
.Length
>= sizeof (EFI_IFR_VARSTORE_EFI
)) &&
1331 ((IfrEfiVarStore
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) != 0))
1334 // Only create node list for Hii Variable with NV attribute.
1336 CreateHiiVariableNode (IfrEfiVarStore
);
1345 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
1356 Var Check Parse Hii Package.
1358 @param[in] HiiPackage Pointer to Hii Package.
1359 @param[in] FromFv Hii Package from FV.
1363 VarCheckParseHiiPackage (
1364 IN VOID
*HiiPackage
,
1368 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1369 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
1370 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1371 BOOLEAN QuestionStoredInBitField
;
1374 // Parse and create Hii Variable node list for this Hii Package.
1376 ParseHiiVariable (HiiPackage
);
1378 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)HiiPackage
;
1380 QuestionStoredInBitField
= FALSE
;
1382 switch (HiiPackageHeader
->Type
) {
1383 case EFI_HII_PACKAGE_FORMS
:
1384 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)(HiiPackageHeader
+ 1);
1386 while ((UINTN
)IfrOpCodeHeader
< (UINTN
)HiiPackageHeader
+ HiiPackageHeader
->Length
) {
1387 switch (IfrOpCodeHeader
->OpCode
) {
1388 case EFI_IFR_GUID_OP
:
1389 if (CompareGuid ((EFI_GUID
*)((UINTN
)IfrOpCodeHeader
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
1390 QuestionStoredInBitField
= TRUE
;
1395 case EFI_IFR_END_OP
:
1396 QuestionStoredInBitField
= FALSE
;
1399 case EFI_IFR_ONE_OF_OP
:
1400 case EFI_IFR_CHECKBOX_OP
:
1401 case EFI_IFR_NUMERIC_OP
:
1402 case EFI_IFR_ORDERED_LIST_OP
:
1403 HiiVariableNode
= FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.VarStoreId
);
1404 if ((HiiVariableNode
== NULL
) ||
1406 // No related Hii Variable node found.
1408 ((((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.Header
.Prompt
== 0) && (((EFI_IFR_ONE_OF
*)IfrOpCodeHeader
)->Question
.Header
.Help
== 0)))
1411 // meanless IFR item introduced by ECP.
1417 ParseHiiQuestion (HiiVariableNode
, IfrOpCodeHeader
, FromFv
, QuestionStoredInBitField
);
1424 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*)((UINTN
)IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
1433 DestroyVarStoreId ();
1437 Var Check Parse Hii Database.
1439 @param[in] HiiDatabase Pointer to Hii Database.
1440 @param[in] HiiDatabaseSize Hii Database size.
1444 VarCheckParseHiiDatabase (
1445 IN VOID
*HiiDatabase
,
1446 IN UINTN HiiDatabaseSize
1449 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageListHeader
;
1450 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1452 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*)HiiDatabase
;
1454 while ((UINTN
)HiiPackageListHeader
< ((UINTN
)HiiDatabase
+ HiiDatabaseSize
)) {
1455 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)(HiiPackageListHeader
+ 1);
1457 while ((UINTN
)HiiPackageHeader
< ((UINTN
)HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
)) {
1459 // Parse Hii Package.
1461 VarCheckParseHiiPackage (HiiPackageHeader
, FALSE
);
1463 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)((UINTN
)HiiPackageHeader
+ HiiPackageHeader
->Length
);
1466 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*)((UINTN
)HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
);
1471 Destroy Hii Variable node.
1475 DestroyHiiVariableNode (
1479 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1480 LIST_ENTRY
*HiiVariableLink
;
1483 while (mVarCheckHiiList
.ForwardLink
!= &mVarCheckHiiList
) {
1484 HiiVariableLink
= mVarCheckHiiList
.ForwardLink
;
1485 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1487 RemoveEntryList (&HiiVariableNode
->Link
);
1490 // Free the allocated buffer.
1492 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
)8; Index
++) {
1493 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1494 InternalVarCheckFreePool (HiiVariableNode
->HiiQuestionArray
[Index
]);
1498 InternalVarCheckFreePool (HiiVariableNode
->HiiQuestionArray
);
1499 InternalVarCheckFreePool (HiiVariableNode
->HiiVariable
);
1500 InternalVarCheckFreePool (HiiVariableNode
);
1505 Build VarCheckHiiBin.
1507 @param[out] Size Pointer to VarCheckHii size.
1509 @return Pointer to VarCheckHiiBin.
1513 BuildVarCheckHiiBin (
1517 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1518 LIST_ENTRY
*HiiVariableLink
;
1523 UINT32 HiiVariableLength
;
1530 for (HiiVariableLink
= mVarCheckHiiList
.ForwardLink
1531 ; HiiVariableLink
!= &mVarCheckHiiList
1532 ; HiiVariableLink
= HiiVariableLink
->ForwardLink
)
1535 // For Hii Variable header align.
1537 BinSize
= (UINT32
)HEADER_ALIGN (BinSize
);
1539 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1540 HiiVariableLength
= HiiVariableNode
->HiiVariable
->HeaderLength
;
1542 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
)8; Index
++) {
1543 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1545 // For Hii Question header align.
1547 HiiVariableLength
= (UINT32
)HEADER_ALIGN (HiiVariableLength
);
1548 HiiVariableLength
+= HiiVariableNode
->HiiQuestionArray
[Index
]->Length
;
1552 HiiVariableNode
->HiiVariable
->Length
= HiiVariableLength
;
1553 BinSize
+= HiiVariableLength
;
1556 DEBUG ((DEBUG_INFO
, "VarCheckHiiBin - size = 0x%x\n", BinSize
));
1563 // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation.
1564 // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
1565 // in SetVariable check handler.
1567 Data
= AllocateRuntimeZeroPool (BinSize
);
1568 ASSERT (Data
!= NULL
);
1570 // Make sure the allocated buffer for VarCheckHiiBin at required alignment.
1572 ASSERT ((((UINTN
)Data
) & (HEADER_ALIGNMENT
- 1)) == 0);
1573 DEBUG ((DEBUG_INFO
, "VarCheckHiiBin - built at 0x%x\n", Data
));
1579 for (HiiVariableLink
= mVarCheckHiiList
.ForwardLink
1580 ; HiiVariableLink
!= &mVarCheckHiiList
1581 ; HiiVariableLink
= HiiVariableLink
->ForwardLink
)
1584 // For Hii Variable header align.
1586 Ptr
= (UINT8
*)HEADER_ALIGN (Ptr
);
1588 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1589 CopyMem (Ptr
, HiiVariableNode
->HiiVariable
, HiiVariableNode
->HiiVariable
->HeaderLength
);
1590 Ptr
+= HiiVariableNode
->HiiVariable
->HeaderLength
;
1592 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
)8; Index
++) {
1593 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1595 // For Hii Question header align.
1597 Ptr
= (UINT8
*)HEADER_ALIGN (Ptr
);
1598 CopyMem (Ptr
, HiiVariableNode
->HiiQuestionArray
[Index
], HiiVariableNode
->HiiQuestionArray
[Index
]->Length
);
1599 Ptr
+= HiiVariableNode
->HiiQuestionArray
[Index
]->Length
;
1609 Generate VarCheckHiiBin from Hii Database and FV.
1618 VarCheckHiiGenFromHiiDatabase ();
1619 VarCheckHiiGenFromFv ();
1621 mVarCheckHiiBin
= BuildVarCheckHiiBin (&mVarCheckHiiBinSize
);
1622 if (mVarCheckHiiBin
== NULL
) {
1623 DEBUG ((DEBUG_INFO
, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
1627 DestroyHiiVariableNode ();
1628 if (mVarName
!= NULL
) {
1629 InternalVarCheckFreePool (mVarName
);
1632 #ifdef DUMP_VAR_CHECK_HII
1634 DumpVarCheckHii (mVarCheckHiiBin
, mVarCheckHiiBinSize
);