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