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