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