2 Var Check Hii bin generation.
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "VarCheckHiiGen.h"
17 LIST_ENTRY mVarCheckHiiList
= INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList
);
19 #define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V')
24 VAR_CHECK_HII_VARIABLE_HEADER
*HiiVariable
;
25 EFI_VARSTORE_ID VarStoreId
;
27 VAR_CHECK_HII_QUESTION_HEADER
**HiiQuestionArray
;
28 } VAR_CHECK_HII_VARIABLE_NODE
;
30 #define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE)
32 CHAR16
*mVarName
= NULL
;
33 UINTN mMaxVarNameSize
= 0;
36 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mIfrOpCodeStringTable
[] = {
37 {EFI_IFR_VARSTORE_OP
, "EFI_IFR_VARSTORE_OP"},
38 {EFI_IFR_VARSTORE_EFI_OP
, "EFI_IFR_VARSTORE_EFI_OP"},
39 {EFI_IFR_ONE_OF_OP
, "EFI_IFR_ONE_OF_OP"},
40 {EFI_IFR_CHECKBOX_OP
, "EFI_IFR_CHECKBOX_OP"},
41 {EFI_IFR_NUMERIC_OP
, "EFI_IFR_NUMERIC_OP"},
42 {EFI_IFR_ORDERED_LIST_OP
, "EFI_IFR_ORDERED_LIST_OP"},
43 {EFI_IFR_ONE_OF_OPTION_OP
, "EFI_IFR_ONE_OF_OPTION_OP"},
49 @param[in] IfrOpCode Ifr OpCode.
51 @return Pointer to string.
60 for (Index
= 0; Index
< ARRAY_SIZE (mIfrOpCodeStringTable
); Index
++) {
61 if (mIfrOpCodeStringTable
[Index
].HiiOpCode
== IfrOpCode
) {
62 return mIfrOpCodeStringTable
[Index
].HiiOpCodeStr
;
66 return "<UnknownIfrOpCode>";
69 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_PACKAGE_TYPE_STRING mPackageTypeStringTable
[] = {
70 {EFI_HII_PACKAGE_TYPE_ALL
, "EFI_HII_PACKAGE_TYPE_ALL"},
71 {EFI_HII_PACKAGE_TYPE_GUID
, "EFI_HII_PACKAGE_TYPE_GUID"},
72 {EFI_HII_PACKAGE_FORMS
, "EFI_HII_PACKAGE_FORMS"},
73 {EFI_HII_PACKAGE_STRINGS
, "EFI_HII_PACKAGE_STRINGS"},
74 {EFI_HII_PACKAGE_FONTS
, "EFI_HII_PACKAGE_FONTS"},
75 {EFI_HII_PACKAGE_IMAGES
, "EFI_HII_PACKAGE_IMAGES"},
76 {EFI_HII_PACKAGE_SIMPLE_FONTS
, "EFI_HII_PACKAGE_SIMPLE_FONTS"},
77 {EFI_HII_PACKAGE_DEVICE_PATH
, "EFI_HII_PACKAGE_DEVICE_PATH"},
78 {EFI_HII_PACKAGE_KEYBOARD_LAYOUT
, "EFI_HII_PACKAGE_KEYBOARD_LAYOUT"},
79 {EFI_HII_PACKAGE_ANIMATIONS
, "EFI_HII_PACKAGE_ANIMATIONS"},
80 {EFI_HII_PACKAGE_END
, "EFI_HII_PACKAGE_END"},
81 {EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN
, "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN"},
82 {EFI_HII_PACKAGE_TYPE_SYSTEM_END
, "EFI_HII_PACKAGE_TYPE_SYSTEM_END"},
86 Hii Package type to string.
88 @param[in] PackageType Package Type
90 @return Pointer to string.
99 for (Index
= 0; Index
< ARRAY_SIZE (mPackageTypeStringTable
); Index
++) {
100 if (mPackageTypeStringTable
[Index
].PackageType
== PackageType
) {
101 return mPackageTypeStringTable
[Index
].PackageTypeStr
;
105 return "<UnknownPackageType>";
111 @param[in] HiiPackage Pointer to Hii Package.
119 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
120 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
121 EFI_IFR_VARSTORE
*IfrVarStore
;
122 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
123 BOOLEAN QuestionStoredInBitField
;
125 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) HiiPackage
;
126 QuestionStoredInBitField
= FALSE
;
128 DEBUG ((DEBUG_INFO
, " HiiPackageHeader->Type - 0x%02x (%a)\n", HiiPackageHeader
->Type
, HiiPackageTypeToStr ((UINT8
) HiiPackageHeader
->Type
)));
129 DEBUG ((DEBUG_INFO
, " HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader
->Length
));
131 switch (HiiPackageHeader
->Type
) {
132 case EFI_HII_PACKAGE_FORMS
:
133 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) (HiiPackageHeader
+ 1);
135 while ((UINTN
) IfrOpCodeHeader
< ((UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
)) {
136 switch (IfrOpCodeHeader
->OpCode
) {
137 case EFI_IFR_VARSTORE_OP
:
138 IfrVarStore
= (EFI_IFR_VARSTORE
*) IfrOpCodeHeader
;
139 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
140 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
141 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
142 DEBUG ((DEBUG_INFO
, " Guid - %g\n", &IfrVarStore
->Guid
));
143 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", IfrVarStore
->VarStoreId
));
144 DEBUG ((DEBUG_INFO
, " Size - 0x%04x\n", IfrVarStore
->Size
));
145 DEBUG ((DEBUG_INFO
, " Name - %a\n", IfrVarStore
->Name
));
148 case EFI_IFR_VARSTORE_EFI_OP
:
149 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*) IfrOpCodeHeader
;
150 if (IfrEfiVarStore
->Header
.Length
>= sizeof (EFI_IFR_VARSTORE_EFI
)) {
151 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
)));
152 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
153 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
154 DEBUG ((DEBUG_INFO
, " Guid - %g\n", &IfrEfiVarStore
->Guid
));
155 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", IfrEfiVarStore
->VarStoreId
));
156 DEBUG ((DEBUG_INFO
, " Size - 0x%04x\n", IfrEfiVarStore
->Size
));
157 DEBUG ((DEBUG_INFO
, " Attributes - 0x%08x\n", IfrEfiVarStore
->Attributes
));
158 DEBUG ((DEBUG_INFO
, " Name - %a\n", IfrEfiVarStore
->Name
));
162 case EFI_IFR_GUID_OP
:
163 if (CompareGuid ((EFI_GUID
*)((UINTN
)IfrOpCodeHeader
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
164 QuestionStoredInBitField
= TRUE
;
168 case EFI_IFR_ONE_OF_OP
:
169 case EFI_IFR_CHECKBOX_OP
:
170 case EFI_IFR_NUMERIC_OP
:
171 case EFI_IFR_ORDERED_LIST_OP
:
172 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader
->OpCode
, IfrOpCodeToStr (IfrOpCodeHeader
->OpCode
), (QuestionStoredInBitField
? "bit level": "byte level")));
173 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader
->Length
));
174 DEBUG ((DEBUG_INFO
, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader
->Scope
));
175 DEBUG ((DEBUG_INFO
, " Prompt - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Prompt
));
176 DEBUG ((DEBUG_INFO
, " Help - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Help
));
177 DEBUG ((DEBUG_INFO
, " QuestionId - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.QuestionId
));
178 DEBUG ((DEBUG_INFO
, " VarStoreId - 0x%04x\n", ((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.VarStoreId
));
179 DEBUG ((DEBUG_INFO
, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF
* )IfrOpCodeHeader
)->Question
.VarStoreInfo
.VarOffset
, (QuestionStoredInBitField
? "bit level": "byte level")));
181 EFI_IFR_ONE_OF
*IfrOneOf
;
182 EFI_IFR_CHECKBOX
*IfrCheckBox
;
183 EFI_IFR_NUMERIC
*IfrNumeric
;
184 EFI_IFR_ORDERED_LIST
*IfrOrderedList
;
186 switch (IfrOpCodeHeader
->OpCode
) {
187 case EFI_IFR_ONE_OF_OP
:
188 IfrOneOf
= (EFI_IFR_ONE_OF
*) IfrOpCodeHeader
;
189 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrOneOf
->Flags
));
190 if (QuestionStoredInBitField
) {
192 // For OneOf stored in bit field, the option value are saved as UINT32 type.
194 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrOneOf
->data
.u32
.MinValue
));
195 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrOneOf
->data
.u32
.MaxValue
));
196 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrOneOf
->data
.u32
.Step
));
198 switch (IfrOneOf
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
199 case EFI_IFR_NUMERIC_SIZE_1
:
200 DEBUG ((DEBUG_INFO
, " MinValue - 0x%02x\n", IfrOneOf
->data
.u8
.MinValue
));
201 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%02x\n", IfrOneOf
->data
.u8
.MaxValue
));
202 DEBUG ((DEBUG_INFO
, " Step - 0x%02x\n", IfrOneOf
->data
.u8
.Step
));
204 case EFI_IFR_NUMERIC_SIZE_2
:
205 DEBUG ((DEBUG_INFO
, " MinValue - 0x%04x\n", IfrOneOf
->data
.u16
.MinValue
));
206 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%04x\n", IfrOneOf
->data
.u16
.MaxValue
));
207 DEBUG ((DEBUG_INFO
, " Step - 0x%04x\n", IfrOneOf
->data
.u16
.Step
));
209 case EFI_IFR_NUMERIC_SIZE_4
:
210 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrOneOf
->data
.u32
.MinValue
));
211 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrOneOf
->data
.u32
.MaxValue
));
212 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrOneOf
->data
.u32
.Step
));
214 case EFI_IFR_NUMERIC_SIZE_8
:
215 DEBUG ((DEBUG_INFO
, " MinValue - 0x%016lx\n", IfrOneOf
->data
.u64
.MinValue
));
216 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%016lx\n", IfrOneOf
->data
.u64
.MaxValue
));
217 DEBUG ((DEBUG_INFO
, " Step - 0x%016lx\n", IfrOneOf
->data
.u64
.Step
));
222 case EFI_IFR_CHECKBOX_OP
:
223 IfrCheckBox
= (EFI_IFR_CHECKBOX
*) IfrOpCodeHeader
;
224 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrCheckBox
->Flags
));
226 case EFI_IFR_NUMERIC_OP
:
227 IfrNumeric
= (EFI_IFR_NUMERIC
*) IfrOpCodeHeader
;
228 DEBUG ((DEBUG_INFO
, " Flags - 0x%02x\n", IfrNumeric
->Flags
));
229 if (QuestionStoredInBitField
) {
231 // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type.
233 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrNumeric
->data
.u32
.MinValue
));
234 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrNumeric
->data
.u32
.MaxValue
));
235 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrNumeric
->data
.u32
.Step
));
237 switch (IfrNumeric
->Flags
& EFI_IFR_NUMERIC_SIZE
) {
238 case EFI_IFR_NUMERIC_SIZE_1
:
239 DEBUG ((DEBUG_INFO
, " MinValue - 0x%02x\n", IfrNumeric
->data
.u8
.MinValue
));
240 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%02x\n", IfrNumeric
->data
.u8
.MaxValue
));
241 DEBUG ((DEBUG_INFO
, " Step - 0x%02x\n", IfrNumeric
->data
.u8
.Step
));
243 case EFI_IFR_NUMERIC_SIZE_2
:
244 DEBUG ((DEBUG_INFO
, " MinValue - 0x%04x\n", IfrNumeric
->data
.u16
.MinValue
));
245 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%04x\n", IfrNumeric
->data
.u16
.MaxValue
));
246 DEBUG ((DEBUG_INFO
, " Step - 0x%04x\n", IfrNumeric
->data
.u16
.Step
));
248 case EFI_IFR_NUMERIC_SIZE_4
:
249 DEBUG ((DEBUG_INFO
, " MinValue - 0x%08x\n", IfrNumeric
->data
.u32
.MinValue
));
250 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%08x\n", IfrNumeric
->data
.u32
.MaxValue
));
251 DEBUG ((DEBUG_INFO
, " Step - 0x%08x\n", IfrNumeric
->data
.u32
.Step
));
253 case EFI_IFR_NUMERIC_SIZE_8
:
254 DEBUG ((DEBUG_INFO
, " MinValue - 0x%016lx\n", IfrNumeric
->data
.u64
.MinValue
));
255 DEBUG ((DEBUG_INFO
, " MaxValue - 0x%016lx\n", IfrNumeric
->data
.u64
.MaxValue
));
256 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
));
307 if (IfrOpCodeHeader
->OpCode
== EFI_IFR_END_OP
) {
308 QuestionStoredInBitField
= FALSE
;
314 } else if (IfrOpCodeHeader
->Scope
!= 0) {
317 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
324 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
335 @param[in] HiiDatabase Pointer to Hii Database.
336 @param[in] HiiDatabaseSize Hii Database size.
341 IN VOID
*HiiDatabase
,
342 IN UINTN HiiDatabaseSize
345 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageListHeader
;
346 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
348 DEBUG ((DEBUG_INFO
, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize
));
349 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) HiiDatabase
;
351 while ((UINTN
) HiiPackageListHeader
< ((UINTN
) HiiDatabase
+ HiiDatabaseSize
)) {
352 DEBUG ((DEBUG_INFO
, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader
->PackageListGuid
));
353 DEBUG ((DEBUG_INFO
, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN
)HiiPackageListHeader
->PackageLength
));
354 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*)(HiiPackageListHeader
+ 1);
356 while ((UINTN
) HiiPackageHeader
< (UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
) {
358 DumpHiiPackage (HiiPackageHeader
);
360 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) ((UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
);
363 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) ((UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
);
371 Allocates a buffer of a certain pool type.
373 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
374 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
375 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
377 @param MemoryType The type of memory to allocate.
378 @param AllocationSize The number of bytes to allocate.
380 @return A pointer to the allocated buffer or NULL if allocation fails.
384 InternalVarCheckAllocatePool (
385 IN EFI_MEMORY_TYPE MemoryType
,
386 IN UINTN AllocationSize
392 Status
= gBS
->AllocatePool (MemoryType
, AllocationSize
, &Memory
);
393 if (EFI_ERROR (Status
)) {
400 Allocates and zeros a buffer of type EfiBootServicesData.
402 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
403 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
404 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
405 request, then NULL is returned.
407 @param AllocationSize The number of bytes to allocate and zero.
409 @return A pointer to the allocated buffer or NULL if allocation fails.
413 InternalVarCheckAllocateZeroPool (
414 IN UINTN AllocationSize
419 Memory
= InternalVarCheckAllocatePool (EfiBootServicesData
, AllocationSize
);
420 if (Memory
!= NULL
) {
421 Memory
= ZeroMem (Memory
, AllocationSize
);
427 Frees a buffer that was previously allocated with one of the pool allocation functions in the
428 Memory Allocation Library.
430 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
431 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
432 resources, then this function will perform no actions.
434 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
437 @param Buffer The pointer to the buffer to free.
442 InternalVarCheckFreePool (
448 Status
= gBS
->FreePool (Buffer
);
449 ASSERT_EFI_ERROR (Status
);
453 Reallocates a buffer of type EfiBootServicesData.
455 Allocates and zeros the number bytes specified by NewSize from memory of type
456 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
457 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
458 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
459 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
460 enough memory remaining to satisfy the request, then NULL is returned.
462 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
463 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
465 @param OldSize The size, in bytes, of OldBuffer.
466 @param NewSize The size, in bytes, of the buffer to reallocate.
467 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
468 parameter that may be NULL.
470 @return A pointer to the allocated buffer or NULL if allocation fails.
474 InternalVarCheckReallocatePool (
477 IN VOID
*OldBuffer OPTIONAL
482 NewBuffer
= InternalVarCheckAllocateZeroPool (NewSize
);
483 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
484 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
485 InternalVarCheckFreePool (OldBuffer
);
493 @param[in, out] HiiVariableNode Pointer to Hii Variable node.
494 @param[in] HiiQuestion Pointer to Hii Question.
495 @param[in] FromFv Hii Question from FV.
500 IN OUT VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
,
501 IN VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion
,
505 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion1
;
506 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion2
;
507 VAR_CHECK_HII_QUESTION_HEADER
*NewHiiQuestion
;
521 // Hii Question from Hii Database has high priority.
522 // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
525 InternalVarCheckFreePool (HiiQuestion
);
529 if (HiiQuestion
->BitFieldStore
) {
530 ArrayIndex
= HiiQuestion
->VarOffset
;
532 ArrayIndex
= HiiQuestion
->VarOffset
* 8;
535 HiiQuestion1
= HiiVariableNode
->HiiQuestionArray
[ArrayIndex
];
536 HiiQuestion2
= HiiQuestion
;
538 ASSERT ((HiiQuestion1
->OpCode
== HiiQuestion2
->OpCode
) && (HiiQuestion1
->StorageWidth
== HiiQuestion2
->StorageWidth
));
540 switch (HiiQuestion1
->OpCode
) {
541 case EFI_IFR_ONE_OF_OP
:
542 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level": "byte level")));
544 // Get the length of Hii Question 1.
546 NewLength
= HiiQuestion1
->Length
;
549 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
551 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion2
+ 1);
552 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
554 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
556 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion1
+ 1);
557 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
559 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
560 if (OneValue2
== OneValue1
) {
566 Ptr1
+= HiiQuestion1
->StorageWidth
;
568 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
572 NewLength
= (UINT8
) (NewLength
+ HiiQuestion1
->StorageWidth
);
574 Ptr2
+= HiiQuestion2
->StorageWidth
;
577 if (NewLength
> HiiQuestion1
->Length
) {
579 // Merge the one of options of Hii Question 2 and Hii Question 1.
581 NewHiiQuestion
= InternalVarCheckAllocateZeroPool (NewLength
);
582 ASSERT (NewHiiQuestion
!= NULL
);
583 CopyMem (NewHiiQuestion
, HiiQuestion1
, HiiQuestion1
->Length
);
585 // Use the new length.
587 NewHiiQuestion
->Length
= NewLength
;
588 Ptr
= (UINT8
*) NewHiiQuestion
+ HiiQuestion1
->Length
;
590 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion2
+ 1);
591 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
593 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
595 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ONEOF
*) HiiQuestion1
+ 1);
596 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
598 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
599 if (OneValue2
== OneValue1
) {
605 Ptr1
+= HiiQuestion1
->StorageWidth
;
607 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
611 CopyMem (Ptr
, &OneValue2
, HiiQuestion1
->StorageWidth
);
612 Ptr
+= HiiQuestion1
->StorageWidth
;
614 Ptr2
+= HiiQuestion2
->StorageWidth
;
617 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = NewHiiQuestion
;
618 InternalVarCheckFreePool (HiiQuestion1
);
622 case EFI_IFR_CHECKBOX_OP
:
623 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level": "byte level")));
626 case EFI_IFR_NUMERIC_OP
:
627 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1
->VarOffset
, (HiiQuestion1
->BitFieldStore
? "bit level": "byte level")));
629 // Get minimum and maximum of Hii Question 1.
633 Ptr
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_NUMERIC
*) HiiQuestion1
+ 1);
634 CopyMem (&Minimum1
, Ptr
, HiiQuestion1
->StorageWidth
);
635 Ptr
+= HiiQuestion1
->StorageWidth
;
636 CopyMem (&Maximum1
, Ptr
, HiiQuestion1
->StorageWidth
);
639 // Get minimum and maximum of Hii Question 2.
643 Ptr
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_NUMERIC
*) HiiQuestion2
+ 1);
644 CopyMem (&Minimum2
, Ptr
, HiiQuestion2
->StorageWidth
);
645 Ptr
+= HiiQuestion2
->StorageWidth
;
646 CopyMem (&Maximum2
, Ptr
, HiiQuestion2
->StorageWidth
);
651 Ptr
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_NUMERIC
*) HiiQuestion1
+ 1);
652 if (Minimum2
< Minimum1
) {
654 CopyMem (Ptr
, &Minimum1
, HiiQuestion1
->StorageWidth
);
659 Ptr
+= HiiQuestion1
->StorageWidth
;
660 if (Maximum2
> Maximum1
) {
662 CopyMem (Ptr
, &Maximum1
, HiiQuestion1
->StorageWidth
);
666 case EFI_IFR_ORDERED_LIST_OP
:
667 DEBUG ((DEBUG_INFO
, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1
->VarOffset
));
669 // Get the length of Hii Question 1.
671 NewLength
= HiiQuestion1
->Length
;
674 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
676 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion2
+ 1);
677 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
679 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
681 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion1
+ 1);
682 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
684 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
685 if (OneValue2
== OneValue1
) {
691 Ptr1
+= HiiQuestion1
->StorageWidth
;
693 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
697 NewLength
= (UINT8
) (NewLength
+ HiiQuestion1
->StorageWidth
);
699 Ptr2
+= HiiQuestion2
->StorageWidth
;
702 if (NewLength
> HiiQuestion1
->Length
) {
704 // Merge the one of options of Hii Question 2 and Hii Question 1.
706 NewHiiQuestion
= InternalVarCheckAllocateZeroPool (NewLength
);
707 ASSERT (NewHiiQuestion
!= NULL
);
708 CopyMem (NewHiiQuestion
, HiiQuestion1
, HiiQuestion1
->Length
);
710 // Use the new length.
712 NewHiiQuestion
->Length
= NewLength
;
713 Ptr
= (UINT8
*) NewHiiQuestion
+ HiiQuestion1
->Length
;
715 Ptr2
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion2
+ 1);
716 while ((UINTN
) Ptr2
< (UINTN
) HiiQuestion2
+ HiiQuestion2
->Length
) {
718 CopyMem (&OneValue2
, Ptr2
, HiiQuestion2
->StorageWidth
);
720 Ptr1
= (UINT8
*) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST
*) HiiQuestion1
+ 1);
721 while ((UINTN
) Ptr1
< (UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
) {
723 CopyMem (&OneValue1
, Ptr1
, HiiQuestion1
->StorageWidth
);
724 if (OneValue2
== OneValue1
) {
730 Ptr1
+= HiiQuestion1
->StorageWidth
;
732 if ((UINTN
) Ptr1
>= ((UINTN
) HiiQuestion1
+ HiiQuestion1
->Length
)) {
736 CopyMem (Ptr
, &OneValue2
, HiiQuestion1
->StorageWidth
);
737 Ptr
+= HiiQuestion1
->StorageWidth
;
739 Ptr2
+= HiiQuestion2
->StorageWidth
;
742 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = NewHiiQuestion
;
743 InternalVarCheckFreePool (HiiQuestion1
);
755 // Hii Question 2 has been merged with Hii Question 1.
757 InternalVarCheckFreePool (HiiQuestion2
);
761 Get OneOf option data.
763 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
764 @param[out] Count Pointer to option count.
765 @param[out] Width Pointer to option width.
766 @param[out] OptionBuffer Pointer to option buffer.
771 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
774 OUT VOID
*OptionBuffer OPTIONAL
778 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
781 // Assume all OPTION has same Width.
785 if (IfrOpCodeHeader
->Scope
!= 0) {
790 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
792 switch (IfrOpCodeHeader
->OpCode
) {
793 case EFI_IFR_ONE_OF_OPTION_OP
:
794 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*) IfrOpCodeHeader
;
795 switch (IfrOneOfOption
->Type
) {
796 case EFI_IFR_TYPE_NUM_SIZE_8
:
798 *Width
= sizeof (UINT8
);
799 if (OptionBuffer
!= NULL
) {
800 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u8
, sizeof (UINT8
));
801 OptionBuffer
= (UINT8
*) OptionBuffer
+ 1;
804 case EFI_IFR_TYPE_NUM_SIZE_16
:
806 *Width
= sizeof (UINT16
);
807 if (OptionBuffer
!= NULL
) {
808 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u16
, sizeof (UINT16
));
809 OptionBuffer
= (UINT16
*) OptionBuffer
+ 1;
812 case EFI_IFR_TYPE_NUM_SIZE_32
:
814 *Width
= sizeof (UINT32
);
815 if (OptionBuffer
!= NULL
) {
816 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u32
, sizeof (UINT32
));
817 OptionBuffer
= (UINT32
*) OptionBuffer
+ 1;
820 case EFI_IFR_TYPE_NUM_SIZE_64
:
822 *Width
= sizeof (UINT64
);
823 if (OptionBuffer
!= NULL
) {
824 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.u64
, sizeof (UINT64
));
825 OptionBuffer
= (UINT64
*) OptionBuffer
+ 1;
828 case EFI_IFR_TYPE_BOOLEAN
:
830 *Width
= sizeof (BOOLEAN
);
831 if (OptionBuffer
!= NULL
) {
832 CopyMem (OptionBuffer
, &IfrOneOfOption
->Value
.b
, sizeof (BOOLEAN
));
833 OptionBuffer
= (BOOLEAN
*) OptionBuffer
+ 1;
845 if (IfrOpCodeHeader
->OpCode
== EFI_IFR_END_OP
) {
851 } else if (IfrOpCodeHeader
->Scope
!= 0) {
857 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
865 Parse Hii Question Oneof.
867 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
868 @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage.
870 return Pointer to Hii Question.
873 VAR_CHECK_HII_QUESTION_HEADER
*
874 ParseHiiQuestionOneOf (
875 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
876 IN BOOLEAN StoredInBitField
879 EFI_IFR_ONE_OF
*IfrOneOf
;
880 VAR_CHECK_HII_QUESTION_ONEOF
*OneOf
;
887 IfrOneOf
= (EFI_IFR_ONE_OF
*) IfrOpCodeHeader
;
890 if (StoredInBitField
) {
892 // When OneOf stored in bit field, the bit width is saved in the lower six bits of the flag.
893 // And the options in the OneOf is saved as UINT32 type.
895 BitWidth
= IfrOneOf
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
896 Width
= sizeof (UINT32
);
898 Width
= (UINT8
) (1 << (IfrOneOf
->Flags
& EFI_IFR_NUMERIC_SIZE
));
901 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, NULL
);
902 ASSERT (Width
== OptionWidth
);
904 Length
= sizeof (*OneOf
) + OptionCount
* Width
;
906 OneOf
= InternalVarCheckAllocateZeroPool (Length
);
907 ASSERT (OneOf
!= NULL
);
908 OneOf
->OpCode
= EFI_IFR_ONE_OF_OP
;
909 OneOf
->Length
= (UINT8
) Length
;
910 OneOf
->VarOffset
= IfrOneOf
->Question
.VarStoreInfo
.VarOffset
;
911 OneOf
->BitFieldStore
= StoredInBitField
;
912 if (StoredInBitField
) {
913 OneOf
->StorageWidth
= BitWidth
;
915 OneOf
->StorageWidth
= Width
;
918 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, OneOf
+ 1);
920 return (VAR_CHECK_HII_QUESTION_HEADER
*) OneOf
;
924 Parse Hii Question CheckBox.
926 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
927 @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage.
929 return Pointer to Hii Question.
932 VAR_CHECK_HII_QUESTION_HEADER
*
933 ParseHiiQuestionCheckBox (
934 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
935 IN BOOLEAN StoredInBitField
938 EFI_IFR_CHECKBOX
*IfrCheckBox
;
939 VAR_CHECK_HII_QUESTION_CHECKBOX
*CheckBox
;
941 IfrCheckBox
= (EFI_IFR_CHECKBOX
*) IfrOpCodeHeader
;
943 CheckBox
= InternalVarCheckAllocateZeroPool (sizeof (*CheckBox
));
944 ASSERT (CheckBox
!= NULL
);
945 CheckBox
->OpCode
= EFI_IFR_CHECKBOX_OP
;
946 CheckBox
->Length
= (UINT8
) sizeof (*CheckBox
);;
947 CheckBox
->VarOffset
= IfrCheckBox
->Question
.VarStoreInfo
.VarOffset
;
948 CheckBox
->BitFieldStore
= StoredInBitField
;
949 if (StoredInBitField
) {
950 CheckBox
->StorageWidth
= 1;
952 CheckBox
->StorageWidth
= (UINT8
) sizeof (BOOLEAN
);
955 return (VAR_CHECK_HII_QUESTION_HEADER
*) CheckBox
;
959 Parse Hii Question Numeric.
961 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
962 @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage.
964 return Pointer to Hii Question.
967 VAR_CHECK_HII_QUESTION_HEADER
*
968 ParseHiiQuestionNumeric (
969 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
970 IN BOOLEAN StoredInBitField
973 EFI_IFR_NUMERIC
*IfrNumeric
;
974 VAR_CHECK_HII_QUESTION_NUMERIC
*Numeric
;
978 IfrNumeric
= (EFI_IFR_NUMERIC
*) IfrOpCodeHeader
;
981 Numeric
= InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC
) + 2 * sizeof (UINT64
));
982 ASSERT (Numeric
!= NULL
);
984 if (StoredInBitField
) {
986 // When Numeric stored in bit field, the bit field width is saved in the lower six bits of the flag.
987 // And the Minimum Maximum of Numeric is saved as UINT32 type.
989 BitWidth
= IfrNumeric
->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
;
990 Width
= sizeof (UINT32
);
992 Width
= (UINT8
) (1 << (IfrNumeric
->Flags
& EFI_IFR_NUMERIC_SIZE
));
995 Numeric
->OpCode
= EFI_IFR_NUMERIC_OP
;
996 Numeric
->Length
= (UINT8
) (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC
) + 2 * Width
);
997 Numeric
->VarOffset
= IfrNumeric
->Question
.VarStoreInfo
.VarOffset
;
998 Numeric
->BitFieldStore
= StoredInBitField
;
999 if (StoredInBitField
) {
1000 Numeric
->StorageWidth
= BitWidth
;
1002 Numeric
->StorageWidth
= Width
;
1005 CopyMem (Numeric
+ 1, &IfrNumeric
->data
, Width
* 2);
1007 return (VAR_CHECK_HII_QUESTION_HEADER
*) Numeric
;
1011 Parse Hii Question OrderedList.
1013 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1015 return Pointer to Hii Question.
1018 VAR_CHECK_HII_QUESTION_HEADER
*
1019 ParseHiiQuestionOrderedList (
1020 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
1023 EFI_IFR_ORDERED_LIST
*IfrOrderedList
;
1024 VAR_CHECK_HII_QUESTION_ORDEREDLIST
*OrderedList
;
1029 IfrOrderedList
= (EFI_IFR_ORDERED_LIST
*) IfrOpCodeHeader
;
1031 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, NULL
);
1033 Length
= sizeof (*OrderedList
) + OptionCount
* OptionWidth
;
1035 OrderedList
= InternalVarCheckAllocateZeroPool (Length
);
1036 ASSERT (OrderedList
!= NULL
);
1037 OrderedList
->OpCode
= EFI_IFR_ORDERED_LIST_OP
;
1038 OrderedList
->Length
= (UINT8
) Length
;
1039 OrderedList
->VarOffset
= IfrOrderedList
->Question
.VarStoreInfo
.VarOffset
;
1040 OrderedList
->StorageWidth
= OptionWidth
;
1041 OrderedList
->MaxContainers
= IfrOrderedList
->MaxContainers
;
1042 OrderedList
->BitFieldStore
= FALSE
;
1044 GetOneOfOption (IfrOpCodeHeader
, &OptionCount
, &OptionWidth
, OrderedList
+ 1);
1046 return (VAR_CHECK_HII_QUESTION_HEADER
*) OrderedList
;
1050 Parse and create Hii Question node.
1052 @param[in] HiiVariableNode Pointer to Hii Variable node.
1053 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1054 @param[in] FromFv Hii Question from FV.
1055 @param[in] StoredInBitField Whether the Question is stored in bit field Storage.
1060 IN VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
,
1061 IN EFI_IFR_OP_HEADER
*IfrOpCodeHeader
,
1063 IN BOOLEAN StoredInBitField
1066 VAR_CHECK_HII_QUESTION_HEADER
*HiiQuestion
;
1070 // Currently only OneOf, CheckBox and Numeric can be stored in bit field.
1072 switch (IfrOpCodeHeader
->OpCode
) {
1073 case EFI_IFR_ONE_OF_OP
:
1074 HiiQuestion
= ParseHiiQuestionOneOf (IfrOpCodeHeader
, StoredInBitField
);
1077 case EFI_IFR_CHECKBOX_OP
:
1078 HiiQuestion
= ParseHiiQuestionCheckBox (IfrOpCodeHeader
, StoredInBitField
);
1081 case EFI_IFR_NUMERIC_OP
:
1082 HiiQuestion
= ParseHiiQuestionNumeric (IfrOpCodeHeader
, StoredInBitField
);
1085 case EFI_IFR_ORDERED_LIST_OP
:
1086 HiiQuestion
= ParseHiiQuestionOrderedList (IfrOpCodeHeader
);
1095 if (StoredInBitField
) {
1096 ArrayIndex
= HiiQuestion
->VarOffset
;
1098 ArrayIndex
= HiiQuestion
->VarOffset
* 8;
1100 if (HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] != NULL
) {
1101 MergeHiiQuestion (HiiVariableNode
, HiiQuestion
, FromFv
);
1103 HiiVariableNode
->HiiQuestionArray
[ArrayIndex
] = HiiQuestion
;
1108 Find Hii variable node by name and GUID.
1110 @param[in] Name Pointer to variable name.
1111 @param[in] Guid Pointer to vendor GUID.
1113 @return Pointer to Hii Variable node.
1116 VAR_CHECK_HII_VARIABLE_NODE
*
1117 FindHiiVariableNode (
1122 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1125 for (Link
= mVarCheckHiiList
.ForwardLink
1126 ;Link
!= &mVarCheckHiiList
1127 ;Link
= Link
->ForwardLink
) {
1128 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1130 if ((StrCmp (Name
, (CHAR16
*) (HiiVariableNode
->HiiVariable
+ 1)) == 0) &&
1131 CompareGuid (Guid
, &HiiVariableNode
->HiiVariable
->Guid
)) {
1132 return HiiVariableNode
;
1140 Find Hii variable node by var store id.
1142 @param[in] VarStoreId Var store id.
1144 @return Pointer to Hii Variable node.
1147 VAR_CHECK_HII_VARIABLE_NODE
*
1148 FindHiiVariableNodeByVarStoreId (
1149 IN EFI_VARSTORE_ID VarStoreId
1152 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1155 if (VarStoreId
== 0) {
1157 // The variable store identifier, which is unique within the current form set.
1158 // A value of zero is invalid.
1163 for (Link
= mVarCheckHiiList
.ForwardLink
1164 ;Link
!= &mVarCheckHiiList
1165 ;Link
= Link
->ForwardLink
) {
1166 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1168 // The variable store identifier, which is unique within the current form set.
1170 if (VarStoreId
== HiiVariableNode
->VarStoreId
) {
1171 return HiiVariableNode
;
1179 Destroy var store id in the Hii Variable node after parsing one Hii Package.
1187 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1190 for (Link
= mVarCheckHiiList
.ForwardLink
1191 ;Link
!= &mVarCheckHiiList
1192 ;Link
= Link
->ForwardLink
) {
1193 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (Link
);
1195 // The variable store identifier, which is unique within the current form set.
1196 // A value of zero is invalid.
1198 HiiVariableNode
->VarStoreId
= 0;
1203 Create Hii Variable node.
1205 @param[in] IfrEfiVarStore Pointer to EFI VARSTORE.
1209 CreateHiiVariableNode (
1210 IN EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
1213 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1214 VAR_CHECK_HII_VARIABLE_HEADER
*HiiVariable
;
1220 // Get variable name.
1222 VarNameSize
= AsciiStrSize ((CHAR8
*) IfrEfiVarStore
->Name
) * sizeof (CHAR16
);
1223 if (VarNameSize
> mMaxVarNameSize
) {
1224 mVarName
= InternalVarCheckReallocatePool (mMaxVarNameSize
, VarNameSize
, mVarName
);
1225 ASSERT (mVarName
!= NULL
);
1226 mMaxVarNameSize
= VarNameSize
;
1228 AsciiStrToUnicodeStrS ((CHAR8
*) IfrEfiVarStore
->Name
, mVarName
, mMaxVarNameSize
/ sizeof (CHAR16
));
1231 HiiVariableNode
= FindHiiVariableNode (
1233 &IfrEfiVarStore
->Guid
1235 if (HiiVariableNode
== NULL
) {
1237 // Not found, then create new.
1239 HeaderLength
= sizeof (*HiiVariable
) + VarNameSize
;
1240 HiiVariable
= InternalVarCheckAllocateZeroPool (HeaderLength
);
1241 ASSERT (HiiVariable
!= NULL
);
1242 HiiVariable
->Revision
= VAR_CHECK_HII_REVISION
;
1243 HiiVariable
->OpCode
= EFI_IFR_VARSTORE_EFI_OP
;
1244 HiiVariable
->HeaderLength
= (UINT16
) HeaderLength
;
1245 HiiVariable
->Size
= IfrEfiVarStore
->Size
;
1246 HiiVariable
->Attributes
= IfrEfiVarStore
->Attributes
;
1247 CopyGuid (&HiiVariable
->Guid
, &IfrEfiVarStore
->Guid
);
1248 StrCpyS ((CHAR16
*) (HiiVariable
+ 1), VarNameSize
/ sizeof (CHAR16
), VarName
);
1250 HiiVariableNode
= InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode
));
1251 ASSERT (HiiVariableNode
!= NULL
);
1252 HiiVariableNode
->Signature
= VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE
;
1253 HiiVariableNode
->HiiVariable
= HiiVariable
;
1255 // The variable store identifier, which is unique within the current form set.
1257 HiiVariableNode
->VarStoreId
= IfrEfiVarStore
->VarStoreId
;
1258 HiiVariableNode
->HiiQuestionArray
= InternalVarCheckAllocateZeroPool (IfrEfiVarStore
->Size
* 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER
*));
1260 InsertTailList (&mVarCheckHiiList
, &HiiVariableNode
->Link
);
1262 HiiVariableNode
->VarStoreId
= IfrEfiVarStore
->VarStoreId
;
1267 Parse and create Hii Variable node list.
1269 @param[in] HiiPackage Pointer to Hii Package.
1277 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1278 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
1279 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
1281 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) HiiPackage
;
1283 switch (HiiPackageHeader
->Type
) {
1284 case EFI_HII_PACKAGE_FORMS
:
1285 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) (HiiPackageHeader
+ 1);
1287 while ((UINTN
) IfrOpCodeHeader
< (UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
) {
1288 switch (IfrOpCodeHeader
->OpCode
) {
1289 case EFI_IFR_VARSTORE_EFI_OP
:
1291 // Come to EFI VARSTORE in Form Package.
1293 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*) IfrOpCodeHeader
;
1294 if ((IfrEfiVarStore
->Header
.Length
>= sizeof (EFI_IFR_VARSTORE_EFI
)) &&
1295 ((IfrEfiVarStore
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) != 0)) {
1297 // Only create node list for Hii Variable with NV attribute.
1299 CreateHiiVariableNode (IfrEfiVarStore
);
1306 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
1316 Var Check Parse Hii Package.
1318 @param[in] HiiPackage Pointer to Hii Package.
1319 @param[in] FromFv Hii Package from FV.
1323 VarCheckParseHiiPackage (
1324 IN VOID
*HiiPackage
,
1328 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1329 EFI_IFR_OP_HEADER
*IfrOpCodeHeader
;
1330 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1331 BOOLEAN QuestionStoredInBitField
;
1334 // Parse and create Hii Variable node list for this Hii Package.
1336 ParseHiiVariable (HiiPackage
);
1338 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) HiiPackage
;
1340 QuestionStoredInBitField
= FALSE
;
1342 switch (HiiPackageHeader
->Type
) {
1343 case EFI_HII_PACKAGE_FORMS
:
1344 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) (HiiPackageHeader
+ 1);
1346 while ((UINTN
) IfrOpCodeHeader
< (UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
) {
1347 switch (IfrOpCodeHeader
->OpCode
) {
1348 case EFI_IFR_GUID_OP
:
1349 if (CompareGuid ((EFI_GUID
*)((UINTN
)IfrOpCodeHeader
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
1350 QuestionStoredInBitField
= TRUE
;
1354 case EFI_IFR_END_OP
:
1355 QuestionStoredInBitField
= FALSE
;
1358 case EFI_IFR_ONE_OF_OP
:
1359 case EFI_IFR_CHECKBOX_OP
:
1360 case EFI_IFR_NUMERIC_OP
:
1361 case EFI_IFR_ORDERED_LIST_OP
:
1362 HiiVariableNode
= FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.VarStoreId
);
1363 if ((HiiVariableNode
== NULL
) ||
1365 // No related Hii Variable node found.
1367 ((((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Prompt
== 0) && (((EFI_IFR_ONE_OF
*) IfrOpCodeHeader
)->Question
.Header
.Help
== 0))) {
1369 // meanless IFR item introduced by ECP.
1375 ParseHiiQuestion (HiiVariableNode
, IfrOpCodeHeader
, FromFv
, QuestionStoredInBitField
);
1380 IfrOpCodeHeader
= (EFI_IFR_OP_HEADER
*) ((UINTN
) IfrOpCodeHeader
+ IfrOpCodeHeader
->Length
);
1387 DestroyVarStoreId ();
1391 Var Check Parse Hii Database.
1393 @param[in] HiiDatabase Pointer to Hii Database.
1394 @param[in] HiiDatabaseSize Hii Database size.
1398 VarCheckParseHiiDatabase (
1399 IN VOID
*HiiDatabase
,
1400 IN UINTN HiiDatabaseSize
1403 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageListHeader
;
1404 EFI_HII_PACKAGE_HEADER
*HiiPackageHeader
;
1406 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) HiiDatabase
;
1408 while ((UINTN
) HiiPackageListHeader
< ((UINTN
) HiiDatabase
+ HiiDatabaseSize
)) {
1409 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) (HiiPackageListHeader
+ 1);
1411 while ((UINTN
) HiiPackageHeader
< ((UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
)) {
1413 // Parse Hii Package.
1415 VarCheckParseHiiPackage (HiiPackageHeader
, FALSE
);
1417 HiiPackageHeader
= (EFI_HII_PACKAGE_HEADER
*) ((UINTN
) HiiPackageHeader
+ HiiPackageHeader
->Length
);
1420 HiiPackageListHeader
= (EFI_HII_PACKAGE_LIST_HEADER
*) ((UINTN
) HiiPackageListHeader
+ HiiPackageListHeader
->PackageLength
);
1425 Destroy Hii Variable node.
1429 DestroyHiiVariableNode (
1433 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1434 LIST_ENTRY
*HiiVariableLink
;
1437 while (mVarCheckHiiList
.ForwardLink
!= &mVarCheckHiiList
) {
1438 HiiVariableLink
= mVarCheckHiiList
.ForwardLink
;
1439 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1441 RemoveEntryList (&HiiVariableNode
->Link
);
1444 // Free the allocated buffer.
1446 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
) 8; Index
++) {
1447 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1448 InternalVarCheckFreePool (HiiVariableNode
->HiiQuestionArray
[Index
]);
1451 InternalVarCheckFreePool (HiiVariableNode
->HiiQuestionArray
);
1452 InternalVarCheckFreePool (HiiVariableNode
->HiiVariable
);
1453 InternalVarCheckFreePool (HiiVariableNode
);
1458 Build VarCheckHiiBin.
1460 @param[out] Size Pointer to VarCheckHii size.
1462 @return Pointer to VarCheckHiiBin.
1466 BuildVarCheckHiiBin (
1470 VAR_CHECK_HII_VARIABLE_NODE
*HiiVariableNode
;
1471 LIST_ENTRY
*HiiVariableLink
;
1476 UINT32 HiiVariableLength
;
1483 for (HiiVariableLink
= mVarCheckHiiList
.ForwardLink
1484 ;HiiVariableLink
!= &mVarCheckHiiList
1485 ;HiiVariableLink
= HiiVariableLink
->ForwardLink
) {
1487 // For Hii Variable header align.
1489 BinSize
= (UINT32
) HEADER_ALIGN (BinSize
);
1491 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1492 HiiVariableLength
= HiiVariableNode
->HiiVariable
->HeaderLength
;
1494 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
) 8; Index
++) {
1495 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1497 // For Hii Question header align.
1499 HiiVariableLength
= (UINT32
) HEADER_ALIGN (HiiVariableLength
);
1500 HiiVariableLength
+= HiiVariableNode
->HiiQuestionArray
[Index
]->Length
;
1504 HiiVariableNode
->HiiVariable
->Length
= HiiVariableLength
;
1505 BinSize
+= HiiVariableLength
;
1508 DEBUG ((DEBUG_INFO
, "VarCheckHiiBin - size = 0x%x\n", BinSize
));
1515 // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation.
1516 // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
1517 // in SetVariable check handler.
1519 Data
= AllocateRuntimeZeroPool (BinSize
);
1520 ASSERT (Data
!= NULL
);
1522 // Make sure the allocated buffer for VarCheckHiiBin at required alignment.
1524 ASSERT ((((UINTN
) Data
) & (HEADER_ALIGNMENT
- 1)) == 0);
1525 DEBUG ((DEBUG_INFO
, "VarCheckHiiBin - built at 0x%x\n", Data
));
1531 for (HiiVariableLink
= mVarCheckHiiList
.ForwardLink
1532 ;HiiVariableLink
!= &mVarCheckHiiList
1533 ;HiiVariableLink
= HiiVariableLink
->ForwardLink
) {
1535 // For Hii Variable header align.
1537 Ptr
= (UINT8
*) HEADER_ALIGN (Ptr
);
1539 HiiVariableNode
= VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink
);
1540 CopyMem (Ptr
, HiiVariableNode
->HiiVariable
, HiiVariableNode
->HiiVariable
->HeaderLength
);
1541 Ptr
+= HiiVariableNode
->HiiVariable
->HeaderLength
;
1543 for (Index
= 0; Index
< HiiVariableNode
->HiiVariable
->Size
* (UINTN
) 8; Index
++) {
1544 if (HiiVariableNode
->HiiQuestionArray
[Index
] != NULL
) {
1546 // For Hii Question header align.
1548 Ptr
= (UINT8
*) HEADER_ALIGN (Ptr
);
1549 CopyMem (Ptr
, HiiVariableNode
->HiiQuestionArray
[Index
], HiiVariableNode
->HiiQuestionArray
[Index
]->Length
);
1550 Ptr
+= HiiVariableNode
->HiiQuestionArray
[Index
]->Length
;
1560 Generate VarCheckHiiBin from Hii Database and FV.
1569 VarCheckHiiGenFromHiiDatabase ();
1570 VarCheckHiiGenFromFv ();
1572 mVarCheckHiiBin
= BuildVarCheckHiiBin (&mVarCheckHiiBinSize
);
1573 if (mVarCheckHiiBin
== NULL
) {
1574 DEBUG ((DEBUG_INFO
, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
1578 DestroyHiiVariableNode ();
1579 if (mVarName
!= NULL
) {
1580 InternalVarCheckFreePool (mVarName
);
1583 #ifdef DUMP_VAR_CHECK_HII
1585 DumpVarCheckHii (mVarCheckHiiBin
, mVarCheckHiiBinSize
);