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