]>
Commit | Line | Data |
---|---|---|
3c59d946 SZ |
1 | /** @file\r |
2 | \r | |
3 | Parser for IFR binary encoding.\r | |
4 | \r | |
5 | Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>\r | |
6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
7 | \r | |
8 | **/\r | |
9 | \r | |
10 | #include "IfrParse.h"\r | |
11 | \r | |
12 | #ifndef EDKII_IFR_BIT_VARSTORE_GUID\r | |
13 | #define EDKII_IFR_BIT_VARSTORE_GUID \\r | |
14 | {0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60 ,0xA7, 0x1D}}\r | |
15 | #endif\r | |
16 | \r | |
17 | #ifndef EDKII_IFR_NUMERIC_SIZE_BIT\r | |
18 | #define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F\r | |
19 | #endif\r | |
20 | \r | |
21 | UINT16 mStatementIndex;\r | |
22 | UINT16 mExpressionOpCodeIndex;\r | |
23 | \r | |
24 | BOOLEAN mInScopeSubtitle;\r | |
25 | BOOLEAN mInScopeSuppress;\r | |
26 | BOOLEAN mInScopeGrayOut;\r | |
27 | BOOLEAN mInScopeDisable;\r | |
28 | FORM_EXPRESSION *mSuppressExpression;\r | |
29 | FORM_EXPRESSION *mGrayOutExpression;\r | |
30 | FORM_EXPRESSION *mDisableExpression;\r | |
31 | \r | |
32 | extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r | |
33 | extern LIST_ENTRY mVarListEntry;\r | |
34 | extern LIST_ENTRY mFormSetListEntry;\r | |
35 | extern UINT32 mFormSetOrderParse;\r | |
36 | \r | |
37 | #define FORM_SET_GUID_PREFIX "Form Set GUID: "\r | |
38 | #define EFI_GUID_FORMAT "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"\r | |
39 | \r | |
40 | UINT32 mMaxCount = 0x100000;\r | |
41 | UINT32 mCount = 0;\r | |
42 | CHAR8 *mStringBuffer = NULL;\r | |
43 | static EFI_GUID gEdkiiIfrBitVarGuid = EDKII_IFR_BIT_VARSTORE_GUID;\r | |
44 | \r | |
45 | /**\r | |
46 | Produces a Null-terminated ASCII string in mStringBuffer based on a Null-terminated\r | |
47 | ASCII format string and variable argument list.\r | |
48 | \r | |
49 | @param FormatString A null-terminated ASCII format string.\r | |
50 | @param ... The variable argument list whose contents are accessed based on the\r | |
51 | format string specified by FormatString.\r | |
52 | **/\r | |
53 | VOID\r | |
54 | StringPrint (\r | |
55 | CHAR8 *FormatString,\r | |
56 | ...\r | |
57 | )\r | |
58 | {\r | |
59 | va_list Marker;\r | |
60 | INT32 Count;\r | |
61 | \r | |
62 | va_start (Marker, FormatString);\r | |
63 | Count = vsprintf (mStringBuffer + mCount, FormatString, Marker);\r | |
64 | mCount = mCount + Count;\r | |
65 | va_end (Marker);\r | |
66 | if (mCount + 0x400 > mMaxCount) {\r | |
67 | mStringBuffer[mCount] = '\0';\r | |
68 | fwrite (mStringBuffer, sizeof (CHAR8), mCount, stdout);\r | |
69 | mCount = 0;\r | |
70 | }\r | |
71 | }\r | |
72 | \r | |
73 | /**\r | |
74 | Print the information of questions.\r | |
75 | \r | |
76 | @param FormSet The pointer to the formset.\r | |
77 | @param FormSet The pointer to the form.\r | |
78 | @param Question The pointer to the question.\r | |
79 | @param PrintOrNot Decide whether print or not.\r | |
80 | \r | |
81 | @return NULL.\r | |
82 | \r | |
83 | **/\r | |
84 | static\r | |
85 | VOID\r | |
86 | PrintQuestion (\r | |
87 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
88 | IN FORM_BROWSER_FORM *Form,\r | |
89 | IN FORM_BROWSER_STATEMENT *Question,\r | |
90 | IN BOOLEAN PrintOrNot\r | |
91 | );\r | |
92 | \r | |
93 | /**\r | |
94 | Writes a Unicode string specified by iStringToken and iLanguage to the script file (converted to ASCII).\r | |
95 | \r | |
96 | @param Package A pointer to the Unicode string.\r | |
97 | \r | |
98 | @return NULL\r | |
99 | \r | |
100 | **/\r | |
101 | static\r | |
102 | VOID\r | |
103 | LogUnicodeString (\r | |
104 | IN CHAR16 *pcString\r | |
105 | )\r | |
106 | {\r | |
107 | UINTN Index;\r | |
108 | \r | |
109 | if (pcString == NULL) {\r | |
110 | return;\r | |
111 | }\r | |
112 | //\r | |
113 | // replace the 0x0D to 0x20, because if the pcString has 0D 0A, then after print it,\r | |
114 | // different editor may have different format\r | |
115 | //\r | |
116 | for (Index = 0; pcString[Index] != 0; Index++) {\r | |
117 | if (pcString[Index] == 0x0D) {\r | |
118 | pcString[Index] = 0x20;\r | |
119 | }\r | |
120 | \r | |
121 | StringPrint("%c", pcString[Index] & 0x00FF);\r | |
122 | }\r | |
123 | }\r | |
124 | \r | |
125 | /**\r | |
126 | Writes a UQIL Unicode string specified by iStringToken to the script file as an array of 16-bit integers in ASCII.\r | |
127 | \r | |
128 | @param Package A pointer to the Unicode string.\r | |
129 | \r | |
130 | @return NULL\r | |
131 | \r | |
132 | **/\r | |
133 | static\r | |
134 | VOID\r | |
135 | LogUqi (\r | |
136 | IN CHAR16 *pcString\r | |
137 | )\r | |
138 | {\r | |
139 | UINT16 Index;\r | |
140 | //\r | |
141 | // Find the UNICODE string length (in CHAR16)\r | |
142 | //\r | |
143 | for (Index = 0; pcString[Index] != 0; Index++);\r | |
144 | //\r | |
145 | // Write each word as a hex integer\r | |
146 | //\r | |
147 | for (Index = 0; pcString[Index] != 0; Index++) {\r | |
148 | StringPrint("%04X ", pcString[Index]);\r | |
149 | }\r | |
150 | }\r | |
151 | \r | |
152 | /**\r | |
153 | Get the question value with bit field from the buffer.\r | |
154 | \r | |
155 | @param Question The question refer to bit field.\r | |
156 | @param Buffer The buffer which the question value get from.\r | |
157 | @param Value Retun the value.\r | |
158 | \r | |
159 | **/\r | |
160 | VOID\r | |
161 | GetBitsQuestionValue(\r | |
162 | IN FORM_BROWSER_STATEMENT *Question,\r | |
163 | IN UINT8 *Buffer,\r | |
164 | OUT UINT32 *Value\r | |
165 | )\r | |
166 | {\r | |
167 | UINT32 PreBits;\r | |
168 | UINT32 Mask;\r | |
169 | \r | |
170 | PreBits = Question->BitVarOffset - Question->VarStoreInfo.VarOffset * 8;\r | |
171 | Mask = (1<< Question->BitStorageWidth) -1;\r | |
172 | \r | |
173 | *Value = *(UINT32*)Buffer;\r | |
174 | (*Value) >>= PreBits;\r | |
175 | (*Value) &= Mask;\r | |
176 | }\r | |
177 | \r | |
178 | /**\r | |
179 | Set the question value with bit field to the buffer.\r | |
180 | \r | |
181 | @param Question The question refer to bit field.\r | |
182 | @param Buffer The buffer which the question value set to.\r | |
183 | @param Value The value need to set.\r | |
184 | \r | |
185 | **/\r | |
186 | VOID\r | |
187 | SetBitsQuestionValue (\r | |
188 | IN FORM_BROWSER_STATEMENT *Question,\r | |
189 | IN OUT UINT8 *Buffer,\r | |
190 | IN UINT32 Value\r | |
191 | )\r | |
192 | {\r | |
193 | UINT32 PreBits;\r | |
194 | UINT32 Mask;\r | |
195 | UINT32 TmpValue;\r | |
196 | \r | |
197 | PreBits = Question->BitVarOffset - Question->VarStoreInfo.VarOffset * 8;\r | |
198 | Value <<= PreBits;\r | |
199 | Mask = (1<< Question->BitStorageWidth) -1;\r | |
200 | Mask <<= PreBits;\r | |
201 | \r | |
202 | TmpValue = *(UINT32*)(Buffer);\r | |
203 | TmpValue = (TmpValue & (~Mask)) | Value;\r | |
204 | CopyMem ((UINT32*)Buffer, &TmpValue, sizeof (UINT32));\r | |
205 | }\r | |
206 | \r | |
207 | /**\r | |
208 | Print the current value of the specified question.\r | |
209 | \r | |
210 | @param Question The pointer to question\r | |
211 | \r | |
212 | @return EFI_SUCCESS\r | |
213 | **/\r | |
214 | static\r | |
215 | EFI_STATUS\r | |
216 | LogIfrValue (\r | |
217 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
218 | IN FORM_BROWSER_STATEMENT *Question\r | |
219 | )\r | |
220 | {\r | |
221 | EFI_STATUS Status;\r | |
222 | FORMSET_STORAGE *VarList;\r | |
223 | UINT8 *VarBuffer;\r | |
224 | UINT32 Value;\r | |
225 | \r | |
226 | VarBuffer = NULL;\r | |
227 | \r | |
228 | Status = SearchVarStorage (\r | |
229 | Question,\r | |
230 | NULL,\r | |
231 | Question->VarStoreInfo.VarOffset,\r | |
232 | FormSet->StorageListHead,\r | |
233 | (CHAR8 **)&VarBuffer,\r | |
234 | &VarList\r | |
235 | );\r | |
236 | \r | |
237 | if (EFI_ERROR (Status)) {\r | |
238 | StringPrint("\nCouldn't read current variable data.");\r | |
239 | return EFI_ABORTED;\r | |
240 | }\r | |
241 | //\r | |
242 | // Log the Value\r | |
243 | //\r | |
244 | if (\r | |
245 | (Question->VarStoreInfo.VarOffset > VarList->Size) \\r | |
246 | && (VarList->Type == EFI_IFR_VARSTORE_OP)\r | |
247 | ) {\r | |
248 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
249 | } else if (\r | |
250 | (Question->VarStoreInfo.VarOffset > VarList->Size) \\r | |
251 | && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r | |
252 | && VarList->NewEfiVarstore\r | |
253 | ) {\r | |
254 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
255 | } else if (\r | |
256 | (Question->StorageWidth > VarList->Size) \\r | |
257 | && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r | |
258 | && !VarList->NewEfiVarstore\r | |
259 | ) {\r | |
260 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
261 | } else {\r | |
262 | if (Question->QuestionReferToBitField) {\r | |
263 | GetBitsQuestionValue (Question, VarBuffer, &Value);\r | |
264 | VarBuffer = (UINT8*)(&Value);\r | |
265 | }\r | |
266 | switch (Question->StorageWidth) {\r | |
267 | \r | |
268 | case sizeof (UINT8):\r | |
269 | StringPrint("%02X", (*(UINT8 *)VarBuffer) & 0xFF);\r | |
270 | break;\r | |
271 | \r | |
272 | case sizeof (UINT16):\r | |
273 | StringPrint("%04X", (*(UINT16 *)VarBuffer) & 0xFFFF);\r | |
274 | break;\r | |
275 | \r | |
276 | case sizeof (UINT32):\r | |
277 | StringPrint("%08X", (*(UINT32 *)VarBuffer) & 0xFFFFFFFF);\r | |
278 | break;\r | |
279 | \r | |
280 | case sizeof (UINT64):\r | |
281 | StringPrint("%016llX", *((UINT64 *)VarBuffer));\r | |
282 | break;\r | |
283 | \r | |
284 | default:\r | |
285 | StringPrint("0000 // Width > 16 is not supported -- FAILURE");\r | |
286 | break;\r | |
287 | }\r | |
288 | }\r | |
289 | return EFI_SUCCESS;\r | |
290 | }\r | |
291 | \r | |
292 | /**\r | |
293 | Print the current value of the STRING question.\r | |
294 | \r | |
295 | @param Question The pointer to question\r | |
296 | \r | |
297 | @return EFI_SUCCESS\r | |
298 | **/\r | |
299 | static\r | |
300 | EFI_STATUS\r | |
301 | LogIfrValueStr (\r | |
302 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
303 | IN FORM_BROWSER_STATEMENT *Question\r | |
304 | )\r | |
305 | {\r | |
306 | EFI_STATUS Status;\r | |
307 | FORMSET_STORAGE *VarList;\r | |
308 | UINT8 *VarBuffer;\r | |
309 | \r | |
310 | VarBuffer = NULL;\r | |
311 | Status = SearchVarStorage (\r | |
312 | Question,\r | |
313 | NULL,\r | |
314 | Question->VarStoreInfo.VarOffset,\r | |
315 | FormSet->StorageListHead,\r | |
316 | (CHAR8 **)&VarBuffer,\r | |
317 | &VarList\r | |
318 | );\r | |
319 | \r | |
320 | if (EFI_ERROR (Status)) {\r | |
321 | StringPrint("\nCouldn't read current variable data.");\r | |
322 | return EFI_ABORTED;\r | |
323 | }\r | |
324 | \r | |
325 | //\r | |
326 | // Log the Value\r | |
327 | //\r | |
328 | if (\r | |
329 | (Question->VarStoreInfo.VarOffset > VarList->Size) \\r | |
330 | && (VarList->Type == EFI_IFR_VARSTORE_OP)\r | |
331 | ) {\r | |
332 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
333 | } else if (\r | |
334 | (Question->VarStoreInfo.VarOffset > VarList->Size) \\r | |
335 | && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r | |
336 | && VarList->NewEfiVarstore\r | |
337 | ) {\r | |
338 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
339 | } else if (\r | |
340 | (Question->StorageWidth > VarList->Size) \\r | |
341 | && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP) \\r | |
342 | && !VarList->NewEfiVarstore\r | |
343 | ) {\r | |
344 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
345 | } else {\r | |
346 | StringPrint("\"");\r | |
347 | LogUnicodeString((CHAR16 *)VarBuffer);\r | |
348 | StringPrint("\"");\r | |
349 | }\r | |
350 | return EFI_SUCCESS;\r | |
351 | }\r | |
352 | \r | |
353 | /**\r | |
354 | Print the current values of an Ordered List question.\r | |
355 | \r | |
356 | @param Question The pointer to question\r | |
357 | @param MaxEntries The max number of options\r | |
358 | @param VarList The dual pointer to the Node of VarList\r | |
359 | \r | |
360 | @return EFI_SUCCESS\r | |
361 | **/\r | |
362 | static\r | |
363 | EFI_STATUS\r | |
364 | LogIfrValueList (\r | |
365 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
366 | IN FORM_BROWSER_STATEMENT *Question\r | |
367 | )\r | |
368 | {\r | |
369 | EFI_STATUS Status;\r | |
370 | FORMSET_STORAGE *VarList;\r | |
371 | UINT8 CurrentEntry;\r | |
372 | UINT8 *VarBuffer;\r | |
373 | \r | |
374 | CurrentEntry = 0;\r | |
375 | VarBuffer = NULL;\r | |
376 | \r | |
377 | Status = SearchVarStorage (\r | |
378 | Question,\r | |
379 | NULL,\r | |
380 | Question->VarStoreInfo.VarOffset,\r | |
381 | FormSet->StorageListHead,\r | |
382 | (CHAR8 **)&VarBuffer,\r | |
383 | &VarList\r | |
384 | );\r | |
385 | \r | |
386 | if (EFI_ERROR (Status)) {\r | |
387 | StringPrint("\nCouldn't read current variable data.");\r | |
388 | return EFI_ABORTED;\r | |
389 | }\r | |
390 | //\r | |
391 | // Log the value\r | |
392 | //\r | |
393 | if (\r | |
394 | ((Question->VarStoreInfo.VarOffset + Question->MaxContainers) > VarList->Size) \\r | |
395 | && (VarList->Type == EFI_IFR_VARSTORE_OP)\r | |
396 | ) {\r | |
397 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
398 | } else if (\r | |
399 | (Question->MaxContainers > VarList->Size) \\r | |
400 | && (VarList->Type == EFI_IFR_VARSTORE_EFI_OP)\r | |
401 | ) {\r | |
402 | StringPrint("0000 // Offset larger than Variable Size -- FAILURE");\r | |
403 | } else {\r | |
404 | for (CurrentEntry = 0; CurrentEntry < Question->MaxContainers; CurrentEntry++) {\r | |
405 | \r | |
406 | switch (Question->StorageWidth/Question->MaxContainers){\r | |
407 | \r | |
408 | case 1:\r | |
409 | StringPrint("%02X ", VarBuffer[CurrentEntry]);\r | |
410 | break;\r | |
411 | \r | |
412 | case 2:\r | |
413 | StringPrint("%04X ", *((UINT16 *)VarBuffer + CurrentEntry));\r | |
414 | break;\r | |
415 | \r | |
416 | case 4:\r | |
417 | StringPrint("%08X ", *((UINT32 *)VarBuffer + CurrentEntry));\r | |
418 | break;\r | |
419 | \r | |
420 | case 8:\r | |
421 | StringPrint("%016llX ", *((UINT64 *)VarBuffer + CurrentEntry));\r | |
422 | break;\r | |
423 | \r | |
424 | default:\r | |
425 | StringPrint("%02X ", VarBuffer[CurrentEntry]);\r | |
426 | }\r | |
427 | }\r | |
428 | }\r | |
429 | return EFI_SUCCESS;\r | |
430 | }\r | |
431 | \r | |
432 | /**\r | |
433 | Compare two Uqi parameters\r | |
434 | \r | |
435 | @param UqiParm1 The pointer to the first Uqi parameter.\r | |
436 | @param UqiParm2 The pointer to the second Uqi parameter.\r | |
437 | \r | |
438 | @retval TRUE If these two Uqi parameters are the same, return TRUE;\r | |
439 | @return FALSE Otherwise, return FALSE;\r | |
440 | **/\r | |
441 | BOOLEAN\r | |
442 | CompareUqiHeader (\r | |
443 | IN CONST UQI_HEADER *UqiParm1,\r | |
444 | IN CONST UQI_HEADER *UqiParm2\r | |
445 | )\r | |
446 | {\r | |
447 | INT32 Index;\r | |
448 | \r | |
449 | if (UqiParm1->HexNum != UqiParm2->HexNum) {\r | |
450 | return FALSE;\r | |
451 | }\r | |
452 | \r | |
453 | for (Index = UqiParm1->HexNum - 1; Index >= 0; Index--) {\r | |
454 | if (UqiParm1->Data[Index] != UqiParm2->Data[Index]) {\r | |
455 | return FALSE;\r | |
456 | }\r | |
457 | }\r | |
458 | \r | |
459 | return TRUE;\r | |
460 | }\r | |
461 | \r | |
462 | \r | |
463 | /**\r | |
464 | Check whether existed a same variable in the LIST_ENTRY.\r | |
465 | \r | |
466 | @param CurVarList A pointer to a variable node.\r | |
467 | \r | |
468 | @return Pointer If existed the same variable, return the pointer to the Node.\r | |
469 | @return NULL Otherwise, return FALSE\r | |
470 | \r | |
471 | **/\r | |
472 | static\r | |
473 | FORMSET_STORAGE *\r | |
474 | NotSameVariableInVarList (\r | |
475 | IN LIST_ENTRY *VariableListEntry,\r | |
476 | IN FORMSET_STORAGE *StorageNode\r | |
477 | )\r | |
478 | {\r | |
479 | FORMSET_STORAGE *CurNode;\r | |
480 | LIST_ENTRY *Link;\r | |
481 | LIST_ENTRY *StorageListHead;\r | |
482 | \r | |
483 | StorageListHead = VariableListEntry;\r | |
484 | CurNode = NULL;\r | |
485 | \r | |
486 | //\r | |
487 | // Find Storage for this Question\r | |
488 | //\r | |
489 | Link = GetFirstNode (StorageListHead);\r | |
490 | while (!IsNull (StorageListHead, Link)) {\r | |
491 | CurNode = FORMSET_STORAGE_FROM_LINK (Link);\r | |
492 | \r | |
493 | if (!CompareGuid (&StorageNode->Guid, &CurNode->Guid) \\r | |
494 | && (CurNode->Name != NULL) \\r | |
495 | && (StorageNode->Name != NULL) \\r | |
496 | && !FceStrCmp (StorageNode->Name, CurNode->Name) \\r | |
497 | && (StorageNode - CurNode != 0)\r | |
498 | ) {\r | |
499 | //\r | |
500 | // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are\r | |
501 | // two variables with same guid same name, but different type, we will take as the same\r | |
502 | // in general mode\r | |
503 | //\r | |
504 | if (mMultiPlatformParam.MultiPlatformOrNot && (CurNode->Type == StorageNode->Type)) {\r | |
505 | //\r | |
506 | // If matched, get the address of EFI_IFR_VARSTORE data.\r | |
507 | //\r | |
508 | return CurNode;\r | |
509 | break;\r | |
510 | } else if (!mMultiPlatformParam.MultiPlatformOrNot) {\r | |
511 | return CurNode;\r | |
512 | break;\r | |
513 | }\r | |
514 | }\r | |
515 | Link = GetNextNode (StorageListHead, Link);\r | |
516 | }\r | |
517 | return NULL;\r | |
518 | }\r | |
519 | \r | |
520 | /**\r | |
521 | Get the UniString by the offset.\r | |
522 | \r | |
523 | @param UniPackge A pointer to the beginning of Null-terminated Unicode string Array.\r | |
524 | @param CurUniPackge A pointer to the current position of Null-terminated Unicode string Array.\r | |
525 | @param VarDefaultNameId The string ID.\r | |
526 | @param CurOrDefaultLang Use the current language or the default language.\r | |
527 | @param VarDefaultName return the name string.\r | |
528 | \r | |
529 | @return EFI_SUCCESS\r | |
530 | @return EFI_INVALID_PARAMETER\r | |
531 | @return EFI_NOT_FOUND\r | |
532 | **/\r | |
533 | static\r | |
534 | EFI_STATUS\r | |
535 | GetStringByOffset (\r | |
536 | IN UINT8 *UniPackge,\r | |
537 | IN UINT8 *CurUniPackge,\r | |
538 | IN UINT16 VarDefaultNameId,\r | |
539 | IN BOOLEAN CurOrDefaultLang,\r | |
540 | IN OUT CHAR16 **VarDefaultName\r | |
541 | )\r | |
542 | {\r | |
543 | UINT8 *HiiStringHeader;\r | |
544 | UINT32 Offset;\r | |
545 | UINT32 Count;\r | |
546 | UINT32 Index;\r | |
547 | EFI_HII_STRING_BLOCK *Block;\r | |
548 | VOID *ThisBlock;\r | |
549 | \r | |
550 | assert ((UniPackge != NULL) && (CurUniPackge != NULL));\r | |
551 | \r | |
552 | HiiStringHeader = NULL;\r | |
553 | Offset = 1;\r | |
554 | Count = 0;\r | |
555 | Block = NULL;\r | |
556 | ThisBlock = NULL;\r | |
557 | \r | |
558 | if (VarDefaultNameId == 0) {\r | |
559 | return EFI_INVALID_PARAMETER;\r | |
560 | }\r | |
561 | if (CurOrDefaultLang) {\r | |
562 | HiiStringHeader = CurUniPackge;\r | |
563 | } else {\r | |
564 | HiiStringHeader = UniPackge + 4;\r | |
565 | }\r | |
566 | \r | |
567 | Block = (EFI_HII_STRING_BLOCK *)((UINT8*)HiiStringHeader + ((EFI_HII_STRING_PACKAGE_HDR *)HiiStringHeader)->HdrSize);\r | |
568 | //\r | |
569 | // Search the matched String in specificated language package by the Offset\r | |
570 | //\r | |
571 | while( Block->BlockType != EFI_HII_SIBT_END ) {\r | |
572 | switch (Block->BlockType) {\r | |
573 | case EFI_HII_SIBT_STRING_SCSU:\r | |
574 | ThisBlock = (VOID *)Block;\r | |
575 | for (Index = 0 ; ((EFI_HII_SIBT_STRING_SCSU_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
576 | Block = (EFI_HII_STRING_BLOCK *)&((EFI_HII_SIBT_STRING_SCSU_BLOCK *)ThisBlock)->StringText[Index + 1];\r | |
577 | break;\r | |
578 | \r | |
579 | case EFI_HII_SIBT_STRING_SCSU_FONT:\r | |
580 | ThisBlock = (VOID *)Block;\r | |
581 | for (Index = 0 ; ((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
582 | Block = (EFI_HII_STRING_BLOCK *)(((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK *)ThisBlock) + 1);\r | |
583 | break;\r | |
584 | \r | |
585 | case EFI_HII_SIBT_STRINGS_SCSU:\r | |
586 | ThisBlock = (VOID *)Block;\r | |
587 | for( Count= ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ThisBlock)->StringCount, Index = 0 ; Count; Count--, Index++ ) {\r | |
588 | for ( ; ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
589 | }\r | |
590 | Block = (EFI_HII_STRING_BLOCK *)&((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ThisBlock)->StringText[Index];\r | |
591 | break;\r | |
592 | \r | |
593 | case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r | |
594 | ThisBlock = (VOID *)Block;\r | |
595 | for( Count = ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ThisBlock)->StringCount, Index = 0 ; Count; Count--, Index++ ) ;\r | |
596 | Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ThisBlock)->StringText[Index];\r | |
597 | break;\r | |
598 | \r | |
599 | case EFI_HII_SIBT_STRING_UCS2:\r | |
600 | ThisBlock = (VOID *)Block;\r | |
601 | if (Offset == VarDefaultNameId) {\r | |
602 | *VarDefaultName = malloc ((FceStrLen ((CHAR16 *) ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)ThisBlock)->StringText) + 1) * sizeof (CHAR16));\r | |
603 | if (*VarDefaultName == NULL) {\r | |
604 | printf ("Fail to allocate memory");\r | |
605 | return EFI_OUT_OF_RESOURCES;\r | |
606 | }\r | |
607 | memset (\r | |
608 | *VarDefaultName,\r | |
609 | 0,\r | |
610 | (FceStrLen ((CHAR16 *) ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)ThisBlock)->StringText) + 1) * sizeof (CHAR16)\r | |
611 | );\r | |
612 | StrCpy (\r | |
613 | *VarDefaultName,\r | |
614 | (CHAR16 *) ((EFI_HII_SIBT_STRING_UCS2_BLOCK *) ThisBlock)->StringText\r | |
615 | );\r | |
616 | return EFI_SUCCESS;\r | |
617 | }\r | |
618 | \r | |
619 | for (Index = 0 ; ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
620 | Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRING_UCS2_BLOCK *) ThisBlock)->StringText[Index + 1];\r | |
621 | Offset += 1;\r | |
622 | break;\r | |
623 | \r | |
624 | case EFI_HII_SIBT_STRING_UCS2_FONT:\r | |
625 | ThisBlock = (VOID *)Block;\r | |
626 | for (Index = 0 ; ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK *) ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
627 | Block = (EFI_HII_STRING_BLOCK *)& ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK *) ThisBlock)->StringText[Index + 1];\r | |
628 | break;\r | |
629 | \r | |
630 | case EFI_HII_SIBT_STRINGS_UCS2:\r | |
631 | ThisBlock = (VOID *)Block;\r | |
632 | for( Count = ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *)ThisBlock)->StringCount, Index = 0 ; Count; Count--, Index++ ) {\r | |
633 | for ( ; ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *) ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
634 | }\r | |
635 | Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *) ThisBlock)->StringText[Index];\r | |
636 | break;\r | |
637 | \r | |
638 | case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r | |
639 | ThisBlock = (VOID *)Block;\r | |
640 | for( Count= ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *) ThisBlock)->StringCount, Index = 0 ; Count ; Count--, Index++ ) {\r | |
641 | for ( ; ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *) ThisBlock)->StringText[Index] != 0 ; Index++) ;\r | |
642 | }\r | |
643 | Block = (EFI_HII_STRING_BLOCK *) & ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *)ThisBlock)->StringText[Index];\r | |
644 | break;\r | |
645 | \r | |
646 | case EFI_HII_SIBT_DUPLICATE:\r | |
647 | ThisBlock = (VOID *)Block;\r | |
648 | Block = (EFI_HII_STRING_BLOCK *)((EFI_HII_SIBT_DUPLICATE_BLOCK *) ThisBlock + 1);\r | |
649 | break;\r | |
650 | \r | |
651 | case EFI_HII_SIBT_SKIP2:\r | |
652 | ThisBlock = (VOID *)Block;\r | |
653 | Offset += ((EFI_HII_SIBT_SKIP2_BLOCK *) ThisBlock)->SkipCount;\r | |
654 | Block = (EFI_HII_STRING_BLOCK *)( (EFI_HII_SIBT_SKIP2_BLOCK *) ThisBlock + 1);\r | |
655 | break;\r | |
656 | \r | |
657 | case EFI_HII_SIBT_SKIP1:\r | |
658 | ThisBlock = (VOID *)Block;\r | |
659 | Offset += ((EFI_HII_SIBT_SKIP1_BLOCK *) ThisBlock)->SkipCount;\r | |
660 | Block = (EFI_HII_STRING_BLOCK *)((EFI_HII_SIBT_SKIP1_BLOCK *)ThisBlock + 1);\r | |
661 | break;\r | |
662 | \r | |
663 | case EFI_HII_SIBT_EXT1:\r | |
664 | ThisBlock = (VOID *)Block;\r | |
665 | Block = (EFI_HII_STRING_BLOCK *)((UINT8*)ThisBlock + ((EFI_HII_SIBT_EXT1_BLOCK *) ThisBlock)->Length);\r | |
666 | break;\r | |
667 | \r | |
668 | case EFI_HII_SIBT_EXT2:\r | |
669 | ThisBlock = (VOID *)Block;\r | |
670 | Block = (EFI_HII_STRING_BLOCK *)((UINT8*)ThisBlock + ((EFI_HII_SIBT_EXT2_BLOCK *) ThisBlock)->Length);\r | |
671 | break;\r | |
672 | \r | |
673 | case EFI_HII_SIBT_EXT4:\r | |
674 | ThisBlock = (VOID *)Block;\r | |
675 | Block = (EFI_HII_STRING_BLOCK *)((UINT8*)ThisBlock + ((EFI_HII_SIBT_EXT4_BLOCK *)ThisBlock)->Length);\r | |
676 | break;\r | |
677 | \r | |
678 | case EFI_HII_SIBT_FONT:\r | |
679 | ThisBlock = (VOID *)Block;\r | |
680 | for (Index = 0 ; ((EFI_HII_SIBT_FONT_BLOCK *) ThisBlock)->FontName[Index] != 0 ; Index++) ;\r | |
681 | Block = (EFI_HII_STRING_BLOCK *)& ((EFI_HII_SIBT_FONT_BLOCK *) ThisBlock)->FontName[Index + 1];\r | |
682 | break;\r | |
683 | \r | |
684 | default:\r | |
685 | StringPrint("Unhandled type = 0x%x\n", Block->BlockType);\r | |
686 | }\r | |
687 | }\r | |
688 | \r | |
689 | return EFI_NOT_FOUND;\r | |
690 | }\r | |
691 | \r | |
692 | /**\r | |
693 | Parse the UniString to get the string information.\r | |
694 | \r | |
695 | @param CachedStringList A pointer to cached string list\r | |
696 | @param UniPackge A pointer to a Null-terminated Unicode string Array.\r | |
697 | @param VarDefaultNameId The string ID.\r | |
698 | @param Language The language, en-US UQI or eng.\r | |
699 | @param VarDefaultName return the name string.\r | |
700 | \r | |
701 | @return EFI_SUCCESS If get the name string successfully\r | |
702 | @return EFI_NOT_FOUND An error occurred.\r | |
703 | @return EFI_INVALID_PARAMETER\r | |
704 | \r | |
705 | **/\r | |
706 | EFI_STATUS\r | |
707 | FindDefaultName (\r | |
708 | IN FORMSET_STRING_LIST *CachedStringList,\r | |
709 | IN UINT8 *UniPackge,\r | |
710 | IN UINT16 VarDefaultNameId,\r | |
711 | IN LANGUAGE Language,\r | |
712 | IN OUT CHAR16 **VarDefaultName\r | |
713 | )\r | |
714 | {\r | |
715 | CHAR8 *UniPackgeEnd;\r | |
716 | CHAR8 *UniBin;\r | |
717 | CHAR8 LangStr[10];\r | |
718 | BOOLEAN IsFound;\r | |
719 | EFI_STATUS Status;\r | |
720 | EFI_STRING_ID Index;\r | |
721 | STRING_INFO *TempBuffer;\r | |
722 | \r | |
723 | UniBin = NULL;\r | |
724 | IsFound = FALSE;\r | |
725 | Status = EFI_NOT_FOUND;\r | |
726 | \r | |
727 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
728 | UniPackgeEnd = (CHAR8 *) UniPackge + *(UINT32 *)UniPackge;\r | |
729 | \r | |
730 | //\r | |
731 | //Handle with the invalid usage "STRING_TOKEN(0)"\r | |
732 | //\r | |
733 | if (VarDefaultNameId == 0) {\r | |
734 | *VarDefaultName = L"";\r | |
735 | return EFI_SUCCESS;\r | |
736 | }\r | |
737 | \r | |
738 | if (CachedStringList != NULL) {\r | |
739 | for (Index = 0; Index < CachedStringList->CachedIdNum; Index ++) {\r | |
740 | if (VarDefaultNameId == CachedStringList->StringInfoList[Index].StringId) {\r | |
741 | *VarDefaultName = CachedStringList->StringInfoList[Index].String;\r | |
742 | return EFI_SUCCESS;\r | |
743 | }\r | |
744 | }\r | |
745 | }\r | |
746 | \r | |
747 | switch (Language) {\r | |
748 | \r | |
749 | case UQI:\r | |
750 | strcpy (LangStr, "uqi");\r | |
751 | break;\r | |
752 | \r | |
753 | case EN_US:\r | |
754 | strcpy (LangStr, "en-US");\r | |
755 | break;\r | |
756 | \r | |
757 | case ENG:\r | |
758 | strcpy (LangStr, "eng");\r | |
759 | break;\r | |
760 | \r | |
761 | default:\r | |
762 | strcpy (LangStr, "en-US");\r | |
763 | break;\r | |
764 | }\r | |
765 | IsFound = FALSE;\r | |
766 | \r | |
767 | if (((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
768 | //\r | |
769 | // Search the specified language package\r | |
770 | //\r | |
771 | while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
772 | if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, LangStr) == 0) {\r | |
773 | IsFound = TRUE;\r | |
774 | break;\r | |
775 | }\r | |
776 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
777 | }\r | |
778 | //\r | |
779 | //If not find the string ID, use the en eng or en-US instead.\r | |
780 | //\r | |
781 | if (!IsFound) {\r | |
782 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
783 | \r | |
784 | while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
785 | if ((strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en") == 0) \\r | |
786 | || (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en-US") == 0) \\r | |
787 | || (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "eng") == 0) \\r | |
788 | ) {\r | |
789 | IsFound = TRUE;\r | |
790 | break;\r | |
791 | }\r | |
792 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
793 | }\r | |
794 | }\r | |
795 | //\r | |
796 | //If not still find the string ID, use the first one instead.\r | |
797 | //\r | |
798 | Status = GetStringByOffset (\r | |
799 | UniPackge,\r | |
800 | (UINT8 *)UniBin,\r | |
801 | VarDefaultNameId,\r | |
802 | IsFound,\r | |
803 | VarDefaultName\r | |
804 | );\r | |
805 | if (!EFI_ERROR (Status)) {\r | |
806 | goto Done;\r | |
807 | }\r | |
808 | //\r | |
809 | //If not find the specified string in UQI package, we use the en en-us eng or uqi insteadly\r | |
810 | //\r | |
811 | IsFound = FALSE;\r | |
812 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
813 | \r | |
814 | while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
815 | if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en") == 0) {\r | |
816 | IsFound = TRUE;\r | |
817 | break;\r | |
818 | }\r | |
819 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
820 | }\r | |
821 | Status = GetStringByOffset (\r | |
822 | UniPackge,\r | |
823 | (UINT8 *)UniBin,\r | |
824 | VarDefaultNameId,\r | |
825 | IsFound,\r | |
826 | VarDefaultName\r | |
827 | );\r | |
828 | if (!EFI_ERROR (Status)) {\r | |
829 | goto Done;\r | |
830 | }\r | |
831 | \r | |
832 | IsFound = FALSE;\r | |
833 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
834 | \r | |
835 | while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
836 | if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "en-US") == 0) {\r | |
837 | IsFound = TRUE;\r | |
838 | break;\r | |
839 | }\r | |
840 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
841 | }\r | |
842 | Status = GetStringByOffset (\r | |
843 | UniPackge,\r | |
844 | (UINT8 *)UniBin,\r | |
845 | VarDefaultNameId,\r | |
846 | IsFound,\r | |
847 | VarDefaultName\r | |
848 | );\r | |
849 | if (!EFI_ERROR (Status)) {\r | |
850 | goto Done;\r | |
851 | }\r | |
852 | \r | |
853 | IsFound = FALSE;\r | |
854 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
855 | \r | |
856 | while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
857 | if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "eng") == 0) {\r | |
858 | IsFound = TRUE;\r | |
859 | break;\r | |
860 | }\r | |
861 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
862 | }\r | |
863 | Status = GetStringByOffset (\r | |
864 | UniPackge,\r | |
865 | (UINT8 *)UniBin,\r | |
866 | VarDefaultNameId,\r | |
867 | IsFound,\r | |
868 | VarDefaultName\r | |
869 | );\r | |
870 | if (!EFI_ERROR (Status)) {\r | |
871 | goto Done;\r | |
872 | }\r | |
873 | \r | |
874 | IsFound = FALSE;\r | |
875 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
876 | \r | |
877 | while ((UniBin < UniPackgeEnd) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
878 | if (strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "uqi") == 0) {\r | |
879 | IsFound = TRUE;\r | |
880 | break;\r | |
881 | }\r | |
882 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
883 | }\r | |
884 | Status = GetStringByOffset (\r | |
885 | UniPackge,\r | |
886 | (UINT8 *)UniBin,\r | |
887 | VarDefaultNameId,\r | |
888 | IsFound,\r | |
889 | VarDefaultName\r | |
890 | );\r | |
891 | if (!EFI_ERROR (Status)) {\r | |
892 | goto Done;\r | |
893 | }\r | |
894 | }\r | |
895 | \r | |
896 | Done:\r | |
897 | if (EFI_ERROR (Status)) {\r | |
898 | *VarDefaultName = NULL;\r | |
899 | return EFI_NOT_FOUND;\r | |
900 | }\r | |
901 | \r | |
902 | if (CachedStringList != NULL) {\r | |
903 | if (CachedStringList->CachedIdNum >= CachedStringList->MaxIdNum) {\r | |
904 | TempBuffer = calloc (sizeof (STRING_INFO), CachedStringList->MaxIdNum + STRING_NUMBER);\r | |
905 | if (TempBuffer == NULL) {\r | |
906 | printf ("Fail to allocate memory! \n");\r | |
907 | free (*VarDefaultName);\r | |
908 | *VarDefaultName = NULL;\r | |
909 | return EFI_OUT_OF_RESOURCES;\r | |
910 | }\r | |
911 | CopyMem (TempBuffer, CachedStringList->StringInfoList, sizeof (STRING_INFO) * CachedStringList->MaxIdNum);\r | |
912 | FreePool (CachedStringList->StringInfoList);\r | |
913 | CachedStringList->StringInfoList = TempBuffer;\r | |
914 | CachedStringList->MaxIdNum = CachedStringList->MaxIdNum + STRING_NUMBER;\r | |
915 | }\r | |
916 | CachedStringList->StringInfoList[CachedStringList->CachedIdNum].StringId = VarDefaultNameId;\r | |
917 | CachedStringList->StringInfoList[CachedStringList->CachedIdNum].String = *VarDefaultName;\r | |
918 | CachedStringList->CachedIdNum ++;\r | |
919 | }\r | |
920 | return EFI_SUCCESS;\r | |
921 | }\r | |
922 | \r | |
923 | /**\r | |
924 | Get the variable Guid and Name by the variableId and FormSetOrder.\r | |
925 | \r | |
926 | @param FormSet The pointer to the formset.\r | |
927 | @param FormSet The pointer to the form.\r | |
928 | @param ListEntry The pointer to the LIST_ENTRY.\r | |
929 | \r | |
930 | @return EFI_SUCCESS\r | |
931 | @return EFI_NOT_FOUND If not find the the variable, or the variable doesn't belong to EfiVarStore or VarStore.\r | |
932 | **/\r | |
933 | static\r | |
934 | EFI_STATUS\r | |
935 | GetGuidNameByVariableId (\r | |
936 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
937 | IN OUT FORM_BROWSER_STATEMENT *Question,\r | |
938 | IN LIST_ENTRY *ListEntry\r | |
939 | )\r | |
940 | {\r | |
941 | FORMSET_STORAGE *CurNode;\r | |
942 | LIST_ENTRY *Link;\r | |
943 | LIST_ENTRY *StorageListHead;\r | |
944 | EFI_STATUS Status;\r | |
945 | CHAR16 *EfiVariableName;\r | |
946 | \r | |
947 | StorageListHead = ListEntry;\r | |
948 | CurNode = NULL;\r | |
949 | Status = EFI_SUCCESS;\r | |
950 | EfiVariableName = NULL;\r | |
951 | \r | |
952 | Link = GetFirstNode (StorageListHead);\r | |
953 | while (!IsNull (StorageListHead, Link)) {\r | |
954 | CurNode = FORMSET_STORAGE_FROM_LINK (Link);\r | |
955 | \r | |
956 | if ((FormSet->FormSetOrder == CurNode->FormSetOrder) \\r | |
957 | && (Question->VarStoreId == CurNode->VarStoreId)\r | |
958 | ) {\r | |
959 | //\r | |
960 | // Copy type to question to avoid the case that EfiVarStore and VarStore have the same Guid and name.\r | |
961 | //\r | |
962 | Question->Type = CurNode->Type;\r | |
963 | Question->NewEfiVarstore = CurNode->NewEfiVarstore;\r | |
964 | Question->Attributes = CurNode->Attributes;\r | |
965 | \r | |
966 | if (CurNode->Type == EFI_IFR_VARSTORE_EFI_OP) {\r | |
967 | CopyMem (&Question->Guid, &CurNode->Guid, sizeof (EFI_GUID));\r | |
968 | //\r | |
969 | // If the first time to access the old EfiVarStore, need to sync the variable name\r | |
970 | //\r | |
971 | if (!CurNode->NewEfiVarstore) {\r | |
972 | if (CurNode->Buffer == NULL) {\r | |
973 | CurNode->Buffer = malloc (Question->StorageWidth);\r | |
974 | }\r | |
975 | if (CurNode->Name == NULL) {\r | |
976 | Status = FindDefaultName (\r | |
977 | &(FormSet->EnUsStringList),\r | |
978 | FormSet->UnicodeBinary,\r | |
979 | Question->VarStoreInfo.VarName,\r | |
980 | EN_US,\r | |
981 | &EfiVariableName\r | |
982 | );\r | |
983 | if (EFI_ERROR(Status)) {\r | |
984 | return Status;\r | |
985 | }\r | |
986 | CurNode->Name = EfiVariableName;\r | |
987 | }\r | |
988 | if (CurNode->Size == 0) {\r | |
989 | CurNode->Size = Question->StorageWidth;\r | |
990 | }\r | |
991 | }\r | |
992 | //\r | |
993 | // Check whether the Efivariable variable name is valid.\r | |
994 | //\r | |
995 | if ((CurNode->Name == NULL) || (FceStrLen (CurNode->Name) == 0)) {\r | |
996 | StringPrint ("Error. The variable name of question is NULL. Its UQI is: ");\r | |
997 | StringPrint("Q %04X ", Question->Uqi.HexNum);\r | |
998 | LogUqi (Question->Uqi.Data);\r | |
999 | StringPrint ("\n");\r | |
1000 | return EFI_ABORTED;\r | |
1001 | }\r | |
1002 | if (Question->VariableName == NULL) {\r | |
1003 | Question->VariableName = (CHAR16 *) malloc (2 * (FceStrLen ((CONST CHAR16 *)CurNode->Name) + 1));\r | |
1004 | if (Question->VariableName == NULL) {\r | |
1005 | return EFI_ABORTED;\r | |
1006 | }\r | |
1007 | }\r | |
1008 | StrCpy (Question->VariableName, CurNode->Name);\r | |
1009 | \r | |
1010 | return EFI_SUCCESS;\r | |
1011 | \r | |
1012 | } else if (CurNode->Type == EFI_IFR_VARSTORE_OP) {\r | |
1013 | CopyMem (&Question->Guid, &CurNode->Guid, sizeof (EFI_GUID));\r | |
1014 | if (Question->VariableName == NULL) {\r | |
1015 | Question->VariableName = (CHAR16 *) malloc (2 * (FceStrLen ((CONST CHAR16 *)CurNode->Name) + 1));\r | |
1016 | if (Question->VariableName == NULL) {\r | |
1017 | return EFI_ABORTED;\r | |
1018 | }\r | |
1019 | }\r | |
1020 | //\r | |
1021 | // Check whether the variable variable name is valid.\r | |
1022 | //\r | |
1023 | if ((CurNode->Name == NULL) || (FceStrLen (CurNode->Name) == 0)) {\r | |
1024 | StringPrint ("Error. The variable name of question is NULL. UQI:");\r | |
1025 | StringPrint("Q %04X ", Question->Uqi.HexNum);\r | |
1026 | LogUqi (Question->Uqi.Data);\r | |
1027 | StringPrint ("\n");\r | |
1028 | return EFI_ABORTED;\r | |
1029 | }\r | |
1030 | StrCpy (Question->VariableName, CurNode->Name);\r | |
1031 | return EFI_SUCCESS;\r | |
1032 | }\r | |
1033 | }\r | |
1034 | Link = GetNextNode (StorageListHead, Link);\r | |
1035 | }\r | |
1036 | return EFI_NOT_FOUND;\r | |
1037 | }\r | |
1038 | \r | |
1039 | /**\r | |
1040 | Search the variable list according to the variable Guid and name, and return the pointer\r | |
1041 | of that Node.\r | |
1042 | \r | |
1043 | @param HiiObjList The pointer to the Question\r | |
1044 | @param VarName The EFI variable name need to be updated to VarList\r | |
1045 | @param Offset The offset of the variable\r | |
1046 | @param StorageListHead The pointer to the LIST_ENTRY of Storage\r | |
1047 | @param Vaue The value in that value offset of the variable\r | |
1048 | @param VarList The dual pointer of Varlist\r | |
1049 | \r | |
1050 | @return EFI_SUCCESS\r | |
1051 | @return EFI_NOT_FOUND\r | |
1052 | **/\r | |
1053 | EFI_STATUS\r | |
1054 | SearchVarStorage (\r | |
1055 | IN FORM_BROWSER_STATEMENT *Question,\r | |
1056 | IN CHAR16* VarName,\r | |
1057 | IN UINT32 Offset,\r | |
1058 | IN LIST_ENTRY *StorageListHead,\r | |
1059 | IN OUT CHAR8 **Value,\r | |
1060 | IN OUT FORMSET_STORAGE **VarList\r | |
1061 | )\r | |
1062 | {\r | |
1063 | FORMSET_STORAGE *CurNode;\r | |
1064 | LIST_ENTRY *Link;\r | |
1065 | BOOLEAN FindOrNot;\r | |
1066 | \r | |
1067 | CurNode = NULL;\r | |
1068 | FindOrNot = FALSE;\r | |
1069 | *VarList = NULL;\r | |
1070 | //\r | |
1071 | // Find Storage for this Question\r | |
1072 | //\r | |
1073 | Link = GetFirstNode (StorageListHead);\r | |
1074 | while (!IsNull (StorageListHead, Link)) {\r | |
1075 | CurNode = FORMSET_STORAGE_FROM_LINK (Link);\r | |
1076 | //\r | |
1077 | // Deal with the old EfiVarstore before UEFI2.31\r | |
1078 | //\r | |
1079 | if (!CompareGuid (&Question->Guid, &CurNode->Guid) \\r | |
1080 | && (CurNode->Type == EFI_IFR_VARSTORE_EFI_OP) \\r | |
1081 | && !CurNode->NewEfiVarstore \\r | |
1082 | && (Question->VariableName != NULL) \\r | |
1083 | && (CurNode->Name != NULL) \\r | |
1084 | && !FceStrCmp(Question->VariableName, CurNode->Name)\r | |
1085 | ) {\r | |
1086 | //\r | |
1087 | // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are\r | |
1088 | // two variables with same guid same name, but different type, we will take as the same\r | |
1089 | // in general mode\r | |
1090 | //\r | |
1091 | if (mMultiPlatformParam.MultiPlatformOrNot && (CurNode->Type == Question->Type)) {\r | |
1092 | //\r | |
1093 | // check whether exist a old EFI_IFR_VARSTORE_EFI or not.\r | |
1094 | //\r | |
1095 | *Value = (CHAR8 *)CurNode->Buffer;\r | |
1096 | *VarList = CurNode;\r | |
1097 | FindOrNot = TRUE;\r | |
1098 | break;\r | |
1099 | } else if (!mMultiPlatformParam.MultiPlatformOrNot) {\r | |
1100 | //\r | |
1101 | // check whether exist a old EFI_IFR_VARSTORE_EFI or not.\r | |
1102 | //\r | |
1103 | *Value = (CHAR8 *)CurNode->Buffer;\r | |
1104 | *VarList = CurNode;\r | |
1105 | FindOrNot = TRUE;\r | |
1106 | break;\r | |
1107 | }\r | |
1108 | }\r | |
1109 | \r | |
1110 | if (!CompareGuid (&Question->Guid, &CurNode->Guid) \\r | |
1111 | && (CurNode->Name != NULL) \\r | |
1112 | && (Question->VariableName != NULL) \\r | |
1113 | && !FceStrCmp(Question->VariableName, CurNode->Name)\r | |
1114 | ) {\r | |
1115 | //\r | |
1116 | // If not multi-plaform support mode, take VarStore as the EfiVarStore. So If there are\r | |
1117 | // two variables with same guid same name, but different type, we will take as the same\r | |
1118 | // in general mode\r | |
1119 | //\r | |
1120 | if (mMultiPlatformParam.MultiPlatformOrNot && (CurNode->Type == Question->Type)) {\r | |
1121 | //\r | |
1122 | // If matched, get the address of EFI_IFR_VARSTORE data.\r | |
1123 | //\r | |
1124 | *Value = (CHAR8 *)(CurNode->Buffer + Offset);\r | |
1125 | *VarList = CurNode;\r | |
1126 | FindOrNot = TRUE;\r | |
1127 | break;\r | |
1128 | } else if (!mMultiPlatformParam.MultiPlatformOrNot) {\r | |
1129 | //\r | |
1130 | // If matched, get the address of EFI_IFR_VARSTORE data.\r | |
1131 | //\r | |
1132 | *Value = (CHAR8 *)(CurNode->Buffer + Offset);\r | |
1133 | *VarList = CurNode;\r | |
1134 | FindOrNot = TRUE;\r | |
1135 | break;\r | |
1136 | }\r | |
1137 | }\r | |
1138 | Link = GetNextNode (StorageListHead, Link);\r | |
1139 | }\r | |
1140 | if (!FindOrNot) {\r | |
1141 | return EFI_NOT_FOUND;\r | |
1142 | }\r | |
1143 | return EFI_SUCCESS;\r | |
1144 | }\r | |
1145 | \r | |
1146 | /**\r | |
1147 | Get the string based on the StringId and HII Package List Handle.\r | |
1148 | \r | |
1149 | @param Token The String's ID.\r | |
1150 | @param HiiHandle The package list in the HII database to search for\r | |
1151 | the specified string.\r | |
1152 | \r | |
1153 | @return The output string.\r | |
1154 | \r | |
1155 | **/\r | |
1156 | CHAR16 *\r | |
1157 | GetToken (\r | |
1158 | IN EFI_STRING_ID Token,\r | |
1159 | IN UINT8 *UniPackge\r | |
1160 | )\r | |
1161 | {\r | |
1162 | CHAR16 *VarDefaultName;\r | |
1163 | EFI_STATUS Status;\r | |
1164 | \r | |
1165 | Status = EFI_SUCCESS;\r | |
1166 | \r | |
1167 | if (UniPackge == NULL) {\r | |
1168 | return NULL;\r | |
1169 | }\r | |
1170 | \r | |
1171 | Status = FindDefaultName (\r | |
1172 | NULL,\r | |
1173 | UniPackge,\r | |
1174 | Token,\r | |
1175 | EN_US,\r | |
1176 | &VarDefaultName\r | |
1177 | );\r | |
1178 | if (EFI_ERROR (Status)) {\r | |
1179 | return NULL;\r | |
1180 | }\r | |
1181 | \r | |
1182 | return VarDefaultName;\r | |
1183 | }\r | |
1184 | \r | |
1185 | /**\r | |
1186 | Initialize Statement header members.\r | |
1187 | \r | |
1188 | @param OpCodeData Pointer of the raw OpCode data.\r | |
1189 | @param FormSet Pointer of the current FormSe.\r | |
1190 | @param Form Pointer of the current Form.\r | |
1191 | \r | |
1192 | @return The Statement.\r | |
1193 | \r | |
1194 | **/\r | |
1195 | FORM_BROWSER_STATEMENT *\r | |
1196 | CreateStatement (\r | |
1197 | IN UINT8 *OpCodeData,\r | |
1198 | IN OUT FORM_BROWSER_FORMSET *FormSet,\r | |
1199 | IN OUT FORM_BROWSER_FORM *Form\r | |
1200 | )\r | |
1201 | {\r | |
1202 | FORM_BROWSER_STATEMENT *Statement;\r | |
1203 | EFI_IFR_STATEMENT_HEADER *StatementHdr;\r | |
1204 | \r | |
1205 | if (Form == NULL) {\r | |
1206 | //\r | |
1207 | // We are currently not in a Form Scope, so just skip this Statement\r | |
1208 | //\r | |
1209 | return NULL;\r | |
1210 | }\r | |
1211 | \r | |
1212 | Statement = &FormSet->StatementBuffer[mStatementIndex];\r | |
1213 | mStatementIndex++;\r | |
1214 | \r | |
1215 | InitializeListHead (&Statement->DefaultListHead);\r | |
1216 | InitializeListHead (&Statement->OptionListHead);\r | |
1217 | InitializeListHead (&Statement->InconsistentListHead);\r | |
1218 | InitializeListHead (&Statement->NoSubmitListHead);\r | |
1219 | InitializeListHead (&Statement->WarningListHead);\r | |
1220 | \r | |
1221 | Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r | |
1222 | \r | |
1223 | Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r | |
1224 | Statement->QuestionReferToBitField = FALSE;\r | |
1225 | \r | |
1226 | StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r | |
1227 | CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r | |
1228 | CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r | |
1229 | \r | |
1230 | if (mInScopeSuppress) {\r | |
1231 | Statement->SuppressExpression = mSuppressExpression;\r | |
1232 | }\r | |
1233 | \r | |
1234 | if (mInScopeGrayOut) {\r | |
1235 | Statement->GrayOutExpression = mGrayOutExpression;\r | |
1236 | }\r | |
1237 | \r | |
1238 | \r | |
1239 | if (mInScopeDisable) {\r | |
1240 | Statement->DisableExpression = mDisableExpression;\r | |
1241 | }\r | |
1242 | \r | |
1243 | Statement->InSubtitle = mInScopeSubtitle;\r | |
1244 | \r | |
1245 | //\r | |
1246 | // Insert this Statement into current Form\r | |
1247 | //\r | |
1248 | InsertTailList (&Form->StatementListHead, &Statement->Link);\r | |
1249 | \r | |
1250 | return Statement;\r | |
1251 | }\r | |
1252 | \r | |
1253 | /**\r | |
1254 | Initialize Question's members.\r | |
1255 | \r | |
1256 | @param OpCodeData Pointer of the raw OpCode data.\r | |
1257 | @param FormSet Pointer of the current FormSet.\r | |
1258 | @param Form Pointer of the current Form.\r | |
1259 | \r | |
1260 | @return The Question.\r | |
1261 | \r | |
1262 | **/\r | |
1263 | FORM_BROWSER_STATEMENT *\r | |
1264 | CreateQuestion (\r | |
1265 | IN UINT8 *OpCodeData,\r | |
1266 | IN OUT FORM_BROWSER_FORMSET *FormSet,\r | |
1267 | IN OUT FORM_BROWSER_FORM *Form\r | |
1268 | )\r | |
1269 | {\r | |
1270 | FORM_BROWSER_STATEMENT *Statement;\r | |
1271 | EFI_IFR_QUESTION_HEADER *QuestionHdr;\r | |
1272 | LIST_ENTRY *Link;\r | |
1273 | FORMSET_STORAGE *Storage;\r | |
1274 | NAME_VALUE_NODE *NameValueNode;\r | |
1275 | \r | |
1276 | Statement = CreateStatement (OpCodeData, FormSet, Form);\r | |
1277 | if (Statement == NULL) {\r | |
1278 | return NULL;\r | |
1279 | }\r | |
1280 | \r | |
1281 | QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r | |
1282 | CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r | |
1283 | CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r | |
1284 | CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r | |
1285 | \r | |
1286 | Statement->QuestionFlags = QuestionHdr->Flags;\r | |
1287 | \r | |
1288 | Statement->FormSetOrder = mFormSetOrderParse;\r | |
1289 | \r | |
1290 | if (Statement->VarStoreId == 0) {\r | |
1291 | //\r | |
1292 | // VarStoreId of zero indicates no variable storage\r | |
1293 | //\r | |
1294 | return Statement;\r | |
1295 | }\r | |
1296 | \r | |
1297 | //\r | |
1298 | // Find Storage for this Question\r | |
1299 | //\r | |
1300 | Link = GetFirstNode (FormSet->StorageListHead);\r | |
1301 | while (!IsNull (FormSet->StorageListHead, Link)) {\r | |
1302 | Storage = FORMSET_STORAGE_FROM_LINK (Link);\r | |
1303 | \r | |
1304 | if ((Storage->VarStoreId == Statement->VarStoreId)\r | |
1305 | && (Storage->FormSetOrder == Statement->FormSetOrder)) {\r | |
1306 | Statement->Storage = Storage;\r | |
1307 | break;\r | |
1308 | }\r | |
1309 | \r | |
1310 | Link = GetNextNode (FormSet->StorageListHead, Link);\r | |
1311 | }\r | |
1312 | ASSERT (Statement->Storage != NULL);\r | |
1313 | \r | |
1314 | if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r | |
1315 | Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->UnicodeBinary);\r | |
1316 | ASSERT (Statement->VariableName != NULL);\r | |
1317 | //\r | |
1318 | // Insert to Name/Value varstore list\r | |
1319 | //\r | |
1320 | NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r | |
1321 | ASSERT (NameValueNode != NULL);\r | |
1322 | NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r | |
1323 | NameValueNode->Name = FceAllocateCopyPool (FceStrSize (Statement->VariableName), Statement->VariableName);\r | |
1324 | ASSERT (NameValueNode->Name != NULL);\r | |
1325 | NameValueNode->Value = AllocateZeroPool (0x10);\r | |
1326 | ASSERT (NameValueNode->Value != NULL);\r | |
1327 | NameValueNode->EditValue = AllocateZeroPool (0x10);\r | |
1328 | ASSERT (NameValueNode->EditValue != NULL);\r | |
1329 | \r | |
1330 | InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r | |
1331 | }\r | |
1332 | \r | |
1333 | return Statement;\r | |
1334 | }\r | |
1335 | \r | |
1336 | \r | |
1337 | /**\r | |
1338 | Allocate a FORM_EXPRESSION node.\r | |
1339 | \r | |
1340 | @param Form The Form associated with this Expression\r | |
1341 | \r | |
1342 | @return Pointer to a FORM_EXPRESSION data structure.\r | |
1343 | \r | |
1344 | **/\r | |
1345 | FORM_EXPRESSION *\r | |
1346 | CreateExpression (\r | |
1347 | IN OUT FORM_BROWSER_FORM *Form\r | |
1348 | )\r | |
1349 | {\r | |
1350 | FORM_EXPRESSION *Expression;\r | |
1351 | \r | |
1352 | Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r | |
1353 | ASSERT (Expression != NULL);\r | |
1354 | Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r | |
1355 | InitializeListHead (&Expression->OpCodeListHead);\r | |
1356 | \r | |
1357 | return Expression;\r | |
1358 | }\r | |
1359 | \r | |
1360 | \r | |
1361 | /**\r | |
1362 | Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r | |
1363 | \r | |
1364 | @param FormSet Pointer of the current FormSet\r | |
1365 | \r | |
1366 | @return Pointer to a FORMSET_STORAGE data structure.\r | |
1367 | \r | |
1368 | **/\r | |
1369 | FORMSET_STORAGE *\r | |
1370 | CreateStorage (\r | |
1371 | IN FORM_BROWSER_FORMSET *FormSet\r | |
1372 | )\r | |
1373 | {\r | |
1374 | FORMSET_STORAGE *Storage;\r | |
1375 | \r | |
1376 | Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r | |
1377 | ASSERT (Storage != NULL);\r | |
1378 | Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r | |
1379 | InitializeListHead (&Storage->NameValueListHead);\r | |
1380 | InsertTailList (FormSet->StorageListHead, &Storage->Link);\r | |
1381 | \r | |
1382 | return Storage;\r | |
1383 | }\r | |
1384 | \r | |
1385 | /**\r | |
1386 | Free resources of a Expression.\r | |
1387 | \r | |
1388 | @param FormSet Pointer of the Expression\r | |
1389 | \r | |
1390 | **/\r | |
1391 | VOID\r | |
1392 | DestroyExpression (\r | |
1393 | IN FORM_EXPRESSION *Expression\r | |
1394 | )\r | |
1395 | {\r | |
1396 | LIST_ENTRY *Link;\r | |
1397 | EXPRESSION_OPCODE *OpCode;\r | |
1398 | LIST_ENTRY *SubExpressionLink;\r | |
1399 | FORM_EXPRESSION *SubExpression;\r | |
1400 | \r | |
1401 | while (!IsListEmpty (&Expression->OpCodeListHead)) {\r | |
1402 | Link = GetFirstNode (&Expression->OpCodeListHead);\r | |
1403 | OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r | |
1404 | RemoveEntryList (&OpCode->Link);\r | |
1405 | \r | |
1406 | if (OpCode->ValueList != NULL) {\r | |
1407 | FreePool (OpCode->ValueList);\r | |
1408 | }\r | |
1409 | \r | |
1410 | if (OpCode->ValueName != NULL) {\r | |
1411 | FreePool (OpCode->ValueName);\r | |
1412 | }\r | |
1413 | \r | |
1414 | if (OpCode->MapExpressionList.ForwardLink != NULL) {\r | |
1415 | while (!IsListEmpty (&OpCode->MapExpressionList)) {\r | |
1416 | SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r | |
1417 | SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r | |
1418 | RemoveEntryList(&SubExpression->Link);\r | |
1419 | DestroyExpression (SubExpression);\r | |
1420 | }\r | |
1421 | }\r | |
1422 | }\r | |
1423 | \r | |
1424 | //\r | |
1425 | // Free this Expression\r | |
1426 | //\r | |
1427 | FreePool (Expression);\r | |
1428 | }\r | |
1429 | \r | |
1430 | \r | |
1431 | /**\r | |
1432 | Free resources of a storage.\r | |
1433 | \r | |
1434 | @param Storage Pointer of the storage\r | |
1435 | \r | |
1436 | **/\r | |
1437 | VOID\r | |
1438 | DestroyStorage (\r | |
1439 | IN FORMSET_STORAGE *Storage\r | |
1440 | )\r | |
1441 | {\r | |
1442 | LIST_ENTRY *Link;\r | |
1443 | NAME_VALUE_NODE *NameValueNode;\r | |
1444 | \r | |
1445 | if (Storage == NULL) {\r | |
1446 | return;\r | |
1447 | }\r | |
1448 | \r | |
1449 | if (Storage->Name != NULL) {\r | |
1450 | FreePool (Storage->Name);\r | |
1451 | }\r | |
1452 | if (Storage->Buffer != NULL) {\r | |
1453 | FreePool (Storage->Buffer);\r | |
1454 | }\r | |
1455 | \r | |
1456 | while (!IsListEmpty (&Storage->NameValueListHead)) {\r | |
1457 | Link = GetFirstNode (&Storage->NameValueListHead);\r | |
1458 | NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r | |
1459 | RemoveEntryList (&NameValueNode->Link);\r | |
1460 | \r | |
1461 | if (NameValueNode->Name != NULL) {\r | |
1462 | FreePool (NameValueNode->Name);\r | |
1463 | }\r | |
1464 | if (NameValueNode->Value != NULL) {\r | |
1465 | FreePool (NameValueNode->Value);\r | |
1466 | }\r | |
1467 | if (NameValueNode->EditValue != NULL) {\r | |
1468 | FreePool (NameValueNode->EditValue);\r | |
1469 | }\r | |
1470 | FreePool (NameValueNode);\r | |
1471 | }\r | |
1472 | \r | |
1473 | FreePool (Storage);\r | |
1474 | Storage = NULL;\r | |
1475 | }\r | |
1476 | \r | |
1477 | /**\r | |
1478 | Free resources allocated for all Storage in an LIST_ENTRY.\r | |
1479 | \r | |
1480 | @param FormSet Pointer of the FormSet\r | |
1481 | \r | |
1482 | **/\r | |
1483 | VOID\r | |
1484 | DestroyAllStorage (\r | |
1485 | IN LIST_ENTRY *StorageEntryListHead\r | |
1486 | )\r | |
1487 | {\r | |
1488 | LIST_ENTRY *Link;\r | |
1489 | FORMSET_STORAGE *Storage;\r | |
1490 | //\r | |
1491 | // Parse Fromset one by one\r | |
1492 | //\r | |
1493 | if (StorageEntryListHead->ForwardLink != NULL) {\r | |
1494 | while (!IsListEmpty (StorageEntryListHead)) {\r | |
1495 | Link = GetFirstNode (StorageEntryListHead);\r | |
1496 | Storage = FORMSET_STORAGE_FROM_LINK (Link);\r | |
1497 | RemoveEntryList (&Storage->Link);\r | |
1498 | \r | |
1499 | DestroyStorage (Storage);\r | |
1500 | }\r | |
1501 | }\r | |
1502 | StorageEntryListHead = NULL;\r | |
1503 | }\r | |
1504 | \r | |
1505 | /**\r | |
1506 | Free resources of a Statement.\r | |
1507 | \r | |
1508 | @param FormSet Pointer of the FormSet\r | |
1509 | @param Statement Pointer of the Statement\r | |
1510 | \r | |
1511 | **/\r | |
1512 | VOID\r | |
1513 | DestroyStatement (\r | |
1514 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
1515 | IN OUT FORM_BROWSER_STATEMENT *Statement\r | |
1516 | )\r | |
1517 | {\r | |
1518 | LIST_ENTRY *Link;\r | |
1519 | QUESTION_DEFAULT *Default;\r | |
1520 | QUESTION_OPTION *Option;\r | |
1521 | FORM_EXPRESSION *Expression;\r | |
1522 | \r | |
1523 | //\r | |
1524 | // Free Default value List\r | |
1525 | //\r | |
1526 | while (!IsListEmpty (&Statement->DefaultListHead)) {\r | |
1527 | Link = GetFirstNode (&Statement->DefaultListHead);\r | |
1528 | Default = QUESTION_DEFAULT_FROM_LINK (Link);\r | |
1529 | RemoveEntryList (&Default->Link);\r | |
1530 | \r | |
1531 | if (Default->Value.Buffer != NULL) {\r | |
1532 | FreePool(Default->Value.Buffer);\r | |
1533 | }\r | |
1534 | FreePool (Default);\r | |
1535 | }\r | |
1536 | \r | |
1537 | //\r | |
1538 | // Free Options List\r | |
1539 | //\r | |
1540 | while (!IsListEmpty (&Statement->OptionListHead)) {\r | |
1541 | Link = GetFirstNode (&Statement->OptionListHead);\r | |
1542 | Option = QUESTION_OPTION_FROM_LINK (Link);\r | |
1543 | RemoveEntryList (&Option->Link);\r | |
1544 | \r | |
1545 | FreePool (Option);\r | |
1546 | }\r | |
1547 | \r | |
1548 | //\r | |
1549 | // Free Inconsistent List\r | |
1550 | //\r | |
1551 | while (!IsListEmpty (&Statement->InconsistentListHead)) {\r | |
1552 | Link = GetFirstNode (&Statement->InconsistentListHead);\r | |
1553 | Expression = FORM_EXPRESSION_FROM_LINK (Link);\r | |
1554 | RemoveEntryList (&Expression->Link);\r | |
1555 | \r | |
1556 | DestroyExpression (Expression);\r | |
1557 | }\r | |
1558 | \r | |
1559 | //\r | |
1560 | // Free NoSubmit List\r | |
1561 | //\r | |
1562 | while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r | |
1563 | Link = GetFirstNode (&Statement->NoSubmitListHead);\r | |
1564 | Expression = FORM_EXPRESSION_FROM_LINK (Link);\r | |
1565 | RemoveEntryList (&Expression->Link);\r | |
1566 | \r | |
1567 | DestroyExpression (Expression);\r | |
1568 | }\r | |
1569 | \r | |
1570 | //\r | |
1571 | // Free WarningIf List\r | |
1572 | //\r | |
1573 | while (!IsListEmpty (&Statement->WarningListHead)) {\r | |
1574 | Link = GetFirstNode (&Statement->WarningListHead);\r | |
1575 | Expression = FORM_EXPRESSION_FROM_LINK (Link);\r | |
1576 | RemoveEntryList (&Expression->Link);\r | |
1577 | \r | |
1578 | DestroyExpression (Expression);\r | |
1579 | }\r | |
1580 | if (Statement->VariableName != NULL) {\r | |
1581 | FreePool (Statement->VariableName);\r | |
1582 | }\r | |
1583 | if (Statement->BufferValue != NULL) {\r | |
1584 | FreePool (Statement->BufferValue);\r | |
1585 | }\r | |
1586 | }\r | |
1587 | \r | |
1588 | /**\r | |
1589 | Free resources of a Form.\r | |
1590 | \r | |
1591 | @param FormSet Pointer of the FormSet\r | |
1592 | @param Form Pointer of the Form.\r | |
1593 | \r | |
1594 | **/\r | |
1595 | VOID\r | |
1596 | DestroyForm (\r | |
1597 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
1598 | IN OUT FORM_BROWSER_FORM *Form\r | |
1599 | )\r | |
1600 | {\r | |
1601 | LIST_ENTRY *Link;\r | |
1602 | FORM_EXPRESSION *Expression;\r | |
1603 | FORM_BROWSER_STATEMENT *Statement;\r | |
1604 | \r | |
1605 | //\r | |
1606 | // Free Form Expressions\r | |
1607 | //\r | |
1608 | while (!IsListEmpty (&Form->ExpressionListHead)) {\r | |
1609 | Link = GetFirstNode (&Form->ExpressionListHead);\r | |
1610 | Expression = FORM_EXPRESSION_FROM_LINK (Link);\r | |
1611 | RemoveEntryList (&Expression->Link);\r | |
1612 | \r | |
1613 | DestroyExpression (Expression);\r | |
1614 | }\r | |
1615 | \r | |
1616 | //\r | |
1617 | // Free Statements/Questions\r | |
1618 | //\r | |
1619 | while (!IsListEmpty (&Form->StatementListHead)) {\r | |
1620 | Link = GetFirstNode (&Form->StatementListHead);\r | |
1621 | Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r | |
1622 | RemoveEntryList (&Statement->Link);\r | |
1623 | \r | |
1624 | DestroyStatement (FormSet, Statement);\r | |
1625 | }\r | |
1626 | \r | |
1627 | //\r | |
1628 | // Free this Form\r | |
1629 | //\r | |
1630 | FreePool (Form);\r | |
1631 | }\r | |
1632 | \r | |
1633 | \r | |
1634 | /**\r | |
1635 | Free resources allocated for a FormSet.\r | |
1636 | \r | |
1637 | @param FormSet Pointer of the FormSet\r | |
1638 | \r | |
1639 | **/\r | |
1640 | VOID\r | |
1641 | DestroyFormSet (\r | |
1642 | IN FORM_BROWSER_FORMSET *FormSet\r | |
1643 | )\r | |
1644 | {\r | |
1645 | LIST_ENTRY *Link;\r | |
1646 | FORMSET_DEFAULTSTORE *DefaultStore;\r | |
1647 | FORM_EXPRESSION *Expression;\r | |
1648 | FORM_BROWSER_FORM *Form;\r | |
1649 | UINT16 Index;\r | |
1650 | \r | |
1651 | //\r | |
1652 | // Free FormSet Default Store\r | |
1653 | //\r | |
1654 | if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r | |
1655 | while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r | |
1656 | Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r | |
1657 | DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r | |
1658 | RemoveEntryList (&DefaultStore->Link);\r | |
1659 | \r | |
1660 | FreePool (DefaultStore);\r | |
1661 | }\r | |
1662 | }\r | |
1663 | \r | |
1664 | //\r | |
1665 | // Free Formset Expressions\r | |
1666 | //\r | |
1667 | while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r | |
1668 | Link = GetFirstNode (&FormSet->ExpressionListHead);\r | |
1669 | Expression = FORM_EXPRESSION_FROM_LINK (Link);\r | |
1670 | RemoveEntryList (&Expression->Link);\r | |
1671 | \r | |
1672 | DestroyExpression (Expression);\r | |
1673 | }\r | |
1674 | \r | |
1675 | //\r | |
1676 | // Free Forms\r | |
1677 | //\r | |
1678 | if (FormSet->FormListHead.ForwardLink != NULL) {\r | |
1679 | while (!IsListEmpty (&FormSet->FormListHead)) {\r | |
1680 | Link = GetFirstNode (&FormSet->FormListHead);\r | |
1681 | Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r | |
1682 | RemoveEntryList (&Form->Link);\r | |
1683 | \r | |
1684 | DestroyForm (FormSet, Form);\r | |
1685 | }\r | |
1686 | }\r | |
1687 | \r | |
1688 | if (FormSet->StatementBuffer != NULL) {\r | |
1689 | FreePool (FormSet->StatementBuffer);\r | |
1690 | }\r | |
1691 | if (FormSet->ExpressionBuffer != NULL) {\r | |
1692 | FreePool (FormSet->ExpressionBuffer);\r | |
1693 | }\r | |
1694 | if (FormSet->EnUsStringList.StringInfoList != NULL) {\r | |
1695 | for (Index = 0; Index < FormSet->EnUsStringList.CachedIdNum; Index ++) {\r | |
1696 | FreePool (FormSet->EnUsStringList.StringInfoList[Index].String);\r | |
1697 | }\r | |
1698 | FreePool (FormSet->EnUsStringList.StringInfoList);\r | |
1699 | }\r | |
1700 | if (FormSet->UqiStringList.StringInfoList != NULL) {\r | |
1701 | for (Index = 0; Index < FormSet->UqiStringList.CachedIdNum; Index ++) {\r | |
1702 | FreePool (FormSet->UqiStringList.StringInfoList[Index].String);\r | |
1703 | }\r | |
1704 | FreePool (FormSet->UqiStringList.StringInfoList);\r | |
1705 | }\r | |
1706 | \r | |
1707 | FreePool (FormSet);\r | |
1708 | }\r | |
1709 | \r | |
1710 | /**\r | |
1711 | Free resources allocated for all FormSet in an LIST_ENTRY.\r | |
1712 | \r | |
1713 | @param FormSet Pointer of the FormSet\r | |
1714 | \r | |
1715 | **/\r | |
1716 | VOID\r | |
1717 | DestroyAllFormSet (\r | |
1718 | IN LIST_ENTRY *FormSetEntryListHead\r | |
1719 | )\r | |
1720 | {\r | |
1721 | LIST_ENTRY *Link;\r | |
1722 | FORM_BROWSER_FORMSET *FormSet;\r | |
1723 | //\r | |
1724 | // Parse Fromset one by one\r | |
1725 | //\r | |
1726 | if (FormSetEntryListHead->ForwardLink != NULL) {\r | |
1727 | while (!IsListEmpty (FormSetEntryListHead)) {\r | |
1728 | Link = GetFirstNode (FormSetEntryListHead);\r | |
1729 | FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r | |
1730 | RemoveEntryList (&FormSet->Link);\r | |
1731 | DestroyFormSet (FormSet);\r | |
1732 | }\r | |
1733 | }\r | |
1734 | }\r | |
1735 | \r | |
1736 | /**\r | |
1737 | Tell whether this Operand is an Expression OpCode or not\r | |
1738 | \r | |
1739 | @param Operand Operand of an IFR OpCode.\r | |
1740 | \r | |
1741 | @retval TRUE This is an Expression OpCode.\r | |
1742 | @retval FALSE Not an Expression OpCode.\r | |
1743 | \r | |
1744 | **/\r | |
1745 | BOOLEAN\r | |
1746 | IsExpressionOpCode (\r | |
1747 | IN UINT8 Operand\r | |
1748 | )\r | |
1749 | {\r | |
1750 | if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r | |
1751 | ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||\r | |
1752 | ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r | |
1753 | (Operand == EFI_IFR_CATENATE_OP) ||\r | |
1754 | (Operand == EFI_IFR_TO_LOWER_OP) ||\r | |
1755 | (Operand == EFI_IFR_TO_UPPER_OP) ||\r | |
1756 | (Operand == EFI_IFR_MAP_OP) ||\r | |
1757 | (Operand == EFI_IFR_VERSION_OP) ||\r | |
1758 | (Operand == EFI_IFR_SECURITY_OP)) {\r | |
1759 | return TRUE;\r | |
1760 | } else {\r | |
1761 | return FALSE;\r | |
1762 | }\r | |
1763 | }\r | |
1764 | \r | |
1765 | \r | |
1766 | /**\r | |
1767 | Calculate number of Statemens(Questions) and Expression OpCodes.\r | |
1768 | \r | |
1769 | @param FormSet The FormSet to be counted.\r | |
1770 | @param NumberOfStatement Number of Statemens(Questions)\r | |
1771 | @param NumberOfExpression Number of Expression OpCodes\r | |
1772 | \r | |
1773 | **/\r | |
1774 | VOID\r | |
1775 | CountOpCodes (\r | |
1776 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
1777 | IN OUT UINT16 *NumberOfStatement,\r | |
1778 | IN OUT UINT16 *NumberOfExpression\r | |
1779 | )\r | |
1780 | {\r | |
1781 | UINT16 StatementCount;\r | |
1782 | UINT16 ExpressionCount;\r | |
1783 | UINT8 *OpCodeData;\r | |
1784 | UINTN Offset;\r | |
1785 | UINTN OpCodeLen;\r | |
1786 | \r | |
1787 | Offset = 0;\r | |
1788 | StatementCount = 0;\r | |
1789 | ExpressionCount = 0;\r | |
1790 | \r | |
1791 | while (Offset < FormSet->IfrBinaryLength) {\r | |
1792 | OpCodeData = FormSet->IfrBinaryData + Offset;\r | |
1793 | OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r | |
1794 | Offset += OpCodeLen;\r | |
1795 | \r | |
1796 | if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r | |
1797 | ExpressionCount++;\r | |
1798 | } else {\r | |
1799 | StatementCount++;\r | |
1800 | }\r | |
1801 | }\r | |
1802 | \r | |
1803 | *NumberOfStatement = StatementCount;\r | |
1804 | *NumberOfExpression = ExpressionCount;\r | |
1805 | }\r | |
1806 | \r | |
1807 | \r | |
1808 | \r | |
1809 | /**\r | |
1810 | Parse opcodes in the formset IFR binary.\r | |
1811 | \r | |
1812 | @param FormSet Pointer of the FormSet data structure.\r | |
1813 | \r | |
1814 | @retval EFI_SUCCESS Opcode parse success.\r | |
1815 | @retval Other Opcode parse fail.\r | |
1816 | \r | |
1817 | **/\r | |
1818 | EFI_STATUS\r | |
1819 | ParseOpCodes (\r | |
1820 | IN FORM_BROWSER_FORMSET *FormSet\r | |
1821 | )\r | |
1822 | {\r | |
1823 | EFI_STATUS Status;\r | |
1824 | UINT16 Index;\r | |
1825 | FORM_BROWSER_FORM *CurrentForm;\r | |
1826 | FORM_BROWSER_STATEMENT *CurrentStatement;\r | |
1827 | EXPRESSION_OPCODE *ExpressionOpCode;\r | |
1828 | FORM_EXPRESSION *CurrentExpression;\r | |
1829 | UINT8 Operand;\r | |
1830 | UINT8 Scope;\r | |
1831 | UINTN OpCodeOffset;\r | |
1832 | UINTN OpCodeLength;\r | |
1833 | UINT8 *OpCodeData;\r | |
1834 | UINT8 ScopeOpCode;\r | |
1835 | FORMSET_STORAGE *Storage;\r | |
1836 | FORMSET_STORAGE *TempStorage;\r | |
1837 | FORMSET_DEFAULTSTORE *DefaultStore;\r | |
1838 | QUESTION_DEFAULT *CurrentDefault;\r | |
1839 | QUESTION_OPTION *CurrentOption;\r | |
1840 | UINT8 Width;\r | |
1841 | CHAR8 *AsciiString;\r | |
1842 | UINT16 NumberOfStatement;\r | |
1843 | UINT16 NumberOfExpression;\r | |
1844 | BOOLEAN SuppressForQuestion;\r | |
1845 | BOOLEAN SuppressForOption;\r | |
1846 | BOOLEAN InScopeOptionSuppress;\r | |
1847 | FORM_EXPRESSION *OptionSuppressExpression;\r | |
1848 | BOOLEAN InScopeFormSuppress;\r | |
1849 | FORM_EXPRESSION *FormSuppressExpression;\r | |
1850 | UINT16 DepthOfDisable;\r | |
1851 | BOOLEAN OpCodeDisabled;\r | |
1852 | BOOLEAN SingleOpCodeExpression;\r | |
1853 | BOOLEAN InScopeDefault;\r | |
1854 | EFI_HII_VALUE *Value;\r | |
1855 | UINT8 MapScopeDepth;\r | |
1856 | LIST_ENTRY *Link;\r | |
1857 | FORMSET_STORAGE *VarStorage;\r | |
1858 | LIST_ENTRY *MapExpressionList;\r | |
1859 | EFI_VARSTORE_ID TempVarstoreId;\r | |
1860 | BOOLEAN ConstantFlag;\r | |
1861 | FORMSET_DEFAULTSTORE *PreDefaultStore;\r | |
1862 | LIST_ENTRY *DefaultLink;\r | |
1863 | BOOLEAN HaveInserted;\r | |
1864 | BOOLEAN BitFieldStorage;\r | |
1865 | UINT16 TotalBits;\r | |
1866 | \r | |
1867 | mInScopeSubtitle = FALSE;\r | |
1868 | SuppressForQuestion = FALSE;\r | |
1869 | SuppressForOption = FALSE;\r | |
1870 | InScopeFormSuppress = FALSE;\r | |
1871 | mInScopeSuppress = FALSE;\r | |
1872 | InScopeOptionSuppress = FALSE;\r | |
1873 | mInScopeGrayOut = FALSE;\r | |
1874 | mInScopeDisable = FALSE;\r | |
1875 | DepthOfDisable = 0;\r | |
1876 | OpCodeDisabled = FALSE;\r | |
1877 | SingleOpCodeExpression = FALSE;\r | |
1878 | InScopeDefault = FALSE;\r | |
1879 | CurrentExpression = NULL;\r | |
1880 | CurrentDefault = NULL;\r | |
1881 | CurrentOption = NULL;\r | |
1882 | OptionSuppressExpression = NULL;\r | |
1883 | FormSuppressExpression = NULL;\r | |
1884 | MapScopeDepth = 0;\r | |
1885 | Link = NULL;\r | |
1886 | VarStorage = NULL;\r | |
1887 | MapExpressionList = NULL;\r | |
1888 | TempVarstoreId = 0;\r | |
1889 | ConstantFlag = TRUE;\r | |
1890 | BitFieldStorage = FALSE;\r | |
1891 | \r | |
1892 | //\r | |
1893 | // Get the number of Statements and Expressions\r | |
1894 | //\r | |
1895 | CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r | |
1896 | \r | |
1897 | mStatementIndex = 0;\r | |
1898 | FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r | |
1899 | if (FormSet->StatementBuffer == NULL) {\r | |
1900 | return EFI_OUT_OF_RESOURCES;\r | |
1901 | }\r | |
1902 | \r | |
1903 | mExpressionOpCodeIndex = 0;\r | |
1904 | FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r | |
1905 | if (FormSet->ExpressionBuffer == NULL) {\r | |
1906 | return EFI_OUT_OF_RESOURCES;\r | |
1907 | }\r | |
1908 | \r | |
1909 | FormSet->StorageListHead = &mVarListEntry;\r | |
1910 | InitializeListHead (&FormSet->DefaultStoreListHead);\r | |
1911 | InitializeListHead (&FormSet->FormListHead);\r | |
1912 | InitializeListHead (&FormSet->ExpressionListHead);\r | |
1913 | ResetCurrentExpressionStack ();\r | |
1914 | ResetMapExpressionListStack ();\r | |
1915 | \r | |
1916 | CurrentForm = NULL;\r | |
1917 | CurrentStatement = NULL;\r | |
1918 | \r | |
1919 | ResetScopeStack ();\r | |
1920 | \r | |
1921 | OpCodeOffset = 0;\r | |
1922 | while (OpCodeOffset < FormSet->IfrBinaryLength) {\r | |
1923 | OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r | |
1924 | \r | |
1925 | OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r | |
1926 | OpCodeOffset += OpCodeLength;\r | |
1927 | Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r | |
1928 | Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r | |
1929 | \r | |
1930 | //\r | |
1931 | // If scope bit set, push onto scope stack\r | |
1932 | //\r | |
1933 | if (Scope != 0) {\r | |
1934 | PushScope (Operand);\r | |
1935 | }\r | |
1936 | \r | |
1937 | if (OpCodeDisabled) {\r | |
1938 | //\r | |
1939 | // DisableIf Expression is evaluated to be TRUE, try to find its end.\r | |
1940 | // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r | |
1941 | //\r | |
1942 | if (Operand == EFI_IFR_DISABLE_IF_OP) {\r | |
1943 | DepthOfDisable++;\r | |
1944 | } else if (Operand == EFI_IFR_END_OP) {\r | |
1945 | Status = PopScope (&ScopeOpCode);\r | |
1946 | if (EFI_ERROR (Status)) {\r | |
1947 | return Status;\r | |
1948 | }\r | |
1949 | \r | |
1950 | if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r | |
1951 | if (DepthOfDisable == 0) {\r | |
1952 | mInScopeDisable = FALSE;\r | |
1953 | OpCodeDisabled = FALSE;\r | |
1954 | } else {\r | |
1955 | DepthOfDisable--;\r | |
1956 | }\r | |
1957 | }\r | |
1958 | }\r | |
1959 | continue;\r | |
1960 | }\r | |
1961 | \r | |
1962 | if (IsExpressionOpCode (Operand)) {\r | |
1963 | ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r | |
1964 | mExpressionOpCodeIndex++;\r | |
1965 | \r | |
1966 | ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r | |
1967 | ExpressionOpCode->Operand = Operand;\r | |
1968 | Value = &ExpressionOpCode->Value;\r | |
1969 | \r | |
1970 | switch (Operand) {\r | |
1971 | case EFI_IFR_EQ_ID_VAL_OP:\r | |
1972 | CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r | |
1973 | \r | |
1974 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r | |
1975 | CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r | |
1976 | break;\r | |
1977 | \r | |
1978 | case EFI_IFR_EQ_ID_ID_OP:\r | |
1979 | CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r | |
1980 | CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r | |
1981 | break;\r | |
1982 | \r | |
1983 | case EFI_IFR_EQ_ID_VAL_LIST_OP:\r | |
1984 | CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r | |
1985 | CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r | |
1986 | ExpressionOpCode->ValueList = FceAllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r | |
1987 | break;\r | |
1988 | \r | |
1989 | case EFI_IFR_TO_STRING_OP:\r | |
1990 | case EFI_IFR_FIND_OP:\r | |
1991 | ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r | |
1992 | break;\r | |
1993 | \r | |
1994 | case EFI_IFR_STRING_REF1_OP:\r | |
1995 | Value->Type = EFI_IFR_TYPE_STRING;\r | |
1996 | CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r | |
1997 | break;\r | |
1998 | \r | |
1999 | case EFI_IFR_RULE_REF_OP:\r | |
2000 | ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r | |
2001 | break;\r | |
2002 | \r | |
2003 | case EFI_IFR_SPAN_OP:\r | |
2004 | ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r | |
2005 | break;\r | |
2006 | \r | |
2007 | case EFI_IFR_THIS_OP:\r | |
2008 | ASSERT (CurrentStatement != NULL);\r | |
2009 | ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r | |
2010 | break;\r | |
2011 | \r | |
2012 | case EFI_IFR_SECURITY_OP:\r | |
2013 | CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r | |
2014 | break;\r | |
2015 | \r | |
2016 | case EFI_IFR_GET_OP:\r | |
2017 | case EFI_IFR_SET_OP:\r | |
2018 | CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r | |
2019 | if (TempVarstoreId != 0) {\r | |
2020 | if (FormSet->StorageListHead->ForwardLink != NULL) {\r | |
2021 | Link = GetFirstNode (FormSet->StorageListHead);\r | |
2022 | while (!IsNull (FormSet->StorageListHead, Link)) {\r | |
2023 | VarStorage = FORMSET_STORAGE_FROM_LINK (Link);\r | |
2024 | if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {\r | |
2025 | ExpressionOpCode->VarStorage = VarStorage;\r | |
2026 | break;\r | |
2027 | }\r | |
2028 | Link = GetNextNode (FormSet->StorageListHead, Link);\r | |
2029 | }\r | |
2030 | }\r | |
2031 | if (ExpressionOpCode->VarStorage == NULL) {\r | |
2032 | //\r | |
2033 | // VarStorage is not found.\r | |
2034 | //\r | |
2035 | return EFI_INVALID_PARAMETER;\r | |
2036 | }\r | |
2037 | }\r | |
2038 | ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;\r | |
2039 | switch (ExpressionOpCode->ValueType) {\r | |
2040 | case EFI_IFR_TYPE_BOOLEAN:\r | |
2041 | case EFI_IFR_TYPE_NUM_SIZE_8:\r | |
2042 | ExpressionOpCode->ValueWidth = 1;\r | |
2043 | break;\r | |
2044 | \r | |
2045 | case EFI_IFR_TYPE_NUM_SIZE_16:\r | |
2046 | case EFI_IFR_TYPE_STRING:\r | |
2047 | ExpressionOpCode->ValueWidth = 2;\r | |
2048 | break;\r | |
2049 | \r | |
2050 | case EFI_IFR_TYPE_NUM_SIZE_32:\r | |
2051 | ExpressionOpCode->ValueWidth = 4;\r | |
2052 | break;\r | |
2053 | \r | |
2054 | case EFI_IFR_TYPE_NUM_SIZE_64:\r | |
2055 | ExpressionOpCode->ValueWidth = 8;\r | |
2056 | break;\r | |
2057 | \r | |
2058 | case EFI_IFR_TYPE_DATE:\r | |
2059 | ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);\r | |
2060 | break;\r | |
2061 | \r | |
2062 | case EFI_IFR_TYPE_TIME:\r | |
2063 | ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);\r | |
2064 | break;\r | |
2065 | \r | |
2066 | case EFI_IFR_TYPE_REF:\r | |
2067 | ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);\r | |
2068 | break;\r | |
2069 | \r | |
2070 | case EFI_IFR_TYPE_OTHER:\r | |
2071 | case EFI_IFR_TYPE_UNDEFINED:\r | |
2072 | case EFI_IFR_TYPE_ACTION:\r | |
2073 | case EFI_IFR_TYPE_BUFFER:\r | |
2074 | default:\r | |
2075 | //\r | |
2076 | // Invalid value type for Get/Set opcode.\r | |
2077 | //\r | |
2078 | return EFI_INVALID_PARAMETER;\r | |
2079 | }\r | |
2080 | CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));\r | |
2081 | CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));\r | |
2082 | if ((ExpressionOpCode->VarStorage != NULL) &&\r | |
2083 | ((ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE)\r | |
2084 | || ((ExpressionOpCode->VarStorage->Type == EFI_IFR_VARSTORE_EFI_OP) && !ExpressionOpCode->VarStorage->NewEfiVarstore))\r | |
2085 | ) {\r | |
2086 | ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->UnicodeBinary);\r | |
2087 | if (ExpressionOpCode->ValueName == NULL) {\r | |
2088 | //\r | |
2089 | // String ID is invalid.\r | |
2090 | //\r | |
2091 | return EFI_INVALID_PARAMETER;\r | |
2092 | }\r | |
2093 | }\r | |
2094 | break;\r | |
2095 | \r | |
2096 | case EFI_IFR_QUESTION_REF1_OP:\r | |
2097 | CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r | |
2098 | break;\r | |
2099 | \r | |
2100 | case EFI_IFR_QUESTION_REF3_OP:\r | |
2101 | if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r | |
2102 | CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r | |
2103 | \r | |
2104 | if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r | |
2105 | CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r | |
2106 | }\r | |
2107 | }\r | |
2108 | break;\r | |
2109 | \r | |
2110 | //\r | |
2111 | // constant\r | |
2112 | //\r | |
2113 | case EFI_IFR_TRUE_OP:\r | |
2114 | Value->Type = EFI_IFR_TYPE_BOOLEAN;\r | |
2115 | Value->Value.b = TRUE;\r | |
2116 | break;\r | |
2117 | \r | |
2118 | case EFI_IFR_FALSE_OP:\r | |
2119 | Value->Type = EFI_IFR_TYPE_BOOLEAN;\r | |
2120 | Value->Value.b = FALSE;\r | |
2121 | break;\r | |
2122 | \r | |
2123 | case EFI_IFR_ONE_OP:\r | |
2124 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r | |
2125 | Value->Value.u8 = 1;\r | |
2126 | break;\r | |
2127 | \r | |
2128 | case EFI_IFR_ZERO_OP:\r | |
2129 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r | |
2130 | Value->Value.u8 = 0;\r | |
2131 | break;\r | |
2132 | \r | |
2133 | case EFI_IFR_ONES_OP:\r | |
2134 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r | |
2135 | Value->Value.u64 = 0xffffffffffffffffULL;\r | |
2136 | break;\r | |
2137 | \r | |
2138 | case EFI_IFR_UINT8_OP:\r | |
2139 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r | |
2140 | Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r | |
2141 | break;\r | |
2142 | \r | |
2143 | case EFI_IFR_UINT16_OP:\r | |
2144 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r | |
2145 | CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r | |
2146 | break;\r | |
2147 | \r | |
2148 | case EFI_IFR_UINT32_OP:\r | |
2149 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r | |
2150 | CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r | |
2151 | break;\r | |
2152 | \r | |
2153 | case EFI_IFR_UINT64_OP:\r | |
2154 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r | |
2155 | CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r | |
2156 | break;\r | |
2157 | \r | |
2158 | case EFI_IFR_UNDEFINED_OP:\r | |
2159 | Value->Type = EFI_IFR_TYPE_UNDEFINED;\r | |
2160 | break;\r | |
2161 | \r | |
2162 | case EFI_IFR_VERSION_OP:\r | |
2163 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r | |
2164 | break;\r | |
2165 | \r | |
2166 | default:\r | |
2167 | break;\r | |
2168 | }\r | |
2169 | //\r | |
2170 | // Create sub expression nested in MAP opcode\r | |
2171 | //\r | |
2172 | if ((CurrentExpression == NULL) && (MapScopeDepth > 0)) {\r | |
2173 | CurrentExpression = CreateExpression (CurrentForm);\r | |
2174 | ASSERT (MapExpressionList != NULL);\r | |
2175 | InsertTailList (MapExpressionList, &CurrentExpression->Link);\r | |
2176 | if (Scope == 0) {\r | |
2177 | SingleOpCodeExpression = TRUE;\r | |
2178 | }\r | |
2179 | }\r | |
2180 | ASSERT (CurrentExpression != NULL);\r | |
2181 | InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r | |
2182 | if (Operand == EFI_IFR_MAP_OP) {\r | |
2183 | //\r | |
2184 | // Store current Map Expression List.\r | |
2185 | //\r | |
2186 | if (MapExpressionList != NULL) {\r | |
2187 | PushMapExpressionList (MapExpressionList);\r | |
2188 | }\r | |
2189 | //\r | |
2190 | // Initialize new Map Expression List.\r | |
2191 | //\r | |
2192 | MapExpressionList = &ExpressionOpCode->MapExpressionList;\r | |
2193 | InitializeListHead (MapExpressionList);\r | |
2194 | //\r | |
2195 | // Store current expression.\r | |
2196 | //\r | |
2197 | PushCurrentExpression (CurrentExpression);\r | |
2198 | CurrentExpression = NULL;\r | |
2199 | MapScopeDepth ++;\r | |
2200 | } else if (SingleOpCodeExpression) {\r | |
2201 | //\r | |
2202 | // There are two cases to indicate the end of an Expression:\r | |
2203 | // for single OpCode expression: one Expression OpCode\r | |
2204 | // for expression consists of more than one OpCode: EFI_IFR_END\r | |
2205 | //\r | |
2206 | SingleOpCodeExpression = FALSE;\r | |
2207 | \r | |
2208 | if (mInScopeDisable && (CurrentForm == NULL)) {\r | |
2209 | //\r | |
2210 | // This is DisableIf expression for Form, it should be a constant expression\r | |
2211 | //\r | |
2212 | ConstantFlag = TRUE;\r | |
2213 | Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression, &ConstantFlag);\r | |
2214 | if (EFI_ERROR (Status)) {\r | |
2215 | return Status;\r | |
2216 | }\r | |
2217 | \r | |
2218 | if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r | |
2219 | return EFI_INVALID_PARAMETER;\r | |
2220 | }\r | |
2221 | if (!ConstantFlag) {\r | |
2222 | StringPrint ("WARNING. The DisableIf expression for Form should be a constant expression.\n");\r | |
2223 | }\r | |
2224 | OpCodeDisabled = CurrentExpression->Result.Value.b;\r | |
2225 | }\r | |
2226 | \r | |
2227 | CurrentExpression = NULL;\r | |
2228 | }\r | |
2229 | \r | |
2230 | continue;\r | |
2231 | }\r | |
2232 | \r | |
2233 | //\r | |
2234 | // Parse the Opcode\r | |
2235 | //\r | |
2236 | switch (Operand) {\r | |
2237 | \r | |
2238 | case EFI_IFR_FORM_SET_OP:\r | |
2239 | \r | |
2240 | CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r | |
2241 | CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r | |
2242 | CopyMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r | |
2243 | \r | |
2244 | if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r | |
2245 | //\r | |
2246 | // The formset OpCode contains ClassGuid\r | |
2247 | //\r | |
2248 | FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r | |
2249 | CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r | |
2250 | }\r | |
2251 | FormSet->FormSetOrder = ++mFormSetOrderParse;\r | |
2252 | break;\r | |
2253 | \r | |
2254 | case EFI_IFR_FORM_OP:\r | |
2255 | case EFI_IFR_FORM_MAP_OP:\r | |
2256 | //\r | |
2257 | // Create a new Form for this FormSet\r | |
2258 | //\r | |
2259 | CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r | |
2260 | ASSERT (CurrentForm != NULL);\r | |
2261 | CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r | |
2262 | InitializeListHead (&CurrentForm->ExpressionListHead);\r | |
2263 | InitializeListHead (&CurrentForm->StatementListHead);\r | |
2264 | \r | |
2265 | CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r | |
2266 | CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r | |
2267 | CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r | |
2268 | \r | |
2269 | if (InScopeFormSuppress) {\r | |
2270 | //\r | |
2271 | // Form is inside of suppressif\r | |
2272 | //\r | |
2273 | CurrentForm->SuppressExpression = FormSuppressExpression;\r | |
2274 | }\r | |
2275 | \r | |
2276 | if (Scope != 0) {\r | |
2277 | //\r | |
2278 | // Enter scope of a Form, suppressif will be used for Question or Option\r | |
2279 | //\r | |
2280 | SuppressForQuestion = TRUE;\r | |
2281 | }\r | |
2282 | \r | |
2283 | //\r | |
2284 | // Insert into Form list of this FormSet\r | |
2285 | //\r | |
2286 | InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r | |
2287 | break;\r | |
2288 | //\r | |
2289 | // Storage\r | |
2290 | //\r | |
2291 | case EFI_IFR_VARSTORE_OP:\r | |
2292 | //\r | |
2293 | // Create a buffer Storage for this FormSet\r | |
2294 | //\r | |
2295 | \r | |
2296 | Storage = CreateStorage (FormSet);\r | |
2297 | Storage->Type = EFI_IFR_VARSTORE_OP;\r | |
2298 | \r | |
2299 | CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r | |
2300 | CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r | |
2301 | CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r | |
2302 | \r | |
2303 | Storage->Buffer = AllocateZeroPool (Storage->Size);\r | |
2304 | \r | |
2305 | AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r | |
2306 | Storage->Name = AllocateZeroPool ((strlen (AsciiString) + 1) * 2);\r | |
2307 | ASSERT (Storage->Name != NULL);\r | |
2308 | for (Index = 0; AsciiString[Index] != 0; Index++) {\r | |
2309 | Storage->Name[Index] = (CHAR16) AsciiString[Index];\r | |
2310 | }\r | |
2311 | Storage->FormSetOrder = mFormSetOrderParse;\r | |
2312 | \r | |
2313 | //\r | |
2314 | // If not existed the same variable in StorageList, insert the new one. Or else, use the old one.\r | |
2315 | // If these two variales have the same Guid name but different size, report an error.\r | |
2316 | //\r | |
2317 | if ((TempStorage = NotSameVariableInVarList (FormSet->StorageListHead, Storage)) != NULL) {\r | |
2318 | if (Storage->Size != TempStorage->Size) {\r | |
2319 | StringPrint ("Error. Two modules found with VarStore variables with same name %S and GUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x, but with different sizes %d and %d.\n",\r | |
2320 | Storage->Name,\r | |
2321 | Storage->Guid.Data1,\r | |
2322 | Storage->Guid.Data2,\r | |
2323 | Storage->Guid.Data3,\r | |
2324 | Storage->Guid.Data4[0],\r | |
2325 | Storage->Guid.Data4[1],\r | |
2326 | Storage->Guid.Data4[2],\r | |
2327 | Storage->Guid.Data4[3],\r | |
2328 | Storage->Guid.Data4[4],\r | |
2329 | Storage->Guid.Data4[5],\r | |
2330 | Storage->Guid.Data4[6],\r | |
2331 | Storage->Guid.Data4[7],\r | |
2332 | Storage->Size,\r | |
2333 | TempStorage->Size\r | |
2334 | );\r | |
2335 | return EFI_ABORTED;\r | |
2336 | }\r | |
2337 | //\r | |
2338 | // Update the VarStoreId for current question to get the variable guid and name information\r | |
2339 | //\r | |
2340 | TempStorage->VarStoreId = Storage->VarStoreId;\r | |
2341 | TempStorage->FormSetOrder = Storage->FormSetOrder;\r | |
2342 | RemoveEntryList (&Storage->Link);\r | |
2343 | DestroyStorage(Storage);\r | |
2344 | }\r | |
2345 | break;\r | |
2346 | \r | |
2347 | case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r | |
2348 | //\r | |
2349 | // Create a name/value Storage for this FormSet\r | |
2350 | //\r | |
2351 | Storage = CreateStorage (FormSet);\r | |
2352 | Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r | |
2353 | \r | |
2354 | CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r | |
2355 | CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r | |
2356 | \r | |
2357 | Storage->FormSetOrder = mFormSetOrderParse;\r | |
2358 | break;\r | |
2359 | \r | |
2360 | case EFI_IFR_VARSTORE_EFI_OP:\r | |
2361 | //\r | |
2362 | // Create a EFI variable Storage for this FormSet\r | |
2363 | //\r | |
2364 | Storage = CreateStorage (FormSet);\r | |
2365 | Storage->Type = EFI_IFR_VARSTORE_EFI_OP;\r | |
2366 | CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r | |
2367 | CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r | |
2368 | CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r | |
2369 | //\r | |
2370 | // Check whether the EfiVarStore before UEFI2.31 or not\r | |
2371 | //\r | |
2372 | Storage->Size = sizeof (EFI_IFR_VARSTORE_EFI_OLD);\r | |
2373 | if (((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Header.Length == sizeof (EFI_IFR_VARSTORE_EFI_OLD)) {\r | |
2374 | Storage->NewEfiVarstore = FALSE;\r | |
2375 | Storage->Size = 0;\r | |
2376 | Storage->Buffer = NULL;\r | |
2377 | Storage->Name = NULL;\r | |
2378 | Storage->Size = 0;\r | |
2379 | } else {\r | |
2380 | //\r | |
2381 | // EfiVarStore structure for UEFI2.31\r | |
2382 | //\r | |
2383 | Storage->NewEfiVarstore = TRUE;\r | |
2384 | CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));\r | |
2385 | \r | |
2386 | Storage->Buffer = AllocateZeroPool (Storage->Size);\r | |
2387 | AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;\r | |
2388 | Storage->Name = AllocateZeroPool ((strlen (AsciiString) + 1) * 2);\r | |
2389 | ASSERT (Storage->Name != NULL);\r | |
2390 | for (Index = 0; AsciiString[Index] != 0; Index++) {\r | |
2391 | Storage->Name[Index] = (CHAR16) AsciiString[Index];\r | |
2392 | }\r | |
2393 | }\r | |
2394 | Storage->FormSetOrder = mFormSetOrderParse;\r | |
2395 | //\r | |
2396 | // If not existed the same variable in StorageList, insert the new one. Or else, use the old one.\r | |
2397 | // If these two variales have the same Guid name but different size, report an error.\r | |
2398 | //\r | |
2399 | if ((TempStorage = NotSameVariableInVarList (FormSet->StorageListHead, Storage)) != NULL) {\r | |
2400 | if (Storage->Size != TempStorage->Size) {\r | |
2401 | StringPrint ("Error. Two modules found with EfiVarStore variables with same name %S and GUID %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x, but different sizes %d and %d.\n",\r | |
2402 | Storage->Name,\r | |
2403 | Storage->Guid.Data1,\r | |
2404 | Storage->Guid.Data2,\r | |
2405 | Storage->Guid.Data3,\r | |
2406 | Storage->Guid.Data4[0],\r | |
2407 | Storage->Guid.Data4[1],\r | |
2408 | Storage->Guid.Data4[2],\r | |
2409 | Storage->Guid.Data4[3],\r | |
2410 | Storage->Guid.Data4[4],\r | |
2411 | Storage->Guid.Data4[5],\r | |
2412 | Storage->Guid.Data4[6],\r | |
2413 | Storage->Guid.Data4[7],\r | |
2414 | Storage->Size,\r | |
2415 | TempStorage->Size\r | |
2416 | );\r | |
2417 | return EFI_ABORTED;\r | |
2418 | }\r | |
2419 | //\r | |
2420 | // Update the VarStoreId for current question to get the variable guid and name information\r | |
2421 | //\r | |
2422 | TempStorage->VarStoreId = Storage->VarStoreId;\r | |
2423 | TempStorage->FormSetOrder = Storage->FormSetOrder;\r | |
2424 | RemoveEntryList (&Storage->Link);\r | |
2425 | DestroyStorage( Storage);\r | |
2426 | }\r | |
2427 | break;\r | |
2428 | \r | |
2429 | //\r | |
2430 | // DefaultStore\r | |
2431 | //\r | |
2432 | case EFI_IFR_DEFAULTSTORE_OP:\r | |
2433 | HaveInserted = FALSE;\r | |
2434 | DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r | |
2435 | ASSERT (DefaultStore != NULL);\r | |
2436 | DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r | |
2437 | \r | |
2438 | CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r | |
2439 | CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r | |
2440 | \r | |
2441 | //\r | |
2442 | // Insert it to the DefaultStore list of this Formset with ascending order.\r | |
2443 | //\r | |
2444 | if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r | |
2445 | DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r | |
2446 | while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r | |
2447 | PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r | |
2448 | DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r | |
2449 | if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {\r | |
2450 | InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);\r | |
2451 | HaveInserted = TRUE;\r | |
2452 | break;\r | |
2453 | }\r | |
2454 | }\r | |
2455 | }\r | |
2456 | if (!HaveInserted) {\r | |
2457 | InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r | |
2458 | }\r | |
2459 | break;\r | |
2460 | \r | |
2461 | //\r | |
2462 | // Statements\r | |
2463 | //\r | |
2464 | case EFI_IFR_SUBTITLE_OP:\r | |
2465 | CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r | |
2466 | ASSERT (CurrentStatement != NULL);\r | |
2467 | \r | |
2468 | CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r | |
2469 | \r | |
2470 | if (Scope != 0) {\r | |
2471 | mInScopeSubtitle = TRUE;\r | |
2472 | }\r | |
2473 | break;\r | |
2474 | \r | |
2475 | case EFI_IFR_TEXT_OP:\r | |
2476 | CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r | |
2477 | ASSERT (CurrentStatement != NULL);\r | |
2478 | \r | |
2479 | CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r | |
2480 | break;\r | |
2481 | \r | |
2482 | case EFI_IFR_RESET_BUTTON_OP:\r | |
2483 | CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r | |
2484 | ASSERT (CurrentStatement != NULL);\r | |
2485 | CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r | |
2486 | break;\r | |
2487 | \r | |
2488 | //\r | |
2489 | // Questions\r | |
2490 | //\r | |
2491 | case EFI_IFR_ACTION_OP:\r | |
2492 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2493 | ASSERT (CurrentStatement != NULL);\r | |
2494 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r | |
2495 | //\r | |
2496 | // No need to deal with the EFI_IFR_ACTION\r | |
2497 | //\r | |
2498 | break;\r | |
2499 | \r | |
2500 | case EFI_IFR_REF_OP:\r | |
2501 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2502 | ASSERT (CurrentStatement != NULL);\r | |
2503 | Value = &CurrentStatement->HiiValue;\r | |
2504 | Value->Type = EFI_IFR_TYPE_REF;\r | |
2505 | if (OpCodeLength >= sizeof (EFI_IFR_REF)) {\r | |
2506 | CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r | |
2507 | \r | |
2508 | if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r | |
2509 | CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r | |
2510 | \r | |
2511 | if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r | |
2512 | CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r | |
2513 | \r | |
2514 | if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r | |
2515 | CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r | |
2516 | }\r | |
2517 | }\r | |
2518 | }\r | |
2519 | }\r | |
2520 | CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);\r | |
2521 | break;\r | |
2522 | \r | |
2523 | case EFI_IFR_ONE_OF_OP:\r | |
2524 | case EFI_IFR_NUMERIC_OP:\r | |
2525 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2526 | ASSERT(CurrentStatement != NULL);\r | |
2527 | \r | |
2528 | CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r | |
2529 | Value = &CurrentStatement->HiiValue;\r | |
2530 | \r | |
2531 | if (BitFieldStorage) {\r | |
2532 | //\r | |
2533 | // Get the bit var store info (bit/byte offset, bit/byte offset)\r | |
2534 | //\r | |
2535 | CurrentStatement->QuestionReferToBitField = TRUE;\r | |
2536 | CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r | |
2537 | CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r | |
2538 | CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r | |
2539 | TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r | |
2540 | CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r | |
2541 | //\r | |
2542 | // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)\r | |
2543 | //\r | |
2544 | CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue;\r | |
2545 | CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue;\r | |
2546 | CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step;\r | |
2547 | } else {\r | |
2548 | switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r | |
2549 | case EFI_IFR_NUMERIC_SIZE_1:\r | |
2550 | CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r | |
2551 | CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r | |
2552 | CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r | |
2553 | CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r | |
2554 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r | |
2555 | break;\r | |
2556 | \r | |
2557 | case EFI_IFR_NUMERIC_SIZE_2:\r | |
2558 | CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r | |
2559 | CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r | |
2560 | CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r | |
2561 | CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r | |
2562 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r | |
2563 | break;\r | |
2564 | \r | |
2565 | case EFI_IFR_NUMERIC_SIZE_4:\r | |
2566 | CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r | |
2567 | CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r | |
2568 | CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r | |
2569 | CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r | |
2570 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r | |
2571 | break;\r | |
2572 | \r | |
2573 | case EFI_IFR_NUMERIC_SIZE_8:\r | |
2574 | CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r | |
2575 | CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r | |
2576 | CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r | |
2577 | CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r | |
2578 | Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r | |
2579 | break;\r | |
2580 | \r | |
2581 | default:\r | |
2582 | break;\r | |
2583 | }\r | |
2584 | }\r | |
2585 | if ((Operand == EFI_IFR_ONE_OF_OP) && (Scope != 0)) {\r | |
2586 | SuppressForOption = TRUE;\r | |
2587 | }\r | |
2588 | //\r | |
2589 | // Get the UQI information\r | |
2590 | //\r | |
2591 | PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r | |
2592 | //\r | |
2593 | // Exchange the Guid and name information between VarList and Question List\r | |
2594 | //\r | |
2595 | Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r | |
2596 | //\r | |
2597 | // Remove the question which isn't stored by EfiVarStore or VarStore\r | |
2598 | //\r | |
2599 | if (EFI_ERROR (Status)) {\r | |
2600 | RemoveEntryList (&CurrentStatement->Link);\r | |
2601 | DestroyStatement (FormSet, CurrentStatement);\r | |
2602 | }\r | |
2603 | break;\r | |
2604 | \r | |
2605 | case EFI_IFR_ORDERED_LIST_OP:\r | |
2606 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2607 | ASSERT(CurrentStatement != NULL);\r | |
2608 | \r | |
2609 | CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r | |
2610 | CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r | |
2611 | \r | |
2612 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r | |
2613 | CurrentStatement->BufferValue = NULL;\r | |
2614 | if (Scope != 0) {\r | |
2615 | SuppressForOption = TRUE;\r | |
2616 | }\r | |
2617 | //\r | |
2618 | // Get the UQI information\r | |
2619 | //\r | |
2620 | PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r | |
2621 | //\r | |
2622 | // Exchange the Guid and name information between VarList and Question List\r | |
2623 | //\r | |
2624 | Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r | |
2625 | //\r | |
2626 | // Remove the question which isn't stored by EfiVarStore or VarStore\r | |
2627 | //\r | |
2628 | if (EFI_ERROR (Status)) {\r | |
2629 | RemoveEntryList (&CurrentStatement->Link);\r | |
2630 | DestroyStatement (FormSet, CurrentStatement);\r | |
2631 | }\r | |
2632 | \r | |
2633 | break;\r | |
2634 | \r | |
2635 | case EFI_IFR_CHECKBOX_OP:\r | |
2636 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2637 | ASSERT(CurrentStatement != NULL);\r | |
2638 | \r | |
2639 | CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r | |
2640 | CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r | |
2641 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r | |
2642 | \r | |
2643 | if (BitFieldStorage) {\r | |
2644 | //\r | |
2645 | // Get the bit var store info (bit/byte offset, bit/byte width)\r | |
2646 | //\r | |
2647 | CurrentStatement->QuestionReferToBitField = TRUE;\r | |
2648 | CurrentStatement->BitStorageWidth = 1;\r | |
2649 | CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r | |
2650 | CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r | |
2651 | TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r | |
2652 | CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r | |
2653 | }\r | |
2654 | //\r | |
2655 | // Get the UQI information\r | |
2656 | //\r | |
2657 | PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r | |
2658 | //\r | |
2659 | // Exchange the Guid and name information between VarList and Question List\r | |
2660 | //\r | |
2661 | Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r | |
2662 | //\r | |
2663 | // Remove the question which isn't stored by EfiVarStore or VarStore\r | |
2664 | //\r | |
2665 | if (EFI_ERROR (Status)) {\r | |
2666 | RemoveEntryList (&CurrentStatement->Link);\r | |
2667 | DestroyStatement (FormSet, CurrentStatement);\r | |
2668 | }\r | |
2669 | \r | |
2670 | break;\r | |
2671 | \r | |
2672 | case EFI_IFR_STRING_OP:\r | |
2673 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2674 | ASSERT (CurrentStatement != NULL);\r | |
2675 | //\r | |
2676 | // MinSize is the minimum number of characters that can be accepted for this opcode,\r | |
2677 | // MaxSize is the maximum number of characters that can be accepted for this opcode.\r | |
2678 | // The characters are stored as Unicode, so the storage width should multiply 2.\r | |
2679 | //\r | |
2680 | CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r | |
2681 | CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r | |
2682 | CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r | |
2683 | CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r | |
2684 | \r | |
2685 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r | |
2686 | CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r | |
2687 | //\r | |
2688 | // Get the UQI information\r | |
2689 | //\r | |
2690 | PrintQuestion(FormSet, CurrentForm, CurrentStatement, FALSE);\r | |
2691 | //\r | |
2692 | // Exchange the Guid and name information between VarList and Question List\r | |
2693 | //\r | |
2694 | Status = GetGuidNameByVariableId (FormSet, CurrentStatement, FormSet->StorageListHead);\r | |
2695 | //\r | |
2696 | // Remove the question which isn't stored by EfiVarStore or VarStore\r | |
2697 | //\r | |
2698 | if (EFI_ERROR (Status)) {\r | |
2699 | RemoveEntryList (&CurrentStatement->Link);\r | |
2700 | DestroyStatement (FormSet, CurrentStatement);\r | |
2701 | }\r | |
2702 | \r | |
2703 | break;\r | |
2704 | \r | |
2705 | case EFI_IFR_PASSWORD_OP:\r | |
2706 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2707 | ASSERT (CurrentStatement != NULL);\r | |
2708 | //\r | |
2709 | // MinSize is the minimum number of characters that can be accepted for this opcode,\r | |
2710 | // MaxSize is the maximum number of characters that can be accepted for this opcode.\r | |
2711 | // The characters are stored as Unicode, so the storage width should multiply 2.\r | |
2712 | //\r | |
2713 | CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r | |
2714 | CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r | |
2715 | CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r | |
2716 | \r | |
2717 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r | |
2718 | CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r | |
2719 | break;\r | |
2720 | \r | |
2721 | case EFI_IFR_DATE_OP:\r | |
2722 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2723 | ASSERT(CurrentStatement != NULL);\r | |
2724 | \r | |
2725 | CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r | |
2726 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r | |
2727 | \r | |
2728 | if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r | |
2729 | CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r | |
2730 | } else {\r | |
2731 | //\r | |
2732 | // Don't assign storage for RTC type of date/time\r | |
2733 | //\r | |
2734 | CurrentStatement->Storage = NULL;\r | |
2735 | CurrentStatement->StorageWidth = 0;\r | |
2736 | }\r | |
2737 | break;\r | |
2738 | \r | |
2739 | case EFI_IFR_TIME_OP:\r | |
2740 | CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r | |
2741 | ASSERT(CurrentStatement != NULL);\r | |
2742 | \r | |
2743 | CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r | |
2744 | CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r | |
2745 | \r | |
2746 | if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r | |
2747 | CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r | |
2748 | } else {\r | |
2749 | //\r | |
2750 | // Don't assign storage for RTC type of date/time\r | |
2751 | //\r | |
2752 | CurrentStatement->Storage = NULL;\r | |
2753 | CurrentStatement->StorageWidth = 0;\r | |
2754 | }\r | |
2755 | break;\r | |
2756 | \r | |
2757 | //\r | |
2758 | // Default\r | |
2759 | //\r | |
2760 | case EFI_IFR_DEFAULT_OP:\r | |
2761 | //\r | |
2762 | // EFI_IFR_DEFAULT appear in scope of a Question,\r | |
2763 | // It creates a default value for the current question.\r | |
2764 | // A Question may have more than one Default value which have different default types.\r | |
2765 | //\r | |
2766 | CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r | |
2767 | ASSERT (CurrentDefault != NULL);\r | |
2768 | CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r | |
2769 | \r | |
2770 | CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r | |
2771 | CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r | |
2772 | if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {\r | |
2773 | CurrentDefault->Value.BufferLen = (UINT16)(OpCodeLength - OFFSET_OF(EFI_IFR_DEFAULT, Value));\r | |
2774 | CurrentDefault->Value.Buffer = FceAllocateCopyPool(CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *)OpCodeData)->Value);\r | |
2775 | ASSERT(CurrentDefault->Value.Buffer != NULL);\r | |
2776 | } else {\r | |
2777 | CopyMem(&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *)OpCodeData)->Value, OpCodeLength - OFFSET_OF(EFI_IFR_DEFAULT, Value));\r | |
2778 | ExtendValueToU64(&CurrentDefault->Value);\r | |
2779 | }\r | |
2780 | \r | |
2781 | //\r | |
2782 | // Insert to Default Value list of current Question\r | |
2783 | //\r | |
2784 | InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r | |
2785 | \r | |
2786 | if (Scope != 0) {\r | |
2787 | InScopeDefault = TRUE;\r | |
2788 | }\r | |
2789 | break;\r | |
2790 | \r | |
2791 | //\r | |
2792 | // Option\r | |
2793 | //\r | |
2794 | case EFI_IFR_ONE_OF_OPTION_OP:\r | |
2795 | ASSERT (CurrentStatement != NULL);\r | |
2796 | if (CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP &&\r | |
2797 | ((((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {\r | |
2798 | //\r | |
2799 | // It's keep the default value for ordered list opcode.\r | |
2800 | //\r | |
2801 | CurrentDefault = AllocateZeroPool(sizeof (QUESTION_DEFAULT));\r | |
2802 | ASSERT(CurrentDefault != NULL);\r | |
2803 | CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r | |
2804 | \r | |
2805 | CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;\r | |
2806 | if ((((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r | |
2807 | CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r | |
2808 | } else {\r | |
2809 | CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r | |
2810 | }\r | |
2811 | \r | |
2812 | CurrentDefault->Value.BufferLen = (UINT16)(OpCodeLength - OFFSET_OF(EFI_IFR_ONE_OF_OPTION, Value));\r | |
2813 | CurrentDefault->Value.Buffer = FceAllocateCopyPool(CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Value);\r | |
2814 | ASSERT(CurrentDefault->Value.Buffer != NULL);\r | |
2815 | \r | |
2816 | //\r | |
2817 | // Insert to Default Value list of current Question\r | |
2818 | //\r | |
2819 | InsertTailList(&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r | |
2820 | break;\r | |
2821 | }\r | |
2822 | //\r | |
2823 | // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r | |
2824 | // It create a selection for use in current Question.\r | |
2825 | //\r | |
2826 | CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r | |
2827 | ASSERT (CurrentOption != NULL);\r | |
2828 | CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r | |
2829 | \r | |
2830 | CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r | |
2831 | CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r | |
2832 | CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r | |
2833 | CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r | |
2834 | ExtendValueToU64 (&CurrentOption->Value);\r | |
2835 | \r | |
2836 | if (InScopeOptionSuppress) {\r | |
2837 | CurrentOption->SuppressExpression = OptionSuppressExpression;\r | |
2838 | }\r | |
2839 | \r | |
2840 | //\r | |
2841 | // Insert to Option list of current Question\r | |
2842 | //\r | |
2843 | InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r | |
2844 | \r | |
2845 | //\r | |
2846 | // Now we know the Storage width of nested Ordered List\r | |
2847 | //\r | |
2848 | if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r | |
2849 | Width = 1;\r | |
2850 | switch (CurrentOption->Value.Type) {\r | |
2851 | case EFI_IFR_TYPE_NUM_SIZE_8:\r | |
2852 | Width = 1;\r | |
2853 | break;\r | |
2854 | \r | |
2855 | case EFI_IFR_TYPE_NUM_SIZE_16:\r | |
2856 | Width = 2;\r | |
2857 | break;\r | |
2858 | \r | |
2859 | case EFI_IFR_TYPE_NUM_SIZE_32:\r | |
2860 | Width = 4;\r | |
2861 | break;\r | |
2862 | \r | |
2863 | case EFI_IFR_TYPE_NUM_SIZE_64:\r | |
2864 | Width = 8;\r | |
2865 | break;\r | |
2866 | \r | |
2867 | default:\r | |
2868 | //\r | |
2869 | // Invalid type for Ordered List\r | |
2870 | //\r | |
2871 | break;\r | |
2872 | }\r | |
2873 | \r | |
2874 | CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r | |
2875 | CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r | |
2876 | CurrentStatement->ValueType = CurrentOption->Value.Type;\r | |
2877 | if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r | |
2878 | CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue;\r | |
2879 | CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth;\r | |
2880 | }\r | |
2881 | }\r | |
2882 | break;\r | |
2883 | \r | |
2884 | //\r | |
2885 | // Conditional\r | |
2886 | //\r | |
2887 | case EFI_IFR_NO_SUBMIT_IF_OP:\r | |
2888 | case EFI_IFR_INCONSISTENT_IF_OP:\r | |
2889 | //\r | |
2890 | // Create an Expression node\r | |
2891 | //\r | |
2892 | CurrentExpression = CreateExpression (CurrentForm);\r | |
2893 | CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r | |
2894 | \r | |
2895 | if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r | |
2896 | CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r | |
2897 | InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r | |
2898 | } else {\r | |
2899 | CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r | |
2900 | InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r | |
2901 | }\r | |
2902 | //\r | |
2903 | // Take a look at next OpCode to see whether current expression consists\r | |
2904 | // of single OpCode\r | |
2905 | //\r | |
2906 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
2907 | SingleOpCodeExpression = TRUE;\r | |
2908 | }\r | |
2909 | break;\r | |
2910 | \r | |
2911 | case EFI_IFR_WARNING_IF_OP:\r | |
2912 | //\r | |
2913 | // Create an Expression node\r | |
2914 | //\r | |
2915 | CurrentExpression = CreateExpression (CurrentForm);\r | |
2916 | CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));\r | |
2917 | CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;\r | |
2918 | CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;\r | |
2919 | InsertTailList (&CurrentStatement->WarningListHead, &CurrentExpression->Link);\r | |
2920 | \r | |
2921 | //\r | |
2922 | // Take a look at next OpCode to see whether current expression consists\r | |
2923 | // of single OpCode\r | |
2924 | //\r | |
2925 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
2926 | SingleOpCodeExpression = TRUE;\r | |
2927 | }\r | |
2928 | break;\r | |
2929 | \r | |
2930 | case EFI_IFR_SUPPRESS_IF_OP:\r | |
2931 | //\r | |
2932 | // Question and Option will appear in scope of this OpCode\r | |
2933 | //\r | |
2934 | CurrentExpression = CreateExpression (CurrentForm);\r | |
2935 | CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r | |
2936 | \r | |
2937 | if (CurrentForm == NULL) {\r | |
2938 | InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r | |
2939 | } else {\r | |
2940 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
2941 | }\r | |
2942 | \r | |
2943 | if (SuppressForOption) {\r | |
2944 | InScopeOptionSuppress = TRUE;\r | |
2945 | OptionSuppressExpression = CurrentExpression;\r | |
2946 | } else if (SuppressForQuestion) {\r | |
2947 | mInScopeSuppress = TRUE;\r | |
2948 | mSuppressExpression = CurrentExpression;\r | |
2949 | } else {\r | |
2950 | InScopeFormSuppress = TRUE;\r | |
2951 | FormSuppressExpression = CurrentExpression;\r | |
2952 | }\r | |
2953 | //\r | |
2954 | // Take a look at next OpCode to see whether current expression consists\r | |
2955 | // of single OpCode\r | |
2956 | //\r | |
2957 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
2958 | SingleOpCodeExpression = TRUE;\r | |
2959 | }\r | |
2960 | break;\r | |
2961 | \r | |
2962 | case EFI_IFR_GRAY_OUT_IF_OP:\r | |
2963 | //\r | |
2964 | // Questions will appear in scope of this OpCode\r | |
2965 | //\r | |
2966 | CurrentExpression = CreateExpression (CurrentForm);\r | |
2967 | CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r | |
2968 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
2969 | \r | |
2970 | mInScopeGrayOut = TRUE;\r | |
2971 | mGrayOutExpression = CurrentExpression;\r | |
2972 | \r | |
2973 | //\r | |
2974 | // Take a look at next OpCode to see whether current expression consists\r | |
2975 | // of single OpCode\r | |
2976 | //\r | |
2977 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
2978 | SingleOpCodeExpression = TRUE;\r | |
2979 | }\r | |
2980 | break;\r | |
2981 | \r | |
2982 | case EFI_IFR_DISABLE_IF_OP:\r | |
2983 | //\r | |
2984 | // The DisableIf expression should only rely on constant, so it could be\r | |
2985 | // evaluated at initialization and it will not be queued\r | |
2986 | //\r | |
2987 | CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r | |
2988 | ASSERT (CurrentExpression != NULL);\r | |
2989 | CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r | |
2990 | CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r | |
2991 | InitializeListHead (&CurrentExpression->OpCodeListHead);\r | |
2992 | \r | |
2993 | if (CurrentForm != NULL) {\r | |
2994 | //\r | |
2995 | // This is DisableIf for Question, enqueue it to Form expression list\r | |
2996 | //\r | |
2997 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
2998 | }\r | |
2999 | \r | |
3000 | mDisableExpression = CurrentExpression;\r | |
3001 | mInScopeDisable = TRUE;\r | |
3002 | OpCodeDisabled = FALSE;\r | |
3003 | \r | |
3004 | //\r | |
3005 | // Take a look at next OpCode to see whether current expression consists\r | |
3006 | // of single OpCode\r | |
3007 | //\r | |
3008 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
3009 | SingleOpCodeExpression = TRUE;\r | |
3010 | }\r | |
3011 | break;\r | |
3012 | \r | |
3013 | //\r | |
3014 | // Expression\r | |
3015 | //\r | |
3016 | case EFI_IFR_VALUE_OP:\r | |
3017 | CurrentExpression = CreateExpression (CurrentForm);\r | |
3018 | CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r | |
3019 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
3020 | \r | |
3021 | if (InScopeDefault) {\r | |
3022 | //\r | |
3023 | // Used for default (EFI_IFR_DEFAULT)\r | |
3024 | //\r | |
3025 | CurrentDefault->ValueExpression = CurrentExpression;\r | |
3026 | } else {\r | |
3027 | //\r | |
3028 | // If used for a question, then the question will be read-only\r | |
3029 | //\r | |
3030 | //\r | |
3031 | // Make sure CurrentStatement is not NULL.\r | |
3032 | // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r | |
3033 | // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r | |
3034 | //\r | |
3035 | ASSERT (CurrentStatement != NULL);\r | |
3036 | CurrentStatement->ValueExpression = CurrentExpression;\r | |
3037 | }\r | |
3038 | \r | |
3039 | //\r | |
3040 | // Take a look at next OpCode to see whether current expression consists\r | |
3041 | // of single OpCode\r | |
3042 | //\r | |
3043 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
3044 | SingleOpCodeExpression = TRUE;\r | |
3045 | }\r | |
3046 | break;\r | |
3047 | \r | |
3048 | case EFI_IFR_RULE_OP:\r | |
3049 | CurrentExpression = CreateExpression (CurrentForm);\r | |
3050 | CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r | |
3051 | \r | |
3052 | CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r | |
3053 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
3054 | \r | |
3055 | //\r | |
3056 | // Take a look at next OpCode to see whether current expression consists\r | |
3057 | // of single OpCode\r | |
3058 | //\r | |
3059 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
3060 | SingleOpCodeExpression = TRUE;\r | |
3061 | }\r | |
3062 | break;\r | |
3063 | \r | |
3064 | case EFI_IFR_READ_OP:\r | |
3065 | CurrentExpression = CreateExpression (CurrentForm);\r | |
3066 | CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r | |
3067 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
3068 | \r | |
3069 | //\r | |
3070 | // Make sure CurrentStatement is not NULL.\r | |
3071 | // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r | |
3072 | // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r | |
3073 | //\r | |
3074 | ASSERT (CurrentStatement != NULL);\r | |
3075 | CurrentStatement->ReadExpression = CurrentExpression;\r | |
3076 | \r | |
3077 | //\r | |
3078 | // Take a look at next OpCode to see whether current expression consists\r | |
3079 | // of single OpCode\r | |
3080 | //\r | |
3081 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
3082 | SingleOpCodeExpression = TRUE;\r | |
3083 | }\r | |
3084 | break;\r | |
3085 | \r | |
3086 | case EFI_IFR_WRITE_OP:\r | |
3087 | CurrentExpression = CreateExpression (CurrentForm);\r | |
3088 | CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r | |
3089 | InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r | |
3090 | \r | |
3091 | //\r | |
3092 | // Make sure CurrentStatement is not NULL.\r | |
3093 | // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r | |
3094 | // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r | |
3095 | //\r | |
3096 | ASSERT (CurrentStatement != NULL);\r | |
3097 | CurrentStatement->WriteExpression = CurrentExpression;\r | |
3098 | \r | |
3099 | //\r | |
3100 | // Take a look at next OpCode to see whether current expression consists\r | |
3101 | // of single OpCode\r | |
3102 | //\r | |
3103 | if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r | |
3104 | SingleOpCodeExpression = TRUE;\r | |
3105 | }\r | |
3106 | break;\r | |
3107 | \r | |
3108 | //\r | |
3109 | // Image\r | |
3110 | //\r | |
3111 | case EFI_IFR_IMAGE_OP:\r | |
3112 | //\r | |
3113 | // Get ScopeOpcode from top of stack\r | |
3114 | //\r | |
3115 | PopScope (&ScopeOpCode);\r | |
3116 | PushScope (ScopeOpCode);\r | |
3117 | \r | |
3118 | switch (ScopeOpCode) {\r | |
3119 | case EFI_IFR_FORM_SET_OP:\r | |
3120 | break;\r | |
3121 | \r | |
3122 | case EFI_IFR_FORM_OP:\r | |
3123 | case EFI_IFR_FORM_MAP_OP:\r | |
3124 | ASSERT (CurrentForm != NULL);\r | |
3125 | break;\r | |
3126 | \r | |
3127 | case EFI_IFR_ONE_OF_OPTION_OP:\r | |
3128 | break;\r | |
3129 | \r | |
3130 | default:\r | |
3131 | //\r | |
3132 | // Make sure CurrentStatement is not NULL.\r | |
3133 | // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r | |
3134 | // file is wrongly generated by tools such as VFR Compiler.\r | |
3135 | //\r | |
3136 | ASSERT (CurrentStatement != NULL);\r | |
3137 | break;\r | |
3138 | }\r | |
3139 | break;\r | |
3140 | \r | |
3141 | //\r | |
3142 | // Refresh\r | |
3143 | //\r | |
3144 | case EFI_IFR_REFRESH_OP:\r | |
3145 | break;\r | |
3146 | \r | |
3147 | //\r | |
3148 | // Refresh guid.\r | |
3149 | //\r | |
3150 | case EFI_IFR_REFRESH_ID_OP:\r | |
3151 | break;\r | |
3152 | \r | |
3153 | //\r | |
3154 | // Modal tag\r | |
3155 | //\r | |
3156 | case EFI_IFR_MODAL_TAG_OP:\r | |
3157 | break;\r | |
3158 | \r | |
3159 | //\r | |
3160 | // Vendor specific\r | |
3161 | //\r | |
3162 | case EFI_IFR_GUID_OP:\r | |
3163 | if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarGuid)==0) {\r | |
3164 | Scope = 0;\r | |
3165 | BitFieldStorage = TRUE;\r | |
3166 | }\r | |
3167 | break;\r | |
3168 | \r | |
3169 | //\r | |
3170 | // Scope End\r | |
3171 | //\r | |
3172 | case EFI_IFR_END_OP:\r | |
3173 | BitFieldStorage = FALSE;\r | |
3174 | Status = PopScope (&ScopeOpCode);\r | |
3175 | if (EFI_ERROR (Status)) {\r | |
3176 | ResetScopeStack ();\r | |
3177 | return Status;\r | |
3178 | }\r | |
3179 | \r | |
3180 | switch (ScopeOpCode) {\r | |
3181 | case EFI_IFR_FORM_SET_OP:\r | |
3182 | //\r | |
3183 | // End of FormSet, update FormSet IFR binary length\r | |
3184 | // to stop parsing substantial OpCodes\r | |
3185 | //\r | |
3186 | FormSet->IfrBinaryLength = OpCodeOffset;\r | |
3187 | break;\r | |
3188 | \r | |
3189 | case EFI_IFR_FORM_OP:\r | |
3190 | case EFI_IFR_FORM_MAP_OP:\r | |
3191 | //\r | |
3192 | // End of Form\r | |
3193 | //\r | |
3194 | CurrentForm = NULL;\r | |
3195 | SuppressForQuestion = FALSE;\r | |
3196 | break;\r | |
3197 | \r | |
3198 | case EFI_IFR_ONE_OF_OPTION_OP:\r | |
3199 | //\r | |
3200 | // End of Option\r | |
3201 | //\r | |
3202 | CurrentOption = NULL;\r | |
3203 | break;\r | |
3204 | \r | |
3205 | case EFI_IFR_SUBTITLE_OP:\r | |
3206 | mInScopeSubtitle = FALSE;\r | |
3207 | break;\r | |
3208 | \r | |
3209 | case EFI_IFR_NO_SUBMIT_IF_OP:\r | |
3210 | case EFI_IFR_INCONSISTENT_IF_OP:\r | |
3211 | case EFI_IFR_WARNING_IF_OP:\r | |
3212 | //\r | |
3213 | // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r | |
3214 | //\r | |
3215 | break;\r | |
3216 | \r | |
3217 | case EFI_IFR_SUPPRESS_IF_OP:\r | |
3218 | if (SuppressForOption) {\r | |
3219 | InScopeOptionSuppress = FALSE;\r | |
3220 | } else if (SuppressForQuestion) {\r | |
3221 | mInScopeSuppress = FALSE;\r | |
3222 | } else {\r | |
3223 | InScopeFormSuppress = FALSE;\r | |
3224 | }\r | |
3225 | break;\r | |
3226 | \r | |
3227 | case EFI_IFR_GRAY_OUT_IF_OP:\r | |
3228 | mInScopeGrayOut = FALSE;\r | |
3229 | break;\r | |
3230 | \r | |
3231 | case EFI_IFR_DISABLE_IF_OP:\r | |
3232 | mInScopeDisable = FALSE;\r | |
3233 | OpCodeDisabled = FALSE;\r | |
3234 | break;\r | |
3235 | \r | |
3236 | case EFI_IFR_ONE_OF_OP:\r | |
3237 | case EFI_IFR_ORDERED_LIST_OP:\r | |
3238 | SuppressForOption = FALSE;\r | |
3239 | break;\r | |
3240 | \r | |
3241 | case EFI_IFR_DEFAULT_OP:\r | |
3242 | InScopeDefault = FALSE;\r | |
3243 | break;\r | |
3244 | \r | |
3245 | case EFI_IFR_MAP_OP:\r | |
3246 | //\r | |
3247 | // Get current Map Expression List.\r | |
3248 | //\r | |
3249 | Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r | |
3250 | if (Status == EFI_ACCESS_DENIED) {\r | |
3251 | MapExpressionList = NULL;\r | |
3252 | }\r | |
3253 | //\r | |
3254 | // Get current expression.\r | |
3255 | //\r | |
3256 | Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r | |
3257 | ASSERT (!EFI_ERROR (Status));\r | |
3258 | ASSERT (MapScopeDepth > 0);\r | |
3259 | MapScopeDepth --;\r | |
3260 | break;\r | |
3261 | \r | |
3262 | default:\r | |
3263 | if (IsExpressionOpCode (ScopeOpCode)) {\r | |
3264 | if (mInScopeDisable && (CurrentForm == NULL)) {\r | |
3265 | //\r | |
3266 | // This is DisableIf expression for Form, it should be a constant expression\r | |
3267 | //\r | |
3268 | ASSERT (CurrentExpression != NULL);\r | |
3269 | ConstantFlag = TRUE;\r | |
3270 | Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression, &ConstantFlag);\r | |
3271 | if (EFI_ERROR (Status)) {\r | |
3272 | return Status;\r | |
3273 | }\r | |
3274 | if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r | |
3275 | return EFI_INVALID_PARAMETER;\r | |
3276 | }\r | |
3277 | if (!ConstantFlag) {\r | |
3278 | StringPrint ("WARNING. The DisableIf expression for Form should be a constant expression.\n");\r | |
3279 | }\r | |
3280 | OpCodeDisabled = CurrentExpression->Result.Value.b;\r | |
3281 | //\r | |
3282 | // DisableIf Expression is only used once and not queued, free it\r | |
3283 | //\r | |
3284 | DestroyExpression (CurrentExpression);\r | |
3285 | }\r | |
3286 | \r | |
3287 | //\r | |
3288 | // End of current Expression\r | |
3289 | //\r | |
3290 | CurrentExpression = NULL;\r | |
3291 | }\r | |
3292 | break;\r | |
3293 | }\r | |
3294 | break;\r | |
3295 | \r | |
3296 | default:\r | |
3297 | break;\r | |
3298 | }\r | |
3299 | }\r | |
3300 | \r | |
3301 | return EFI_SUCCESS;\r | |
3302 | }\r | |
3303 | \r | |
3304 | /**\r | |
3305 | Search an Option of a Question by its value.\r | |
3306 | \r | |
3307 | @param Question The Question\r | |
3308 | @param OptionValue Value for Option to be searched.\r | |
3309 | \r | |
3310 | @retval Pointer Pointer to the found Option.\r | |
3311 | @retval NULL Option not found.\r | |
3312 | \r | |
3313 | **/\r | |
3314 | QUESTION_OPTION *\r | |
3315 | ValueToOption (\r | |
3316 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
3317 | IN FORM_BROWSER_STATEMENT *Question,\r | |
3318 | IN EFI_HII_VALUE *OptionValue\r | |
3319 | )\r | |
3320 | {\r | |
3321 | LIST_ENTRY *Link;\r | |
3322 | QUESTION_OPTION *Option;\r | |
3323 | \r | |
3324 | Link = GetFirstNode (&Question->OptionListHead);\r | |
3325 | while (!IsNull (&Question->OptionListHead, Link)) {\r | |
3326 | Option = QUESTION_OPTION_FROM_LINK (Link);\r | |
3327 | \r | |
3328 | if (CompareHiiValue (&Option->Value, OptionValue, FormSet) == 0) {\r | |
3329 | return Option;\r | |
3330 | }\r | |
3331 | \r | |
3332 | Link = GetNextNode (&Question->OptionListHead, Link);\r | |
3333 | }\r | |
3334 | \r | |
3335 | return NULL;\r | |
3336 | }\r | |
3337 | \r | |
3338 | /**\r | |
3339 | Set value of a data element in an Array by its Index.\r | |
3340 | \r | |
3341 | @param Array The data array.\r | |
3342 | @param Type Type of the data in this array.\r | |
3343 | @param Index Zero based index for data in this array.\r | |
3344 | @param Value The value to be set.\r | |
3345 | \r | |
3346 | **/\r | |
3347 | VOID\r | |
3348 | SetArrayData (\r | |
3349 | IN VOID *Array,\r | |
3350 | IN UINT8 Type,\r | |
3351 | IN UINTN Index,\r | |
3352 | IN UINT64 Value\r | |
3353 | )\r | |
3354 | {\r | |
3355 | \r | |
3356 | ASSERT (Array != NULL);\r | |
3357 | \r | |
3358 | switch (Type) {\r | |
3359 | case EFI_IFR_TYPE_NUM_SIZE_8:\r | |
3360 | *(((UINT8 *) Array) + Index) = (UINT8) Value;\r | |
3361 | break;\r | |
3362 | \r | |
3363 | case EFI_IFR_TYPE_NUM_SIZE_16:\r | |
3364 | *(((UINT16 *) Array) + Index) = (UINT16) Value;\r | |
3365 | break;\r | |
3366 | \r | |
3367 | case EFI_IFR_TYPE_NUM_SIZE_32:\r | |
3368 | *(((UINT32 *) Array) + Index) = (UINT32) Value;\r | |
3369 | break;\r | |
3370 | \r | |
3371 | case EFI_IFR_TYPE_NUM_SIZE_64:\r | |
3372 | *(((UINT64 *) Array) + Index) = (UINT64) Value;\r | |
3373 | break;\r | |
3374 | \r | |
3375 | default:\r | |
3376 | break;\r | |
3377 | }\r | |
3378 | }\r | |
3379 | \r | |
3380 | /**\r | |
3381 | Reset Question of five kinds to its default value.\r | |
3382 | \r | |
3383 | @param FormSet The form set.\r | |
3384 | @param Form The form.\r | |
3385 | @param Question The question.\r | |
3386 | @param DefaultId The default Id.\r | |
3387 | @param DefaultId The platform Id.\r | |
3388 | \r | |
3389 | @retval EFI_SUCCESS Question is reset to default value.\r | |
3390 | \r | |
3391 | **/\r | |
3392 | EFI_STATUS\r | |
3393 | GetQuestionDefault (\r | |
3394 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
3395 | IN FORM_BROWSER_FORM *Form,\r | |
3396 | IN FORM_BROWSER_STATEMENT *Question,\r | |
3397 | IN UINT16 DefaultId,\r | |
3398 | IN UINT64 PlatformId\r | |
3399 | )\r | |
3400 | {\r | |
3401 | EFI_STATUS Status;\r | |
3402 | LIST_ENTRY *Link;\r | |
3403 | QUESTION_DEFAULT *Default;\r | |
3404 | QUESTION_OPTION *Option;\r | |
3405 | EFI_HII_VALUE *HiiValue;\r | |
3406 | UINT8 Index;\r | |
3407 | FORMSET_STORAGE *VarList;\r | |
3408 | UINT8 *VarBuffer;\r | |
3409 | BOOLEAN ConstantFlag;\r | |
3410 | UINT16 OriginalDefaultId;\r | |
3411 | FORMSET_DEFAULTSTORE *DefaultStore;\r | |
3412 | LIST_ENTRY *DefaultLink;\r | |
3413 | CHAR16 *VarDefaultName;\r | |
3414 | \r | |
3415 | VarDefaultName = NULL;\r | |
3416 | Status = EFI_SUCCESS;\r | |
3417 | ConstantFlag = TRUE;\r | |
3418 | OriginalDefaultId = DefaultId;\r | |
3419 | DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r | |
3420 | \r | |
3421 | //\r | |
3422 | // Statement don't have storage, skip them\r | |
3423 | //\r | |
3424 | if (Question->QuestionId == 0) {\r | |
3425 | return EFI_NOT_FOUND;\r | |
3426 | }\r | |
3427 | //\r | |
3428 | // Return if no any kinds of\r | |
3429 | //\r | |
3430 | if ((Question->Operand != EFI_IFR_CHECKBOX_OP)\r | |
3431 | && (Question->Operand != EFI_IFR_ONE_OF_OP)\r | |
3432 | && (Question->Operand != EFI_IFR_ORDERED_LIST_OP)\r | |
3433 | && (Question->Operand != EFI_IFR_NUMERIC_OP)\r | |
3434 | && (Question->Operand != EFI_IFR_STRING_OP)\r | |
3435 | ) {\r | |
3436 | return EFI_ABORTED;\r | |
3437 | }\r | |
3438 | //\r | |
3439 | // Search the variable for this question (Compatible with the old EfiVarStore before UEFI2.31)\r | |
3440 | //\r | |
3441 | \r | |
3442 | //\r | |
3443 | //VarStoreInfoDepending on the type of variable store selected,\r | |
3444 | //this contains either a 16-bit Buffer Storage offset (VarOffset)\r | |
3445 | //or a Name/Value or EFI Variable name (VarName).\r | |
3446 | //\r | |
3447 | Status = SearchVarStorage (\r | |
3448 | Question,\r | |
3449 | NULL,\r | |
3450 | Question->VarStoreInfo.VarOffset,\r | |
3451 | FormSet->StorageListHead,\r | |
3452 | (CHAR8 **)&VarBuffer,\r | |
3453 | &VarList\r | |
3454 | );\r | |
3455 | if (EFI_ERROR(Status)) {\r | |
3456 | return Status;\r | |
3457 | }\r | |
3458 | //\r | |
3459 | // There are three ways to specify default value for a Question:\r | |
3460 | // 1, use nested EFI_IFR_DEFAULT\r | |
3461 | // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r | |
3462 | // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r | |
3463 | //\r | |
3464 | ReGetDefault:\r | |
3465 | HiiValue = &Question->HiiValue;\r | |
3466 | //\r | |
3467 | // EFI_IFR_DEFAULT has highest priority\r | |
3468 | //\r | |
3469 | if (!IsListEmpty (&Question->DefaultListHead)) {\r | |
3470 | Link = GetFirstNode (&Question->DefaultListHead);\r | |
3471 | while (!IsNull (&Question->DefaultListHead, Link)) {\r | |
3472 | Default = QUESTION_DEFAULT_FROM_LINK (Link);\r | |
3473 | \r | |
3474 | if (Default->DefaultId == DefaultId) {\r | |
3475 | if (Default->ValueExpression != NULL) {\r | |
3476 | //\r | |
3477 | // Default is provided by an Expression, evaluate it\r | |
3478 | //\r | |
3479 | Status = EvaluateExpression (FormSet, Form, Default->ValueExpression, &ConstantFlag);\r | |
3480 | if (EFI_ERROR (Status)) {\r | |
3481 | return Status;\r | |
3482 | }\r | |
3483 | \r | |
3484 | if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r | |
3485 | if (Question->StorageWidth > Default->ValueExpression->Result.BufferLen) {\r | |
3486 | CopyMem(Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen);\r | |
3487 | Question->HiiValue.BufferLen = Default->ValueExpression->Result.BufferLen;\r | |
3488 | } else {\r | |
3489 | CopyMem(Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Question->StorageWidth);\r | |
3490 | Question->HiiValue.BufferLen = Question->StorageWidth;\r | |
3491 | }\r | |
3492 | FreePool(Default->ValueExpression->Result.Buffer);\r | |
3493 | }\r | |
3494 | HiiValue->Type = Default->ValueExpression->Result.Type;\r | |
3495 | CopyMem(&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));\r | |
3496 | } else {\r | |
3497 | //\r | |
3498 | // Default value is embedded in EFI_IFR_DEFAULT\r | |
3499 | //\r | |
3500 | if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {\r | |
3501 | CopyMem(HiiValue->Buffer, Default->Value.Buffer, Default->Value.BufferLen);\r | |
3502 | } else {\r | |
3503 | CopyMem(HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r | |
3504 | }\r | |
3505 | }\r | |
3506 | if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {\r | |
3507 | CopyMem(VarBuffer, HiiValue->Buffer, HiiValue->BufferLen);\r | |
3508 | } else if (HiiValue->Type == EFI_IFR_TYPE_STRING){\r | |
3509 | Status = FindDefaultName (\r | |
3510 | &(FormSet->EnUsStringList),\r | |
3511 | FormSet->UnicodeBinary,\r | |
3512 | HiiValue->Value.string,\r | |
3513 | EN_US,\r | |
3514 | &VarDefaultName\r | |
3515 | );\r | |
3516 | if (VarDefaultName == NULL) {\r | |
3517 | return EFI_NOT_FOUND;\r | |
3518 | }\r | |
3519 | if (Question->StorageWidth > FceStrSize(VarDefaultName)) {\r | |
3520 | ZeroMem (VarBuffer, Question->StorageWidth);\r | |
3521 | CopyMem (VarBuffer, VarDefaultName, FceStrSize(VarDefaultName));\r | |
3522 | } else {\r | |
3523 | CopyMem (VarBuffer, VarDefaultName, Question->StorageWidth);\r | |
3524 | }\r | |
3525 | } else {\r | |
3526 | if (Question->QuestionReferToBitField) {\r | |
3527 | SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r | |
3528 | } else {\r | |
3529 | CopyMem(VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r | |
3530 | }\r | |
3531 | }\r | |
3532 | return EFI_SUCCESS;\r | |
3533 | }\r | |
3534 | if (Default->DefaultId == DefaultId) {\r | |
3535 | return EFI_SUCCESS;\r | |
3536 | }\r | |
3537 | Link = GetNextNode (&Question->DefaultListHead, Link);\r | |
3538 | }\r | |
3539 | }\r | |
3540 | \r | |
3541 | if (HiiValue->Buffer == NULL) {\r | |
3542 | ZeroMem (HiiValue, sizeof (EFI_HII_VALUE));\r | |
3543 | }\r | |
3544 | \r | |
3545 | //\r | |
3546 | // EFI_ONE_OF_OPTION\r | |
3547 | //\r | |
3548 | if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r | |
3549 | if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r | |
3550 | //\r | |
3551 | // OneOfOption could only provide Standard and Manufacturing default\r | |
3552 | //\r | |
3553 | Link = GetFirstNode (&Question->OptionListHead);\r | |
3554 | while (!IsNull (&Question->OptionListHead, Link)) {\r | |
3555 | Option = QUESTION_OPTION_FROM_LINK (Link);\r | |
3556 | \r | |
3557 | if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||\r | |
3558 | ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))\r | |
3559 | ) {\r | |
3560 | CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r | |
3561 | if (Question->QuestionReferToBitField) {\r | |
3562 | SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r | |
3563 | } else {\r | |
3564 | CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r | |
3565 | }\r | |
3566 | return EFI_SUCCESS;\r | |
3567 | }\r | |
3568 | \r | |
3569 | Link = GetNextNode (&Question->OptionListHead, Link);\r | |
3570 | }\r | |
3571 | }\r | |
3572 | }\r | |
3573 | \r | |
3574 | //\r | |
3575 | // EFI_IFR_CHECKBOX - lowest priority\r | |
3576 | //\r | |
3577 | if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r | |
3578 | if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r | |
3579 | //\r | |
3580 | // Checkbox could only provide Standard and Manufacturing default\r | |
3581 | //\r | |
3582 | if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||\r | |
3583 | ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r | |
3584 | ) {\r | |
3585 | HiiValue->Value.b = TRUE;\r | |
3586 | if (Question->QuestionReferToBitField) {\r | |
3587 | SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r | |
3588 | } else {\r | |
3589 | CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r | |
3590 | }\r | |
3591 | return EFI_SUCCESS;\r | |
3592 | }\r | |
3593 | }\r | |
3594 | }\r | |
3595 | \r | |
3596 | //\r | |
3597 | // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.\r | |
3598 | // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.\r | |
3599 | // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.\r | |
3600 | //\r | |
3601 | while (!IsNull(&FormSet->DefaultStoreListHead, DefaultLink)) {\r | |
3602 | DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r | |
3603 | DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead,DefaultLink);\r | |
3604 | DefaultId = DefaultStore->DefaultId;\r | |
3605 | if (DefaultId == OriginalDefaultId) {\r | |
3606 | continue;\r | |
3607 | }\r | |
3608 | goto ReGetDefault;\r | |
3609 | }\r | |
3610 | \r | |
3611 | //\r | |
3612 | // For Questions without default\r | |
3613 | //\r | |
3614 | Status = EFI_NOT_FOUND;\r | |
3615 | switch (Question->Operand) {\r | |
3616 | case EFI_IFR_CHECKBOX_OP:\r | |
3617 | HiiValue->Value.b = FALSE;\r | |
3618 | if (Question->QuestionReferToBitField) {\r | |
3619 | SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r | |
3620 | } else {\r | |
3621 | CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r | |
3622 | }\r | |
3623 | break;\r | |
3624 | \r | |
3625 | case EFI_IFR_NUMERIC_OP:\r | |
3626 | //\r | |
3627 | // Take minimum value as numeric default value\r | |
3628 | //\r | |
3629 | if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {\r | |
3630 | HiiValue->Value.u64 = Question->Minimum;\r | |
3631 | if (Question->QuestionReferToBitField) {\r | |
3632 | SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r | |
3633 | } else {\r | |
3634 | CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r | |
3635 | }\r | |
3636 | return EFI_SUCCESS;\r | |
3637 | }\r | |
3638 | break;\r | |
3639 | \r | |
3640 | case EFI_IFR_ONE_OF_OP:\r | |
3641 | //\r | |
3642 | // Take first oneof option as oneof's default value\r | |
3643 | //\r | |
3644 | if (ValueToOption (FormSet, Question, HiiValue) == NULL) {\r | |
3645 | Link = GetFirstNode (&Question->OptionListHead);\r | |
3646 | if (!IsNull (&Question->OptionListHead, Link)) {\r | |
3647 | Option = QUESTION_OPTION_FROM_LINK (Link);\r | |
3648 | CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r | |
3649 | if (Question->QuestionReferToBitField) {\r | |
3650 | SetBitsQuestionValue(Question, VarBuffer, HiiValue->Value.u32);\r | |
3651 | } else {\r | |
3652 | CopyMem (VarBuffer, &HiiValue->Value.u64, Question->StorageWidth);\r | |
3653 | }\r | |
3654 | return EFI_SUCCESS;\r | |
3655 | }\r | |
3656 | }\r | |
3657 | break;\r | |
3658 | \r | |
3659 | case EFI_IFR_ORDERED_LIST_OP:\r | |
3660 | //\r | |
3661 | // Take option sequence in IFR as ordered list's default value\r | |
3662 | //\r | |
3663 | Index = 0;\r | |
3664 | Link = GetFirstNode (&Question->OptionListHead);\r | |
3665 | while (!IsNull (&Question->OptionListHead, Link)) {\r | |
3666 | Option = QUESTION_OPTION_FROM_LINK (Link);\r | |
3667 | \r | |
3668 | SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);\r | |
3669 | SetArrayData (VarBuffer, Question->ValueType, Index, Option->Value.Value.u64);\r | |
3670 | \r | |
3671 | Index++;\r | |
3672 | if (Index >= Question->MaxContainers) {\r | |
3673 | break;\r | |
3674 | }\r | |
3675 | \r | |
3676 | Link = GetNextNode (&Question->OptionListHead, Link);\r | |
3677 | }\r | |
3678 | break;\r | |
3679 | \r | |
3680 | default:\r | |
3681 | break;\r | |
3682 | }\r | |
3683 | \r | |
3684 | return EFI_SUCCESS;\r | |
3685 | }\r | |
3686 | \r | |
3687 | /**\r | |
3688 | Set the value to the variable of platformId question.\r | |
3689 | \r | |
3690 | @param PlatformId The form set.\r | |
3691 | \r | |
3692 | @retval EFI_SUCCESS Set successfully.\r | |
3693 | \r | |
3694 | **/\r | |
3695 | EFI_STATUS\r | |
3696 | AssignThePlatformId (\r | |
3697 | IN UINT64 PlatformId\r | |
3698 | )\r | |
3699 | {\r | |
3700 | EFI_STATUS Status;\r | |
3701 | FORMSET_STORAGE *VarList;\r | |
3702 | UINT8 *VarBuffer;\r | |
3703 | \r | |
3704 | Status = EFI_SUCCESS;\r | |
3705 | VarBuffer = NULL;\r | |
3706 | //\r | |
3707 | // Set the Storage\r | |
3708 | //\r | |
3709 | Status = SearchVarStorage (\r | |
3710 | &mMultiPlatformParam.PlatformIdQuestion,\r | |
3711 | NULL,\r | |
3712 | mMultiPlatformParam.PlatformIdQuestion.VarStoreInfo.VarOffset,\r | |
3713 | &mVarListEntry,\r | |
3714 | (CHAR8 **)&VarBuffer,\r | |
3715 | &VarList\r | |
3716 | );\r | |
3717 | if (EFI_ERROR(Status)) {\r | |
3718 | return Status;\r | |
3719 | }\r | |
3720 | CopyMem (VarBuffer, &PlatformId, mMultiPlatformParam.PlatformIdWidth);\r | |
3721 | //\r | |
3722 | // Set the HIIvalue of this questions\r | |
3723 | //\r | |
3724 | CopyMem (&mMultiPlatformParam.Question->HiiValue.Value.u64, &PlatformId, mMultiPlatformParam.PlatformIdWidth);\r | |
3725 | \r | |
3726 | switch (mMultiPlatformParam.PlatformIdWidth) {\r | |
3727 | case sizeof (UINT8):\r | |
3728 | mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r | |
3729 | break;\r | |
3730 | \r | |
3731 | case sizeof (UINT16):\r | |
3732 | mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r | |
3733 | break;\r | |
3734 | \r | |
3735 | case sizeof (UINT32):\r | |
3736 | mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_32;\r | |
3737 | break;\r | |
3738 | \r | |
3739 | case sizeof (UINT64):\r | |
3740 | mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r | |
3741 | break;\r | |
3742 | \r | |
3743 | default:\r | |
3744 | mMultiPlatformParam.Question->HiiValue.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r | |
3745 | }\r | |
3746 | return EFI_SUCCESS;\r | |
3747 | }\r | |
3748 | /**\r | |
3749 | Reset Questions to their default value in a Form, Formset or System.\r | |
3750 | \r | |
3751 | @param FormSet FormSet data structure.\r | |
3752 | @param Form Form data structure.\r | |
3753 | @param DefaultId The default Id\r | |
3754 | @param PlatformId The platform Id\r | |
3755 | @param SettingScope Setting Scope for Default action.\r | |
3756 | \r | |
3757 | @retval EFI_SUCCESS The function completed successfully.\r | |
3758 | @retval EFI_UNSUPPORTED Unsupport SettingScope.\r | |
3759 | \r | |
3760 | **/\r | |
3761 | EFI_STATUS\r | |
3762 | ExtractDefault (\r | |
3763 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
3764 | IN FORM_BROWSER_FORM *Form,\r | |
3765 | IN UINT16 DefaultId,\r | |
3766 | IN UINT64 PlatformId,\r | |
3767 | IN BROWSER_SETTING_SCOPE SettingScope\r | |
3768 | )\r | |
3769 | {\r | |
3770 | EFI_STATUS Status;\r | |
3771 | LIST_ENTRY *FormLink;\r | |
3772 | LIST_ENTRY *Link;\r | |
3773 | LIST_ENTRY *FormSetEntryListHead;\r | |
3774 | FORM_BROWSER_STATEMENT *Question;\r | |
3775 | //\r | |
3776 | // Check the supported setting level.\r | |
3777 | //\r | |
3778 | if (SettingScope >= MaxLevel) {\r | |
3779 | return EFI_UNSUPPORTED;\r | |
3780 | }\r | |
3781 | \r | |
3782 | if (SettingScope == FormLevel) {\r | |
3783 | //\r | |
3784 | // Extract Form default\r | |
3785 | //\r | |
3786 | Link = GetFirstNode (&Form->StatementListHead);\r | |
3787 | while (!IsNull (&Form->StatementListHead, Link)) {\r | |
3788 | Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r | |
3789 | Link = GetNextNode (&Form->StatementListHead, Link);\r | |
3790 | //\r | |
3791 | // Re-set the platformId before calcuate the platformId of every question to avoid over-written.\r | |
3792 | //\r | |
3793 | if (mMultiPlatformParam.MultiPlatformOrNot) {\r | |
3794 | Status = AssignThePlatformId (PlatformId);\r | |
3795 | if (EFI_ERROR (Status)) {\r | |
3796 | StringPrint ("Error. Failed to assign the platformId.\n");\r | |
3797 | return Status;\r | |
3798 | }\r | |
3799 | }\r | |
3800 | //\r | |
3801 | // Reset Question to its default value, and store the default to variable\r | |
3802 | //\r | |
3803 | Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, PlatformId);\r | |
3804 | if (EFI_ERROR (Status)) {\r | |
3805 | continue;\r | |
3806 | }\r | |
3807 | }\r | |
3808 | } else if (SettingScope == FormSetLevel) {\r | |
3809 | FormLink = GetFirstNode (&FormSet->FormListHead);\r | |
3810 | while (!IsNull (&FormSet->FormListHead, FormLink)) {\r | |
3811 | Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r | |
3812 | ExtractDefault (FormSet, Form, DefaultId, PlatformId, FormLevel);\r | |
3813 | FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r | |
3814 | }\r | |
3815 | } else if (SettingScope == SystemLevel) {\r | |
3816 | //\r | |
3817 | // Parse Fromset one by one\r | |
3818 | //\r | |
3819 | FormSetEntryListHead = &mFormSetListEntry;\r | |
3820 | \r | |
3821 | FormLink = GetFirstNode (FormSetEntryListHead);\r | |
3822 | while (!IsNull (FormSetEntryListHead, FormLink)) {\r | |
3823 | FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormLink);\r | |
3824 | ExtractDefault (FormSet, NULL, DefaultId, PlatformId, FormSetLevel);\r | |
3825 | FormLink = GetNextNode (FormSetEntryListHead, FormLink);\r | |
3826 | }\r | |
3827 | }\r | |
3828 | \r | |
3829 | return EFI_SUCCESS;\r | |
3830 | }\r | |
3831 | \r | |
3832 | /**\r | |
3833 | Check whether existed the UQI in Current Unicode String.\r | |
3834 | \r | |
3835 | @param UniPackge A pointer to a Null-terminated Unicode string Array.\r | |
3836 | \r | |
3837 | @return TRUE If find the uqi, return TRUE\r | |
3838 | @return FALSE Otherwise, return FALSE\r | |
3839 | \r | |
3840 | **/\r | |
3841 | static\r | |
3842 | BOOLEAN\r | |
3843 | IsUqiOrNot (\r | |
3844 | IN UINT8 *UniPackge\r | |
3845 | )\r | |
3846 | {\r | |
3847 | CHAR8 *UniBin;\r | |
3848 | UINTN UniLength;\r | |
3849 | UINTN Index;\r | |
3850 | BOOLEAN FindIt;\r | |
3851 | \r | |
3852 | UniBin = (CHAR8 *) UniPackge + 4;\r | |
3853 | Index = 4;\r | |
3854 | FindIt = FALSE;\r | |
3855 | UniLength = *(UINT32 *) UniPackge;\r | |
3856 | \r | |
3857 | if (((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS) {\r | |
3858 | //\r | |
3859 | // Search the uqi language\r | |
3860 | //\r | |
3861 | while ((Index < UniLength) && ((EFI_HII_PACKAGE_HEADER *)UniBin)->Type == EFI_HII_PACKAGE_STRINGS){\r | |
3862 | if (!strcmp (((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Language, "uqi")) {\r | |
3863 | FindIt = TRUE;\r | |
3864 | break;\r | |
3865 | }\r | |
3866 | Index = Index + ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
3867 | UniBin += ((EFI_HII_STRING_PACKAGE_HDR *)UniBin)->Header.Length;\r | |
3868 | }\r | |
3869 | }\r | |
3870 | return FindIt;\r | |
3871 | }\r | |
3872 | \r | |
3873 | /**\r | |
3874 | Returns Length of UQI string (in CHAR16) (not including null termination).\r | |
3875 | \r | |
3876 | @param UniPackge A pointer to a UQI string.\r | |
3877 | \r | |
3878 | @return Number Length of UQIL string (in words) or 0\r | |
3879 | \r | |
3880 | **/\r | |
3881 | static\r | |
3882 | UINT16\r | |
3883 | GetUqiNum (\r | |
3884 | IN CHAR16 *UniString\r | |
3885 | )\r | |
3886 | {\r | |
3887 | UINT16 Number;\r | |
3888 | \r | |
3889 | if (UniString == NULL) {\r | |
3890 | return 0;\r | |
3891 | }\r | |
3892 | for (Number = 0; UniString[Number] != 0; Number++) {\r | |
3893 | ;\r | |
3894 | }\r | |
3895 | return Number;\r | |
3896 | }\r | |
3897 | \r | |
3898 | /**\r | |
3899 | Print the formset title information.\r | |
3900 | \r | |
3901 | @param FormSet The pointer to the formset.\r | |
3902 | \r | |
3903 | @return NULL.\r | |
3904 | \r | |
3905 | **/\r | |
3906 | static\r | |
3907 | VOID\r | |
3908 | StringPrintormSetTitle (\r | |
3909 | IN FORM_BROWSER_FORMSET *FormSet\r | |
3910 | )\r | |
3911 | {\r | |
3912 | CHAR16 *VarDefaultName;\r | |
3913 | EFI_STATUS Status;\r | |
3914 | \r | |
3915 | VarDefaultName = NULL;\r | |
3916 | \r | |
3917 | StringPrint("\n\n// Form Set: ");\r | |
3918 | \r | |
3919 | Status = FindDefaultName (\r | |
3920 | &(FormSet->EnUsStringList),\r | |
3921 | FormSet->UnicodeBinary,\r | |
3922 | FormSet->FormSetTitle,\r | |
3923 | EN_US,\r | |
3924 | &VarDefaultName\r | |
3925 | );\r | |
3926 | assert (!EFI_ERROR (Status));\r | |
3927 | LogUnicodeString (VarDefaultName);\r | |
3928 | \r | |
3929 | StringPrint("\n// %s",FORM_SET_GUID_PREFIX);\r | |
3930 | StringPrint(\r | |
3931 | EFI_GUID_FORMAT,\r | |
3932 | FormSet->Guid.Data1, FormSet->Guid.Data2,\r | |
3933 | FormSet->Guid.Data3, FormSet->Guid.Data4[0],\r | |
3934 | FormSet->Guid.Data4[1],FormSet->Guid.Data4[2],\r | |
3935 | FormSet->Guid.Data4[3],FormSet->Guid.Data4[4],\r | |
3936 | FormSet->Guid.Data4[5],FormSet->Guid.Data4[6],\r | |
3937 | FormSet->Guid.Data4[7]);\r | |
3938 | StringPrint("\n");\r | |
3939 | \r | |
3940 | if (&(FormSet->EnUsStringList) == NULL && VarDefaultName != NULL && FormSet->FormSetTitle != 0) {\r | |
3941 | free (VarDefaultName);\r | |
3942 | VarDefaultName = NULL;\r | |
3943 | }\r | |
3944 | }\r | |
3945 | \r | |
3946 | /**\r | |
3947 | Print the formset title information.\r | |
3948 | \r | |
3949 | @param FormSet The pointer to the formset.\r | |
3950 | @param Question The pointer to the question of ONE_OF.\r | |
3951 | \r | |
3952 | @return NULL.\r | |
3953 | \r | |
3954 | **/\r | |
3955 | static\r | |
3956 | EFI_STATUS\r | |
3957 | PrintOneOfOptions (\r | |
3958 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
3959 | IN FORM_BROWSER_STATEMENT *Question\r | |
3960 | )\r | |
3961 | {\r | |
3962 | LIST_ENTRY *Link;\r | |
3963 | QUESTION_OPTION *Option;\r | |
3964 | CHAR16 *VarDefaultName;\r | |
3965 | EFI_STATUS Status;\r | |
3966 | \r | |
3967 | Status = EFI_SUCCESS;\r | |
3968 | VarDefaultName = NULL;\r | |
3969 | \r | |
3970 | if ((Question->Operand != EFI_IFR_ONE_OF_OP)\r | |
3971 | && (Question->Operand != EFI_IFR_ORDERED_LIST_OP)\r | |
3972 | ) {\r | |
3973 | return EFI_ABORTED;\r | |
3974 | }\r | |
3975 | \r | |
3976 | Link = GetFirstNode (&Question->OptionListHead);\r | |
3977 | while (!IsNull (&Question->OptionListHead, Link)) {\r | |
3978 | Option = QUESTION_OPTION_FROM_LINK (Link);\r | |
3979 | if (Question->QuestionReferToBitField) {\r | |
3980 | StringPrint("// %08X = ", Option->Value.Value.u32);\r | |
3981 | } else {\r | |
3982 | switch(Option->Value.Type) {\r | |
3983 | \r | |
3984 | case EFI_IFR_TYPE_NUM_SIZE_8:\r | |
3985 | StringPrint("// %02X = ", Option->Value.Value.u8);\r | |
3986 | break;\r | |
3987 | \r | |
3988 | case EFI_IFR_TYPE_NUM_SIZE_16:\r | |
3989 | StringPrint("// %04X = ", Option->Value.Value.u16);\r | |
3990 | break;\r | |
3991 | \r | |
3992 | case EFI_IFR_TYPE_NUM_SIZE_32:\r | |
3993 | StringPrint("// %08X = ", Option->Value.Value.u32);\r | |
3994 | break;\r | |
3995 | \r | |
3996 | case EFI_IFR_TYPE_NUM_SIZE_64:\r | |
3997 | StringPrint("// %016llX = ", Option->Value.Value.u64);\r | |
3998 | break;\r | |
3999 | \r | |
4000 | case EFI_IFR_TYPE_BOOLEAN:\r | |
4001 | StringPrint("// %X = ", Option->Value.Value.b);\r | |
4002 | break;\r | |
4003 | \r | |
4004 | case EFI_IFR_TYPE_STRING:\r | |
4005 | StringPrint("// %X = ", Option->Value.Value.string);\r | |
4006 | break;\r | |
4007 | \r | |
4008 | default:\r | |
4009 | break;\r | |
4010 | }\r | |
4011 | }\r | |
4012 | Status = FindDefaultName (\r | |
4013 | &(FormSet->EnUsStringList),\r | |
4014 | FormSet->UnicodeBinary,\r | |
4015 | Option->Text,\r | |
4016 | EN_US,\r | |
4017 | &VarDefaultName\r | |
4018 | );\r | |
4019 | \r | |
4020 | LogUnicodeString (VarDefaultName);\r | |
4021 | StringPrint("\n");\r | |
4022 | if (&(FormSet->EnUsStringList) == NULL && VarDefaultName != NULL && Option->Text != 0) {\r | |
4023 | free (VarDefaultName);\r | |
4024 | VarDefaultName = NULL;\r | |
4025 | }\r | |
4026 | Link = GetNextNode (&Question->OptionListHead, Link);\r | |
4027 | }\r | |
4028 | return Status;\r | |
4029 | }\r | |
4030 | \r | |
4031 | /**\r | |
4032 | Print the form title information.\r | |
4033 | \r | |
4034 | @param FormSet The pointer to the formset.\r | |
4035 | @param FormSet The pointer to the form.\r | |
4036 | \r | |
4037 | @return NULL.\r | |
4038 | \r | |
4039 | **/\r | |
4040 | static\r | |
4041 | VOID\r | |
4042 | StringPrintormTitle (\r | |
4043 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
4044 | IN FORM_BROWSER_FORM *Form\r | |
4045 | )\r | |
4046 | {\r | |
4047 | CHAR16 *VarDefaultName;\r | |
4048 | EFI_STATUS Status;\r | |
4049 | \r | |
4050 | VarDefaultName = NULL;\r | |
4051 | \r | |
4052 | StringPrint("\n// Form: ");\r | |
4053 | Status = FindDefaultName (\r | |
4054 | &(FormSet->EnUsStringList),\r | |
4055 | FormSet->UnicodeBinary,\r | |
4056 | Form->FormTitle,\r | |
4057 | EN_US,\r | |
4058 | &VarDefaultName\r | |
4059 | );\r | |
4060 | assert (!EFI_ERROR (Status));\r | |
4061 | \r | |
4062 | LogUnicodeString (VarDefaultName);\r | |
4063 | StringPrint("\n");\r | |
4064 | \r | |
4065 | if (&(FormSet->EnUsStringList) == NULL && VarDefaultName != NULL && Form->FormTitle != 0) {\r | |
4066 | free (VarDefaultName);\r | |
4067 | VarDefaultName = NULL;\r | |
4068 | }\r | |
4069 | \r | |
4070 | }\r | |
4071 | \r | |
4072 | /**\r | |
4073 | Print the information of questions.\r | |
4074 | \r | |
4075 | @param FormSet The pointer to the formset.\r | |
4076 | @param FormSet The pointer to the form.\r | |
4077 | @param Question The pointer to the question.\r | |
4078 | @param PrintOrNot Decide whether print or not.\r | |
4079 | \r | |
4080 | @return NULL.\r | |
4081 | \r | |
4082 | **/\r | |
4083 | static\r | |
4084 | VOID\r | |
4085 | PrintQuestion (\r | |
4086 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
4087 | IN FORM_BROWSER_FORM *Form,\r | |
4088 | IN FORM_BROWSER_STATEMENT *Question,\r | |
4089 | IN BOOLEAN PrintOrNot\r | |
4090 | )\r | |
4091 | {\r | |
4092 | EFI_STATUS Status;\r | |
4093 | CHAR16 *VarDefaultName;\r | |
4094 | UINT16 UqiStringLength;\r | |
4095 | BOOLEAN HaveUQIlanguage;\r | |
4096 | \r | |
4097 | Status = EFI_SUCCESS;\r | |
4098 | VarDefaultName = NULL;\r | |
4099 | UqiStringLength = 0;\r | |
4100 | \r | |
4101 | HaveUQIlanguage = IsUqiOrNot (FormSet->UnicodeBinary);\r | |
4102 | \r | |
4103 | switch (Question->Operand) {\r | |
4104 | \r | |
4105 | case EFI_IFR_SUBTITLE_OP:\r | |
4106 | if (PrintOrNot) {\r | |
4107 | Status = FindDefaultName (\r | |
4108 | &(FormSet->EnUsStringList),\r | |
4109 | FormSet->UnicodeBinary,\r | |
4110 | Question->Prompt,\r | |
4111 | EN_US,\r | |
4112 | &VarDefaultName\r | |
4113 | );\r | |
4114 | assert (!EFI_ERROR (Status));\r | |
4115 | if ((VarDefaultName != NULL) && (FceStrCmp (VarDefaultName, L"") != 0)) {\r | |
4116 | StringPrint("// Subtitle: ");\r | |
4117 | StringPrint("// ");\r | |
4118 | LogUnicodeString (VarDefaultName);\r | |
4119 | StringPrint("\n");\r | |
4120 | }\r | |
4121 | }\r | |
4122 | break;\r | |
4123 | \r | |
4124 | case EFI_IFR_ONE_OF_OP:\r | |
4125 | \r | |
4126 | if( HaveUQIlanguage ) {\r | |
4127 | Status = FindDefaultName (\r | |
4128 | &(FormSet->UqiStringList),\r | |
4129 | FormSet->UnicodeBinary,\r | |
4130 | Question->Prompt,\r | |
4131 | UQI,\r | |
4132 | &VarDefaultName\r | |
4133 | );\r | |
4134 | assert (!EFI_ERROR (Status));\r | |
4135 | \r | |
4136 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4137 | if (PrintOrNot) {\r | |
4138 | if (UqiStringLength > 0) {\r | |
4139 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4140 | LogUqi(VarDefaultName);\r | |
4141 | } else {\r | |
4142 | StringPrint("\n// [No UQI] ");\r | |
4143 | }\r | |
4144 | }\r | |
4145 | } else {\r | |
4146 | Status = FindDefaultName (\r | |
4147 | &(FormSet->EnUsStringList),\r | |
4148 | FormSet->UnicodeBinary,\r | |
4149 | Question->Prompt,\r | |
4150 | EN_US,\r | |
4151 | &VarDefaultName\r | |
4152 | );\r | |
4153 | assert (!EFI_ERROR (Status));\r | |
4154 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4155 | \r | |
4156 | if (PrintOrNot) {\r | |
4157 | if (UqiStringLength > 0) {\r | |
4158 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4159 | LogUqi(VarDefaultName);\r | |
4160 | } else {\r | |
4161 | StringPrint("\n// [No UQI] ");\r | |
4162 | }\r | |
4163 | }\r | |
4164 | }\r | |
4165 | //\r | |
4166 | //Record the UQi to the Question\r | |
4167 | //\r | |
4168 | Question->Uqi.HexNum = UqiStringLength;\r | |
4169 | Question->Uqi.Data = VarDefaultName;\r | |
4170 | Question->Uqi.Type = ONE_OF;\r | |
4171 | \r | |
4172 | if (PrintOrNot) {\r | |
4173 | StringPrint("ONE_OF ");\r | |
4174 | \r | |
4175 | LogIfrValue (\r | |
4176 | FormSet,\r | |
4177 | Question\r | |
4178 | );\r | |
4179 | StringPrint(" // ");\r | |
4180 | Status = FindDefaultName (\r | |
4181 | &(FormSet->EnUsStringList),\r | |
4182 | FormSet->UnicodeBinary,\r | |
4183 | Question->Prompt,\r | |
4184 | EN_US,\r | |
4185 | &VarDefaultName\r | |
4186 | );\r | |
4187 | assert (!EFI_ERROR (Status));\r | |
4188 | LogUnicodeString (VarDefaultName);\r | |
4189 | StringPrint("\n");\r | |
4190 | //\r | |
4191 | // Print ONE_OF_OPTION\r | |
4192 | //\r | |
4193 | PrintOneOfOptions (FormSet, Question);\r | |
4194 | }\r | |
4195 | break;\r | |
4196 | \r | |
4197 | case EFI_IFR_CHECKBOX_OP:\r | |
4198 | \r | |
4199 | if( HaveUQIlanguage ) {\r | |
4200 | Status = FindDefaultName (\r | |
4201 | &(FormSet->UqiStringList),\r | |
4202 | FormSet->UnicodeBinary,\r | |
4203 | Question->Prompt,\r | |
4204 | UQI,\r | |
4205 | &VarDefaultName\r | |
4206 | );\r | |
4207 | assert (!EFI_ERROR (Status));\r | |
4208 | \r | |
4209 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4210 | if (PrintOrNot) {\r | |
4211 | if (UqiStringLength > 0) {\r | |
4212 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4213 | LogUqi(VarDefaultName);\r | |
4214 | } else {\r | |
4215 | StringPrint("\n// [No UQI] ");\r | |
4216 | }\r | |
4217 | }\r | |
4218 | } else {\r | |
4219 | Status = FindDefaultName (\r | |
4220 | &(FormSet->EnUsStringList),\r | |
4221 | FormSet->UnicodeBinary,\r | |
4222 | Question->Prompt,\r | |
4223 | EN_US,\r | |
4224 | &VarDefaultName\r | |
4225 | );\r | |
4226 | assert (!EFI_ERROR (Status));\r | |
4227 | \r | |
4228 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4229 | \r | |
4230 | if (PrintOrNot) {\r | |
4231 | if (UqiStringLength > 0) {\r | |
4232 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4233 | LogUqi(VarDefaultName);\r | |
4234 | } else {\r | |
4235 | StringPrint("\n// [No UQI] ");\r | |
4236 | }\r | |
4237 | }\r | |
4238 | }\r | |
4239 | //\r | |
4240 | //Record the UQi to the HiiObjList\r | |
4241 | //\r | |
4242 | Question->Uqi.HexNum = UqiStringLength;\r | |
4243 | Question->Uqi.Data = VarDefaultName;\r | |
4244 | Question->Uqi.Type = CHECKBOX;\r | |
4245 | if (PrintOrNot) {\r | |
4246 | StringPrint("CHECKBOX ");\r | |
4247 | LogIfrValue (\r | |
4248 | FormSet,\r | |
4249 | Question\r | |
4250 | );\r | |
4251 | StringPrint(" // ");\r | |
4252 | Status = FindDefaultName (\r | |
4253 | &(FormSet->EnUsStringList),\r | |
4254 | FormSet->UnicodeBinary,\r | |
4255 | Question->Prompt,\r | |
4256 | EN_US,\r | |
4257 | &VarDefaultName\r | |
4258 | );\r | |
4259 | assert (!EFI_ERROR (Status));\r | |
4260 | LogUnicodeString (VarDefaultName);\r | |
4261 | StringPrint("\n");\r | |
4262 | StringPrint("// 0 = Unchecked\n");\r | |
4263 | StringPrint("// 1 = Checked\n");\r | |
4264 | }\r | |
4265 | break;\r | |
4266 | \r | |
4267 | case EFI_IFR_STRING_OP:\r | |
4268 | if( HaveUQIlanguage ) {\r | |
4269 | Status = FindDefaultName (\r | |
4270 | &(FormSet->UqiStringList),\r | |
4271 | FormSet->UnicodeBinary,\r | |
4272 | Question->Prompt,\r | |
4273 | UQI,\r | |
4274 | &VarDefaultName\r | |
4275 | );\r | |
4276 | assert (!EFI_ERROR (Status));\r | |
4277 | \r | |
4278 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4279 | if (PrintOrNot) {\r | |
4280 | if (UqiStringLength > 0) {\r | |
4281 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4282 | LogUqi(VarDefaultName);\r | |
4283 | } else {\r | |
4284 | StringPrint("\n// [No UQI] ");\r | |
4285 | }\r | |
4286 | }\r | |
4287 | } else {\r | |
4288 | Status = FindDefaultName (\r | |
4289 | &(FormSet->EnUsStringList),\r | |
4290 | FormSet->UnicodeBinary,\r | |
4291 | Question->Prompt,\r | |
4292 | EN_US,\r | |
4293 | &VarDefaultName\r | |
4294 | );\r | |
4295 | assert (!EFI_ERROR (Status));\r | |
4296 | \r | |
4297 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4298 | \r | |
4299 | if (PrintOrNot) {\r | |
4300 | if (UqiStringLength > 0) {\r | |
4301 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4302 | LogUqi(VarDefaultName);\r | |
4303 | } else {\r | |
4304 | StringPrint("\n// [No UQI] ");\r | |
4305 | }\r | |
4306 | }\r | |
4307 | }\r | |
4308 | //\r | |
4309 | //Record the UQi to the HiiObjList\r | |
4310 | //\r | |
4311 | Question->Uqi.HexNum = UqiStringLength;\r | |
4312 | Question->Uqi.Data = VarDefaultName;\r | |
4313 | Question->Uqi.Type = STRING;\r | |
4314 | if (PrintOrNot) {\r | |
4315 | StringPrint("STRING ");\r | |
4316 | LogIfrValueStr (\r | |
4317 | FormSet,\r | |
4318 | Question\r | |
4319 | );\r | |
4320 | StringPrint(" // ");\r | |
4321 | Status = FindDefaultName (\r | |
4322 | &(FormSet->EnUsStringList),\r | |
4323 | FormSet->UnicodeBinary,\r | |
4324 | Question->Prompt,\r | |
4325 | EN_US,\r | |
4326 | &VarDefaultName\r | |
4327 | );\r | |
4328 | assert (!EFI_ERROR (Status));\r | |
4329 | LogUnicodeString (VarDefaultName);\r | |
4330 | StringPrint("\n");\r | |
4331 | }\r | |
4332 | break;\r | |
4333 | \r | |
4334 | case EFI_IFR_NUMERIC_OP:\r | |
4335 | \r | |
4336 | if( HaveUQIlanguage ) {\r | |
4337 | Status = FindDefaultName (\r | |
4338 | &(FormSet->UqiStringList),\r | |
4339 | FormSet->UnicodeBinary,\r | |
4340 | Question->Prompt,\r | |
4341 | UQI,\r | |
4342 | &VarDefaultName\r | |
4343 | );\r | |
4344 | assert (!EFI_ERROR (Status));\r | |
4345 | \r | |
4346 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4347 | if (PrintOrNot) {\r | |
4348 | if (UqiStringLength > 0) {\r | |
4349 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4350 | LogUqi(VarDefaultName);\r | |
4351 | } else {\r | |
4352 | StringPrint("\n// [No UQI] ");\r | |
4353 | }\r | |
4354 | }\r | |
4355 | } else {\r | |
4356 | Status = FindDefaultName (\r | |
4357 | &(FormSet->EnUsStringList),\r | |
4358 | FormSet->UnicodeBinary,\r | |
4359 | Question->Prompt,\r | |
4360 | EN_US,\r | |
4361 | &VarDefaultName\r | |
4362 | );\r | |
4363 | assert (!EFI_ERROR (Status));\r | |
4364 | \r | |
4365 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4366 | if (PrintOrNot) {\r | |
4367 | if (UqiStringLength > 0) {\r | |
4368 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4369 | LogUqi(VarDefaultName);\r | |
4370 | } else {\r | |
4371 | StringPrint("\n// [No UQI] ");\r | |
4372 | }\r | |
4373 | }\r | |
4374 | }\r | |
4375 | //\r | |
4376 | //Record the UQi to the HiiObjList\r | |
4377 | //\r | |
4378 | Question->Uqi.HexNum = UqiStringLength;\r | |
4379 | Question->Uqi.Data = VarDefaultName;\r | |
4380 | Question->Uqi.Type = NUMERIC;\r | |
4381 | if (PrintOrNot) {\r | |
4382 | StringPrint("NUMERIC ");\r | |
4383 | LogIfrValue (\r | |
4384 | FormSet,\r | |
4385 | Question\r | |
4386 | );\r | |
4387 | StringPrint(" // ");\r | |
4388 | Status = FindDefaultName (\r | |
4389 | &(FormSet->EnUsStringList),\r | |
4390 | FormSet->UnicodeBinary,\r | |
4391 | Question->Prompt,\r | |
4392 | EN_US,\r | |
4393 | &VarDefaultName\r | |
4394 | );\r | |
4395 | assert (!EFI_ERROR (Status));\r | |
4396 | LogUnicodeString (VarDefaultName);\r | |
4397 | StringPrint("\n");\r | |
4398 | \r | |
4399 | if (Question->QuestionReferToBitField) {\r | |
4400 | StringPrint("// Minimum = %08llX \n", Question->Minimum);\r | |
4401 | StringPrint("// Maximum = %08llX \n", Question->Maximum);\r | |
4402 | StringPrint("// Step = %08llX \n", Question->Step);\r | |
4403 | } else {\r | |
4404 | switch (Question->StorageWidth) {\r | |
4405 | \r | |
4406 | case sizeof (UINT8):\r | |
4407 | StringPrint("// Minimum = %02llX \n", Question->Minimum);\r | |
4408 | StringPrint("// Maximum = %02llX \n", Question->Maximum);\r | |
4409 | StringPrint("// Step = %02llX \n", Question->Step);\r | |
4410 | break;\r | |
4411 | \r | |
4412 | case sizeof (UINT16):\r | |
4413 | StringPrint("// Minimum = %04llX \n", Question->Minimum);\r | |
4414 | StringPrint("// Maximum = %04llX \n", Question->Maximum);\r | |
4415 | StringPrint("// Step = %04llX \n", Question->Step);\r | |
4416 | break;\r | |
4417 | \r | |
4418 | case sizeof (UINT32):\r | |
4419 | StringPrint("// Minimum = %08llX \n", Question->Minimum);\r | |
4420 | StringPrint("// Maximum = %08llX \n", Question->Maximum);\r | |
4421 | StringPrint("// Step = %08llX \n", Question->Step);\r | |
4422 | break;\r | |
4423 | \r | |
4424 | case sizeof (UINT64):\r | |
4425 | StringPrint("// Minimum = %016llX \n", Question->Minimum);\r | |
4426 | StringPrint("// Maximum = %016llX \n", Question->Maximum);\r | |
4427 | StringPrint("// Step = %016llX \n", Question->Step);\r | |
4428 | break;\r | |
4429 | \r | |
4430 | default:\r | |
4431 | StringPrint("0000 // Width > 16 is not supported -- FAILURE");\r | |
4432 | break;\r | |
4433 | }\r | |
4434 | }\r | |
4435 | }\r | |
4436 | break;\r | |
4437 | \r | |
4438 | case EFI_IFR_ORDERED_LIST_OP:\r | |
4439 | \r | |
4440 | if( HaveUQIlanguage ) {\r | |
4441 | Status = FindDefaultName (\r | |
4442 | &(FormSet->UqiStringList),\r | |
4443 | FormSet->UnicodeBinary,\r | |
4444 | Question->Prompt,\r | |
4445 | UQI,\r | |
4446 | &VarDefaultName\r | |
4447 | );\r | |
4448 | assert (!EFI_ERROR (Status));\r | |
4449 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4450 | \r | |
4451 | if (PrintOrNot) {\r | |
4452 | if (UqiStringLength > 0) {\r | |
4453 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4454 | LogUqi(VarDefaultName);\r | |
4455 | } else {\r | |
4456 | StringPrint("\n// [No UQI] ");\r | |
4457 | }\r | |
4458 | }\r | |
4459 | } else {\r | |
4460 | Status = FindDefaultName (\r | |
4461 | &(FormSet->EnUsStringList),\r | |
4462 | FormSet->UnicodeBinary,\r | |
4463 | Question->Prompt,\r | |
4464 | EN_US,\r | |
4465 | &VarDefaultName\r | |
4466 | );\r | |
4467 | \r | |
4468 | assert (!EFI_ERROR (Status));\r | |
4469 | \r | |
4470 | UqiStringLength = GetUqiNum (VarDefaultName);\r | |
4471 | if (PrintOrNot) {\r | |
4472 | if (UqiStringLength > 0) {\r | |
4473 | StringPrint("\nQ %04X ", UqiStringLength);\r | |
4474 | LogUqi(VarDefaultName);\r | |
4475 | } else {\r | |
4476 | StringPrint("\n// [No UQI] ");\r | |
4477 | }\r | |
4478 | }\r | |
4479 | }\r | |
4480 | //\r | |
4481 | //Record the UQi to the HiiObjList\r | |
4482 | //\r | |
4483 | Question->Uqi.HexNum = UqiStringLength;\r | |
4484 | Question->Uqi.Data = VarDefaultName;\r | |
4485 | Question->Uqi.Type = ORDERED_LIST;\r | |
4486 | \r | |
4487 | if (PrintOrNot) {\r | |
4488 | StringPrint("ORDERED_LIST %04X ", Question->MaxContainers);\r | |
4489 | \r | |
4490 | LogIfrValueList (\r | |
4491 | FormSet,\r | |
4492 | Question\r | |
4493 | );\r | |
4494 | StringPrint(" // ");\r | |
4495 | Status = FindDefaultName (\r | |
4496 | &(FormSet->EnUsStringList),\r | |
4497 | FormSet->UnicodeBinary,\r | |
4498 | Question->Prompt,\r | |
4499 | EN_US,\r | |
4500 | &VarDefaultName\r | |
4501 | );\r | |
4502 | assert (!EFI_ERROR (Status));\r | |
4503 | LogUnicodeString (VarDefaultName);\r | |
4504 | StringPrint("\n");\r | |
4505 | }\r | |
4506 | //\r | |
4507 | // Print ONE_OF_OPTION\r | |
4508 | //\r | |
4509 | PrintOneOfOptions (FormSet, Question);\r | |
4510 | break;\r | |
4511 | \r | |
4512 | default:\r | |
4513 | break;\r | |
4514 | }\r | |
4515 | \r | |
4516 | if (&(FormSet->EnUsStringList) == NULL &&VarDefaultName != NULL && Question->Prompt != 0) {\r | |
4517 | free (VarDefaultName);\r | |
4518 | VarDefaultName = NULL;\r | |
4519 | }\r | |
4520 | \r | |
4521 | if (PrintOrNot && Question->Storage) {\r | |
4522 | StringPrint("// size = 0x%x", Question->StorageWidth);\r | |
4523 | StringPrint("\n// offset = 0x%x", Question->VarStoreInfo.VarOffset);\r | |
4524 | StringPrint("\n// name = ");\r | |
4525 | LogUnicodeString(Question->VariableName);\r | |
4526 | StringPrint("\n// guid = ");\r | |
4527 | StringPrint(\r | |
4528 | EFI_GUID_FORMAT,\r | |
4529 | Question->Guid.Data1, Question->Guid.Data2,\r | |
4530 | Question->Guid.Data3, Question->Guid.Data4[0],\r | |
4531 | Question->Guid.Data4[1],Question->Guid.Data4[2],\r | |
4532 | Question->Guid.Data4[3],Question->Guid.Data4[4],\r | |
4533 | Question->Guid.Data4[5],Question->Guid.Data4[6],\r | |
4534 | Question->Guid.Data4[7]\r | |
4535 | );\r | |
4536 | StringPrint("\n// attribute = 0x%x", Question->Attributes);\r | |
4537 | StringPrint("\n// help = ");\r | |
4538 | Status = FindDefaultName (\r | |
4539 | &(FormSet->EnUsStringList),\r | |
4540 | FormSet->UnicodeBinary,\r | |
4541 | Question->Help,\r | |
4542 | EN_US,\r | |
4543 | &VarDefaultName\r | |
4544 | );\r | |
4545 | assert (!EFI_ERROR (Status));\r | |
4546 | LogUnicodeString (VarDefaultName);\r | |
4547 | StringPrint("\n");\r | |
4548 | if (&(FormSet->EnUsStringList) == NULL &&VarDefaultName != NULL && Question->Help != 0) {\r | |
4549 | free (VarDefaultName);\r | |
4550 | VarDefaultName = NULL;\r | |
4551 | }\r | |
4552 | }\r | |
4553 | \r | |
4554 | }\r | |
4555 | \r | |
4556 | /**\r | |
4557 | Check whether current Formset or Form is NULL. If no valid questions, return FASLE.\r | |
4558 | \r | |
4559 | @param FormSet The pointer to the formset.\r | |
4560 | @param FormSet The pointer to the form.\r | |
4561 | @param IsFormSet FormSet or Form.\r | |
4562 | \r | |
4563 | @retval TRUE\r | |
4564 | @return FALSE\r | |
4565 | **/\r | |
4566 | BOOLEAN\r | |
4567 | CheckFormSetOrFormNull (\r | |
4568 | IN FORM_BROWSER_FORMSET *FormSet,\r | |
4569 | IN FORM_BROWSER_FORM *Form,\r | |
4570 | IN BOOLEAN IsFormSet\r | |
4571 | )\r | |
4572 | {\r | |
4573 | LIST_ENTRY *FormLink;\r | |
4574 | FORM_BROWSER_STATEMENT *Question;\r | |
4575 | LIST_ENTRY *QuestionLink;\r | |
4576 | \r | |
4577 | FormLink = NULL;\r | |
4578 | Question = NULL;\r | |
4579 | QuestionLink = NULL;\r | |
4580 | \r | |
4581 | //\r | |
4582 | // Parse all forms in formset\r | |
4583 | //\r | |
4584 | if (IsFormSet) {\r | |
4585 | FormLink = GetFirstNode (&FormSet->FormListHead);\r | |
4586 | \r | |
4587 | while (!IsNull (&FormSet->FormListHead, FormLink)) {\r | |
4588 | Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r | |
4589 | //\r | |
4590 | // Parse five kinds of Questions in Form\r | |
4591 | //\r | |
4592 | QuestionLink = GetFirstNode (&Form->StatementListHead);\r | |
4593 | \r | |
4594 | while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r | |
4595 | Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r | |
4596 | //\r | |
4597 | // Parse five kinds of Questions in Form\r | |
4598 | //\r | |
4599 | if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r | |
4600 | || (Question->Operand == EFI_IFR_NUMERIC_OP)\r | |
4601 | || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r | |
4602 | || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r | |
4603 | || (Question->Operand == EFI_IFR_STRING_OP)\r | |
4604 | ) {\r | |
4605 | if (mMultiPlatformParam.MultiPlatformOrNot) {\r | |
4606 | //\r | |
4607 | // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode\r | |
4608 | //\r | |
4609 | if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) {\r | |
4610 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4611 | continue;\r | |
4612 | }\r | |
4613 | if (Question->Type == EFI_IFR_VARSTORE_EFI_OP\r | |
4614 | && Question->NewEfiVarstore\r | |
4615 | && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) {\r | |
4616 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4617 | continue;\r | |
4618 | }\r | |
4619 | }\r | |
4620 | //\r | |
4621 | //If invalid variable type, skip it.\r | |
4622 | //\r | |
4623 | if ((Question->Type != EFI_IFR_VARSTORE_EFI_OP)\r | |
4624 | && (Question->Type != EFI_IFR_VARSTORE_OP)) {\r | |
4625 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4626 | continue;\r | |
4627 | }\r | |
4628 | return TRUE;\r | |
4629 | }\r | |
4630 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4631 | }\r | |
4632 | \r | |
4633 | FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r | |
4634 | }\r | |
4635 | } else {\r | |
4636 | //\r | |
4637 | // Parse five kinds of Questions in Form\r | |
4638 | //\r | |
4639 | QuestionLink = GetFirstNode (&Form->StatementListHead);\r | |
4640 | \r | |
4641 | while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r | |
4642 | Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r | |
4643 | //\r | |
4644 | // Parse five kinds of Questions in Form\r | |
4645 | //\r | |
4646 | if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r | |
4647 | || (Question->Operand == EFI_IFR_NUMERIC_OP)\r | |
4648 | || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r | |
4649 | || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r | |
4650 | || (Question->Operand == EFI_IFR_STRING_OP)\r | |
4651 | ) {\r | |
4652 | if (mMultiPlatformParam.MultiPlatformOrNot) {\r | |
4653 | //\r | |
4654 | // Only compare the valid EFI_IFR_VARSTORE_EFI_OP in multi-platform mode\r | |
4655 | //\r | |
4656 | if (Question->Type != EFI_IFR_VARSTORE_EFI_OP) {\r | |
4657 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4658 | continue;\r | |
4659 | }\r | |
4660 | if ((Question->Type == EFI_IFR_VARSTORE_EFI_OP)\r | |
4661 | && Question->NewEfiVarstore\r | |
4662 | && ((Question->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) {\r | |
4663 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4664 | continue;\r | |
4665 | }\r | |
4666 | }\r | |
4667 | //\r | |
4668 | //If invalid variable type, skip it.\r | |
4669 | //\r | |
4670 | if ((Question->Type != EFI_IFR_VARSTORE_EFI_OP)\r | |
4671 | && (Question->Type != EFI_IFR_VARSTORE_OP)) {\r | |
4672 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4673 | continue;\r | |
4674 | }\r | |
4675 | return TRUE;\r | |
4676 | }\r | |
4677 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4678 | }\r | |
4679 | }\r | |
4680 | return FALSE;\r | |
4681 | }\r | |
4682 | \r | |
4683 | /**\r | |
4684 | Print all ONE_OF ORDER_LIST NUMERIC STRING and CHECKBOX in all fromsets.\r | |
4685 | \r | |
4686 | @param Formset The pointer to the entry of the fromset list\r | |
4687 | @param Formset The pointer to the entry of the storage list\r | |
4688 | \r | |
4689 | @retval EFI_SUCCESS It was complete successfully\r | |
4690 | @return EFI_ABORTED An error occurred\r | |
4691 | **/\r | |
4692 | EFI_STATUS\r | |
4693 | PrintInfoInAllFormset (\r | |
4694 | IN LIST_ENTRY *FormSetEntryListHead,\r | |
4695 | IN LIST_ENTRY *StorageEntryListHead\r | |
4696 | )\r | |
4697 | {\r | |
4698 | EFI_STATUS Status;\r | |
4699 | FORM_BROWSER_FORMSET *FormSet;\r | |
4700 | LIST_ENTRY *FormSetLink;\r | |
4701 | LIST_ENTRY *FormLink;\r | |
4702 | FORM_BROWSER_FORM *Form;\r | |
4703 | FORM_BROWSER_STATEMENT *Question;\r | |
4704 | LIST_ENTRY *QuestionLink;\r | |
4705 | FORMSET_STORAGE *Storage;\r | |
4706 | CHAR8 *VarBuffer;\r | |
4707 | LIST_ENTRY *TempStorageLink;\r | |
4708 | UINT32 Index;\r | |
4709 | BOOLEAN Skip;\r | |
4710 | BOOLEAN ConstantFlag;\r | |
4711 | \r | |
4712 | Status = EFI_SUCCESS;\r | |
4713 | FormSet = NULL;\r | |
4714 | FormSetLink = NULL;\r | |
4715 | FormLink = NULL;\r | |
4716 | Form = NULL;\r | |
4717 | Question = NULL;\r | |
4718 | QuestionLink = NULL;\r | |
4719 | Storage = NULL;\r | |
4720 | VarBuffer = NULL;\r | |
4721 | TempStorageLink = NULL;\r | |
4722 | Index = 0;\r | |
4723 | Skip = FALSE;\r | |
4724 | ConstantFlag = TRUE;\r | |
4725 | //\r | |
4726 | // Print platformId, defaultId and platformIdUqi\r | |
4727 | //\r | |
4728 | if (mMultiPlatformParam.MultiPlatformOrNot) {\r | |
4729 | StringPrint("\n\n// FCEKEY DEFAULT_ID:");\r | |
4730 | TempStorageLink = GetFirstNode (StorageEntryListHead);\r | |
4731 | Storage = FORMSET_STORAGE_FROM_LINK (TempStorageLink);\r | |
4732 | for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r | |
4733 | StringPrint (" %4d", Storage->DefaultId[Index]);\r | |
4734 | }\r | |
4735 | StringPrint("\n\n//FCEKEY PLATFORM_ID:");\r | |
4736 | for (Index = 0; Index <= Storage->DefaultPlatformIdNum; Index++) {\r | |
4737 | StringPrint (" %4lld", Storage->PlatformId[Index]);\r | |
4738 | }\r | |
4739 | if (mMultiPlatformParam.Uqi.Data != NULL) {\r | |
4740 | StringPrint("\n\n//FCEKEY PLATFORM_UQI:");\r | |
4741 | StringPrint(" %04X ", mMultiPlatformParam.Uqi.HexNum);\r | |
4742 | LogUqi(mMultiPlatformParam.Uqi.Data);\r | |
4743 | }\r | |
4744 | }\r | |
4745 | FormSetLink = GetFirstNode (FormSetEntryListHead);\r | |
4746 | while (!IsNull (FormSetEntryListHead, FormSetLink)) {\r | |
4747 | FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormSetLink);\r | |
4748 | //\r | |
4749 | //Assign the new storage list\r | |
4750 | //\r | |
4751 | FormSet->StorageListHead = StorageEntryListHead;\r | |
4752 | \r | |
4753 | if (CheckFormSetOrFormNull (FormSet, NULL, TRUE)) {\r | |
4754 | StringPrintormSetTitle (FormSet);\r | |
4755 | } else {\r | |
4756 | FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink);\r | |
4757 | continue;\r | |
4758 | }\r | |
4759 | //\r | |
4760 | // Parse all forms in formset\r | |
4761 | //\r | |
4762 | FormLink = GetFirstNode (&FormSet->FormListHead);\r | |
4763 | \r | |
4764 | while (!IsNull (&FormSet->FormListHead, FormLink)) {\r | |
4765 | Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r | |
4766 | \r | |
4767 | if (CheckFormSetOrFormNull (NULL, Form, FALSE)) {\r | |
4768 | StringPrintormTitle(FormSet,Form);\r | |
4769 | } else {\r | |
4770 | FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r | |
4771 | continue;\r | |
4772 | }\r | |
4773 | //\r | |
4774 | // Parse five kinds of Questions in Form\r | |
4775 | //\r | |
4776 | QuestionLink = GetFirstNode (&Form->StatementListHead);\r | |
4777 | \r | |
4778 | while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r | |
4779 | Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r | |
4780 | //\r | |
4781 | // Parse five kinds of Questions in Form\r | |
4782 | //\r | |
4783 | if ((Question->Operand == EFI_IFR_ONE_OF_OP)\r | |
4784 | || (Question->Operand == EFI_IFR_NUMERIC_OP)\r | |
4785 | || (Question->Operand == EFI_IFR_CHECKBOX_OP)\r | |
4786 | || (Question->Operand == EFI_IFR_ORDERED_LIST_OP)\r | |
4787 | || (Question->Operand == EFI_IFR_SUBTITLE_OP)\r | |
4788 | || (Question->Operand == EFI_IFR_STRING_OP)\r | |
4789 | ) {\r | |
4790 | Skip = FALSE;\r | |
4791 | \r | |
4792 | //\r | |
4793 | //Only output the questions stored by EFI_IFR_VARSTORE_EFI_OP.\r | |
4794 | //\r | |
4795 | if (mMultiPlatformParam.MultiPlatformOrNot\r | |
4796 | && (Question->Operand != EFI_IFR_SUBTITLE_OP)\r | |
4797 | ) {\r | |
4798 | Status = SearchVarStorage (\r | |
4799 | Question,\r | |
4800 | NULL,\r | |
4801 | Question->VarStoreInfo.VarOffset,\r | |
4802 | StorageEntryListHead,\r | |
4803 | (CHAR8 **)&VarBuffer,\r | |
4804 | &Storage\r | |
4805 | );\r | |
4806 | \r | |
4807 | if (EFI_ERROR (Status)) {\r | |
4808 | Skip = TRUE;\r | |
4809 | }\r | |
4810 | }\r | |
4811 | //\r | |
4812 | // If Question is constant expression and "disabledIf True", don't output it.\r | |
4813 | //\r | |
4814 | ConstantFlag = TRUE;\r | |
4815 | if (!Skip && (Question->DisableExpression != NULL)) {\r | |
4816 | Status = EvaluateExpression (FormSet, Form, Question->DisableExpression, &ConstantFlag);\r | |
4817 | if (!EFI_ERROR (Status) && Question->DisableExpression->Result.Value.b && ConstantFlag) {\r | |
4818 | Skip = TRUE;\r | |
4819 | }\r | |
4820 | }\r | |
4821 | \r | |
4822 | if (!Skip) {\r | |
4823 | PrintQuestion(FormSet, Form, Question, TRUE);\r | |
4824 | }\r | |
4825 | }\r | |
4826 | QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r | |
4827 | }\r | |
4828 | \r | |
4829 | FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r | |
4830 | }\r | |
4831 | FormSetLink = GetNextNode (FormSetEntryListHead, FormSetLink);\r | |
4832 | }\r | |
4833 | \r | |
4834 | return EFI_SUCCESS;\r | |
4835 | }\r | |
4836 | \r |