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