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