]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / VarCheckHiiLib / VarCheckHiiGen.c
1 /** @file
2 Var Check Hii bin generation.
3
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "VarCheckHiiGen.h"
10
11 LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList);
12
13 #define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V')
14
15 typedef struct {
16 UINTN Signature;
17 LIST_ENTRY Link;
18 VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
19 EFI_VARSTORE_ID VarStoreId;
20
21 VAR_CHECK_HII_QUESTION_HEADER **HiiQuestionArray;
22 } VAR_CHECK_HII_VARIABLE_NODE;
23
24 #define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE)
25
26 CHAR16 *mVarName = NULL;
27 UINTN mMaxVarNameSize = 0;
28
29 #ifdef DUMP_HII_DATA
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"},
38 };
39
40 /**
41 Ifr opcode to string.
42
43 @param[in] IfrOpCode Ifr OpCode.
44
45 @return Pointer to string.
46
47 **/
48 CHAR8 *
49 IfrOpCodeToStr (
50 IN UINT8 IfrOpCode
51 )
52 {
53 UINTN Index;
54 for (Index = 0; Index < ARRAY_SIZE (mIfrOpCodeStringTable); Index++) {
55 if (mIfrOpCodeStringTable[Index].HiiOpCode == IfrOpCode) {
56 return mIfrOpCodeStringTable[Index].HiiOpCodeStr;
57 }
58 }
59
60 return "<UnknownIfrOpCode>";
61 }
62
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"},
77 };
78
79 /**
80 Hii Package type to string.
81
82 @param[in] PackageType Package Type
83
84 @return Pointer to string.
85
86 **/
87 CHAR8 *
88 HiiPackageTypeToStr (
89 IN UINT8 PackageType
90 )
91 {
92 UINTN Index;
93 for (Index = 0; Index < ARRAY_SIZE (mPackageTypeStringTable); Index++) {
94 if (mPackageTypeStringTable[Index].PackageType == PackageType) {
95 return mPackageTypeStringTable[Index].PackageTypeStr;
96 }
97 }
98
99 return "<UnknownPackageType>";
100 }
101
102 /**
103 Dump Hii Package.
104
105 @param[in] HiiPackage Pointer to Hii Package.
106
107 **/
108 VOID
109 DumpHiiPackage (
110 IN VOID *HiiPackage
111 )
112 {
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;
118
119 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;
120 QuestionStoredInBitField = FALSE;
121
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));
124
125 switch (HiiPackageHeader->Type) {
126 case EFI_HII_PACKAGE_FORMS:
127 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) (HiiPackageHeader + 1);
128
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));
140 break;
141
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));
153 }
154 break;
155
156 case EFI_IFR_GUID_OP:
157 if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
158 QuestionStoredInBitField = TRUE;
159 }
160 break;
161
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")));
174 {
175 EFI_IFR_ONE_OF *IfrOneOf;
176 EFI_IFR_CHECKBOX *IfrCheckBox;
177 EFI_IFR_NUMERIC *IfrNumeric;
178 EFI_IFR_ORDERED_LIST *IfrOrderedList;
179
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) {
185 //
186 // For OneOf stored in bit field, the option value are saved as UINT32 type.
187 //
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));
191 } else {
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));
197 break;
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));
202 break;
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));
207 break;
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));
212 break;
213 }
214 }
215 break;
216 case EFI_IFR_CHECKBOX_OP:
217 IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpCodeHeader;
218 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrCheckBox->Flags));
219 break;
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) {
224 //
225 // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type.
226 //
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));
230 } else {
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));
236 break;
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));
241 break;
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));
246 break;
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));
251 break;
252 }
253 }
254 break;
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));
259 break;
260 default:
261 break;
262 }
263
264 if (IfrOpCodeHeader->Scope != 0) {
265 UINTN Scope;
266 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
267
268 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
269 Scope = 1;
270 while (Scope != 0) {
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));
282 break;
283 case EFI_IFR_TYPE_NUM_SIZE_16:
284 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%04x\n", IfrOneOfOption->Value.u16));
285 break;
286 case EFI_IFR_TYPE_NUM_SIZE_32:
287 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%08x\n", IfrOneOfOption->Value.u32));
288 break;
289 case EFI_IFR_TYPE_NUM_SIZE_64:
290 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%016lx\n", IfrOneOfOption->Value.u64));
291 break;
292 case EFI_IFR_TYPE_BOOLEAN:
293 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.b));
294 break;
295 default:
296 break;
297 }
298 break;
299 }
300
301 if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
302 QuestionStoredInBitField = FALSE;
303 ASSERT (Scope > 0);
304 Scope--;
305 if (Scope == 0) {
306 break;
307 }
308 } else if (IfrOpCodeHeader->Scope != 0) {
309 Scope++;
310 }
311 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
312 }
313 }
314 }
315 default:
316 break;
317 }
318 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
319 }
320 break;
321 default:
322 break;
323 }
324 }
325
326 /**
327 Dump Hii Database.
328
329 @param[in] HiiDatabase Pointer to Hii Database.
330 @param[in] HiiDatabaseSize Hii Database size.
331
332 **/
333 VOID
334 DumpHiiDatabase (
335 IN VOID *HiiDatabase,
336 IN UINTN HiiDatabaseSize
337 )
338 {
339 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader;
340 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
341
342 DEBUG ((DEBUG_INFO, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize));
343 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) HiiDatabase;
344
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);
349
350 while ((UINTN) HiiPackageHeader < (UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength) {
351
352 DumpHiiPackage (HiiPackageHeader);
353
354 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINTN) HiiPackageHeader + HiiPackageHeader->Length);
355 }
356
357 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) ((UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength);
358 }
359
360 return ;
361 }
362 #endif
363
364 /**
365 Allocates a buffer of a certain pool type.
366
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.
370
371 @param MemoryType The type of memory to allocate.
372 @param AllocationSize The number of bytes to allocate.
373
374 @return A pointer to the allocated buffer or NULL if allocation fails.
375
376 **/
377 VOID *
378 InternalVarCheckAllocatePool (
379 IN EFI_MEMORY_TYPE MemoryType,
380 IN UINTN AllocationSize
381 )
382 {
383 EFI_STATUS Status;
384 VOID *Memory;
385
386 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
387 if (EFI_ERROR (Status)) {
388 Memory = NULL;
389 }
390 return Memory;
391 }
392
393 /**
394 Allocates and zeros a buffer of type EfiBootServicesData.
395
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.
400
401 @param AllocationSize The number of bytes to allocate and zero.
402
403 @return A pointer to the allocated buffer or NULL if allocation fails.
404
405 **/
406 VOID *
407 InternalVarCheckAllocateZeroPool (
408 IN UINTN AllocationSize
409 )
410 {
411 VOID *Memory;
412
413 Memory = InternalVarCheckAllocatePool (EfiBootServicesData, AllocationSize);
414 if (Memory != NULL) {
415 Memory = ZeroMem (Memory, AllocationSize);
416 }
417 return Memory;
418 }
419
420 /**
421 Frees a buffer that was previously allocated with one of the pool allocation functions in the
422 Memory Allocation Library.
423
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.
427
428 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
429 then ASSERT().
430
431 @param Buffer The pointer to the buffer to free.
432
433 **/
434 VOID
435 EFIAPI
436 InternalVarCheckFreePool (
437 IN VOID *Buffer
438 )
439 {
440 EFI_STATUS Status;
441
442 Status = gBS->FreePool (Buffer);
443 ASSERT_EFI_ERROR (Status);
444 }
445
446 /**
447 Reallocates a buffer of type EfiBootServicesData.
448
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.
455
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().
458
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.
463
464 @return A pointer to the allocated buffer or NULL if allocation fails.
465
466 **/
467 VOID *
468 InternalVarCheckReallocatePool (
469 IN UINTN OldSize,
470 IN UINTN NewSize,
471 IN VOID *OldBuffer OPTIONAL
472 )
473 {
474 VOID *NewBuffer;
475
476 NewBuffer = InternalVarCheckAllocateZeroPool (NewSize);
477 if (NewBuffer != NULL && OldBuffer != NULL) {
478 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
479 InternalVarCheckFreePool (OldBuffer);
480 }
481 return NewBuffer;
482 }
483
484 /**
485 Merge Hii Question.
486
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.
490
491 **/
492 VOID
493 MergeHiiQuestion (
494 IN OUT VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode,
495 IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,
496 IN BOOLEAN FromFv
497 )
498 {
499 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion1;
500 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion2;
501 VAR_CHECK_HII_QUESTION_HEADER *NewHiiQuestion;
502 UINT8 NewLength;
503 UINT64 Minimum1;
504 UINT64 Maximum1;
505 UINT64 OneValue1;
506 UINT64 Minimum2;
507 UINT64 Maximum2;
508 UINT64 OneValue2;
509 UINT8 *Ptr;
510 UINT8 *Ptr1;
511 UINT8 *Ptr2;
512 UINTN ArrayIndex;
513
514 //
515 // Hii Question from Hii Database has high priority.
516 // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
517 //
518 if (FromFv) {
519 InternalVarCheckFreePool (HiiQuestion);
520 return;
521 }
522
523 if (HiiQuestion->BitFieldStore) {
524 ArrayIndex = HiiQuestion->VarOffset;
525 } else {
526 ArrayIndex = HiiQuestion->VarOffset * 8;
527 }
528
529 HiiQuestion1 = HiiVariableNode->HiiQuestionArray[ArrayIndex];
530 HiiQuestion2 = HiiQuestion;
531
532 ASSERT ((HiiQuestion1->OpCode == HiiQuestion2->OpCode) && (HiiQuestion1->StorageWidth == HiiQuestion2->StorageWidth));
533
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")));
537 //
538 // Get the length of Hii Question 1.
539 //
540 NewLength = HiiQuestion1->Length;
541
542 //
543 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
544 //
545 Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion2 + 1);
546 while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
547 OneValue2 = 0;
548 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
549
550 Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion1 + 1);
551 while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
552 OneValue1 = 0;
553 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
554 if (OneValue2 == OneValue1) {
555 //
556 // Match
557 //
558 break;
559 }
560 Ptr1 += HiiQuestion1->StorageWidth;
561 }
562 if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
563 //
564 // No match
565 //
566 NewLength = (UINT8) (NewLength + HiiQuestion1->StorageWidth);
567 }
568 Ptr2 += HiiQuestion2->StorageWidth;
569 }
570
571 if (NewLength > HiiQuestion1->Length) {
572 //
573 // Merge the one of options of Hii Question 2 and Hii Question 1.
574 //
575 NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
576 ASSERT (NewHiiQuestion != NULL);
577 CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
578 //
579 // Use the new length.
580 //
581 NewHiiQuestion->Length = NewLength;
582 Ptr = (UINT8 *) NewHiiQuestion + HiiQuestion1->Length;
583
584 Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion2 + 1);
585 while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
586 OneValue2 = 0;
587 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
588
589 Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion1 + 1);
590 while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
591 OneValue1 = 0;
592 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
593 if (OneValue2 == OneValue1) {
594 //
595 // Match
596 //
597 break;
598 }
599 Ptr1 += HiiQuestion1->StorageWidth;
600 }
601 if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
602 //
603 // No match
604 //
605 CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
606 Ptr += HiiQuestion1->StorageWidth;
607 }
608 Ptr2 += HiiQuestion2->StorageWidth;
609 }
610
611 HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;
612 InternalVarCheckFreePool (HiiQuestion1);
613 }
614 break;
615
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")));
618 break;
619
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")));
622 //
623 // Get minimum and maximum of Hii Question 1.
624 //
625 Minimum1 = 0;
626 Maximum1 = 0;
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);
631
632 //
633 // Get minimum and maximum of Hii Question 2.
634 //
635 Minimum2 = 0;
636 Maximum2 = 0;
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);
641
642 //
643 // Update minimum.
644 //
645 Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion1 + 1);
646 if (Minimum2 < Minimum1) {
647 Minimum1 = Minimum2;
648 CopyMem (Ptr, &Minimum1, HiiQuestion1->StorageWidth);
649 }
650 //
651 // Update maximum.
652 //
653 Ptr += HiiQuestion1->StorageWidth;
654 if (Maximum2 > Maximum1) {
655 Maximum1 = Maximum2;
656 CopyMem (Ptr, &Maximum1, HiiQuestion1->StorageWidth);
657 }
658 break;
659
660 case EFI_IFR_ORDERED_LIST_OP:
661 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
662 //
663 // Get the length of Hii Question 1.
664 //
665 NewLength = HiiQuestion1->Length;
666
667 //
668 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
669 //
670 Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion2 + 1);
671 while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
672 OneValue2 = 0;
673 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
674
675 Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion1 + 1);
676 while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
677 OneValue1 = 0;
678 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
679 if (OneValue2 == OneValue1) {
680 //
681 // Match
682 //
683 break;
684 }
685 Ptr1 += HiiQuestion1->StorageWidth;
686 }
687 if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
688 //
689 // No match
690 //
691 NewLength = (UINT8) (NewLength + HiiQuestion1->StorageWidth);
692 }
693 Ptr2 += HiiQuestion2->StorageWidth;
694 }
695
696 if (NewLength > HiiQuestion1->Length) {
697 //
698 // Merge the one of options of Hii Question 2 and Hii Question 1.
699 //
700 NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
701 ASSERT (NewHiiQuestion != NULL);
702 CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
703 //
704 // Use the new length.
705 //
706 NewHiiQuestion->Length = NewLength;
707 Ptr = (UINT8 *) NewHiiQuestion + HiiQuestion1->Length;
708
709 Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion2 + 1);
710 while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
711 OneValue2 = 0;
712 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
713
714 Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion1 + 1);
715 while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
716 OneValue1 = 0;
717 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
718 if (OneValue2 == OneValue1) {
719 //
720 // Match
721 //
722 break;
723 }
724 Ptr1 += HiiQuestion1->StorageWidth;
725 }
726 if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
727 //
728 // No match
729 //
730 CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
731 Ptr += HiiQuestion1->StorageWidth;
732 }
733 Ptr2 += HiiQuestion2->StorageWidth;
734 }
735
736 HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;
737 InternalVarCheckFreePool (HiiQuestion1);
738 }
739 break;
740
741 default:
742 ASSERT (FALSE);
743 return;
744 break;
745 }
746
747 //
748 //
749 // Hii Question 2 has been merged with Hii Question 1.
750 //
751 InternalVarCheckFreePool (HiiQuestion2);
752 }
753
754 /**
755 Get OneOf option data.
756
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.
761
762 **/
763 VOID
764 GetOneOfOption (
765 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
766 OUT UINTN *Count,
767 OUT UINT8 *Width,
768 OUT VOID *OptionBuffer OPTIONAL
769 )
770 {
771 UINTN Scope;
772 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
773
774 //
775 // Assume all OPTION has same Width.
776 //
777 *Count = 0;
778
779 if (IfrOpCodeHeader->Scope != 0) {
780 //
781 // Nested OpCode.
782 //
783 Scope = 1;
784 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
785 while (Scope != 0) {
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:
791 *Count = *Count + 1;
792 *Width = sizeof (UINT8);
793 if (OptionBuffer != NULL) {
794 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u8, sizeof (UINT8));
795 OptionBuffer = (UINT8 *) OptionBuffer + 1;
796 }
797 break;
798 case EFI_IFR_TYPE_NUM_SIZE_16:
799 *Count = *Count + 1;
800 *Width = sizeof (UINT16);
801 if (OptionBuffer != NULL) {
802 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u16, sizeof (UINT16));
803 OptionBuffer = (UINT16 *) OptionBuffer + 1;
804 }
805 break;
806 case EFI_IFR_TYPE_NUM_SIZE_32:
807 *Count = *Count + 1;
808 *Width = sizeof (UINT32);
809 if (OptionBuffer != NULL) {
810 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u32, sizeof (UINT32));
811 OptionBuffer = (UINT32 *) OptionBuffer + 1;
812 }
813 break;
814 case EFI_IFR_TYPE_NUM_SIZE_64:
815 *Count = *Count + 1;
816 *Width = sizeof (UINT64);
817 if (OptionBuffer != NULL) {
818 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u64, sizeof (UINT64));
819 OptionBuffer = (UINT64 *) OptionBuffer + 1;
820 }
821 break;
822 case EFI_IFR_TYPE_BOOLEAN:
823 *Count = *Count + 1;
824 *Width = sizeof (BOOLEAN);
825 if (OptionBuffer != NULL) {
826 CopyMem (OptionBuffer, &IfrOneOfOption->Value.b, sizeof (BOOLEAN));
827 OptionBuffer = (BOOLEAN *) OptionBuffer + 1;
828 }
829 break;
830 default:
831 break;
832 }
833 break;
834 }
835
836 //
837 // Until End OpCode.
838 //
839 if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
840 ASSERT (Scope > 0);
841 Scope--;
842 if (Scope == 0) {
843 break;
844 }
845 } else if (IfrOpCodeHeader->Scope != 0) {
846 //
847 // Nested OpCode.
848 //
849 Scope++;
850 }
851 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
852 }
853 }
854
855 return ;
856 }
857
858 /**
859 Parse Hii Question Oneof.
860
861 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
862 @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage.
863
864 return Pointer to Hii Question.
865
866 **/
867 VAR_CHECK_HII_QUESTION_HEADER *
868 ParseHiiQuestionOneOf (
869 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
870 IN BOOLEAN StoredInBitField
871 )
872 {
873 EFI_IFR_ONE_OF *IfrOneOf;
874 VAR_CHECK_HII_QUESTION_ONEOF *OneOf;
875 UINTN Length;
876 UINT8 Width;
877 UINTN OptionCount;
878 UINT8 OptionWidth;
879 UINT8 BitWidth;
880
881 IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpCodeHeader;
882 BitWidth = 0;
883
884 if (StoredInBitField) {
885 //
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.
888 //
889 BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
890 Width = sizeof (UINT32);
891 } else {
892 Width = (UINT8) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
893 }
894
895 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
896 ASSERT (Width == OptionWidth);
897
898 Length = sizeof (*OneOf) + OptionCount * Width;
899
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;
908 } else {
909 OneOf->StorageWidth = Width;
910 }
911
912 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OneOf + 1);
913
914 return (VAR_CHECK_HII_QUESTION_HEADER *) OneOf;
915 }
916
917 /**
918 Parse Hii Question CheckBox.
919
920 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
921 @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage.
922
923 return Pointer to Hii Question.
924
925 **/
926 VAR_CHECK_HII_QUESTION_HEADER *
927 ParseHiiQuestionCheckBox (
928 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
929 IN BOOLEAN StoredInBitField
930 )
931 {
932 EFI_IFR_CHECKBOX *IfrCheckBox;
933 VAR_CHECK_HII_QUESTION_CHECKBOX *CheckBox;
934
935 IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpCodeHeader;
936
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;
945 } else {
946 CheckBox->StorageWidth = (UINT8) sizeof (BOOLEAN);
947 }
948
949 return (VAR_CHECK_HII_QUESTION_HEADER *) CheckBox;
950 }
951
952 /**
953 Parse Hii Question Numeric.
954
955 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
956 @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage.
957
958 return Pointer to Hii Question.
959
960 **/
961 VAR_CHECK_HII_QUESTION_HEADER *
962 ParseHiiQuestionNumeric (
963 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
964 IN BOOLEAN StoredInBitField
965 )
966 {
967 EFI_IFR_NUMERIC *IfrNumeric;
968 VAR_CHECK_HII_QUESTION_NUMERIC *Numeric;
969 UINT8 Width;
970 UINT8 BitWidth;
971
972 IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpCodeHeader;
973 BitWidth = 0;
974
975 Numeric = InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * sizeof (UINT64));
976 ASSERT (Numeric != NULL);
977
978 if (StoredInBitField) {
979 //
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.
982 //
983 BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
984 Width = sizeof (UINT32);
985 } else {
986 Width = (UINT8) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
987 }
988
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;
995 } else {
996 Numeric->StorageWidth = Width;
997 }
998
999 CopyMem (Numeric + 1, &IfrNumeric->data, Width * 2);
1000
1001 return (VAR_CHECK_HII_QUESTION_HEADER *) Numeric;
1002 }
1003
1004 /**
1005 Parse Hii Question OrderedList.
1006
1007 @param[in] IfrOpCodeHeader Pointer to Ifr OpCode header.
1008
1009 return Pointer to Hii Question.
1010
1011 **/
1012 VAR_CHECK_HII_QUESTION_HEADER *
1013 ParseHiiQuestionOrderedList (
1014 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader
1015 )
1016 {
1017 EFI_IFR_ORDERED_LIST *IfrOrderedList;
1018 VAR_CHECK_HII_QUESTION_ORDEREDLIST *OrderedList;
1019 UINTN Length;
1020 UINTN OptionCount;
1021 UINT8 OptionWidth;
1022
1023 IfrOrderedList = (EFI_IFR_ORDERED_LIST *) IfrOpCodeHeader;
1024
1025 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
1026
1027 Length = sizeof (*OrderedList) + OptionCount * OptionWidth;
1028
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;
1037
1038 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OrderedList + 1);
1039
1040 return (VAR_CHECK_HII_QUESTION_HEADER *) OrderedList;
1041 }
1042
1043 /**
1044 Parse and create Hii Question node.
1045
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.
1050
1051 **/
1052 VOID
1053 ParseHiiQuestion (
1054 IN VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode,
1055 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
1056 IN BOOLEAN FromFv,
1057 IN BOOLEAN StoredInBitField
1058 )
1059 {
1060 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
1061 UINTN ArrayIndex;
1062
1063 //
1064 // Currently only OneOf, CheckBox and Numeric can be stored in bit field.
1065 //
1066 switch (IfrOpCodeHeader->OpCode) {
1067 case EFI_IFR_ONE_OF_OP:
1068 HiiQuestion = ParseHiiQuestionOneOf (IfrOpCodeHeader, StoredInBitField);
1069 break;
1070
1071 case EFI_IFR_CHECKBOX_OP:
1072 HiiQuestion = ParseHiiQuestionCheckBox (IfrOpCodeHeader, StoredInBitField);
1073 break;
1074
1075 case EFI_IFR_NUMERIC_OP:
1076 HiiQuestion = ParseHiiQuestionNumeric (IfrOpCodeHeader, StoredInBitField);
1077 break;
1078
1079 case EFI_IFR_ORDERED_LIST_OP:
1080 HiiQuestion = ParseHiiQuestionOrderedList (IfrOpCodeHeader);
1081 break;
1082
1083 default:
1084 ASSERT (FALSE);
1085 return;
1086 break;
1087 }
1088
1089 if (StoredInBitField) {
1090 ArrayIndex = HiiQuestion->VarOffset;
1091 } else {
1092 ArrayIndex = HiiQuestion->VarOffset * 8;
1093 }
1094 if (HiiVariableNode->HiiQuestionArray[ArrayIndex] != NULL) {
1095 MergeHiiQuestion (HiiVariableNode, HiiQuestion, FromFv);
1096 } else {
1097 HiiVariableNode->HiiQuestionArray[ArrayIndex] = HiiQuestion;
1098 }
1099 }
1100
1101 /**
1102 Find Hii variable node by name and GUID.
1103
1104 @param[in] Name Pointer to variable name.
1105 @param[in] Guid Pointer to vendor GUID.
1106
1107 @return Pointer to Hii Variable node.
1108
1109 **/
1110 VAR_CHECK_HII_VARIABLE_NODE *
1111 FindHiiVariableNode (
1112 IN CHAR16 *Name,
1113 IN EFI_GUID *Guid
1114 )
1115 {
1116 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1117 LIST_ENTRY *Link;
1118
1119 for (Link = mVarCheckHiiList.ForwardLink
1120 ;Link != &mVarCheckHiiList
1121 ;Link = Link->ForwardLink) {
1122 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
1123
1124 if ((StrCmp (Name, (CHAR16 *) (HiiVariableNode->HiiVariable + 1)) == 0) &&
1125 CompareGuid (Guid, &HiiVariableNode->HiiVariable->Guid)) {
1126 return HiiVariableNode;
1127 }
1128 }
1129
1130 return NULL;
1131 }
1132
1133 /**
1134 Find Hii variable node by var store id.
1135
1136 @param[in] VarStoreId Var store id.
1137
1138 @return Pointer to Hii Variable node.
1139
1140 **/
1141 VAR_CHECK_HII_VARIABLE_NODE *
1142 FindHiiVariableNodeByVarStoreId (
1143 IN EFI_VARSTORE_ID VarStoreId
1144 )
1145 {
1146 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1147 LIST_ENTRY *Link;
1148
1149 if (VarStoreId == 0) {
1150 //
1151 // The variable store identifier, which is unique within the current form set.
1152 // A value of zero is invalid.
1153 //
1154 return NULL;
1155 }
1156
1157 for (Link = mVarCheckHiiList.ForwardLink
1158 ;Link != &mVarCheckHiiList
1159 ;Link = Link->ForwardLink) {
1160 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
1161 //
1162 // The variable store identifier, which is unique within the current form set.
1163 //
1164 if (VarStoreId == HiiVariableNode->VarStoreId) {
1165 return HiiVariableNode;
1166 }
1167 }
1168
1169 return NULL;
1170 }
1171
1172 /**
1173 Destroy var store id in the Hii Variable node after parsing one Hii Package.
1174
1175 **/
1176 VOID
1177 DestroyVarStoreId (
1178 VOID
1179 )
1180 {
1181 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1182 LIST_ENTRY *Link;
1183
1184 for (Link = mVarCheckHiiList.ForwardLink
1185 ;Link != &mVarCheckHiiList
1186 ;Link = Link->ForwardLink) {
1187 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
1188 //
1189 // The variable store identifier, which is unique within the current form set.
1190 // A value of zero is invalid.
1191 //
1192 HiiVariableNode->VarStoreId = 0;
1193 }
1194 }
1195
1196 /**
1197 Create Hii Variable node.
1198
1199 @param[in] IfrEfiVarStore Pointer to EFI VARSTORE.
1200
1201 **/
1202 VOID
1203 CreateHiiVariableNode (
1204 IN EFI_IFR_VARSTORE_EFI *IfrEfiVarStore
1205 )
1206 {
1207 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1208 VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
1209 UINTN HeaderLength;
1210 CHAR16 *VarName;
1211 UINTN VarNameSize;
1212
1213 //
1214 // Get variable name.
1215 //
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;
1221 }
1222 AsciiStrToUnicodeStrS ((CHAR8 *) IfrEfiVarStore->Name, mVarName, mMaxVarNameSize / sizeof (CHAR16));
1223 VarName = mVarName;
1224
1225 HiiVariableNode = FindHiiVariableNode (
1226 VarName,
1227 &IfrEfiVarStore->Guid
1228 );
1229 if (HiiVariableNode == NULL) {
1230 //
1231 // Not found, then create new.
1232 //
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);
1243
1244 HiiVariableNode = InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode));
1245 ASSERT (HiiVariableNode != NULL);
1246 HiiVariableNode->Signature = VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE;
1247 HiiVariableNode->HiiVariable = HiiVariable;
1248 //
1249 // The variable store identifier, which is unique within the current form set.
1250 //
1251 HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
1252 HiiVariableNode->HiiQuestionArray = InternalVarCheckAllocateZeroPool (IfrEfiVarStore->Size * 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER *));
1253
1254 InsertTailList (&mVarCheckHiiList, &HiiVariableNode->Link);
1255 } else {
1256 HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
1257 }
1258 }
1259
1260 /**
1261 Parse and create Hii Variable node list.
1262
1263 @param[in] HiiPackage Pointer to Hii Package.
1264
1265 **/
1266 VOID
1267 ParseHiiVariable (
1268 IN VOID *HiiPackage
1269 )
1270 {
1271 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
1272 EFI_IFR_OP_HEADER *IfrOpCodeHeader;
1273 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
1274
1275 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;
1276
1277 switch (HiiPackageHeader->Type) {
1278 case EFI_HII_PACKAGE_FORMS:
1279 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) (HiiPackageHeader + 1);
1280
1281 while ((UINTN) IfrOpCodeHeader < (UINTN) HiiPackageHeader + HiiPackageHeader->Length) {
1282 switch (IfrOpCodeHeader->OpCode) {
1283 case EFI_IFR_VARSTORE_EFI_OP:
1284 //
1285 // Come to EFI VARSTORE in Form Package.
1286 //
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)) {
1290 //
1291 // Only create node list for Hii Variable with NV attribute.
1292 //
1293 CreateHiiVariableNode (IfrEfiVarStore);
1294 }
1295 break;
1296
1297 default:
1298 break;
1299 }
1300 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
1301 }
1302 break;
1303
1304 default:
1305 break;
1306 }
1307 }
1308
1309 /**
1310 Var Check Parse Hii Package.
1311
1312 @param[in] HiiPackage Pointer to Hii Package.
1313 @param[in] FromFv Hii Package from FV.
1314
1315 **/
1316 VOID
1317 VarCheckParseHiiPackage (
1318 IN VOID *HiiPackage,
1319 IN BOOLEAN FromFv
1320 )
1321 {
1322 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
1323 EFI_IFR_OP_HEADER *IfrOpCodeHeader;
1324 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1325 BOOLEAN QuestionStoredInBitField;
1326
1327 //
1328 // Parse and create Hii Variable node list for this Hii Package.
1329 //
1330 ParseHiiVariable (HiiPackage);
1331
1332 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;
1333
1334 QuestionStoredInBitField = FALSE;
1335
1336 switch (HiiPackageHeader->Type) {
1337 case EFI_HII_PACKAGE_FORMS:
1338 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) (HiiPackageHeader + 1);
1339
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;
1345 }
1346 break;
1347
1348 case EFI_IFR_END_OP:
1349 QuestionStoredInBitField = FALSE;
1350 break;
1351
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) ||
1358 //
1359 // No related Hii Variable node found.
1360 //
1361 ((((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.Header.Prompt == 0) && (((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.Header.Help == 0))) {
1362 //
1363 // meanless IFR item introduced by ECP.
1364 //
1365 } else {
1366 //
1367 // Normal IFR
1368 //
1369 ParseHiiQuestion (HiiVariableNode, IfrOpCodeHeader, FromFv, QuestionStoredInBitField);
1370 }
1371 default:
1372 break;
1373 }
1374 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
1375 }
1376 break;
1377
1378 default:
1379 break;
1380 }
1381 DestroyVarStoreId ();
1382 }
1383
1384 /**
1385 Var Check Parse Hii Database.
1386
1387 @param[in] HiiDatabase Pointer to Hii Database.
1388 @param[in] HiiDatabaseSize Hii Database size.
1389
1390 **/
1391 VOID
1392 VarCheckParseHiiDatabase (
1393 IN VOID *HiiDatabase,
1394 IN UINTN HiiDatabaseSize
1395 )
1396 {
1397 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader;
1398 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
1399
1400 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) HiiDatabase;
1401
1402 while ((UINTN) HiiPackageListHeader < ((UINTN) HiiDatabase + HiiDatabaseSize)) {
1403 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiPackageListHeader + 1);
1404
1405 while ((UINTN) HiiPackageHeader < ((UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength)) {
1406 //
1407 // Parse Hii Package.
1408 //
1409 VarCheckParseHiiPackage (HiiPackageHeader, FALSE);
1410
1411 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINTN) HiiPackageHeader + HiiPackageHeader->Length);
1412 }
1413
1414 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) ((UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength);
1415 }
1416 }
1417
1418 /**
1419 Destroy Hii Variable node.
1420
1421 **/
1422 VOID
1423 DestroyHiiVariableNode (
1424 VOID
1425 )
1426 {
1427 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1428 LIST_ENTRY *HiiVariableLink;
1429 UINTN Index;
1430
1431 while (mVarCheckHiiList.ForwardLink != &mVarCheckHiiList) {
1432 HiiVariableLink = mVarCheckHiiList.ForwardLink;
1433 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
1434
1435 RemoveEntryList (&HiiVariableNode->Link);
1436
1437 //
1438 // Free the allocated buffer.
1439 //
1440 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN) 8; Index++) {
1441 if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
1442 InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray[Index]);
1443 }
1444 }
1445 InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray);
1446 InternalVarCheckFreePool (HiiVariableNode->HiiVariable);
1447 InternalVarCheckFreePool (HiiVariableNode);
1448 }
1449 }
1450
1451 /**
1452 Build VarCheckHiiBin.
1453
1454 @param[out] Size Pointer to VarCheckHii size.
1455
1456 @return Pointer to VarCheckHiiBin.
1457
1458 **/
1459 VOID *
1460 BuildVarCheckHiiBin (
1461 OUT UINTN *Size
1462 )
1463 {
1464 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1465 LIST_ENTRY *HiiVariableLink;
1466 UINTN Index;
1467 VOID *Data;
1468 UINT8 *Ptr;
1469 UINT32 BinSize;
1470 UINT32 HiiVariableLength;
1471
1472 //
1473 // Get Size
1474 //
1475 BinSize = 0;
1476
1477 for (HiiVariableLink = mVarCheckHiiList.ForwardLink
1478 ;HiiVariableLink != &mVarCheckHiiList
1479 ;HiiVariableLink = HiiVariableLink->ForwardLink) {
1480 //
1481 // For Hii Variable header align.
1482 //
1483 BinSize = (UINT32) HEADER_ALIGN (BinSize);
1484
1485 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
1486 HiiVariableLength = HiiVariableNode->HiiVariable->HeaderLength;
1487
1488 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN) 8; Index++) {
1489 if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
1490 //
1491 // For Hii Question header align.
1492 //
1493 HiiVariableLength = (UINT32) HEADER_ALIGN (HiiVariableLength);
1494 HiiVariableLength += HiiVariableNode->HiiQuestionArray[Index]->Length;
1495 }
1496 }
1497
1498 HiiVariableNode->HiiVariable->Length = HiiVariableLength;
1499 BinSize += HiiVariableLength;
1500 }
1501
1502 DEBUG ((DEBUG_INFO, "VarCheckHiiBin - size = 0x%x\n", BinSize));
1503 if (BinSize == 0) {
1504 *Size = BinSize;
1505 return NULL;
1506 }
1507
1508 //
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.
1512 //
1513 Data = AllocateRuntimeZeroPool (BinSize);
1514 ASSERT (Data != NULL);
1515 //
1516 // Make sure the allocated buffer for VarCheckHiiBin at required alignment.
1517 //
1518 ASSERT ((((UINTN) Data) & (HEADER_ALIGNMENT - 1)) == 0);
1519 DEBUG ((DEBUG_INFO, "VarCheckHiiBin - built at 0x%x\n", Data));
1520
1521 //
1522 // Gen Data
1523 //
1524 Ptr = Data;
1525 for (HiiVariableLink = mVarCheckHiiList.ForwardLink
1526 ;HiiVariableLink != &mVarCheckHiiList
1527 ;HiiVariableLink = HiiVariableLink->ForwardLink) {
1528 //
1529 // For Hii Variable header align.
1530 //
1531 Ptr = (UINT8 *) HEADER_ALIGN (Ptr);
1532
1533 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
1534 CopyMem (Ptr, HiiVariableNode->HiiVariable, HiiVariableNode->HiiVariable->HeaderLength);
1535 Ptr += HiiVariableNode->HiiVariable->HeaderLength;
1536
1537 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN) 8; Index++) {
1538 if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
1539 //
1540 // For Hii Question header align.
1541 //
1542 Ptr = (UINT8 *) HEADER_ALIGN (Ptr);
1543 CopyMem (Ptr, HiiVariableNode->HiiQuestionArray[Index], HiiVariableNode->HiiQuestionArray[Index]->Length);
1544 Ptr += HiiVariableNode->HiiQuestionArray[Index]->Length;
1545 }
1546 }
1547 }
1548
1549 *Size = BinSize;
1550 return Data;
1551 }
1552
1553 /**
1554 Generate VarCheckHiiBin from Hii Database and FV.
1555
1556 **/
1557 VOID
1558 EFIAPI
1559 VarCheckHiiGen (
1560 VOID
1561 )
1562 {
1563 VarCheckHiiGenFromHiiDatabase ();
1564 VarCheckHiiGenFromFv ();
1565
1566 mVarCheckHiiBin = BuildVarCheckHiiBin (&mVarCheckHiiBinSize);
1567 if (mVarCheckHiiBin == NULL) {
1568 DEBUG ((DEBUG_INFO, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
1569 return;
1570 }
1571
1572 DestroyHiiVariableNode ();
1573 if (mVarName != NULL) {
1574 InternalVarCheckFreePool (mVarName);
1575 }
1576
1577 #ifdef DUMP_VAR_CHECK_HII
1578 DEBUG_CODE (
1579 DumpVarCheckHii (mVarCheckHiiBin, mVarCheckHiiBinSize);
1580 );
1581 #endif
1582 }
1583