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