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