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