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