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