TianoCore EDK2 master
Loading...
Searching...
No Matches
VarCheckHiiGen.c
Go to the documentation of this file.
1
9#include "VarCheckHiiGen.h"
10#include "VarCheckHii.h"
11
12VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL;
13UINTN mVarCheckHiiBinSize = 0;
14LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList);
15
16#define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V')
17
18typedef struct {
19 UINTN Signature;
20 LIST_ENTRY Link;
22 EFI_VARSTORE_ID VarStoreId;
23
24 VAR_CHECK_HII_QUESTION_HEADER **HiiQuestionArray;
26
27#define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE)
28
29CHAR16 *mVarName = NULL;
30UINTN mMaxVarNameSize = 0;
31
32#ifdef DUMP_HII_DATA
34 { EFI_IFR_VARSTORE_OP, "EFI_IFR_VARSTORE_OP" },
35 { EFI_IFR_VARSTORE_EFI_OP, "EFI_IFR_VARSTORE_EFI_OP" },
36 { EFI_IFR_ONE_OF_OP, "EFI_IFR_ONE_OF_OP" },
37 { EFI_IFR_CHECKBOX_OP, "EFI_IFR_CHECKBOX_OP" },
38 { EFI_IFR_NUMERIC_OP, "EFI_IFR_NUMERIC_OP" },
39 { EFI_IFR_ORDERED_LIST_OP, "EFI_IFR_ORDERED_LIST_OP" },
40 { EFI_IFR_ONE_OF_OPTION_OP, "EFI_IFR_ONE_OF_OPTION_OP" },
41};
42
51CHAR8 *
52IfrOpCodeToStr (
53 IN UINT8 IfrOpCode
54 )
55{
56 UINTN Index;
57
58 for (Index = 0; Index < ARRAY_SIZE (mIfrOpCodeStringTable); Index++) {
59 if (mIfrOpCodeStringTable[Index].HiiOpCode == IfrOpCode) {
60 return mIfrOpCodeStringTable[Index].HiiOpCodeStr;
61 }
62 }
63
64 return "<UnknownIfrOpCode>";
65}
66
68 { EFI_HII_PACKAGE_TYPE_ALL, "EFI_HII_PACKAGE_TYPE_ALL" },
69 { EFI_HII_PACKAGE_TYPE_GUID, "EFI_HII_PACKAGE_TYPE_GUID" },
70 { EFI_HII_PACKAGE_FORMS, "EFI_HII_PACKAGE_FORMS" },
71 { EFI_HII_PACKAGE_STRINGS, "EFI_HII_PACKAGE_STRINGS" },
72 { EFI_HII_PACKAGE_FONTS, "EFI_HII_PACKAGE_FONTS" },
73 { EFI_HII_PACKAGE_IMAGES, "EFI_HII_PACKAGE_IMAGES" },
74 { EFI_HII_PACKAGE_SIMPLE_FONTS, "EFI_HII_PACKAGE_SIMPLE_FONTS" },
75 { EFI_HII_PACKAGE_DEVICE_PATH, "EFI_HII_PACKAGE_DEVICE_PATH" },
76 { EFI_HII_PACKAGE_KEYBOARD_LAYOUT, "EFI_HII_PACKAGE_KEYBOARD_LAYOUT" },
77 { EFI_HII_PACKAGE_ANIMATIONS, "EFI_HII_PACKAGE_ANIMATIONS" },
78 { EFI_HII_PACKAGE_END, "EFI_HII_PACKAGE_END" },
79 { EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN, "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN" },
80 { EFI_HII_PACKAGE_TYPE_SYSTEM_END, "EFI_HII_PACKAGE_TYPE_SYSTEM_END" },
81};
82
91CHAR8 *
92HiiPackageTypeToStr (
93 IN UINT8 PackageType
94 )
95{
96 UINTN Index;
97
98 for (Index = 0; Index < ARRAY_SIZE (mPackageTypeStringTable); Index++) {
99 if (mPackageTypeStringTable[Index].PackageType == PackageType) {
100 return mPackageTypeStringTable[Index].PackageTypeStr;
101 }
102 }
103
104 return "<UnknownPackageType>";
105}
106
113VOID
115 IN VOID *HiiPackage
116 )
117{
118 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
119 EFI_IFR_OP_HEADER *IfrOpCodeHeader;
120 EFI_IFR_VARSTORE *IfrVarStore;
121 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
122 BOOLEAN QuestionStoredInBitField;
123
124 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
125 QuestionStoredInBitField = FALSE;
126
127 DEBUG ((DEBUG_INFO, " HiiPackageHeader->Type - 0x%02x (%a)\n", HiiPackageHeader->Type, HiiPackageTypeToStr ((UINT8)HiiPackageHeader->Type)));
128 DEBUG ((DEBUG_INFO, " HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader->Length));
129
130 switch (HiiPackageHeader->Type) {
131 case EFI_HII_PACKAGE_FORMS:
132 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
133
134 while ((UINTN)IfrOpCodeHeader < ((UINTN)HiiPackageHeader + HiiPackageHeader->Length)) {
135 switch (IfrOpCodeHeader->OpCode) {
136 case EFI_IFR_VARSTORE_OP:
137 IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpCodeHeader;
138 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
139 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
140 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
141 DEBUG ((DEBUG_INFO, " Guid - %g\n", &IfrVarStore->Guid));
142 DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", IfrVarStore->VarStoreId));
143 DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", IfrVarStore->Size));
144 DEBUG ((DEBUG_INFO, " Name - %a\n", IfrVarStore->Name));
145 break;
146
147 case EFI_IFR_VARSTORE_EFI_OP:
148 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpCodeHeader;
149 if (IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) {
150 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
151 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
152 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
153 DEBUG ((DEBUG_INFO, " Guid - %g\n", &IfrEfiVarStore->Guid));
154 DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", IfrEfiVarStore->VarStoreId));
155 DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", IfrEfiVarStore->Size));
156 DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", IfrEfiVarStore->Attributes));
157 DEBUG ((DEBUG_INFO, " Name - %a\n", IfrEfiVarStore->Name));
158 }
159
160 break;
161
162 case EFI_IFR_GUID_OP:
163 if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
164 QuestionStoredInBitField = TRUE;
165 }
166
167 break;
168
169 case EFI_IFR_ONE_OF_OP:
170 case EFI_IFR_CHECKBOX_OP:
171 case EFI_IFR_NUMERIC_OP:
172 case EFI_IFR_ORDERED_LIST_OP:
173 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode), (QuestionStoredInBitField ? "bit level" : "byte level")));
174 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
175 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
176 DEBUG ((DEBUG_INFO, " Prompt - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Prompt));
177 DEBUG ((DEBUG_INFO, " Help - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Help));
178 DEBUG ((DEBUG_INFO, " QuestionId - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.QuestionId));
179 DEBUG ((DEBUG_INFO, " VarStoreId - 0x%04x\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreId));
180 DEBUG ((DEBUG_INFO, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreInfo.VarOffset, (QuestionStoredInBitField ? "bit level" : "byte level")));
181 {
182 EFI_IFR_ONE_OF *IfrOneOf;
183 EFI_IFR_CHECKBOX *IfrCheckBox;
184 EFI_IFR_NUMERIC *IfrNumeric;
185 EFI_IFR_ORDERED_LIST *IfrOrderedList;
186
187 switch (IfrOpCodeHeader->OpCode) {
188 case EFI_IFR_ONE_OF_OP:
189 IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpCodeHeader;
190 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOneOf->Flags));
191 if (QuestionStoredInBitField) {
192 //
193 // For OneOf stored in bit field, the option value are saved as UINT32 type.
194 //
195 DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrOneOf->data.u32.MinValue));
196 DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrOneOf->data.u32.MaxValue));
197 DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrOneOf->data.u32.Step));
198 } else {
199 switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {
200 case EFI_IFR_NUMERIC_SIZE_1:
201 DEBUG ((DEBUG_INFO, " MinValue - 0x%02x\n", IfrOneOf->data.u8.MinValue));
202 DEBUG ((DEBUG_INFO, " MaxValue - 0x%02x\n", IfrOneOf->data.u8.MaxValue));
203 DEBUG ((DEBUG_INFO, " Step - 0x%02x\n", IfrOneOf->data.u8.Step));
204 break;
205 case EFI_IFR_NUMERIC_SIZE_2:
206 DEBUG ((DEBUG_INFO, " MinValue - 0x%04x\n", IfrOneOf->data.u16.MinValue));
207 DEBUG ((DEBUG_INFO, " MaxValue - 0x%04x\n", IfrOneOf->data.u16.MaxValue));
208 DEBUG ((DEBUG_INFO, " Step - 0x%04x\n", IfrOneOf->data.u16.Step));
209 break;
210 case EFI_IFR_NUMERIC_SIZE_4:
211 DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrOneOf->data.u32.MinValue));
212 DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrOneOf->data.u32.MaxValue));
213 DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrOneOf->data.u32.Step));
214 break;
215 case EFI_IFR_NUMERIC_SIZE_8:
216 DEBUG ((DEBUG_INFO, " MinValue - 0x%016lx\n", IfrOneOf->data.u64.MinValue));
217 DEBUG ((DEBUG_INFO, " MaxValue - 0x%016lx\n", IfrOneOf->data.u64.MaxValue));
218 DEBUG ((DEBUG_INFO, " Step - 0x%016lx\n", IfrOneOf->data.u64.Step));
219 break;
220 }
221 }
222
223 break;
224 case EFI_IFR_CHECKBOX_OP:
225 IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;
226 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrCheckBox->Flags));
227 break;
228 case EFI_IFR_NUMERIC_OP:
229 IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpCodeHeader;
230 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrNumeric->Flags));
231 if (QuestionStoredInBitField) {
232 //
233 // For Numeric stored in bit field, the MinValue,MaxValue and Step are saved as UINT32 type.
234 //
235 DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrNumeric->data.u32.MinValue));
236 DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrNumeric->data.u32.MaxValue));
237 DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrNumeric->data.u32.Step));
238 } else {
239 switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
240 case EFI_IFR_NUMERIC_SIZE_1:
241 DEBUG ((DEBUG_INFO, " MinValue - 0x%02x\n", IfrNumeric->data.u8.MinValue));
242 DEBUG ((DEBUG_INFO, " MaxValue - 0x%02x\n", IfrNumeric->data.u8.MaxValue));
243 DEBUG ((DEBUG_INFO, " Step - 0x%02x\n", IfrNumeric->data.u8.Step));
244 break;
245 case EFI_IFR_NUMERIC_SIZE_2:
246 DEBUG ((DEBUG_INFO, " MinValue - 0x%04x\n", IfrNumeric->data.u16.MinValue));
247 DEBUG ((DEBUG_INFO, " MaxValue - 0x%04x\n", IfrNumeric->data.u16.MaxValue));
248 DEBUG ((DEBUG_INFO, " Step - 0x%04x\n", IfrNumeric->data.u16.Step));
249 break;
250 case EFI_IFR_NUMERIC_SIZE_4:
251 DEBUG ((DEBUG_INFO, " MinValue - 0x%08x\n", IfrNumeric->data.u32.MinValue));
252 DEBUG ((DEBUG_INFO, " MaxValue - 0x%08x\n", IfrNumeric->data.u32.MaxValue));
253 DEBUG ((DEBUG_INFO, " Step - 0x%08x\n", IfrNumeric->data.u32.Step));
254 break;
255 case EFI_IFR_NUMERIC_SIZE_8:
256 DEBUG ((DEBUG_INFO, " MinValue - 0x%016lx\n", IfrNumeric->data.u64.MinValue));
257 DEBUG ((DEBUG_INFO, " MaxValue - 0x%016lx\n", IfrNumeric->data.u64.MaxValue));
258 DEBUG ((DEBUG_INFO, " Step - 0x%016lx\n", IfrNumeric->data.u64.Step));
259 break;
260 }
261 }
262
263 break;
264 case EFI_IFR_ORDERED_LIST_OP:
265 IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpCodeHeader;
266 DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", IfrOrderedList->MaxContainers));
267 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOrderedList->Flags));
268 break;
269 default:
270 break;
271 }
272
273 if (IfrOpCodeHeader->Scope != 0) {
274 UINTN Scope;
275 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
276
277 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
278 Scope = 1;
279 while (Scope != 0) {
280 switch (IfrOpCodeHeader->OpCode) {
281 case EFI_IFR_ONE_OF_OPTION_OP:
282 IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader;
283 DEBUG ((DEBUG_INFO, "!!!! IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", (UINTN)IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
284 DEBUG ((DEBUG_INFO, "!!!! IfrOpCodeHeader->Scope - 0x%02x\n", IfrOpCodeHeader->Scope));
285 DEBUG ((DEBUG_INFO, "!!!! Option - 0x%04x\n", IfrOneOfOption->Option));
286 DEBUG ((DEBUG_INFO, "!!!! Flags - 0x%02x\n", IfrOneOfOption->Flags));
287 DEBUG ((DEBUG_INFO, "!!!! Type - 0x%02x\n", IfrOneOfOption->Type));
288 switch (IfrOneOfOption->Type) {
289 case EFI_IFR_TYPE_NUM_SIZE_8:
290 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.u8));
291 break;
292 case EFI_IFR_TYPE_NUM_SIZE_16:
293 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%04x\n", IfrOneOfOption->Value.u16));
294 break;
295 case EFI_IFR_TYPE_NUM_SIZE_32:
296 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%08x\n", IfrOneOfOption->Value.u32));
297 break;
298 case EFI_IFR_TYPE_NUM_SIZE_64:
299 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%016lx\n", IfrOneOfOption->Value.u64));
300 break;
301 case EFI_IFR_TYPE_BOOLEAN:
302 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.b));
303 break;
304 default:
305 break;
306 }
307
308 break;
309 }
310
311 if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
312 QuestionStoredInBitField = FALSE;
313 ASSERT (Scope > 0);
314 Scope--;
315 if (Scope == 0) {
316 break;
317 }
318 } else if (IfrOpCodeHeader->Scope != 0) {
319 Scope++;
320 }
321
322 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
323 }
324 }
325 }
326 default:
327 break;
328 }
329
330 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
331 }
332
333 break;
334 default:
335 break;
336 }
337}
338
346VOID
348 IN VOID *HiiDatabase,
349 IN UINTN HiiDatabaseSize
350 )
351{
352 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader;
353 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
354
355 DEBUG ((DEBUG_INFO, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize));
356 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)HiiDatabase;
357
358 while ((UINTN)HiiPackageListHeader < ((UINTN)HiiDatabase + HiiDatabaseSize)) {
359 DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader->PackageListGuid));
360 DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN)HiiPackageListHeader->PackageLength));
361 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1);
362
363 while ((UINTN)HiiPackageHeader < (UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength) {
364 DumpHiiPackage (HiiPackageHeader);
365
366 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)HiiPackageHeader + HiiPackageHeader->Length);
367 }
368
369 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength);
370 }
371
372 return;
373}
374
375#endif
376
390VOID *
392 IN EFI_MEMORY_TYPE MemoryType,
393 IN UINTN AllocationSize
394 )
395{
396 EFI_STATUS Status;
397 VOID *Memory;
398
399 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
400 if (EFI_ERROR (Status)) {
401 Memory = NULL;
402 }
403
404 return Memory;
405}
406
420VOID *
422 IN UINTN AllocationSize
423 )
424{
425 VOID *Memory;
426
427 Memory = InternalVarCheckAllocatePool (EfiBootServicesData, AllocationSize);
428 if (Memory != NULL) {
429 Memory = ZeroMem (Memory, AllocationSize);
430 }
431
432 return Memory;
433}
434
449VOID
450EFIAPI
452 IN VOID *Buffer
453 )
454{
455 EFI_STATUS Status;
456
457 Status = gBS->FreePool (Buffer);
458 ASSERT_EFI_ERROR (Status);
459}
460
482VOID *
484 IN UINTN OldSize,
485 IN UINTN NewSize,
486 IN VOID *OldBuffer OPTIONAL
487 )
488{
489 VOID *NewBuffer;
490
491 NewBuffer = InternalVarCheckAllocateZeroPool (NewSize);
492 if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
493 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
494 InternalVarCheckFreePool (OldBuffer);
495 }
496
497 return NewBuffer;
498}
499
508VOID
510 IN OUT VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode,
512 IN BOOLEAN FromFv
513 )
514{
515 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion1;
516 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion2;
517 VAR_CHECK_HII_QUESTION_HEADER *NewHiiQuestion;
518 UINT8 NewLength;
519 UINT64 Minimum1;
520 UINT64 Maximum1;
521 UINT64 OneValue1;
522 UINT64 Minimum2;
523 UINT64 Maximum2;
524 UINT64 OneValue2;
525 UINT8 *Ptr;
526 UINT8 *Ptr1;
527 UINT8 *Ptr2;
528 UINTN ArrayIndex;
529
530 //
531 // Hii Question from Hii Database has high priority.
532 // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
533 //
534 if (FromFv) {
535 InternalVarCheckFreePool (HiiQuestion);
536 return;
537 }
538
539 if (HiiQuestion->BitFieldStore) {
540 ArrayIndex = HiiQuestion->VarOffset;
541 } else {
542 ArrayIndex = HiiQuestion->VarOffset * 8;
543 }
544
545 HiiQuestion1 = HiiVariableNode->HiiQuestionArray[ArrayIndex];
546 HiiQuestion2 = HiiQuestion;
547
548 ASSERT ((HiiQuestion1->OpCode == HiiQuestion2->OpCode) && (HiiQuestion1->StorageWidth == HiiQuestion2->StorageWidth));
549
550 switch (HiiQuestion1->OpCode) {
551 case EFI_IFR_ONE_OF_OP:
552 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level")));
553 //
554 // Get the length of Hii Question 1.
555 //
556 NewLength = HiiQuestion1->Length;
557
558 //
559 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
560 //
561 Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion2 + 1);
562 while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
563 OneValue2 = 0;
564 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
565
566 Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion1 + 1);
567 while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
568 OneValue1 = 0;
569 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
570 if (OneValue2 == OneValue1) {
571 //
572 // Match
573 //
574 break;
575 }
576
577 Ptr1 += HiiQuestion1->StorageWidth;
578 }
579
580 if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
581 //
582 // No match
583 //
584 NewLength = (UINT8)(NewLength + HiiQuestion1->StorageWidth);
585 }
586
587 Ptr2 += HiiQuestion2->StorageWidth;
588 }
589
590 if (NewLength > HiiQuestion1->Length) {
591 //
592 // Merge the one of options of Hii Question 2 and Hii Question 1.
593 //
594 NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
595 ASSERT (NewHiiQuestion != NULL);
596 CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
597 //
598 // Use the new length.
599 //
600 NewHiiQuestion->Length = NewLength;
601 Ptr = (UINT8 *)NewHiiQuestion + HiiQuestion1->Length;
602
603 Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion2 + 1);
604 while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
605 OneValue2 = 0;
606 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
607
608 Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion1 + 1);
609 while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
610 OneValue1 = 0;
611 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
612 if (OneValue2 == OneValue1) {
613 //
614 // Match
615 //
616 break;
617 }
618
619 Ptr1 += HiiQuestion1->StorageWidth;
620 }
621
622 if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
623 //
624 // No match
625 //
626 CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
627 Ptr += HiiQuestion1->StorageWidth;
628 }
629
630 Ptr2 += HiiQuestion2->StorageWidth;
631 }
632
633 HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;
634 InternalVarCheckFreePool (HiiQuestion1);
635 }
636
637 break;
638
639 case EFI_IFR_CHECKBOX_OP:
640 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level")));
641 break;
642
643 case EFI_IFR_NUMERIC_OP:
644 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore ? "bit level" : "byte level")));
645 //
646 // Get minimum and maximum of Hii Question 1.
647 //
648 Minimum1 = 0;
649 Maximum1 = 0;
650 Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion1 + 1);
651 CopyMem (&Minimum1, Ptr, HiiQuestion1->StorageWidth);
652 Ptr += HiiQuestion1->StorageWidth;
653 CopyMem (&Maximum1, Ptr, HiiQuestion1->StorageWidth);
654
655 //
656 // Get minimum and maximum of Hii Question 2.
657 //
658 Minimum2 = 0;
659 Maximum2 = 0;
660 Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion2 + 1);
661 CopyMem (&Minimum2, Ptr, HiiQuestion2->StorageWidth);
662 Ptr += HiiQuestion2->StorageWidth;
663 CopyMem (&Maximum2, Ptr, HiiQuestion2->StorageWidth);
664
665 //
666 // Update minimum.
667 //
668 Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion1 + 1);
669 if (Minimum2 < Minimum1) {
670 Minimum1 = Minimum2;
671 CopyMem (Ptr, &Minimum1, HiiQuestion1->StorageWidth);
672 }
673
674 //
675 // Update maximum.
676 //
677 Ptr += HiiQuestion1->StorageWidth;
678 if (Maximum2 > Maximum1) {
679 Maximum1 = Maximum2;
680 CopyMem (Ptr, &Maximum1, HiiQuestion1->StorageWidth);
681 }
682
683 break;
684
685 case EFI_IFR_ORDERED_LIST_OP:
686 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
687 //
688 // Get the length of Hii Question 1.
689 //
690 NewLength = HiiQuestion1->Length;
691
692 //
693 // Check if the one of options in Hii Question 2 have been in Hii Question 1.
694 //
695 Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion2 + 1);
696 while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
697 OneValue2 = 0;
698 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
699
700 Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion1 + 1);
701 while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
702 OneValue1 = 0;
703 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
704 if (OneValue2 == OneValue1) {
705 //
706 // Match
707 //
708 break;
709 }
710
711 Ptr1 += HiiQuestion1->StorageWidth;
712 }
713
714 if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
715 //
716 // No match
717 //
718 NewLength = (UINT8)(NewLength + HiiQuestion1->StorageWidth);
719 }
720
721 Ptr2 += HiiQuestion2->StorageWidth;
722 }
723
724 if (NewLength > HiiQuestion1->Length) {
725 //
726 // Merge the one of options of Hii Question 2 and Hii Question 1.
727 //
728 NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
729 ASSERT (NewHiiQuestion != NULL);
730 CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
731 //
732 // Use the new length.
733 //
734 NewHiiQuestion->Length = NewLength;
735 Ptr = (UINT8 *)NewHiiQuestion + HiiQuestion1->Length;
736
737 Ptr2 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion2 + 1);
738 while ((UINTN)Ptr2 < (UINTN)HiiQuestion2 + HiiQuestion2->Length) {
739 OneValue2 = 0;
740 CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
741
742 Ptr1 = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion1 + 1);
743 while ((UINTN)Ptr1 < (UINTN)HiiQuestion1 + HiiQuestion1->Length) {
744 OneValue1 = 0;
745 CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
746 if (OneValue2 == OneValue1) {
747 //
748 // Match
749 //
750 break;
751 }
752
753 Ptr1 += HiiQuestion1->StorageWidth;
754 }
755
756 if ((UINTN)Ptr1 >= ((UINTN)HiiQuestion1 + HiiQuestion1->Length)) {
757 //
758 // No match
759 //
760 CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
761 Ptr += HiiQuestion1->StorageWidth;
762 }
763
764 Ptr2 += HiiQuestion2->StorageWidth;
765 }
766
767 HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;
768 InternalVarCheckFreePool (HiiQuestion1);
769 }
770
771 break;
772
773 default:
774 ASSERT (FALSE);
775 return;
776 break;
777 }
778
779 //
780 //
781 // Hii Question 2 has been merged with Hii Question 1.
782 //
783 InternalVarCheckFreePool (HiiQuestion2);
784}
785
795VOID
797 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
798 OUT UINTN *Count,
799 OUT UINT8 *Width,
800 OUT VOID *OptionBuffer OPTIONAL
801 )
802{
803 UINTN Scope;
804 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
805
806 //
807 // Assume all OPTION has same Width.
808 //
809 *Count = 0;
810
811 if (IfrOpCodeHeader->Scope != 0) {
812 //
813 // Nested OpCode.
814 //
815 Scope = 1;
816 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
817 while (Scope != 0) {
818 switch (IfrOpCodeHeader->OpCode) {
819 case EFI_IFR_ONE_OF_OPTION_OP:
820 IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader;
821 switch (IfrOneOfOption->Type) {
822 case EFI_IFR_TYPE_NUM_SIZE_8:
823 *Count = *Count + 1;
824 *Width = sizeof (UINT8);
825 if (OptionBuffer != NULL) {
826 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u8, sizeof (UINT8));
827 OptionBuffer = (UINT8 *)OptionBuffer + 1;
828 }
829
830 break;
831 case EFI_IFR_TYPE_NUM_SIZE_16:
832 *Count = *Count + 1;
833 *Width = sizeof (UINT16);
834 if (OptionBuffer != NULL) {
835 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u16, sizeof (UINT16));
836 OptionBuffer = (UINT16 *)OptionBuffer + 1;
837 }
838
839 break;
840 case EFI_IFR_TYPE_NUM_SIZE_32:
841 *Count = *Count + 1;
842 *Width = sizeof (UINT32);
843 if (OptionBuffer != NULL) {
844 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u32, sizeof (UINT32));
845 OptionBuffer = (UINT32 *)OptionBuffer + 1;
846 }
847
848 break;
849 case EFI_IFR_TYPE_NUM_SIZE_64:
850 *Count = *Count + 1;
851 *Width = sizeof (UINT64);
852 if (OptionBuffer != NULL) {
853 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u64, sizeof (UINT64));
854 OptionBuffer = (UINT64 *)OptionBuffer + 1;
855 }
856
857 break;
858 case EFI_IFR_TYPE_BOOLEAN:
859 *Count = *Count + 1;
860 *Width = sizeof (BOOLEAN);
861 if (OptionBuffer != NULL) {
862 CopyMem (OptionBuffer, &IfrOneOfOption->Value.b, sizeof (BOOLEAN));
863 OptionBuffer = (BOOLEAN *)OptionBuffer + 1;
864 }
865
866 break;
867 default:
868 break;
869 }
870
871 break;
872 }
873
874 //
875 // Until End OpCode.
876 //
877 if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
878 ASSERT (Scope > 0);
879 Scope--;
880 if (Scope == 0) {
881 break;
882 }
883 } else if (IfrOpCodeHeader->Scope != 0) {
884 //
885 // Nested OpCode.
886 //
887 Scope++;
888 }
889
890 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
891 }
892 }
893
894 return;
895}
896
908 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
909 IN BOOLEAN StoredInBitField
910 )
911{
912 EFI_IFR_ONE_OF *IfrOneOf;
914 UINTN Length;
915 UINT8 Width;
916 UINTN OptionCount;
917 UINT8 OptionWidth;
918 UINT8 BitWidth;
919
920 IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpCodeHeader;
921 BitWidth = 0;
922
923 if (StoredInBitField) {
924 //
925 // When OneOf stored in bit field, the bit width is saved in the lower six bits of the flag.
926 // And the options in the OneOf is saved as UINT32 type.
927 //
928 BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
929 Width = sizeof (UINT32);
930 } else {
931 Width = (UINT8)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
932 }
933
934 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
935 ASSERT (Width == OptionWidth);
936
937 Length = sizeof (*OneOf) + OptionCount * Width;
938
939 OneOf = InternalVarCheckAllocateZeroPool (Length);
940 ASSERT (OneOf != NULL);
941 OneOf->OpCode = EFI_IFR_ONE_OF_OP;
942 OneOf->Length = (UINT8)Length;
943 OneOf->VarOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;
944 OneOf->BitFieldStore = StoredInBitField;
945 if (StoredInBitField) {
946 OneOf->StorageWidth = BitWidth;
947 } else {
948 OneOf->StorageWidth = Width;
949 }
950
951 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OneOf + 1);
952
953 return (VAR_CHECK_HII_QUESTION_HEADER *)OneOf;
954}
955
967 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
968 IN BOOLEAN StoredInBitField
969 )
970{
971 EFI_IFR_CHECKBOX *IfrCheckBox;
973
974 IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;
975
976 CheckBox = InternalVarCheckAllocateZeroPool (sizeof (*CheckBox));
977 ASSERT (CheckBox != NULL);
978 CheckBox->OpCode = EFI_IFR_CHECKBOX_OP;
979 CheckBox->Length = (UINT8)sizeof (*CheckBox);
980 CheckBox->VarOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
981 CheckBox->BitFieldStore = StoredInBitField;
982 if (StoredInBitField) {
983 CheckBox->StorageWidth = 1;
984 } else {
985 CheckBox->StorageWidth = (UINT8)sizeof (BOOLEAN);
986 }
987
988 return (VAR_CHECK_HII_QUESTION_HEADER *)CheckBox;
989}
990
1002 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
1003 IN BOOLEAN StoredInBitField
1004 )
1005{
1006 EFI_IFR_NUMERIC *IfrNumeric;
1008 UINT8 Width;
1009 UINT8 BitWidth;
1010
1011 IfrNumeric = (EFI_IFR_NUMERIC *)IfrOpCodeHeader;
1012 BitWidth = 0;
1013
1014 Numeric = InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * sizeof (UINT64));
1015 ASSERT (Numeric != NULL);
1016
1017 if (StoredInBitField) {
1018 //
1019 // When Numeric stored in bit field, the bit field width is saved in the lower six bits of the flag.
1020 // And the Minimum Maximum of Numeric is saved as UINT32 type.
1021 //
1022 BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
1023 Width = sizeof (UINT32);
1024 } else {
1025 Width = (UINT8)(1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
1026 }
1027
1028 Numeric->OpCode = EFI_IFR_NUMERIC_OP;
1029 Numeric->Length = (UINT8)(sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * Width);
1030 Numeric->VarOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;
1031 Numeric->BitFieldStore = StoredInBitField;
1032 if (StoredInBitField) {
1033 Numeric->StorageWidth = BitWidth;
1034 } else {
1035 Numeric->StorageWidth = Width;
1036 }
1037
1038 CopyMem (Numeric + 1, &IfrNumeric->data, Width * 2);
1039
1040 return (VAR_CHECK_HII_QUESTION_HEADER *)Numeric;
1041}
1042
1053 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader
1054 )
1055{
1056 EFI_IFR_ORDERED_LIST *IfrOrderedList;
1058 UINTN Length;
1059 UINTN OptionCount;
1060 UINT8 OptionWidth;
1061
1062 IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpCodeHeader;
1063
1064 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
1065
1066 Length = sizeof (*OrderedList) + OptionCount * OptionWidth;
1067
1068 OrderedList = InternalVarCheckAllocateZeroPool (Length);
1069 ASSERT (OrderedList != NULL);
1070 OrderedList->OpCode = EFI_IFR_ORDERED_LIST_OP;
1071 OrderedList->Length = (UINT8)Length;
1072 OrderedList->VarOffset = IfrOrderedList->Question.VarStoreInfo.VarOffset;
1073 OrderedList->StorageWidth = OptionWidth;
1074 OrderedList->MaxContainers = IfrOrderedList->MaxContainers;
1075 OrderedList->BitFieldStore = FALSE;
1076
1077 GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OrderedList + 1);
1078
1079 return (VAR_CHECK_HII_QUESTION_HEADER *)OrderedList;
1080}
1081
1091VOID
1093 IN VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode,
1094 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,
1095 IN BOOLEAN FromFv,
1096 IN BOOLEAN StoredInBitField
1097 )
1098{
1099 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
1100 UINTN ArrayIndex;
1101
1102 //
1103 // Currently only OneOf, CheckBox and Numeric can be stored in bit field.
1104 //
1105 switch (IfrOpCodeHeader->OpCode) {
1106 case EFI_IFR_ONE_OF_OP:
1107 HiiQuestion = ParseHiiQuestionOneOf (IfrOpCodeHeader, StoredInBitField);
1108 break;
1109
1110 case EFI_IFR_CHECKBOX_OP:
1111 HiiQuestion = ParseHiiQuestionCheckBox (IfrOpCodeHeader, StoredInBitField);
1112 break;
1113
1114 case EFI_IFR_NUMERIC_OP:
1115 HiiQuestion = ParseHiiQuestionNumeric (IfrOpCodeHeader, StoredInBitField);
1116 break;
1117
1118 case EFI_IFR_ORDERED_LIST_OP:
1119 HiiQuestion = ParseHiiQuestionOrderedList (IfrOpCodeHeader);
1120 break;
1121
1122 default:
1123 ASSERT (FALSE);
1124 return;
1125 break;
1126 }
1127
1128 if (StoredInBitField) {
1129 ArrayIndex = HiiQuestion->VarOffset;
1130 } else {
1131 ArrayIndex = HiiQuestion->VarOffset * 8;
1132 }
1133
1134 if (HiiVariableNode->HiiQuestionArray[ArrayIndex] != NULL) {
1135 MergeHiiQuestion (HiiVariableNode, HiiQuestion, FromFv);
1136 } else {
1137 HiiVariableNode->HiiQuestionArray[ArrayIndex] = HiiQuestion;
1138 }
1139}
1140
1152 IN CHAR16 *Name,
1153 IN EFI_GUID *Guid
1154 )
1155{
1156 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1157 LIST_ENTRY *Link;
1158
1159 for (Link = mVarCheckHiiList.ForwardLink
1160 ; Link != &mVarCheckHiiList
1161 ; Link = Link->ForwardLink)
1162 {
1163 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
1164
1165 if ((StrCmp (Name, (CHAR16 *)(HiiVariableNode->HiiVariable + 1)) == 0) &&
1166 CompareGuid (Guid, &HiiVariableNode->HiiVariable->Guid))
1167 {
1168 return HiiVariableNode;
1169 }
1170 }
1171
1172 return NULL;
1173}
1174
1185 IN EFI_VARSTORE_ID VarStoreId
1186 )
1187{
1188 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1189 LIST_ENTRY *Link;
1190
1191 if (VarStoreId == 0) {
1192 //
1193 // The variable store identifier, which is unique within the current form set.
1194 // A value of zero is invalid.
1195 //
1196 return NULL;
1197 }
1198
1199 for (Link = mVarCheckHiiList.ForwardLink
1200 ; Link != &mVarCheckHiiList
1201 ; Link = Link->ForwardLink)
1202 {
1203 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
1204 //
1205 // The variable store identifier, which is unique within the current form set.
1206 //
1207 if (VarStoreId == HiiVariableNode->VarStoreId) {
1208 return HiiVariableNode;
1209 }
1210 }
1211
1212 return NULL;
1213}
1214
1219VOID
1221 VOID
1222 )
1223{
1224 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1225 LIST_ENTRY *Link;
1226
1227 for (Link = mVarCheckHiiList.ForwardLink
1228 ; Link != &mVarCheckHiiList
1229 ; Link = Link->ForwardLink)
1230 {
1231 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
1232 //
1233 // The variable store identifier, which is unique within the current form set.
1234 // A value of zero is invalid.
1235 //
1236 HiiVariableNode->VarStoreId = 0;
1237 }
1238}
1239
1246VOID
1248 IN EFI_IFR_VARSTORE_EFI *IfrEfiVarStore
1249 )
1250{
1251 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1252 VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
1253 UINTN HeaderLength;
1254 CHAR16 *VarName;
1255 UINTN VarNameSize;
1256
1257 //
1258 // Get variable name.
1259 //
1260 VarNameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16);
1261 if (VarNameSize > mMaxVarNameSize) {
1262 mVarName = InternalVarCheckReallocatePool (mMaxVarNameSize, VarNameSize, mVarName);
1263 ASSERT (mVarName != NULL);
1264 mMaxVarNameSize = VarNameSize;
1265 }
1266
1267 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, mVarName, mMaxVarNameSize / sizeof (CHAR16));
1268 VarName = mVarName;
1269
1270 HiiVariableNode = FindHiiVariableNode (
1271 VarName,
1272 &IfrEfiVarStore->Guid
1273 );
1274 if (HiiVariableNode == NULL) {
1275 //
1276 // Not found, then create new.
1277 //
1278 HeaderLength = sizeof (*HiiVariable) + VarNameSize;
1279 HiiVariable = InternalVarCheckAllocateZeroPool (HeaderLength);
1280 ASSERT (HiiVariable != NULL);
1281 HiiVariable->Revision = VAR_CHECK_HII_REVISION;
1282 HiiVariable->OpCode = EFI_IFR_VARSTORE_EFI_OP;
1283 HiiVariable->HeaderLength = (UINT16)HeaderLength;
1284 HiiVariable->Size = IfrEfiVarStore->Size;
1285 HiiVariable->Attributes = IfrEfiVarStore->Attributes;
1286 CopyGuid (&HiiVariable->Guid, &IfrEfiVarStore->Guid);
1287 StrCpyS ((CHAR16 *)(HiiVariable + 1), VarNameSize / sizeof (CHAR16), VarName);
1288
1289 HiiVariableNode = InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode));
1290 ASSERT (HiiVariableNode != NULL);
1291 HiiVariableNode->Signature = VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE;
1292 HiiVariableNode->HiiVariable = HiiVariable;
1293 //
1294 // The variable store identifier, which is unique within the current form set.
1295 //
1296 HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
1297 HiiVariableNode->HiiQuestionArray = InternalVarCheckAllocateZeroPool (IfrEfiVarStore->Size * 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER *));
1298
1299 InsertTailList (&mVarCheckHiiList, &HiiVariableNode->Link);
1300 } else {
1301 HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
1302 }
1303}
1304
1311VOID
1313 IN VOID *HiiPackage
1314 )
1315{
1316 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
1317 EFI_IFR_OP_HEADER *IfrOpCodeHeader;
1318 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
1319
1320 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
1321
1322 switch (HiiPackageHeader->Type) {
1323 case EFI_HII_PACKAGE_FORMS:
1324 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
1325
1326 while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {
1327 switch (IfrOpCodeHeader->OpCode) {
1328 case EFI_IFR_VARSTORE_EFI_OP:
1329 //
1330 // Come to EFI VARSTORE in Form Package.
1331 //
1332 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpCodeHeader;
1333 if ((IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) &&
1334 ((IfrEfiVarStore->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0))
1335 {
1336 //
1337 // Only create node list for Hii Variable with NV attribute.
1338 //
1339 CreateHiiVariableNode (IfrEfiVarStore);
1340 }
1341
1342 break;
1343
1344 default:
1345 break;
1346 }
1347
1348 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
1349 }
1350
1351 break;
1352
1353 default:
1354 break;
1355 }
1356}
1357
1365VOID
1367 IN VOID *HiiPackage,
1368 IN BOOLEAN FromFv
1369 )
1370{
1371 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
1372 EFI_IFR_OP_HEADER *IfrOpCodeHeader;
1373 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1374 BOOLEAN QuestionStoredInBitField;
1375
1376 //
1377 // Parse and create Hii Variable node list for this Hii Package.
1378 //
1379 ParseHiiVariable (HiiPackage);
1380
1381 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
1382
1383 QuestionStoredInBitField = FALSE;
1384
1385 switch (HiiPackageHeader->Type) {
1386 case EFI_HII_PACKAGE_FORMS:
1387 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
1388
1389 while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {
1390 switch (IfrOpCodeHeader->OpCode) {
1391 case EFI_IFR_GUID_OP:
1392 if (CompareGuid ((EFI_GUID *)((UINTN)IfrOpCodeHeader + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
1393 QuestionStoredInBitField = TRUE;
1394 }
1395
1396 break;
1397
1398 case EFI_IFR_END_OP:
1399 QuestionStoredInBitField = FALSE;
1400 break;
1401
1402 case EFI_IFR_ONE_OF_OP:
1403 case EFI_IFR_CHECKBOX_OP:
1404 case EFI_IFR_NUMERIC_OP:
1405 case EFI_IFR_ORDERED_LIST_OP:
1406 HiiVariableNode = FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.VarStoreId);
1407 if ((HiiVariableNode == NULL) ||
1408 //
1409 // No related Hii Variable node found.
1410 //
1411 ((((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Prompt == 0) && (((EFI_IFR_ONE_OF *)IfrOpCodeHeader)->Question.Header.Help == 0)))
1412 {
1413 //
1414 // meanless IFR item introduced by ECP.
1415 //
1416 } else {
1417 //
1418 // Normal IFR
1419 //
1420 ParseHiiQuestion (HiiVariableNode, IfrOpCodeHeader, FromFv, QuestionStoredInBitField);
1421 }
1422
1423 default:
1424 break;
1425 }
1426
1427 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
1428 }
1429
1430 break;
1431
1432 default:
1433 break;
1434 }
1435
1437}
1438
1446VOID
1448 IN VOID *HiiDatabase,
1449 IN UINTN HiiDatabaseSize
1450 )
1451{
1452 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader;
1453 EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
1454
1455 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)HiiDatabase;
1456
1457 while ((UINTN)HiiPackageListHeader < ((UINTN)HiiDatabase + HiiDatabaseSize)) {
1458 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1);
1459
1460 while ((UINTN)HiiPackageHeader < ((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength)) {
1461 //
1462 // Parse Hii Package.
1463 //
1464 VarCheckParseHiiPackage (HiiPackageHeader, FALSE);
1465
1466 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)HiiPackageHeader + HiiPackageHeader->Length);
1467 }
1468
1469 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)((UINTN)HiiPackageListHeader + HiiPackageListHeader->PackageLength);
1470 }
1471}
1472
1477VOID
1479 VOID
1480 )
1481{
1482 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1483 LIST_ENTRY *HiiVariableLink;
1484 UINTN Index;
1485
1486 while (mVarCheckHiiList.ForwardLink != &mVarCheckHiiList) {
1487 HiiVariableLink = mVarCheckHiiList.ForwardLink;
1488 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
1489
1490 RemoveEntryList (&HiiVariableNode->Link);
1491
1492 //
1493 // Free the allocated buffer.
1494 //
1495 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) {
1496 if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
1497 InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray[Index]);
1498 }
1499 }
1500
1501 InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray);
1502 InternalVarCheckFreePool (HiiVariableNode->HiiVariable);
1503 InternalVarCheckFreePool (HiiVariableNode);
1504 }
1505}
1506
1515VOID *
1517 IN OUT UINTN *Size
1518 )
1519{
1520 VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
1521 LIST_ENTRY *HiiVariableLink;
1522 UINTN Index;
1523 VOID *Data;
1524 UINT8 *Ptr;
1525 UINT32 BinSize;
1526 UINT32 HiiVariableLength;
1527
1528 //
1529 // Get Size
1530 //
1531 BinSize = 0;
1532
1533 for (HiiVariableLink = mVarCheckHiiList.ForwardLink
1534 ; HiiVariableLink != &mVarCheckHiiList
1535 ; HiiVariableLink = HiiVariableLink->ForwardLink)
1536 {
1537 //
1538 // For Hii Variable header align.
1539 //
1540 BinSize = (UINT32)HEADER_ALIGN (BinSize);
1541
1542 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
1543 HiiVariableLength = HiiVariableNode->HiiVariable->HeaderLength;
1544
1545 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) {
1546 if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
1547 //
1548 // For Hii Question header align.
1549 //
1550 HiiVariableLength = (UINT32)HEADER_ALIGN (HiiVariableLength);
1551 HiiVariableLength += HiiVariableNode->HiiQuestionArray[Index]->Length;
1552 }
1553 }
1554
1555 HiiVariableNode->HiiVariable->Length = HiiVariableLength;
1556 BinSize += HiiVariableLength;
1557 }
1558
1559 DEBUG ((DEBUG_INFO, "VarCheckHiiBin - size = 0x%x\n", BinSize));
1560 if (BinSize == 0) {
1561 *Size = BinSize;
1562 return NULL;
1563 }
1564
1565 //
1566 // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation.
1567 // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
1568 // in SetVariable check handler.
1569 //
1570 Data = AllocateRuntimeZeroPool (BinSize);
1571 ASSERT (Data != NULL);
1572 //
1573 // Make sure the allocated buffer for VarCheckHiiBin at required alignment.
1574 //
1575 ASSERT ((((UINTN)Data) & (HEADER_ALIGNMENT - 1)) == 0);
1576 DEBUG ((DEBUG_INFO, "VarCheckHiiBin - built at 0x%x\n", Data));
1577
1578 //
1579 // Gen Data
1580 //
1581 Ptr = Data;
1582 for (HiiVariableLink = mVarCheckHiiList.ForwardLink
1583 ; HiiVariableLink != &mVarCheckHiiList
1584 ; HiiVariableLink = HiiVariableLink->ForwardLink)
1585 {
1586 //
1587 // For Hii Variable header align.
1588 //
1589 Ptr = (UINT8 *)HEADER_ALIGN (Ptr);
1590
1591 HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
1592 CopyMem (Ptr, HiiVariableNode->HiiVariable, HiiVariableNode->HiiVariable->HeaderLength);
1593 Ptr += HiiVariableNode->HiiVariable->HeaderLength;
1594
1595 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN)8; Index++) {
1596 if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
1597 //
1598 // For Hii Question header align.
1599 //
1600 Ptr = (UINT8 *)HEADER_ALIGN (Ptr);
1601 CopyMem (Ptr, HiiVariableNode->HiiQuestionArray[Index], HiiVariableNode->HiiQuestionArray[Index]->Length);
1602 Ptr += HiiVariableNode->HiiQuestionArray[Index]->Length;
1603 }
1604 }
1605 }
1606
1607 *Size = BinSize;
1608 return Data;
1609}
1610
1615VOID
1616EFIAPI
1618 VOID
1619 )
1620{
1623
1624 mVarCheckHiiBin = BuildVarCheckHiiBin (&mVarCheckHiiBinSize);
1625 if (mVarCheckHiiBin == NULL) {
1626 DEBUG ((DEBUG_INFO, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
1627 return;
1628 }
1629
1631 if (mVarName != NULL) {
1632 InternalVarCheckFreePool (mVarName);
1633 }
1634
1635 #ifdef DUMP_VAR_CHECK_HII
1636 DEBUG_CODE (
1637 DumpVarCheckHii (mVarCheckHiiBin, mVarCheckHiiBinSize);
1638 );
1639 #endif
1640}
UINT64 UINTN
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2904
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2873
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateRuntimeZeroPool(IN UINTN AllocationSize)
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
EFI_BOOT_SERVICES * gBS
EFI_MEMORY_TYPE
@ EfiBootServicesData
#define EFI_VARIABLE_NON_VOLATILE
VOID DumpVarCheckHii(IN VOID *VarCheckHiiBin, IN UINTN VarCheckHiiBinSize)
VOID ParseHiiVariable(IN VOID *HiiPackage)
VOID CreateHiiVariableNode(IN EFI_IFR_VARSTORE_EFI *IfrEfiVarStore)
VAR_CHECK_HII_QUESTION_HEADER * ParseHiiQuestionOneOf(IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, IN BOOLEAN StoredInBitField)
VAR_CHECK_HII_QUESTION_HEADER * ParseHiiQuestionOrderedList(IN EFI_IFR_OP_HEADER *IfrOpCodeHeader)
VOID EFIAPI VarCheckHiiGen(VOID)
VOID DestroyHiiVariableNode(VOID)
VAR_CHECK_HII_VARIABLE_NODE * FindHiiVariableNodeByVarStoreId(IN EFI_VARSTORE_ID VarStoreId)
VOID GetOneOfOption(IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, OUT UINTN *Count, OUT UINT8 *Width, OUT VOID *OptionBuffer OPTIONAL)
VOID * BuildVarCheckHiiBin(IN OUT UINTN *Size)
VOID ParseHiiQuestion(IN VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode, IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, IN BOOLEAN FromFv, IN BOOLEAN StoredInBitField)
VOID EFIAPI InternalVarCheckFreePool(IN VOID *Buffer)
VOID VarCheckParseHiiPackage(IN VOID *HiiPackage, IN BOOLEAN FromFv)
VAR_CHECK_HII_VARIABLE_NODE * FindHiiVariableNode(IN CHAR16 *Name, IN EFI_GUID *Guid)
VAR_CHECK_HII_QUESTION_HEADER * ParseHiiQuestionNumeric(IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, IN BOOLEAN StoredInBitField)
VOID * InternalVarCheckReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID * InternalVarCheckAllocatePool(IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize)
VOID * InternalVarCheckAllocateZeroPool(IN UINTN AllocationSize)
VOID MergeHiiQuestion(IN OUT VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode, IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion, IN BOOLEAN FromFv)
VOID VarCheckParseHiiDatabase(IN VOID *HiiDatabase, IN UINTN HiiDatabaseSize)
VOID DestroyVarStoreId(VOID)
VAR_CHECK_HII_QUESTION_HEADER * ParseHiiQuestionCheckBox(IN EFI_IFR_OP_HEADER *IfrOpCodeHeader, IN BOOLEAN StoredInBitField)
VOID VarCheckHiiGenFromFv(VOID)
VOID DumpHiiDatabase(IN VOID *HiiDatabase, IN UINTN HiiDatabaseSize)
VOID DumpHiiPackage(IN VOID *HiiPackage)
VOID VarCheckHiiGenFromHiiDatabase(VOID)
#define HEADER_ALIGNMENT
Definition: Base.h:213