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