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