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