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