]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/FCE/IfrParse.c
BaseTools: Fix various typos
[mirror_edk2.git] / BaseTools / Source / C / FCE / IfrParse.c
CommitLineData
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
21UINT16 mStatementIndex;\r
22UINT16 mExpressionOpCodeIndex;\r
23\r
24BOOLEAN mInScopeSubtitle;\r
25BOOLEAN mInScopeSuppress;\r
26BOOLEAN mInScopeGrayOut;\r
27BOOLEAN mInScopeDisable;\r
28FORM_EXPRESSION *mSuppressExpression;\r
29FORM_EXPRESSION *mGrayOutExpression;\r
30FORM_EXPRESSION *mDisableExpression;\r
31\r
32extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam;\r
33extern LIST_ENTRY mVarListEntry;\r
34extern LIST_ENTRY mFormSetListEntry;\r
35extern 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
40UINT32 mMaxCount = 0x100000;\r
41UINT32 mCount = 0;\r
42CHAR8 *mStringBuffer = NULL;\r
43static 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
53VOID\r
54StringPrint (\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
84static\r
85VOID\r
86PrintQuestion (\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
101static\r
102VOID\r
103LogUnicodeString (\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
133static\r
134VOID\r
135LogUqi (\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
160VOID\r
161GetBitsQuestionValue(\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
186VOID\r
187SetBitsQuestionValue (\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
214static\r
215EFI_STATUS\r
216LogIfrValue (\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
299static\r
300EFI_STATUS\r
301LogIfrValueStr (\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
362static\r
363EFI_STATUS\r
364LogIfrValueList (\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
441BOOLEAN\r
442CompareUqiHeader (\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
472static\r
473FORMSET_STORAGE *\r
474NotSameVariableInVarList (\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
533static\r
534EFI_STATUS\r
535GetStringByOffset (\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
706EFI_STATUS\r
707FindDefaultName (\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
896Done:\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
933static\r
934EFI_STATUS\r
935GetGuidNameByVariableId (\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
1053EFI_STATUS\r
1054SearchVarStorage (\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
1156CHAR16 *\r
1157GetToken (\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
1195FORM_BROWSER_STATEMENT *\r
1196CreateStatement (\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
1263FORM_BROWSER_STATEMENT *\r
1264CreateQuestion (\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
1345FORM_EXPRESSION *\r
1346CreateExpression (\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
1369FORMSET_STORAGE *\r
1370CreateStorage (\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
1391VOID\r
1392DestroyExpression (\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
1437VOID\r
1438DestroyStorage (\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
1483VOID\r
1484DestroyAllStorage (\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
1512VOID\r
1513DestroyStatement (\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
1595VOID\r
1596DestroyForm (\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
1640VOID\r
1641DestroyFormSet (\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
1716VOID\r
1717DestroyAllFormSet (\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
1745BOOLEAN\r
1746IsExpressionOpCode (\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
1774VOID\r
1775CountOpCodes (\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
1818EFI_STATUS\r
1819ParseOpCodes (\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
3314QUESTION_OPTION *\r
3315ValueToOption (\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
3347VOID\r
3348SetArrayData (\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
3392EFI_STATUS\r
3393GetQuestionDefault (\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
3464ReGetDefault:\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
3695EFI_STATUS\r
3696AssignThePlatformId (\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
3761EFI_STATUS\r
3762ExtractDefault (\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
3841static\r
3842BOOLEAN\r
3843IsUqiOrNot (\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
3881static\r
3882UINT16\r
3883GetUqiNum (\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
3906static\r
3907VOID\r
3908StringPrintormSetTitle (\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
3955static\r
3956EFI_STATUS\r
3957PrintOneOfOptions (\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
4040static\r
4041VOID\r
4042StringPrintormTitle (\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
4083static\r
4084VOID\r
4085PrintQuestion (\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
4566BOOLEAN\r
4567CheckFormSetOrFormNull (\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
4692EFI_STATUS\r
4693PrintInfoInAllFormset (\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