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