]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg:System hangs in setup menu
[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
0b567d18
ED
905 if (Default->Value.Buffer != NULL) {\r
906 FreePool (Default->Value.Buffer);\r
907 }\r
f4113e1f 908 FreePool (Default);\r
c60a0616 909 }\r
910\r
911 //\r
912 // Free Options List\r
913 //\r
914 while (!IsListEmpty (&Statement->OptionListHead)) {\r
915 Link = GetFirstNode (&Statement->OptionListHead);\r
916 Option = QUESTION_OPTION_FROM_LINK (Link);\r
31585af4
ED
917 if (Option->SuppressExpression != NULL) {\r
918 FreePool (Option->SuppressExpression);\r
919 }\r
c60a0616 920 RemoveEntryList (&Option->Link);\r
921\r
f4113e1f 922 FreePool (Option);\r
c60a0616 923 }\r
924\r
925 //\r
926 // Free Inconsistent List\r
927 //\r
928 while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
929 Link = GetFirstNode (&Statement->InconsistentListHead);\r
930 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
931 RemoveEntryList (&Expression->Link);\r
932\r
933 DestroyExpression (Expression);\r
934 }\r
935\r
936 //\r
937 // Free NoSubmit List\r
938 //\r
939 while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
940 Link = GetFirstNode (&Statement->NoSubmitListHead);\r
941 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
942 RemoveEntryList (&Expression->Link);\r
943\r
944 DestroyExpression (Expression);\r
945 }\r
946\r
1c0d306f
ED
947 //\r
948 // Free WarningIf List\r
949 //\r
950 while (!IsListEmpty (&Statement->WarningListHead)) {\r
951 Link = GetFirstNode (&Statement->WarningListHead);\r
952 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
953 RemoveEntryList (&Expression->Link);\r
954\r
955 DestroyExpression (Expression);\r
956 }\r
957\r
31585af4
ED
958 if (Statement->Expression != NULL) {\r
959 FreePool (Statement->Expression);\r
960 }\r
961\r
c60a0616 962 if (Statement->VariableName != NULL) {\r
963 FreePool (Statement->VariableName);\r
964 }\r
965 if (Statement->BlockName != NULL) {\r
966 FreePool (Statement->BlockName);\r
967 }\r
b86b413a
LG
968 if (Statement->BufferValue != NULL) {\r
969 FreePool (Statement->BufferValue);\r
970 }\r
e2100bfa
ED
971 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {\r
972 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);\r
973 }\r
c60a0616 974}\r
975\r
976\r
977/**\r
978 Free resources of a Form.\r
979\r
e2100bfa 980 @param FormSet Pointer of the FormSet\r
c60a0616 981 @param Form Pointer of the Form.\r
982\r
983**/\r
984VOID\r
985DestroyForm (\r
e2100bfa
ED
986 IN FORM_BROWSER_FORMSET *FormSet,\r
987 IN OUT FORM_BROWSER_FORM *Form\r
c60a0616 988 )\r
989{\r
990 LIST_ENTRY *Link;\r
991 FORM_EXPRESSION *Expression;\r
992 FORM_BROWSER_STATEMENT *Statement;\r
b18e7050 993 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
c60a0616 994\r
995 //\r
996 // Free Form Expressions\r
997 //\r
998 while (!IsListEmpty (&Form->ExpressionListHead)) {\r
999 Link = GetFirstNode (&Form->ExpressionListHead);\r
1000 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
1001 RemoveEntryList (&Expression->Link);\r
1002\r
1003 DestroyExpression (Expression);\r
1004 }\r
1005\r
1006 //\r
1007 // Free Statements/Questions\r
1008 //\r
1009 while (!IsListEmpty (&Form->StatementListHead)) {\r
1010 Link = GetFirstNode (&Form->StatementListHead);\r
1011 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1012 RemoveEntryList (&Statement->Link);\r
1013\r
e2100bfa 1014 DestroyStatement (FormSet, Statement);\r
c60a0616 1015 }\r
1016\r
b18e7050
ED
1017 //\r
1018 // Free ConfigRequest string.\r
1019 //\r
1020 while (!IsListEmpty (&Form->ConfigRequestHead)) {\r
1021 Link = GetFirstNode (&Form->ConfigRequestHead);\r
1022 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
1023 RemoveEntryList (&ConfigInfo->Link);\r
1024\r
1025 FreePool (ConfigInfo->ConfigRequest);\r
1026 FreePool (ConfigInfo);\r
1027 }\r
1028\r
31585af4
ED
1029 if (Form->SuppressExpression != NULL) {\r
1030 FreePool (Form->SuppressExpression);\r
1031 }\r
1032\r
4d4deaac
ED
1033 UiFreeMenuList (&Form->FormViewListHead);\r
1034\r
c60a0616 1035 //\r
1036 // Free this Form\r
1037 //\r
f4113e1f 1038 FreePool (Form);\r
c60a0616 1039}\r
1040\r
1041\r
1042/**\r
1043 Free resources allocated for a FormSet.\r
1044\r
1045 @param FormSet Pointer of the FormSet\r
1046\r
1047**/\r
1048VOID\r
1049DestroyFormSet (\r
1050 IN OUT FORM_BROWSER_FORMSET *FormSet\r
1051 )\r
1052{\r
1053 LIST_ENTRY *Link;\r
1054 FORMSET_STORAGE *Storage;\r
1055 FORMSET_DEFAULTSTORE *DefaultStore;\r
0c66bc76 1056 FORM_EXPRESSION *Expression;\r
c60a0616 1057 FORM_BROWSER_FORM *Form;\r
1058\r
4c8358c7 1059 if (FormSet->IfrBinaryData == NULL) {\r
1060 //\r
1061 // Uninitialized FormSet\r
1062 //\r
1063 FreePool (FormSet);\r
1064 return;\r
1065 }\r
1066\r
c60a0616 1067 //\r
1068 // Free IFR binary buffer\r
1069 //\r
1070 FreePool (FormSet->IfrBinaryData);\r
1071\r
1072 //\r
1073 // Free FormSet Storage\r
1074 //\r
1075 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
1076 while (!IsListEmpty (&FormSet->StorageListHead)) {\r
1077 Link = GetFirstNode (&FormSet->StorageListHead);\r
1078 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
1079 RemoveEntryList (&Storage->Link);\r
1080\r
1081 DestroyStorage (Storage);\r
1082 }\r
1083 }\r
1084\r
1085 //\r
1086 // Free FormSet Default Store\r
1087 //\r
1088 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
1089 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
1090 Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
1091 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
1092 RemoveEntryList (&DefaultStore->Link);\r
1093\r
f4113e1f 1094 FreePool (DefaultStore);\r
c60a0616 1095 }\r
1096 }\r
1097\r
0c66bc76
LG
1098 //\r
1099 // Free Formset Expressions\r
1100 //\r
1101 while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
1102 Link = GetFirstNode (&FormSet->ExpressionListHead);\r
1103 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
1104 RemoveEntryList (&Expression->Link);\r
1105\r
1106 DestroyExpression (Expression);\r
1107 }\r
1108\r
c60a0616 1109 //\r
1110 // Free Forms\r
1111 //\r
1112 if (FormSet->FormListHead.ForwardLink != NULL) {\r
1113 while (!IsListEmpty (&FormSet->FormListHead)) {\r
1114 Link = GetFirstNode (&FormSet->FormListHead);\r
1115 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
1116 RemoveEntryList (&Form->Link);\r
1117\r
e2100bfa 1118 DestroyForm (FormSet, Form);\r
c60a0616 1119 }\r
1120 }\r
1121\r
1122 if (FormSet->StatementBuffer != NULL) {\r
1123 FreePool (FormSet->StatementBuffer);\r
1124 }\r
1125 if (FormSet->ExpressionBuffer != NULL) {\r
1126 FreePool (FormSet->ExpressionBuffer);\r
1127 }\r
1128\r
1129 FreePool (FormSet);\r
1130}\r
1131\r
1132\r
1133/**\r
1134 Tell whether this Operand is an Expression OpCode or not\r
1135\r
1136 @param Operand Operand of an IFR OpCode.\r
1137\r
1138 @retval TRUE This is an Expression OpCode.\r
1139 @retval FALSE Not an Expression OpCode.\r
1140\r
1141**/\r
1142BOOLEAN\r
1143IsExpressionOpCode (\r
1144 IN UINT8 Operand\r
1145 )\r
1146{\r
1147 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
2573712e
LG
1148 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||\r
1149 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
c60a0616 1150 (Operand == EFI_IFR_CATENATE_OP) ||\r
1151 (Operand == EFI_IFR_TO_LOWER_OP) ||\r
1152 (Operand == EFI_IFR_TO_UPPER_OP) ||\r
2573712e 1153 (Operand == EFI_IFR_MAP_OP) ||\r
cbf73e50 1154 (Operand == EFI_IFR_VERSION_OP) ||\r
9bd22b08
ED
1155 (Operand == EFI_IFR_SECURITY_OP) ||\r
1156 (Operand == EFI_IFR_MATCH2_OP)) {\r
c60a0616 1157 return TRUE;\r
1158 } else {\r
1159 return FALSE;\r
1160 }\r
1161}\r
1162\r
077c7aee
ED
1163/**\r
1164 Tell whether this Operand is an Statement OpCode.\r
1165\r
1166 @param Operand Operand of an IFR OpCode.\r
1167\r
1168 @retval TRUE This is an Statement OpCode.\r
1169 @retval FALSE Not an Statement OpCode.\r
1170\r
1171**/\r
1172BOOLEAN\r
1173IsStatementOpCode (\r
1174 IN UINT8 Operand\r
1175 )\r
1176{\r
1177 if ((Operand == EFI_IFR_SUBTITLE_OP) ||\r
1178 (Operand == EFI_IFR_TEXT_OP) ||\r
1179 (Operand == EFI_IFR_RESET_BUTTON_OP) ||\r
1180 (Operand == EFI_IFR_REF_OP) ||\r
1181 (Operand == EFI_IFR_ACTION_OP) ||\r
1182 (Operand == EFI_IFR_NUMERIC_OP) ||\r
1183 (Operand == EFI_IFR_ORDERED_LIST_OP) ||\r
1184 (Operand == EFI_IFR_CHECKBOX_OP) ||\r
1185 (Operand == EFI_IFR_STRING_OP) ||\r
1186 (Operand == EFI_IFR_PASSWORD_OP) ||\r
1187 (Operand == EFI_IFR_DATE_OP) ||\r
1188 (Operand == EFI_IFR_TIME_OP) ||\r
1189 (Operand == EFI_IFR_GUID_OP) ||\r
1190 (Operand == EFI_IFR_ONE_OF_OP)) {\r
1191 return TRUE;\r
1192 } else {\r
1193 return FALSE;\r
1194 }\r
1195}\r
c60a0616 1196\r
7e2f3289
ED
1197/**\r
1198 Tell whether this Operand is an known OpCode.\r
1199\r
1200 @param Operand Operand of an IFR OpCode.\r
1201\r
1202 @retval TRUE This is an Statement OpCode.\r
1203 @retval FALSE Not an Statement OpCode.\r
1204\r
1205**/\r
1206BOOLEAN\r
1207IsUnKnownOpCode (\r
1208 IN UINT8 Operand\r
1209 )\r
1210{\r
9bd22b08 1211 return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;\r
7e2f3289
ED
1212}\r
1213\r
c60a0616 1214/**\r
1215 Calculate number of Statemens(Questions) and Expression OpCodes.\r
1216\r
1217 @param FormSet The FormSet to be counted.\r
1218 @param NumberOfStatement Number of Statemens(Questions)\r
1219 @param NumberOfExpression Number of Expression OpCodes\r
1220\r
1221**/\r
1222VOID\r
1223CountOpCodes (\r
1224 IN FORM_BROWSER_FORMSET *FormSet,\r
1225 IN OUT UINT16 *NumberOfStatement,\r
1226 IN OUT UINT16 *NumberOfExpression\r
1227 )\r
1228{\r
1229 UINT16 StatementCount;\r
1230 UINT16 ExpressionCount;\r
1231 UINT8 *OpCodeData;\r
1232 UINTN Offset;\r
1233 UINTN OpCodeLen;\r
1234\r
1235 Offset = 0;\r
1236 StatementCount = 0;\r
1237 ExpressionCount = 0;\r
1238\r
1239 while (Offset < FormSet->IfrBinaryLength) {\r
1240 OpCodeData = FormSet->IfrBinaryData + Offset;\r
1241 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
1242 Offset += OpCodeLen;\r
1243\r
1244 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
1245 ExpressionCount++;\r
1246 } else {\r
1247 StatementCount++;\r
1248 }\r
1249 }\r
1250\r
1251 *NumberOfStatement = StatementCount;\r
1252 *NumberOfExpression = ExpressionCount;\r
1253}\r
1254\r
1255\r
1256\r
1257/**\r
1258 Parse opcodes in the formset IFR binary.\r
1259\r
1260 @param FormSet Pointer of the FormSet data structure.\r
1261\r
1262 @retval EFI_SUCCESS Opcode parse success.\r
1263 @retval Other Opcode parse fail.\r
1264\r
1265**/\r
1266EFI_STATUS\r
1267ParseOpCodes (\r
1268 IN FORM_BROWSER_FORMSET *FormSet\r
1269 )\r
1270{\r
1271 EFI_STATUS Status;\r
c60a0616 1272 FORM_BROWSER_FORM *CurrentForm;\r
1273 FORM_BROWSER_STATEMENT *CurrentStatement;\r
077c7aee 1274 FORM_BROWSER_STATEMENT *ParentStatement;\r
c60a0616 1275 EXPRESSION_OPCODE *ExpressionOpCode;\r
1276 FORM_EXPRESSION *CurrentExpression;\r
1277 UINT8 Operand;\r
1278 UINT8 Scope;\r
1279 UINTN OpCodeOffset;\r
1280 UINTN OpCodeLength;\r
1281 UINT8 *OpCodeData;\r
1282 UINT8 ScopeOpCode;\r
1283 FORMSET_STORAGE *Storage;\r
1284 FORMSET_DEFAULTSTORE *DefaultStore;\r
1285 QUESTION_DEFAULT *CurrentDefault;\r
1286 QUESTION_OPTION *CurrentOption;\r
d02847d3 1287 UINT8 Width;\r
c60a0616 1288 UINT16 NumberOfStatement;\r
1289 UINT16 NumberOfExpression;\r
1290 EFI_IMAGE_ID *ImageId;\r
0c66bc76 1291 BOOLEAN SuppressForQuestion;\r
c60a0616 1292 BOOLEAN SuppressForOption;\r
c60a0616 1293 UINT16 DepthOfDisable;\r
1294 BOOLEAN OpCodeDisabled;\r
1295 BOOLEAN SingleOpCodeExpression;\r
1296 BOOLEAN InScopeDefault;\r
1297 EFI_HII_VALUE *Value;\r
2573712e
LG
1298 EFI_IFR_FORM_MAP_METHOD *MapMethod;\r
1299 UINT8 MapScopeDepth;\r
1300 LIST_ENTRY *Link;\r
1301 FORMSET_STORAGE *VarStorage;\r
1302 LIST_ENTRY *MapExpressionList;\r
1303 EFI_VARSTORE_ID TempVarstoreId;\r
31585af4
ED
1304 BOOLEAN InScopeDisable;\r
1305 INTN ConditionalExprCount;\r
7e2f3289
ED
1306 BOOLEAN InUnknownScope;\r
1307 UINT8 UnknownDepth;\r
c60a0616 1308\r
0c66bc76 1309 SuppressForQuestion = FALSE;\r
c60a0616 1310 SuppressForOption = FALSE;\r
31585af4 1311 InScopeDisable = FALSE;\r
c60a0616 1312 DepthOfDisable = 0;\r
1313 OpCodeDisabled = FALSE;\r
1314 SingleOpCodeExpression = FALSE;\r
1315 InScopeDefault = FALSE;\r
1316 CurrentExpression = NULL;\r
1317 CurrentDefault = NULL;\r
1318 CurrentOption = NULL;\r
c410589e 1319 ImageId = NULL;\r
2573712e
LG
1320 MapMethod = NULL;\r
1321 MapScopeDepth = 0;\r
1322 Link = NULL;\r
1323 VarStorage = NULL;\r
1324 MapExpressionList = NULL;\r
1325 TempVarstoreId = 0;\r
31585af4 1326 ConditionalExprCount = 0;\r
7e2f3289
ED
1327 InUnknownScope = FALSE;\r
1328 UnknownDepth = 0;\r
c60a0616 1329\r
1330 //\r
1331 // Get the number of Statements and Expressions\r
1332 //\r
1333 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
1334\r
1335 mStatementIndex = 0;\r
7c6c064c 1336 mUsedQuestionId = 1;\r
c60a0616 1337 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
1338 if (FormSet->StatementBuffer == NULL) {\r
1339 return EFI_OUT_OF_RESOURCES;\r
1340 }\r
1341\r
1342 mExpressionOpCodeIndex = 0;\r
1343 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
1344 if (FormSet->ExpressionBuffer == NULL) {\r
1345 return EFI_OUT_OF_RESOURCES;\r
1346 }\r
1347\r
7c6c064c 1348 InitializeListHead (&FormSet->StatementListOSF);\r
c60a0616 1349 InitializeListHead (&FormSet->StorageListHead);\r
4d4deaac 1350 InitializeListHead (&FormSet->SaveFailStorageListHead);\r
c60a0616 1351 InitializeListHead (&FormSet->DefaultStoreListHead);\r
1352 InitializeListHead (&FormSet->FormListHead);\r
48a9d5f7 1353 InitializeListHead (&FormSet->ExpressionListHead);\r
2573712e
LG
1354 ResetCurrentExpressionStack ();\r
1355 ResetMapExpressionListStack ();\r
c60a0616 1356\r
1357 CurrentForm = NULL;\r
1358 CurrentStatement = NULL;\r
077c7aee 1359 ParentStatement = NULL;\r
c60a0616 1360\r
1361 ResetScopeStack ();\r
1362\r
1363 OpCodeOffset = 0;\r
1364 while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
1365 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
1366\r
1367 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
1368 OpCodeOffset += OpCodeLength;\r
1369 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
1370 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
1371\r
7e2f3289
ED
1372 if (InUnknownScope) {\r
1373 if (Operand == EFI_IFR_END_OP) {\r
1374 UnknownDepth --;\r
1375\r
1376 if (UnknownDepth == 0) {\r
1377 InUnknownScope = FALSE;\r
1378 }\r
1379 } else {\r
1380 if (Scope != 0) {\r
1381 UnknownDepth ++;\r
1382 }\r
1383 }\r
1384\r
1385 continue;\r
1386 }\r
1387\r
1388 if (IsUnKnownOpCode(Operand)) {\r
1389 if (Scope != 0) {\r
1390 InUnknownScope = TRUE;\r
1391 UnknownDepth ++;\r
1392 }\r
1393\r
1394 continue;\r
1395 }\r
1396\r
c60a0616 1397 //\r
1398 // If scope bit set, push onto scope stack\r
1399 //\r
1400 if (Scope != 0) {\r
1401 PushScope (Operand);\r
1402 }\r
1403\r
1404 if (OpCodeDisabled) {\r
1405 //\r
1406 // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
1407 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
1408 //\r
1409 if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
1410 DepthOfDisable++;\r
1411 } else if (Operand == EFI_IFR_END_OP) {\r
1412 Status = PopScope (&ScopeOpCode);\r
1413 if (EFI_ERROR (Status)) {\r
1414 return Status;\r
1415 }\r
1416\r
1417 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
1418 if (DepthOfDisable == 0) {\r
31585af4 1419 InScopeDisable = FALSE;\r
c60a0616 1420 OpCodeDisabled = FALSE;\r
1421 } else {\r
1422 DepthOfDisable--;\r
1423 }\r
1424 }\r
1425 }\r
1426 continue;\r
1427 }\r
1428\r
1429 if (IsExpressionOpCode (Operand)) {\r
1430 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
1431 mExpressionOpCodeIndex++;\r
1432\r
1433 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
1434 ExpressionOpCode->Operand = Operand;\r
1435 Value = &ExpressionOpCode->Value;\r
1436\r
1437 switch (Operand) {\r
1438 case EFI_IFR_EQ_ID_VAL_OP:\r
1439 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1440\r
1441 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1442 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
1443 break;\r
1444\r
1445 case EFI_IFR_EQ_ID_ID_OP:\r
1446 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
1447 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
1448 break;\r
1449\r
e8ef4283 1450 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
2654f642 1451 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1452 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
1453 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
c60a0616 1454 break;\r
1455\r
1456 case EFI_IFR_TO_STRING_OP:\r
1457 case EFI_IFR_FIND_OP:\r
1458 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
1459 break;\r
1460\r
1461 case EFI_IFR_STRING_REF1_OP:\r
1462 Value->Type = EFI_IFR_TYPE_STRING;\r
1463 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
1464 break;\r
1465\r
1466 case EFI_IFR_RULE_REF_OP:\r
1467 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
1468 break;\r
1469\r
1470 case EFI_IFR_SPAN_OP:\r
1471 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
1472 break;\r
1473\r
1474 case EFI_IFR_THIS_OP:\r
077c7aee
ED
1475 ASSERT (ParentStatement != NULL);\r
1476 ExpressionOpCode->QuestionId = ParentStatement->QuestionId;\r
c60a0616 1477 break;\r
1478\r
cbf73e50 1479 case EFI_IFR_SECURITY_OP:\r
1480 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r
1481 break;\r
1482\r
9bd22b08
ED
1483 case EFI_IFR_MATCH2_OP:\r
1484 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));\r
1485 break;\r
1486\r
2573712e
LG
1487 case EFI_IFR_GET_OP:\r
1488 case EFI_IFR_SET_OP:\r
1489 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r
1490 if (TempVarstoreId != 0) {\r
1491 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
1492 Link = GetFirstNode (&FormSet->StorageListHead);\r
1493 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
1494 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
1495 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {\r
94f3aae7 1496 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;\r
2573712e
LG
1497 break;\r
1498 }\r
1499 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
1500 }\r
1501 }\r
1502 if (ExpressionOpCode->VarStorage == NULL) {\r
1503 //\r
1504 // VarStorage is not found.\r
1505 //\r
1506 return EFI_INVALID_PARAMETER;\r
1507 }\r
1508 }\r
1509 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;\r
1510 switch (ExpressionOpCode->ValueType) {\r
1511 case EFI_IFR_TYPE_BOOLEAN:\r
1512 case EFI_IFR_TYPE_NUM_SIZE_8: \r
1513 ExpressionOpCode->ValueWidth = 1;\r
1514 break;\r
1515\r
1516 case EFI_IFR_TYPE_NUM_SIZE_16:\r
1517 case EFI_IFR_TYPE_STRING:\r
1518 ExpressionOpCode->ValueWidth = 2;\r
1519 break;\r
1520\r
1521 case EFI_IFR_TYPE_NUM_SIZE_32:\r
1522 ExpressionOpCode->ValueWidth = 4;\r
1523 break;\r
1524\r
1525 case EFI_IFR_TYPE_NUM_SIZE_64:\r
1526 ExpressionOpCode->ValueWidth = 8;\r
1527 break;\r
1528\r
1529 case EFI_IFR_TYPE_DATE:\r
c9325700 1530 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);\r
2573712e
LG
1531 break;\r
1532\r
1533 case EFI_IFR_TYPE_TIME:\r
c9325700 1534 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);\r
2573712e
LG
1535 break;\r
1536\r
8ca6180f
ED
1537 case EFI_IFR_TYPE_REF:\r
1538 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);\r
1539 break;\r
1540\r
2573712e
LG
1541 case EFI_IFR_TYPE_OTHER:\r
1542 case EFI_IFR_TYPE_UNDEFINED:\r
1543 case EFI_IFR_TYPE_ACTION:\r
1544 case EFI_IFR_TYPE_BUFFER:\r
1545 default:\r
1546 //\r
1547 // Invalid value type for Get/Set opcode.\r
1548 //\r
1549 return EFI_INVALID_PARAMETER;\r
1550 }\r
1551 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));\r
1552 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));\r
1553 if ((ExpressionOpCode->VarStorage != NULL) && \r
1554 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE || \r
1555 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
1556 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);\r
1557 if (ExpressionOpCode->ValueName == NULL) {\r
1558 //\r
1559 // String ID is invalid.\r
1560 //\r
1561 return EFI_INVALID_PARAMETER;\r
1562 }\r
1563 }\r
1564 break;\r
1565\r
c60a0616 1566 case EFI_IFR_QUESTION_REF1_OP:\r
2654f642 1567 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 1568 break;\r
1569\r
1570 case EFI_IFR_QUESTION_REF3_OP:\r
1571 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
1572 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1573\r
1574 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
1575 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1576 }\r
1577 }\r
1578 break;\r
1579\r
1580 //\r
1581 // constant\r
1582 //\r
1583 case EFI_IFR_TRUE_OP:\r
1584 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1585 Value->Value.b = TRUE;\r
1586 break;\r
1587\r
1588 case EFI_IFR_FALSE_OP:\r
1589 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1590 Value->Value.b = FALSE;\r
1591 break;\r
1592\r
1593 case EFI_IFR_ONE_OP:\r
1594 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1595 Value->Value.u8 = 1;\r
1596 break;\r
1597\r
1598 case EFI_IFR_ZERO_OP:\r
1599 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1600 Value->Value.u8 = 0;\r
1601 break;\r
1602\r
1603 case EFI_IFR_ONES_OP:\r
1604 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1605 Value->Value.u64 = 0xffffffffffffffffULL;\r
1606 break;\r
1607\r
1608 case EFI_IFR_UINT8_OP:\r
1609 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1610 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
1611 break;\r
1612\r
1613 case EFI_IFR_UINT16_OP:\r
1614 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1615 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
1616 break;\r
1617\r
1618 case EFI_IFR_UINT32_OP:\r
1619 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1620 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
1621 break;\r
1622\r
1623 case EFI_IFR_UINT64_OP:\r
1624 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1625 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
1626 break;\r
1627\r
1628 case EFI_IFR_UNDEFINED_OP:\r
d02847d3 1629 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
c60a0616 1630 break;\r
1631\r
1632 case EFI_IFR_VERSION_OP:\r
1633 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1634 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
1635 break;\r
1636\r
1637 default:\r
1638 break;\r
1639 }\r
2573712e
LG
1640 //\r
1641 // Create sub expression nested in MAP opcode\r
1642 //\r
1643 if (CurrentExpression == NULL && MapScopeDepth > 0) {\r
bfae1330 1644 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
771ececd 1645 ASSERT (MapExpressionList != NULL);\r
2573712e
LG
1646 InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
1647 if (Scope == 0) {\r
1648 SingleOpCodeExpression = TRUE;\r
1649 }\r
1650 }\r
f8a1c229 1651 ASSERT (CurrentExpression != NULL);\r
c60a0616 1652 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
2573712e
LG
1653 if (Operand == EFI_IFR_MAP_OP) {\r
1654 //\r
1655 // Store current Map Expression List.\r
1656 //\r
1657 if (MapExpressionList != NULL) {\r
1658 PushMapExpressionList (MapExpressionList);\r
1659 }\r
1660 //\r
1661 // Initialize new Map Expression List.\r
1662 //\r
1663 MapExpressionList = &ExpressionOpCode->MapExpressionList;\r
1664 InitializeListHead (MapExpressionList);\r
1665 //\r
1666 // Store current expression.\r
1667 //\r
1668 PushCurrentExpression (CurrentExpression);\r
1669 CurrentExpression = NULL;\r
1670 MapScopeDepth ++;\r
1671 } else if (SingleOpCodeExpression) {\r
c60a0616 1672 //\r
1673 // There are two cases to indicate the end of an Expression:\r
1674 // for single OpCode expression: one Expression OpCode\r
1675 // for expression consists of more than one OpCode: EFI_IFR_END\r
1676 //\r
1677 SingleOpCodeExpression = FALSE;\r
1678\r
31585af4 1679 if (InScopeDisable && CurrentForm == NULL) {\r
c60a0616 1680 //\r
0a1147ed 1681 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 1682 //\r
1683 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1684 if (EFI_ERROR (Status)) {\r
1685 return Status;\r
1686 }\r
c410589e 1687\r
e6106e89 1688 OpCodeDisabled = IsTrue(&CurrentExpression->Result);\r
c60a0616 1689 }\r
1690\r
1691 CurrentExpression = NULL;\r
1692 }\r
1693\r
1694 continue;\r
1695 }\r
1696\r
1697 //\r
1698 // Parse the Opcode\r
1699 //\r
1700 switch (Operand) {\r
1701\r
1702 case EFI_IFR_FORM_SET_OP:\r
1703 //\r
f8a1c229 1704 // Check the formset GUID\r
c60a0616 1705 //\r
1706 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1707 return EFI_INVALID_PARAMETER;\r
1708 }\r
1709\r
1710 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1711 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
5e30b69e 1712 FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset\r
0a1147ed 1713\r
d228526f
LG
1714 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
1715 //\r
1716 // The formset OpCode contains ClassGuid\r
1717 //\r
1718 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1719 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
1720 }\r
c60a0616 1721 break;\r
1722\r
1723 case EFI_IFR_FORM_OP:\r
1724 //\r
1725 // Create a new Form for this FormSet\r
1726 //\r
1727 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1ac628ee 1728 ASSERT (CurrentForm != NULL);\r
c60a0616 1729 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1730 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1731 InitializeListHead (&CurrentForm->StatementListHead);\r
b18e7050 1732 InitializeListHead (&CurrentForm->ConfigRequestHead);\r
4d4deaac 1733 InitializeListHead (&CurrentForm->FormViewListHead);\r
c60a0616 1734\r
2573712e 1735 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
c60a0616 1736 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1737 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1738\r
31585af4
ED
1739 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);\r
1740 if ( ConditionalExprCount > 0) {\r
0c66bc76
LG
1741 //\r
1742 // Form is inside of suppressif\r
1743 //\r
31585af4
ED
1744 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool( \r
1745 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
1746 ASSERT (CurrentForm->SuppressExpression != NULL);\r
1747 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;\r
1748 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
1749 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
0c66bc76
LG
1750 }\r
1751\r
1752 if (Scope != 0) {\r
1753 //\r
1754 // Enter scope of a Form, suppressif will be used for Question or Option\r
1755 //\r
1756 SuppressForQuestion = TRUE;\r
1757 }\r
1758\r
c60a0616 1759 //\r
1760 // Insert into Form list of this FormSet\r
1761 //\r
1762 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1763 break;\r
1764\r
2573712e
LG
1765 case EFI_IFR_FORM_MAP_OP:\r
1766 //\r
1767 // Create a new Form for this FormSet\r
1768 //\r
1769 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1770 ASSERT (CurrentForm != NULL);\r
1771 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1772 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1773 InitializeListHead (&CurrentForm->StatementListHead);\r
b18e7050 1774 InitializeListHead (&CurrentForm->ConfigRequestHead);\r
4d4deaac
ED
1775 InitializeListHead (&CurrentForm->FormViewListHead);\r
1776\r
2573712e
LG
1777 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1778\r
1779 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1780 //\r
1781 // FormMap Form must contain at least one Map Method.\r
1782 //\r
1783 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
1784 return EFI_INVALID_PARAMETER;\r
1785 }\r
1786 //\r
1787 // Try to find the standard form map method.\r
1788 //\r
1789 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
1790 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
1791 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1792 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1793 break;\r
1794 }\r
1795 MapMethod ++;\r
1796 }\r
1797 //\r
1798 // If the standard form map method is not found, the first map method title will be used.\r
1799 //\r
1800 if (CurrentForm->FormTitle == 0) {\r
1801 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1802 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1803 }\r
1804\r
31585af4
ED
1805 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);\r
1806 if ( ConditionalExprCount > 0) {\r
2573712e
LG
1807 //\r
1808 // Form is inside of suppressif\r
1809 //\r
31585af4
ED
1810 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool( \r
1811 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
1812 ASSERT (CurrentForm->SuppressExpression != NULL);\r
1813 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;\r
1814 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
1815 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
2573712e
LG
1816 }\r
1817\r
1818 if (Scope != 0) {\r
1819 //\r
1820 // Enter scope of a Form, suppressif will be used for Question or Option\r
1821 //\r
1822 SuppressForQuestion = TRUE;\r
1823 }\r
1824\r
1825 //\r
1826 // Insert into Form list of this FormSet\r
1827 //\r
1828 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1829 break;\r
1830\r
c60a0616 1831 //\r
1832 // Storage\r
1833 //\r
1834 case EFI_IFR_VARSTORE_OP:\r
1835 //\r
1836 // Create a buffer Storage for this FormSet\r
1837 //\r
94f3aae7 1838 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);\r
c60a0616 1839 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
c60a0616 1840 break;\r
1841\r
1842 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1843 //\r
1844 // Create a name/value Storage for this FormSet\r
1845 //\r
94f3aae7 1846 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);\r
c60a0616 1847 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
c60a0616 1848 break;\r
1849\r
1850 case EFI_IFR_VARSTORE_EFI_OP:\r
1851 //\r
1852 // Create a EFI variable Storage for this FormSet\r
1853 //\r
cce6230f 1854 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
c0462ea7
ED
1855 //\r
1856 // Create efi varstore with format follow UEFI spec before 2.3.1.\r
1857 //\r
94f3aae7
ED
1858 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);\r
1859 } else {\r
c0462ea7
ED
1860 //\r
1861 // Create efi varstore with format follow UEFI spec 2.3.1 and later.\r
1862 //\r
94f3aae7 1863 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);\r
cce6230f 1864 }\r
94f3aae7 1865 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
c60a0616 1866 break;\r
1867\r
1868 //\r
1869 // DefaultStore\r
1870 //\r
1871 case EFI_IFR_DEFAULTSTORE_OP:\r
1872 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1ac628ee 1873 ASSERT (DefaultStore != NULL);\r
c60a0616 1874 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1875\r
1876 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1877 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1878\r
1879 //\r
1880 // Insert to DefaultStore list of this Formset\r
1881 //\r
1882 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1883 break;\r
1884\r
1885 //\r
1886 // Statements\r
1887 //\r
1888 case EFI_IFR_SUBTITLE_OP:\r
1889 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1890 ASSERT (CurrentStatement != NULL);\r
8b0fc5c1 1891\r
c60a0616 1892 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
7c6c064c 1893 CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
c60a0616 1894 break;\r
1895\r
1896 case EFI_IFR_TEXT_OP:\r
1897 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1898 ASSERT (CurrentStatement != NULL);\r
7c6c064c 1899 CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
c60a0616 1900 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1901 break;\r
1902\r
f8a1c229 1903 case EFI_IFR_RESET_BUTTON_OP:\r
1904 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1905 ASSERT (CurrentStatement != NULL);\r
7c6c064c 1906 CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
f8a1c229 1907 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1908 break;\r
1909\r
c60a0616 1910 //\r
1911 // Questions\r
1912 //\r
1913 case EFI_IFR_ACTION_OP:\r
1914 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1915 ASSERT (CurrentStatement != NULL);\r
d02847d3 1916 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
c60a0616 1917\r
1918 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1919 //\r
1920 // No QuestionConfig present, so no configuration string will be processed\r
1921 //\r
1922 CurrentStatement->QuestionConfig = 0;\r
1923 } else {\r
1924 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1925 }\r
1926 break;\r
1927\r
c60a0616 1928 case EFI_IFR_REF_OP:\r
1929 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1930 ASSERT (CurrentStatement != NULL);\r
8ca6180f
ED
1931 Value = &CurrentStatement->HiiValue;\r
1932 Value->Type = EFI_IFR_TYPE_REF;\r
1933 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {\r
1934 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
c60a0616 1935\r
8ca6180f
ED
1936 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1937 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 1938\r
8ca6180f
ED
1939 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1940 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1941\r
1942 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1943 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1944 }\r
c60a0616 1945 }\r
1946 }\r
1947 }\r
8ca6180f
ED
1948 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF); \r
1949 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1950 break;\r
1951\r
1952 case EFI_IFR_ONE_OF_OP:\r
1953 case EFI_IFR_NUMERIC_OP:\r
1954 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
945e3aed 1955 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1956\r
c60a0616 1957 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1958 Value = &CurrentStatement->HiiValue;\r
1959\r
1960 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1961 case EFI_IFR_NUMERIC_SIZE_1:\r
1962 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1963 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1964 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
cd7bfc2c 1965 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
c60a0616 1966 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1967 break;\r
1968\r
1969 case EFI_IFR_NUMERIC_SIZE_2:\r
1970 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1971 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1972 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
cd7bfc2c 1973 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
c60a0616 1974 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1975 break;\r
1976\r
1977 case EFI_IFR_NUMERIC_SIZE_4:\r
1978 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1979 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1980 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
cd7bfc2c 1981 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
c60a0616 1982 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1983 break;\r
1984\r
1985 case EFI_IFR_NUMERIC_SIZE_8:\r
1986 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1987 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1988 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
cd7bfc2c 1989 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
c60a0616 1990 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1991 break;\r
1992\r
1993 default:\r
1994 break;\r
1995 }\r
1996\r
b18e7050 1997 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1998\r
1999 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
2000 SuppressForOption = TRUE;\r
2001 }\r
2002 break;\r
2003\r
2004 case EFI_IFR_ORDERED_LIST_OP:\r
2005 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2006 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 2007\r
c60a0616 2008 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
2009 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
c60a0616 2010\r
d02847d3 2011 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
b86b413a 2012 CurrentStatement->BufferValue = NULL;\r
c60a0616 2013\r
2014 if (Scope != 0) {\r
2015 SuppressForOption = TRUE;\r
2016 }\r
2017 break;\r
2018\r
2019 case EFI_IFR_CHECKBOX_OP:\r
2020 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2021 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 2022\r
c60a0616 2023 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
cd7bfc2c 2024 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
c60a0616 2025 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
2026\r
b18e7050 2027 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2028\r
2029 break;\r
2030\r
2031 case EFI_IFR_STRING_OP:\r
2032 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2033 ASSERT (CurrentStatement != NULL);\r
c60a0616 2034 //\r
2035 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
2036 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
2037 // The characters are stored as Unicode, so the storage width should multiply 2.\r
2038 //\r
2039 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
2040 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
2041 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
2042 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
2043\r
2044 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
2045 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
e2100bfa 2046 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
c60a0616 2047\r
b18e7050 2048 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2049 break;\r
2050\r
2051 case EFI_IFR_PASSWORD_OP:\r
2052 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2053 ASSERT (CurrentStatement != NULL);\r
c60a0616 2054 //\r
2055 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
2056 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
2057 // The characters are stored as Unicode, so the storage width should multiply 2.\r
2058 //\r
2059 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
2060 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
2061 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
2062\r
2063 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
2064 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
e2100bfa 2065 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
c60a0616 2066\r
b18e7050 2067 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2068 break;\r
2069\r
2070 case EFI_IFR_DATE_OP:\r
2071 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2072 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 2073\r
c60a0616 2074 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
2075 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
2076\r
2077 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
cd7bfc2c 2078 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r
c60a0616 2079\r
b18e7050 2080 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2081 } else {\r
2082 //\r
2083 // Don't assign storage for RTC type of date/time\r
2084 //\r
2085 CurrentStatement->Storage = NULL;\r
2086 CurrentStatement->StorageWidth = 0;\r
2087 }\r
2088 break;\r
2089\r
2090 case EFI_IFR_TIME_OP:\r
2091 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 2092 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 2093\r
c60a0616 2094 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
2095 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
2096\r
2097 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
5ec56d19 2098 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r
c60a0616 2099\r
b18e7050 2100 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 2101 } else {\r
2102 //\r
2103 // Don't assign storage for RTC type of date/time\r
2104 //\r
2105 CurrentStatement->Storage = NULL;\r
2106 CurrentStatement->StorageWidth = 0;\r
2107 }\r
2108 break;\r
2109\r
2110 //\r
2111 // Default\r
2112 //\r
2113 case EFI_IFR_DEFAULT_OP:\r
2114 //\r
2115 // EFI_IFR_DEFAULT appear in scope of a Question,\r
2116 // It creates a default value for the current question.\r
2117 // A Question may have more than one Default value which have different default types.\r
2118 //\r
2119 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1ac628ee 2120 ASSERT (CurrentDefault != NULL);\r
c60a0616 2121 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
2122\r
2123 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
2124 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
0b567d18
ED
2125 if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
2126 CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
2127 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);\r
2128 ASSERT (CurrentDefault->Value.Buffer != NULL);\r
2129 } else {\r
23fe74dc 2130 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
4706ff4f
ED
2131 ExtendValueToU64 (&CurrentDefault->Value);\r
2132 }\r
c60a0616 2133\r
2134 //\r
2135 // Insert to Default Value list of current Question\r
2136 //\r
077c7aee 2137 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
c60a0616 2138\r
2139 if (Scope != 0) {\r
2140 InScopeDefault = TRUE;\r
2141 }\r
2142 break;\r
2143\r
2144 //\r
2145 // Option\r
2146 //\r
2147 case EFI_IFR_ONE_OF_OPTION_OP:\r
aee257db 2148 ASSERT (ParentStatement != NULL);\r
0b567d18
ED
2149 if (ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP && ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {\r
2150 //\r
2151 // It's keep the default value for ordered list opcode.\r
2152 //\r
2153 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
2154 ASSERT (CurrentDefault != NULL);\r
2155 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
2156\r
2157 CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;\r
2158 if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
2159 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
2160 } else {\r
2161 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
2162 }\r
2163\r
2164 CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
2165 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);\r
2166 ASSERT (CurrentDefault->Value.Buffer != NULL);\r
2167\r
2168 //\r
2169 // Insert to Default Value list of current Question\r
2170 //\r
2171 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
2172 break;\r
2173 }\r
2174\r
c60a0616 2175 //\r
2176 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
2177 // It create a selection for use in current Question.\r
2178 //\r
2179 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1ac628ee 2180 ASSERT (CurrentOption != NULL);\r
c60a0616 2181 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
7c6c064c 2182 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;\r
c60a0616 2183\r
2184 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
2185 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
2186 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
a7f87053 2187 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
c60a0616 2188 ExtendValueToU64 (&CurrentOption->Value);\r
2189\r
31585af4
ED
2190 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);\r
2191 if ( ConditionalExprCount > 0) {\r
2192 //\r
2193 // Form is inside of suppressif\r
2194 //\r
2195 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool( \r
2196 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));\r
2197 ASSERT (CurrentOption->SuppressExpression != NULL);\r
2198 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;\r
2199 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;\r
2200 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
c60a0616 2201 }\r
2202\r
2203 //\r
2204 // Insert to Option list of current Question\r
2205 //\r
077c7aee 2206 InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);\r
d02847d3 2207 //\r
2208 // Now we know the Storage width of nested Ordered List\r
2209 //\r
077c7aee 2210 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {\r
d02847d3 2211 Width = 1;\r
2212 switch (CurrentOption->Value.Type) {\r
2213 case EFI_IFR_TYPE_NUM_SIZE_8:\r
2214 Width = 1;\r
2215 break;\r
2216\r
2217 case EFI_IFR_TYPE_NUM_SIZE_16:\r
2218 Width = 2;\r
2219 break;\r
2220\r
2221 case EFI_IFR_TYPE_NUM_SIZE_32:\r
2222 Width = 4;\r
2223 break;\r
2224\r
2225 case EFI_IFR_TYPE_NUM_SIZE_64:\r
2226 Width = 8;\r
2227 break;\r
2228\r
2229 default:\r
2230 //\r
2231 // Invalid type for Ordered List\r
2232 //\r
2233 break;\r
2234 }\r
2235\r
077c7aee
ED
2236 ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);\r
2237 ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);\r
2238 ParentStatement->ValueType = CurrentOption->Value.Type;\r
2239 if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
2240 ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;\r
2241 ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;\r
901ba0e7 2242 }\r
d02847d3 2243\r
077c7aee 2244 InitializeRequestElement (FormSet, ParentStatement, CurrentForm);\r
d02847d3 2245 }\r
c60a0616 2246 break;\r
2247\r
2248 //\r
2249 // Conditional\r
2250 //\r
2251 case EFI_IFR_NO_SUBMIT_IF_OP:\r
2252 case EFI_IFR_INCONSISTENT_IF_OP:\r
2253 //\r
2254 // Create an Expression node\r
2255 //\r
bfae1330 2256 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2257 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
2258\r
2259 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
2260 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
077c7aee 2261 InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
c60a0616 2262 } else {\r
2263 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
077c7aee 2264 InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);\r
c60a0616 2265 }\r
0c66bc76
LG
2266\r
2267 //\r
2268 // Take a look at next OpCode to see whether current expression consists\r
2269 // of single OpCode\r
2270 //\r
2271 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2272 SingleOpCodeExpression = TRUE;\r
2273 }\r
c60a0616 2274 break;\r
2275\r
1c0d306f
ED
2276 case EFI_IFR_WARNING_IF_OP:\r
2277 //\r
2278 // Create an Expression node\r
2279 //\r
bfae1330 2280 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
1c0d306f
ED
2281 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));\r
2282 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;\r
2283 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;\r
077c7aee 2284 InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);\r
1c0d306f
ED
2285\r
2286 //\r
2287 // Take a look at next OpCode to see whether current expression consists\r
2288 // of single OpCode\r
2289 //\r
2290 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2291 SingleOpCodeExpression = TRUE;\r
2292 }\r
2293 break;\r
2294\r
c60a0616 2295 case EFI_IFR_SUPPRESS_IF_OP:\r
2296 //\r
2297 // Question and Option will appear in scope of this OpCode\r
2298 //\r
bfae1330 2299 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2300 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
0c66bc76
LG
2301\r
2302 if (CurrentForm == NULL) {\r
2303 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
2304 } else {\r
2305 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2306 }\r
c60a0616 2307\r
2308 if (SuppressForOption) {\r
31585af4 2309 PushConditionalExpression(CurrentExpression, ExpressOption); \r
0c66bc76 2310 } else if (SuppressForQuestion) {\r
31585af4 2311 PushConditionalExpression(CurrentExpression, ExpressStatement); \r
0c66bc76 2312 } else {\r
31585af4 2313 PushConditionalExpression(CurrentExpression, ExpressForm); \r
0c66bc76
LG
2314 }\r
2315\r
2316 //\r
2317 // Take a look at next OpCode to see whether current expression consists\r
2318 // of single OpCode\r
2319 //\r
2320 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2321 SingleOpCodeExpression = TRUE;\r
c60a0616 2322 }\r
2323 break;\r
2324\r
2325 case EFI_IFR_GRAY_OUT_IF_OP:\r
2326 //\r
2327 // Questions will appear in scope of this OpCode\r
2328 //\r
bfae1330 2329 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2330 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
2331 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
31585af4 2332 PushConditionalExpression(CurrentExpression, ExpressStatement);\r
0c66bc76
LG
2333\r
2334 //\r
2335 // Take a look at next OpCode to see whether current expression consists\r
2336 // of single OpCode\r
2337 //\r
2338 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2339 SingleOpCodeExpression = TRUE;\r
2340 }\r
c60a0616 2341 break;\r
2342\r
2343 case EFI_IFR_DISABLE_IF_OP:\r
2344 //\r
2345 // The DisableIf expression should only rely on constant, so it could be\r
2346 // evaluated at initialization and it will not be queued\r
2347 //\r
2348 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1ac628ee 2349 ASSERT (CurrentExpression != NULL);\r
c60a0616 2350 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
2351 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
2352 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
2353\r
0a1147ed
LG
2354 if (CurrentForm != NULL) {\r
2355 //\r
2356 // This is DisableIf for Question, enqueue it to Form expression list\r
2357 //\r
2358 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
31585af4 2359 PushConditionalExpression(CurrentExpression, ExpressStatement);\r
0a1147ed
LG
2360 }\r
2361\r
31585af4
ED
2362 OpCodeDisabled = FALSE;\r
2363 InScopeDisable = TRUE;\r
c60a0616 2364 //\r
2365 // Take a look at next OpCode to see whether current expression consists\r
2366 // of single OpCode\r
2367 //\r
2368 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2369 SingleOpCodeExpression = TRUE;\r
2370 }\r
2371 break;\r
2372\r
2373 //\r
2374 // Expression\r
2375 //\r
2376 case EFI_IFR_VALUE_OP:\r
bfae1330 2377 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2378 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
2379 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2380\r
2381 if (InScopeDefault) {\r
2382 //\r
2383 // Used for default (EFI_IFR_DEFAULT)\r
2384 //\r
2385 CurrentDefault->ValueExpression = CurrentExpression;\r
2386 } else {\r
2387 //\r
2388 // If used for a question, then the question will be read-only\r
2389 //\r
bc166db3 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->ValueExpression = CurrentExpression;\r
c60a0616 2397 }\r
0c66bc76
LG
2398\r
2399 //\r
2400 // Take a look at next OpCode to see whether current expression consists\r
2401 // of single OpCode\r
2402 //\r
2403 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2404 SingleOpCodeExpression = TRUE;\r
2405 }\r
c60a0616 2406 break;\r
2407\r
2408 case EFI_IFR_RULE_OP:\r
bfae1330 2409 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
c60a0616 2410 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
2411\r
2412 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
2413 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
0c66bc76
LG
2414\r
2415 //\r
2416 // Take a look at next OpCode to see whether current expression consists\r
2417 // of single OpCode\r
2418 //\r
2419 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2420 SingleOpCodeExpression = TRUE;\r
2421 }\r
c60a0616 2422 break;\r
2423\r
2573712e 2424 case EFI_IFR_READ_OP:\r
bfae1330 2425 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
2573712e
LG
2426 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
2427 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2428\r
2429 //\r
2430 // Make sure CurrentStatement is not NULL.\r
2431 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2432 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
2433 //\r
077c7aee
ED
2434 ASSERT (ParentStatement != NULL);\r
2435 ParentStatement->ReadExpression = CurrentExpression;\r
2573712e
LG
2436\r
2437 //\r
2438 // Take a look at next OpCode to see whether current expression consists\r
2439 // of single OpCode\r
2440 //\r
2441 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2442 SingleOpCodeExpression = TRUE;\r
2443 }\r
2444 break;\r
2445\r
2446 case EFI_IFR_WRITE_OP:\r
bfae1330 2447 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
2573712e
LG
2448 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
2449 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2450\r
2451 //\r
2452 // Make sure CurrentStatement is not NULL.\r
2453 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2454 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
2455 //\r
077c7aee
ED
2456 ASSERT (ParentStatement != NULL);\r
2457 ParentStatement->WriteExpression = CurrentExpression;\r
2573712e
LG
2458\r
2459 //\r
2460 // Take a look at next OpCode to see whether current expression consists\r
2461 // of single OpCode\r
2462 //\r
2463 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2464 SingleOpCodeExpression = TRUE;\r
2465 }\r
2466 break;\r
2467\r
c60a0616 2468 //\r
2469 // Image\r
2470 //\r
2471 case EFI_IFR_IMAGE_OP:\r
2472 //\r
2473 // Get ScopeOpcode from top of stack\r
2474 //\r
2475 PopScope (&ScopeOpCode);\r
2476 PushScope (ScopeOpCode);\r
2477\r
2478 switch (ScopeOpCode) {\r
2479 case EFI_IFR_FORM_SET_OP:\r
2480 ImageId = &FormSet->ImageId;\r
2481 break;\r
2482\r
2483 case EFI_IFR_FORM_OP:\r
2573712e 2484 case EFI_IFR_FORM_MAP_OP:\r
d0720b57 2485 ASSERT (CurrentForm != NULL);\r
c60a0616 2486 ImageId = &CurrentForm->ImageId;\r
2487 break;\r
2488\r
2489 case EFI_IFR_ONE_OF_OPTION_OP:\r
523f48e7 2490 ASSERT (CurrentOption != NULL);\r
c60a0616 2491 ImageId = &CurrentOption->ImageId;\r
2492 break;\r
2493\r
2494 default:\r
bc166db3 2495 //\r
2496 // Make sure CurrentStatement is not NULL.\r
2497 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2498 // file is wrongly generated by tools such as VFR Compiler.\r
2499 //\r
077c7aee
ED
2500 ASSERT (ParentStatement != NULL);\r
2501 ImageId = &ParentStatement->ImageId;\r
c60a0616 2502 break;\r
2503 }\r
2504\r
c410589e 2505 ASSERT (ImageId != NULL);\r
c60a0616 2506 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
2507 break;\r
2508\r
2509 //\r
2510 // Refresh\r
2511 //\r
2512 case EFI_IFR_REFRESH_OP:\r
077c7aee
ED
2513 ASSERT (ParentStatement != NULL);\r
2514 ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
c60a0616 2515 break;\r
2516\r
211cc6e5
ED
2517 //\r
2518 // Refresh guid.\r
2519 //\r
2520 case EFI_IFR_REFRESH_ID_OP:\r
790447b2
ED
2521 //\r
2522 // Get ScopeOpcode from top of stack\r
2523 //\r
2524 PopScope (&ScopeOpCode);\r
2525 PushScope (ScopeOpCode);\r
2526\r
2527 switch (ScopeOpCode) {\r
2528 case EFI_IFR_FORM_OP:\r
2529 case EFI_IFR_FORM_MAP_OP:\r
2530 ASSERT (CurrentForm != NULL);\r
2531 CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
2532 break;\r
2533\r
2534 default:\r
2535 ASSERT (ParentStatement != NULL);\r
2536 CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
2537 break;\r
2538 }\r
211cc6e5
ED
2539 break;\r
2540\r
b00964a9
ED
2541 //\r
2542 // Modal tag\r
2543 //\r
2544 case EFI_IFR_MODAL_TAG_OP:\r
2545 ASSERT (CurrentForm != NULL);\r
2546 CurrentForm->ModalForm = TRUE;\r
2547 break;\r
2548\r
f67c4382
ED
2549 //\r
2550 // Lock tag, used by form and statement.\r
2551 //\r
2552 case EFI_IFR_LOCKED_OP:\r
2553 //\r
2554 // Get ScopeOpcode from top of stack\r
2555 //\r
2556 PopScope (&ScopeOpCode);\r
2557 PushScope (ScopeOpCode);\r
2558 switch (ScopeOpCode) {\r
2559 case EFI_IFR_FORM_OP:\r
2560 case EFI_IFR_FORM_MAP_OP:\r
2561 ASSERT (CurrentForm != NULL);\r
2562 CurrentForm->Locked = TRUE;\r
2563 break;\r
2564\r
2565 default:\r
077c7aee
ED
2566 ASSERT (ParentStatement != NULL);\r
2567 ParentStatement->Locked = TRUE;\r
f67c4382
ED
2568 } \r
2569 break;\r
2570\r
c60a0616 2571 //\r
2572 // Vendor specific\r
2573 //\r
7c6c064c
ED
2574 case EFI_IFR_GUID_OP: \r
2575 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
c60a0616 2576 break;\r
2577\r
2578 //\r
2579 // Scope End\r
2580 //\r
2581 case EFI_IFR_END_OP:\r
2582 Status = PopScope (&ScopeOpCode);\r
2583 if (EFI_ERROR (Status)) {\r
2584 ResetScopeStack ();\r
2585 return Status;\r
2586 }\r
077c7aee
ED
2587 \r
2588 //\r
2589 // Parent statement end tag found, update ParentStatement info.\r
2590 //\r
5fdd2a81 2591 if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {\r
077c7aee
ED
2592 ParentStatement = ParentStatement->ParentStatement;\r
2593 }\r
c60a0616 2594\r
2595 switch (ScopeOpCode) {\r
2596 case EFI_IFR_FORM_SET_OP:\r
2597 //\r
2598 // End of FormSet, update FormSet IFR binary length\r
2599 // to stop parsing substantial OpCodes\r
2600 //\r
2601 FormSet->IfrBinaryLength = OpCodeOffset;\r
2602 break;\r
2603\r
2604 case EFI_IFR_FORM_OP:\r
2573712e 2605 case EFI_IFR_FORM_MAP_OP:\r
c60a0616 2606 //\r
2607 // End of Form\r
2608 //\r
2609 CurrentForm = NULL;\r
0c66bc76 2610 SuppressForQuestion = FALSE;\r
c60a0616 2611 break;\r
2612\r
2613 case EFI_IFR_ONE_OF_OPTION_OP:\r
2614 //\r
2615 // End of Option\r
2616 //\r
2617 CurrentOption = NULL;\r
2618 break;\r
2619\r
c60a0616 2620 case EFI_IFR_NO_SUBMIT_IF_OP:\r
2621 case EFI_IFR_INCONSISTENT_IF_OP:\r
1c0d306f 2622 case EFI_IFR_WARNING_IF_OP:\r
c60a0616 2623 //\r
2624 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
2625 //\r
2626 break;\r
2627\r
2628 case EFI_IFR_SUPPRESS_IF_OP:\r
2629 if (SuppressForOption) {\r
31585af4 2630 PopConditionalExpression(ExpressOption); \r
0c66bc76 2631 } else if (SuppressForQuestion) {\r
31585af4 2632 PopConditionalExpression(ExpressStatement);\r
0c66bc76 2633 } else {\r
31585af4 2634 PopConditionalExpression(ExpressForm);\r
c60a0616 2635 }\r
2636 break;\r
2637\r
2638 case EFI_IFR_GRAY_OUT_IF_OP:\r
31585af4 2639 PopConditionalExpression(ExpressStatement);\r
c60a0616 2640 break;\r
2641\r
2642 case EFI_IFR_DISABLE_IF_OP:\r
31585af4
ED
2643 if (CurrentForm != NULL) {\r
2644 PopConditionalExpression(ExpressStatement);\r
2645 }\r
2646 InScopeDisable = FALSE;\r
c60a0616 2647 OpCodeDisabled = FALSE;\r
2648 break;\r
2649\r
2650 case EFI_IFR_ONE_OF_OP:\r
2651 case EFI_IFR_ORDERED_LIST_OP:\r
2652 SuppressForOption = FALSE;\r
2653 break;\r
2654\r
2655 case EFI_IFR_DEFAULT_OP:\r
2656 InScopeDefault = FALSE;\r
2657 break;\r
2658\r
2573712e
LG
2659 case EFI_IFR_MAP_OP:\r
2660 //\r
2661 // Get current Map Expression List.\r
2662 //\r
2663 Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r
2664 if (Status == EFI_ACCESS_DENIED) {\r
2665 MapExpressionList = NULL;\r
2666 }\r
2667 //\r
2668 // Get current expression.\r
2669 //\r
2670 Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r
2671 ASSERT_EFI_ERROR (Status);\r
771ececd 2672 ASSERT (MapScopeDepth > 0);\r
2573712e
LG
2673 MapScopeDepth --;\r
2674 break;\r
2675\r
c60a0616 2676 default:\r
2677 if (IsExpressionOpCode (ScopeOpCode)) {\r
31585af4 2678 if (InScopeDisable && CurrentForm == NULL) {\r
c60a0616 2679 //\r
0a1147ed 2680 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 2681 //\r
f8a1c229 2682 ASSERT (CurrentExpression != NULL);\r
c60a0616 2683 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
2684 if (EFI_ERROR (Status)) {\r
2685 return Status;\r
2686 }\r
a935a0d8 2687\r
e6106e89 2688 OpCodeDisabled = IsTrue (&CurrentExpression->Result);\r
c60a0616 2689\r
c60a0616 2690 //\r
2573712e 2691 // DisableIf Expression is only used once and not queued, free it\r
c60a0616 2692 //\r
2693 DestroyExpression (CurrentExpression);\r
2694 }\r
2695\r
2696 //\r
2697 // End of current Expression\r
2698 //\r
2699 CurrentExpression = NULL;\r
2700 }\r
2701 break;\r
2702 }\r
2703 break;\r
2704\r
2705 default:\r
2706 break;\r
2707 }\r
077c7aee
ED
2708\r
2709 if (IsStatementOpCode(Operand)) {\r
2710 CurrentStatement->ParentStatement = ParentStatement;\r
2711 if (Scope != 0) {\r
2712 //\r
2713 // Scope != 0, other statements or options may nest in this statement.\r
2714 // Update the ParentStatement info.\r
2715 //\r
2716 ParentStatement = CurrentStatement;\r
2717 }\r
2718 }\r
c60a0616 2719 }\r
2720\r
2721 return EFI_SUCCESS;\r
2722}\r