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