]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / VarCheckHiiLib / VarCheckHiiGen.c
CommitLineData
1241af95
SZ
1/** @file\r
2 Var Check Hii bin generation.\r
3\r
427b2f41 4Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
1241af95
SZ
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
fe69b398 54 for (Index = 0; Index < ARRAY_SIZE (mIfrOpCodeStringTable); Index++) {\r
1241af95
SZ
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
fe69b398 93 for (Index = 0; Index < ARRAY_SIZE (mPackageTypeStringTable); Index++) {\r
1241af95
SZ
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
8182e9f4 117 BOOLEAN QuestionStoredInBitField;\r
1241af95
SZ
118\r
119 HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;\r
8182e9f4 120 QuestionStoredInBitField = FALSE;\r
1241af95 121\r
c9a7f343
DB
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
1241af95
SZ
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
c9a7f343
DB
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
1241af95
SZ
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
c9a7f343
DB
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
1241af95
SZ
153 }\r
154 break;\r
155\r
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4 166 DEBUG ((DEBUG_INFO, " IfrOpCodeHeader->OpCode - 0x%02x (%a) (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode), (QuestionStoredInBitField? "bit level": "byte level")));\r
c9a7f343
DB
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
8182e9f4 173 DEBUG ((DEBUG_INFO, " VarStoreInfo - 0x%04x (%a)\n", ((EFI_IFR_ONE_OF * )IfrOpCodeHeader)->Question.VarStoreInfo.VarOffset, (QuestionStoredInBitField? "bit level": "byte level")));\r
1241af95
SZ
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
c9a7f343 183 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOneOf->Flags));\r
8182e9f4
DB
184 if (QuestionStoredInBitField) {\r
185 //\r
186 // For OneOf stored in bit field, the option value are saved as UINT32 type.\r
187 //\r
c9a7f343
DB
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
8182e9f4
DB
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
1241af95
SZ
214 }\r
215 break;\r
216 case EFI_IFR_CHECKBOX_OP:\r
217 IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpCodeHeader;\r
c9a7f343 218 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrCheckBox->Flags));\r
1241af95
SZ
219 break;\r
220 case EFI_IFR_NUMERIC_OP:\r
221 IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpCodeHeader;\r
c9a7f343 222 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrNumeric->Flags));\r
8182e9f4
DB
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
c9a7f343
DB
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
8182e9f4
DB
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
1241af95
SZ
253 }\r
254 break;\r
255 case EFI_IFR_ORDERED_LIST_OP:\r
256 IfrOrderedList = (EFI_IFR_ORDERED_LIST *) IfrOpCodeHeader;\r
c9a7f343
DB
257 DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", IfrOrderedList->MaxContainers));\r
258 DEBUG ((DEBUG_INFO, " Flags - 0x%02x\n", IfrOrderedList->Flags));\r
1241af95
SZ
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
c9a7f343
DB
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
1241af95
SZ
279 switch (IfrOneOfOption->Type) {\r
280 case EFI_IFR_TYPE_NUM_SIZE_8:\r
c9a7f343 281 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.u8));\r
1241af95
SZ
282 break;\r
283 case EFI_IFR_TYPE_NUM_SIZE_16:\r
c9a7f343 284 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%04x\n", IfrOneOfOption->Value.u16));\r
1241af95
SZ
285 break;\r
286 case EFI_IFR_TYPE_NUM_SIZE_32:\r
c9a7f343 287 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%08x\n", IfrOneOfOption->Value.u32));\r
1241af95
SZ
288 break;\r
289 case EFI_IFR_TYPE_NUM_SIZE_64:\r
c9a7f343 290 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%016lx\n", IfrOneOfOption->Value.u64));\r
1241af95
SZ
291 break;\r
292 case EFI_IFR_TYPE_BOOLEAN:\r
c9a7f343 293 DEBUG ((DEBUG_INFO, "!!!! Value - 0x%02x\n", IfrOneOfOption->Value.b));\r
1241af95
SZ
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
8182e9f4 302 QuestionStoredInBitField = FALSE;\r
1241af95
SZ
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
c9a7f343 342 DEBUG ((DEBUG_INFO, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize));\r
1241af95
SZ
343 HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) HiiDatabase;\r
344\r
345 while ((UINTN) HiiPackageListHeader < ((UINTN) HiiDatabase + HiiDatabaseSize)) {\r
c9a7f343
DB
346 DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader->PackageListGuid));\r
347 DEBUG ((DEBUG_INFO, "HiiPackageListHeader->PackageLength - 0x%x\n", (UINTN)HiiPackageListHeader->PackageLength));\r
1241af95
SZ
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
427b2f41 512 UINTN ArrayIndex;\r
1241af95
SZ
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
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4 536 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore? "bit level": "byte level")));\r
1241af95
SZ
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
8182e9f4 611 HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;\r
1241af95
SZ
612 InternalVarCheckFreePool (HiiQuestion1);\r
613 }\r
614 break;\r
615\r
616 case EFI_IFR_CHECKBOX_OP:\r
8182e9f4 617 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore? "bit level": "byte level")));\r
1241af95
SZ
618 break;\r
619\r
620 case EFI_IFR_NUMERIC_OP:\r
8182e9f4 621 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x (%a)\n", HiiQuestion1->VarOffset, (HiiQuestion1->BitFieldStore? "bit level": "byte level")));\r
1241af95
SZ
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
c9a7f343 661 DEBUG ((DEBUG_INFO, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));\r
1241af95
SZ
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
8182e9f4 736 HiiVariableNode->HiiQuestionArray[ArrayIndex] = NewHiiQuestion;\r
1241af95
SZ
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
8182e9f4 862 @param[in] StoredInBitField Whether the OneOf is stored in bit field Storage.\r
1241af95
SZ
863\r
864 return Pointer to Hii Question.\r
865\r
866**/\r
867VAR_CHECK_HII_QUESTION_HEADER *\r
868ParseHiiQuestionOneOf (\r
8182e9f4
DB
869 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,\r
870 IN BOOLEAN StoredInBitField\r
1241af95
SZ
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
8182e9f4 879 UINT8 BitWidth;\r
1241af95
SZ
880\r
881 IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpCodeHeader;\r
8182e9f4 882 BitWidth = 0;\r
1241af95 883\r
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4 921 @param[in] StoredInBitField Whether the CheckBox is stored in bit field Storage.\r
1241af95
SZ
922\r
923 return Pointer to Hii Question.\r
924\r
925**/\r
926VAR_CHECK_HII_QUESTION_HEADER *\r
927ParseHiiQuestionCheckBox (\r
8182e9f4
DB
928 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,\r
929 IN BOOLEAN StoredInBitField\r
1241af95
SZ
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
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4 956 @param[in] StoredInBitField Whether the Numeric is stored in bit field Storage.\r
1241af95
SZ
957\r
958 return Pointer to Hii Question.\r
959\r
960**/\r
961VAR_CHECK_HII_QUESTION_HEADER *\r
962ParseHiiQuestionNumeric (\r
8182e9f4
DB
963 IN EFI_IFR_OP_HEADER *IfrOpCodeHeader,\r
964 IN BOOLEAN StoredInBitField\r
1241af95
SZ
965 )\r
966{\r
967 EFI_IFR_NUMERIC *IfrNumeric;\r
968 VAR_CHECK_HII_QUESTION_NUMERIC *Numeric;\r
969 UINT8 Width;\r
8182e9f4 970 UINT8 BitWidth;\r
1241af95
SZ
971\r
972 IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpCodeHeader;\r
8182e9f4 973 BitWidth = 0;\r
1241af95
SZ
974\r
975 Numeric = InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * sizeof (UINT64));\r
976 ASSERT (Numeric != NULL);\r
977\r
8182e9f4
DB
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
1241af95 988\r
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4 1036 OrderedList->BitFieldStore = FALSE;\r
1241af95
SZ
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
8182e9f4 1049 @param[in] StoredInBitField Whether the Question is stored in bit field Storage.\r
1241af95
SZ
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
8182e9f4
DB
1056 IN BOOLEAN FromFv,\r
1057 IN BOOLEAN StoredInBitField\r
1241af95
SZ
1058 )\r
1059{\r
1060 VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;\r
427b2f41 1061 UINTN ArrayIndex;\r
1241af95 1062\r
8182e9f4
DB
1063 //\r
1064 // Currently only OneOf, CheckBox and Numeric can be stored in bit field.\r
1065 //\r
1241af95
SZ
1066 switch (IfrOpCodeHeader->OpCode) {\r
1067 case EFI_IFR_ONE_OF_OP:\r
8182e9f4 1068 HiiQuestion = ParseHiiQuestionOneOf (IfrOpCodeHeader, StoredInBitField);\r
1241af95
SZ
1069 break;\r
1070\r
1071 case EFI_IFR_CHECKBOX_OP:\r
8182e9f4 1072 HiiQuestion = ParseHiiQuestionCheckBox (IfrOpCodeHeader, StoredInBitField);\r
1241af95
SZ
1073 break;\r
1074\r
1075 case EFI_IFR_NUMERIC_OP:\r
8182e9f4 1076 HiiQuestion = ParseHiiQuestionNumeric (IfrOpCodeHeader, StoredInBitField);\r
1241af95
SZ
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
8182e9f4
DB
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
1241af95
SZ
1095 MergeHiiQuestion (HiiVariableNode, HiiQuestion, FromFv);\r
1096 } else {\r
8182e9f4 1097 HiiVariableNode->HiiQuestionArray[ArrayIndex] = HiiQuestion;\r
1241af95
SZ
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
b68ccac1 1216 VarNameSize = AsciiStrSize ((CHAR8 *) IfrEfiVarStore->Name) * sizeof (CHAR16);\r
1241af95
SZ
1217 if (VarNameSize > mMaxVarNameSize) {\r
1218 mVarName = InternalVarCheckReallocatePool (mMaxVarNameSize, VarNameSize, mVarName);\r
1219 ASSERT (mVarName != NULL);\r
1220 mMaxVarNameSize = VarNameSize;\r
1221 }\r
b68ccac1 1222 AsciiStrToUnicodeStrS ((CHAR8 *) IfrEfiVarStore->Name, mVarName, mMaxVarNameSize / sizeof (CHAR16));\r
1241af95
SZ
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
8182e9f4 1252 HiiVariableNode->HiiQuestionArray = InternalVarCheckAllocateZeroPool (IfrEfiVarStore->Size * 8 * sizeof (VAR_CHECK_HII_QUESTION_HEADER *));\r
1241af95
SZ
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
8182e9f4 1325 BOOLEAN QuestionStoredInBitField;\r
1241af95
SZ
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
8182e9f4
DB
1334 QuestionStoredInBitField = FALSE;\r
1335\r
1241af95
SZ
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
8182e9f4
DB
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
1241af95
SZ
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
8182e9f4 1369 ParseHiiQuestion (HiiVariableNode, IfrOpCodeHeader, FromFv, QuestionStoredInBitField);\r
1241af95
SZ
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
3b28e744 1407 // Parse Hii Package.\r
1241af95
SZ
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
8182e9f4 1440 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN) 8; Index++) {\r
1241af95
SZ
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
8182e9f4 1488 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN) 8; Index++) {\r
1241af95
SZ
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
c9a7f343 1502 DEBUG ((DEBUG_INFO, "VarCheckHiiBin - size = 0x%x\n", BinSize));\r
1241af95
SZ
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
3d110afb
SZ
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
c9a7f343 1519 DEBUG ((DEBUG_INFO, "VarCheckHiiBin - built at 0x%x\n", Data));\r
1241af95
SZ
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
8182e9f4 1537 for (Index = 0; Index < HiiVariableNode->HiiVariable->Size * (UINTN) 8; Index++) {\r
1241af95
SZ
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
c9a7f343 1568 DEBUG ((DEBUG_INFO, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));\r
1241af95
SZ
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