]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg: Change use of EFI_D_* to DEBUG_*
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
CommitLineData
c60a0616 1/** @file\r
2Parser for IFR binary encoding.\r
3\r
94057f74 4Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c60a0616 6\r
7**/\r
8\r
9#include "Setup.h"\r
c60a0616 10\r
94057f74
BH
11UINTN mStatementIndex;\r
12UINTN mExpressionOpCodeIndex;\r
7c6c064c 13EFI_QUESTION_ID mUsedQuestionId;\r
94f3aae7 14extern LIST_ENTRY gBrowserStorageList;\r
c60a0616 15/**\r
16 Initialize Statement header members.\r
17\r
18 @param OpCodeData Pointer of the raw OpCode data.\r
fda7cd4f 19 @param FormSet Pointer of the current FormSet.\r
c60a0616 20 @param Form Pointer of the current Form.\r
21\r
22 @return The Statement.\r
23\r
24**/\r
25FORM_BROWSER_STATEMENT *\r
26CreateStatement (\r
27 IN UINT8 *OpCodeData,\r
28 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
29 IN OUT FORM_BROWSER_FORM *Form\r
30 )\r
31{\r
32 FORM_BROWSER_STATEMENT *Statement;\r
33 EFI_IFR_STATEMENT_HEADER *StatementHdr;\r
d1102dba 34 INTN ConditionalExprCount;\r
c60a0616 35\r
36 if (Form == NULL) {\r
37 //\r
7c6c064c 38 // Only guid op may out side the form level.\r
c60a0616 39 //\r
7c6c064c 40 ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);\r
c60a0616 41 }\r
42\r
43 Statement = &FormSet->StatementBuffer[mStatementIndex];\r
44 mStatementIndex++;\r
45\r
46 InitializeListHead (&Statement->DefaultListHead);\r
47 InitializeListHead (&Statement->OptionListHead);\r
48 InitializeListHead (&Statement->InconsistentListHead);\r
49 InitializeListHead (&Statement->NoSubmitListHead);\r
1c0d306f 50 InitializeListHead (&Statement->WarningListHead);\r
c60a0616 51\r
52 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
53\r
54 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
7c6c064c 55 Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;\r
560a435d 56 Statement->QuestionReferToBitField = FALSE;\r
c60a0616 57\r
58 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
59 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
60 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
61\r
31585af4
ED
62 ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement);\r
63 if (ConditionalExprCount > 0) {\r
64 //\r
65 // Form is inside of suppressif\r
66 //\r
d1102dba
LG
67\r
68 Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool(\r
31585af4
ED
69 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
70 ASSERT (Statement->Expression != NULL);\r
71 Statement->Expression->Count = (UINTN) ConditionalExprCount;\r
72 Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
73 CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
0a1147ed
LG
74 }\r
75\r
c60a0616 76 //\r
77 // Insert this Statement into current Form\r
78 //\r
7c6c064c
ED
79 if (Form == NULL) {\r
80 InsertTailList (&FormSet->StatementListOSF, &Statement->Link);\r
81 } else {\r
82 InsertTailList (&Form->StatementListHead, &Statement->Link);\r
83 }\r
c60a0616 84 return Statement;\r
85}\r
86\r
c60a0616 87/**\r
88 Initialize Question's members.\r
89\r
90 @param OpCodeData Pointer of the raw OpCode data.\r
91 @param FormSet Pointer of the current FormSet.\r
92 @param Form Pointer of the current Form.\r
93\r
94 @return The Question.\r
95\r
96**/\r
97FORM_BROWSER_STATEMENT *\r
98CreateQuestion (\r
99 IN UINT8 *OpCodeData,\r
100 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
101 IN OUT FORM_BROWSER_FORM *Form\r
102 )\r
103{\r
104 FORM_BROWSER_STATEMENT *Statement;\r
105 EFI_IFR_QUESTION_HEADER *QuestionHdr;\r
106 LIST_ENTRY *Link;\r
107 FORMSET_STORAGE *Storage;\r
108 NAME_VALUE_NODE *NameValueNode;\r
94f3aae7 109 BOOLEAN Find;\r
c60a0616 110\r
111 Statement = CreateStatement (OpCodeData, FormSet, Form);\r
112 if (Statement == NULL) {\r
113 return NULL;\r
114 }\r
115\r
116 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
117 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
118 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
119 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
120\r
121 Statement->QuestionFlags = QuestionHdr->Flags;\r
122\r
123 if (Statement->VarStoreId == 0) {\r
124 //\r
125 // VarStoreId of zero indicates no variable storage\r
126 //\r
127 return Statement;\r
128 }\r
129\r
c60a0616 130 //\r
131 // Find Storage for this Question\r
132 //\r
133 Link = GetFirstNode (&FormSet->StorageListHead);\r
134 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
135 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
136\r
137 if (Storage->VarStoreId == Statement->VarStoreId) {\r
94f3aae7 138 Statement->Storage = Storage->BrowserStorage;\r
c60a0616 139 break;\r
140 }\r
141\r
142 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
143 }\r
144 ASSERT (Statement->Storage != NULL);\r
145\r
146 //\r
147 // Initialilze varname for Name/Value or EFI Variable\r
148 //\r
149 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
150 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
151 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
152 ASSERT (Statement->VariableName != NULL);\r
153\r
154 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
155 //\r
94f3aae7 156 // Check whether old string node already exist.\r
c60a0616 157 //\r
94f3aae7 158 Find = FALSE;\r
d1102dba 159 if (!IsListEmpty(&Statement->Storage->NameValueListHead)) {\r
94f3aae7
ED
160 Link = GetFirstNode (&Statement->Storage->NameValueListHead);\r
161 while (!IsNull (&Statement->Storage->NameValueListHead, Link)) {\r
162 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
163\r
164 if (StrCmp (Statement->VariableName, NameValueNode->Name) == 0) {\r
165 Find = TRUE;\r
166 break;\r
167 }\r
168\r
169 Link = GetNextNode (&Statement->Storage->NameValueListHead, Link);\r
170 }\r
171 }\r
172\r
173 if (!Find) {\r
174 //\r
175 // Insert to Name/Value varstore list\r
176 //\r
177 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
178 ASSERT (NameValueNode != NULL);\r
179 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
180 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
181 ASSERT (NameValueNode->Name != NULL);\r
182 NameValueNode->Value = AllocateZeroPool (0x10);\r
183 ASSERT (NameValueNode->Value != NULL);\r
184 NameValueNode->EditValue = AllocateZeroPool (0x10);\r
185 ASSERT (NameValueNode->EditValue != NULL);\r
186\r
187 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
188 }\r
c60a0616 189 }\r
190 }\r
191\r
192 return Statement;\r
193}\r
194\r
195\r
196/**\r
197 Allocate a FORM_EXPRESSION node.\r
198\r
199 @param Form The Form associated with this Expression\r
bfae1330 200 @param OpCode The binary opcode data.\r
c60a0616 201\r
202 @return Pointer to a FORM_EXPRESSION data structure.\r
203\r
204**/\r
205FORM_EXPRESSION *\r
206CreateExpression (\r
bfae1330
ED
207 IN OUT FORM_BROWSER_FORM *Form,\r
208 IN UINT8 *OpCode\r
c60a0616 209 )\r
210{\r
211 FORM_EXPRESSION *Expression;\r
212\r
213 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1ac628ee 214 ASSERT (Expression != NULL);\r
c60a0616 215 Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
216 InitializeListHead (&Expression->OpCodeListHead);\r
bfae1330 217 Expression->OpCode = (EFI_IFR_OP_HEADER *) OpCode;\r
c60a0616 218\r
219 return Expression;\r
220}\r
221\r
c60a0616 222/**\r
223 Create ConfigHdr string for a storage.\r
224\r
225 @param FormSet Pointer of the current FormSet\r
226 @param Storage Pointer of the storage\r
227\r
228 @retval EFI_SUCCESS Initialize ConfigHdr success\r
229\r
230**/\r
231EFI_STATUS\r
232InitializeConfigHdr (\r
233 IN FORM_BROWSER_FORMSET *FormSet,\r
a35ecb75 234 IN OUT FORMSET_STORAGE *Storage\r
c60a0616 235 )\r
236{\r
c60a0616 237 CHAR16 *Name;\r
8b0fc5c1 238\r
d1102dba 239 if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||\r
a35ecb75
ED
240 Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
241 Name = Storage->BrowserStorage->Name;\r
c60a0616 242 } else {\r
243 Name = NULL;\r
244 }\r
8b0fc5c1 245\r
7e3bcccb 246 Storage->ConfigHdr = HiiConstructConfigHdr (\r
a35ecb75 247 &Storage->BrowserStorage->Guid,\r
7e3bcccb
LG
248 Name,\r
249 FormSet->DriverHandle\r
250 );\r
8b0fc5c1 251\r
7e3bcccb
LG
252 if (Storage->ConfigHdr == NULL) {\r
253 return EFI_NOT_FOUND;\r
c60a0616 254 }\r
255\r
c60a0616 256 return EFI_SUCCESS;\r
257}\r
258\r
94f3aae7
ED
259/**\r
260 Find the global storage link base on the input storate type, name and guid.\r
261\r
fae73624
ED
262 For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,\r
263 same guid + name = same storage\r
264\r
265 For EFI_HII_VARSTORE_NAME_VALUE:\r
266 same guid + HiiHandle = same storage\r
267\r
268 For EFI_HII_VARSTORE_BUFFER:\r
269 same guid + name + HiiHandle = same storage\r
270\r
94f3aae7
ED
271 @param StorageType Storage type.\r
272 @param StorageGuid Storage guid.\r
273 @param StorageName Storage Name.\r
fae73624 274 @param HiiHandle HiiHandle for this varstore.\r
94f3aae7
ED
275\r
276 @return Pointer to a GLOBAL_STORAGE data structure.\r
277\r
278**/\r
279BROWSER_STORAGE *\r
280FindStorageInList (\r
281 IN UINT8 StorageType,\r
282 IN EFI_GUID *StorageGuid,\r
fae73624
ED
283 IN CHAR16 *StorageName,\r
284 IN EFI_HII_HANDLE HiiHandle\r
94f3aae7
ED
285 )\r
286{\r
287 LIST_ENTRY *Link;\r
288 BROWSER_STORAGE *BrowserStorage;\r
289\r
290 Link = GetFirstNode (&gBrowserStorageList);\r
291 while (!IsNull (&gBrowserStorageList, Link)) {\r
292 BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);\r
0f83ac34 293 Link = GetNextNode (&gBrowserStorageList, Link);\r
94f3aae7
ED
294\r
295 if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {\r
0f83ac34
ED
296 if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {\r
297 if (BrowserStorage->HiiHandle == HiiHandle) {\r
298 return BrowserStorage;\r
299 }\r
300\r
301 continue;\r
94f3aae7
ED
302 }\r
303\r
0f83ac34 304 ASSERT (StorageName != NULL);\r
94f3aae7 305 if (StrCmp (BrowserStorage->Name, StorageName) == 0) {\r
fae73624
ED
306 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
307 return BrowserStorage;\r
308 } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {\r
309 return BrowserStorage;\r
310 }\r
94f3aae7
ED
311 }\r
312 }\r
94f3aae7
ED
313 }\r
314\r
315 return NULL;\r
316}\r
317\r
318/**\r
319 Intialize the Global Storage.\r
320\r
321 @param BrowserStorage Pointer to the global storage.\r
322 @param StorageType Storage type.\r
323 @param OpCodeData Binary data for this opcode.\r
324\r
325**/\r
326VOID\r
327IntializeBrowserStorage (\r
328 IN BROWSER_STORAGE *BrowserStorage,\r
329 IN UINT8 StorageType,\r
330 IN UINT8 *OpCodeData\r
331 )\r
332{\r
333 switch (StorageType) {\r
334 case EFI_HII_VARSTORE_BUFFER:\r
335 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
336 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
337\r
338 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);\r
339 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);\r
340 break;\r
341\r
342 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
343 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
344 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
345 CopyMem (&BrowserStorage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
346 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));\r
347\r
348 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
349 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);\r
350 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);\r
351 }\r
352 break;\r
353\r
354 case EFI_HII_VARSTORE_NAME_VALUE:\r
355 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
356\r
357 InitializeListHead (&BrowserStorage->NameValueListHead);\r
358 break;\r
359\r
360 default:\r
361 break;\r
362 }\r
363}\r
364\r
300c1f0d 365\r
94f3aae7
ED
366/**\r
367 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
368\r
369 @param FormSet Pointer of the current FormSet\r
370 @param StorageType Storage type.\r
371 @param OpCodeData Binary data for this opcode.\r
372\r
373 @return Pointer to a FORMSET_STORAGE data structure.\r
374\r
375**/\r
376FORMSET_STORAGE *\r
377CreateStorage (\r
378 IN FORM_BROWSER_FORMSET *FormSet,\r
379 IN UINT8 StorageType,\r
380 IN UINT8 *OpCodeData\r
381 )\r
382{\r
383 FORMSET_STORAGE *Storage;\r
384 CHAR16 *UnicodeString;\r
385 UINT16 Index;\r
386 BROWSER_STORAGE *BrowserStorage;\r
387 EFI_GUID *StorageGuid;\r
388 CHAR8 *StorageName;\r
389\r
390 UnicodeString = NULL;\r
391 StorageName = NULL;\r
392 switch (StorageType) {\r
393 case EFI_HII_VARSTORE_BUFFER:\r
394 StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE *) OpCodeData)->Guid;\r
395 StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
396 break;\r
397\r
398 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
399 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
400 StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid;\r
401 StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;\r
402 break;\r
403\r
404 default:\r
405 ASSERT (StorageType == EFI_HII_VARSTORE_NAME_VALUE);\r
406 StorageGuid = &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid;\r
407 break;\r
408 }\r
409\r
410 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {\r
411 ASSERT (StorageName != NULL);\r
412\r
413 UnicodeString = AllocateZeroPool (AsciiStrSize (StorageName) * 2);\r
414 ASSERT (UnicodeString != NULL);\r
415 for (Index = 0; StorageName[Index] != 0; Index++) {\r
416 UnicodeString[Index] = (CHAR16) StorageName[Index];\r
417 }\r
418 }\r
419\r
420 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
421 ASSERT (Storage != NULL);\r
422 Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
423 InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
424\r
fae73624 425 BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);\r
94f3aae7
ED
426 if (BrowserStorage == NULL) {\r
427 BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));\r
428 ASSERT (BrowserStorage != NULL);\r
429\r
430 BrowserStorage->Signature = BROWSER_STORAGE_SIGNATURE;\r
431 InsertTailList (&gBrowserStorageList, &BrowserStorage->Link);\r
432\r
433 IntializeBrowserStorage (BrowserStorage, StorageType, OpCodeData);\r
434 BrowserStorage->Type = StorageType;\r
435 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {\r
436 BrowserStorage->Name = UnicodeString;\r
437 }\r
438\r
fae73624 439 BrowserStorage->HiiHandle = FormSet->HiiHandle;\r
fae73624
ED
440\r
441 BrowserStorage->Initialized = FALSE;\r
94f3aae7 442 }\r
94f3aae7
ED
443\r
444 Storage->BrowserStorage = BrowserStorage;\r
a35ecb75
ED
445 InitializeConfigHdr (FormSet, Storage);\r
446 Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
94f3aae7
ED
447 Storage->SpareStrLen = 0;\r
448\r
449 return Storage;\r
450}\r
c60a0616 451\r
a35ecb75
ED
452/**\r
453 Get Formset_storage base on the input varstoreid info.\r
454\r
455 @param FormSet Pointer of the current FormSet.\r
456 @param VarStoreId Varstore ID info.\r
457\r
458 @return Pointer to a FORMSET_STORAGE data structure.\r
459\r
460**/\r
461FORMSET_STORAGE *\r
462GetFstStgFromVarId (\r
463 IN FORM_BROWSER_FORMSET *FormSet,\r
464 IN EFI_VARSTORE_ID VarStoreId\r
465 )\r
466{\r
467 FORMSET_STORAGE *FormsetStorage;\r
468 LIST_ENTRY *Link;\r
469 BOOLEAN Found;\r
470\r
471 Found = FALSE;\r
472 FormsetStorage = NULL;\r
473 //\r
474 // Find Formset Storage for this Question\r
475 //\r
476 Link = GetFirstNode (&FormSet->StorageListHead);\r
477 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
478 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
479\r
480 if (FormsetStorage->VarStoreId == VarStoreId) {\r
481 Found = TRUE;\r
482 break;\r
483 }\r
484\r
485 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
486 }\r
487\r
488 return Found ? FormsetStorage : NULL;\r
489}\r
490\r
491/**\r
492 Get Formset_storage base on the input browser storage.\r
493\r
494 More than one formsets may share the same browser storage,\r
495 this function just get the first formset storage which\r
496 share the browser storage.\r
497\r
498 @param Storage browser storage info.\r
499\r
500 @return Pointer to a FORMSET_STORAGE data structure.\r
d1102dba 501\r
a35ecb75
ED
502\r
503**/\r
504FORMSET_STORAGE *\r
505GetFstStgFromBrsStg (\r
506 IN BROWSER_STORAGE *Storage\r
507 )\r
508{\r
509 FORMSET_STORAGE *FormsetStorage;\r
510 LIST_ENTRY *Link;\r
511 LIST_ENTRY *FormsetLink;\r
512 FORM_BROWSER_FORMSET *FormSet;\r
513 BOOLEAN Found;\r
514\r
515 Found = FALSE;\r
516 FormsetStorage = NULL;\r
517\r
518 FormsetLink = GetFirstNode (&gBrowserFormSetList);\r
519 while (!IsNull (&gBrowserFormSetList, FormsetLink)) {\r
520 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink);\r
521 FormsetLink = GetNextNode (&gBrowserFormSetList, FormsetLink);\r
522\r
523 Link = GetFirstNode (&FormSet->StorageListHead);\r
524 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
525 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
526 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
527\r
528 if (FormsetStorage->BrowserStorage == Storage) {\r
529 Found = TRUE;\r
530 break;\r
531 }\r
532 }\r
533\r
534 if (Found) {\r
535 break;\r
536 }\r
537 }\r
538\r
539 return Found ? FormsetStorage : NULL;\r
540}\r
541\r
c60a0616 542/**\r
543 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
544\r
545 @param FormSet Pointer of the current FormSet.\r
546 @param Question The Question to be initialized.\r
b18e7050 547 @param Form Pointer of the current form.\r
c60a0616 548\r
549 @retval EFI_SUCCESS Function success.\r
550 @retval EFI_INVALID_PARAMETER No storage associated with the Question.\r
551\r
552**/\r
553EFI_STATUS\r
554InitializeRequestElement (\r
555 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
b18e7050
ED
556 IN OUT FORM_BROWSER_STATEMENT *Question,\r
557 IN OUT FORM_BROWSER_FORM *Form\r
c60a0616 558 )\r
559{\r
94f3aae7
ED
560 BROWSER_STORAGE *Storage;\r
561 FORMSET_STORAGE *FormsetStorage;\r
c60a0616 562 UINTN StrLen;\r
563 UINTN StringSize;\r
564 CHAR16 *NewStr;\r
565 CHAR16 RequestElement[30];\r
b18e7050
ED
566 LIST_ENTRY *Link;\r
567 BOOLEAN Find;\r
568 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
5ad66ec6 569 UINTN MaxLen;\r
c60a0616 570\r
571 Storage = Question->Storage;\r
572 if (Storage == NULL) {\r
573 return EFI_INVALID_PARAMETER;\r
574 }\r
575\r
576 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
577 //\r
578 // <ConfigRequest> is unnecessary for EFI variable storage,\r
579 // GetVariable()/SetVariable() will be used to retrieve/save values\r
580 //\r
581 return EFI_SUCCESS;\r
582 }\r
583\r
584 //\r
585 // Prepare <RequestElement>\r
586 //\r
d1102dba 587 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||\r
cce6230f 588 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
c60a0616 589 StrLen = UnicodeSPrint (\r
590 RequestElement,\r
591 30 * sizeof (CHAR16),\r
7a9612ce 592 L"&OFFSET=%04x&WIDTH=%04x",\r
c60a0616 593 Question->VarStoreInfo.VarOffset,\r
594 Question->StorageWidth\r
595 );\r
a0973dcb 596 HiiToLower(RequestElement);\r
c60a0616 597 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
598 } else {\r
599 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
600 }\r
601\r
602 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {\r
603 //\r
604 // Password with CALLBACK flag is stored in encoded format,\r
605 // so don't need to append it to <ConfigRequest>\r
606 //\r
607 return EFI_SUCCESS;\r
608 }\r
609\r
94f3aae7
ED
610 //\r
611 // Find Formset Storage for this Question\r
612 //\r
a35ecb75 613 FormsetStorage = GetFstStgFromVarId(FormSet, Question->VarStoreId);\r
94f3aae7 614 ASSERT (FormsetStorage != NULL);\r
5ad66ec6
DB
615 StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
616 MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;\r
94f3aae7 617\r
c60a0616 618 //\r
619 // Append <RequestElement> to <ConfigRequest>\r
620 //\r
94f3aae7 621 if (StrLen > FormsetStorage->SpareStrLen) {\r
c60a0616 622 //\r
623 // Old String buffer is not sufficient for RequestElement, allocate a new one\r
624 //\r
5ad66ec6
DB
625 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
626 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
1ac628ee 627 ASSERT (NewStr != NULL);\r
94f3aae7
ED
628 if (FormsetStorage->ConfigRequest != NULL) {\r
629 CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);\r
630 FreePool (FormsetStorage->ConfigRequest);\r
c60a0616 631 }\r
94f3aae7
ED
632 FormsetStorage->ConfigRequest = NewStr;\r
633 FormsetStorage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
c60a0616 634 }\r
635\r
5ad66ec6 636 StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);\r
94f3aae7
ED
637 FormsetStorage->ElementCount++;\r
638 FormsetStorage->SpareStrLen -= StrLen;\r
c60a0616 639\r
b18e7050
ED
640 //\r
641 // Update the Config Request info saved in the form.\r
642 //\r
643 ConfigInfo = NULL;\r
644 Find = FALSE;\r
645 Link = GetFirstNode (&Form->ConfigRequestHead);\r
646 while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
647 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
648\r
a35ecb75 649 if (ConfigInfo != NULL && ConfigInfo->Storage == FormsetStorage->BrowserStorage) {\r
b18e7050
ED
650 Find = TRUE;\r
651 break;\r
652 }\r
653\r
654 Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
655 }\r
656\r
657 if (!Find) {\r
658 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));\r
0194d26c 659 ASSERT (ConfigInfo != NULL);\r
b18e7050 660 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;\r
a35ecb75 661 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (FormsetStorage->ConfigHdr), FormsetStorage->ConfigHdr);\r
523f48e7 662 ASSERT (ConfigInfo->ConfigRequest != NULL);\r
b18e7050 663 ConfigInfo->SpareStrLen = 0;\r
a35ecb75 664 ConfigInfo->Storage = FormsetStorage->BrowserStorage;\r
b18e7050
ED
665 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);\r
666 }\r
5ad66ec6
DB
667 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
668 MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;\r
b18e7050
ED
669\r
670 //\r
671 // Append <RequestElement> to <ConfigRequest>\r
672 //\r
673 if (StrLen > ConfigInfo->SpareStrLen) {\r
674 //\r
675 // Old String buffer is not sufficient for RequestElement, allocate a new one\r
676 //\r
5ad66ec6
DB
677 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
678 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
b18e7050
ED
679 ASSERT (NewStr != NULL);\r
680 if (ConfigInfo->ConfigRequest != NULL) {\r
681 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);\r
682 FreePool (ConfigInfo->ConfigRequest);\r
683 }\r
684 ConfigInfo->ConfigRequest = NewStr;\r
685 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
686 }\r
687\r
5ad66ec6 688 StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);\r
b18e7050
ED
689 ConfigInfo->ElementCount++;\r
690 ConfigInfo->SpareStrLen -= StrLen;\r
c60a0616 691 return EFI_SUCCESS;\r
692}\r
693\r
694\r
695/**\r
696 Free resources of a Expression.\r
697\r
698 @param FormSet Pointer of the Expression\r
699\r
700**/\r
701VOID\r
702DestroyExpression (\r
703 IN FORM_EXPRESSION *Expression\r
704 )\r
705{\r
706 LIST_ENTRY *Link;\r
707 EXPRESSION_OPCODE *OpCode;\r
2573712e
LG
708 LIST_ENTRY *SubExpressionLink;\r
709 FORM_EXPRESSION *SubExpression;\r
c60a0616 710\r
711 while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
712 Link = GetFirstNode (&Expression->OpCodeListHead);\r
713 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
714 RemoveEntryList (&OpCode->Link);\r
715\r
716 if (OpCode->ValueList != NULL) {\r
717 FreePool (OpCode->ValueList);\r
718 }\r
2573712e
LG
719\r
720 if (OpCode->ValueName != NULL) {\r
721 FreePool (OpCode->ValueName);\r
722 }\r
723\r
724 if (OpCode->MapExpressionList.ForwardLink != NULL) {\r
725 while (!IsListEmpty (&OpCode->MapExpressionList)) {\r
726 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r
727 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
728 RemoveEntryList(&SubExpression->Link);\r
729 DestroyExpression (SubExpression);\r
730 }\r
731 }\r
c60a0616 732 }\r
733\r
734 //\r
735 // Free this Expression\r
736 //\r
f4113e1f 737 FreePool (Expression);\r
c60a0616 738}\r
739\r
c60a0616 740/**\r
741 Free resources of a storage.\r
742\r
743 @param Storage Pointer of the storage\r
744\r
745**/\r
746VOID\r
747DestroyStorage (\r
748 IN FORMSET_STORAGE *Storage\r
749 )\r
750{\r
c60a0616 751 if (Storage == NULL) {\r
752 return;\r
753 }\r
754\r
c60a0616 755 if (Storage->ConfigRequest != NULL) {\r
756 FreePool (Storage->ConfigRequest);\r
757 }\r
758\r
759 FreePool (Storage);\r
760}\r
761\r
762\r
763/**\r
764 Free resources of a Statement.\r
765\r
e2100bfa 766 @param FormSet Pointer of the FormSet\r
c60a0616 767 @param Statement Pointer of the Statement\r
768\r
769**/\r
770VOID\r
771DestroyStatement (\r
e2100bfa 772 IN FORM_BROWSER_FORMSET *FormSet,\r
c60a0616 773 IN OUT FORM_BROWSER_STATEMENT *Statement\r
774 )\r
775{\r
776 LIST_ENTRY *Link;\r
777 QUESTION_DEFAULT *Default;\r
778 QUESTION_OPTION *Option;\r
779 FORM_EXPRESSION *Expression;\r
780\r
781 //\r
782 // Free Default value List\r
783 //\r
784 while (!IsListEmpty (&Statement->DefaultListHead)) {\r
785 Link = GetFirstNode (&Statement->DefaultListHead);\r
786 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
787 RemoveEntryList (&Default->Link);\r
788\r
0b567d18
ED
789 if (Default->Value.Buffer != NULL) {\r
790 FreePool (Default->Value.Buffer);\r
791 }\r
f4113e1f 792 FreePool (Default);\r
c60a0616 793 }\r
794\r
795 //\r
796 // Free Options List\r
797 //\r
798 while (!IsListEmpty (&Statement->OptionListHead)) {\r
799 Link = GetFirstNode (&Statement->OptionListHead);\r
800 Option = QUESTION_OPTION_FROM_LINK (Link);\r
31585af4
ED
801 if (Option->SuppressExpression != NULL) {\r
802 FreePool (Option->SuppressExpression);\r
803 }\r
c60a0616 804 RemoveEntryList (&Option->Link);\r
805\r
f4113e1f 806 FreePool (Option);\r
c60a0616 807 }\r
808\r
809 //\r
810 // Free Inconsistent List\r
811 //\r
812 while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
813 Link = GetFirstNode (&Statement->InconsistentListHead);\r
814 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
815 RemoveEntryList (&Expression->Link);\r
816\r
817 DestroyExpression (Expression);\r
818 }\r
819\r
820 //\r
821 // Free NoSubmit List\r
822 //\r
823 while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
824 Link = GetFirstNode (&Statement->NoSubmitListHead);\r
825 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
826 RemoveEntryList (&Expression->Link);\r
827\r
828 DestroyExpression (Expression);\r
829 }\r
830\r
1c0d306f
ED
831 //\r
832 // Free WarningIf List\r
833 //\r
834 while (!IsListEmpty (&Statement->WarningListHead)) {\r
835 Link = GetFirstNode (&Statement->WarningListHead);\r
836 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
837 RemoveEntryList (&Expression->Link);\r
838\r
839 DestroyExpression (Expression);\r
840 }\r
841\r
31585af4
ED
842 if (Statement->Expression != NULL) {\r
843 FreePool (Statement->Expression);\r
844 }\r
845\r
c60a0616 846 if (Statement->VariableName != NULL) {\r
847 FreePool (Statement->VariableName);\r
848 }\r
849 if (Statement->BlockName != NULL) {\r
850 FreePool (Statement->BlockName);\r
851 }\r
b86b413a
LG
852 if (Statement->BufferValue != NULL) {\r
853 FreePool (Statement->BufferValue);\r
854 }\r
e2100bfa
ED
855 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {\r
856 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);\r
857 }\r
c60a0616 858}\r
859\r
860\r
861/**\r
862 Free resources of a Form.\r
863\r
e2100bfa 864 @param FormSet Pointer of the FormSet\r
c60a0616 865 @param Form Pointer of the Form.\r
866\r
867**/\r
868VOID\r
869DestroyForm (\r
e2100bfa
ED
870 IN FORM_BROWSER_FORMSET *FormSet,\r
871 IN OUT FORM_BROWSER_FORM *Form\r
c60a0616 872 )\r
873{\r
874 LIST_ENTRY *Link;\r
875 FORM_EXPRESSION *Expression;\r
876 FORM_BROWSER_STATEMENT *Statement;\r
b18e7050 877 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
c60a0616 878\r
879 //\r
880 // Free Form Expressions\r
881 //\r
882 while (!IsListEmpty (&Form->ExpressionListHead)) {\r
883 Link = GetFirstNode (&Form->ExpressionListHead);\r
884 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
885 RemoveEntryList (&Expression->Link);\r
886\r
887 DestroyExpression (Expression);\r
888 }\r
889\r
890 //\r
891 // Free Statements/Questions\r
892 //\r
893 while (!IsListEmpty (&Form->StatementListHead)) {\r
894 Link = GetFirstNode (&Form->StatementListHead);\r
895 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
896 RemoveEntryList (&Statement->Link);\r
897\r
e2100bfa 898 DestroyStatement (FormSet, Statement);\r
c60a0616 899 }\r
900\r
b18e7050
ED
901 //\r
902 // Free ConfigRequest string.\r
903 //\r
904 while (!IsListEmpty (&Form->ConfigRequestHead)) {\r
905 Link = GetFirstNode (&Form->ConfigRequestHead);\r
906 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
907 RemoveEntryList (&ConfigInfo->Link);\r
908\r
909 FreePool (ConfigInfo->ConfigRequest);\r
910 FreePool (ConfigInfo);\r
911 }\r
912\r
31585af4
ED
913 if (Form->SuppressExpression != NULL) {\r
914 FreePool (Form->SuppressExpression);\r
915 }\r
916\r
4d4deaac
ED
917 UiFreeMenuList (&Form->FormViewListHead);\r
918\r
c60a0616 919 //\r
920 // Free this Form\r
921 //\r
f4113e1f 922 FreePool (Form);\r
c60a0616 923}\r
924\r
925\r
926/**\r
927 Free resources allocated for a FormSet.\r
928\r
929 @param FormSet Pointer of the FormSet\r
930\r
931**/\r
932VOID\r
933DestroyFormSet (\r
934 IN OUT FORM_BROWSER_FORMSET *FormSet\r
935 )\r
936{\r
937 LIST_ENTRY *Link;\r
938 FORMSET_STORAGE *Storage;\r
939 FORMSET_DEFAULTSTORE *DefaultStore;\r
0c66bc76 940 FORM_EXPRESSION *Expression;\r
c60a0616 941 FORM_BROWSER_FORM *Form;\r
942\r
4c8358c7 943 if (FormSet->IfrBinaryData == NULL) {\r
944 //\r
945 // Uninitialized FormSet\r
946 //\r
947 FreePool (FormSet);\r
948 return;\r
949 }\r
950\r
c60a0616 951 //\r
952 // Free IFR binary buffer\r
953 //\r
954 FreePool (FormSet->IfrBinaryData);\r
955\r
956 //\r
957 // Free FormSet Storage\r
958 //\r
959 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
960 while (!IsListEmpty (&FormSet->StorageListHead)) {\r
961 Link = GetFirstNode (&FormSet->StorageListHead);\r
962 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
963 RemoveEntryList (&Storage->Link);\r
964\r
965 DestroyStorage (Storage);\r
966 }\r
967 }\r
968\r
969 //\r
970 // Free FormSet Default Store\r
971 //\r
972 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
973 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
974 Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
975 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
976 RemoveEntryList (&DefaultStore->Link);\r
977\r
f4113e1f 978 FreePool (DefaultStore);\r
c60a0616 979 }\r
980 }\r
981\r
0c66bc76
LG
982 //\r
983 // Free Formset Expressions\r
984 //\r
985 while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
986 Link = GetFirstNode (&FormSet->ExpressionListHead);\r
987 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
988 RemoveEntryList (&Expression->Link);\r
989\r
990 DestroyExpression (Expression);\r
991 }\r
992\r
c60a0616 993 //\r
994 // Free Forms\r
995 //\r
996 if (FormSet->FormListHead.ForwardLink != NULL) {\r
997 while (!IsListEmpty (&FormSet->FormListHead)) {\r
998 Link = GetFirstNode (&FormSet->FormListHead);\r
999 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
1000 RemoveEntryList (&Form->Link);\r
1001\r
e2100bfa 1002 DestroyForm (FormSet, Form);\r
c60a0616 1003 }\r
1004 }\r
1005\r
1006 if (FormSet->StatementBuffer != NULL) {\r
1007 FreePool (FormSet->StatementBuffer);\r
1008 }\r
1009 if (FormSet->ExpressionBuffer != NULL) {\r
1010 FreePool (FormSet->ExpressionBuffer);\r
1011 }\r
1012\r
1013 FreePool (FormSet);\r
1014}\r
1015\r
1016\r
1017/**\r
1018 Tell whether this Operand is an Expression OpCode or not\r
1019\r
1020 @param Operand Operand of an IFR OpCode.\r
1021\r
1022 @retval TRUE This is an Expression OpCode.\r
1023 @retval FALSE Not an Expression OpCode.\r
1024\r
1025**/\r
1026BOOLEAN\r
1027IsExpressionOpCode (\r
1028 IN UINT8 Operand\r
1029 )\r
1030{\r
1031 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
2573712e
LG
1032 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||\r
1033 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
c60a0616 1034 (Operand == EFI_IFR_CATENATE_OP) ||\r
1035 (Operand == EFI_IFR_TO_LOWER_OP) ||\r
1036 (Operand == EFI_IFR_TO_UPPER_OP) ||\r
2573712e 1037 (Operand == EFI_IFR_MAP_OP) ||\r
cbf73e50 1038 (Operand == EFI_IFR_VERSION_OP) ||\r
9bd22b08
ED
1039 (Operand == EFI_IFR_SECURITY_OP) ||\r
1040 (Operand == EFI_IFR_MATCH2_OP)) {\r
c60a0616 1041 return TRUE;\r
1042 } else {\r
1043 return FALSE;\r
1044 }\r
1045}\r
1046\r
077c7aee
ED
1047/**\r
1048 Tell whether this Operand is an Statement OpCode.\r
1049\r
1050 @param Operand Operand of an IFR OpCode.\r
1051\r
1052 @retval TRUE This is an Statement OpCode.\r
1053 @retval FALSE Not an Statement OpCode.\r
1054\r
1055**/\r
1056BOOLEAN\r
1057IsStatementOpCode (\r
1058 IN UINT8 Operand\r
1059 )\r
1060{\r
1061 if ((Operand == EFI_IFR_SUBTITLE_OP) ||\r
1062 (Operand == EFI_IFR_TEXT_OP) ||\r
1063 (Operand == EFI_IFR_RESET_BUTTON_OP) ||\r
1064 (Operand == EFI_IFR_REF_OP) ||\r
1065 (Operand == EFI_IFR_ACTION_OP) ||\r
1066 (Operand == EFI_IFR_NUMERIC_OP) ||\r
1067 (Operand == EFI_IFR_ORDERED_LIST_OP) ||\r
1068 (Operand == EFI_IFR_CHECKBOX_OP) ||\r
1069 (Operand == EFI_IFR_STRING_OP) ||\r
1070 (Operand == EFI_IFR_PASSWORD_OP) ||\r
1071 (Operand == EFI_IFR_DATE_OP) ||\r
1072 (Operand == EFI_IFR_TIME_OP) ||\r
1073 (Operand == EFI_IFR_GUID_OP) ||\r
1074 (Operand == EFI_IFR_ONE_OF_OP)) {\r
1075 return TRUE;\r
1076 } else {\r
1077 return FALSE;\r
1078 }\r
1079}\r
c60a0616 1080\r
7e2f3289
ED
1081/**\r
1082 Tell whether this Operand is an known OpCode.\r
1083\r
1084 @param Operand Operand of an IFR OpCode.\r
1085\r
1086 @retval TRUE This is an Statement OpCode.\r
1087 @retval FALSE Not an Statement OpCode.\r
1088\r
1089**/\r
1090BOOLEAN\r
1091IsUnKnownOpCode (\r
1092 IN UINT8 Operand\r
1093 )\r
1094{\r
9bd22b08 1095 return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;\r
7e2f3289
ED
1096}\r
1097\r
c60a0616 1098/**\r
1099 Calculate number of Statemens(Questions) and Expression OpCodes.\r
1100\r
1101 @param FormSet The FormSet to be counted.\r
1102 @param NumberOfStatement Number of Statemens(Questions)\r
1103 @param NumberOfExpression Number of Expression OpCodes\r
1104\r
1105**/\r
1106VOID\r
1107CountOpCodes (\r
1108 IN FORM_BROWSER_FORMSET *FormSet,\r
94057f74
BH
1109 OUT UINTN *NumberOfStatement,\r
1110 OUT UINTN *NumberOfExpression\r
c60a0616 1111 )\r
1112{\r
94057f74
BH
1113 UINTN StatementCount;\r
1114 UINTN ExpressionCount;\r
c60a0616 1115 UINT8 *OpCodeData;\r
1116 UINTN Offset;\r
1117 UINTN OpCodeLen;\r
1118\r
1119 Offset = 0;\r
1120 StatementCount = 0;\r
1121 ExpressionCount = 0;\r
1122\r
1123 while (Offset < FormSet->IfrBinaryLength) {\r
1124 OpCodeData = FormSet->IfrBinaryData + Offset;\r
1125 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
1126 Offset += OpCodeLen;\r
1127\r
1128 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
1129 ExpressionCount++;\r
1130 } else {\r
1131 StatementCount++;\r
1132 }\r
1133 }\r
1134\r
1135 *NumberOfStatement = StatementCount;\r
1136 *NumberOfExpression = ExpressionCount;\r
1137}\r
1138\r
1139\r
1140\r
1141/**\r
1142 Parse opcodes in the formset IFR binary.\r
1143\r
1144 @param FormSet Pointer of the FormSet data structure.\r
1145\r
1146 @retval EFI_SUCCESS Opcode parse success.\r
1147 @retval Other Opcode parse fail.\r
1148\r
1149**/\r
1150EFI_STATUS\r
1151ParseOpCodes (\r
1152 IN FORM_BROWSER_FORMSET *FormSet\r
1153 )\r
1154{\r
1155 EFI_STATUS Status;\r
c60a0616 1156 FORM_BROWSER_FORM *CurrentForm;\r
1157 FORM_BROWSER_STATEMENT *CurrentStatement;\r
077c7aee 1158 FORM_BROWSER_STATEMENT *ParentStatement;\r
c60a0616 1159 EXPRESSION_OPCODE *ExpressionOpCode;\r
1160 FORM_EXPRESSION *CurrentExpression;\r
1161 UINT8 Operand;\r
1162 UINT8 Scope;\r
1163 UINTN OpCodeOffset;\r
1164 UINTN OpCodeLength;\r
1165 UINT8 *OpCodeData;\r
1166 UINT8 ScopeOpCode;\r
1167 FORMSET_STORAGE *Storage;\r
1168 FORMSET_DEFAULTSTORE *DefaultStore;\r
1169 QUESTION_DEFAULT *CurrentDefault;\r
1170 QUESTION_OPTION *CurrentOption;\r
d02847d3 1171 UINT8 Width;\r
94057f74
BH
1172 UINTN NumberOfStatement;\r
1173 UINTN NumberOfExpression;\r
c60a0616 1174 EFI_IMAGE_ID *ImageId;\r
0c66bc76 1175 BOOLEAN SuppressForQuestion;\r
c60a0616 1176 BOOLEAN SuppressForOption;\r
c60a0616 1177 UINT16 DepthOfDisable;\r
1178 BOOLEAN OpCodeDisabled;\r
1179 BOOLEAN SingleOpCodeExpression;\r
1180 BOOLEAN InScopeDefault;\r
1181 EFI_HII_VALUE *Value;\r
2573712e
LG
1182 EFI_IFR_FORM_MAP_METHOD *MapMethod;\r
1183 UINT8 MapScopeDepth;\r
1184 LIST_ENTRY *Link;\r
1185 FORMSET_STORAGE *VarStorage;\r
1186 LIST_ENTRY *MapExpressionList;\r
1187 EFI_VARSTORE_ID TempVarstoreId;\r
31585af4
ED
1188 BOOLEAN InScopeDisable;\r
1189 INTN ConditionalExprCount;\r
7e2f3289
ED
1190 BOOLEAN InUnknownScope;\r
1191 UINT8 UnknownDepth;\r
75596726
DB
1192 FORMSET_DEFAULTSTORE *PreDefaultStore;\r
1193 LIST_ENTRY *DefaultLink;\r
1194 BOOLEAN HaveInserted;\r
560a435d
DB
1195 UINT16 TotalBits;\r
1196 BOOLEAN QuestionReferBitField;\r
c60a0616 1197\r
0c66bc76 1198 SuppressForQuestion = FALSE;\r
c60a0616 1199 SuppressForOption = FALSE;\r
31585af4 1200 InScopeDisable = FALSE;\r
c60a0616 1201 DepthOfDisable = 0;\r
1202 OpCodeDisabled = FALSE;\r
1203 SingleOpCodeExpression = FALSE;\r
1204 InScopeDefault = FALSE;\r
1205 CurrentExpression = NULL;\r
1206 CurrentDefault = NULL;\r
1207 CurrentOption = NULL;\r
c410589e 1208 ImageId = NULL;\r
2573712e
LG
1209 MapMethod = NULL;\r
1210 MapScopeDepth = 0;\r
1211 Link = NULL;\r
1212 VarStorage = NULL;\r
1213 MapExpressionList = NULL;\r
1214 TempVarstoreId = 0;\r
31585af4 1215 ConditionalExprCount = 0;\r
7e2f3289
ED
1216 InUnknownScope = FALSE;\r
1217 UnknownDepth = 0;\r
560a435d 1218 QuestionReferBitField = FALSE;\r
c60a0616 1219\r
1220 //\r
1221 // Get the number of Statements and Expressions\r
1222 //\r
1223 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
1224\r
1225 mStatementIndex = 0;\r
7c6c064c 1226 mUsedQuestionId = 1;\r
c60a0616 1227 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
1228 if (FormSet->StatementBuffer == NULL) {\r
1229 return EFI_OUT_OF_RESOURCES;\r
1230 }\r
1231\r
1232 mExpressionOpCodeIndex = 0;\r
1233 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
1234 if (FormSet->ExpressionBuffer == NULL) {\r
1235 return EFI_OUT_OF_RESOURCES;\r
1236 }\r
1237\r
7c6c064c 1238 InitializeListHead (&FormSet->StatementListOSF);\r
c60a0616 1239 InitializeListHead (&FormSet->StorageListHead);\r
4d4deaac 1240 InitializeListHead (&FormSet->SaveFailStorageListHead);\r
c60a0616 1241 InitializeListHead (&FormSet->DefaultStoreListHead);\r
1242 InitializeListHead (&FormSet->FormListHead);\r
48a9d5f7 1243 InitializeListHead (&FormSet->ExpressionListHead);\r
2573712e
LG
1244 ResetCurrentExpressionStack ();\r
1245 ResetMapExpressionListStack ();\r
c60a0616 1246\r
1247 CurrentForm = NULL;\r
1248 CurrentStatement = NULL;\r
077c7aee 1249 ParentStatement = NULL;\r
c60a0616 1250\r
1251 ResetScopeStack ();\r
1252\r
1253 OpCodeOffset = 0;\r
1254 while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
1255 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
1256\r
1257 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
1258 OpCodeOffset += OpCodeLength;\r
1259 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
1260 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
1261\r
7e2f3289
ED
1262 if (InUnknownScope) {\r
1263 if (Operand == EFI_IFR_END_OP) {\r
1264 UnknownDepth --;\r
1265\r
1266 if (UnknownDepth == 0) {\r
1267 InUnknownScope = FALSE;\r
1268 }\r
1269 } else {\r
1270 if (Scope != 0) {\r
1271 UnknownDepth ++;\r
1272 }\r
1273 }\r
1274\r
1275 continue;\r
1276 }\r
1277\r
1278 if (IsUnKnownOpCode(Operand)) {\r
1279 if (Scope != 0) {\r
1280 InUnknownScope = TRUE;\r
1281 UnknownDepth ++;\r
1282 }\r
1283\r
1284 continue;\r
1285 }\r
1286\r
c60a0616 1287 //\r
1288 // If scope bit set, push onto scope stack\r
1289 //\r
1290 if (Scope != 0) {\r
1291 PushScope (Operand);\r
1292 }\r
1293\r
1294 if (OpCodeDisabled) {\r
1295 //\r
1296 // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
1297 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
1298 //\r
1299 if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
1300 DepthOfDisable++;\r
1301 } else if (Operand == EFI_IFR_END_OP) {\r
1302 Status = PopScope (&ScopeOpCode);\r
1303 if (EFI_ERROR (Status)) {\r
1304 return Status;\r
1305 }\r
1306\r
1307 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
1308 if (DepthOfDisable == 0) {\r
31585af4 1309 InScopeDisable = FALSE;\r
c60a0616 1310 OpCodeDisabled = FALSE;\r
1311 } else {\r
1312 DepthOfDisable--;\r
1313 }\r
1314 }\r
1315 }\r
1316 continue;\r
1317 }\r
1318\r
1319 if (IsExpressionOpCode (Operand)) {\r
1320 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
1321 mExpressionOpCodeIndex++;\r
1322\r
1323 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
1324 ExpressionOpCode->Operand = Operand;\r
1325 Value = &ExpressionOpCode->Value;\r
1326\r
1327 switch (Operand) {\r
1328 case EFI_IFR_EQ_ID_VAL_OP:\r
1329 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1330\r
1331 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1332 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
1333 break;\r
1334\r
1335 case EFI_IFR_EQ_ID_ID_OP:\r
1336 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
1337 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
1338 break;\r
1339\r
e8ef4283 1340 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
2654f642 1341 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1342 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
1343 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
c60a0616 1344 break;\r
1345\r
1346 case EFI_IFR_TO_STRING_OP:\r
1347 case EFI_IFR_FIND_OP:\r
1348 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
1349 break;\r
1350\r
1351 case EFI_IFR_STRING_REF1_OP:\r
1352 Value->Type = EFI_IFR_TYPE_STRING;\r
1353 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
1354 break;\r
1355\r
1356 case EFI_IFR_RULE_REF_OP:\r
1357 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
1358 break;\r
1359\r
1360 case EFI_IFR_SPAN_OP:\r
1361 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
1362 break;\r
1363\r
1364 case EFI_IFR_THIS_OP:\r
077c7aee
ED
1365 ASSERT (ParentStatement != NULL);\r
1366 ExpressionOpCode->QuestionId = ParentStatement->QuestionId;\r
c60a0616 1367 break;\r
1368\r
cbf73e50 1369 case EFI_IFR_SECURITY_OP:\r
1370 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r
1371 break;\r
1372\r
9bd22b08
ED
1373 case EFI_IFR_MATCH2_OP:\r
1374 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));\r
1375 break;\r
1376\r
2573712e
LG
1377 case EFI_IFR_GET_OP:\r
1378 case EFI_IFR_SET_OP:\r
1379 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r
1380 if (TempVarstoreId != 0) {\r
1381 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
1382 Link = GetFirstNode (&FormSet->StorageListHead);\r
1383 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
1384 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
1385 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {\r
94f3aae7 1386 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;\r
2573712e
LG
1387 break;\r
1388 }\r
1389 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
1390 }\r
1391 }\r
1392 if (ExpressionOpCode->VarStorage == NULL) {\r
1393 //\r
1394 // VarStorage is not found.\r
1395 //\r
1396 return EFI_INVALID_PARAMETER;\r
1397 }\r
1398 }\r
1399 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;\r
1400 switch (ExpressionOpCode->ValueType) {\r
1401 case EFI_IFR_TYPE_BOOLEAN:\r
d1102dba 1402 case EFI_IFR_TYPE_NUM_SIZE_8:\r
2573712e
LG
1403 ExpressionOpCode->ValueWidth = 1;\r
1404 break;\r
1405\r
1406 case EFI_IFR_TYPE_NUM_SIZE_16:\r
1407 case EFI_IFR_TYPE_STRING:\r
1408 ExpressionOpCode->ValueWidth = 2;\r
1409 break;\r
1410\r
1411 case EFI_IFR_TYPE_NUM_SIZE_32:\r
1412 ExpressionOpCode->ValueWidth = 4;\r
1413 break;\r
1414\r
1415 case EFI_IFR_TYPE_NUM_SIZE_64:\r
1416 ExpressionOpCode->ValueWidth = 8;\r
1417 break;\r
1418\r
1419 case EFI_IFR_TYPE_DATE:\r
c9325700 1420 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);\r
2573712e
LG
1421 break;\r
1422\r
1423 case EFI_IFR_TYPE_TIME:\r
c9325700 1424 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);\r
2573712e
LG
1425 break;\r
1426\r
8ca6180f
ED
1427 case EFI_IFR_TYPE_REF:\r
1428 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);\r
1429 break;\r
1430\r
2573712e
LG
1431 case EFI_IFR_TYPE_OTHER:\r
1432 case EFI_IFR_TYPE_UNDEFINED:\r
1433 case EFI_IFR_TYPE_ACTION:\r
1434 case EFI_IFR_TYPE_BUFFER:\r
1435 default:\r
1436 //\r
1437 // Invalid value type for Get/Set opcode.\r
1438 //\r
1439 return EFI_INVALID_PARAMETER;\r
1440 }\r
1441 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));\r
1442 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));\r
d1102dba
LG
1443 if ((ExpressionOpCode->VarStorage != NULL) &&\r
1444 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||\r
2573712e
LG
1445 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
1446 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);\r
1447 if (ExpressionOpCode->ValueName == NULL) {\r
1448 //\r
1449 // String ID is invalid.\r
1450 //\r
1451 return EFI_INVALID_PARAMETER;\r
1452 }\r
1453 }\r
1454 break;\r
1455\r
c60a0616 1456 case EFI_IFR_QUESTION_REF1_OP:\r
2654f642 1457 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 1458 break;\r
1459\r
1460 case EFI_IFR_QUESTION_REF3_OP:\r
1461 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
1462 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1463\r
1464 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
1465 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1466 }\r
1467 }\r
1468 break;\r
1469\r
1470 //\r
1471 // constant\r
1472 //\r
1473 case EFI_IFR_TRUE_OP:\r
1474 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1475 Value->Value.b = TRUE;\r
1476 break;\r
1477\r
1478 case EFI_IFR_FALSE_OP:\r
1479 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1480 Value->Value.b = FALSE;\r
1481 break;\r
1482\r
1483 case EFI_IFR_ONE_OP:\r
1484 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1485 Value->Value.u8 = 1;\r
1486 break;\r
1487\r
1488 case EFI_IFR_ZERO_OP:\r
1489 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1490 Value->Value.u8 = 0;\r
1491 break;\r
1492\r
1493 case EFI_IFR_ONES_OP:\r
1494 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1495 Value->Value.u64 = 0xffffffffffffffffULL;\r
1496 break;\r
1497\r
1498 case EFI_IFR_UINT8_OP:\r
1499 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1500 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
1501 break;\r
1502\r
1503 case EFI_IFR_UINT16_OP:\r
1504 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1505 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
1506 break;\r
1507\r
1508 case EFI_IFR_UINT32_OP:\r
1509 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1510 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
1511 break;\r
1512\r
1513 case EFI_IFR_UINT64_OP:\r
1514 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1515 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
1516 break;\r
1517\r
1518 case EFI_IFR_UNDEFINED_OP:\r
d02847d3 1519 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
c60a0616 1520 break;\r
1521\r
1522 case EFI_IFR_VERSION_OP:\r
1523 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1524 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
1525 break;\r
1526\r
1527 default:\r
1528 break;\r
1529 }\r
2573712e
LG
1530 //\r
1531 // Create sub expression nested in MAP opcode\r
1532 //\r
1533 if (CurrentExpression == NULL && MapScopeDepth > 0) {\r
bfae1330 1534 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
771ececd 1535 ASSERT (MapExpressionList != NULL);\r
2573712e
LG
1536 InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
1537 if (Scope == 0) {\r
1538 SingleOpCodeExpression = TRUE;\r
1539 }\r
1540 }\r
f8a1c229 1541 ASSERT (CurrentExpression != NULL);\r
c60a0616 1542 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
2573712e
LG
1543 if (Operand == EFI_IFR_MAP_OP) {\r
1544 //\r
1545 // Store current Map Expression List.\r
1546 //\r
1547 if (MapExpressionList != NULL) {\r
1548 PushMapExpressionList (MapExpressionList);\r
1549 }\r
1550 //\r
1551 // Initialize new Map Expression List.\r
1552 //\r
1553 MapExpressionList = &ExpressionOpCode->MapExpressionList;\r
1554 InitializeListHead (MapExpressionList);\r
1555 //\r
1556 // Store current expression.\r
1557 //\r
1558 PushCurrentExpression (CurrentExpression);\r
1559 CurrentExpression = NULL;\r
1560 MapScopeDepth ++;\r
1561 } else if (SingleOpCodeExpression) {\r
c60a0616 1562 //\r
1563 // There are two cases to indicate the end of an Expression:\r
1564 // for single OpCode expression: one Expression OpCode\r
1565 // for expression consists of more than one OpCode: EFI_IFR_END\r
1566 //\r
1567 SingleOpCodeExpression = FALSE;\r
1568\r
31585af4 1569 if (InScopeDisable && CurrentForm == NULL) {\r
c60a0616 1570 //\r
0a1147ed 1571 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 1572 //\r
1573 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1574 if (EFI_ERROR (Status)) {\r
1575 return Status;\r
1576 }\r
c410589e 1577\r
e6106e89 1578 OpCodeDisabled = IsTrue(&CurrentExpression->Result);\r
c60a0616 1579 }\r
1580\r
1581 CurrentExpression = NULL;\r
1582 }\r
1583\r
1584 continue;\r
1585 }\r
1586\r
1587 //\r
1588 // Parse the Opcode\r
1589 //\r
1590 switch (Operand) {\r
1591\r
1592 case EFI_IFR_FORM_SET_OP:\r
1593 //\r
f8a1c229 1594 // Check the formset GUID\r
c60a0616 1595 //\r
1596 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1597 return EFI_INVALID_PARAMETER;\r
1598 }\r
1599\r
1600 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1601 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
5e30b69e 1602 FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset\r
0a1147ed 1603\r
d228526f
LG
1604 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
1605 //\r
1606 // The formset OpCode contains ClassGuid\r
1607 //\r
1608 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1609 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
1610 }\r
c60a0616 1611 break;\r
1612\r
1613 case EFI_IFR_FORM_OP:\r
1614 //\r
1615 // Create a new Form for this FormSet\r
1616 //\r
1617 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1ac628ee 1618 ASSERT (CurrentForm != NULL);\r
c60a0616 1619 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1620 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1621 InitializeListHead (&CurrentForm->StatementListHead);\r
b18e7050 1622 InitializeListHead (&CurrentForm->ConfigRequestHead);\r
4d4deaac 1623 InitializeListHead (&CurrentForm->FormViewListHead);\r
c60a0616 1624\r
2573712e 1625 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
c60a0616 1626 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1627 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1628\r
31585af4
ED
1629 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);\r
1630 if ( ConditionalExprCount > 0) {\r
0c66bc76
LG
1631 //\r
1632 // Form is inside of suppressif\r
1633 //\r
d1102dba 1634 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(\r
31585af4
ED
1635 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
1636 ASSERT (CurrentForm->SuppressExpression != NULL);\r
1637 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;\r
1638 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
1639 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
0c66bc76
LG
1640 }\r
1641\r
1642 if (Scope != 0) {\r
1643 //\r
1644 // Enter scope of a Form, suppressif will be used for Question or Option\r
1645 //\r
1646 SuppressForQuestion = TRUE;\r
1647 }\r
1648\r
c60a0616 1649 //\r
1650 // Insert into Form list of this FormSet\r
1651 //\r
1652 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1653 break;\r
1654\r
2573712e
LG
1655 case EFI_IFR_FORM_MAP_OP:\r
1656 //\r
1657 // Create a new Form for this FormSet\r
1658 //\r
1659 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1660 ASSERT (CurrentForm != NULL);\r
1661 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1662 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1663 InitializeListHead (&CurrentForm->StatementListHead);\r
b18e7050 1664 InitializeListHead (&CurrentForm->ConfigRequestHead);\r
4d4deaac
ED
1665 InitializeListHead (&CurrentForm->FormViewListHead);\r
1666\r
2573712e
LG
1667 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1668\r
1669 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1670 //\r
1671 // FormMap Form must contain at least one Map Method.\r
1672 //\r
1673 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
1674 return EFI_INVALID_PARAMETER;\r
1675 }\r
1676 //\r
1677 // Try to find the standard form map method.\r
1678 //\r
1679 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
1680 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
1681 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1682 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1683 break;\r
1684 }\r
1685 MapMethod ++;\r
1686 }\r
1687 //\r
1688 // If the standard form map method is not found, the first map method title will be used.\r
1689 //\r
1690 if (CurrentForm->FormTitle == 0) {\r
1691 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1692 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1693 }\r
1694\r
31585af4
ED
1695 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);\r
1696 if ( ConditionalExprCount > 0) {\r
2573712e
LG
1697 //\r
1698 // Form is inside of suppressif\r
1699 //\r
d1102dba 1700 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(\r
31585af4
ED
1701 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
1702 ASSERT (CurrentForm->SuppressExpression != NULL);\r
1703 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;\r
1704 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
1705 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
2573712e
LG
1706 }\r
1707\r
1708 if (Scope != 0) {\r
1709 //\r
1710 // Enter scope of a Form, suppressif will be used for Question or Option\r
1711 //\r
1712 SuppressForQuestion = TRUE;\r
1713 }\r
1714\r
1715 //\r
1716 // Insert into Form list of this FormSet\r
1717 //\r
1718 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1719 break;\r
1720\r
c60a0616 1721 //\r
1722 // Storage\r
1723 //\r
1724 case EFI_IFR_VARSTORE_OP:\r
1725 //\r
1726 // Create a buffer Storage for this FormSet\r
1727 //\r
94f3aae7 1728 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);\r
c60a0616 1729 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
c60a0616 1730 break;\r
1731\r
1732 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1733 //\r
1734 // Create a name/value Storage for this FormSet\r
1735 //\r
94f3aae7 1736 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);\r
c60a0616 1737 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
c60a0616 1738 break;\r
1739\r
1740 case EFI_IFR_VARSTORE_EFI_OP:\r
1741 //\r
1742 // Create a EFI variable Storage for this FormSet\r
1743 //\r
cce6230f 1744 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
c0462ea7
ED
1745 //\r
1746 // Create efi varstore with format follow UEFI spec before 2.3.1.\r
1747 //\r
94f3aae7
ED
1748 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);\r
1749 } else {\r
c0462ea7
ED
1750 //\r
1751 // Create efi varstore with format follow UEFI spec 2.3.1 and later.\r
1752 //\r
94f3aae7 1753 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);\r
cce6230f 1754 }\r
94f3aae7 1755 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
c60a0616 1756 break;\r
1757\r
1758 //\r
1759 // DefaultStore\r
1760 //\r
1761 case EFI_IFR_DEFAULTSTORE_OP:\r
75596726 1762 HaveInserted = FALSE;\r
c60a0616 1763 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1ac628ee 1764 ASSERT (DefaultStore != NULL);\r
c60a0616 1765 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1766\r
1767 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1768 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
c60a0616 1769 //\r
75596726 1770 // Insert it to the DefaultStore list of this Formset with ascending order.\r
c60a0616 1771 //\r
75596726
DB
1772 if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
1773 DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
1774 while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
1775 PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
1776 DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
1777 if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {\r
1778 InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);\r
1779 HaveInserted = TRUE;\r
1780 break;\r
1781 }\r
1782 }\r
1783 }\r
1784 if (!HaveInserted) {\r
1785 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1786 }\r
c60a0616 1787 break;\r
1788\r
1789 //\r
1790 // Statements\r
1791 //\r
1792 case EFI_IFR_SUBTITLE_OP:\r
1793 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1794 ASSERT (CurrentStatement != NULL);\r
8b0fc5c1 1795\r
c60a0616 1796 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
7c6c064c 1797 CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
c60a0616 1798 break;\r
1799\r
1800 case EFI_IFR_TEXT_OP:\r
1801 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1802 ASSERT (CurrentStatement != NULL);\r
7c6c064c 1803 CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
c60a0616 1804 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1805 break;\r
1806\r
f8a1c229 1807 case EFI_IFR_RESET_BUTTON_OP:\r
1808 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1809 ASSERT (CurrentStatement != NULL);\r
7c6c064c 1810 CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
f8a1c229 1811 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1812 break;\r
1813\r
c60a0616 1814 //\r
1815 // Questions\r
1816 //\r
1817 case EFI_IFR_ACTION_OP:\r
1818 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1819 ASSERT (CurrentStatement != NULL);\r
d02847d3 1820 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
c60a0616 1821\r
1822 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1823 //\r
1824 // No QuestionConfig present, so no configuration string will be processed\r
1825 //\r
1826 CurrentStatement->QuestionConfig = 0;\r
1827 } else {\r
1828 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1829 }\r
1830 break;\r
1831\r
c60a0616 1832 case EFI_IFR_REF_OP:\r
1833 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1834 ASSERT (CurrentStatement != NULL);\r
8ca6180f
ED
1835 Value = &CurrentStatement->HiiValue;\r
1836 Value->Type = EFI_IFR_TYPE_REF;\r
1837 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {\r
1838 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
c60a0616 1839\r
8ca6180f
ED
1840 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1841 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 1842\r
8ca6180f
ED
1843 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1844 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1845\r
1846 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1847 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1848 }\r
c60a0616 1849 }\r
1850 }\r
1851 }\r
d1102dba 1852 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);\r
8ca6180f 1853 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1854 break;\r
1855\r
1856 case EFI_IFR_ONE_OF_OP:\r
1857 case EFI_IFR_NUMERIC_OP:\r
1858 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
945e3aed 1859 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1860\r
c60a0616 1861 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1862 Value = &CurrentStatement->HiiValue;\r
1863\r
560a435d
DB
1864 if (QuestionReferBitField) {\r
1865 //\r
1866 // Get the bit var store info (bit/byte offset, bit/byte offset)\r
1867 //\r
1868 CurrentStatement->QuestionReferToBitField = TRUE;\r
1869 CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
1870 CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
1871 CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
1872 TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
1873 CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
c60a0616 1874\r
560a435d
DB
1875 //\r
1876 // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)\r
1877 //\r
1878 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue;\r
1879 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue;\r
1880 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step;\r
c60a0616 1881\r
560a435d
DB
1882 //\r
1883 // Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,\r
1884 // in order to make Browser handle these question with bit varstore correctly.\r
1885 //\r
1886 ((EFI_IFR_NUMERIC *) OpCodeData)->Flags &= EDKII_IFR_DISPLAY_BIT;\r
1887 ((EFI_IFR_NUMERIC *) OpCodeData)->Flags >>= 2;\r
1888 switch (CurrentStatement->StorageWidth) {\r
1889 case 1:\r
1890 ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;\r
1891 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue = (UINT8)CurrentStatement->Minimum;\r
1892 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue = (UINT8)CurrentStatement->Maximum;\r
1893 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step = (UINT8)CurrentStatement->Step;\r
1894 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1895 break;\r
1896 case 2:\r
1897 ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;\r
1898 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue = (UINT16)CurrentStatement->Minimum;\r
1899 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue = (UINT16)CurrentStatement->Maximum;\r
1900 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step = (UINT16)CurrentStatement->Step;\r
1901 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1902 break;\r
1903 case 3:\r
1904 case 4:\r
1905 ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;\r
1906 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue = (UINT32)CurrentStatement->Minimum;\r
1907 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue = (UINT32)CurrentStatement->Maximum;\r
1908 ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step = (UINT32)CurrentStatement->Step;\r
1909 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1910 break;\r
1911 default:\r
1912 break;\r
1913 }\r
1914 } else {\r
1915 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1916 case EFI_IFR_NUMERIC_SIZE_1:\r
1917 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1918 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1919 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1920 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
1921 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1922 break;\r
c60a0616 1923\r
560a435d
DB
1924 case EFI_IFR_NUMERIC_SIZE_2:\r
1925 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1926 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1927 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
1928 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
1929 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1930 break;\r
c60a0616 1931\r
560a435d
DB
1932 case EFI_IFR_NUMERIC_SIZE_4:\r
1933 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1934 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1935 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
1936 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
1937 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1938 break;\r
1939\r
1940 case EFI_IFR_NUMERIC_SIZE_8:\r
1941 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1942 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1943 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
1944 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
1945 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1946 break;\r
c60a0616 1947\r
560a435d
DB
1948 default:\r
1949 break;\r
1950 }\r
1951 }\r
b18e7050 1952 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1953\r
1954 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
1955 SuppressForOption = TRUE;\r
1956 }\r
1957 break;\r
1958\r
1959 case EFI_IFR_ORDERED_LIST_OP:\r
1960 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1961 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1962\r
c60a0616 1963 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1964 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
c60a0616 1965\r
d02847d3 1966 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
b86b413a 1967 CurrentStatement->BufferValue = NULL;\r
c60a0616 1968\r
1969 if (Scope != 0) {\r
1970 SuppressForOption = TRUE;\r
1971 }\r
1972 break;\r
1973\r
1974 case EFI_IFR_CHECKBOX_OP:\r
1975 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1976 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1977\r
c60a0616 1978 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
cd7bfc2c 1979 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
c60a0616 1980 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1981\r
560a435d
DB
1982 if (QuestionReferBitField) {\r
1983 //\r
1984 // Get the bit var store info (bit/byte offset, bit/byte offset)\r
1985 //\r
1986 CurrentStatement->QuestionReferToBitField = TRUE;\r
1987 CurrentStatement->BitStorageWidth = 1;\r
1988 CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
1989 CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
1990 TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
1991 CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
1992 }\r
1993\r
b18e7050 1994 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1995\r
1996 break;\r
1997\r
1998 case EFI_IFR_STRING_OP:\r
1999 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2000 ASSERT (CurrentStatement != NULL);\r
c60a0616 2001 //\r
2002 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
2003 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
2004 // The characters are stored as Unicode, so the storage width should multiply 2.\r
2005 //\r
2006 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
2007 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
2008 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
2009 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
2010\r
2011 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
2012 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
e2100bfa 2013 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
c60a0616 2014\r
b18e7050 2015 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2016 break;\r
2017\r
2018 case EFI_IFR_PASSWORD_OP:\r
2019 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2020 ASSERT (CurrentStatement != NULL);\r
c60a0616 2021 //\r
2022 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
2023 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
2024 // The characters are stored as Unicode, so the storage width should multiply 2.\r
2025 //\r
2026 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
2027 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
2028 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
2029\r
2030 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
2031 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
e2100bfa 2032 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
c60a0616 2033\r
b18e7050 2034 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2035 break;\r
2036\r
2037 case EFI_IFR_DATE_OP:\r
2038 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2039 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 2040\r
c60a0616 2041 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
2042 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
2043\r
2044 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
cd7bfc2c 2045 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r
c60a0616 2046\r
b18e7050 2047 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2048 } else {\r
2049 //\r
2050 // Don't assign storage for RTC type of date/time\r
2051 //\r
2052 CurrentStatement->Storage = NULL;\r
2053 CurrentStatement->StorageWidth = 0;\r
2054 }\r
2055 break;\r
2056\r
2057 case EFI_IFR_TIME_OP:\r
2058 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2059 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 2060\r
c60a0616 2061 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
2062 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
2063\r
2064 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
5ec56d19 2065 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r
c60a0616 2066\r
b18e7050 2067 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2068 } else {\r
2069 //\r
2070 // Don't assign storage for RTC type of date/time\r
2071 //\r
2072 CurrentStatement->Storage = NULL;\r
2073 CurrentStatement->StorageWidth = 0;\r
2074 }\r
2075 break;\r
2076\r
2077 //\r
2078 // Default\r
2079 //\r
2080 case EFI_IFR_DEFAULT_OP:\r
2081 //\r
2082 // EFI_IFR_DEFAULT appear in scope of a Question,\r
2083 // It creates a default value for the current question.\r
2084 // A Question may have more than one Default value which have different default types.\r
2085 //\r
2086 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1ac628ee 2087 ASSERT (CurrentDefault != NULL);\r
c60a0616 2088 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
2089\r
2090 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
2091 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
0b567d18
ED
2092 if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
2093 CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
2094 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);\r
2095 ASSERT (CurrentDefault->Value.Buffer != NULL);\r
2096 } else {\r
23fe74dc 2097 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
4706ff4f
ED
2098 ExtendValueToU64 (&CurrentDefault->Value);\r
2099 }\r
c60a0616 2100\r
2101 //\r
2102 // Insert to Default Value list of current Question\r
2103 //\r
077c7aee 2104 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
c60a0616 2105\r
2106 if (Scope != 0) {\r
2107 InScopeDefault = TRUE;\r
2108 }\r
2109 break;\r
2110\r
2111 //\r
2112 // Option\r
2113 //\r
2114 case EFI_IFR_ONE_OF_OPTION_OP:\r
aee257db 2115 ASSERT (ParentStatement != NULL);\r
0b567d18
ED
2116 if (ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP && ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {\r
2117 //\r
2118 // It's keep the default value for ordered list opcode.\r
2119 //\r
2120 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
2121 ASSERT (CurrentDefault != NULL);\r
2122 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
2123\r
2124 CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;\r
2125 if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
2126 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
2127 } else {\r
2128 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
2129 }\r
2130\r
2131 CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
2132 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);\r
2133 ASSERT (CurrentDefault->Value.Buffer != NULL);\r
2134\r
2135 //\r
2136 // Insert to Default Value list of current Question\r
2137 //\r
2138 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
2139 break;\r
2140 }\r
2141\r
c60a0616 2142 //\r
2143 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
2144 // It create a selection for use in current Question.\r
2145 //\r
2146 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1ac628ee 2147 ASSERT (CurrentOption != NULL);\r
c60a0616 2148 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
7c6c064c 2149 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;\r
c60a0616 2150\r
2151 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
2152 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
2153 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
a7f87053 2154 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
c60a0616 2155 ExtendValueToU64 (&CurrentOption->Value);\r
2156\r
31585af4
ED
2157 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);\r
2158 if ( ConditionalExprCount > 0) {\r
2159 //\r
2160 // Form is inside of suppressif\r
2161 //\r
d1102dba 2162 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(\r
31585af4
ED
2163 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
2164 ASSERT (CurrentOption->SuppressExpression != NULL);\r
2165 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;\r
2166 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
2167 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
c60a0616 2168 }\r
2169\r
2170 //\r
2171 // Insert to Option list of current Question\r
2172 //\r
077c7aee 2173 InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);\r
d02847d3 2174 //\r
2175 // Now we know the Storage width of nested Ordered List\r
2176 //\r
077c7aee 2177 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {\r
d02847d3 2178 Width = 1;\r
2179 switch (CurrentOption->Value.Type) {\r
2180 case EFI_IFR_TYPE_NUM_SIZE_8:\r
2181 Width = 1;\r
2182 break;\r
2183\r
2184 case EFI_IFR_TYPE_NUM_SIZE_16:\r
2185 Width = 2;\r
2186 break;\r
2187\r
2188 case EFI_IFR_TYPE_NUM_SIZE_32:\r
2189 Width = 4;\r
2190 break;\r
2191\r
2192 case EFI_IFR_TYPE_NUM_SIZE_64:\r
2193 Width = 8;\r
2194 break;\r
2195\r
2196 default:\r
2197 //\r
2198 // Invalid type for Ordered List\r
2199 //\r
2200 break;\r
2201 }\r
2202\r
077c7aee
ED
2203 ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);\r
2204 ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);\r
2205 ParentStatement->ValueType = CurrentOption->Value.Type;\r
2206 if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
2207 ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;\r
2208 ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;\r
901ba0e7 2209 }\r
d02847d3 2210\r
077c7aee 2211 InitializeRequestElement (FormSet, ParentStatement, CurrentForm);\r
d02847d3 2212 }\r
c60a0616 2213 break;\r
2214\r
2215 //\r
2216 // Conditional\r
2217 //\r
2218 case EFI_IFR_NO_SUBMIT_IF_OP:\r
2219 case EFI_IFR_INCONSISTENT_IF_OP:\r
2220 //\r
2221 // Create an Expression node\r
2222 //\r
bfae1330 2223 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2224 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
2225\r
2226 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
2227 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
077c7aee 2228 InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
c60a0616 2229 } else {\r
2230 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
077c7aee 2231 InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);\r
c60a0616 2232 }\r
0c66bc76
LG
2233\r
2234 //\r
2235 // Take a look at next OpCode to see whether current expression consists\r
2236 // of single OpCode\r
2237 //\r
2238 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2239 SingleOpCodeExpression = TRUE;\r
2240 }\r
c60a0616 2241 break;\r
2242\r
1c0d306f
ED
2243 case EFI_IFR_WARNING_IF_OP:\r
2244 //\r
2245 // Create an Expression node\r
2246 //\r
bfae1330 2247 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
1c0d306f
ED
2248 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));\r
2249 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;\r
2250 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;\r
077c7aee 2251 InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);\r
1c0d306f
ED
2252\r
2253 //\r
2254 // Take a look at next OpCode to see whether current expression consists\r
2255 // of single OpCode\r
2256 //\r
2257 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2258 SingleOpCodeExpression = TRUE;\r
2259 }\r
2260 break;\r
2261\r
c60a0616 2262 case EFI_IFR_SUPPRESS_IF_OP:\r
2263 //\r
2264 // Question and Option will appear in scope of this OpCode\r
2265 //\r
bfae1330 2266 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2267 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
0c66bc76
LG
2268\r
2269 if (CurrentForm == NULL) {\r
2270 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
2271 } else {\r
2272 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2273 }\r
c60a0616 2274\r
2275 if (SuppressForOption) {\r
d1102dba 2276 PushConditionalExpression(CurrentExpression, ExpressOption);\r
0c66bc76 2277 } else if (SuppressForQuestion) {\r
d1102dba 2278 PushConditionalExpression(CurrentExpression, ExpressStatement);\r
0c66bc76 2279 } else {\r
d1102dba 2280 PushConditionalExpression(CurrentExpression, ExpressForm);\r
0c66bc76
LG
2281 }\r
2282\r
2283 //\r
2284 // Take a look at next OpCode to see whether current expression consists\r
2285 // of single OpCode\r
2286 //\r
2287 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2288 SingleOpCodeExpression = TRUE;\r
c60a0616 2289 }\r
2290 break;\r
2291\r
2292 case EFI_IFR_GRAY_OUT_IF_OP:\r
2293 //\r
2294 // Questions will appear in scope of this OpCode\r
2295 //\r
bfae1330 2296 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2297 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
2298 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
31585af4 2299 PushConditionalExpression(CurrentExpression, ExpressStatement);\r
0c66bc76
LG
2300\r
2301 //\r
2302 // Take a look at next OpCode to see whether current expression consists\r
2303 // of single OpCode\r
2304 //\r
2305 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2306 SingleOpCodeExpression = TRUE;\r
2307 }\r
c60a0616 2308 break;\r
2309\r
2310 case EFI_IFR_DISABLE_IF_OP:\r
2311 //\r
2312 // The DisableIf expression should only rely on constant, so it could be\r
2313 // evaluated at initialization and it will not be queued\r
2314 //\r
2315 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1ac628ee 2316 ASSERT (CurrentExpression != NULL);\r
c60a0616 2317 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
2318 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
2319 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
2320\r
0a1147ed
LG
2321 if (CurrentForm != NULL) {\r
2322 //\r
2323 // This is DisableIf for Question, enqueue it to Form expression list\r
2324 //\r
2325 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
31585af4 2326 PushConditionalExpression(CurrentExpression, ExpressStatement);\r
0a1147ed
LG
2327 }\r
2328\r
31585af4
ED
2329 OpCodeDisabled = FALSE;\r
2330 InScopeDisable = TRUE;\r
c60a0616 2331 //\r
2332 // Take a look at next OpCode to see whether current expression consists\r
2333 // of single OpCode\r
2334 //\r
2335 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2336 SingleOpCodeExpression = TRUE;\r
2337 }\r
2338 break;\r
2339\r
2340 //\r
2341 // Expression\r
2342 //\r
2343 case EFI_IFR_VALUE_OP:\r
bfae1330 2344 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2345 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
2346 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2347\r
2348 if (InScopeDefault) {\r
2349 //\r
2350 // Used for default (EFI_IFR_DEFAULT)\r
2351 //\r
2352 CurrentDefault->ValueExpression = CurrentExpression;\r
2353 } else {\r
2354 //\r
2355 // If used for a question, then the question will be read-only\r
2356 //\r
bc166db3 2357 //\r
2358 // Make sure CurrentStatement is not NULL.\r
2359 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2360 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
2361 //\r
077c7aee
ED
2362 ASSERT (ParentStatement != NULL);\r
2363 ParentStatement->ValueExpression = CurrentExpression;\r
c60a0616 2364 }\r
0c66bc76
LG
2365\r
2366 //\r
2367 // Take a look at next OpCode to see whether current expression consists\r
2368 // of single OpCode\r
2369 //\r
2370 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2371 SingleOpCodeExpression = TRUE;\r
2372 }\r
c60a0616 2373 break;\r
2374\r
2375 case EFI_IFR_RULE_OP:\r
bfae1330 2376 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2377 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
2378\r
2379 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
2380 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
0c66bc76
LG
2381\r
2382 //\r
2383 // Take a look at next OpCode to see whether current expression consists\r
2384 // of single OpCode\r
2385 //\r
2386 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2387 SingleOpCodeExpression = TRUE;\r
2388 }\r
c60a0616 2389 break;\r
2390\r
2573712e 2391 case EFI_IFR_READ_OP:\r
bfae1330 2392 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
2573712e
LG
2393 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
2394 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2395\r
2396 //\r
2397 // Make sure CurrentStatement is not NULL.\r
2398 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2399 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
2400 //\r
077c7aee
ED
2401 ASSERT (ParentStatement != NULL);\r
2402 ParentStatement->ReadExpression = CurrentExpression;\r
2573712e
LG
2403\r
2404 //\r
2405 // Take a look at next OpCode to see whether current expression consists\r
2406 // of single OpCode\r
2407 //\r
2408 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2409 SingleOpCodeExpression = TRUE;\r
2410 }\r
2411 break;\r
2412\r
2413 case EFI_IFR_WRITE_OP:\r
bfae1330 2414 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
2573712e
LG
2415 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
2416 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2417\r
2418 //\r
2419 // Make sure CurrentStatement is not NULL.\r
2420 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2421 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
2422 //\r
077c7aee
ED
2423 ASSERT (ParentStatement != NULL);\r
2424 ParentStatement->WriteExpression = CurrentExpression;\r
2573712e
LG
2425\r
2426 //\r
2427 // Take a look at next OpCode to see whether current expression consists\r
2428 // of single OpCode\r
2429 //\r
2430 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2431 SingleOpCodeExpression = TRUE;\r
2432 }\r
2433 break;\r
2434\r
c60a0616 2435 //\r
2436 // Image\r
2437 //\r
2438 case EFI_IFR_IMAGE_OP:\r
2439 //\r
2440 // Get ScopeOpcode from top of stack\r
2441 //\r
2442 PopScope (&ScopeOpCode);\r
2443 PushScope (ScopeOpCode);\r
2444\r
2445 switch (ScopeOpCode) {\r
2446 case EFI_IFR_FORM_SET_OP:\r
2447 ImageId = &FormSet->ImageId;\r
2448 break;\r
2449\r
2450 case EFI_IFR_FORM_OP:\r
2573712e 2451 case EFI_IFR_FORM_MAP_OP:\r
d0720b57 2452 ASSERT (CurrentForm != NULL);\r
c60a0616 2453 ImageId = &CurrentForm->ImageId;\r
2454 break;\r
2455\r
2456 case EFI_IFR_ONE_OF_OPTION_OP:\r
523f48e7 2457 ASSERT (CurrentOption != NULL);\r
c60a0616 2458 ImageId = &CurrentOption->ImageId;\r
2459 break;\r
2460\r
2461 default:\r
bc166db3 2462 //\r
2463 // Make sure CurrentStatement is not NULL.\r
2464 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2465 // file is wrongly generated by tools such as VFR Compiler.\r
2466 //\r
077c7aee
ED
2467 ASSERT (ParentStatement != NULL);\r
2468 ImageId = &ParentStatement->ImageId;\r
c60a0616 2469 break;\r
2470 }\r
2471\r
c410589e 2472 ASSERT (ImageId != NULL);\r
c60a0616 2473 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
2474 break;\r
2475\r
2476 //\r
2477 // Refresh\r
2478 //\r
2479 case EFI_IFR_REFRESH_OP:\r
077c7aee
ED
2480 ASSERT (ParentStatement != NULL);\r
2481 ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
c60a0616 2482 break;\r
2483\r
211cc6e5
ED
2484 //\r
2485 // Refresh guid.\r
2486 //\r
2487 case EFI_IFR_REFRESH_ID_OP:\r
790447b2
ED
2488 //\r
2489 // Get ScopeOpcode from top of stack\r
2490 //\r
2491 PopScope (&ScopeOpCode);\r
2492 PushScope (ScopeOpCode);\r
2493\r
2494 switch (ScopeOpCode) {\r
2495 case EFI_IFR_FORM_OP:\r
2496 case EFI_IFR_FORM_MAP_OP:\r
2497 ASSERT (CurrentForm != NULL);\r
2498 CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
2499 break;\r
2500\r
2501 default:\r
2502 ASSERT (ParentStatement != NULL);\r
2503 CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
2504 break;\r
2505 }\r
211cc6e5
ED
2506 break;\r
2507\r
b00964a9
ED
2508 //\r
2509 // Modal tag\r
2510 //\r
2511 case EFI_IFR_MODAL_TAG_OP:\r
2512 ASSERT (CurrentForm != NULL);\r
2513 CurrentForm->ModalForm = TRUE;\r
2514 break;\r
2515\r
f67c4382
ED
2516 //\r
2517 // Lock tag, used by form and statement.\r
2518 //\r
2519 case EFI_IFR_LOCKED_OP:\r
2520 //\r
2521 // Get ScopeOpcode from top of stack\r
2522 //\r
2523 PopScope (&ScopeOpCode);\r
2524 PushScope (ScopeOpCode);\r
2525 switch (ScopeOpCode) {\r
2526 case EFI_IFR_FORM_OP:\r
2527 case EFI_IFR_FORM_MAP_OP:\r
2528 ASSERT (CurrentForm != NULL);\r
2529 CurrentForm->Locked = TRUE;\r
2530 break;\r
2531\r
2532 default:\r
077c7aee
ED
2533 ASSERT (ParentStatement != NULL);\r
2534 ParentStatement->Locked = TRUE;\r
d1102dba 2535 }\r
f67c4382
ED
2536 break;\r
2537\r
c60a0616 2538 //\r
2539 // Vendor specific\r
2540 //\r
560a435d 2541 case EFI_IFR_GUID_OP:\r
7c6c064c 2542 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
560a435d
DB
2543 if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
2544 Scope = 0;\r
2545 QuestionReferBitField = TRUE;\r
2546 }\r
c60a0616 2547 break;\r
2548\r
2549 //\r
2550 // Scope End\r
2551 //\r
2552 case EFI_IFR_END_OP:\r
560a435d 2553 QuestionReferBitField = FALSE;\r
c60a0616 2554 Status = PopScope (&ScopeOpCode);\r
2555 if (EFI_ERROR (Status)) {\r
2556 ResetScopeStack ();\r
2557 return Status;\r
2558 }\r
d1102dba 2559\r
077c7aee
ED
2560 //\r
2561 // Parent statement end tag found, update ParentStatement info.\r
2562 //\r
5fdd2a81 2563 if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {\r
077c7aee
ED
2564 ParentStatement = ParentStatement->ParentStatement;\r
2565 }\r
c60a0616 2566\r
2567 switch (ScopeOpCode) {\r
2568 case EFI_IFR_FORM_SET_OP:\r
2569 //\r
2570 // End of FormSet, update FormSet IFR binary length\r
2571 // to stop parsing substantial OpCodes\r
2572 //\r
2573 FormSet->IfrBinaryLength = OpCodeOffset;\r
2574 break;\r
2575\r
2576 case EFI_IFR_FORM_OP:\r
2573712e 2577 case EFI_IFR_FORM_MAP_OP:\r
c60a0616 2578 //\r
2579 // End of Form\r
2580 //\r
2581 CurrentForm = NULL;\r
0c66bc76 2582 SuppressForQuestion = FALSE;\r
c60a0616 2583 break;\r
2584\r
2585 case EFI_IFR_ONE_OF_OPTION_OP:\r
2586 //\r
2587 // End of Option\r
2588 //\r
2589 CurrentOption = NULL;\r
2590 break;\r
2591\r
c60a0616 2592 case EFI_IFR_NO_SUBMIT_IF_OP:\r
2593 case EFI_IFR_INCONSISTENT_IF_OP:\r
1c0d306f 2594 case EFI_IFR_WARNING_IF_OP:\r
c60a0616 2595 //\r
2596 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
2597 //\r
2598 break;\r
2599\r
2600 case EFI_IFR_SUPPRESS_IF_OP:\r
2601 if (SuppressForOption) {\r
d1102dba 2602 PopConditionalExpression(ExpressOption);\r
0c66bc76 2603 } else if (SuppressForQuestion) {\r
31585af4 2604 PopConditionalExpression(ExpressStatement);\r
0c66bc76 2605 } else {\r
31585af4 2606 PopConditionalExpression(ExpressForm);\r
c60a0616 2607 }\r
2608 break;\r
2609\r
2610 case EFI_IFR_GRAY_OUT_IF_OP:\r
31585af4 2611 PopConditionalExpression(ExpressStatement);\r
c60a0616 2612 break;\r
2613\r
2614 case EFI_IFR_DISABLE_IF_OP:\r
31585af4
ED
2615 if (CurrentForm != NULL) {\r
2616 PopConditionalExpression(ExpressStatement);\r
2617 }\r
2618 InScopeDisable = FALSE;\r
c60a0616 2619 OpCodeDisabled = FALSE;\r
2620 break;\r
2621\r
2622 case EFI_IFR_ONE_OF_OP:\r
2623 case EFI_IFR_ORDERED_LIST_OP:\r
2624 SuppressForOption = FALSE;\r
2625 break;\r
2626\r
2627 case EFI_IFR_DEFAULT_OP:\r
2628 InScopeDefault = FALSE;\r
2629 break;\r
2630\r
2573712e
LG
2631 case EFI_IFR_MAP_OP:\r
2632 //\r
2633 // Get current Map Expression List.\r
2634 //\r
2635 Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r
2636 if (Status == EFI_ACCESS_DENIED) {\r
2637 MapExpressionList = NULL;\r
2638 }\r
2639 //\r
2640 // Get current expression.\r
2641 //\r
2642 Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r
2643 ASSERT_EFI_ERROR (Status);\r
771ececd 2644 ASSERT (MapScopeDepth > 0);\r
2573712e
LG
2645 MapScopeDepth --;\r
2646 break;\r
2647\r
c60a0616 2648 default:\r
2649 if (IsExpressionOpCode (ScopeOpCode)) {\r
31585af4 2650 if (InScopeDisable && CurrentForm == NULL) {\r
c60a0616 2651 //\r
0a1147ed 2652 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 2653 //\r
f8a1c229 2654 ASSERT (CurrentExpression != NULL);\r
c60a0616 2655 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
2656 if (EFI_ERROR (Status)) {\r
2657 return Status;\r
2658 }\r
a935a0d8 2659\r
e6106e89 2660 OpCodeDisabled = IsTrue (&CurrentExpression->Result);\r
c60a0616 2661\r
c60a0616 2662 //\r
2573712e 2663 // DisableIf Expression is only used once and not queued, free it\r
c60a0616 2664 //\r
2665 DestroyExpression (CurrentExpression);\r
2666 }\r
2667\r
2668 //\r
2669 // End of current Expression\r
2670 //\r
2671 CurrentExpression = NULL;\r
2672 }\r
2673 break;\r
2674 }\r
2675 break;\r
2676\r
2677 default:\r
2678 break;\r
2679 }\r
077c7aee
ED
2680\r
2681 if (IsStatementOpCode(Operand)) {\r
2682 CurrentStatement->ParentStatement = ParentStatement;\r
2683 if (Scope != 0) {\r
2684 //\r
2685 // Scope != 0, other statements or options may nest in this statement.\r
2686 // Update the ParentStatement info.\r
2687 //\r
2688 ParentStatement = CurrentStatement;\r
2689 }\r
2690 }\r
c60a0616 2691 }\r
2692\r
2693 return EFI_SUCCESS;\r
2694}\r