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