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