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