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