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