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