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