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