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