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