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