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