]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Add new “Modal form” opcode.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
1 /** @file
2 Parser for IFR binary encoding.
3
4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "Setup.h"
16
17 UINT16 mStatementIndex;
18 UINT16 mExpressionOpCodeIndex;
19
20 BOOLEAN mInScopeSubtitle;
21 BOOLEAN mInScopeSuppress;
22 BOOLEAN mInScopeGrayOut;
23 BOOLEAN mInScopeDisable;
24 FORM_EXPRESSION *mSuppressExpression;
25 FORM_EXPRESSION *mGrayOutExpression;
26 FORM_EXPRESSION *mDisableExpression;
27
28 /**
29 Initialize Statement header members.
30
31 @param OpCodeData Pointer of the raw OpCode data.
32 @param FormSet Pointer of the current FormSe.
33 @param Form Pointer of the current Form.
34
35 @return The Statement.
36
37 **/
38 FORM_BROWSER_STATEMENT *
39 CreateStatement (
40 IN UINT8 *OpCodeData,
41 IN OUT FORM_BROWSER_FORMSET *FormSet,
42 IN OUT FORM_BROWSER_FORM *Form
43 )
44 {
45 FORM_BROWSER_STATEMENT *Statement;
46 EFI_IFR_STATEMENT_HEADER *StatementHdr;
47
48 if (Form == NULL) {
49 //
50 // We are currently not in a Form Scope, so just skip this Statement
51 //
52 return NULL;
53 }
54
55 Statement = &FormSet->StatementBuffer[mStatementIndex];
56 mStatementIndex++;
57
58 InitializeListHead (&Statement->DefaultListHead);
59 InitializeListHead (&Statement->OptionListHead);
60 InitializeListHead (&Statement->InconsistentListHead);
61 InitializeListHead (&Statement->NoSubmitListHead);
62
63 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
64
65 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
66
67 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
68 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
69 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
70
71 if (mInScopeSuppress) {
72 Statement->SuppressExpression = mSuppressExpression;
73 }
74
75 if (mInScopeGrayOut) {
76 Statement->GrayOutExpression = mGrayOutExpression;
77 }
78
79
80 if (mInScopeDisable) {
81 Statement->DisableExpression = mDisableExpression;
82 }
83
84 Statement->InSubtitle = mInScopeSubtitle;
85
86 //
87 // Insert this Statement into current Form
88 //
89 InsertTailList (&Form->StatementListHead, &Statement->Link);
90
91 return Statement;
92 }
93
94 /**
95 Convert a numeric value to a Unicode String and insert it to String Package.
96 This string is used as the Unicode Name for the EFI Variable. This is to support
97 the deprecated vareqval opcode.
98
99 @param FormSet The FormSet.
100 @param Statement The numeric question whose VarStoreInfo.VarName is the
101 numeric value which is used to produce the Unicode Name
102 for the EFI Variable.
103
104 If the Statement is NULL, the ASSERT.
105 If the opcode is not Numeric, then ASSERT.
106
107 @retval EFI_SUCCESS The funtion always succeeds.
108 **/
109 EFI_STATUS
110 UpdateCheckBoxStringToken (
111 IN CONST FORM_BROWSER_FORMSET *FormSet,
112 IN FORM_BROWSER_STATEMENT *Statement
113 )
114 {
115 CHAR16 Str[MAXIMUM_VALUE_CHARACTERS];
116 EFI_STRING_ID Id;
117
118 ASSERT (Statement != NULL);
119 ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);
120
121 UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);
122
123 Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);
124 if (Id == 0) {
125 return EFI_OUT_OF_RESOURCES;
126 }
127
128 Statement->VarStoreInfo.VarName = Id;
129
130 return EFI_SUCCESS;
131 }
132
133 /**
134 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
135
136 @param OpCodeData The current opcode.
137
138 @retval TRUE Yes.
139 @retval FALSE No.
140 **/
141 BOOLEAN
142 IsNextOpCodeGuidedVarEqName (
143 IN UINT8 *OpCodeData
144 )
145 {
146 //
147 // Get next opcode
148 //
149 OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
150 if (*OpCodeData == EFI_IFR_GUID_OP) {
151 if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
152 //
153 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
154 //
155 if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {
156 return TRUE;
157 }
158 }
159 }
160
161 return FALSE;
162 }
163
164 /**
165 Initialize Question's members.
166
167 @param OpCodeData Pointer of the raw OpCode data.
168 @param FormSet Pointer of the current FormSet.
169 @param Form Pointer of the current Form.
170
171 @return The Question.
172
173 **/
174 FORM_BROWSER_STATEMENT *
175 CreateQuestion (
176 IN UINT8 *OpCodeData,
177 IN OUT FORM_BROWSER_FORMSET *FormSet,
178 IN OUT FORM_BROWSER_FORM *Form
179 )
180 {
181 FORM_BROWSER_STATEMENT *Statement;
182 EFI_IFR_QUESTION_HEADER *QuestionHdr;
183 LIST_ENTRY *Link;
184 FORMSET_STORAGE *Storage;
185 NAME_VALUE_NODE *NameValueNode;
186 EFI_STATUS Status;
187
188 Statement = CreateStatement (OpCodeData, FormSet, Form);
189 if (Statement == NULL) {
190 return NULL;
191 }
192
193 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
194 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
195 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
196 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
197
198 Statement->QuestionFlags = QuestionHdr->Flags;
199
200 if (Statement->VarStoreId == 0) {
201 //
202 // VarStoreId of zero indicates no variable storage
203 //
204 return Statement;
205 }
206
207 //
208 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
209 // Framework Compatibility
210 //
211 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
212 if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {
213 Status = UpdateCheckBoxStringToken (FormSet, Statement);
214 if (EFI_ERROR (Status)) {
215 return NULL;
216 }
217 }
218 }
219
220 //
221 // Find Storage for this Question
222 //
223 Link = GetFirstNode (&FormSet->StorageListHead);
224 while (!IsNull (&FormSet->StorageListHead, Link)) {
225 Storage = FORMSET_STORAGE_FROM_LINK (Link);
226
227 if (Storage->VarStoreId == Statement->VarStoreId) {
228 Statement->Storage = Storage;
229 break;
230 }
231
232 Link = GetNextNode (&FormSet->StorageListHead, Link);
233 }
234 ASSERT (Statement->Storage != NULL);
235
236 //
237 // Initialilze varname for Name/Value or EFI Variable
238 //
239 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
240 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
241 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
242 ASSERT (Statement->VariableName != NULL);
243
244 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
245 //
246 // Insert to Name/Value varstore list
247 //
248 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
249 ASSERT (NameValueNode != NULL);
250 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
251 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
252 ASSERT (NameValueNode->Name != NULL);
253 NameValueNode->Value = AllocateZeroPool (0x10);
254 ASSERT (NameValueNode->Value != NULL);
255 NameValueNode->EditValue = AllocateZeroPool (0x10);
256 ASSERT (NameValueNode->EditValue != NULL);
257
258 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
259 }
260 }
261
262 return Statement;
263 }
264
265
266 /**
267 Allocate a FORM_EXPRESSION node.
268
269 @param Form The Form associated with this Expression
270
271 @return Pointer to a FORM_EXPRESSION data structure.
272
273 **/
274 FORM_EXPRESSION *
275 CreateExpression (
276 IN OUT FORM_BROWSER_FORM *Form
277 )
278 {
279 FORM_EXPRESSION *Expression;
280
281 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
282 ASSERT (Expression != NULL);
283 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
284 InitializeListHead (&Expression->OpCodeListHead);
285
286 return Expression;
287 }
288
289
290 /**
291 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
292
293 @param FormSet Pointer of the current FormSet
294
295 @return Pointer to a FORMSET_STORAGE data structure.
296
297 **/
298 FORMSET_STORAGE *
299 CreateStorage (
300 IN FORM_BROWSER_FORMSET *FormSet
301 )
302 {
303 FORMSET_STORAGE *Storage;
304
305 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
306 ASSERT (Storage != NULL);
307 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
308 InitializeListHead (&Storage->NameValueListHead);
309 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
310
311 return Storage;
312 }
313
314
315 /**
316 Create ConfigHdr string for a storage.
317
318 @param FormSet Pointer of the current FormSet
319 @param Storage Pointer of the storage
320
321 @retval EFI_SUCCESS Initialize ConfigHdr success
322
323 **/
324 EFI_STATUS
325 InitializeConfigHdr (
326 IN FORM_BROWSER_FORMSET *FormSet,
327 IN OUT FORMSET_STORAGE *Storage
328 )
329 {
330 CHAR16 *Name;
331
332 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
333 Name = Storage->Name;
334 } else {
335 Name = NULL;
336 }
337
338 Storage->ConfigHdr = HiiConstructConfigHdr (
339 &Storage->Guid,
340 Name,
341 FormSet->DriverHandle
342 );
343
344 if (Storage->ConfigHdr == NULL) {
345 return EFI_NOT_FOUND;
346 }
347
348 Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
349 Storage->SpareStrLen = 0;
350
351 return EFI_SUCCESS;
352 }
353
354
355 /**
356 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
357
358 @param FormSet Pointer of the current FormSet.
359 @param Question The Question to be initialized.
360 @param Form Pointer of the current form.
361
362 @retval EFI_SUCCESS Function success.
363 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
364
365 **/
366 EFI_STATUS
367 InitializeRequestElement (
368 IN OUT FORM_BROWSER_FORMSET *FormSet,
369 IN OUT FORM_BROWSER_STATEMENT *Question,
370 IN OUT FORM_BROWSER_FORM *Form
371 )
372 {
373 FORMSET_STORAGE *Storage;
374 UINTN StrLen;
375 UINTN StringSize;
376 CHAR16 *NewStr;
377 CHAR16 RequestElement[30];
378 LIST_ENTRY *Link;
379 BOOLEAN Find;
380 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
381
382 Storage = Question->Storage;
383 if (Storage == NULL) {
384 return EFI_INVALID_PARAMETER;
385 }
386
387 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
388 //
389 // <ConfigRequest> is unnecessary for EFI variable storage,
390 // GetVariable()/SetVariable() will be used to retrieve/save values
391 //
392 return EFI_SUCCESS;
393 }
394
395 //
396 // Prepare <RequestElement>
397 //
398 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
399 StrLen = UnicodeSPrint (
400 RequestElement,
401 30 * sizeof (CHAR16),
402 L"&OFFSET=%x&WIDTH=%x",
403 Question->VarStoreInfo.VarOffset,
404 Question->StorageWidth
405 );
406 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
407 } else {
408 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
409 }
410
411 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
412 //
413 // Password with CALLBACK flag is stored in encoded format,
414 // so don't need to append it to <ConfigRequest>
415 //
416 return EFI_SUCCESS;
417 }
418
419 //
420 // Append <RequestElement> to <ConfigRequest>
421 //
422 if (StrLen > Storage->SpareStrLen) {
423 //
424 // Old String buffer is not sufficient for RequestElement, allocate a new one
425 //
426 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);
427 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
428 ASSERT (NewStr != NULL);
429 if (Storage->ConfigRequest != NULL) {
430 CopyMem (NewStr, Storage->ConfigRequest, StringSize);
431 FreePool (Storage->ConfigRequest);
432 }
433 Storage->ConfigRequest = NewStr;
434 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
435 }
436
437 StrCat (Storage->ConfigRequest, RequestElement);
438 Storage->ElementCount++;
439 Storage->SpareStrLen -= StrLen;
440
441 //
442 // Update the Config Request info saved in the form.
443 //
444 ConfigInfo = NULL;
445 Find = FALSE;
446 Link = GetFirstNode (&Form->ConfigRequestHead);
447 while (!IsNull (&Form->ConfigRequestHead, Link)) {
448 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
449
450 if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) {
451 Find = TRUE;
452 break;
453 }
454
455 Link = GetNextNode (&Form->ConfigRequestHead, Link);
456 }
457
458 if (!Find) {
459 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
460 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
461 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
462 ConfigInfo->SpareStrLen = 0;
463 ConfigInfo->Storage = Storage;
464 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
465 }
466
467 //
468 // Append <RequestElement> to <ConfigRequest>
469 //
470 if (StrLen > ConfigInfo->SpareStrLen) {
471 //
472 // Old String buffer is not sufficient for RequestElement, allocate a new one
473 //
474 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
475 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
476 ASSERT (NewStr != NULL);
477 if (ConfigInfo->ConfigRequest != NULL) {
478 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
479 FreePool (ConfigInfo->ConfigRequest);
480 }
481 ConfigInfo->ConfigRequest = NewStr;
482 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
483 }
484
485 StrCat (ConfigInfo->ConfigRequest, RequestElement);
486 ConfigInfo->ElementCount++;
487 ConfigInfo->SpareStrLen -= StrLen;
488 return EFI_SUCCESS;
489 }
490
491
492 /**
493 Free resources of a Expression.
494
495 @param FormSet Pointer of the Expression
496
497 **/
498 VOID
499 DestroyExpression (
500 IN FORM_EXPRESSION *Expression
501 )
502 {
503 LIST_ENTRY *Link;
504 EXPRESSION_OPCODE *OpCode;
505 LIST_ENTRY *SubExpressionLink;
506 FORM_EXPRESSION *SubExpression;
507
508 while (!IsListEmpty (&Expression->OpCodeListHead)) {
509 Link = GetFirstNode (&Expression->OpCodeListHead);
510 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
511 RemoveEntryList (&OpCode->Link);
512
513 if (OpCode->ValueList != NULL) {
514 FreePool (OpCode->ValueList);
515 }
516
517 if (OpCode->ValueName != NULL) {
518 FreePool (OpCode->ValueName);
519 }
520
521 if (OpCode->MapExpressionList.ForwardLink != NULL) {
522 while (!IsListEmpty (&OpCode->MapExpressionList)) {
523 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
524 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
525 RemoveEntryList(&SubExpression->Link);
526 DestroyExpression (SubExpression);
527 }
528 }
529 }
530
531 //
532 // Free this Expression
533 //
534 FreePool (Expression);
535 }
536
537
538 /**
539 Free resources of a storage.
540
541 @param Storage Pointer of the storage
542
543 **/
544 VOID
545 DestroyStorage (
546 IN FORMSET_STORAGE *Storage
547 )
548 {
549 LIST_ENTRY *Link;
550 NAME_VALUE_NODE *NameValueNode;
551
552 if (Storage == NULL) {
553 return;
554 }
555
556 if (Storage->Name != NULL) {
557 FreePool (Storage->Name);
558 }
559 if (Storage->Buffer != NULL) {
560 FreePool (Storage->Buffer);
561 }
562 if (Storage->EditBuffer != NULL) {
563 FreePool (Storage->EditBuffer);
564 }
565
566 while (!IsListEmpty (&Storage->NameValueListHead)) {
567 Link = GetFirstNode (&Storage->NameValueListHead);
568 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
569 RemoveEntryList (&NameValueNode->Link);
570
571 if (NameValueNode->Name != NULL) {
572 FreePool (NameValueNode->Name);
573 }
574 if (NameValueNode->Value != NULL) {
575 FreePool (NameValueNode->Value);
576 }
577 if (NameValueNode->EditValue != NULL) {
578 FreePool (NameValueNode->EditValue);
579 }
580 FreePool (NameValueNode);
581 }
582
583 if (Storage->ConfigHdr != NULL) {
584 FreePool (Storage->ConfigHdr);
585 }
586 if (Storage->ConfigRequest != NULL) {
587 FreePool (Storage->ConfigRequest);
588 }
589
590 FreePool (Storage);
591 }
592
593
594 /**
595 Free resources of a Statement.
596
597 @param FormSet Pointer of the FormSet
598 @param Statement Pointer of the Statement
599
600 **/
601 VOID
602 DestroyStatement (
603 IN FORM_BROWSER_FORMSET *FormSet,
604 IN OUT FORM_BROWSER_STATEMENT *Statement
605 )
606 {
607 LIST_ENTRY *Link;
608 QUESTION_DEFAULT *Default;
609 QUESTION_OPTION *Option;
610 FORM_EXPRESSION *Expression;
611
612 //
613 // Free Default value List
614 //
615 while (!IsListEmpty (&Statement->DefaultListHead)) {
616 Link = GetFirstNode (&Statement->DefaultListHead);
617 Default = QUESTION_DEFAULT_FROM_LINK (Link);
618 RemoveEntryList (&Default->Link);
619
620 FreePool (Default);
621 }
622
623 //
624 // Free Options List
625 //
626 while (!IsListEmpty (&Statement->OptionListHead)) {
627 Link = GetFirstNode (&Statement->OptionListHead);
628 Option = QUESTION_OPTION_FROM_LINK (Link);
629 RemoveEntryList (&Option->Link);
630
631 FreePool (Option);
632 }
633
634 //
635 // Free Inconsistent List
636 //
637 while (!IsListEmpty (&Statement->InconsistentListHead)) {
638 Link = GetFirstNode (&Statement->InconsistentListHead);
639 Expression = FORM_EXPRESSION_FROM_LINK (Link);
640 RemoveEntryList (&Expression->Link);
641
642 DestroyExpression (Expression);
643 }
644
645 //
646 // Free NoSubmit List
647 //
648 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
649 Link = GetFirstNode (&Statement->NoSubmitListHead);
650 Expression = FORM_EXPRESSION_FROM_LINK (Link);
651 RemoveEntryList (&Expression->Link);
652
653 DestroyExpression (Expression);
654 }
655
656 if (Statement->VariableName != NULL) {
657 FreePool (Statement->VariableName);
658 }
659 if (Statement->BlockName != NULL) {
660 FreePool (Statement->BlockName);
661 }
662 if (Statement->BufferValue != NULL) {
663 FreePool (Statement->BufferValue);
664 }
665 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
666 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
667 }
668 }
669
670
671 /**
672 Free resources of a Form.
673
674 @param FormSet Pointer of the FormSet
675 @param Form Pointer of the Form.
676
677 **/
678 VOID
679 DestroyForm (
680 IN FORM_BROWSER_FORMSET *FormSet,
681 IN OUT FORM_BROWSER_FORM *Form
682 )
683 {
684 LIST_ENTRY *Link;
685 FORM_EXPRESSION *Expression;
686 FORM_BROWSER_STATEMENT *Statement;
687 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
688
689 //
690 // Free Form Expressions
691 //
692 while (!IsListEmpty (&Form->ExpressionListHead)) {
693 Link = GetFirstNode (&Form->ExpressionListHead);
694 Expression = FORM_EXPRESSION_FROM_LINK (Link);
695 RemoveEntryList (&Expression->Link);
696
697 DestroyExpression (Expression);
698 }
699
700 //
701 // Free Statements/Questions
702 //
703 while (!IsListEmpty (&Form->StatementListHead)) {
704 Link = GetFirstNode (&Form->StatementListHead);
705 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
706 RemoveEntryList (&Statement->Link);
707
708 DestroyStatement (FormSet, Statement);
709 }
710
711 //
712 // Free ConfigRequest string.
713 //
714 while (!IsListEmpty (&Form->ConfigRequestHead)) {
715 Link = GetFirstNode (&Form->ConfigRequestHead);
716 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
717 RemoveEntryList (&ConfigInfo->Link);
718
719 FreePool (ConfigInfo->ConfigRequest);
720 FreePool (ConfigInfo);
721 }
722
723 //
724 // Free this Form
725 //
726 FreePool (Form);
727 }
728
729
730 /**
731 Free resources allocated for a FormSet.
732
733 @param FormSet Pointer of the FormSet
734
735 **/
736 VOID
737 DestroyFormSet (
738 IN OUT FORM_BROWSER_FORMSET *FormSet
739 )
740 {
741 LIST_ENTRY *Link;
742 FORMSET_STORAGE *Storage;
743 FORMSET_DEFAULTSTORE *DefaultStore;
744 FORM_EXPRESSION *Expression;
745 FORM_BROWSER_FORM *Form;
746
747 if (FormSet->IfrBinaryData == NULL) {
748 //
749 // Uninitialized FormSet
750 //
751 FreePool (FormSet);
752 return;
753 }
754
755 //
756 // Free IFR binary buffer
757 //
758 FreePool (FormSet->IfrBinaryData);
759
760 //
761 // Free FormSet Storage
762 //
763 if (FormSet->StorageListHead.ForwardLink != NULL) {
764 while (!IsListEmpty (&FormSet->StorageListHead)) {
765 Link = GetFirstNode (&FormSet->StorageListHead);
766 Storage = FORMSET_STORAGE_FROM_LINK (Link);
767 RemoveEntryList (&Storage->Link);
768
769 DestroyStorage (Storage);
770 }
771 }
772
773 //
774 // Free FormSet Default Store
775 //
776 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
777 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
778 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
779 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
780 RemoveEntryList (&DefaultStore->Link);
781
782 FreePool (DefaultStore);
783 }
784 }
785
786 //
787 // Free Formset Expressions
788 //
789 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
790 Link = GetFirstNode (&FormSet->ExpressionListHead);
791 Expression = FORM_EXPRESSION_FROM_LINK (Link);
792 RemoveEntryList (&Expression->Link);
793
794 DestroyExpression (Expression);
795 }
796
797 //
798 // Free Forms
799 //
800 if (FormSet->FormListHead.ForwardLink != NULL) {
801 while (!IsListEmpty (&FormSet->FormListHead)) {
802 Link = GetFirstNode (&FormSet->FormListHead);
803 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
804 RemoveEntryList (&Form->Link);
805
806 DestroyForm (FormSet, Form);
807 }
808 }
809
810 if (FormSet->StatementBuffer != NULL) {
811 FreePool (FormSet->StatementBuffer);
812 }
813 if (FormSet->ExpressionBuffer != NULL) {
814 FreePool (FormSet->ExpressionBuffer);
815 }
816
817 FreePool (FormSet);
818 }
819
820
821 /**
822 Tell whether this Operand is an Expression OpCode or not
823
824 @param Operand Operand of an IFR OpCode.
825
826 @retval TRUE This is an Expression OpCode.
827 @retval FALSE Not an Expression OpCode.
828
829 **/
830 BOOLEAN
831 IsExpressionOpCode (
832 IN UINT8 Operand
833 )
834 {
835 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
836 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
837 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
838 (Operand == EFI_IFR_CATENATE_OP) ||
839 (Operand == EFI_IFR_TO_LOWER_OP) ||
840 (Operand == EFI_IFR_TO_UPPER_OP) ||
841 (Operand == EFI_IFR_MAP_OP) ||
842 (Operand == EFI_IFR_VERSION_OP) ||
843 (Operand == EFI_IFR_SECURITY_OP)) {
844 return TRUE;
845 } else {
846 return FALSE;
847 }
848 }
849
850
851 /**
852 Calculate number of Statemens(Questions) and Expression OpCodes.
853
854 @param FormSet The FormSet to be counted.
855 @param NumberOfStatement Number of Statemens(Questions)
856 @param NumberOfExpression Number of Expression OpCodes
857
858 **/
859 VOID
860 CountOpCodes (
861 IN FORM_BROWSER_FORMSET *FormSet,
862 IN OUT UINT16 *NumberOfStatement,
863 IN OUT UINT16 *NumberOfExpression
864 )
865 {
866 UINT16 StatementCount;
867 UINT16 ExpressionCount;
868 UINT8 *OpCodeData;
869 UINTN Offset;
870 UINTN OpCodeLen;
871
872 Offset = 0;
873 StatementCount = 0;
874 ExpressionCount = 0;
875
876 while (Offset < FormSet->IfrBinaryLength) {
877 OpCodeData = FormSet->IfrBinaryData + Offset;
878 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
879 Offset += OpCodeLen;
880
881 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
882 ExpressionCount++;
883 } else {
884 StatementCount++;
885 }
886 }
887
888 *NumberOfStatement = StatementCount;
889 *NumberOfExpression = ExpressionCount;
890 }
891
892
893
894 /**
895 Parse opcodes in the formset IFR binary.
896
897 @param FormSet Pointer of the FormSet data structure.
898
899 @retval EFI_SUCCESS Opcode parse success.
900 @retval Other Opcode parse fail.
901
902 **/
903 EFI_STATUS
904 ParseOpCodes (
905 IN FORM_BROWSER_FORMSET *FormSet
906 )
907 {
908 EFI_STATUS Status;
909 UINT16 Index;
910 FORM_BROWSER_FORM *CurrentForm;
911 FORM_BROWSER_STATEMENT *CurrentStatement;
912 EXPRESSION_OPCODE *ExpressionOpCode;
913 FORM_EXPRESSION *CurrentExpression;
914 UINT8 Operand;
915 UINT8 Scope;
916 UINTN OpCodeOffset;
917 UINTN OpCodeLength;
918 UINT8 *OpCodeData;
919 UINT8 ScopeOpCode;
920 FORMSET_STORAGE *Storage;
921 FORMSET_DEFAULTSTORE *DefaultStore;
922 QUESTION_DEFAULT *CurrentDefault;
923 QUESTION_OPTION *CurrentOption;
924 UINT8 Width;
925 CHAR8 *AsciiString;
926 UINT16 NumberOfStatement;
927 UINT16 NumberOfExpression;
928 EFI_IMAGE_ID *ImageId;
929 BOOLEAN SuppressForQuestion;
930 BOOLEAN SuppressForOption;
931 BOOLEAN InScopeOptionSuppress;
932 FORM_EXPRESSION *OptionSuppressExpression;
933 BOOLEAN InScopeFormSuppress;
934 FORM_EXPRESSION *FormSuppressExpression;
935 UINT16 DepthOfDisable;
936 BOOLEAN OpCodeDisabled;
937 BOOLEAN SingleOpCodeExpression;
938 BOOLEAN InScopeDefault;
939 EFI_HII_VALUE *Value;
940 EFI_IFR_FORM_MAP_METHOD *MapMethod;
941 UINT8 MapScopeDepth;
942 LIST_ENTRY *Link;
943 FORMSET_STORAGE *VarStorage;
944 LIST_ENTRY *MapExpressionList;
945 EFI_VARSTORE_ID TempVarstoreId;
946
947 mInScopeSubtitle = FALSE;
948 SuppressForQuestion = FALSE;
949 SuppressForOption = FALSE;
950 InScopeFormSuppress = FALSE;
951 mInScopeSuppress = FALSE;
952 InScopeOptionSuppress = FALSE;
953 mInScopeGrayOut = FALSE;
954 mInScopeDisable = FALSE;
955 DepthOfDisable = 0;
956 OpCodeDisabled = FALSE;
957 SingleOpCodeExpression = FALSE;
958 InScopeDefault = FALSE;
959 CurrentExpression = NULL;
960 CurrentDefault = NULL;
961 CurrentOption = NULL;
962 OptionSuppressExpression = NULL;
963 FormSuppressExpression = NULL;
964 ImageId = NULL;
965 MapMethod = NULL;
966 MapScopeDepth = 0;
967 Link = NULL;
968 VarStorage = NULL;
969 MapExpressionList = NULL;
970 TempVarstoreId = 0;
971
972 //
973 // Get the number of Statements and Expressions
974 //
975 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
976
977 mStatementIndex = 0;
978 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
979 if (FormSet->StatementBuffer == NULL) {
980 return EFI_OUT_OF_RESOURCES;
981 }
982
983 mExpressionOpCodeIndex = 0;
984 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
985 if (FormSet->ExpressionBuffer == NULL) {
986 return EFI_OUT_OF_RESOURCES;
987 }
988
989 InitializeListHead (&FormSet->StorageListHead);
990 InitializeListHead (&FormSet->DefaultStoreListHead);
991 InitializeListHead (&FormSet->FormListHead);
992 ResetCurrentExpressionStack ();
993 ResetMapExpressionListStack ();
994
995 CurrentForm = NULL;
996 CurrentStatement = NULL;
997
998 ResetScopeStack ();
999
1000 OpCodeOffset = 0;
1001 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1002 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1003
1004 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1005 OpCodeOffset += OpCodeLength;
1006 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1007 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1008
1009 //
1010 // If scope bit set, push onto scope stack
1011 //
1012 if (Scope != 0) {
1013 PushScope (Operand);
1014 }
1015
1016 if (OpCodeDisabled) {
1017 //
1018 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1019 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1020 //
1021 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1022 DepthOfDisable++;
1023 } else if (Operand == EFI_IFR_END_OP) {
1024 Status = PopScope (&ScopeOpCode);
1025 if (EFI_ERROR (Status)) {
1026 return Status;
1027 }
1028
1029 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1030 if (DepthOfDisable == 0) {
1031 mInScopeDisable = FALSE;
1032 OpCodeDisabled = FALSE;
1033 } else {
1034 DepthOfDisable--;
1035 }
1036 }
1037 }
1038 continue;
1039 }
1040
1041 if (IsExpressionOpCode (Operand)) {
1042 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1043 mExpressionOpCodeIndex++;
1044
1045 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1046 ExpressionOpCode->Operand = Operand;
1047 Value = &ExpressionOpCode->Value;
1048
1049 switch (Operand) {
1050 case EFI_IFR_EQ_ID_VAL_OP:
1051 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1052
1053 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1054 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1055 break;
1056
1057 case EFI_IFR_EQ_ID_ID_OP:
1058 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1059 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1060 break;
1061
1062 case EFI_IFR_EQ_ID_LIST_OP:
1063 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1064 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1065 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
1066 break;
1067
1068 case EFI_IFR_TO_STRING_OP:
1069 case EFI_IFR_FIND_OP:
1070 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1071 break;
1072
1073 case EFI_IFR_STRING_REF1_OP:
1074 Value->Type = EFI_IFR_TYPE_STRING;
1075 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1076 break;
1077
1078 case EFI_IFR_RULE_REF_OP:
1079 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1080 break;
1081
1082 case EFI_IFR_SPAN_OP:
1083 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1084 break;
1085
1086 case EFI_IFR_THIS_OP:
1087 ASSERT (CurrentStatement != NULL);
1088 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;
1089 break;
1090
1091 case EFI_IFR_SECURITY_OP:
1092 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1093 break;
1094
1095 case EFI_IFR_GET_OP:
1096 case EFI_IFR_SET_OP:
1097 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1098 if (TempVarstoreId != 0) {
1099 if (FormSet->StorageListHead.ForwardLink != NULL) {
1100 Link = GetFirstNode (&FormSet->StorageListHead);
1101 while (!IsNull (&FormSet->StorageListHead, Link)) {
1102 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1103 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
1104 ExpressionOpCode->VarStorage = VarStorage;
1105 break;
1106 }
1107 Link = GetNextNode (&FormSet->StorageListHead, Link);
1108 }
1109 }
1110 if (ExpressionOpCode->VarStorage == NULL) {
1111 //
1112 // VarStorage is not found.
1113 //
1114 return EFI_INVALID_PARAMETER;
1115 }
1116 }
1117 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1118 switch (ExpressionOpCode->ValueType) {
1119 case EFI_IFR_TYPE_BOOLEAN:
1120 case EFI_IFR_TYPE_NUM_SIZE_8:
1121 ExpressionOpCode->ValueWidth = 1;
1122 break;
1123
1124 case EFI_IFR_TYPE_NUM_SIZE_16:
1125 case EFI_IFR_TYPE_STRING:
1126 ExpressionOpCode->ValueWidth = 2;
1127 break;
1128
1129 case EFI_IFR_TYPE_NUM_SIZE_32:
1130 ExpressionOpCode->ValueWidth = 4;
1131 break;
1132
1133 case EFI_IFR_TYPE_NUM_SIZE_64:
1134 ExpressionOpCode->ValueWidth = 8;
1135 break;
1136
1137 case EFI_IFR_TYPE_DATE:
1138 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
1139 break;
1140
1141 case EFI_IFR_TYPE_TIME:
1142 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
1143 break;
1144
1145 case EFI_IFR_TYPE_OTHER:
1146 case EFI_IFR_TYPE_UNDEFINED:
1147 case EFI_IFR_TYPE_ACTION:
1148 case EFI_IFR_TYPE_BUFFER:
1149 default:
1150 //
1151 // Invalid value type for Get/Set opcode.
1152 //
1153 return EFI_INVALID_PARAMETER;
1154 }
1155 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1156 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1157 if ((ExpressionOpCode->VarStorage != NULL) &&
1158 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1159 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1160 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1161 if (ExpressionOpCode->ValueName == NULL) {
1162 //
1163 // String ID is invalid.
1164 //
1165 return EFI_INVALID_PARAMETER;
1166 }
1167 }
1168 break;
1169
1170 case EFI_IFR_QUESTION_REF1_OP:
1171 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1172 break;
1173
1174 case EFI_IFR_QUESTION_REF3_OP:
1175 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1176 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1177
1178 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1179 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1180 }
1181 }
1182 break;
1183
1184 //
1185 // constant
1186 //
1187 case EFI_IFR_TRUE_OP:
1188 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1189 Value->Value.b = TRUE;
1190 break;
1191
1192 case EFI_IFR_FALSE_OP:
1193 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1194 Value->Value.b = FALSE;
1195 break;
1196
1197 case EFI_IFR_ONE_OP:
1198 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1199 Value->Value.u8 = 1;
1200 break;
1201
1202 case EFI_IFR_ZERO_OP:
1203 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1204 Value->Value.u8 = 0;
1205 break;
1206
1207 case EFI_IFR_ONES_OP:
1208 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1209 Value->Value.u64 = 0xffffffffffffffffULL;
1210 break;
1211
1212 case EFI_IFR_UINT8_OP:
1213 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1214 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1215 break;
1216
1217 case EFI_IFR_UINT16_OP:
1218 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1219 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1220 break;
1221
1222 case EFI_IFR_UINT32_OP:
1223 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1224 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1225 break;
1226
1227 case EFI_IFR_UINT64_OP:
1228 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1229 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1230 break;
1231
1232 case EFI_IFR_UNDEFINED_OP:
1233 Value->Type = EFI_IFR_TYPE_UNDEFINED;
1234 break;
1235
1236 case EFI_IFR_VERSION_OP:
1237 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1238 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1239 break;
1240
1241 default:
1242 break;
1243 }
1244 //
1245 // Create sub expression nested in MAP opcode
1246 //
1247 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1248 CurrentExpression = CreateExpression (CurrentForm);
1249 ASSERT (MapExpressionList != NULL);
1250 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1251 if (Scope == 0) {
1252 SingleOpCodeExpression = TRUE;
1253 }
1254 }
1255 ASSERT (CurrentExpression != NULL);
1256 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
1257 if (Operand == EFI_IFR_MAP_OP) {
1258 //
1259 // Store current Map Expression List.
1260 //
1261 if (MapExpressionList != NULL) {
1262 PushMapExpressionList (MapExpressionList);
1263 }
1264 //
1265 // Initialize new Map Expression List.
1266 //
1267 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1268 InitializeListHead (MapExpressionList);
1269 //
1270 // Store current expression.
1271 //
1272 PushCurrentExpression (CurrentExpression);
1273 CurrentExpression = NULL;
1274 MapScopeDepth ++;
1275 } else if (SingleOpCodeExpression) {
1276 //
1277 // There are two cases to indicate the end of an Expression:
1278 // for single OpCode expression: one Expression OpCode
1279 // for expression consists of more than one OpCode: EFI_IFR_END
1280 //
1281 SingleOpCodeExpression = FALSE;
1282
1283 if (mInScopeDisable && CurrentForm == NULL) {
1284 //
1285 // This is DisableIf expression for Form, it should be a constant expression
1286 //
1287 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1288 if (EFI_ERROR (Status)) {
1289 return Status;
1290 }
1291
1292 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1293 return EFI_INVALID_PARAMETER;
1294 }
1295
1296 OpCodeDisabled = CurrentExpression->Result.Value.b;
1297 }
1298
1299 CurrentExpression = NULL;
1300 }
1301
1302 continue;
1303 }
1304
1305 //
1306 // Parse the Opcode
1307 //
1308 switch (Operand) {
1309
1310 case EFI_IFR_FORM_SET_OP:
1311 //
1312 // Check the formset GUID
1313 //
1314 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1315 return EFI_INVALID_PARAMETER;
1316 }
1317
1318 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1319 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
1320
1321 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1322 //
1323 // The formset OpCode contains ClassGuid
1324 //
1325 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1326 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1327 }
1328
1329 InitializeListHead (&FormSet->ExpressionListHead);
1330 break;
1331
1332 case EFI_IFR_FORM_OP:
1333 //
1334 // Create a new Form for this FormSet
1335 //
1336 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1337 ASSERT (CurrentForm != NULL);
1338 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1339 InitializeListHead (&CurrentForm->ExpressionListHead);
1340 InitializeListHead (&CurrentForm->StatementListHead);
1341 InitializeListHead (&CurrentForm->ConfigRequestHead);
1342
1343 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1344 CurrentForm->NvUpdateRequired = FALSE;
1345 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1346 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1347
1348 if (InScopeFormSuppress) {
1349 //
1350 // Form is inside of suppressif
1351 //
1352 CurrentForm->SuppressExpression = FormSuppressExpression;
1353 }
1354
1355 if (Scope != 0) {
1356 //
1357 // Enter scope of a Form, suppressif will be used for Question or Option
1358 //
1359 SuppressForQuestion = TRUE;
1360 }
1361
1362 //
1363 // Insert into Form list of this FormSet
1364 //
1365 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1366 break;
1367
1368 case EFI_IFR_FORM_MAP_OP:
1369 //
1370 // Create a new Form for this FormSet
1371 //
1372 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1373 ASSERT (CurrentForm != NULL);
1374 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1375 CurrentForm->NvUpdateRequired = FALSE;
1376 InitializeListHead (&CurrentForm->ExpressionListHead);
1377 InitializeListHead (&CurrentForm->StatementListHead);
1378 InitializeListHead (&CurrentForm->ConfigRequestHead);
1379 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1380
1381 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1382 //
1383 // FormMap Form must contain at least one Map Method.
1384 //
1385 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1386 return EFI_INVALID_PARAMETER;
1387 }
1388 //
1389 // Try to find the standard form map method.
1390 //
1391 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1392 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1393 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1394 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1395 break;
1396 }
1397 MapMethod ++;
1398 }
1399 //
1400 // If the standard form map method is not found, the first map method title will be used.
1401 //
1402 if (CurrentForm->FormTitle == 0) {
1403 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1404 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1405 }
1406
1407 if (InScopeFormSuppress) {
1408 //
1409 // Form is inside of suppressif
1410 //
1411 CurrentForm->SuppressExpression = FormSuppressExpression;
1412 }
1413
1414 if (Scope != 0) {
1415 //
1416 // Enter scope of a Form, suppressif will be used for Question or Option
1417 //
1418 SuppressForQuestion = TRUE;
1419 }
1420
1421 //
1422 // Insert into Form list of this FormSet
1423 //
1424 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1425 break;
1426
1427 //
1428 // Storage
1429 //
1430 case EFI_IFR_VARSTORE_OP:
1431 //
1432 // Create a buffer Storage for this FormSet
1433 //
1434 Storage = CreateStorage (FormSet);
1435 Storage->Type = EFI_HII_VARSTORE_BUFFER;
1436
1437 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1438 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1439 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
1440
1441 Storage->Buffer = AllocateZeroPool (Storage->Size);
1442 Storage->EditBuffer = AllocateZeroPool (Storage->Size);
1443
1444 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
1445 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
1446 ASSERT (Storage->Name != NULL);
1447 for (Index = 0; AsciiString[Index] != 0; Index++) {
1448 Storage->Name[Index] = (CHAR16) AsciiString[Index];
1449 }
1450
1451 //
1452 // Initialize <ConfigHdr>
1453 //
1454 InitializeConfigHdr (FormSet, Storage);
1455 break;
1456
1457 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1458 //
1459 // Create a name/value Storage for this FormSet
1460 //
1461 Storage = CreateStorage (FormSet);
1462 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
1463
1464 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1465 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1466
1467 //
1468 // Initialize <ConfigHdr>
1469 //
1470 InitializeConfigHdr (FormSet, Storage);
1471 break;
1472
1473 case EFI_IFR_VARSTORE_EFI_OP:
1474 //
1475 // Create a EFI variable Storage for this FormSet
1476 //
1477 Storage = CreateStorage (FormSet);
1478 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
1479
1480 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1481 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
1482 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
1483 break;
1484
1485 //
1486 // DefaultStore
1487 //
1488 case EFI_IFR_DEFAULTSTORE_OP:
1489 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1490 ASSERT (DefaultStore != NULL);
1491 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1492
1493 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1494 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1495
1496 //
1497 // Insert to DefaultStore list of this Formset
1498 //
1499 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1500 break;
1501
1502 //
1503 // Statements
1504 //
1505 case EFI_IFR_SUBTITLE_OP:
1506 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1507 ASSERT (CurrentStatement != NULL);
1508
1509 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1510
1511 if (Scope != 0) {
1512 mInScopeSubtitle = TRUE;
1513 }
1514 break;
1515
1516 case EFI_IFR_TEXT_OP:
1517 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1518 ASSERT (CurrentStatement != NULL);
1519
1520 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1521 break;
1522
1523 case EFI_IFR_RESET_BUTTON_OP:
1524 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1525 ASSERT (CurrentStatement != NULL);
1526 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1527 break;
1528
1529 //
1530 // Questions
1531 //
1532 case EFI_IFR_ACTION_OP:
1533 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1534 ASSERT (CurrentStatement != NULL);
1535 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
1536
1537 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1538 //
1539 // No QuestionConfig present, so no configuration string will be processed
1540 //
1541 CurrentStatement->QuestionConfig = 0;
1542 } else {
1543 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1544 }
1545 break;
1546
1547 case EFI_IFR_REF_OP:
1548 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1549 ASSERT (CurrentStatement != NULL);
1550 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;
1551 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1552 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1553 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1554
1555 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1556 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1557
1558 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1559 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1560 }
1561 }
1562 }
1563 break;
1564
1565 case EFI_IFR_ONE_OF_OP:
1566 case EFI_IFR_NUMERIC_OP:
1567 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1568 ASSERT(CurrentStatement != NULL);
1569
1570 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1571 Value = &CurrentStatement->HiiValue;
1572
1573 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1574 case EFI_IFR_NUMERIC_SIZE_1:
1575 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1576 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1577 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
1578 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
1579 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1580 break;
1581
1582 case EFI_IFR_NUMERIC_SIZE_2:
1583 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1584 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1585 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
1586 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
1587 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1588 break;
1589
1590 case EFI_IFR_NUMERIC_SIZE_4:
1591 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1592 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1593 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
1594 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
1595 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1596 break;
1597
1598 case EFI_IFR_NUMERIC_SIZE_8:
1599 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1600 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1601 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
1602 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
1603 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1604 break;
1605
1606 default:
1607 break;
1608 }
1609
1610 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1611
1612 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
1613 SuppressForOption = TRUE;
1614 }
1615 break;
1616
1617 case EFI_IFR_ORDERED_LIST_OP:
1618 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1619 ASSERT(CurrentStatement != NULL);
1620
1621 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1622 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
1623
1624 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
1625 CurrentStatement->BufferValue = NULL;
1626
1627 if (Scope != 0) {
1628 SuppressForOption = TRUE;
1629 }
1630 break;
1631
1632 case EFI_IFR_CHECKBOX_OP:
1633 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1634 ASSERT(CurrentStatement != NULL);
1635
1636 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
1637 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
1638 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1639
1640 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1641
1642 break;
1643
1644 case EFI_IFR_STRING_OP:
1645 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1646 ASSERT (CurrentStatement != NULL);
1647 //
1648 // MinSize is the minimum number of characters that can be accepted for this opcode,
1649 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1650 // The characters are stored as Unicode, so the storage width should multiply 2.
1651 //
1652 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1653 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1654 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1655 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1656
1657 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1658 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
1659 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1660
1661 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1662 break;
1663
1664 case EFI_IFR_PASSWORD_OP:
1665 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1666 ASSERT (CurrentStatement != NULL);
1667 //
1668 // MinSize is the minimum number of characters that can be accepted for this opcode,
1669 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1670 // The characters are stored as Unicode, so the storage width should multiply 2.
1671 //
1672 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1673 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1674 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1675
1676 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1677 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
1678 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1679
1680 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1681 break;
1682
1683 case EFI_IFR_DATE_OP:
1684 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1685 ASSERT(CurrentStatement != NULL);
1686
1687 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1688 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1689
1690 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
1691 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
1692
1693 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1694 } else {
1695 //
1696 // Don't assign storage for RTC type of date/time
1697 //
1698 CurrentStatement->Storage = NULL;
1699 CurrentStatement->StorageWidth = 0;
1700 }
1701 break;
1702
1703 case EFI_IFR_TIME_OP:
1704 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1705 ASSERT(CurrentStatement != NULL);
1706
1707 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1708 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1709
1710 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
1711 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
1712
1713 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1714 } else {
1715 //
1716 // Don't assign storage for RTC type of date/time
1717 //
1718 CurrentStatement->Storage = NULL;
1719 CurrentStatement->StorageWidth = 0;
1720 }
1721 break;
1722
1723 //
1724 // Default
1725 //
1726 case EFI_IFR_DEFAULT_OP:
1727 //
1728 // EFI_IFR_DEFAULT appear in scope of a Question,
1729 // It creates a default value for the current question.
1730 // A Question may have more than one Default value which have different default types.
1731 //
1732 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
1733 ASSERT (CurrentDefault != NULL);
1734 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1735
1736 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1737 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
1738 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1739 ExtendValueToU64 (&CurrentDefault->Value);
1740
1741 //
1742 // Insert to Default Value list of current Question
1743 //
1744 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
1745
1746 if (Scope != 0) {
1747 InScopeDefault = TRUE;
1748 }
1749 break;
1750
1751 //
1752 // Option
1753 //
1754 case EFI_IFR_ONE_OF_OPTION_OP:
1755 //
1756 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1757 // It create a selection for use in current Question.
1758 //
1759 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
1760 ASSERT (CurrentOption != NULL);
1761 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
1762
1763 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1764 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1765 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
1766 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1767 ExtendValueToU64 (&CurrentOption->Value);
1768
1769 if (InScopeOptionSuppress) {
1770 CurrentOption->SuppressExpression = OptionSuppressExpression;
1771 }
1772
1773 //
1774 // Insert to Option list of current Question
1775 //
1776 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
1777
1778 //
1779 // Now we know the Storage width of nested Ordered List
1780 //
1781 ASSERT (CurrentStatement != NULL);
1782 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {
1783 Width = 1;
1784 switch (CurrentOption->Value.Type) {
1785 case EFI_IFR_TYPE_NUM_SIZE_8:
1786 Width = 1;
1787 break;
1788
1789 case EFI_IFR_TYPE_NUM_SIZE_16:
1790 Width = 2;
1791 break;
1792
1793 case EFI_IFR_TYPE_NUM_SIZE_32:
1794 Width = 4;
1795 break;
1796
1797 case EFI_IFR_TYPE_NUM_SIZE_64:
1798 Width = 8;
1799 break;
1800
1801 default:
1802 //
1803 // Invalid type for Ordered List
1804 //
1805 break;
1806 }
1807
1808 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);
1809 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
1810 CurrentStatement->ValueType = CurrentOption->Value.Type;
1811
1812 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1813 }
1814 break;
1815
1816 //
1817 // Conditional
1818 //
1819 case EFI_IFR_NO_SUBMIT_IF_OP:
1820 case EFI_IFR_INCONSISTENT_IF_OP:
1821 //
1822 // Create an Expression node
1823 //
1824 CurrentExpression = CreateExpression (CurrentForm);
1825 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
1826
1827 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
1828 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
1829 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);
1830 } else {
1831 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
1832 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);
1833 }
1834
1835 //
1836 // Take a look at next OpCode to see whether current expression consists
1837 // of single OpCode
1838 //
1839 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1840 SingleOpCodeExpression = TRUE;
1841 }
1842 break;
1843
1844 case EFI_IFR_SUPPRESS_IF_OP:
1845 //
1846 // Question and Option will appear in scope of this OpCode
1847 //
1848 CurrentExpression = CreateExpression (CurrentForm);
1849 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
1850
1851 if (CurrentForm == NULL) {
1852 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
1853 } else {
1854 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1855 }
1856
1857 if (SuppressForOption) {
1858 InScopeOptionSuppress = TRUE;
1859 OptionSuppressExpression = CurrentExpression;
1860 } else if (SuppressForQuestion) {
1861 mInScopeSuppress = TRUE;
1862 mSuppressExpression = CurrentExpression;
1863 } else {
1864 InScopeFormSuppress = TRUE;
1865 FormSuppressExpression = CurrentExpression;
1866 }
1867
1868 //
1869 // Take a look at next OpCode to see whether current expression consists
1870 // of single OpCode
1871 //
1872 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1873 SingleOpCodeExpression = TRUE;
1874 }
1875 break;
1876
1877 case EFI_IFR_GRAY_OUT_IF_OP:
1878 //
1879 // Questions will appear in scope of this OpCode
1880 //
1881 CurrentExpression = CreateExpression (CurrentForm);
1882 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
1883 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1884
1885 mInScopeGrayOut = TRUE;
1886 mGrayOutExpression = CurrentExpression;
1887
1888 //
1889 // Take a look at next OpCode to see whether current expression consists
1890 // of single OpCode
1891 //
1892 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1893 SingleOpCodeExpression = TRUE;
1894 }
1895 break;
1896
1897 case EFI_IFR_DISABLE_IF_OP:
1898 //
1899 // The DisableIf expression should only rely on constant, so it could be
1900 // evaluated at initialization and it will not be queued
1901 //
1902 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
1903 ASSERT (CurrentExpression != NULL);
1904 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
1905 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
1906 InitializeListHead (&CurrentExpression->OpCodeListHead);
1907
1908 if (CurrentForm != NULL) {
1909 //
1910 // This is DisableIf for Question, enqueue it to Form expression list
1911 //
1912 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1913 }
1914
1915 mDisableExpression = CurrentExpression;
1916 mInScopeDisable = TRUE;
1917 OpCodeDisabled = FALSE;
1918
1919 //
1920 // Take a look at next OpCode to see whether current expression consists
1921 // of single OpCode
1922 //
1923 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1924 SingleOpCodeExpression = TRUE;
1925 }
1926 break;
1927
1928 //
1929 // Expression
1930 //
1931 case EFI_IFR_VALUE_OP:
1932 CurrentExpression = CreateExpression (CurrentForm);
1933 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
1934 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1935
1936 if (InScopeDefault) {
1937 //
1938 // Used for default (EFI_IFR_DEFAULT)
1939 //
1940 CurrentDefault->ValueExpression = CurrentExpression;
1941 } else {
1942 //
1943 // If used for a question, then the question will be read-only
1944 //
1945 //
1946 // Make sure CurrentStatement is not NULL.
1947 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1948 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1949 //
1950 ASSERT (CurrentStatement != NULL);
1951 CurrentStatement->ValueExpression = CurrentExpression;
1952 }
1953
1954 //
1955 // Take a look at next OpCode to see whether current expression consists
1956 // of single OpCode
1957 //
1958 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1959 SingleOpCodeExpression = TRUE;
1960 }
1961 break;
1962
1963 case EFI_IFR_RULE_OP:
1964 CurrentExpression = CreateExpression (CurrentForm);
1965 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
1966
1967 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
1968 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1969
1970 //
1971 // Take a look at next OpCode to see whether current expression consists
1972 // of single OpCode
1973 //
1974 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1975 SingleOpCodeExpression = TRUE;
1976 }
1977 break;
1978
1979 case EFI_IFR_READ_OP:
1980 CurrentExpression = CreateExpression (CurrentForm);
1981 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
1982 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1983
1984 //
1985 // Make sure CurrentStatement is not NULL.
1986 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1987 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1988 //
1989 ASSERT (CurrentStatement != NULL);
1990 CurrentStatement->ReadExpression = CurrentExpression;
1991
1992 //
1993 // Take a look at next OpCode to see whether current expression consists
1994 // of single OpCode
1995 //
1996 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1997 SingleOpCodeExpression = TRUE;
1998 }
1999 break;
2000
2001 case EFI_IFR_WRITE_OP:
2002 CurrentExpression = CreateExpression (CurrentForm);
2003 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2004 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2005
2006 //
2007 // Make sure CurrentStatement is not NULL.
2008 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2009 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2010 //
2011 ASSERT (CurrentStatement != NULL);
2012 CurrentStatement->WriteExpression = CurrentExpression;
2013
2014 //
2015 // Take a look at next OpCode to see whether current expression consists
2016 // of single OpCode
2017 //
2018 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2019 SingleOpCodeExpression = TRUE;
2020 }
2021 break;
2022
2023 //
2024 // Image
2025 //
2026 case EFI_IFR_IMAGE_OP:
2027 //
2028 // Get ScopeOpcode from top of stack
2029 //
2030 PopScope (&ScopeOpCode);
2031 PushScope (ScopeOpCode);
2032
2033 switch (ScopeOpCode) {
2034 case EFI_IFR_FORM_SET_OP:
2035 ImageId = &FormSet->ImageId;
2036 break;
2037
2038 case EFI_IFR_FORM_OP:
2039 case EFI_IFR_FORM_MAP_OP:
2040 ASSERT (CurrentForm != NULL);
2041 ImageId = &CurrentForm->ImageId;
2042 break;
2043
2044 case EFI_IFR_ONE_OF_OPTION_OP:
2045 ImageId = &CurrentOption->ImageId;
2046 break;
2047
2048 default:
2049 //
2050 // Make sure CurrentStatement is not NULL.
2051 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2052 // file is wrongly generated by tools such as VFR Compiler.
2053 //
2054 ASSERT (CurrentStatement != NULL);
2055 ImageId = &CurrentStatement->ImageId;
2056 break;
2057 }
2058
2059 ASSERT (ImageId != NULL);
2060 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2061 break;
2062
2063 //
2064 // Refresh
2065 //
2066 case EFI_IFR_REFRESH_OP:
2067 ASSERT (CurrentStatement != NULL);
2068 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
2069 break;
2070
2071 //
2072 // Modal tag
2073 //
2074 case EFI_IFR_MODAL_TAG_OP:
2075 ASSERT (CurrentForm != NULL);
2076 CurrentForm->ModalForm = TRUE;
2077 break;
2078
2079 //
2080 // Vendor specific
2081 //
2082 case EFI_IFR_GUID_OP:
2083 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
2084 //
2085 // Tiano specific GUIDed opcodes
2086 //
2087 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
2088 case EFI_IFR_EXTEND_OP_LABEL:
2089 //
2090 // just ignore label
2091 //
2092 break;
2093
2094 case EFI_IFR_EXTEND_OP_BANNER:
2095 //
2096 // By SubClass to get Banner Data from Front Page
2097 //
2098 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
2099 CopyMem (
2100 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
2101 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
2102 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
2103 sizeof (EFI_STRING_ID)
2104 );
2105 }
2106 break;
2107
2108 case EFI_IFR_EXTEND_OP_CLASS:
2109 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
2110 break;
2111
2112 case EFI_IFR_EXTEND_OP_SUBCLASS:
2113 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
2114 break;
2115
2116 default:
2117 break;
2118 }
2119 }
2120
2121 break;
2122
2123 //
2124 // Scope End
2125 //
2126 case EFI_IFR_END_OP:
2127 Status = PopScope (&ScopeOpCode);
2128 if (EFI_ERROR (Status)) {
2129 ResetScopeStack ();
2130 return Status;
2131 }
2132
2133 switch (ScopeOpCode) {
2134 case EFI_IFR_FORM_SET_OP:
2135 //
2136 // End of FormSet, update FormSet IFR binary length
2137 // to stop parsing substantial OpCodes
2138 //
2139 FormSet->IfrBinaryLength = OpCodeOffset;
2140 break;
2141
2142 case EFI_IFR_FORM_OP:
2143 case EFI_IFR_FORM_MAP_OP:
2144 //
2145 // End of Form
2146 //
2147 CurrentForm = NULL;
2148 SuppressForQuestion = FALSE;
2149 break;
2150
2151 case EFI_IFR_ONE_OF_OPTION_OP:
2152 //
2153 // End of Option
2154 //
2155 CurrentOption = NULL;
2156 break;
2157
2158 case EFI_IFR_SUBTITLE_OP:
2159 mInScopeSubtitle = FALSE;
2160 break;
2161
2162 case EFI_IFR_NO_SUBMIT_IF_OP:
2163 case EFI_IFR_INCONSISTENT_IF_OP:
2164 //
2165 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2166 //
2167 break;
2168
2169 case EFI_IFR_SUPPRESS_IF_OP:
2170 if (SuppressForOption) {
2171 InScopeOptionSuppress = FALSE;
2172 } else if (SuppressForQuestion) {
2173 mInScopeSuppress = FALSE;
2174 } else {
2175 InScopeFormSuppress = FALSE;
2176 }
2177 break;
2178
2179 case EFI_IFR_GRAY_OUT_IF_OP:
2180 mInScopeGrayOut = FALSE;
2181 break;
2182
2183 case EFI_IFR_DISABLE_IF_OP:
2184 mInScopeDisable = FALSE;
2185 OpCodeDisabled = FALSE;
2186 break;
2187
2188 case EFI_IFR_ONE_OF_OP:
2189 case EFI_IFR_ORDERED_LIST_OP:
2190 SuppressForOption = FALSE;
2191 break;
2192
2193 case EFI_IFR_DEFAULT_OP:
2194 InScopeDefault = FALSE;
2195 break;
2196
2197 case EFI_IFR_MAP_OP:
2198 //
2199 // Get current Map Expression List.
2200 //
2201 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2202 if (Status == EFI_ACCESS_DENIED) {
2203 MapExpressionList = NULL;
2204 }
2205 //
2206 // Get current expression.
2207 //
2208 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2209 ASSERT_EFI_ERROR (Status);
2210 ASSERT (MapScopeDepth > 0);
2211 MapScopeDepth --;
2212 break;
2213
2214 default:
2215 if (IsExpressionOpCode (ScopeOpCode)) {
2216 if (mInScopeDisable && CurrentForm == NULL) {
2217 //
2218 // This is DisableIf expression for Form, it should be a constant expression
2219 //
2220 ASSERT (CurrentExpression != NULL);
2221 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2222 if (EFI_ERROR (Status)) {
2223 return Status;
2224 }
2225
2226 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
2227 return EFI_INVALID_PARAMETER;
2228 }
2229
2230 OpCodeDisabled = CurrentExpression->Result.Value.b;
2231 //
2232 // DisableIf Expression is only used once and not queued, free it
2233 //
2234 DestroyExpression (CurrentExpression);
2235 }
2236
2237 //
2238 // End of current Expression
2239 //
2240 CurrentExpression = NULL;
2241 }
2242 break;
2243 }
2244 break;
2245
2246 default:
2247 break;
2248 }
2249 }
2250
2251 return EFI_SUCCESS;
2252 }