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