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