]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Add PI complied S3 implementation. Include the Opcode definition and EFI_BOOT_SCRIPT_...
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
... / ...
CommitLineData
1/** @file\r
2Parser for IFR binary encoding.\r
3\r
4Copyright (c) 2007 - 2009, Intel Corporation\r
5All rights reserved. This 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
19\r
20BOOLEAN mInScopeSubtitle;\r
21BOOLEAN mInScopeSuppress;\r
22BOOLEAN mInScopeGrayOut;\r
23BOOLEAN mInScopeDisable;\r
24FORM_EXPRESSION *mSuppressExpression;\r
25FORM_EXPRESSION *mGrayOutExpression;\r
26FORM_EXPRESSION *mDisableExpression;\r
27\r
28/**\r
29 Initialize Statement header members.\r
30\r
31 @param OpCodeData Pointer of the raw OpCode data.\r
32 @param FormSet Pointer of the current FormSe.\r
33 @param Form Pointer of the current Form.\r
34\r
35 @return The Statement.\r
36\r
37**/\r
38FORM_BROWSER_STATEMENT *\r
39CreateStatement (\r
40 IN UINT8 *OpCodeData,\r
41 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
42 IN OUT FORM_BROWSER_FORM *Form\r
43 )\r
44{\r
45 FORM_BROWSER_STATEMENT *Statement;\r
46 EFI_IFR_STATEMENT_HEADER *StatementHdr;\r
47\r
48 if (Form == NULL) {\r
49 //\r
50 // We are currently not in a Form Scope, so just skip this Statement\r
51 //\r
52 return NULL;\r
53 }\r
54\r
55 Statement = &FormSet->StatementBuffer[mStatementIndex];\r
56 mStatementIndex++;\r
57\r
58 InitializeListHead (&Statement->DefaultListHead);\r
59 InitializeListHead (&Statement->OptionListHead);\r
60 InitializeListHead (&Statement->InconsistentListHead);\r
61 InitializeListHead (&Statement->NoSubmitListHead);\r
62\r
63 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
64\r
65 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
66\r
67 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
68 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
69 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
70\r
71 if (mInScopeSuppress) {\r
72 Statement->SuppressExpression = mSuppressExpression;\r
73 }\r
74\r
75 if (mInScopeGrayOut) {\r
76 Statement->GrayOutExpression = mGrayOutExpression;\r
77 }\r
78\r
79\r
80 if (mInScopeDisable) {\r
81 Statement->DisableExpression = mDisableExpression;\r
82 }\r
83\r
84 Statement->InSubtitle = mInScopeSubtitle;\r
85\r
86 //\r
87 // Insert this Statement into current Form\r
88 //\r
89 InsertTailList (&Form->StatementListHead, &Statement->Link);\r
90\r
91 return Statement;\r
92}\r
93\r
94/**\r
95 Convert a numeric value to a Unicode String and insert it to String Package.\r
96 This string is used as the Unicode Name for the EFI Variable. This is to support\r
97 the deprecated vareqval opcode.\r
98\r
99 @param FormSet The FormSet.\r
100 @param Statement The numeric question whose VarStoreInfo.VarName is the\r
101 numeric value which is used to produce the Unicode Name\r
102 for the EFI Variable.\r
103\r
104 If the Statement is NULL, the ASSERT.\r
105 If the opcode is not Numeric, then ASSERT.\r
106\r
107 @retval EFI_SUCCESS The funtion always succeeds.\r
108**/\r
109EFI_STATUS\r
110UpdateCheckBoxStringToken (\r
111 IN CONST FORM_BROWSER_FORMSET *FormSet,\r
112 IN FORM_BROWSER_STATEMENT *Statement\r
113 )\r
114{\r
115 CHAR16 Str[MAXIMUM_VALUE_CHARACTERS];\r
116 EFI_STRING_ID Id;\r
117\r
118 ASSERT (Statement != NULL);\r
119 ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);\r
120\r
121 UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
122\r
123 Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);\r
124 if (Id == 0) {\r
125 return EFI_OUT_OF_RESOURCES;\r
126 }\r
127\r
128 Statement->VarStoreInfo.VarName = Id;\r
129\r
130 return EFI_SUCCESS;\r
131}\r
132\r
133/**\r
134 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.\r
135\r
136 @param OpCodeData The current opcode.\r
137\r
138 @retval TRUE Yes.\r
139 @retval FALSE No.\r
140**/\r
141BOOLEAN\r
142IsNextOpCodeGuidedVarEqName (\r
143 IN UINT8 *OpCodeData\r
144 )\r
145{\r
146 //\r
147 // Get next opcode\r
148 //\r
149 OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
150 if (*OpCodeData == EFI_IFR_GUID_OP) {\r
151 if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
152 //\r
153 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR\r
154 //\r
155 if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {\r
156 return TRUE;\r
157 }\r
158 }\r
159 }\r
160\r
161 return FALSE;\r
162}\r
163\r
164/**\r
165 Initialize Question's members.\r
166\r
167 @param OpCodeData Pointer of the raw OpCode data.\r
168 @param FormSet Pointer of the current FormSet.\r
169 @param Form Pointer of the current Form.\r
170\r
171 @return The Question.\r
172\r
173**/\r
174FORM_BROWSER_STATEMENT *\r
175CreateQuestion (\r
176 IN UINT8 *OpCodeData,\r
177 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
178 IN OUT FORM_BROWSER_FORM *Form\r
179 )\r
180{\r
181 FORM_BROWSER_STATEMENT *Statement;\r
182 EFI_IFR_QUESTION_HEADER *QuestionHdr;\r
183 LIST_ENTRY *Link;\r
184 FORMSET_STORAGE *Storage;\r
185 NAME_VALUE_NODE *NameValueNode;\r
186 EFI_STATUS Status;\r
187\r
188 Statement = CreateStatement (OpCodeData, FormSet, Form);\r
189 if (Statement == NULL) {\r
190 return NULL;\r
191 }\r
192\r
193 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
194 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
195 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
196 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
197\r
198 Statement->QuestionFlags = QuestionHdr->Flags;\r
199\r
200 if (Statement->VarStoreId == 0) {\r
201 //\r
202 // VarStoreId of zero indicates no variable storage\r
203 //\r
204 return Statement;\r
205 }\r
206\r
207 //\r
208 // Take a look at next OpCode to see whether it is a GUIDed opcode to support\r
209 // Framework Compatibility\r
210 //\r
211 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
212 if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {\r
213 Status = UpdateCheckBoxStringToken (FormSet, Statement);\r
214 if (EFI_ERROR (Status)) {\r
215 return NULL;\r
216 }\r
217 }\r
218 }\r
219\r
220 //\r
221 // Find Storage for this Question\r
222 //\r
223 Link = GetFirstNode (&FormSet->StorageListHead);\r
224 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
225 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
226\r
227 if (Storage->VarStoreId == Statement->VarStoreId) {\r
228 Statement->Storage = Storage;\r
229 break;\r
230 }\r
231\r
232 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
233 }\r
234 ASSERT (Statement->Storage != NULL);\r
235\r
236 //\r
237 // Initialilze varname for Name/Value or EFI Variable\r
238 //\r
239 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
240 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
241 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
242 ASSERT (Statement->VariableName != NULL);\r
243\r
244 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
245 //\r
246 // Insert to Name/Value varstore list\r
247 //\r
248 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
249 ASSERT (NameValueNode != NULL);\r
250 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
251 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
252 ASSERT (NameValueNode->Name != NULL);\r
253 NameValueNode->Value = AllocateZeroPool (0x10);\r
254 ASSERT (NameValueNode->Value != NULL);\r
255 NameValueNode->EditValue = AllocateZeroPool (0x10);\r
256 ASSERT (NameValueNode->EditValue != NULL);\r
257\r
258 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
259 }\r
260 }\r
261\r
262 return Statement;\r
263}\r
264\r
265\r
266/**\r
267 Allocate a FORM_EXPRESSION node.\r
268\r
269 @param Form The Form associated with this Expression\r
270\r
271 @return Pointer to a FORM_EXPRESSION data structure.\r
272\r
273**/\r
274FORM_EXPRESSION *\r
275CreateExpression (\r
276 IN OUT FORM_BROWSER_FORM *Form\r
277 )\r
278{\r
279 FORM_EXPRESSION *Expression;\r
280\r
281 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
282 ASSERT (Expression != NULL);\r
283 Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
284 InitializeListHead (&Expression->OpCodeListHead);\r
285\r
286 return Expression;\r
287}\r
288\r
289\r
290/**\r
291 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
292\r
293 @param FormSet Pointer of the current FormSet\r
294\r
295 @return Pointer to a FORMSET_STORAGE data structure.\r
296\r
297**/\r
298FORMSET_STORAGE *\r
299CreateStorage (\r
300 IN FORM_BROWSER_FORMSET *FormSet\r
301 )\r
302{\r
303 FORMSET_STORAGE *Storage;\r
304\r
305 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
306 ASSERT (Storage != NULL);\r
307 Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
308 InitializeListHead (&Storage->NameValueListHead);\r
309 InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
310\r
311 return Storage;\r
312}\r
313\r
314\r
315/**\r
316 Create ConfigHdr string for a storage.\r
317\r
318 @param FormSet Pointer of the current FormSet\r
319 @param Storage Pointer of the storage\r
320\r
321 @retval EFI_SUCCESS Initialize ConfigHdr success\r
322\r
323**/\r
324EFI_STATUS\r
325InitializeConfigHdr (\r
326 IN FORM_BROWSER_FORMSET *FormSet,\r
327 IN OUT FORMSET_STORAGE *Storage\r
328 )\r
329{\r
330 CHAR16 *Name;\r
331\r
332 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
333 Name = Storage->Name;\r
334 } else {\r
335 Name = NULL;\r
336 }\r
337\r
338 Storage->ConfigHdr = HiiConstructConfigHdr (\r
339 &Storage->Guid,\r
340 Name,\r
341 FormSet->DriverHandle\r
342 );\r
343\r
344 if (Storage->ConfigHdr == NULL) {\r
345 return EFI_NOT_FOUND;\r
346 }\r
347\r
348 Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
349 Storage->SpareStrLen = 0;\r
350\r
351 return EFI_SUCCESS;\r
352}\r
353\r
354\r
355/**\r
356 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
357\r
358 @param FormSet Pointer of the current FormSet.\r
359 @param Question The Question to be initialized.\r
360\r
361 @retval EFI_SUCCESS Function success.\r
362 @retval EFI_INVALID_PARAMETER No storage associated with the Question.\r
363\r
364**/\r
365EFI_STATUS\r
366InitializeRequestElement (\r
367 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
368 IN OUT FORM_BROWSER_STATEMENT *Question\r
369 )\r
370{\r
371 FORMSET_STORAGE *Storage;\r
372 UINTN StrLen;\r
373 UINTN StringSize;\r
374 CHAR16 *NewStr;\r
375 CHAR16 RequestElement[30];\r
376\r
377 Storage = Question->Storage;\r
378 if (Storage == NULL) {\r
379 return EFI_INVALID_PARAMETER;\r
380 }\r
381\r
382 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
383 //\r
384 // <ConfigRequest> is unnecessary for EFI variable storage,\r
385 // GetVariable()/SetVariable() will be used to retrieve/save values\r
386 //\r
387 return EFI_SUCCESS;\r
388 }\r
389\r
390 //\r
391 // Prepare <RequestElement>\r
392 //\r
393 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
394 StrLen = UnicodeSPrint (\r
395 RequestElement,\r
396 30 * sizeof (CHAR16),\r
397 L"&OFFSET=%x&WIDTH=%x",\r
398 Question->VarStoreInfo.VarOffset,\r
399 Question->StorageWidth\r
400 );\r
401 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
402 } else {\r
403 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
404 }\r
405\r
406 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {\r
407 //\r
408 // Password with CALLBACK flag is stored in encoded format,\r
409 // so don't need to append it to <ConfigRequest>\r
410 //\r
411 return EFI_SUCCESS;\r
412 }\r
413\r
414 //\r
415 // Append <RequestElement> to <ConfigRequest>\r
416 //\r
417 if (StrLen > Storage->SpareStrLen) {\r
418 //\r
419 // Old String buffer is not sufficient for RequestElement, allocate a new one\r
420 //\r
421 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);\r
422 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
423 ASSERT (NewStr != NULL);\r
424 if (Storage->ConfigRequest != NULL) {\r
425 CopyMem (NewStr, Storage->ConfigRequest, StringSize);\r
426 FreePool (Storage->ConfigRequest);\r
427 }\r
428 Storage->ConfigRequest = NewStr;\r
429 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
430 }\r
431\r
432 StrCat (Storage->ConfigRequest, RequestElement);\r
433 Storage->ElementCount++;\r
434 Storage->SpareStrLen -= StrLen;\r
435\r
436 return EFI_SUCCESS;\r
437}\r
438\r
439\r
440/**\r
441 Free resources of a Expression.\r
442\r
443 @param FormSet Pointer of the Expression\r
444\r
445**/\r
446VOID\r
447DestroyExpression (\r
448 IN FORM_EXPRESSION *Expression\r
449 )\r
450{\r
451 LIST_ENTRY *Link;\r
452 EXPRESSION_OPCODE *OpCode;\r
453\r
454 while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
455 Link = GetFirstNode (&Expression->OpCodeListHead);\r
456 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
457 RemoveEntryList (&OpCode->Link);\r
458\r
459 if (OpCode->ValueList != NULL) {\r
460 FreePool (OpCode->ValueList);\r
461 }\r
462 }\r
463\r
464 //\r
465 // Free this Expression\r
466 //\r
467 FreePool (Expression);\r
468}\r
469\r
470\r
471/**\r
472 Free resources of a storage.\r
473\r
474 @param Storage Pointer of the storage\r
475\r
476**/\r
477VOID\r
478DestroyStorage (\r
479 IN FORMSET_STORAGE *Storage\r
480 )\r
481{\r
482 LIST_ENTRY *Link;\r
483 NAME_VALUE_NODE *NameValueNode;\r
484\r
485 if (Storage == NULL) {\r
486 return;\r
487 }\r
488\r
489 if (Storage->Name != NULL) {\r
490 FreePool (Storage->Name);\r
491 }\r
492 if (Storage->Buffer != NULL) {\r
493 FreePool (Storage->Buffer);\r
494 }\r
495 if (Storage->EditBuffer != NULL) {\r
496 FreePool (Storage->EditBuffer);\r
497 }\r
498\r
499 while (!IsListEmpty (&Storage->NameValueListHead)) {\r
500 Link = GetFirstNode (&Storage->NameValueListHead);\r
501 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
502 RemoveEntryList (&NameValueNode->Link);\r
503\r
504 if (NameValueNode->Name != NULL) {\r
505 FreePool (NameValueNode->Name);\r
506 }\r
507 if (NameValueNode->Value != NULL) {\r
508 FreePool (NameValueNode->Value);\r
509 }\r
510 if (NameValueNode->EditValue != NULL) {\r
511 FreePool (NameValueNode->EditValue);\r
512 }\r
513 FreePool (NameValueNode);\r
514 }\r
515\r
516 if (Storage->ConfigHdr != NULL) {\r
517 FreePool (Storage->ConfigHdr);\r
518 }\r
519 if (Storage->ConfigRequest != NULL) {\r
520 FreePool (Storage->ConfigRequest);\r
521 }\r
522\r
523 FreePool (Storage);\r
524}\r
525\r
526\r
527/**\r
528 Free resources of a Statement.\r
529\r
530 @param Statement Pointer of the Statement\r
531\r
532**/\r
533VOID\r
534DestroyStatement (\r
535 IN OUT FORM_BROWSER_STATEMENT *Statement\r
536 )\r
537{\r
538 LIST_ENTRY *Link;\r
539 QUESTION_DEFAULT *Default;\r
540 QUESTION_OPTION *Option;\r
541 FORM_EXPRESSION *Expression;\r
542\r
543 //\r
544 // Free Default value List\r
545 //\r
546 while (!IsListEmpty (&Statement->DefaultListHead)) {\r
547 Link = GetFirstNode (&Statement->DefaultListHead);\r
548 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
549 RemoveEntryList (&Default->Link);\r
550\r
551 FreePool (Default);\r
552 }\r
553\r
554 //\r
555 // Free Options List\r
556 //\r
557 while (!IsListEmpty (&Statement->OptionListHead)) {\r
558 Link = GetFirstNode (&Statement->OptionListHead);\r
559 Option = QUESTION_OPTION_FROM_LINK (Link);\r
560 RemoveEntryList (&Option->Link);\r
561\r
562 FreePool (Option);\r
563 }\r
564\r
565 //\r
566 // Free Inconsistent List\r
567 //\r
568 while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
569 Link = GetFirstNode (&Statement->InconsistentListHead);\r
570 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
571 RemoveEntryList (&Expression->Link);\r
572\r
573 DestroyExpression (Expression);\r
574 }\r
575\r
576 //\r
577 // Free NoSubmit List\r
578 //\r
579 while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
580 Link = GetFirstNode (&Statement->NoSubmitListHead);\r
581 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
582 RemoveEntryList (&Expression->Link);\r
583\r
584 DestroyExpression (Expression);\r
585 }\r
586\r
587 if (Statement->VariableName != NULL) {\r
588 FreePool (Statement->VariableName);\r
589 }\r
590 if (Statement->BlockName != NULL) {\r
591 FreePool (Statement->BlockName);\r
592 }\r
593}\r
594\r
595\r
596/**\r
597 Free resources of a Form.\r
598\r
599 @param Form Pointer of the Form.\r
600\r
601**/\r
602VOID\r
603DestroyForm (\r
604 IN OUT FORM_BROWSER_FORM *Form\r
605 )\r
606{\r
607 LIST_ENTRY *Link;\r
608 FORM_EXPRESSION *Expression;\r
609 FORM_BROWSER_STATEMENT *Statement;\r
610\r
611 //\r
612 // Free Form Expressions\r
613 //\r
614 while (!IsListEmpty (&Form->ExpressionListHead)) {\r
615 Link = GetFirstNode (&Form->ExpressionListHead);\r
616 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
617 RemoveEntryList (&Expression->Link);\r
618\r
619 DestroyExpression (Expression);\r
620 }\r
621\r
622 //\r
623 // Free Statements/Questions\r
624 //\r
625 while (!IsListEmpty (&Form->StatementListHead)) {\r
626 Link = GetFirstNode (&Form->StatementListHead);\r
627 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
628 RemoveEntryList (&Statement->Link);\r
629\r
630 DestroyStatement (Statement);\r
631 }\r
632\r
633 //\r
634 // Free this Form\r
635 //\r
636 FreePool (Form);\r
637}\r
638\r
639\r
640/**\r
641 Free resources allocated for a FormSet.\r
642\r
643 @param FormSet Pointer of the FormSet\r
644\r
645**/\r
646VOID\r
647DestroyFormSet (\r
648 IN OUT FORM_BROWSER_FORMSET *FormSet\r
649 )\r
650{\r
651 LIST_ENTRY *Link;\r
652 FORMSET_STORAGE *Storage;\r
653 FORMSET_DEFAULTSTORE *DefaultStore;\r
654 FORM_EXPRESSION *Expression;\r
655 FORM_BROWSER_FORM *Form;\r
656\r
657 if (FormSet->IfrBinaryData == NULL) {\r
658 //\r
659 // Uninitialized FormSet\r
660 //\r
661 FreePool (FormSet);\r
662 return;\r
663 }\r
664\r
665 //\r
666 // Free IFR binary buffer\r
667 //\r
668 FreePool (FormSet->IfrBinaryData);\r
669\r
670 //\r
671 // Free FormSet Storage\r
672 //\r
673 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
674 while (!IsListEmpty (&FormSet->StorageListHead)) {\r
675 Link = GetFirstNode (&FormSet->StorageListHead);\r
676 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
677 RemoveEntryList (&Storage->Link);\r
678\r
679 DestroyStorage (Storage);\r
680 }\r
681 }\r
682\r
683 //\r
684 // Free FormSet Default Store\r
685 //\r
686 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
687 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
688 Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
689 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
690 RemoveEntryList (&DefaultStore->Link);\r
691\r
692 FreePool (DefaultStore);\r
693 }\r
694 }\r
695\r
696 //\r
697 // Free Formset Expressions\r
698 //\r
699 while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
700 Link = GetFirstNode (&FormSet->ExpressionListHead);\r
701 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
702 RemoveEntryList (&Expression->Link);\r
703\r
704 DestroyExpression (Expression);\r
705 }\r
706\r
707 //\r
708 // Free Forms\r
709 //\r
710 if (FormSet->FormListHead.ForwardLink != NULL) {\r
711 while (!IsListEmpty (&FormSet->FormListHead)) {\r
712 Link = GetFirstNode (&FormSet->FormListHead);\r
713 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
714 RemoveEntryList (&Form->Link);\r
715\r
716 DestroyForm (Form);\r
717 }\r
718 }\r
719\r
720 if (FormSet->StatementBuffer != NULL) {\r
721 FreePool (FormSet->StatementBuffer);\r
722 }\r
723 if (FormSet->ExpressionBuffer != NULL) {\r
724 FreePool (FormSet->ExpressionBuffer);\r
725 }\r
726\r
727 FreePool (FormSet);\r
728}\r
729\r
730\r
731/**\r
732 Tell whether this Operand is an Expression OpCode or not\r
733\r
734 @param Operand Operand of an IFR OpCode.\r
735\r
736 @retval TRUE This is an Expression OpCode.\r
737 @retval FALSE Not an Expression OpCode.\r
738\r
739**/\r
740BOOLEAN\r
741IsExpressionOpCode (\r
742 IN UINT8 Operand\r
743 )\r
744{\r
745 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
746 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
747 (Operand == EFI_IFR_CATENATE_OP) ||\r
748 (Operand == EFI_IFR_TO_LOWER_OP) ||\r
749 (Operand == EFI_IFR_TO_UPPER_OP) ||\r
750 (Operand == EFI_IFR_VERSION_OP)\r
751 ) {\r
752 return TRUE;\r
753 } else {\r
754 return FALSE;\r
755 }\r
756}\r
757\r
758\r
759/**\r
760 Calculate number of Statemens(Questions) and Expression OpCodes.\r
761\r
762 @param FormSet The FormSet to be counted.\r
763 @param NumberOfStatement Number of Statemens(Questions)\r
764 @param NumberOfExpression Number of Expression OpCodes\r
765\r
766**/\r
767VOID\r
768CountOpCodes (\r
769 IN FORM_BROWSER_FORMSET *FormSet,\r
770 IN OUT UINT16 *NumberOfStatement,\r
771 IN OUT UINT16 *NumberOfExpression\r
772 )\r
773{\r
774 UINT16 StatementCount;\r
775 UINT16 ExpressionCount;\r
776 UINT8 *OpCodeData;\r
777 UINTN Offset;\r
778 UINTN OpCodeLen;\r
779\r
780 Offset = 0;\r
781 StatementCount = 0;\r
782 ExpressionCount = 0;\r
783\r
784 while (Offset < FormSet->IfrBinaryLength) {\r
785 OpCodeData = FormSet->IfrBinaryData + Offset;\r
786 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
787 Offset += OpCodeLen;\r
788\r
789 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
790 ExpressionCount++;\r
791 } else {\r
792 StatementCount++;\r
793 }\r
794 }\r
795\r
796 *NumberOfStatement = StatementCount;\r
797 *NumberOfExpression = ExpressionCount;\r
798}\r
799\r
800\r
801\r
802/**\r
803 Parse opcodes in the formset IFR binary.\r
804\r
805 @param FormSet Pointer of the FormSet data structure.\r
806\r
807 @retval EFI_SUCCESS Opcode parse success.\r
808 @retval Other Opcode parse fail.\r
809\r
810**/\r
811EFI_STATUS\r
812ParseOpCodes (\r
813 IN FORM_BROWSER_FORMSET *FormSet\r
814 )\r
815{\r
816 EFI_STATUS Status;\r
817 UINT16 Index;\r
818 FORM_BROWSER_FORM *CurrentForm;\r
819 FORM_BROWSER_STATEMENT *CurrentStatement;\r
820 EXPRESSION_OPCODE *ExpressionOpCode;\r
821 FORM_EXPRESSION *CurrentExpression;\r
822 UINT8 Operand;\r
823 UINT8 Scope;\r
824 UINTN OpCodeOffset;\r
825 UINTN OpCodeLength;\r
826 UINT8 *OpCodeData;\r
827 UINT8 ScopeOpCode;\r
828 FORMSET_STORAGE *Storage;\r
829 FORMSET_DEFAULTSTORE *DefaultStore;\r
830 QUESTION_DEFAULT *CurrentDefault;\r
831 QUESTION_OPTION *CurrentOption;\r
832 UINT8 Width;\r
833 CHAR8 *AsciiString;\r
834 UINT16 NumberOfStatement;\r
835 UINT16 NumberOfExpression;\r
836 EFI_IMAGE_ID *ImageId;\r
837 BOOLEAN SuppressForQuestion;\r
838 BOOLEAN SuppressForOption;\r
839 BOOLEAN InScopeOptionSuppress;\r
840 FORM_EXPRESSION *OptionSuppressExpression;\r
841 BOOLEAN InScopeFormSuppress;\r
842 FORM_EXPRESSION *FormSuppressExpression;\r
843 UINT16 DepthOfDisable;\r
844 BOOLEAN OpCodeDisabled;\r
845 BOOLEAN SingleOpCodeExpression;\r
846 BOOLEAN InScopeDefault;\r
847 EFI_HII_VALUE *Value;\r
848\r
849 mInScopeSubtitle = FALSE;\r
850 SuppressForQuestion = FALSE;\r
851 SuppressForOption = FALSE;\r
852 InScopeFormSuppress = FALSE;\r
853 mInScopeSuppress = FALSE;\r
854 InScopeOptionSuppress = FALSE;\r
855 mInScopeGrayOut = FALSE;\r
856 mInScopeDisable = FALSE;\r
857 DepthOfDisable = 0;\r
858 OpCodeDisabled = FALSE;\r
859 SingleOpCodeExpression = FALSE;\r
860 InScopeDefault = FALSE;\r
861 CurrentExpression = NULL;\r
862 CurrentDefault = NULL;\r
863 CurrentOption = NULL;\r
864 OptionSuppressExpression = NULL;\r
865 FormSuppressExpression = NULL;\r
866 ImageId = NULL;\r
867\r
868 //\r
869 // Get the number of Statements and Expressions\r
870 //\r
871 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
872\r
873 mStatementIndex = 0;\r
874 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
875 if (FormSet->StatementBuffer == NULL) {\r
876 return EFI_OUT_OF_RESOURCES;\r
877 }\r
878\r
879 mExpressionOpCodeIndex = 0;\r
880 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
881 if (FormSet->ExpressionBuffer == NULL) {\r
882 return EFI_OUT_OF_RESOURCES;\r
883 }\r
884\r
885 InitializeListHead (&FormSet->StorageListHead);\r
886 InitializeListHead (&FormSet->DefaultStoreListHead);\r
887 InitializeListHead (&FormSet->FormListHead);\r
888\r
889 CurrentForm = NULL;\r
890 CurrentStatement = NULL;\r
891\r
892 ResetScopeStack ();\r
893\r
894 OpCodeOffset = 0;\r
895 while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
896 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
897\r
898 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
899 OpCodeOffset += OpCodeLength;\r
900 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
901 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
902\r
903 //\r
904 // If scope bit set, push onto scope stack\r
905 //\r
906 if (Scope != 0) {\r
907 PushScope (Operand);\r
908 }\r
909\r
910 if (OpCodeDisabled) {\r
911 //\r
912 // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
913 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
914 //\r
915 if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
916 DepthOfDisable++;\r
917 } else if (Operand == EFI_IFR_END_OP) {\r
918 Status = PopScope (&ScopeOpCode);\r
919 if (EFI_ERROR (Status)) {\r
920 return Status;\r
921 }\r
922\r
923 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
924 if (DepthOfDisable == 0) {\r
925 mInScopeDisable = FALSE;\r
926 OpCodeDisabled = FALSE;\r
927 } else {\r
928 DepthOfDisable--;\r
929 }\r
930 }\r
931 }\r
932 continue;\r
933 }\r
934\r
935 if (IsExpressionOpCode (Operand)) {\r
936 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
937 mExpressionOpCodeIndex++;\r
938\r
939 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
940 ExpressionOpCode->Operand = Operand;\r
941 Value = &ExpressionOpCode->Value;\r
942\r
943 switch (Operand) {\r
944 case EFI_IFR_EQ_ID_VAL_OP:\r
945 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
946\r
947 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
948 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
949 break;\r
950\r
951 case EFI_IFR_EQ_ID_ID_OP:\r
952 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
953 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
954 break;\r
955\r
956 case EFI_IFR_EQ_ID_LIST_OP:\r
957 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
958 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
959 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
960 break;\r
961\r
962 case EFI_IFR_TO_STRING_OP:\r
963 case EFI_IFR_FIND_OP:\r
964 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
965 break;\r
966\r
967 case EFI_IFR_STRING_REF1_OP:\r
968 Value->Type = EFI_IFR_TYPE_STRING;\r
969 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
970 break;\r
971\r
972 case EFI_IFR_RULE_REF_OP:\r
973 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
974 break;\r
975\r
976 case EFI_IFR_SPAN_OP:\r
977 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
978 break;\r
979\r
980 case EFI_IFR_THIS_OP:\r
981 ASSERT (CurrentStatement != NULL);\r
982 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
983 break;\r
984\r
985 case EFI_IFR_QUESTION_REF1_OP:\r
986 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
987 break;\r
988\r
989 case EFI_IFR_QUESTION_REF3_OP:\r
990 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
991 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
992\r
993 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
994 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
995 }\r
996 }\r
997 break;\r
998\r
999 //\r
1000 // constant\r
1001 //\r
1002 case EFI_IFR_TRUE_OP:\r
1003 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1004 Value->Value.b = TRUE;\r
1005 break;\r
1006\r
1007 case EFI_IFR_FALSE_OP:\r
1008 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1009 Value->Value.b = FALSE;\r
1010 break;\r
1011\r
1012 case EFI_IFR_ONE_OP:\r
1013 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1014 Value->Value.u8 = 1;\r
1015 break;\r
1016\r
1017 case EFI_IFR_ZERO_OP:\r
1018 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1019 Value->Value.u8 = 0;\r
1020 break;\r
1021\r
1022 case EFI_IFR_ONES_OP:\r
1023 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1024 Value->Value.u64 = 0xffffffffffffffffULL;\r
1025 break;\r
1026\r
1027 case EFI_IFR_UINT8_OP:\r
1028 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1029 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
1030 break;\r
1031\r
1032 case EFI_IFR_UINT16_OP:\r
1033 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1034 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
1035 break;\r
1036\r
1037 case EFI_IFR_UINT32_OP:\r
1038 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1039 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
1040 break;\r
1041\r
1042 case EFI_IFR_UINT64_OP:\r
1043 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1044 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
1045 break;\r
1046\r
1047 case EFI_IFR_UNDEFINED_OP:\r
1048 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
1049 break;\r
1050\r
1051 case EFI_IFR_VERSION_OP:\r
1052 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1053 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
1054 break;\r
1055\r
1056 default:\r
1057 break;\r
1058 }\r
1059\r
1060 ASSERT (CurrentExpression != NULL);\r
1061 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
1062\r
1063 if (SingleOpCodeExpression) {\r
1064 //\r
1065 // There are two cases to indicate the end of an Expression:\r
1066 // for single OpCode expression: one Expression OpCode\r
1067 // for expression consists of more than one OpCode: EFI_IFR_END\r
1068 //\r
1069 SingleOpCodeExpression = FALSE;\r
1070\r
1071 if (mInScopeDisable && CurrentForm == NULL) {\r
1072 //\r
1073 // This is DisableIf expression for Form, it should be a constant expression\r
1074 //\r
1075 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1076 if (EFI_ERROR (Status)) {\r
1077 return Status;\r
1078 }\r
1079\r
1080 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1081 return EFI_INVALID_PARAMETER;\r
1082 }\r
1083\r
1084 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1085 }\r
1086\r
1087 CurrentExpression = NULL;\r
1088 }\r
1089\r
1090 continue;\r
1091 }\r
1092\r
1093 //\r
1094 // Parse the Opcode\r
1095 //\r
1096 switch (Operand) {\r
1097\r
1098 case EFI_IFR_FORM_SET_OP:\r
1099 //\r
1100 // Check the formset GUID\r
1101 //\r
1102 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1103 return EFI_INVALID_PARAMETER;\r
1104 }\r
1105\r
1106 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1107 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
1108\r
1109 //\r
1110 // The formset OpCode contains ClassGuid\r
1111 //\r
1112 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1113 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
1114\r
1115 InitializeListHead (&FormSet->ExpressionListHead);\r
1116 break;\r
1117\r
1118 case EFI_IFR_FORM_OP:\r
1119 //\r
1120 // Create a new Form for this FormSet\r
1121 //\r
1122 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1123 ASSERT (CurrentForm != NULL);\r
1124 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1125 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1126 InitializeListHead (&CurrentForm->StatementListHead);\r
1127\r
1128 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1129 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1130\r
1131 if (InScopeFormSuppress) {\r
1132 //\r
1133 // Form is inside of suppressif\r
1134 //\r
1135 CurrentForm->SuppressExpression = FormSuppressExpression;\r
1136 }\r
1137\r
1138 if (Scope != 0) {\r
1139 //\r
1140 // Enter scope of a Form, suppressif will be used for Question or Option\r
1141 //\r
1142 SuppressForQuestion = TRUE;\r
1143 }\r
1144\r
1145 //\r
1146 // Insert into Form list of this FormSet\r
1147 //\r
1148 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1149 break;\r
1150\r
1151 //\r
1152 // Storage\r
1153 //\r
1154 case EFI_IFR_VARSTORE_OP:\r
1155 //\r
1156 // Create a buffer Storage for this FormSet\r
1157 //\r
1158 Storage = CreateStorage (FormSet);\r
1159 Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1160\r
1161 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1162 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1163 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
1164\r
1165 Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1166 Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1167\r
1168 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1169 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1170 ASSERT (Storage->Name != NULL);\r
1171 for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1172 Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1173 }\r
1174\r
1175 //\r
1176 // Initialize <ConfigHdr>\r
1177 //\r
1178 InitializeConfigHdr (FormSet, Storage);\r
1179 break;\r
1180\r
1181 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1182 //\r
1183 // Create a name/value Storage for this FormSet\r
1184 //\r
1185 Storage = CreateStorage (FormSet);\r
1186 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1187\r
1188 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1189 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1190\r
1191 //\r
1192 // Initialize <ConfigHdr>\r
1193 //\r
1194 InitializeConfigHdr (FormSet, Storage);\r
1195 break;\r
1196\r
1197 case EFI_IFR_VARSTORE_EFI_OP:\r
1198 //\r
1199 // Create a EFI variable Storage for this FormSet\r
1200 //\r
1201 Storage = CreateStorage (FormSet);\r
1202 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1203\r
1204 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1205 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1206 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1207 break;\r
1208\r
1209 //\r
1210 // DefaultStore\r
1211 //\r
1212 case EFI_IFR_DEFAULTSTORE_OP:\r
1213 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1214 ASSERT (DefaultStore != NULL);\r
1215 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1216\r
1217 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1218 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1219\r
1220 //\r
1221 // Insert to DefaultStore list of this Formset\r
1222 //\r
1223 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1224 break;\r
1225\r
1226 //\r
1227 // Statements\r
1228 //\r
1229 case EFI_IFR_SUBTITLE_OP:\r
1230 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1231 ASSERT (CurrentStatement != NULL);\r
1232\r
1233 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1234\r
1235 if (Scope != 0) {\r
1236 mInScopeSubtitle = TRUE;\r
1237 }\r
1238 break;\r
1239\r
1240 case EFI_IFR_TEXT_OP:\r
1241 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1242 ASSERT (CurrentStatement != NULL);\r
1243\r
1244 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1245 break;\r
1246\r
1247 case EFI_IFR_RESET_BUTTON_OP:\r
1248 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1249 ASSERT (CurrentStatement != NULL);\r
1250 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1251 break;\r
1252\r
1253 //\r
1254 // Questions\r
1255 //\r
1256 case EFI_IFR_ACTION_OP:\r
1257 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1258 ASSERT (CurrentStatement != NULL);\r
1259 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
1260\r
1261 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1262 //\r
1263 // No QuestionConfig present, so no configuration string will be processed\r
1264 //\r
1265 CurrentStatement->QuestionConfig = 0;\r
1266 } else {\r
1267 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1268 }\r
1269 break;\r
1270\r
1271 case EFI_IFR_REF_OP:\r
1272 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1273 ASSERT (CurrentStatement != NULL);\r
1274 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;\r
1275 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
1276 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1277 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1278\r
1279 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1280 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1281\r
1282 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1283 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1284 }\r
1285 }\r
1286 }\r
1287 break;\r
1288\r
1289 case EFI_IFR_ONE_OF_OP:\r
1290 case EFI_IFR_NUMERIC_OP:\r
1291 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1292 ASSERT(CurrentStatement != NULL);\r
1293\r
1294 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1295 Value = &CurrentStatement->HiiValue;\r
1296\r
1297 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1298 case EFI_IFR_NUMERIC_SIZE_1:\r
1299 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1300 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1301 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1302 CurrentStatement->StorageWidth = sizeof (UINT8);\r
1303 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1304 break;\r
1305\r
1306 case EFI_IFR_NUMERIC_SIZE_2:\r
1307 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1308 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1309 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
1310 CurrentStatement->StorageWidth = sizeof (UINT16);\r
1311 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1312 break;\r
1313\r
1314 case EFI_IFR_NUMERIC_SIZE_4:\r
1315 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1316 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1317 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
1318 CurrentStatement->StorageWidth = sizeof (UINT32);\r
1319 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1320 break;\r
1321\r
1322 case EFI_IFR_NUMERIC_SIZE_8:\r
1323 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1324 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1325 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
1326 CurrentStatement->StorageWidth = sizeof (UINT64);\r
1327 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1328 break;\r
1329\r
1330 default:\r
1331 break;\r
1332 }\r
1333\r
1334 InitializeRequestElement (FormSet, CurrentStatement);\r
1335\r
1336 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
1337 SuppressForOption = TRUE;\r
1338 }\r
1339 break;\r
1340\r
1341 case EFI_IFR_ORDERED_LIST_OP:\r
1342 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1343 ASSERT(CurrentStatement != NULL);\r
1344\r
1345 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1346 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
1347\r
1348 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
1349\r
1350 if (Scope != 0) {\r
1351 SuppressForOption = TRUE;\r
1352 }\r
1353 break;\r
1354\r
1355 case EFI_IFR_CHECKBOX_OP:\r
1356 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1357 ASSERT(CurrentStatement != NULL);\r
1358\r
1359 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
1360 CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
1361 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1362\r
1363 InitializeRequestElement (FormSet, CurrentStatement);\r
1364\r
1365 break;\r
1366\r
1367 case EFI_IFR_STRING_OP:\r
1368 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1369 ASSERT (CurrentStatement != NULL);\r
1370 //\r
1371 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1372 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1373 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1374 //\r
1375 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1376 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1377 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1378 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1379\r
1380 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1381 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
1382\r
1383 InitializeRequestElement (FormSet, CurrentStatement);\r
1384 break;\r
1385\r
1386 case EFI_IFR_PASSWORD_OP:\r
1387 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1388 ASSERT (CurrentStatement != NULL);\r
1389 //\r
1390 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1391 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1392 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1393 //\r
1394 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1395 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1396 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1397\r
1398 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1399 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
1400\r
1401 InitializeRequestElement (FormSet, CurrentStatement);\r
1402 break;\r
1403\r
1404 case EFI_IFR_DATE_OP:\r
1405 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1406 ASSERT(CurrentStatement != NULL);\r
1407\r
1408 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1409 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1410\r
1411 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
1412 CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
1413\r
1414 InitializeRequestElement (FormSet, CurrentStatement);\r
1415 } else {\r
1416 //\r
1417 // Don't assign storage for RTC type of date/time\r
1418 //\r
1419 CurrentStatement->Storage = NULL;\r
1420 CurrentStatement->StorageWidth = 0;\r
1421 }\r
1422 break;\r
1423\r
1424 case EFI_IFR_TIME_OP:\r
1425 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1426 ASSERT(CurrentStatement != NULL);\r
1427\r
1428 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1429 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1430\r
1431 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
1432 CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
1433\r
1434 InitializeRequestElement (FormSet, CurrentStatement);\r
1435 } else {\r
1436 //\r
1437 // Don't assign storage for RTC type of date/time\r
1438 //\r
1439 CurrentStatement->Storage = NULL;\r
1440 CurrentStatement->StorageWidth = 0;\r
1441 }\r
1442 break;\r
1443\r
1444 //\r
1445 // Default\r
1446 //\r
1447 case EFI_IFR_DEFAULT_OP:\r
1448 //\r
1449 // EFI_IFR_DEFAULT appear in scope of a Question,\r
1450 // It creates a default value for the current question.\r
1451 // A Question may have more than one Default value which have different default types.\r
1452 //\r
1453 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1454 ASSERT (CurrentDefault != NULL);\r
1455 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1456\r
1457 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1458 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1459 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1460 ExtendValueToU64 (&CurrentDefault->Value);\r
1461\r
1462 //\r
1463 // Insert to Default Value list of current Question\r
1464 //\r
1465 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1466\r
1467 if (Scope != 0) {\r
1468 InScopeDefault = TRUE;\r
1469 }\r
1470 break;\r
1471\r
1472 //\r
1473 // Option\r
1474 //\r
1475 case EFI_IFR_ONE_OF_OPTION_OP:\r
1476 //\r
1477 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1478 // It create a selection for use in current Question.\r
1479 //\r
1480 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1481 ASSERT (CurrentOption != NULL);\r
1482 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1483\r
1484 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1485 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1486 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1487 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1488 ExtendValueToU64 (&CurrentOption->Value);\r
1489\r
1490 if (InScopeOptionSuppress) {\r
1491 CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1492 }\r
1493\r
1494 //\r
1495 // Insert to Option list of current Question\r
1496 //\r
1497 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
1498\r
1499 //\r
1500 // Now we know the Storage width of nested Ordered List\r
1501 //\r
1502 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
1503 Width = 1;\r
1504 switch (CurrentOption->Value.Type) {\r
1505 case EFI_IFR_TYPE_NUM_SIZE_8:\r
1506 Width = 1;\r
1507 break;\r
1508\r
1509 case EFI_IFR_TYPE_NUM_SIZE_16:\r
1510 Width = 2;\r
1511 break;\r
1512\r
1513 case EFI_IFR_TYPE_NUM_SIZE_32:\r
1514 Width = 4;\r
1515 break;\r
1516\r
1517 case EFI_IFR_TYPE_NUM_SIZE_64:\r
1518 Width = 8;\r
1519 break;\r
1520\r
1521 default:\r
1522 //\r
1523 // Invalid type for Ordered List\r
1524 //\r
1525 break;\r
1526 }\r
1527\r
1528 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
1529 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1530 CurrentStatement->ValueType = CurrentOption->Value.Type;\r
1531\r
1532 InitializeRequestElement (FormSet, CurrentStatement);\r
1533 }\r
1534 break;\r
1535\r
1536 //\r
1537 // Conditional\r
1538 //\r
1539 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1540 case EFI_IFR_INCONSISTENT_IF_OP:\r
1541 //\r
1542 // Create an Expression node\r
1543 //\r
1544 CurrentExpression = CreateExpression (CurrentForm);\r
1545 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1546\r
1547 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1548 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1549 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1550 } else {\r
1551 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1552 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1553 }\r
1554\r
1555 //\r
1556 // Take a look at next OpCode to see whether current expression consists\r
1557 // of single OpCode\r
1558 //\r
1559 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1560 SingleOpCodeExpression = TRUE;\r
1561 }\r
1562 break;\r
1563\r
1564 case EFI_IFR_SUPPRESS_IF_OP:\r
1565 //\r
1566 // Question and Option will appear in scope of this OpCode\r
1567 //\r
1568 CurrentExpression = CreateExpression (CurrentForm);\r
1569 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
1570\r
1571 if (CurrentForm == NULL) {\r
1572 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
1573 } else {\r
1574 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1575 }\r
1576\r
1577 if (SuppressForOption) {\r
1578 InScopeOptionSuppress = TRUE;\r
1579 OptionSuppressExpression = CurrentExpression;\r
1580 } else if (SuppressForQuestion) {\r
1581 mInScopeSuppress = TRUE;\r
1582 mSuppressExpression = CurrentExpression;\r
1583 } else {\r
1584 InScopeFormSuppress = TRUE;\r
1585 FormSuppressExpression = CurrentExpression;\r
1586 }\r
1587\r
1588 //\r
1589 // Take a look at next OpCode to see whether current expression consists\r
1590 // of single OpCode\r
1591 //\r
1592 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1593 SingleOpCodeExpression = TRUE;\r
1594 }\r
1595 break;\r
1596\r
1597 case EFI_IFR_GRAY_OUT_IF_OP:\r
1598 //\r
1599 // Questions will appear in scope of this OpCode\r
1600 //\r
1601 CurrentExpression = CreateExpression (CurrentForm);\r
1602 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1603 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1604\r
1605 mInScopeGrayOut = TRUE;\r
1606 mGrayOutExpression = CurrentExpression;\r
1607\r
1608 //\r
1609 // Take a look at next OpCode to see whether current expression consists\r
1610 // of single OpCode\r
1611 //\r
1612 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1613 SingleOpCodeExpression = TRUE;\r
1614 }\r
1615 break;\r
1616\r
1617 case EFI_IFR_DISABLE_IF_OP:\r
1618 //\r
1619 // The DisableIf expression should only rely on constant, so it could be\r
1620 // evaluated at initialization and it will not be queued\r
1621 //\r
1622 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1623 ASSERT (CurrentExpression != NULL);\r
1624 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1625 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1626 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1627\r
1628 if (CurrentForm != NULL) {\r
1629 //\r
1630 // This is DisableIf for Question, enqueue it to Form expression list\r
1631 //\r
1632 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1633 }\r
1634\r
1635 mDisableExpression = CurrentExpression;\r
1636 mInScopeDisable = TRUE;\r
1637 OpCodeDisabled = FALSE;\r
1638\r
1639 //\r
1640 // Take a look at next OpCode to see whether current expression consists\r
1641 // of single OpCode\r
1642 //\r
1643 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1644 SingleOpCodeExpression = TRUE;\r
1645 }\r
1646 break;\r
1647\r
1648 //\r
1649 // Expression\r
1650 //\r
1651 case EFI_IFR_VALUE_OP:\r
1652 CurrentExpression = CreateExpression (CurrentForm);\r
1653 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1654 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1655\r
1656 if (InScopeDefault) {\r
1657 //\r
1658 // Used for default (EFI_IFR_DEFAULT)\r
1659 //\r
1660 CurrentDefault->ValueExpression = CurrentExpression;\r
1661 } else {\r
1662 //\r
1663 // If used for a question, then the question will be read-only\r
1664 //\r
1665 //\r
1666 // Make sure CurrentStatement is not NULL.\r
1667 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1668 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1669 //\r
1670 ASSERT (CurrentStatement != NULL);\r
1671 CurrentStatement->ValueExpression = CurrentExpression;\r
1672 }\r
1673\r
1674 //\r
1675 // Take a look at next OpCode to see whether current expression consists\r
1676 // of single OpCode\r
1677 //\r
1678 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1679 SingleOpCodeExpression = TRUE;\r
1680 }\r
1681 break;\r
1682\r
1683 case EFI_IFR_RULE_OP:\r
1684 CurrentExpression = CreateExpression (CurrentForm);\r
1685 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1686\r
1687 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1688 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1689\r
1690 //\r
1691 // Take a look at next OpCode to see whether current expression consists\r
1692 // of single OpCode\r
1693 //\r
1694 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1695 SingleOpCodeExpression = TRUE;\r
1696 }\r
1697 break;\r
1698\r
1699 //\r
1700 // Image\r
1701 //\r
1702 case EFI_IFR_IMAGE_OP:\r
1703 //\r
1704 // Get ScopeOpcode from top of stack\r
1705 //\r
1706 PopScope (&ScopeOpCode);\r
1707 PushScope (ScopeOpCode);\r
1708\r
1709 switch (ScopeOpCode) {\r
1710 case EFI_IFR_FORM_SET_OP:\r
1711 ImageId = &FormSet->ImageId;\r
1712 break;\r
1713\r
1714 case EFI_IFR_FORM_OP:\r
1715 ASSERT (CurrentForm != NULL);\r
1716 ImageId = &CurrentForm->ImageId;\r
1717 break;\r
1718\r
1719 case EFI_IFR_ONE_OF_OPTION_OP:\r
1720 ImageId = &CurrentOption->ImageId;\r
1721 break;\r
1722\r
1723 default:\r
1724 //\r
1725 // Make sure CurrentStatement is not NULL.\r
1726 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1727 // file is wrongly generated by tools such as VFR Compiler.\r
1728 //\r
1729 ASSERT (CurrentStatement != NULL);\r
1730 ImageId = &CurrentStatement->ImageId;\r
1731 break;\r
1732 }\r
1733\r
1734 ASSERT (ImageId != NULL);\r
1735 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
1736 break;\r
1737\r
1738 //\r
1739 // Refresh\r
1740 //\r
1741 case EFI_IFR_REFRESH_OP:\r
1742 ASSERT (CurrentStatement != NULL);\r
1743 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
1744 break;\r
1745\r
1746 //\r
1747 // Vendor specific\r
1748 //\r
1749 case EFI_IFR_GUID_OP:\r
1750 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
1751 //\r
1752 // Tiano specific GUIDed opcodes\r
1753 //\r
1754 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
1755 case EFI_IFR_EXTEND_OP_LABEL:\r
1756 //\r
1757 // just ignore label\r
1758 //\r
1759 break;\r
1760\r
1761 case EFI_IFR_EXTEND_OP_BANNER:\r
1762 //\r
1763 // By SubClass to get Banner Data from Front Page\r
1764 //\r
1765 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
1766 CopyMem (\r
1767 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
1768 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
1769 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
1770 sizeof (EFI_STRING_ID)\r
1771 );\r
1772 }\r
1773 break;\r
1774\r
1775 case EFI_IFR_EXTEND_OP_CLASS:\r
1776 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
1777 break;\r
1778\r
1779 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
1780 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
1781 break;\r
1782\r
1783 default:\r
1784 break;\r
1785 }\r
1786 }\r
1787\r
1788 break;\r
1789\r
1790 //\r
1791 // Scope End\r
1792 //\r
1793 case EFI_IFR_END_OP:\r
1794 Status = PopScope (&ScopeOpCode);\r
1795 if (EFI_ERROR (Status)) {\r
1796 ResetScopeStack ();\r
1797 return Status;\r
1798 }\r
1799\r
1800 switch (ScopeOpCode) {\r
1801 case EFI_IFR_FORM_SET_OP:\r
1802 //\r
1803 // End of FormSet, update FormSet IFR binary length\r
1804 // to stop parsing substantial OpCodes\r
1805 //\r
1806 FormSet->IfrBinaryLength = OpCodeOffset;\r
1807 break;\r
1808\r
1809 case EFI_IFR_FORM_OP:\r
1810 //\r
1811 // End of Form\r
1812 //\r
1813 CurrentForm = NULL;\r
1814 SuppressForQuestion = FALSE;\r
1815 break;\r
1816\r
1817 case EFI_IFR_ONE_OF_OPTION_OP:\r
1818 //\r
1819 // End of Option\r
1820 //\r
1821 CurrentOption = NULL;\r
1822 break;\r
1823\r
1824 case EFI_IFR_SUBTITLE_OP:\r
1825 mInScopeSubtitle = FALSE;\r
1826 break;\r
1827\r
1828 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1829 case EFI_IFR_INCONSISTENT_IF_OP:\r
1830 //\r
1831 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
1832 //\r
1833 break;\r
1834\r
1835 case EFI_IFR_SUPPRESS_IF_OP:\r
1836 if (SuppressForOption) {\r
1837 InScopeOptionSuppress = FALSE;\r
1838 } else if (SuppressForQuestion) {\r
1839 mInScopeSuppress = FALSE;\r
1840 } else {\r
1841 InScopeFormSuppress = FALSE;\r
1842 }\r
1843 break;\r
1844\r
1845 case EFI_IFR_GRAY_OUT_IF_OP:\r
1846 mInScopeGrayOut = FALSE;\r
1847 break;\r
1848\r
1849 case EFI_IFR_DISABLE_IF_OP:\r
1850 mInScopeDisable = FALSE;\r
1851 OpCodeDisabled = FALSE;\r
1852 break;\r
1853\r
1854 case EFI_IFR_ONE_OF_OP:\r
1855 case EFI_IFR_ORDERED_LIST_OP:\r
1856 SuppressForOption = FALSE;\r
1857 break;\r
1858\r
1859 case EFI_IFR_DEFAULT_OP:\r
1860 InScopeDefault = FALSE;\r
1861 break;\r
1862\r
1863 default:\r
1864 if (IsExpressionOpCode (ScopeOpCode)) {\r
1865 if (mInScopeDisable && CurrentForm == NULL) {\r
1866 //\r
1867 // This is DisableIf expression for Form, it should be a constant expression\r
1868 //\r
1869 ASSERT (CurrentExpression != NULL);\r
1870 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1871 if (EFI_ERROR (Status)) {\r
1872 return Status;\r
1873 }\r
1874\r
1875 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1876 return EFI_INVALID_PARAMETER;\r
1877 }\r
1878\r
1879 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1880 //\r
1881 // DisableIf Expression is only used once and not quequed, free it\r
1882 //\r
1883 DestroyExpression (CurrentExpression);\r
1884 }\r
1885\r
1886 //\r
1887 // End of current Expression\r
1888 //\r
1889 CurrentExpression = NULL;\r
1890 }\r
1891 break;\r
1892 }\r
1893 break;\r
1894\r
1895 default:\r
1896 break;\r
1897 }\r
1898 }\r
1899\r
1900 return EFI_SUCCESS;\r
1901}\r