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