TianoCore EDK2 master
Loading...
Searching...
No Matches
IfrParse.c
Go to the documentation of this file.
1
9#include "Setup.h"
10
11UINTN mStatementIndex;
12UINTN mExpressionOpCodeIndex;
13EFI_QUESTION_ID mUsedQuestionId;
14extern LIST_ENTRY gBrowserStorageList;
15
28 IN UINT8 *OpCodeData,
31 )
32{
33 FORM_BROWSER_STATEMENT *Statement;
34 EFI_IFR_STATEMENT_HEADER *StatementHdr;
35 INTN ConditionalExprCount;
36
37 if (Form == NULL) {
38 //
39 // Only guid op may out side the form level.
40 //
41 ASSERT (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_GUID_OP);
42 }
43
44 Statement = &FormSet->StatementBuffer[mStatementIndex];
45 mStatementIndex++;
46
47 InitializeListHead (&Statement->DefaultListHead);
48 InitializeListHead (&Statement->OptionListHead);
49 InitializeListHead (&Statement->InconsistentListHead);
50 InitializeListHead (&Statement->NoSubmitListHead);
51 InitializeListHead (&Statement->WarningListHead);
52
53 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
54
55 Statement->Operand = ((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode;
56 Statement->OpCode = (EFI_IFR_OP_HEADER *)OpCodeData;
57 Statement->QuestionReferToBitField = FALSE;
58
59 StatementHdr = (EFI_IFR_STATEMENT_HEADER *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER));
60 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
61 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
62
63 ConditionalExprCount = GetConditionalExpressionCount (ExpressStatement);
64 if (ConditionalExprCount > 0) {
65 //
66 // Form is inside of suppressif
67 //
68
69 Statement->Expression = (FORM_EXPRESSION_LIST *)AllocatePool (
70 (UINTN)(sizeof (FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof (FORM_EXPRESSION *)))
71 );
72 ASSERT (Statement->Expression != NULL);
73 Statement->Expression->Count = (UINTN)ConditionalExprCount;
74 Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
75 CopyMem (Statement->Expression->Expression, GetConditionalExpressionList (ExpressStatement), (UINTN)(sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
76 }
77
78 //
79 // Insert this Statement into current Form
80 //
81 if (Form == NULL) {
82 InsertTailList (&FormSet->StatementListOSF, &Statement->Link);
83 } else {
84 InsertTailList (&Form->StatementListHead, &Statement->Link);
85 }
86
87 return Statement;
88}
89
102 IN UINT8 *OpCodeData,
103 IN OUT FORM_BROWSER_FORMSET *FormSet,
105 )
106{
107 FORM_BROWSER_STATEMENT *Statement;
108 EFI_IFR_QUESTION_HEADER *QuestionHdr;
109 LIST_ENTRY *Link;
110 FORMSET_STORAGE *Storage;
111 NAME_VALUE_NODE *NameValueNode;
112 BOOLEAN Find;
113
114 Statement = CreateStatement (OpCodeData, FormSet, Form);
115 if (Statement == NULL) {
116 return NULL;
117 }
118
119 QuestionHdr = (EFI_IFR_QUESTION_HEADER *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER));
120 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
121 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
122 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
123
124 Statement->QuestionFlags = QuestionHdr->Flags;
125
126 if (Statement->VarStoreId == 0) {
127 //
128 // VarStoreId of zero indicates no variable storage
129 //
130 return Statement;
131 }
132
133 //
134 // Find Storage for this Question
135 //
136 Link = GetFirstNode (&FormSet->StorageListHead);
137 while (!IsNull (&FormSet->StorageListHead, Link)) {
138 Storage = FORMSET_STORAGE_FROM_LINK (Link);
139
140 if (Storage->VarStoreId == Statement->VarStoreId) {
141 Statement->Storage = Storage->BrowserStorage;
142 break;
143 }
144
145 Link = GetNextNode (&FormSet->StorageListHead, Link);
146 }
147
148 ASSERT (Statement->Storage != NULL);
149
150 //
151 // Initialilze varname for Name/Value or EFI Variable
152 //
153 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
154 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE))
155 {
156 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
157 ASSERT (Statement->VariableName != NULL);
158
159 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
160 //
161 // Check whether old string node already exist.
162 //
163 Find = FALSE;
164 if (!IsListEmpty (&Statement->Storage->NameValueListHead)) {
165 Link = GetFirstNode (&Statement->Storage->NameValueListHead);
166 while (!IsNull (&Statement->Storage->NameValueListHead, Link)) {
167 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
168
169 if (StrCmp (Statement->VariableName, NameValueNode->Name) == 0) {
170 Find = TRUE;
171 break;
172 }
173
174 Link = GetNextNode (&Statement->Storage->NameValueListHead, Link);
175 }
176 }
177
178 if (!Find) {
179 //
180 // Insert to Name/Value varstore list
181 //
182 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
183 ASSERT (NameValueNode != NULL);
184 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
185 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
186 ASSERT (NameValueNode->Name != NULL);
187 NameValueNode->Value = AllocateZeroPool (0x10);
188 ASSERT (NameValueNode->Value != NULL);
189 NameValueNode->EditValue = AllocateZeroPool (0x10);
190 ASSERT (NameValueNode->EditValue != NULL);
191
192 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
193 }
194 }
195 }
196
197 return Statement;
198}
199
212 IN UINT8 *OpCode
213 )
214{
215 FORM_EXPRESSION *Expression;
216
217 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
218 ASSERT (Expression != NULL);
219 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
220 InitializeListHead (&Expression->OpCodeListHead);
221 Expression->OpCode = (EFI_IFR_OP_HEADER *)OpCode;
222
223 return Expression;
224}
225
237 IN FORM_BROWSER_FORMSET *FormSet,
238 IN OUT FORMSET_STORAGE *Storage
239 )
240{
241 CHAR16 *Name;
242
243 if ((Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER) ||
244 (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))
245 {
246 Name = Storage->BrowserStorage->Name;
247 } else {
248 Name = NULL;
249 }
250
251 Storage->ConfigHdr = HiiConstructConfigHdr (
252 &Storage->BrowserStorage->Guid,
253 Name,
254 FormSet->DriverHandle
255 );
256
257 if (Storage->ConfigHdr == NULL) {
258 return EFI_NOT_FOUND;
259 }
260
261 return EFI_SUCCESS;
262}
263
286 IN UINT8 StorageType,
287 IN EFI_GUID *StorageGuid,
288 IN CHAR16 *StorageName,
289 IN EFI_HII_HANDLE HiiHandle
290 )
291{
292 LIST_ENTRY *Link;
293 BROWSER_STORAGE *BrowserStorage;
294
295 Link = GetFirstNode (&gBrowserStorageList);
296 while (!IsNull (&gBrowserStorageList, Link)) {
297 BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);
298 Link = GetNextNode (&gBrowserStorageList, Link);
299
300 if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {
301 if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {
302 if (BrowserStorage->HiiHandle == HiiHandle) {
303 return BrowserStorage;
304 }
305
306 continue;
307 }
308
309 ASSERT (StorageName != NULL);
310 if (StrCmp (BrowserStorage->Name, StorageName) == 0) {
311 if ((StorageType == EFI_HII_VARSTORE_EFI_VARIABLE) || (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
312 return BrowserStorage;
313 } else if ((StorageType == EFI_HII_VARSTORE_BUFFER) && (BrowserStorage->HiiHandle == HiiHandle)) {
314 return BrowserStorage;
315 }
316 }
317 }
318 }
319
320 return NULL;
321}
322
331VOID
333 IN BROWSER_STORAGE *BrowserStorage,
334 IN UINT8 StorageType,
335 IN UINT8 *OpCodeData
336 )
337{
338 switch (StorageType) {
339 case EFI_HII_VARSTORE_BUFFER:
340 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE *)OpCodeData)->Guid, sizeof (EFI_GUID));
341 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE *)OpCodeData)->Size, sizeof (UINT16));
342
343 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);
344 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
345 break;
346
347 case EFI_HII_VARSTORE_EFI_VARIABLE:
348 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
349 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Guid, sizeof (EFI_GUID));
350 CopyMem (&BrowserStorage->Attributes, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Attributes, sizeof (UINT32));
351 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Size, sizeof (UINT16));
352
353 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
354 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);
355 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
356 }
357
358 break;
359
360 case EFI_HII_VARSTORE_NAME_VALUE:
361 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *)OpCodeData)->Guid, sizeof (EFI_GUID));
362
363 InitializeListHead (&BrowserStorage->NameValueListHead);
364 break;
365
366 default:
367 break;
368 }
369}
370
383 IN FORM_BROWSER_FORMSET *FormSet,
384 IN UINT8 StorageType,
385 IN UINT8 *OpCodeData
386 )
387{
388 FORMSET_STORAGE *Storage;
389 CHAR16 *UnicodeString;
390 UINT16 Index;
391 BROWSER_STORAGE *BrowserStorage;
392 EFI_GUID *StorageGuid;
393 CHAR8 *StorageName;
394
395 UnicodeString = NULL;
396 StorageName = NULL;
397 switch (StorageType) {
398 case EFI_HII_VARSTORE_BUFFER:
399 StorageGuid = (EFI_GUID *)(CHAR8 *)&((EFI_IFR_VARSTORE *)OpCodeData)->Guid;
400 StorageName = (CHAR8 *)((EFI_IFR_VARSTORE *)OpCodeData)->Name;
401 break;
402
403 case EFI_HII_VARSTORE_EFI_VARIABLE:
404 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
405 StorageGuid = (EFI_GUID *)(CHAR8 *)&((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Guid;
406 StorageName = (CHAR8 *)((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Name;
407 break;
408
409 default:
410 ASSERT (StorageType == EFI_HII_VARSTORE_NAME_VALUE);
411 StorageGuid = &((EFI_IFR_VARSTORE_NAME_VALUE *)OpCodeData)->Guid;
412 break;
413 }
414
415 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
416 ASSERT (StorageName != NULL);
417
418 UnicodeString = AllocateZeroPool (AsciiStrSize (StorageName) * 2);
419 ASSERT (UnicodeString != NULL);
420 for (Index = 0; StorageName[Index] != 0; Index++) {
421 UnicodeString[Index] = (CHAR16)StorageName[Index];
422 }
423 }
424
425 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
426 ASSERT (Storage != NULL);
427 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
428 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
429
430 BrowserStorage = FindStorageInList (StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);
431 if (BrowserStorage == NULL) {
432 BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));
433 ASSERT (BrowserStorage != NULL);
434
435 BrowserStorage->Signature = BROWSER_STORAGE_SIGNATURE;
436 InsertTailList (&gBrowserStorageList, &BrowserStorage->Link);
437
438 IntializeBrowserStorage (BrowserStorage, StorageType, OpCodeData);
439 BrowserStorage->Type = StorageType;
440 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
441 BrowserStorage->Name = UnicodeString;
442 }
443
444 BrowserStorage->HiiHandle = FormSet->HiiHandle;
445
446 BrowserStorage->Initialized = FALSE;
447 }
448
449 Storage->BrowserStorage = BrowserStorage;
450 InitializeConfigHdr (FormSet, Storage);
451 Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
452 Storage->SpareStrLen = 0;
453
454 return Storage;
455}
456
468 IN FORM_BROWSER_FORMSET *FormSet,
469 IN EFI_VARSTORE_ID VarStoreId
470 )
471{
472 FORMSET_STORAGE *FormsetStorage;
473 LIST_ENTRY *Link;
474 BOOLEAN Found;
475
476 Found = FALSE;
477 FormsetStorage = NULL;
478 //
479 // Find Formset Storage for this Question
480 //
481 Link = GetFirstNode (&FormSet->StorageListHead);
482 while (!IsNull (&FormSet->StorageListHead, Link)) {
483 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
484
485 if (FormsetStorage->VarStoreId == VarStoreId) {
486 Found = TRUE;
487 break;
488 }
489
490 Link = GetNextNode (&FormSet->StorageListHead, Link);
491 }
492
493 return Found ? FormsetStorage : NULL;
494}
495
511 IN BROWSER_STORAGE *Storage
512 )
513{
514 FORMSET_STORAGE *FormsetStorage;
515 LIST_ENTRY *Link;
516 LIST_ENTRY *FormsetLink;
517 FORM_BROWSER_FORMSET *FormSet;
518 BOOLEAN Found;
519
520 Found = FALSE;
521 FormsetStorage = NULL;
522
523 FormsetLink = GetFirstNode (&gBrowserFormSetList);
524 while (!IsNull (&gBrowserFormSetList, FormsetLink)) {
525 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink);
526 FormsetLink = GetNextNode (&gBrowserFormSetList, FormsetLink);
527
528 Link = GetFirstNode (&FormSet->StorageListHead);
529 while (!IsNull (&FormSet->StorageListHead, Link)) {
530 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
531 Link = GetNextNode (&FormSet->StorageListHead, Link);
532
533 if (FormsetStorage->BrowserStorage == Storage) {
534 Found = TRUE;
535 break;
536 }
537 }
538
539 if (Found) {
540 break;
541 }
542 }
543
544 return Found ? FormsetStorage : NULL;
545}
546
560 IN OUT FORM_BROWSER_FORMSET *FormSet,
561 IN OUT FORM_BROWSER_STATEMENT *Question,
563 )
564{
565 BROWSER_STORAGE *Storage;
566 FORMSET_STORAGE *FormsetStorage;
568 UINTN StringSize;
569 CHAR16 *NewStr;
570 CHAR16 RequestElement[30];
571 LIST_ENTRY *Link;
572 BOOLEAN Find;
573 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
574 UINTN MaxLen;
575
576 Storage = Question->Storage;
577 if (Storage == NULL) {
578 return EFI_INVALID_PARAMETER;
579 }
580
581 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
582 //
583 // <ConfigRequest> is unnecessary for EFI variable storage,
584 // GetVariable()/SetVariable() will be used to retrieve/save values
585 //
586 return EFI_SUCCESS;
587 }
588
589 //
590 // Prepare <RequestElement>
591 //
592 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ||
593 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))
594 {
596 RequestElement,
597 30 * sizeof (CHAR16),
598 L"&OFFSET=%04x&WIDTH=%04x",
599 Question->VarStoreInfo.VarOffset,
600 Question->StorageWidth
601 );
602 HiiToLower (RequestElement);
603 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
604 } else {
605 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
606 }
607
608 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
609 //
610 // Password with CALLBACK flag is stored in encoded format,
611 // so don't need to append it to <ConfigRequest>
612 //
613 return EFI_SUCCESS;
614 }
615
616 //
617 // Find Formset Storage for this Question
618 //
619 FormsetStorage = GetFstStgFromVarId (FormSet, Question->VarStoreId);
620 ASSERT (FormsetStorage != NULL);
621 StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);
622 MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;
623
624 //
625 // Append <RequestElement> to <ConfigRequest>
626 //
627 if (StrLen > FormsetStorage->SpareStrLen) {
628 //
629 // Old String buffer is not sufficient for RequestElement, allocate a new one
630 //
631 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
632 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
633 ASSERT (NewStr != NULL);
634 if (FormsetStorage->ConfigRequest != NULL) {
635 CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);
636 FreePool (FormsetStorage->ConfigRequest);
637 }
638
639 FormsetStorage->ConfigRequest = NewStr;
640 FormsetStorage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
641 }
642
643 StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);
644 FormsetStorage->ElementCount++;
645 FormsetStorage->SpareStrLen -= StrLen;
646
647 //
648 // Update the Config Request info saved in the form.
649 //
650 ConfigInfo = NULL;
651 Find = FALSE;
652 Link = GetFirstNode (&Form->ConfigRequestHead);
653 while (!IsNull (&Form->ConfigRequestHead, Link)) {
654 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
655
656 if ((ConfigInfo != NULL) && (ConfigInfo->Storage == FormsetStorage->BrowserStorage)) {
657 Find = TRUE;
658 break;
659 }
660
661 Link = GetNextNode (&Form->ConfigRequestHead, Link);
662 }
663
664 if (!Find) {
665 ConfigInfo = AllocateZeroPool (sizeof (FORM_BROWSER_CONFIG_REQUEST));
666 ASSERT (ConfigInfo != NULL);
667 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
668 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (FormsetStorage->ConfigHdr), FormsetStorage->ConfigHdr);
669 ASSERT (ConfigInfo->ConfigRequest != NULL);
670 ConfigInfo->SpareStrLen = 0;
671 ConfigInfo->Storage = FormsetStorage->BrowserStorage;
672 InsertTailList (&Form->ConfigRequestHead, &ConfigInfo->Link);
673 }
674
675 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
676 MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;
677
678 //
679 // Append <RequestElement> to <ConfigRequest>
680 //
681 if (StrLen > ConfigInfo->SpareStrLen) {
682 //
683 // Old String buffer is not sufficient for RequestElement, allocate a new one
684 //
685 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
686 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
687 ASSERT (NewStr != NULL);
688 if (ConfigInfo->ConfigRequest != NULL) {
689 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
690 FreePool (ConfigInfo->ConfigRequest);
691 }
692
693 ConfigInfo->ConfigRequest = NewStr;
694 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
695 }
696
697 StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);
698 ConfigInfo->ElementCount++;
699 ConfigInfo->SpareStrLen -= StrLen;
700 return EFI_SUCCESS;
701}
702
709VOID
711 IN FORM_EXPRESSION *Expression
712 )
713{
714 LIST_ENTRY *Link;
715 EXPRESSION_OPCODE *OpCode;
716 LIST_ENTRY *SubExpressionLink;
717 FORM_EXPRESSION *SubExpression;
718
719 while (!IsListEmpty (&Expression->OpCodeListHead)) {
720 Link = GetFirstNode (&Expression->OpCodeListHead);
721 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
722 RemoveEntryList (&OpCode->Link);
723
724 if (OpCode->ValueList != NULL) {
725 FreePool (OpCode->ValueList);
726 }
727
728 if (OpCode->ValueName != NULL) {
729 FreePool (OpCode->ValueName);
730 }
731
732 if (OpCode->MapExpressionList.ForwardLink != NULL) {
733 while (!IsListEmpty (&OpCode->MapExpressionList)) {
734 SubExpressionLink = GetFirstNode (&OpCode->MapExpressionList);
735 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
736 RemoveEntryList (&SubExpression->Link);
737 DestroyExpression (SubExpression);
738 }
739 }
740 }
741
742 //
743 // Free this Expression
744 //
745 FreePool (Expression);
746}
747
754VOID
756 IN FORMSET_STORAGE *Storage
757 )
758{
759 if (Storage == NULL) {
760 return;
761 }
762
763 if (Storage->ConfigRequest != NULL) {
764 FreePool (Storage->ConfigRequest);
765 }
766
767 FreePool (Storage);
768}
769
777VOID
779 IN FORM_BROWSER_FORMSET *FormSet,
780 IN OUT FORM_BROWSER_STATEMENT *Statement
781 )
782{
783 LIST_ENTRY *Link;
784 QUESTION_DEFAULT *Default;
785 QUESTION_OPTION *Option;
786 FORM_EXPRESSION *Expression;
787
788 //
789 // Free Default value List
790 //
791 while (!IsListEmpty (&Statement->DefaultListHead)) {
792 Link = GetFirstNode (&Statement->DefaultListHead);
793 Default = QUESTION_DEFAULT_FROM_LINK (Link);
794 RemoveEntryList (&Default->Link);
795
796 if (Default->Value.Buffer != NULL) {
797 FreePool (Default->Value.Buffer);
798 }
799
800 FreePool (Default);
801 }
802
803 //
804 // Free Options List
805 //
806 while (!IsListEmpty (&Statement->OptionListHead)) {
807 Link = GetFirstNode (&Statement->OptionListHead);
808 Option = QUESTION_OPTION_FROM_LINK (Link);
809 if (Option->SuppressExpression != NULL) {
810 FreePool (Option->SuppressExpression);
811 }
812
813 RemoveEntryList (&Option->Link);
814
815 FreePool (Option);
816 }
817
818 //
819 // Free Inconsistent List
820 //
821 while (!IsListEmpty (&Statement->InconsistentListHead)) {
822 Link = GetFirstNode (&Statement->InconsistentListHead);
823 Expression = FORM_EXPRESSION_FROM_LINK (Link);
824 RemoveEntryList (&Expression->Link);
825
826 DestroyExpression (Expression);
827 }
828
829 //
830 // Free NoSubmit List
831 //
832 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
833 Link = GetFirstNode (&Statement->NoSubmitListHead);
834 Expression = FORM_EXPRESSION_FROM_LINK (Link);
835 RemoveEntryList (&Expression->Link);
836
837 DestroyExpression (Expression);
838 }
839
840 //
841 // Free WarningIf List
842 //
843 while (!IsListEmpty (&Statement->WarningListHead)) {
844 Link = GetFirstNode (&Statement->WarningListHead);
845 Expression = FORM_EXPRESSION_FROM_LINK (Link);
846 RemoveEntryList (&Expression->Link);
847
848 DestroyExpression (Expression);
849 }
850
851 if (Statement->Expression != NULL) {
852 FreePool (Statement->Expression);
853 }
854
855 if (Statement->VariableName != NULL) {
856 FreePool (Statement->VariableName);
857 }
858
859 if (Statement->BlockName != NULL) {
860 FreePool (Statement->BlockName);
861 }
862
863 if (Statement->BufferValue != NULL) {
864 FreePool (Statement->BufferValue);
865 }
866
867 if ((Statement->Operand == EFI_IFR_STRING_OP) || (Statement->Operand == EFI_IFR_PASSWORD_OP)) {
868 DeleteString (Statement->HiiValue.Value.string, FormSet->HiiHandle);
869 }
870}
871
879VOID
881 IN FORM_BROWSER_FORMSET *FormSet,
883 )
884{
885 LIST_ENTRY *Link;
886 FORM_EXPRESSION *Expression;
887 FORM_BROWSER_STATEMENT *Statement;
888 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
889
890 //
891 // Free Form Expressions
892 //
893 while (!IsListEmpty (&Form->ExpressionListHead)) {
894 Link = GetFirstNode (&Form->ExpressionListHead);
895 Expression = FORM_EXPRESSION_FROM_LINK (Link);
896 RemoveEntryList (&Expression->Link);
897
898 DestroyExpression (Expression);
899 }
900
901 //
902 // Free Statements/Questions
903 //
904 while (!IsListEmpty (&Form->StatementListHead)) {
905 Link = GetFirstNode (&Form->StatementListHead);
906 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
907 RemoveEntryList (&Statement->Link);
908
909 DestroyStatement (FormSet, Statement);
910 }
911
912 //
913 // Free ConfigRequest string.
914 //
915 while (!IsListEmpty (&Form->ConfigRequestHead)) {
916 Link = GetFirstNode (&Form->ConfigRequestHead);
917 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
918 RemoveEntryList (&ConfigInfo->Link);
919
920 FreePool (ConfigInfo->ConfigRequest);
921 FreePool (ConfigInfo);
922 }
923
924 if (Form->SuppressExpression != NULL) {
925 FreePool (Form->SuppressExpression);
926 }
927
928 UiFreeMenuList (&Form->FormViewListHead);
929
930 //
931 // Free this Form
932 //
933 FreePool (Form);
934}
935
942VOID
945 )
946{
947 LIST_ENTRY *Link;
948 FORMSET_STORAGE *Storage;
949 FORMSET_DEFAULTSTORE *DefaultStore;
950 FORM_EXPRESSION *Expression;
951 FORM_BROWSER_FORM *Form;
952
953 if (FormSet->IfrBinaryData == NULL) {
954 //
955 // Uninitialized FormSet
956 //
957 FreePool (FormSet);
958 return;
959 }
960
961 //
962 // Free IFR binary buffer
963 //
964 FreePool (FormSet->IfrBinaryData);
965
966 //
967 // Free FormSet Storage
968 //
969 if (FormSet->StorageListHead.ForwardLink != NULL) {
970 while (!IsListEmpty (&FormSet->StorageListHead)) {
971 Link = GetFirstNode (&FormSet->StorageListHead);
972 Storage = FORMSET_STORAGE_FROM_LINK (Link);
973 RemoveEntryList (&Storage->Link);
974
975 DestroyStorage (Storage);
976 }
977 }
978
979 //
980 // Free FormSet Default Store
981 //
982 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
983 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
984 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
985 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
986 RemoveEntryList (&DefaultStore->Link);
987
988 FreePool (DefaultStore);
989 }
990 }
991
992 //
993 // Free Formset Expressions
994 //
995 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
996 Link = GetFirstNode (&FormSet->ExpressionListHead);
997 Expression = FORM_EXPRESSION_FROM_LINK (Link);
998 RemoveEntryList (&Expression->Link);
999
1000 DestroyExpression (Expression);
1001 }
1002
1003 //
1004 // Free Forms
1005 //
1006 if (FormSet->FormListHead.ForwardLink != NULL) {
1007 while (!IsListEmpty (&FormSet->FormListHead)) {
1008 Link = GetFirstNode (&FormSet->FormListHead);
1009 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
1010 RemoveEntryList (&Form->Link);
1011
1012 DestroyForm (FormSet, Form);
1013 }
1014 }
1015
1016 if (FormSet->StatementBuffer != NULL) {
1017 FreePool (FormSet->StatementBuffer);
1018 }
1019
1020 if (FormSet->ExpressionBuffer != NULL) {
1021 FreePool (FormSet->ExpressionBuffer);
1022 }
1023
1024 FreePool (FormSet);
1025}
1026
1036BOOLEAN
1038 IN UINT8 Operand
1039 )
1040{
1041 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
1042 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
1043 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
1044 (Operand == EFI_IFR_CATENATE_OP) ||
1045 (Operand == EFI_IFR_TO_LOWER_OP) ||
1046 (Operand == EFI_IFR_TO_UPPER_OP) ||
1047 (Operand == EFI_IFR_MAP_OP) ||
1048 (Operand == EFI_IFR_VERSION_OP) ||
1049 (Operand == EFI_IFR_SECURITY_OP) ||
1050 (Operand == EFI_IFR_MATCH2_OP))
1051 {
1052 return TRUE;
1053 } else {
1054 return FALSE;
1055 }
1056}
1057
1067BOOLEAN
1069 IN UINT8 Operand
1070 )
1071{
1072 if ((Operand == EFI_IFR_SUBTITLE_OP) ||
1073 (Operand == EFI_IFR_TEXT_OP) ||
1074 (Operand == EFI_IFR_RESET_BUTTON_OP) ||
1075 (Operand == EFI_IFR_REF_OP) ||
1076 (Operand == EFI_IFR_ACTION_OP) ||
1077 (Operand == EFI_IFR_NUMERIC_OP) ||
1078 (Operand == EFI_IFR_ORDERED_LIST_OP) ||
1079 (Operand == EFI_IFR_CHECKBOX_OP) ||
1080 (Operand == EFI_IFR_STRING_OP) ||
1081 (Operand == EFI_IFR_PASSWORD_OP) ||
1082 (Operand == EFI_IFR_DATE_OP) ||
1083 (Operand == EFI_IFR_TIME_OP) ||
1084 (Operand == EFI_IFR_GUID_OP) ||
1085 (Operand == EFI_IFR_ONE_OF_OP))
1086 {
1087 return TRUE;
1088 } else {
1089 return FALSE;
1090 }
1091}
1092
1102BOOLEAN
1104 IN UINT8 Operand
1105 )
1106{
1107 return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;
1108}
1109
1118VOID
1120 IN FORM_BROWSER_FORMSET *FormSet,
1121 OUT UINTN *NumberOfStatement,
1122 OUT UINTN *NumberOfExpression
1123 )
1124{
1125 UINTN StatementCount;
1126 UINTN ExpressionCount;
1127 UINT8 *OpCodeData;
1128 UINTN Offset;
1129 UINTN OpCodeLen;
1130
1131 Offset = 0;
1132 StatementCount = 0;
1133 ExpressionCount = 0;
1134
1135 while (Offset < FormSet->IfrBinaryLength) {
1136 OpCodeData = FormSet->IfrBinaryData + Offset;
1137 OpCodeLen = ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
1138 Offset += OpCodeLen;
1139
1140 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode)) {
1141 ExpressionCount++;
1142 } else {
1143 StatementCount++;
1144 }
1145 }
1146
1147 *NumberOfStatement = StatementCount;
1148 *NumberOfExpression = ExpressionCount;
1149}
1150
1162 IN FORM_BROWSER_FORMSET *FormSet
1163 )
1164{
1165 EFI_STATUS Status;
1166 FORM_BROWSER_FORM *CurrentForm;
1167 FORM_BROWSER_STATEMENT *CurrentStatement;
1168 FORM_BROWSER_STATEMENT *ParentStatement;
1169 EXPRESSION_OPCODE *ExpressionOpCode;
1170 FORM_EXPRESSION *CurrentExpression;
1171 UINT8 Operand;
1172 UINT8 Scope;
1173 UINTN OpCodeOffset;
1174 UINTN OpCodeLength;
1175 UINT8 *OpCodeData;
1176 UINT8 ScopeOpCode;
1177 FORMSET_STORAGE *Storage;
1178 FORMSET_DEFAULTSTORE *DefaultStore;
1179 QUESTION_DEFAULT *CurrentDefault;
1180 QUESTION_OPTION *CurrentOption;
1181 UINT8 Width;
1182 UINTN NumberOfStatement;
1183 UINTN NumberOfExpression;
1184 EFI_IMAGE_ID *ImageId;
1185 BOOLEAN SuppressForQuestion;
1186 BOOLEAN SuppressForOption;
1187 UINT16 DepthOfDisable;
1188 BOOLEAN OpCodeDisabled;
1189 BOOLEAN SingleOpCodeExpression;
1190 BOOLEAN InScopeDefault;
1191 EFI_HII_VALUE *Value;
1192 EFI_IFR_FORM_MAP_METHOD *MapMethod;
1193 UINT8 MapScopeDepth;
1194 LIST_ENTRY *Link;
1195 FORMSET_STORAGE *VarStorage;
1196 LIST_ENTRY *MapExpressionList;
1197 EFI_VARSTORE_ID TempVarstoreId;
1198 BOOLEAN InScopeDisable;
1199 INTN ConditionalExprCount;
1200 BOOLEAN InUnknownScope;
1201 UINT8 UnknownDepth;
1202 FORMSET_DEFAULTSTORE *PreDefaultStore;
1203 LIST_ENTRY *DefaultLink;
1204 BOOLEAN HaveInserted;
1205 UINT16 TotalBits;
1206 BOOLEAN QuestionReferBitField;
1207
1208 SuppressForQuestion = FALSE;
1209 SuppressForOption = FALSE;
1210 InScopeDisable = FALSE;
1211 DepthOfDisable = 0;
1212 OpCodeDisabled = FALSE;
1213 SingleOpCodeExpression = FALSE;
1214 InScopeDefault = FALSE;
1215 CurrentExpression = NULL;
1216 CurrentDefault = NULL;
1217 CurrentOption = NULL;
1218 ImageId = NULL;
1219 MapMethod = NULL;
1220 MapScopeDepth = 0;
1221 Link = NULL;
1222 VarStorage = NULL;
1223 MapExpressionList = NULL;
1224 TempVarstoreId = 0;
1225 ConditionalExprCount = 0;
1226 InUnknownScope = FALSE;
1227 UnknownDepth = 0;
1228 QuestionReferBitField = FALSE;
1229
1230 //
1231 // Get the number of Statements and Expressions
1232 //
1233 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
1234
1235 mStatementIndex = 0;
1236 mUsedQuestionId = 1;
1237 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
1238 if (FormSet->StatementBuffer == NULL) {
1239 return EFI_OUT_OF_RESOURCES;
1240 }
1241
1242 mExpressionOpCodeIndex = 0;
1243 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
1244 if (FormSet->ExpressionBuffer == NULL) {
1245 return EFI_OUT_OF_RESOURCES;
1246 }
1247
1248 InitializeListHead (&FormSet->StatementListOSF);
1249 InitializeListHead (&FormSet->StorageListHead);
1250 InitializeListHead (&FormSet->SaveFailStorageListHead);
1251 InitializeListHead (&FormSet->DefaultStoreListHead);
1252 InitializeListHead (&FormSet->FormListHead);
1253 InitializeListHead (&FormSet->ExpressionListHead);
1256
1257 CurrentForm = NULL;
1258 CurrentStatement = NULL;
1259 ParentStatement = NULL;
1260
1261 ResetScopeStack ();
1262
1263 OpCodeOffset = 0;
1264 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1265 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1266
1267 OpCodeLength = ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
1268 OpCodeOffset += OpCodeLength;
1269 Operand = ((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode;
1270 Scope = ((EFI_IFR_OP_HEADER *)OpCodeData)->Scope;
1271
1272 if (InUnknownScope) {
1273 if (Operand == EFI_IFR_END_OP) {
1274 UnknownDepth--;
1275
1276 if (UnknownDepth == 0) {
1277 InUnknownScope = FALSE;
1278 }
1279 } else {
1280 if (Scope != 0) {
1281 UnknownDepth++;
1282 }
1283 }
1284
1285 continue;
1286 }
1287
1288 if (IsUnKnownOpCode (Operand)) {
1289 if (Scope != 0) {
1290 InUnknownScope = TRUE;
1291 UnknownDepth++;
1292 }
1293
1294 continue;
1295 }
1296
1297 //
1298 // If scope bit set, push onto scope stack
1299 //
1300 if (Scope != 0) {
1301 PushScope (Operand);
1302 }
1303
1304 if (OpCodeDisabled) {
1305 //
1306 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1307 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1308 //
1309 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1310 DepthOfDisable++;
1311 } else if (Operand == EFI_IFR_END_OP) {
1312 Status = PopScope (&ScopeOpCode);
1313 if (EFI_ERROR (Status)) {
1314 return Status;
1315 }
1316
1317 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1318 if (DepthOfDisable == 0) {
1319 InScopeDisable = FALSE;
1320 OpCodeDisabled = FALSE;
1321 } else {
1322 DepthOfDisable--;
1323 }
1324 }
1325 }
1326
1327 continue;
1328 }
1329
1330 if (IsExpressionOpCode (Operand)) {
1331 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1332 mExpressionOpCodeIndex++;
1333
1334 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1335 ExpressionOpCode->Operand = Operand;
1336 Value = &ExpressionOpCode->Value;
1337
1338 switch (Operand) {
1339 case EFI_IFR_EQ_ID_VAL_OP:
1340 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *)OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1341
1342 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1343 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *)OpCodeData)->Value, sizeof (UINT16));
1344 break;
1345
1346 case EFI_IFR_EQ_ID_ID_OP:
1347 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *)OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1348 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *)OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1349 break;
1350
1351 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1352 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *)OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1353 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *)OpCodeData)->ListLength, sizeof (UINT16));
1354 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *)OpCodeData)->ValueList);
1355 break;
1356
1357 case EFI_IFR_TO_STRING_OP:
1358 case EFI_IFR_FIND_OP:
1359 ExpressionOpCode->Format = ((EFI_IFR_TO_STRING *)OpCodeData)->Format;
1360 break;
1361
1362 case EFI_IFR_STRING_REF1_OP:
1363 Value->Type = EFI_IFR_TYPE_STRING;
1364 CopyMem (&Value->Value.string, &((EFI_IFR_STRING_REF1 *)OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1365 break;
1366
1367 case EFI_IFR_RULE_REF_OP:
1368 ExpressionOpCode->RuleId = ((EFI_IFR_RULE_REF *)OpCodeData)->RuleId;
1369 break;
1370
1371 case EFI_IFR_SPAN_OP:
1372 ExpressionOpCode->Flags = ((EFI_IFR_SPAN *)OpCodeData)->Flags;
1373 break;
1374
1375 case EFI_IFR_THIS_OP:
1376 ASSERT (ParentStatement != NULL);
1377 ExpressionOpCode->QuestionId = ParentStatement->QuestionId;
1378 break;
1379
1380 case EFI_IFR_SECURITY_OP:
1381 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *)OpCodeData)->Permissions, sizeof (EFI_GUID));
1382 break;
1383
1384 case EFI_IFR_MATCH2_OP:
1385 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *)OpCodeData)->SyntaxType, sizeof (EFI_GUID));
1386 break;
1387
1388 case EFI_IFR_GET_OP:
1389 case EFI_IFR_SET_OP:
1390 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *)OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1391 if (TempVarstoreId != 0) {
1392 if (FormSet->StorageListHead.ForwardLink != NULL) {
1393 Link = GetFirstNode (&FormSet->StorageListHead);
1394 while (!IsNull (&FormSet->StorageListHead, Link)) {
1395 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1396 if (VarStorage->VarStoreId == ((EFI_IFR_GET *)OpCodeData)->VarStoreId) {
1397 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
1398 break;
1399 }
1400
1401 Link = GetNextNode (&FormSet->StorageListHead, Link);
1402 }
1403 }
1404
1405 if (ExpressionOpCode->VarStorage == NULL) {
1406 //
1407 // VarStorage is not found.
1408 //
1409 return EFI_INVALID_PARAMETER;
1410 }
1411 }
1412
1413 ExpressionOpCode->ValueType = ((EFI_IFR_GET *)OpCodeData)->VarStoreType;
1414 switch (ExpressionOpCode->ValueType) {
1415 case EFI_IFR_TYPE_BOOLEAN:
1416 case EFI_IFR_TYPE_NUM_SIZE_8:
1417 ExpressionOpCode->ValueWidth = 1;
1418 break;
1419
1420 case EFI_IFR_TYPE_NUM_SIZE_16:
1421 case EFI_IFR_TYPE_STRING:
1422 ExpressionOpCode->ValueWidth = 2;
1423 break;
1424
1425 case EFI_IFR_TYPE_NUM_SIZE_32:
1426 ExpressionOpCode->ValueWidth = 4;
1427 break;
1428
1429 case EFI_IFR_TYPE_NUM_SIZE_64:
1430 ExpressionOpCode->ValueWidth = 8;
1431 break;
1432
1433 case EFI_IFR_TYPE_DATE:
1434 ExpressionOpCode->ValueWidth = (UINT8)sizeof (EFI_IFR_DATE);
1435 break;
1436
1437 case EFI_IFR_TYPE_TIME:
1438 ExpressionOpCode->ValueWidth = (UINT8)sizeof (EFI_IFR_TIME);
1439 break;
1440
1441 case EFI_IFR_TYPE_REF:
1442 ExpressionOpCode->ValueWidth = (UINT8)sizeof (EFI_IFR_REF);
1443 break;
1444
1445 case EFI_IFR_TYPE_OTHER:
1446 case EFI_IFR_TYPE_UNDEFINED:
1447 case EFI_IFR_TYPE_ACTION:
1448 case EFI_IFR_TYPE_BUFFER:
1449 default:
1450 //
1451 // Invalid value type for Get/Set opcode.
1452 //
1453 return EFI_INVALID_PARAMETER;
1454 }
1455
1456 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *)OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1457 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *)OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1458 if ((ExpressionOpCode->VarStorage != NULL) &&
1459 ((ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
1460 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)))
1461 {
1462 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1463 if (ExpressionOpCode->ValueName == NULL) {
1464 //
1465 // String ID is invalid.
1466 //
1467 return EFI_INVALID_PARAMETER;
1468 }
1469 }
1470
1471 break;
1472
1473 case EFI_IFR_QUESTION_REF1_OP:
1474 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *)OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1475 break;
1476
1477 case EFI_IFR_QUESTION_REF3_OP:
1478 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1479 CopyMem (&ExpressionOpCode->DevicePath, &((EFI_IFR_QUESTION_REF3_2 *)OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1480
1481 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1482 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_QUESTION_REF3_3 *)OpCodeData)->Guid, sizeof (EFI_GUID));
1483 }
1484 }
1485
1486 break;
1487
1488 //
1489 // constant
1490 //
1491 case EFI_IFR_TRUE_OP:
1492 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1493 Value->Value.b = TRUE;
1494 break;
1495
1496 case EFI_IFR_FALSE_OP:
1497 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1498 Value->Value.b = FALSE;
1499 break;
1500
1501 case EFI_IFR_ONE_OP:
1502 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1503 Value->Value.u8 = 1;
1504 break;
1505
1506 case EFI_IFR_ZERO_OP:
1507 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1508 Value->Value.u8 = 0;
1509 break;
1510
1511 case EFI_IFR_ONES_OP:
1512 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1513 Value->Value.u64 = 0xffffffffffffffffULL;
1514 break;
1515
1516 case EFI_IFR_UINT8_OP:
1517 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1518 Value->Value.u8 = ((EFI_IFR_UINT8 *)OpCodeData)->Value;
1519 break;
1520
1521 case EFI_IFR_UINT16_OP:
1522 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1523 CopyMem (&Value->Value.u16, &((EFI_IFR_UINT16 *)OpCodeData)->Value, sizeof (UINT16));
1524 break;
1525
1526 case EFI_IFR_UINT32_OP:
1527 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1528 CopyMem (&Value->Value.u32, &((EFI_IFR_UINT32 *)OpCodeData)->Value, sizeof (UINT32));
1529 break;
1530
1531 case EFI_IFR_UINT64_OP:
1532 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1533 CopyMem (&Value->Value.u64, &((EFI_IFR_UINT64 *)OpCodeData)->Value, sizeof (UINT64));
1534 break;
1535
1536 case EFI_IFR_UNDEFINED_OP:
1537 Value->Type = EFI_IFR_TYPE_UNDEFINED;
1538 break;
1539
1540 case EFI_IFR_VERSION_OP:
1541 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1542 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1543 break;
1544
1545 default:
1546 break;
1547 }
1548
1549 //
1550 // Create sub expression nested in MAP opcode
1551 //
1552 if ((CurrentExpression == NULL) && (MapScopeDepth > 0)) {
1553 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
1554 ASSERT (MapExpressionList != NULL);
1555 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1556 if (Scope == 0) {
1557 SingleOpCodeExpression = TRUE;
1558 }
1559 }
1560
1561 ASSERT (CurrentExpression != NULL);
1562 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
1563 if (Operand == EFI_IFR_MAP_OP) {
1564 //
1565 // Store current Map Expression List.
1566 //
1567 if (MapExpressionList != NULL) {
1568 PushMapExpressionList (MapExpressionList);
1569 }
1570
1571 //
1572 // Initialize new Map Expression List.
1573 //
1574 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1575 InitializeListHead (MapExpressionList);
1576 //
1577 // Store current expression.
1578 //
1579 PushCurrentExpression (CurrentExpression);
1580 CurrentExpression = NULL;
1581 MapScopeDepth++;
1582 } else if (SingleOpCodeExpression) {
1583 //
1584 // There are two cases to indicate the end of an Expression:
1585 // for single OpCode expression: one Expression OpCode
1586 // for expression consists of more than one OpCode: EFI_IFR_END
1587 //
1588 SingleOpCodeExpression = FALSE;
1589
1590 if (InScopeDisable && (CurrentForm == NULL)) {
1591 //
1592 // This is DisableIf expression for Form, it should be a constant expression
1593 //
1594 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1595 if (EFI_ERROR (Status)) {
1596 return Status;
1597 }
1598
1599 OpCodeDisabled = IsTrue (&CurrentExpression->Result);
1600 }
1601
1602 CurrentExpression = NULL;
1603 }
1604
1605 continue;
1606 }
1607
1608 //
1609 // Parse the Opcode
1610 //
1611 switch (Operand) {
1612 case EFI_IFR_FORM_SET_OP:
1613 //
1614 // Check the formset GUID
1615 //
1616 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *)OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1617 return EFI_INVALID_PARAMETER;
1618 }
1619
1620 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *)OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1621 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *)OpCodeData)->Help, sizeof (EFI_STRING_ID));
1622 FormSet->OpCode = (EFI_IFR_OP_HEADER *)OpCodeData;// save the opcode address of formset
1623
1624 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1625 //
1626 // The formset OpCode contains ClassGuid
1627 //
1628 FormSet->NumberOfClassGuid = (UINT8)(((EFI_IFR_FORM_SET *)OpCodeData)->Flags & 0x3);
1629 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1630 }
1631
1632 break;
1633
1634 case EFI_IFR_FORM_OP:
1635 //
1636 // Create a new Form for this FormSet
1637 //
1638 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1639 ASSERT (CurrentForm != NULL);
1640 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1641 InitializeListHead (&CurrentForm->ExpressionListHead);
1642 InitializeListHead (&CurrentForm->StatementListHead);
1643 InitializeListHead (&CurrentForm->ConfigRequestHead);
1644 InitializeListHead (&CurrentForm->FormViewListHead);
1645
1646 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1647 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *)OpCodeData)->FormId, sizeof (UINT16));
1648 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *)OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1649
1650 ConditionalExprCount = GetConditionalExpressionCount (ExpressForm);
1651 if ( ConditionalExprCount > 0) {
1652 //
1653 // Form is inside of suppressif
1654 //
1655 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *)AllocatePool (
1656 (UINTN)(sizeof (FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof (FORM_EXPRESSION *)))
1657 );
1658 ASSERT (CurrentForm->SuppressExpression != NULL);
1659 CurrentForm->SuppressExpression->Count = (UINTN)ConditionalExprCount;
1660 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1661 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList (ExpressForm), (UINTN)(sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1662 }
1663
1664 if (Scope != 0) {
1665 //
1666 // Enter scope of a Form, suppressif will be used for Question or Option
1667 //
1668 SuppressForQuestion = TRUE;
1669 }
1670
1671 //
1672 // Insert into Form list of this FormSet
1673 //
1674 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1675 break;
1676
1677 case EFI_IFR_FORM_MAP_OP:
1678 //
1679 // Create a new Form for this FormSet
1680 //
1681 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1682 ASSERT (CurrentForm != NULL);
1683 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1684 InitializeListHead (&CurrentForm->ExpressionListHead);
1685 InitializeListHead (&CurrentForm->StatementListHead);
1686 InitializeListHead (&CurrentForm->ConfigRequestHead);
1687 InitializeListHead (&CurrentForm->FormViewListHead);
1688
1689 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *)OpCodeData)->FormId, sizeof (UINT16));
1690
1691 MapMethod = (EFI_IFR_FORM_MAP_METHOD *)(OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1692 //
1693 // FormMap Form must contain at least one Map Method.
1694 //
1695 if (((EFI_IFR_OP_HEADER *)OpCodeData)->Length < ((UINTN)(UINT8 *)(MapMethod + 1) - (UINTN)OpCodeData)) {
1696 return EFI_INVALID_PARAMETER;
1697 }
1698
1699 //
1700 // Try to find the standard form map method.
1701 //
1702 while (((UINTN)(UINT8 *)MapMethod - (UINTN)OpCodeData) < ((EFI_IFR_OP_HEADER *)OpCodeData)->Length) {
1703 if (CompareGuid ((EFI_GUID *)(VOID *)&MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1704 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1705 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1706 break;
1707 }
1708
1709 MapMethod++;
1710 }
1711
1712 //
1713 // If the standard form map method is not found, the first map method title will be used.
1714 //
1715 if (CurrentForm->FormTitle == 0) {
1716 MapMethod = (EFI_IFR_FORM_MAP_METHOD *)(OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1717 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1718 }
1719
1720 ConditionalExprCount = GetConditionalExpressionCount (ExpressForm);
1721 if ( ConditionalExprCount > 0) {
1722 //
1723 // Form is inside of suppressif
1724 //
1725 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *)AllocatePool (
1726 (UINTN)(sizeof (FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof (FORM_EXPRESSION *)))
1727 );
1728 ASSERT (CurrentForm->SuppressExpression != NULL);
1729 CurrentForm->SuppressExpression->Count = (UINTN)ConditionalExprCount;
1730 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1731 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList (ExpressForm), (UINTN)(sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1732 }
1733
1734 if (Scope != 0) {
1735 //
1736 // Enter scope of a Form, suppressif will be used for Question or Option
1737 //
1738 SuppressForQuestion = TRUE;
1739 }
1740
1741 //
1742 // Insert into Form list of this FormSet
1743 //
1744 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1745 break;
1746
1747 //
1748 // Storage
1749 //
1750 case EFI_IFR_VARSTORE_OP:
1751 //
1752 // Create a buffer Storage for this FormSet
1753 //
1754 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
1755 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *)OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1756 break;
1757
1758 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1759 //
1760 // Create a name/value Storage for this FormSet
1761 //
1762 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
1763 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *)OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1764 break;
1765
1766 case EFI_IFR_VARSTORE_EFI_OP:
1767 //
1768 // Create a EFI variable Storage for this FormSet
1769 //
1770 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
1771 //
1772 // Create efi varstore with format follow UEFI spec before 2.3.1.
1773 //
1774 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
1775 } else {
1776 //
1777 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1778 //
1779 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
1780 }
1781
1782 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1783 break;
1784
1785 //
1786 // DefaultStore
1787 //
1788 case EFI_IFR_DEFAULTSTORE_OP:
1789 HaveInserted = FALSE;
1790 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1791 ASSERT (DefaultStore != NULL);
1792 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1793
1794 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *)OpCodeData)->DefaultId, sizeof (UINT16));
1795 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *)OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1796 //
1797 // Insert it to the DefaultStore list of this Formset with ascending order.
1798 //
1799 if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
1800 DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);
1801 while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {
1802 PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink);
1803 DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);
1804 if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {
1805 InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);
1806 HaveInserted = TRUE;
1807 break;
1808 }
1809 }
1810 }
1811
1812 if (!HaveInserted) {
1813 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1814 }
1815
1816 break;
1817
1818 //
1819 // Statements
1820 //
1821 case EFI_IFR_SUBTITLE_OP:
1822 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1823 ASSERT (CurrentStatement != NULL);
1824
1825 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *)OpCodeData)->Flags;
1826 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1827 break;
1828
1829 case EFI_IFR_TEXT_OP:
1830 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1831 ASSERT (CurrentStatement != NULL);
1832 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1833 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *)OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1834 break;
1835
1836 case EFI_IFR_RESET_BUTTON_OP:
1837 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1838 ASSERT (CurrentStatement != NULL);
1839 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1840 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *)OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1841 break;
1842
1843 //
1844 // Questions
1845 //
1846 case EFI_IFR_ACTION_OP:
1847 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1848 ASSERT (CurrentStatement != NULL);
1849 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
1850
1851 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1852 //
1853 // No QuestionConfig present, so no configuration string will be processed
1854 //
1855 CurrentStatement->QuestionConfig = 0;
1856 } else {
1857 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *)OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1858 }
1859
1860 break;
1861
1862 case EFI_IFR_REF_OP:
1863 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1864 ASSERT (CurrentStatement != NULL);
1865 Value = &CurrentStatement->HiiValue;
1866 Value->Type = EFI_IFR_TYPE_REF;
1867 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1868 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *)OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1869
1870 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1871 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *)OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1872
1873 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1874 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *)OpCodeData)->FormSetId, sizeof (EFI_GUID));
1875
1876 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1877 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *)OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1878 }
1879 }
1880 }
1881 }
1882
1883 CurrentStatement->StorageWidth = (UINT16)sizeof (EFI_HII_REF);
1884 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1885 break;
1886
1887 case EFI_IFR_ONE_OF_OP:
1888 case EFI_IFR_NUMERIC_OP:
1889 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1890 ASSERT (CurrentStatement != NULL);
1891
1892 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *)OpCodeData)->Flags;
1893 Value = &CurrentStatement->HiiValue;
1894
1895 if (QuestionReferBitField) {
1896 //
1897 // Get the bit var store info (bit/byte offset, bit/byte offset)
1898 //
1899 CurrentStatement->QuestionReferToBitField = TRUE;
1900 CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
1901 CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;
1902 CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;
1903 TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;
1904 CurrentStatement->StorageWidth = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
1905
1906 //
1907 // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)
1908 //
1909 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.MinValue;
1910 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.MaxValue;
1911 CurrentStatement->Step = ((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.Step;
1912
1913 //
1914 // Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,
1915 // in order to make Browser handle these question with bit varstore correctly.
1916 //
1917 ((EFI_IFR_NUMERIC *)OpCodeData)->Flags &= EDKII_IFR_DISPLAY_BIT;
1918 ((EFI_IFR_NUMERIC *)OpCodeData)->Flags >>= 2;
1919 switch (CurrentStatement->StorageWidth) {
1920 case 1:
1921 ((EFI_IFR_NUMERIC *)OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;
1922 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u8.MinValue = (UINT8)CurrentStatement->Minimum;
1923 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u8.MaxValue = (UINT8)CurrentStatement->Maximum;
1924 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u8.Step = (UINT8)CurrentStatement->Step;
1925 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1926 break;
1927 case 2:
1928 ((EFI_IFR_NUMERIC *)OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;
1929 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u16.MinValue = (UINT16)CurrentStatement->Minimum;
1930 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u16.MaxValue = (UINT16)CurrentStatement->Maximum;
1931 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u16.Step = (UINT16)CurrentStatement->Step;
1932 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1933 break;
1934 case 3:
1935 case 4:
1936 ((EFI_IFR_NUMERIC *)OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;
1937 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.MinValue = (UINT32)CurrentStatement->Minimum;
1938 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.MaxValue = (UINT32)CurrentStatement->Maximum;
1939 ((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.Step = (UINT32)CurrentStatement->Step;
1940 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1941 break;
1942 default:
1943 break;
1944 }
1945 } else {
1946 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1947 case EFI_IFR_NUMERIC_SIZE_1:
1948 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *)OpCodeData)->data.u8.MinValue;
1949 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *)OpCodeData)->data.u8.MaxValue;
1950 CurrentStatement->Step = ((EFI_IFR_NUMERIC *)OpCodeData)->data.u8.Step;
1951 CurrentStatement->StorageWidth = (UINT16)sizeof (UINT8);
1952 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1953 break;
1954
1955 case EFI_IFR_NUMERIC_SIZE_2:
1956 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1957 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1958 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u16.Step, sizeof (UINT16));
1959 CurrentStatement->StorageWidth = (UINT16)sizeof (UINT16);
1960 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1961 break;
1962
1963 case EFI_IFR_NUMERIC_SIZE_4:
1964 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1965 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1966 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u32.Step, sizeof (UINT32));
1967 CurrentStatement->StorageWidth = (UINT16)sizeof (UINT32);
1968 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1969 break;
1970
1971 case EFI_IFR_NUMERIC_SIZE_8:
1972 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1973 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1974 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *)OpCodeData)->data.u64.Step, sizeof (UINT64));
1975 CurrentStatement->StorageWidth = (UINT16)sizeof (UINT64);
1976 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1977 break;
1978
1979 default:
1980 break;
1981 }
1982 }
1983
1984 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1985
1986 if ((Operand == EFI_IFR_ONE_OF_OP) && (Scope != 0)) {
1987 SuppressForOption = TRUE;
1988 }
1989
1990 break;
1991
1992 case EFI_IFR_ORDERED_LIST_OP:
1993 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1994 ASSERT (CurrentStatement != NULL);
1995
1996 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *)OpCodeData)->Flags;
1997 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *)OpCodeData)->MaxContainers;
1998
1999 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
2000 CurrentStatement->BufferValue = NULL;
2001
2002 if (Scope != 0) {
2003 SuppressForOption = TRUE;
2004 }
2005
2006 break;
2007
2008 case EFI_IFR_CHECKBOX_OP:
2009 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2010 ASSERT (CurrentStatement != NULL);
2011
2012 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *)OpCodeData)->Flags;
2013 CurrentStatement->StorageWidth = (UINT16)sizeof (BOOLEAN);
2014 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
2015
2016 if (QuestionReferBitField) {
2017 //
2018 // Get the bit var store info (bit/byte offset, bit/byte offset)
2019 //
2020 CurrentStatement->QuestionReferToBitField = TRUE;
2021 CurrentStatement->BitStorageWidth = 1;
2022 CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;
2023 CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;
2024 TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;
2025 CurrentStatement->StorageWidth = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
2026 }
2027
2028 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2029
2030 break;
2031
2032 case EFI_IFR_STRING_OP:
2033 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2034 ASSERT (CurrentStatement != NULL);
2035 //
2036 // MinSize is the minimum number of characters that can be accepted for this opcode,
2037 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2038 // The characters are stored as Unicode, so the storage width should multiply 2.
2039 //
2040 CurrentStatement->Minimum = ((EFI_IFR_STRING *)OpCodeData)->MinSize;
2041 CurrentStatement->Maximum = ((EFI_IFR_STRING *)OpCodeData)->MaxSize;
2042 CurrentStatement->StorageWidth = (UINT16)((UINTN)CurrentStatement->Maximum * sizeof (CHAR16));
2043 CurrentStatement->Flags = ((EFI_IFR_STRING *)OpCodeData)->Flags;
2044
2045 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
2046 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
2047 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16 *)CurrentStatement->BufferValue, FormSet->HiiHandle);
2048
2049 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2050 break;
2051
2052 case EFI_IFR_PASSWORD_OP:
2053 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2054 ASSERT (CurrentStatement != NULL);
2055 //
2056 // MinSize is the minimum number of characters that can be accepted for this opcode,
2057 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2058 // The characters are stored as Unicode, so the storage width should multiply 2.
2059 //
2060 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *)OpCodeData)->MinSize, sizeof (UINT16));
2061 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *)OpCodeData)->MaxSize, sizeof (UINT16));
2062 CurrentStatement->StorageWidth = (UINT16)((UINTN)CurrentStatement->Maximum * sizeof (CHAR16));
2063
2064 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
2065 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
2066 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16 *)CurrentStatement->BufferValue, FormSet->HiiHandle);
2067
2068 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2069 break;
2070
2071 case EFI_IFR_DATE_OP:
2072 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2073 ASSERT (CurrentStatement != NULL);
2074
2075 CurrentStatement->Flags = ((EFI_IFR_DATE *)OpCodeData)->Flags;
2076 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
2077
2078 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
2079 CurrentStatement->StorageWidth = (UINT16)sizeof (EFI_HII_DATE);
2080
2081 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2082 } else {
2083 //
2084 // Don't assign storage for RTC type of date/time
2085 //
2086 CurrentStatement->Storage = NULL;
2087 CurrentStatement->StorageWidth = 0;
2088 }
2089
2090 break;
2091
2092 case EFI_IFR_TIME_OP:
2093 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2094 ASSERT (CurrentStatement != NULL);
2095
2096 CurrentStatement->Flags = ((EFI_IFR_TIME *)OpCodeData)->Flags;
2097 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
2098
2099 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
2100 CurrentStatement->StorageWidth = (UINT16)sizeof (EFI_HII_TIME);
2101
2102 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2103 } else {
2104 //
2105 // Don't assign storage for RTC type of date/time
2106 //
2107 CurrentStatement->Storage = NULL;
2108 CurrentStatement->StorageWidth = 0;
2109 }
2110
2111 break;
2112
2113 //
2114 // Default
2115 //
2116 case EFI_IFR_DEFAULT_OP:
2117 //
2118 // EFI_IFR_DEFAULT appear in scope of a Question,
2119 // It creates a default value for the current question.
2120 // A Question may have more than one Default value which have different default types.
2121 //
2122 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
2123 ASSERT (CurrentDefault != NULL);
2124 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
2125
2126 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *)OpCodeData)->Type;
2127 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *)OpCodeData)->DefaultId, sizeof (UINT16));
2128 if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {
2129 CurrentDefault->Value.BufferLen = (UINT16)(OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
2130 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *)OpCodeData)->Value);
2131 ASSERT (CurrentDefault->Value.Buffer != NULL);
2132 } else {
2133 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *)OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
2134 ExtendValueToU64 (&CurrentDefault->Value);
2135 }
2136
2137 //
2138 // Insert to Default Value list of current Question
2139 //
2140 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
2141
2142 if (Scope != 0) {
2143 InScopeDefault = TRUE;
2144 }
2145
2146 break;
2147
2148 //
2149 // Option
2150 //
2151 case EFI_IFR_ONE_OF_OPTION_OP:
2152 ASSERT (ParentStatement != NULL);
2153 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && ((((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {
2154 //
2155 // It's keep the default value for ordered list opcode.
2156 //
2157 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
2158 ASSERT (CurrentDefault != NULL);
2159 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
2160
2161 CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;
2162 if ((((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
2163 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
2164 } else {
2165 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2166 }
2167
2168 CurrentDefault->Value.BufferLen = (UINT16)(OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
2169 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Value);
2170 ASSERT (CurrentDefault->Value.Buffer != NULL);
2171
2172 //
2173 // Insert to Default Value list of current Question
2174 //
2175 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
2176 break;
2177 }
2178
2179 //
2180 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
2181 // It create a selection for use in current Question.
2182 //
2183 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
2184 ASSERT (CurrentOption != NULL);
2185 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
2186 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *)OpCodeData;
2187
2188 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Flags;
2189 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Type;
2190 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Option, sizeof (EFI_STRING_ID));
2191 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *)OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
2192 ExtendValueToU64 (&CurrentOption->Value);
2193
2194 ConditionalExprCount = GetConditionalExpressionCount (ExpressOption);
2195 if ( ConditionalExprCount > 0) {
2196 //
2197 // Form is inside of suppressif
2198 //
2199 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *)AllocatePool (
2200 (UINTN)(sizeof (FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof (FORM_EXPRESSION *)))
2201 );
2202 ASSERT (CurrentOption->SuppressExpression != NULL);
2203 CurrentOption->SuppressExpression->Count = (UINTN)ConditionalExprCount;
2204 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
2205 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList (ExpressOption), (UINTN)(sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
2206 }
2207
2208 //
2209 // Insert to Option list of current Question
2210 //
2211 InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);
2212 //
2213 // Now we know the Storage width of nested Ordered List
2214 //
2215 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {
2216 Width = 1;
2217 switch (CurrentOption->Value.Type) {
2218 case EFI_IFR_TYPE_NUM_SIZE_8:
2219 Width = 1;
2220 break;
2221
2222 case EFI_IFR_TYPE_NUM_SIZE_16:
2223 Width = 2;
2224 break;
2225
2226 case EFI_IFR_TYPE_NUM_SIZE_32:
2227 Width = 4;
2228 break;
2229
2230 case EFI_IFR_TYPE_NUM_SIZE_64:
2231 Width = 8;
2232 break;
2233
2234 default:
2235 //
2236 // Invalid type for Ordered List
2237 //
2238 break;
2239 }
2240
2241 ParentStatement->StorageWidth = (UINT16)(ParentStatement->MaxContainers * Width);
2242 ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);
2243 ParentStatement->ValueType = CurrentOption->Value.Type;
2244 if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
2245 ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;
2246 ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;
2247 }
2248
2249 InitializeRequestElement (FormSet, ParentStatement, CurrentForm);
2250 }
2251
2252 break;
2253
2254 //
2255 // Conditional
2256 //
2257 case EFI_IFR_NO_SUBMIT_IF_OP:
2258 case EFI_IFR_INCONSISTENT_IF_OP:
2259 //
2260 // Create an Expression node
2261 //
2262 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2263 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *)OpCodeData)->Error, sizeof (EFI_STRING_ID));
2264
2265 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
2266 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
2267 InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);
2268 } else {
2269 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
2270 InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);
2271 }
2272
2273 //
2274 // Take a look at next OpCode to see whether current expression consists
2275 // of single OpCode
2276 //
2277 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2278 SingleOpCodeExpression = TRUE;
2279 }
2280
2281 break;
2282
2283 case EFI_IFR_WARNING_IF_OP:
2284 //
2285 // Create an Expression node
2286 //
2287 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2288 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *)OpCodeData)->Warning, sizeof (EFI_STRING_ID));
2289 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *)OpCodeData)->TimeOut;
2290 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;
2291 InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);
2292
2293 //
2294 // Take a look at next OpCode to see whether current expression consists
2295 // of single OpCode
2296 //
2297 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2298 SingleOpCodeExpression = TRUE;
2299 }
2300
2301 break;
2302
2303 case EFI_IFR_SUPPRESS_IF_OP:
2304 //
2305 // Question and Option will appear in scope of this OpCode
2306 //
2307 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2308 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
2309
2310 if (CurrentForm == NULL) {
2311 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
2312 } else {
2313 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2314 }
2315
2316 if (SuppressForOption) {
2317 PushConditionalExpression (CurrentExpression, ExpressOption);
2318 } else if (SuppressForQuestion) {
2319 PushConditionalExpression (CurrentExpression, ExpressStatement);
2320 } else {
2321 PushConditionalExpression (CurrentExpression, ExpressForm);
2322 }
2323
2324 //
2325 // Take a look at next OpCode to see whether current expression consists
2326 // of single OpCode
2327 //
2328 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2329 SingleOpCodeExpression = TRUE;
2330 }
2331
2332 break;
2333
2334 case EFI_IFR_GRAY_OUT_IF_OP:
2335 //
2336 // Questions will appear in scope of this OpCode
2337 //
2338 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2339 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
2340 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2341 PushConditionalExpression (CurrentExpression, ExpressStatement);
2342
2343 //
2344 // Take a look at next OpCode to see whether current expression consists
2345 // of single OpCode
2346 //
2347 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2348 SingleOpCodeExpression = TRUE;
2349 }
2350
2351 break;
2352
2353 case EFI_IFR_DISABLE_IF_OP:
2354 //
2355 // The DisableIf expression should only rely on constant, so it could be
2356 // evaluated at initialization and it will not be queued
2357 //
2358 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
2359 ASSERT (CurrentExpression != NULL);
2360 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
2361 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
2362 InitializeListHead (&CurrentExpression->OpCodeListHead);
2363
2364 if (CurrentForm != NULL) {
2365 //
2366 // This is DisableIf for Question, enqueue it to Form expression list
2367 //
2368 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2369 PushConditionalExpression (CurrentExpression, ExpressStatement);
2370 }
2371
2372 OpCodeDisabled = FALSE;
2373 InScopeDisable = TRUE;
2374 //
2375 // Take a look at next OpCode to see whether current expression consists
2376 // of single OpCode
2377 //
2378 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2379 SingleOpCodeExpression = TRUE;
2380 }
2381
2382 break;
2383
2384 //
2385 // Expression
2386 //
2387 case EFI_IFR_VALUE_OP:
2388 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2389 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
2390 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2391
2392 if (InScopeDefault) {
2393 //
2394 // Used for default (EFI_IFR_DEFAULT)
2395 //
2396 CurrentDefault->ValueExpression = CurrentExpression;
2397 } else {
2398 //
2399 // If used for a question, then the question will be read-only
2400 //
2401 //
2402 // Make sure CurrentStatement is not NULL.
2403 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2404 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2405 //
2406 ASSERT (ParentStatement != NULL);
2407 ParentStatement->ValueExpression = CurrentExpression;
2408 }
2409
2410 //
2411 // Take a look at next OpCode to see whether current expression consists
2412 // of single OpCode
2413 //
2414 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2415 SingleOpCodeExpression = TRUE;
2416 }
2417
2418 break;
2419
2420 case EFI_IFR_RULE_OP:
2421 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2422 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
2423
2424 CurrentExpression->RuleId = ((EFI_IFR_RULE *)OpCodeData)->RuleId;
2425 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2426
2427 //
2428 // Take a look at next OpCode to see whether current expression consists
2429 // of single OpCode
2430 //
2431 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2432 SingleOpCodeExpression = TRUE;
2433 }
2434
2435 break;
2436
2437 case EFI_IFR_READ_OP:
2438 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2439 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
2440 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2441
2442 //
2443 // Make sure CurrentStatement is not NULL.
2444 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2445 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2446 //
2447 ASSERT (ParentStatement != NULL);
2448 ParentStatement->ReadExpression = CurrentExpression;
2449
2450 //
2451 // Take a look at next OpCode to see whether current expression consists
2452 // of single OpCode
2453 //
2454 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2455 SingleOpCodeExpression = TRUE;
2456 }
2457
2458 break;
2459
2460 case EFI_IFR_WRITE_OP:
2461 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2462 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2463 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2464
2465 //
2466 // Make sure CurrentStatement is not NULL.
2467 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2468 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2469 //
2470 ASSERT (ParentStatement != NULL);
2471 ParentStatement->WriteExpression = CurrentExpression;
2472
2473 //
2474 // Take a look at next OpCode to see whether current expression consists
2475 // of single OpCode
2476 //
2477 if (((EFI_IFR_OP_HEADER *)(OpCodeData + OpCodeLength))->Scope == 0) {
2478 SingleOpCodeExpression = TRUE;
2479 }
2480
2481 break;
2482
2483 //
2484 // Image
2485 //
2486 case EFI_IFR_IMAGE_OP:
2487 //
2488 // Get ScopeOpcode from top of stack
2489 //
2490 PopScope (&ScopeOpCode);
2491 PushScope (ScopeOpCode);
2492
2493 switch (ScopeOpCode) {
2494 case EFI_IFR_FORM_SET_OP:
2495 ImageId = &FormSet->ImageId;
2496 break;
2497
2498 case EFI_IFR_FORM_OP:
2499 case EFI_IFR_FORM_MAP_OP:
2500 ASSERT (CurrentForm != NULL);
2501 ImageId = &CurrentForm->ImageId;
2502 break;
2503
2504 case EFI_IFR_ONE_OF_OPTION_OP:
2505 ASSERT (CurrentOption != NULL);
2506 ImageId = &CurrentOption->ImageId;
2507 break;
2508
2509 default:
2510 //
2511 // Make sure CurrentStatement is not NULL.
2512 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2513 // file is wrongly generated by tools such as VFR Compiler.
2514 //
2515 ASSERT (ParentStatement != NULL);
2516 ImageId = &ParentStatement->ImageId;
2517 break;
2518 }
2519
2520 ASSERT (ImageId != NULL);
2521 CopyMem (ImageId, &((EFI_IFR_IMAGE *)OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2522 break;
2523
2524 //
2525 // Refresh
2526 //
2527 case EFI_IFR_REFRESH_OP:
2528 ASSERT (ParentStatement != NULL);
2529 ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *)OpCodeData)->RefreshInterval;
2530 break;
2531
2532 //
2533 // Refresh guid.
2534 //
2535 case EFI_IFR_REFRESH_ID_OP:
2536 //
2537 // Get ScopeOpcode from top of stack
2538 //
2539 PopScope (&ScopeOpCode);
2540 PushScope (ScopeOpCode);
2541
2542 switch (ScopeOpCode) {
2543 case EFI_IFR_FORM_OP:
2544 case EFI_IFR_FORM_MAP_OP:
2545 ASSERT (CurrentForm != NULL);
2546 CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *)OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2547 break;
2548
2549 default:
2550 ASSERT (ParentStatement != NULL);
2551 CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *)OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2552 break;
2553 }
2554
2555 break;
2556
2557 //
2558 // Modal tag
2559 //
2560 case EFI_IFR_MODAL_TAG_OP:
2561 ASSERT (CurrentForm != NULL);
2562 CurrentForm->ModalForm = TRUE;
2563 break;
2564
2565 //
2566 // Lock tag, used by form and statement.
2567 //
2568 case EFI_IFR_LOCKED_OP:
2569 //
2570 // Get ScopeOpcode from top of stack
2571 //
2572 PopScope (&ScopeOpCode);
2573 PushScope (ScopeOpCode);
2574 switch (ScopeOpCode) {
2575 case EFI_IFR_FORM_OP:
2576 case EFI_IFR_FORM_MAP_OP:
2577 ASSERT (CurrentForm != NULL);
2578 CurrentForm->Locked = TRUE;
2579 break;
2580
2581 default:
2582 ASSERT (ParentStatement != NULL);
2583 ParentStatement->Locked = TRUE;
2584 }
2585
2586 break;
2587
2588 //
2589 // Vendor specific
2590 //
2591 case EFI_IFR_GUID_OP:
2592 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
2593 if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
2594 Scope = 0;
2595 QuestionReferBitField = TRUE;
2596 }
2597
2598 break;
2599
2600 //
2601 // Scope End
2602 //
2603 case EFI_IFR_END_OP:
2604 QuestionReferBitField = FALSE;
2605 Status = PopScope (&ScopeOpCode);
2606 if (EFI_ERROR (Status)) {
2607 ResetScopeStack ();
2608 return Status;
2609 }
2610
2611 //
2612 // Parent statement end tag found, update ParentStatement info.
2613 //
2614 if (IsStatementOpCode (ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {
2615 ParentStatement = ParentStatement->ParentStatement;
2616 }
2617
2618 switch (ScopeOpCode) {
2619 case EFI_IFR_FORM_SET_OP:
2620 //
2621 // End of FormSet, update FormSet IFR binary length
2622 // to stop parsing substantial OpCodes
2623 //
2624 FormSet->IfrBinaryLength = OpCodeOffset;
2625 break;
2626
2627 case EFI_IFR_FORM_OP:
2628 case EFI_IFR_FORM_MAP_OP:
2629 //
2630 // End of Form
2631 //
2632 CurrentForm = NULL;
2633 SuppressForQuestion = FALSE;
2634 break;
2635
2636 case EFI_IFR_ONE_OF_OPTION_OP:
2637 //
2638 // End of Option
2639 //
2640 CurrentOption = NULL;
2641 break;
2642
2643 case EFI_IFR_NO_SUBMIT_IF_OP:
2644 case EFI_IFR_INCONSISTENT_IF_OP:
2645 case EFI_IFR_WARNING_IF_OP:
2646 //
2647 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2648 //
2649 break;
2650
2651 case EFI_IFR_SUPPRESS_IF_OP:
2652 if (SuppressForOption) {
2653 PopConditionalExpression (ExpressOption);
2654 } else if (SuppressForQuestion) {
2655 PopConditionalExpression (ExpressStatement);
2656 } else {
2657 PopConditionalExpression (ExpressForm);
2658 }
2659
2660 break;
2661
2662 case EFI_IFR_GRAY_OUT_IF_OP:
2663 PopConditionalExpression (ExpressStatement);
2664 break;
2665
2666 case EFI_IFR_DISABLE_IF_OP:
2667 if (CurrentForm != NULL) {
2668 PopConditionalExpression (ExpressStatement);
2669 }
2670
2671 InScopeDisable = FALSE;
2672 OpCodeDisabled = FALSE;
2673 break;
2674
2675 case EFI_IFR_ONE_OF_OP:
2676 case EFI_IFR_ORDERED_LIST_OP:
2677 SuppressForOption = FALSE;
2678 break;
2679
2680 case EFI_IFR_DEFAULT_OP:
2681 InScopeDefault = FALSE;
2682 break;
2683
2684 case EFI_IFR_MAP_OP:
2685 //
2686 // Get current Map Expression List.
2687 //
2688 Status = PopMapExpressionList ((VOID **)&MapExpressionList);
2689 if (Status == EFI_ACCESS_DENIED) {
2690 MapExpressionList = NULL;
2691 }
2692
2693 //
2694 // Get current expression.
2695 //
2696 Status = PopCurrentExpression ((VOID **)&CurrentExpression);
2697 ASSERT_EFI_ERROR (Status);
2698 ASSERT (MapScopeDepth > 0);
2699 MapScopeDepth--;
2700 break;
2701
2702 default:
2703 if (IsExpressionOpCode (ScopeOpCode)) {
2704 if (InScopeDisable && (CurrentForm == NULL)) {
2705 //
2706 // This is DisableIf expression for Form, it should be a constant expression
2707 //
2708 ASSERT (CurrentExpression != NULL);
2709 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2710 if (EFI_ERROR (Status)) {
2711 return Status;
2712 }
2713
2714 OpCodeDisabled = IsTrue (&CurrentExpression->Result);
2715
2716 //
2717 // DisableIf Expression is only used once and not queued, free it
2718 //
2719 DestroyExpression (CurrentExpression);
2720 }
2721
2722 //
2723 // End of current Expression
2724 //
2725 CurrentExpression = NULL;
2726 }
2727
2728 break;
2729 }
2730
2731 break;
2732
2733 default:
2734 break;
2735 }
2736
2737 if (IsStatementOpCode (Operand)) {
2738 CurrentStatement->ParentStatement = ParentStatement;
2739 if (Scope != 0) {
2740 //
2741 // Scope != 0, other statements or options may nest in this statement.
2742 // Update the ParentStatement info.
2743 //
2744 ParentStatement = CurrentStatement;
2745 }
2746 }
2747 }
2748
2749 return EFI_SUCCESS;
2750}
UINT64 UINTN
INT64 INTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
RETURN_STATUS EFIAPI StrCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:405
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID HiiToLower(IN EFI_STRING ConfigString)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EvaluateExpression(IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORM *Form, IN OUT FORM_EXPRESSION *Expression)
Definition: Expression.c:2536
EFI_STATUS PopMapExpressionList(OUT VOID **Pointer)
Definition: Expression.c:594
VOID ResetScopeStack(VOID)
Definition: Expression.c:617
VOID ExtendValueToU64(IN EFI_HII_VALUE *Value)
Definition: Expression.c:2096
EFI_STATUS PushCurrentExpression(IN VOID *Pointer)
Definition: Expression.c:216
VOID ResetCurrentExpressionStack(VOID)
Definition: Expression.c:196
EFI_STATUS PushConditionalExpression(IN FORM_EXPRESSION *Pointer, IN EXPRESS_LEVEL Level)
Definition: Expression.c:479
EFI_STATUS PushScope(IN UINT8 Operand)
Definition: Expression.c:635
EFI_STATUS PopConditionalExpression(IN EXPRESS_LEVEL Level)
Definition: Expression.c:523
INTN GetConditionalExpressionCount(IN EXPRESS_LEVEL Level)
Definition: Expression.c:423
EFI_STATUS PopCurrentExpression(OUT VOID **Pointer)
Definition: Expression.c:243
EFI_STATUS PushMapExpressionList(IN VOID *Pointer)
Definition: Expression.c:567
EFI_STATUS PopScope(OUT UINT8 *Operand)
Definition: Expression.c:663
FORM_EXPRESSION ** GetConditionalExpressionList(IN EXPRESS_LEVEL Level)
Definition: Expression.c:450
VOID ResetMapExpressionListStack(VOID)
Definition: Expression.c:266
BOOLEAN IsTrue(IN EFI_HII_VALUE *Result)
Definition: Expression.c:3692
CHAR16 * GetToken(IN EFI_STRING_ID Token, IN EFI_HII_HANDLE HiiHandle)
Definition: FormDisplay.c:191
EFI_STRING EFIAPI HiiConstructConfigHdr(IN CONST EFI_GUID *Guid OPTIONAL, IN CONST CHAR16 *Name OPTIONAL, IN EFI_HANDLE DriverHandle)
Definition: HiiLib.c:723
FORMSET_STORAGE * GetFstStgFromBrsStg(IN BROWSER_STORAGE *Storage)
Definition: IfrParse.c:510
BOOLEAN IsStatementOpCode(IN UINT8 Operand)
Definition: IfrParse.c:1068
FORM_BROWSER_STATEMENT * CreateStatement(IN UINT8 *OpCodeData, IN OUT FORM_BROWSER_FORMSET *FormSet, IN OUT FORM_BROWSER_FORM *Form)
Definition: IfrParse.c:27
EFI_STATUS ParseOpCodes(IN FORM_BROWSER_FORMSET *FormSet)
Definition: IfrParse.c:1161
VOID DestroyFormSet(IN OUT FORM_BROWSER_FORMSET *FormSet)
Definition: IfrParse.c:943
VOID DestroyStatement(IN FORM_BROWSER_FORMSET *FormSet, IN OUT FORM_BROWSER_STATEMENT *Statement)
Definition: IfrParse.c:778
EFI_STATUS InitializeConfigHdr(IN FORM_BROWSER_FORMSET *FormSet, IN OUT FORMSET_STORAGE *Storage)
Definition: IfrParse.c:236
VOID DestroyExpression(IN FORM_EXPRESSION *Expression)
Definition: IfrParse.c:710
FORMSET_STORAGE * CreateStorage(IN FORM_BROWSER_FORMSET *FormSet, IN UINT8 StorageType, IN UINT8 *OpCodeData)
Definition: IfrParse.c:382
VOID CountOpCodes(IN FORM_BROWSER_FORMSET *FormSet, OUT UINTN *NumberOfStatement, OUT UINTN *NumberOfExpression)
Definition: IfrParse.c:1119
BOOLEAN IsExpressionOpCode(IN UINT8 Operand)
Definition: IfrParse.c:1037
VOID IntializeBrowserStorage(IN BROWSER_STORAGE *BrowserStorage, IN UINT8 StorageType, IN UINT8 *OpCodeData)
Definition: IfrParse.c:332
BROWSER_STORAGE * FindStorageInList(IN UINT8 StorageType, IN EFI_GUID *StorageGuid, IN CHAR16 *StorageName, IN EFI_HII_HANDLE HiiHandle)
Definition: IfrParse.c:285
BOOLEAN IsUnKnownOpCode(IN UINT8 Operand)
Definition: IfrParse.c:1103
VOID DestroyForm(IN FORM_BROWSER_FORMSET *FormSet, IN OUT FORM_BROWSER_FORM *Form)
Definition: IfrParse.c:880
FORMSET_STORAGE * GetFstStgFromVarId(IN FORM_BROWSER_FORMSET *FormSet, IN EFI_VARSTORE_ID VarStoreId)
Definition: IfrParse.c:467
VOID DestroyStorage(IN FORMSET_STORAGE *Storage)
Definition: IfrParse.c:755
FORM_BROWSER_STATEMENT * CreateQuestion(IN UINT8 *OpCodeData, IN OUT FORM_BROWSER_FORMSET *FormSet, IN OUT FORM_BROWSER_FORM *Form)
Definition: IfrParse.c:101
EFI_STATUS InitializeRequestElement(IN OUT FORM_BROWSER_FORMSET *FormSet, IN OUT FORM_BROWSER_STATEMENT *Question, IN OUT FORM_BROWSER_FORM *Form)
Definition: IfrParse.c:559
FORM_EXPRESSION * CreateExpression(IN OUT FORM_BROWSER_FORM *Form, IN UINT8 *OpCode)
Definition: IfrParse.c:210
#define EDKII_IFR_DISPLAY_BIT
Definition: MdeModuleHii.h:218
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID UiFreeMenuList(LIST_ENTRY *MenuListHead)
Definition: Setup.c:267
EFI_STATUS DeleteString(IN EFI_STRING_ID StringId, IN EFI_HII_HANDLE HiiHandle)
Definition: Setup.c:1004
EFI_STRING_ID NewString(IN CHAR16 *String, IN EFI_HII_HANDLE HiiHandle)
Definition: Setup.c:981
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID * EFI_HII_HANDLE
Definition: Base.h:213
EFI_STRING_ID string
EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION.