TianoCore EDK2 master
Loading...
Searching...
No Matches
HiiUtilityInternal.c
Go to the documentation of this file.
1
12#include "HiiInternal.h"
13
14CHAR16 *mUnknownString = L"!";
15CHAR16 *gEmptyString = L"";
16
17EFI_HII_VALUE *mExpressionEvaluationStack = NULL;
18EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;
19EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;
20UINTN mExpressionEvaluationStackOffset = 0;
21
22//
23// Unicode collation protocol interface
24//
25EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;
26EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL;
27
35VOID
37 IN OUT CHAR16 **Dest,
38 IN CHAR16 *Src
39 )
40{
41 if (*Dest != NULL) {
42 FreePool (*Dest);
43 }
44
45 *Dest = AllocateCopyPool (StrSize (Src), Src);
46}
47
62 IN HII_FORMSET_STORAGE *Storage,
63 IN CHAR16 *Name,
64 IN CHAR16 *Value,
65 OUT HII_NAME_VALUE_NODE **ReturnNode
66 )
67{
68 LIST_ENTRY *Link;
70 CHAR16 *Buffer;
71
72 Link = GetFirstNode (&Storage->NameValueList);
73 while (!IsNull (&Storage->NameValueList, Link)) {
74 Node = HII_NAME_VALUE_NODE_FROM_LINK (Link);
75
76 if (StrCmp (Name, Node->Name) == 0) {
77 Buffer = Node->Value;
78 if (Buffer != NULL) {
79 FreePool (Buffer);
80 }
81
82 Buffer = AllocateCopyPool (StrSize (Value), Value);
83 if (Buffer == NULL) {
84 return EFI_OUT_OF_RESOURCES;
85 }
86
87 Node->Value = Buffer;
88
89 if (ReturnNode != NULL) {
90 *ReturnNode = Node;
91 }
92
93 return EFI_SUCCESS;
94 }
95
96 Link = GetNextNode (&Storage->NameValueList, Link);
97 }
98
99 return EFI_NOT_FOUND;
100}
101
111VOID
113 IN HII_STATEMENT *Question,
114 IN UINT8 *Buffer,
115 OUT HII_STATEMENT_VALUE *QuestionValue
116 )
117{
118 UINTN StartBit;
119 UINTN EndBit;
120 UINT32 RetVal;
121 UINT32 BufferValue;
122
123 StartBit = Question->BitVarOffset % 8;
124 EndBit = StartBit + Question->BitStorageWidth - 1;
125
126 CopyMem ((UINT8 *)&BufferValue, Buffer, Question->StorageWidth);
127
128 RetVal = BitFieldRead32 (BufferValue, StartBit, EndBit);
129
130 //
131 // Set question value.
132 // Note: Since Question with BufferValue (orderedlist, password, string)are not supported to refer bit field.
133 // Only oneof/checkbox/oneof can support bit field.So we can copy the value to the HiiValue of Question directly.
134 //
135 CopyMem ((UINT8 *)&QuestionValue->Value, (UINT8 *)&RetVal, Question->StorageWidth);
136}
137
147VOID
149 IN HII_STATEMENT *Question,
150 IN OUT UINT8 *Buffer,
151 IN UINT32 Value
152 )
153{
154 UINT32 Operand;
155 UINTN StartBit;
156 UINTN EndBit;
157 UINT32 RetVal;
158
159 StartBit = Question->BitVarOffset % 8;
160 EndBit = StartBit + Question->BitStorageWidth - 1;
161
162 CopyMem ((UINT8 *)&Operand, Buffer, Question->StorageWidth);
163 RetVal = BitFieldWrite32 (Operand, StartBit, EndBit, Value);
164 CopyMem (Buffer, (UINT8 *)&RetVal, Question->StorageWidth);
165}
166
179 IN HII_STATEMENT *Question,
180 IN CHAR16 *Value,
181 OUT HII_STATEMENT_VALUE *QuestionValue
182 )
183{
184 CHAR16 *StringPtr;
185 BOOLEAN IsBufferStorage;
186 CHAR16 *DstBuf;
187 CHAR16 TempChar;
188 UINTN LengthStr;
189 UINT8 *Dst;
190 CHAR16 TemStr[5];
191 UINTN Index;
192 UINT8 DigitUint8;
193 BOOLEAN IsString;
194 UINTN Length;
195 EFI_STATUS Status;
196 UINT8 *Buffer;
197
198 Buffer = NULL;
199
200 IsString = (BOOLEAN)((QuestionValue->Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
201 if ((Question->Storage->Type == EFI_HII_VARSTORE_BUFFER) ||
202 (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))
203 {
204 IsBufferStorage = TRUE;
205 } else {
206 IsBufferStorage = FALSE;
207 }
208
209 //
210 // Question Value is provided by Buffer Storage or NameValue Storage
211 //
212 if ((QuestionValue->Type == EFI_IFR_TYPE_STRING) || (QuestionValue->Type == EFI_IFR_TYPE_BUFFER)) {
213 //
214 // This Question is password or orderedlist
215 //
216 if (QuestionValue->Buffer == NULL) {
217 return EFI_OUT_OF_RESOURCES;
218 }
219
220 Dst = QuestionValue->Buffer;
221 } else {
222 //
223 // Other type of Questions
224 //
225 if (Question->QuestionReferToBitField) {
226 Buffer = (UINT8 *)AllocateZeroPool (Question->StorageWidth);
227 if (Buffer == NULL) {
228 return EFI_OUT_OF_RESOURCES;
229 }
230
231 Dst = Buffer;
232 } else {
233 Dst = (UINT8 *)&QuestionValue->Value;
234 }
235 }
236
237 //
238 // Temp cut at the end of this section, end with '\0' or '&'.
239 //
240 StringPtr = Value;
241 while (*StringPtr != L'\0' && *StringPtr != L'&') {
242 StringPtr++;
243 }
244
245 TempChar = *StringPtr;
246 *StringPtr = L'\0';
247
248 LengthStr = StrLen (Value);
249
250 //
251 // Value points to a Unicode hexadecimal string, we need to convert the string to the value with CHAR16/UINT8...type.
252 // When generating the Value string, we follow this rule: 1 byte -> 2 Unicode characters (for string: 2 byte(CHAR16) ->4 Unicode characters).
253 // So the maximum value string length of a question is : Question->StorageWidth * 2.
254 // If the value string length > Question->StorageWidth * 2, only set the string length as Question->StorageWidth * 2, then convert.
255 //
256 if (LengthStr > (UINTN)Question->StorageWidth * 2) {
257 Length = (UINTN)Question->StorageWidth * 2;
258 } else {
259 Length = LengthStr;
260 }
261
262 Status = EFI_SUCCESS;
263 if (!IsBufferStorage && IsString) {
264 //
265 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
266 // Add string tail char L'\0' into Length
267 //
268 DstBuf = (CHAR16 *)Dst;
269 ZeroMem (TemStr, sizeof (TemStr));
270 for (Index = 0; Index < Length; Index += 4) {
271 StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value + Index, 4);
272 DstBuf[Index/4] = (CHAR16)StrHexToUint64 (TemStr);
273 }
274
275 //
276 // Add tailing L'\0' character
277 //
278 DstBuf[Index/4] = L'\0';
279 } else {
280 ZeroMem (TemStr, sizeof (TemStr));
281 for (Index = 0; Index < Length; Index++) {
282 TemStr[0] = Value[LengthStr - Index - 1];
283 DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
284 if ((Index & 1) == 0) {
285 Dst[Index/2] = DigitUint8;
286 } else {
287 Dst[Index/2] = (UINT8)((DigitUint8 << 4) + Dst[Index/2]);
288 }
289 }
290 }
291
292 *StringPtr = TempChar;
293
294 if ((Buffer != NULL) && Question->QuestionReferToBitField) {
295 GetBitsQuestionValue (Question, Buffer, QuestionValue);
296 FreePool (Buffer);
297 }
298
299 return Status;
300}
301
312CHAR16 *
314 IN EFI_STRING_ID Token,
315 IN EFI_HII_HANDLE HiiHandle
316 )
317{
318 EFI_STRING String;
319
320 if (HiiHandle == NULL) {
321 return NULL;
322 }
323
324 String = HiiGetString (HiiHandle, Token, NULL);
325 if (String == NULL) {
326 String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);
327 if (String == NULL) {
328 return NULL;
329 }
330 }
331
332 return (CHAR16 *)String;
333}
334
342VOID
343EFIAPI
345 IN EFI_STRING ConfigString
346 )
347{
348 EFI_STRING String;
349 BOOLEAN Lower;
350
351 //
352 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
353 //
354 for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
355 if (*String == L'=') {
356 Lower = TRUE;
357 } else if (*String == L'&') {
358 Lower = FALSE;
359 } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
360 *String = (CHAR16)(*String - L'A' + L'a');
361 }
362 }
363}
364
374BOOLEAN
376 IN EFI_HII_VALUE *Result
377 )
378{
379 switch (Result->Type) {
380 case EFI_IFR_TYPE_BOOLEAN:
381 return Result->Value.b;
382
383 case EFI_IFR_TYPE_NUM_SIZE_8:
384 return (BOOLEAN)(Result->Value.u8 != 0);
385
386 case EFI_IFR_TYPE_NUM_SIZE_16:
387 return (BOOLEAN)(Result->Value.u16 != 0);
388
389 case EFI_IFR_TYPE_NUM_SIZE_32:
390 return (BOOLEAN)(Result->Value.u32 != 0);
391
392 case EFI_IFR_TYPE_NUM_SIZE_64:
393 return (BOOLEAN)(Result->Value.u64 != 0);
394
395 default:
396 return FALSE;
397 }
398}
399
412EFI_STRING_ID
414 IN CHAR16 *String,
415 IN EFI_HII_HANDLE HiiHandle
416 )
417{
418 EFI_STRING_ID StringId;
419
420 StringId = HiiSetString (HiiHandle, 0, String, NULL);
421 return StringId;
422}
423
437 IN HII_FORMSET *FormSet,
438 IN HII_FORM *Form,
439 IN HII_STATEMENT *Question
440 )
441{
442 EFI_STATUS Status;
443 LIST_ENTRY *Link;
444 LIST_ENTRY *ListHead;
445 HII_EXPRESSION *Expression;
446
447 ListHead = &Question->NoSubmitListHead;
448 Link = GetFirstNode (ListHead);
449 while (!IsNull (ListHead, Link)) {
450 Expression = HII_EXPRESSION_FROM_LINK (Link);
451
452 //
453 // Evaluate the expression
454 //
455 Status = EvaluateHiiExpression (FormSet, Form, Expression);
456 if (EFI_ERROR (Status)) {
457 return Status;
458 }
459
460 if (IsHiiValueTrue (&Expression->Result)) {
461 return EFI_NOT_READY;
462 }
463
464 Link = GetNextNode (ListHead, Link);
465 }
466
467 return EFI_SUCCESS;
468}
469
483 IN HII_FORMSET *FormSet,
484 IN OUT HII_FORM **CurrentForm,
485 OUT HII_STATEMENT **Statement
486 )
487{
488 EFI_STATUS Status;
489 LIST_ENTRY *Link;
490 HII_STATEMENT *Question;
491 HII_FORM *Form;
492 LIST_ENTRY *LinkForm;
493
494 LinkForm = GetFirstNode (&FormSet->FormListHead);
495 while (!IsNull (&FormSet->FormListHead, LinkForm)) {
496 Form = HII_FORM_FROM_LINK (LinkForm);
497 LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);
498
499 if ((*CurrentForm != NULL) && (*CurrentForm != Form)) {
500 continue;
501 }
502
503 Link = GetFirstNode (&Form->StatementListHead);
504 while (!IsNull (&Form->StatementListHead, Link)) {
505 Question = HII_STATEMENT_FROM_LINK (Link);
506 Status = ValidateNoSubmit (FormSet, Form, Question);
507 if (EFI_ERROR (Status)) {
508 if (*CurrentForm == NULL) {
509 *CurrentForm = Form;
510 }
511
512 if (Statement != NULL) {
513 *Statement = Question;
514 }
515
516 return Status;
517 }
518
519 Link = GetNextNode (&Form->StatementListHead, Link);
520 }
521 }
522
523 return EFI_SUCCESS;
524}
525
533VOID
535 IN OUT CHAR16 **Dest,
536 IN CHAR16 *Src
537 )
538{
539 CHAR16 *NewHiiString;
540 UINTN MaxLen;
541
542 if (*Dest == NULL) {
543 NewStringCopy (Dest, Src);
544 return;
545 }
546
547 MaxLen = (StrSize (*Dest) + StrSize (Src) - 2) / sizeof (CHAR16);
548 NewHiiString = AllocatePool (MaxLen * sizeof (CHAR16));
549 if (NewHiiString == NULL) {
550 return;
551 }
552
553 StrCpyS (NewHiiString, MaxLen, *Dest);
554 StrCatS (NewHiiString, MaxLen, Src);
555
556 FreePool (*Dest);
557 *Dest = NewHiiString;
558}
559
573 IN HII_FORMSET_STORAGE *Storage,
574 IN CHAR16 **ConfigResp,
575 IN CHAR16 *ConfigRequest
576 )
577{
578 EFI_STATUS Status;
579 EFI_STRING Progress;
580 LIST_ENTRY *Link;
582 UINT8 *SourceBuf;
583 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
584 EFI_STRING TempConfigRequest;
585 UINTN RequestStrSize;
586
587 Status = EFI_SUCCESS;
588
589 if (Storage->ConfigHdr == NULL) {
590 return EFI_INVALID_PARAMETER;
591 }
592
593 if (ConfigRequest != NULL) {
594 TempConfigRequest = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);
595 if (TempConfigRequest == NULL) {
596 return EFI_OUT_OF_RESOURCES;
597 }
598 } else {
599 RequestStrSize = (StrLen (Storage->ConfigHdr) + StrLen (Storage->ConfigRequest) + 1) * sizeof (CHAR16);
600 TempConfigRequest = AllocatePool (RequestStrSize);
601 if (TempConfigRequest == NULL) {
602 return EFI_OUT_OF_RESOURCES;
603 }
604
606 TempConfigRequest,
607 RequestStrSize,
608 L"%s%s",
609 Storage->ConfigHdr,
610 Storage->ConfigRequest
611 );
612 }
613
614 switch (Storage->Type) {
615 case EFI_HII_VARSTORE_BUFFER:
616 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
617
618 Status = gBS->LocateProtocol (
619 &gEfiHiiConfigRoutingProtocolGuid,
620 NULL,
621 (VOID **)&HiiConfigRouting
622 );
623 if (EFI_ERROR (Status)) {
624 return Status;
625 }
626
627 SourceBuf = Storage->Buffer;
628 Status = HiiConfigRouting->BlockToConfig (
629 HiiConfigRouting,
630 TempConfigRequest,
631 SourceBuf,
632 Storage->Size,
633 ConfigResp,
634 &Progress
635 );
636 break;
637
638 case EFI_HII_VARSTORE_NAME_VALUE:
639
640 *ConfigResp = NULL;
641 NewStringCat (ConfigResp, Storage->ConfigHdr);
642
643 Link = GetFirstNode (&Storage->NameValueList);
644 while (!IsNull (&Storage->NameValueList, Link)) {
645 Node = HII_NAME_VALUE_NODE_FROM_LINK (Link);
646
647 if (StrStr (TempConfigRequest, Node->Name) != NULL) {
648 NewStringCat (ConfigResp, L"&");
649 NewStringCat (ConfigResp, Node->Name);
650 NewStringCat (ConfigResp, L"=");
651 NewStringCat (ConfigResp, Node->Value);
652 }
653
654 Link = GetNextNode (&Storage->NameValueList, Link);
655 }
656
657 break;
658
659 case EFI_HII_VARSTORE_EFI_VARIABLE:
660 default:
661 Status = EFI_INVALID_PARAMETER;
662 break;
663 }
664
665 return Status;
666}
667
680 IN HII_FORMSET_STORAGE *Storage,
681 IN CHAR16 *ConfigResp
682 )
683{
684 EFI_STATUS Status;
685 EFI_STRING Progress;
686 UINTN BufferSize;
687 CHAR16 *StrPtr;
688 CHAR16 *Name;
689 CHAR16 *Value;
690 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
691
692 Status = EFI_SUCCESS;
693
694 switch (Storage->Type) {
695 case EFI_HII_VARSTORE_BUFFER:
696 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
697
698 Status = gBS->LocateProtocol (
699 &gEfiHiiConfigRoutingProtocolGuid,
700 NULL,
701 (VOID **)&HiiConfigRouting
702 );
703 if (EFI_ERROR (Status)) {
704 return Status;
705 }
706
707 BufferSize = Storage->Size;
708 Status = HiiConfigRouting->ConfigToBlock (
709 HiiConfigRouting,
710 ConfigResp,
711 Storage->Buffer,
712 &BufferSize,
713 &Progress
714 );
715 break;
716
717 case EFI_HII_VARSTORE_NAME_VALUE:
718 StrPtr = StrStr (ConfigResp, L"PATH");
719 if (StrPtr == NULL) {
720 break;
721 }
722
723 StrPtr = StrStr (ConfigResp, L"&");
724 while (StrPtr != NULL) {
725 //
726 // Skip '&'
727 //
728 StrPtr = StrPtr + 1;
729 Name = StrPtr;
730 StrPtr = StrStr (StrPtr, L"=");
731 if (StrPtr == NULL) {
732 break;
733 }
734
735 *StrPtr = 0;
736
737 //
738 // Skip '='
739 //
740 StrPtr = StrPtr + 1;
741 Value = StrPtr;
742 StrPtr = StrStr (StrPtr, L"&");
743 if (StrPtr != NULL) {
744 *StrPtr = 0;
745 }
746
747 SetValueByName (Storage, Name, Value, NULL);
748 }
749
750 break;
751
752 case EFI_HII_VARSTORE_EFI_VARIABLE:
753 default:
754 Status = EFI_INVALID_PARAMETER;
755 break;
756 }
757
758 return Status;
759}
760
782 IN EFI_HII_HANDLE Handle,
783 IN OUT EFI_GUID *FormSetGuid,
784 OUT UINTN *BinaryLength,
785 OUT UINT8 **BinaryData
786 )
787{
788 EFI_STATUS Status;
789 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
790 UINTN BufferSize;
791 UINT8 *Package;
792 UINT8 *OpCodeData;
793 UINT32 Offset;
794 UINT32 Offset2;
795 UINT32 PackageListLength;
796 EFI_HII_PACKAGE_HEADER PackageHeader;
797 UINT8 Index;
798 UINT8 NumberOfClassGuid;
799 BOOLEAN ClassGuidMatch;
800 EFI_GUID *ClassGuid;
801 EFI_GUID *ComparingGuid;
802 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
803
804 OpCodeData = NULL;
805 Package = NULL;
806 ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
807
808 //
809 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
810 //
811 if (FormSetGuid == NULL) {
812 ComparingGuid = &gZeroGuid;
813 } else {
814 ComparingGuid = FormSetGuid;
815 }
816
817 //
818 // Get HII PackageList
819 //
820 Status = gBS->LocateProtocol (
821 &gEfiHiiDatabaseProtocolGuid,
822 NULL,
823 (VOID **)&HiiDatabase
824 );
825 if (EFI_ERROR (Status)) {
826 *BinaryData = NULL;
827 return Status;
828 }
829
830 BufferSize = 0;
831 HiiPackageList = NULL;
832 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
833 if (Status == EFI_BUFFER_TOO_SMALL) {
834 HiiPackageList = AllocatePool (BufferSize);
835 if (HiiPackageList == NULL) {
836 return EFI_OUT_OF_RESOURCES;
837 }
838
839 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
840 }
841
842 if (EFI_ERROR (Status)) {
843 if (HiiPackageList != NULL) {
844 FreePool (HiiPackageList);
845 }
846
847 *BinaryData = NULL;
848 return Status;
849 }
850
851 //
852 // Get Form package from this HII package List
853 //
854 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
855 Offset2 = 0;
856 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
857
858 ClassGuidMatch = FALSE;
859 while (Offset < PackageListLength) {
860 Package = ((UINT8 *)HiiPackageList) + Offset;
861 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
862
863 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
864 //
865 // Search FormSet in this Form Package
866 //
867
868 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
869 while (Offset2 < PackageHeader.Length) {
870 OpCodeData = Package + Offset2;
871
872 if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
873 //
874 // Try to compare against formset GUID
875 //
876
877 if (IsZeroGuid (FormSetGuid) ||
878 CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER))))
879 {
880 break;
881 }
882
883 if (((EFI_IFR_OP_HEADER *)OpCodeData)->Length > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
884 //
885 // Try to compare against formset class GUID
886 //
887 NumberOfClassGuid = (UINT8)(((EFI_IFR_FORM_SET *)OpCodeData)->Flags & 0x3);
888 ClassGuid = (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_FORM_SET));
889 for (Index = 0; Index < NumberOfClassGuid; Index++) {
890 if (CompareGuid (ComparingGuid, ClassGuid + Index)) {
891 ClassGuidMatch = TRUE;
892 break;
893 }
894 }
895
896 if (ClassGuidMatch) {
897 break;
898 }
899 } else if (ComparingGuid == &gEfiHiiPlatformSetupFormsetGuid) {
900 ClassGuidMatch = TRUE;
901 break;
902 }
903 }
904
905 Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
906 }
907
908 if (Offset2 < PackageHeader.Length) {
909 //
910 // Target formset found
911 //
912 break;
913 }
914 }
915
916 Offset += PackageHeader.Length;
917 }
918
919 if (Offset >= PackageListLength) {
920 //
921 // Form package not found in this Package List
922 //
923 FreePool (HiiPackageList);
924 *BinaryData = NULL;
925 return EFI_NOT_FOUND;
926 }
927
928 if (FormSetGuid != NULL) {
929 //
930 // Return the FormSet GUID
931 //
932 CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *)OpCodeData)->Guid, sizeof (EFI_GUID));
933 }
934
935 //
936 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
937 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
938 // of the Form Package.
939 //
940
941 *BinaryLength = PackageHeader.Length - Offset2;
942 *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);
943 FreePool (HiiPackageList);
944 if (*BinaryData == NULL) {
945 return EFI_OUT_OF_RESOURCES;
946 }
947
948 return EFI_SUCCESS;
949}
950
958BOOLEAN
960 IN HII_FORMSET_STORAGE *Storage,
961 IN CHAR16 *RequestElement
962 )
963{
964 return StrStr (Storage->ConfigRequest, RequestElement) != NULL ? TRUE : FALSE;
965}
966
975VOID
977 IN OUT CHAR16 **ConfigRequest,
978 IN OUT UINTN *SpareStrLen,
979 IN CHAR16 *RequestElement
980 )
981{
982 CHAR16 *NewStr;
983 UINTN StringSize;
984 UINTN StrLength;
985 UINTN MaxLen;
986
987 StrLength = StrLen (RequestElement);
988 StringSize = (*ConfigRequest != NULL) ? StrSize (*ConfigRequest) : sizeof (CHAR16);
989 MaxLen = StringSize / sizeof (CHAR16) + *SpareStrLen;
990
991 //
992 // Append <RequestElement> to <ConfigRequest>
993 //
994 if (StrLength > *SpareStrLen) {
995 //
996 // Old String buffer is not sufficient for RequestElement, allocate a new one
997 //
998 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
999 NewStr = AllocatePool (MaxLen * sizeof (CHAR16));
1000 if (NewStr == NULL) {
1001 return;
1002 }
1003
1004 if (*ConfigRequest != NULL) {
1005 CopyMem (NewStr, *ConfigRequest, StringSize);
1006 FreePool (*ConfigRequest);
1007 } else {
1008 NewStr[0] = L'\0';
1009 }
1010
1011 *ConfigRequest = NewStr;
1012 *SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
1013 }
1014
1015 StrCatS (*ConfigRequest, MaxLen, RequestElement);
1016 *SpareStrLen -= StrLength;
1017}
1018
1030BOOLEAN
1032 IN HII_FORMSET_STORAGE *Storage,
1033 IN CHAR16 *Request,
1034 IN BOOLEAN RespString
1035 )
1036{
1037 CHAR16 *RequestElement;
1038 CHAR16 *NextRequestElement;
1039 CHAR16 *NextElementBackup;
1040 CHAR16 *SearchKey;
1041 CHAR16 *ValueKey;
1042 BOOLEAN RetVal;
1043 CHAR16 *ConfigRequest;
1044
1045 RetVal = FALSE;
1046 NextElementBackup = NULL;
1047 ValueKey = NULL;
1048
1049 if (Request != NULL) {
1050 ConfigRequest = Request;
1051 } else {
1052 ConfigRequest = Storage->ConfigRequest;
1053 }
1054
1055 if (Storage->ConfigRequest == NULL) {
1056 Storage->ConfigRequest = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);
1057 if (Storage->ConfigRequest == NULL) {
1058 return FALSE;
1059 }
1060
1061 return TRUE;
1062 }
1063
1064 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
1065 //
1066 // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage
1067 //
1068 SearchKey = L"&";
1069 } else {
1070 //
1071 // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage
1072 //
1073 SearchKey = L"&OFFSET";
1074 ValueKey = L"&VALUE";
1075 }
1076
1077 //
1078 // Find SearchKey storage
1079 //
1080 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
1081 RequestElement = StrStr (ConfigRequest, L"PATH");
1082 if (RequestElement == NULL) {
1083 return FALSE;
1084 }
1085
1086 RequestElement = StrStr (RequestElement, SearchKey);
1087 } else {
1088 RequestElement = StrStr (ConfigRequest, SearchKey);
1089 }
1090
1091 while (RequestElement != NULL) {
1092 //
1093 // +1 to avoid find header itself.
1094 //
1095 NextRequestElement = StrStr (RequestElement + 1, SearchKey);
1096
1097 //
1098 // The last Request element in configRequest string.
1099 //
1100 if (NextRequestElement != NULL) {
1101 if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
1102 NextElementBackup = NextRequestElement;
1103 NextRequestElement = StrStr (RequestElement, ValueKey);
1104 if (NextRequestElement == NULL) {
1105 return FALSE;
1106 }
1107 }
1108
1109 //
1110 // Replace "&" with '\0'.
1111 //
1112 *NextRequestElement = L'\0';
1113 } else {
1114 if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
1115 NextElementBackup = NextRequestElement;
1116 NextRequestElement = StrStr (RequestElement, ValueKey);
1117 if (NextRequestElement == NULL) {
1118 return FALSE;
1119 }
1120
1121 //
1122 // Replace "&" with '\0'.
1123 //
1124 *NextRequestElement = L'\0';
1125 }
1126 }
1127
1128 if (!ElementValidation (Storage, RequestElement)) {
1129 //
1130 // Add this element to the Storage->BrowserStorage->AllRequestElement.
1131 //
1132 AppendConfigRequest (&Storage->ConfigRequest, &Storage->SpareStrLen, RequestElement);
1133 RetVal = TRUE;
1134 }
1135
1136 if (NextRequestElement != NULL) {
1137 //
1138 // Restore '&' with '\0' for later used.
1139 //
1140 *NextRequestElement = L'&';
1141 }
1142
1143 if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
1144 RequestElement = NextElementBackup;
1145 } else {
1146 RequestElement = NextRequestElement;
1147 }
1148 }
1149
1150 return RetVal;
1151}
1152
1160VOID
1162 IN HII_FORMSET *FormSet,
1163 IN HII_FORMSET_STORAGE *Storage
1164 )
1165{
1166 EFI_STATUS Status;
1167 EFI_STRING Progress;
1168 EFI_STRING Result;
1169 CHAR16 *StrPtr;
1170 EFI_STRING ConfigRequest;
1171 UINTN RequestStrSize;
1172 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1173
1174 ConfigRequest = NULL;
1175
1176 switch (Storage->Type) {
1177 case EFI_HII_VARSTORE_EFI_VARIABLE:
1178 return;
1179
1180 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
1181 #if 0 // bug fix for efivarstore
1182 if (Storage->ConfigRequest != NULL) {
1183 ConfigRequestAdjust (Storage, Storage->ConfigRequest, FALSE);
1184 return;
1185 }
1186
1187 #endif
1188 break;
1189
1190 case EFI_HII_VARSTORE_BUFFER:
1191 case EFI_HII_VARSTORE_NAME_VALUE:
1192 //
1193 // Skip if there is no RequestElement.
1194 //
1195 if (Storage->ElementCount == 0) {
1196 return;
1197 }
1198
1199 break;
1200
1201 default:
1202 return;
1203 }
1204
1205 if (Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {
1206 //
1207 // Create the config request string to get all fields for this storage.
1208 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1209 // followed by "&OFFSET=0&WIDTH=WWWW"followed by a Null-terminator
1210 //
1211 RequestStrSize = StrSize (Storage->ConfigHdr) + 20 * sizeof (CHAR16);
1212 ConfigRequest = AllocatePool (RequestStrSize);
1213 if (ConfigRequest == NULL) {
1214 return;
1215 }
1216
1218 ConfigRequest,
1219 RequestStrSize,
1220 L"%s&OFFSET=0&WIDTH=%04x",
1221 Storage->ConfigHdr,
1222 Storage->Size
1223 );
1224 } else {
1225 RequestStrSize = (StrLen (Storage->ConfigHdr) + StrLen (Storage->ConfigRequest) + 1) * sizeof (CHAR16);
1226 ConfigRequest = AllocatePool (RequestStrSize);
1227 if (ConfigRequest == NULL) {
1228 return;
1229 }
1230
1232 ConfigRequest,
1233 RequestStrSize,
1234 L"%s%s",
1235 Storage->ConfigHdr,
1236 Storage->ConfigRequest
1237 );
1238 }
1239
1240 //
1241 // Request current settings from Configuration Driver
1242 //
1243 Status = gBS->LocateProtocol (
1244 &gEfiHiiConfigRoutingProtocolGuid,
1245 NULL,
1246 (VOID **)&HiiConfigRouting
1247 );
1248 if (EFI_ERROR (Status)) {
1249 return;
1250 }
1251
1252 Status = HiiConfigRouting->ExtractConfig (
1253 HiiConfigRouting,
1254 ConfigRequest,
1255 &Progress,
1256 &Result
1257 );
1258 if (!EFI_ERROR (Status)) {
1259 //
1260 // Convert Result from <ConfigAltResp> to <ConfigResp>
1261 //
1262 StrPtr = StrStr (Result, L"&GUID=");
1263 if (StrPtr != NULL) {
1264 *StrPtr = L'\0';
1265 }
1266
1267 Status = ConfigRespToStorage (Storage, Result);
1268 FreePool (Result);
1269 }
1270
1271 Storage->ConfigRequest = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);
1272 if (Storage->ConfigRequest == NULL) {
1273 if (ConfigRequest != NULL) {
1274 FreePool (ConfigRequest);
1275 }
1276
1277 return;
1278 }
1279
1280 if (Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {
1281 if (ConfigRequest != NULL) {
1282 FreePool (ConfigRequest);
1283 }
1284 }
1285}
1286
1293VOID
1295 IN HII_STATEMENT_VALUE *Value
1296 )
1297{
1298 UINT64 Temp;
1299
1300 Temp = 0;
1301 switch (Value->Type) {
1302 case EFI_IFR_TYPE_NUM_SIZE_8:
1303 Temp = Value->Value.u8;
1304 break;
1305
1306 case EFI_IFR_TYPE_NUM_SIZE_16:
1307 Temp = Value->Value.u16;
1308 break;
1309
1310 case EFI_IFR_TYPE_NUM_SIZE_32:
1311 Temp = Value->Value.u32;
1312 break;
1313
1314 case EFI_IFR_TYPE_BOOLEAN:
1315 Temp = Value->Value.b;
1316 break;
1317
1318 case EFI_IFR_TYPE_TIME:
1319 Temp = Value->Value.u32 & 0xffffff;
1320 break;
1321
1322 case EFI_IFR_TYPE_DATE:
1323 Temp = Value->Value.u32;
1324 break;
1325
1326 default:
1327 return;
1328 }
1329
1330 Value->Value.u64 = Temp;
1331}
1332
1345PopStack (
1346 IN EFI_HII_VALUE *Stack,
1347 IN OUT EFI_HII_VALUE **StackPtr,
1348 OUT EFI_HII_VALUE *Data
1349 );
1350
1364PushStack (
1365 IN OUT EFI_HII_VALUE **Stack,
1366 IN OUT EFI_HII_VALUE **StackPtr,
1367 IN OUT EFI_HII_VALUE **StackEnd,
1368 IN EFI_HII_VALUE *Data
1369 );
1370
1388 IN EFI_HII_HANDLE Handle,
1389 IN OUT EFI_GUID *FormSetGuid,
1390 OUT HII_FORMSET *FormSet
1391 );
1392
1399VOID
1401 IN OUT HII_FORMSET *FormSet
1402 );
1403
1418 IN HII_FORMSET_STORAGE *Storage,
1419 IN CHAR16 *Name,
1420 IN OUT CHAR16 **Value
1421 )
1422{
1423 LIST_ENTRY *Link;
1424 HII_NAME_VALUE_NODE *Node;
1425
1426 if ((Storage == NULL) || (Value == NULL)) {
1427 return EFI_INVALID_PARAMETER;
1428 }
1429
1430 *Value = NULL;
1431
1432 Link = GetFirstNode (&Storage->NameValueList);
1433 while (!IsNull (&Storage->NameValueList, Link)) {
1434 Node = HII_NAME_VALUE_NODE_FROM_LINK (Link);
1435
1436 if (StrCmp (Name, Node->Name) == 0) {
1437 NewStringCopy (Value, Node->Value);
1438 return EFI_SUCCESS;
1439 }
1440
1441 Link = GetNextNode (&Storage->NameValueList, Link);
1442 }
1443
1444 return EFI_NOT_FOUND;
1445}
1446
1461 IN HII_FORMSET *FormSet,
1462 IN HII_FORM *Form,
1463 IN OUT HII_STATEMENT *Question,
1464 IN GET_SET_QUESTION_VALUE_WITH GetValueFrom
1465 )
1466{
1467 EFI_STATUS Status;
1468 BOOLEAN Enabled;
1469 BOOLEAN Pending;
1470 UINT8 *Dst;
1471 UINTN StorageWidth;
1472 EFI_TIME EfiTime;
1473 HII_FORMSET_STORAGE *Storage;
1474 HII_FORMSET_STORAGE *FormsetStorage;
1475 EFI_IFR_TYPE_VALUE *QuestionValue;
1476 CHAR16 *ConfigRequest;
1477 CHAR16 *Progress;
1478 CHAR16 *Result;
1479 CHAR16 *Value;
1480 UINTN Length;
1481 BOOLEAN IsBufferStorage;
1482 UINTN MaxLen;
1483 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1484
1485 if ((FormSet == NULL) || (Form == NULL) || (Question == NULL)) {
1486 return EFI_INVALID_PARAMETER;
1487 }
1488
1489 Status = EFI_SUCCESS;
1490 Value = NULL;
1491 Result = NULL;
1492
1493 if (GetValueFrom >= GetSetValueWithMax) {
1494 return EFI_INVALID_PARAMETER;
1495 }
1496
1497 //
1498 // Question value is provided by an Expression, evaluate it
1499 //
1500 if (Question->ValueExpression != NULL) {
1501 Status = EvaluateHiiExpression (FormSet, Form, Question->ValueExpression);
1502 if (!EFI_ERROR (Status)) {
1503 if (Question->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {
1504 ASSERT (Question->Value.Type == EFI_IFR_TYPE_BUFFER && Question->Value.Buffer != NULL);
1505 if (Question->StorageWidth > Question->ValueExpression->Result.BufferLen) {
1506 CopyMem (Question->Value.Buffer, Question->ValueExpression->Result.Buffer, Question->ValueExpression->Result.BufferLen);
1507 Question->Value.BufferLen = Question->ValueExpression->Result.BufferLen;
1508 } else {
1509 CopyMem (Question->Value.Buffer, Question->ValueExpression->Result.Buffer, Question->StorageWidth);
1510 Question->Value.BufferLen = Question->StorageWidth;
1511 }
1512
1513 FreePool (Question->ValueExpression->Result.Buffer);
1514 }
1515
1516 Question->Value.Type = Question->ValueExpression->Result.Type;
1517 CopyMem (&Question->Value.Value, &Question->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));
1518 }
1519
1520 return Status;
1521 }
1522
1523 //
1524 // Get question value by read expression.
1525 //
1526 if ((Question->ReadExpression != NULL) && (Form->FormType == STANDARD_MAP_FORM_TYPE)) {
1527 Status = EvaluateHiiExpression (FormSet, Form, Question->ReadExpression);
1528 if (!EFI_ERROR (Status) &&
1529 ((Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER) || (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER)))
1530 {
1531 //
1532 // Only update question value to the valid result.
1533 //
1534 if (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {
1535 ASSERT (Question->Value.Type == EFI_IFR_TYPE_BUFFER && Question->Value.Buffer != NULL);
1536 if (Question->StorageWidth > Question->ReadExpression->Result.BufferLen) {
1537 CopyMem (Question->Value.Buffer, Question->ReadExpression->Result.Buffer, Question->ReadExpression->Result.BufferLen);
1538 Question->Value.BufferLen = Question->ReadExpression->Result.BufferLen;
1539 } else {
1540 CopyMem (Question->Value.Buffer, Question->ReadExpression->Result.Buffer, Question->StorageWidth);
1541 Question->Value.BufferLen = Question->StorageWidth;
1542 }
1543
1544 FreePool (Question->ReadExpression->Result.Buffer);
1545 }
1546
1547 Question->Value.Type = Question->ReadExpression->Result.Type;
1548 CopyMem (&Question->Value.Value, &Question->ReadExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));
1549 return EFI_SUCCESS;
1550 }
1551 }
1552
1553 //
1554 // Question value is provided by RTC
1555 //
1556 Storage = Question->Storage;
1557 QuestionValue = &Question->Value.Value;
1558 if (Storage == NULL) {
1559 //
1560 // It's a Question without storage, or RTC date/time
1561 //
1562 if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
1563 //
1564 // Date and time define the same Flags bit
1565 //
1566 switch (Question->ExtraData.Flags & EFI_QF_DATE_STORAGE) {
1567 case QF_DATE_STORAGE_TIME:
1568 Status = gRT->GetTime (&EfiTime, NULL);
1569 break;
1570
1571 case QF_DATE_STORAGE_WAKEUP:
1572 Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);
1573 break;
1574
1575 case QF_DATE_STORAGE_NORMAL:
1576 default:
1577 //
1578 // For date/time without storage
1579 //
1580 return EFI_SUCCESS;
1581 }
1582
1583 if (EFI_ERROR (Status)) {
1584 if (Question->Operand == EFI_IFR_DATE_OP) {
1585 QuestionValue->date.Year = 0xff;
1586 QuestionValue->date.Month = 0xff;
1587 QuestionValue->date.Day = 0xff;
1588 } else {
1589 QuestionValue->time.Hour = 0xff;
1590 QuestionValue->time.Minute = 0xff;
1591 QuestionValue->time.Second = 0xff;
1592 }
1593
1594 return EFI_SUCCESS;
1595 }
1596
1597 if (Question->Operand == EFI_IFR_DATE_OP) {
1598 QuestionValue->date.Year = EfiTime.Year;
1599 QuestionValue->date.Month = EfiTime.Month;
1600 QuestionValue->date.Day = EfiTime.Day;
1601 } else {
1602 QuestionValue->time.Hour = EfiTime.Hour;
1603 QuestionValue->time.Minute = EfiTime.Minute;
1604 QuestionValue->time.Second = EfiTime.Second;
1605 }
1606 }
1607
1608 return EFI_SUCCESS;
1609 }
1610
1611 //
1612 // Question value is provided by EFI variable
1613 //
1614 StorageWidth = Question->StorageWidth;
1615 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
1616 if (Question->Value.Buffer != NULL) {
1617 Dst = Question->Value.Buffer;
1618 } else {
1619 Dst = (UINT8 *)QuestionValue;
1620 }
1621
1622 Status = gRT->GetVariable (
1623 Question->VariableName,
1624 &Storage->Guid,
1625 NULL,
1626 &StorageWidth,
1627 Dst
1628 );
1629 //
1630 // Always return success, even this EFI variable doesn't exist
1631 //
1632 return EFI_SUCCESS;
1633 }
1634
1635 //
1636 // Question Value is provided by Buffer Storage or NameValue Storage
1637 //
1638 if (Question->Value.Buffer != NULL) {
1639 //
1640 // This Question is password or orderedlist
1641 //
1642 Dst = Question->Value.Buffer;
1643 } else {
1644 //
1645 // Other type of Questions
1646 //
1647 Dst = (UINT8 *)&Question->Value.Value;
1648 }
1649
1650 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ||
1651 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))
1652 {
1653 IsBufferStorage = TRUE;
1654 } else {
1655 IsBufferStorage = FALSE;
1656 }
1657
1658 if (GetValueFrom == GetSetValueWithBuffer ) {
1659 if (IsBufferStorage) {
1660 //
1661 // Copy from storage Edit buffer
1662 // If the Question refer to bit filed, get the value in the related bit filed.
1663 //
1664 if (Question->QuestionReferToBitField) {
1665 GetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset, &Question->Value);
1666 } else {
1667 CopyMem (Dst, Storage->Buffer + Question->VarStoreInfo.VarOffset, StorageWidth);
1668 }
1669 } else {
1670 Value = NULL;
1671 Status = GetValueByName (Storage, Question->VariableName, &Value);
1672 if (EFI_ERROR (Status)) {
1673 return Status;
1674 }
1675
1676 ASSERT (Value != NULL);
1677 Status = BufferToQuestionValue (Question, Value, &Question->Value);
1678 FreePool (Value);
1679 }
1680 } else {
1681 FormsetStorage = GetFstStgFromVarId (FormSet, Question->VarStoreId);
1682 ASSERT (FormsetStorage != NULL);
1683 //
1684 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1685 // <ConfigHdr> + "&" + <VariableName>
1686 //
1687 if (IsBufferStorage) {
1688 Length = StrLen (FormsetStorage->ConfigHdr);
1689 Length += StrLen (Question->BlockName);
1690 } else {
1691 Length = StrLen (FormsetStorage->ConfigHdr);
1692 Length += StrLen (Question->VariableName) + 1;
1693 }
1694
1695 // Allocate buffer include '\0'
1696 MaxLen = Length + 1;
1697 ConfigRequest = AllocatePool (MaxLen * sizeof (CHAR16));
1698 ASSERT (ConfigRequest != NULL);
1699
1700 StrCpyS (ConfigRequest, MaxLen, FormsetStorage->ConfigHdr);
1701 if (IsBufferStorage) {
1702 StrCatS (ConfigRequest, MaxLen, Question->BlockName);
1703 } else {
1704 StrCatS (ConfigRequest, MaxLen, L"&");
1705 StrCatS (ConfigRequest, MaxLen, Question->VariableName);
1706 }
1707
1708 Status = gBS->LocateProtocol (
1709 &gEfiHiiConfigRoutingProtocolGuid,
1710 NULL,
1711 (VOID **)&HiiConfigRouting
1712 );
1713 if (EFI_ERROR (Status)) {
1714 return Status;
1715 }
1716
1717 //
1718 // Request current settings from Configuration Driver
1719 //
1720 Status = HiiConfigRouting->ExtractConfig (
1721 HiiConfigRouting,
1722 ConfigRequest,
1723 &Progress,
1724 &Result
1725 );
1726 FreePool (ConfigRequest);
1727 if (EFI_ERROR (Status)) {
1728 return Status;
1729 }
1730
1731 //
1732 // Skip <ConfigRequest>
1733 //
1734 if (IsBufferStorage) {
1735 Value = StrStr (Result, L"&VALUE");
1736 if (Value == NULL) {
1737 FreePool (Result);
1738 return EFI_NOT_FOUND;
1739 }
1740
1741 //
1742 // Skip "&VALUE"
1743 //
1744 Value = Value + 6;
1745 } else {
1746 Value = Result + Length;
1747 }
1748
1749 if (*Value != '=') {
1750 FreePool (Result);
1751 return EFI_NOT_FOUND;
1752 }
1753
1754 //
1755 // Skip '=', point to value
1756 //
1757 Value = Value + 1;
1758
1759 Status = BufferToQuestionValue (Question, Value, &Question->Value);
1760 if (EFI_ERROR (Status)) {
1761 FreePool (Result);
1762 return Status;
1763 }
1764
1765 //
1766 // Synchronize Buffer
1767 //
1768 if (IsBufferStorage) {
1769 CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);
1770 } else {
1771 SetValueByName (Storage, Question->VariableName, Value, NULL);
1772 }
1773
1774 if (Result != NULL) {
1775 FreePool (Result);
1776 }
1777 }
1778
1779 return Status;
1780}
1781
1788VOID
1790 IN CHAR16 *String
1791 )
1792{
1793 if (String == NULL) {
1794 return;
1795 }
1796
1797 while (*String != 0) {
1798 if ((*String >= 'a') && (*String <= 'z')) {
1799 *String = (UINT16)((*String) & ((UINT16) ~0x20));
1800 }
1801
1802 String++;
1803 }
1804}
1805
1818BOOLEAN
1820 IN EFI_HII_VALUE *Value
1821 )
1822{
1823 if (Value == NULL) {
1824 return FALSE;
1825 }
1826
1827 switch (Value->Type) {
1828 case EFI_IFR_TYPE_BUFFER:
1829 case EFI_IFR_TYPE_DATE:
1830 case EFI_IFR_TYPE_TIME:
1831 case EFI_IFR_TYPE_REF:
1832 return TRUE;
1833
1834 default:
1835 return FALSE;
1836 }
1837}
1838
1848BOOLEAN
1850 IN EFI_HII_VALUE *Value
1851 )
1852{
1853 if (Value == NULL) {
1854 return FALSE;
1855 }
1856
1857 switch (Value->Type) {
1858 case EFI_IFR_TYPE_NUM_SIZE_8:
1859 case EFI_IFR_TYPE_NUM_SIZE_16:
1860 case EFI_IFR_TYPE_NUM_SIZE_32:
1861 case EFI_IFR_TYPE_NUM_SIZE_64:
1862 case EFI_IFR_TYPE_BOOLEAN:
1863 return TRUE;
1864
1865 default:
1866 return FALSE;
1867 }
1868}
1869
1881UINT8 *
1883 IN EFI_HII_VALUE *Value
1884 )
1885{
1886 if (Value == NULL) {
1887 return NULL;
1888 }
1889
1890 switch (Value->Type) {
1891 case EFI_IFR_TYPE_BUFFER:
1892 return Value->Buffer;
1893
1894 case EFI_IFR_TYPE_DATE:
1895 return (UINT8 *)(&Value->Value.date);
1896
1897 case EFI_IFR_TYPE_TIME:
1898 return (UINT8 *)(&Value->Value.time);
1899
1900 case EFI_IFR_TYPE_REF:
1901 return (UINT8 *)(&Value->Value.ref);
1902
1903 default:
1904 return NULL;
1905 }
1906}
1907
1919UINT16
1921 IN EFI_HII_VALUE *Value
1922 )
1923{
1924 if (Value == NULL) {
1925 return 0;
1926 }
1927
1928 switch (Value->Type) {
1929 case EFI_IFR_TYPE_BUFFER:
1930 return Value->BufferLen;
1931
1932 case EFI_IFR_TYPE_DATE:
1933 return (UINT16)sizeof (EFI_HII_DATE);
1934
1935 case EFI_IFR_TYPE_TIME:
1936 return (UINT16)sizeof (EFI_HII_TIME);
1937
1938 case EFI_IFR_TYPE_REF:
1939 return (UINT16)sizeof (EFI_HII_REF);
1940
1941 default:
1942 return 0;
1943 }
1944}
1945
1954UINT64
1956 IN EFI_HII_VALUE *Value
1957 )
1958{
1959 UINT64 RetVal;
1960
1961 if (Value == NULL) {
1962 return 0;
1963 }
1964
1965 RetVal = 0;
1966
1967 switch (Value->Type) {
1968 case EFI_IFR_TYPE_NUM_SIZE_8:
1969 RetVal = Value->Value.u8;
1970 break;
1971
1972 case EFI_IFR_TYPE_NUM_SIZE_16:
1973 RetVal = Value->Value.u16;
1974 break;
1975
1976 case EFI_IFR_TYPE_NUM_SIZE_32:
1977 RetVal = Value->Value.u32;
1978 break;
1979
1980 case EFI_IFR_TYPE_BOOLEAN:
1981 RetVal = Value->Value.b;
1982 break;
1983
1984 case EFI_IFR_TYPE_DATE:
1985 RetVal = *(UINT64 *)&Value->Value.date;
1986 break;
1987
1988 case EFI_IFR_TYPE_TIME:
1989 RetVal = (*(UINT64 *)&Value->Value.time) & 0xffffff;
1990 break;
1991
1992 default:
1993 RetVal = Value->Value.u64;
1994 break;
1995 }
1996
1997 return RetVal;
1998}
1999
2018 IN EFI_HII_VALUE *Value1,
2019 IN EFI_HII_VALUE *Value2,
2020 OUT INTN *Result,
2021 IN EFI_HII_HANDLE HiiHandle OPTIONAL
2022 )
2023{
2024 INT64 Temp64;
2025 CHAR16 *Str1;
2026 CHAR16 *Str2;
2027 UINTN Len;
2028 UINT8 *Buf1;
2029 UINT16 Buf1Len;
2030 UINT8 *Buf2;
2031 UINT16 Buf2Len;
2032
2033 if ((Value1 == NULL) || (Value2 == NULL) || (Result == NULL)) {
2034 return EFI_INVALID_PARAMETER;
2035 }
2036
2037 if ((Value1->Type == EFI_IFR_TYPE_STRING) && (Value2->Type == EFI_IFR_TYPE_STRING)) {
2038 if ((Value1->Value.string == 0) || (Value2->Value.string == 0)) {
2039 //
2040 // StringId 0 is reserved
2041 //
2042 return EFI_INVALID_PARAMETER;
2043 }
2044
2045 if (Value1->Value.string == Value2->Value.string) {
2046 *Result = 0;
2047 return EFI_SUCCESS;
2048 }
2049
2050 Str1 = GetTokenString (Value1->Value.string, HiiHandle);
2051 if (Str1 == NULL) {
2052 //
2053 // String not found
2054 //
2055 return EFI_NOT_FOUND;
2056 }
2057
2058 Str2 = GetTokenString (Value2->Value.string, HiiHandle);
2059 if (Str2 == NULL) {
2060 FreePool (Str1);
2061 return EFI_NOT_FOUND;
2062 }
2063
2064 *Result = StrCmp (Str1, Str2);
2065
2066 FreePool (Str1);
2067 FreePool (Str2);
2068
2069 return EFI_SUCCESS;
2070 }
2071
2072 //
2073 // Take types(date, time, ref, buffer) as buffer
2074 //
2075 if (IsTypeInBuffer (Value1) && IsTypeInBuffer (Value2)) {
2076 Buf1 = GetBufferForValue (Value1);
2077 Buf1Len = GetLengthForValue (Value1);
2078 Buf2 = GetBufferForValue (Value2);
2079 Buf2Len = GetLengthForValue (Value2);
2080
2081 Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;
2082 *Result = CompareMem (Buf1, Buf2, Len);
2083 if ((*Result == 0) && (Buf1Len != Buf2Len)) {
2084 //
2085 // In this case, means base on small number buffer, the data is same
2086 // So which value has more data, which value is bigger.
2087 //
2088 *Result = Buf1Len > Buf2Len ? 1 : -1;
2089 }
2090
2091 return EFI_SUCCESS;
2092 }
2093
2094 //
2095 // Take types(integer, boolean) as integer
2096 //
2097 if (IsTypeInUINT64 (Value1) && IsTypeInUINT64 (Value2)) {
2098 Temp64 = HiiValueToUINT64 (Value1) - HiiValueToUINT64 (Value2);
2099 if (Temp64 > 0) {
2100 *Result = 1;
2101 } else if (Temp64 < 0) {
2102 *Result = -1;
2103 } else {
2104 *Result = 0;
2105 }
2106
2107 return EFI_SUCCESS;
2108 }
2109
2110 return EFI_UNSUPPORTED;
2111}
2112
2121BOOLEAN
2123 IN EFI_GUID *Guid
2124 )
2125{
2126 EFI_STATUS Status;
2127 EFI_USER_PROFILE_HANDLE UserProfileHandle;
2128 EFI_USER_INFO_HANDLE UserInfoHandle;
2129 EFI_USER_INFO *UserInfo;
2130 EFI_GUID *UserPermissionsGuid;
2131 UINTN UserInfoSize;
2132 UINTN AccessControlDataSize;
2133 EFI_USER_INFO_ACCESS_CONTROL *AccessControl;
2134 UINTN RemainSize;
2135
2136 if (mUserManager == NULL) {
2137 Status = gBS->LocateProtocol (
2138 &gEfiUserManagerProtocolGuid,
2139 NULL,
2140 (VOID **)&mUserManager
2141 );
2142 if (EFI_ERROR (Status)) {
2148 return TRUE;
2149 }
2150 }
2151
2152 Status = mUserManager->Current (mUserManager, &UserProfileHandle);
2153 ASSERT_EFI_ERROR (Status);
2154
2159
2160 for (UserInfoHandle = NULL; ;) {
2161 Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);
2162 if (EFI_ERROR (Status)) {
2163 break;
2164 }
2165
2166 UserInfoSize = 0;
2167 Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, NULL, &UserInfoSize);
2168 if (Status != EFI_BUFFER_TOO_SMALL) {
2169 continue;
2170 }
2171
2172 UserInfo = (EFI_USER_INFO *)AllocatePool (UserInfoSize);
2173 if (UserInfo == NULL) {
2174 break;
2175 }
2176
2177 Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, UserInfo, &UserInfoSize);
2178 if (EFI_ERROR (Status) ||
2180 (UserInfo->InfoSize <= sizeof (EFI_USER_INFO)))
2181 {
2182 FreePool (UserInfo);
2183 continue;
2184 }
2185
2186 RemainSize = UserInfo->InfoSize - sizeof (EFI_USER_INFO);
2187 AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)(UserInfo + 1);
2188 while (RemainSize >= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {
2189 if ((RemainSize < AccessControl->Size) || (AccessControl->Size < sizeof (EFI_USER_INFO_ACCESS_CONTROL))) {
2190 break;
2191 }
2192
2193 if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {
2197
2198 UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);
2199 AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);
2200 while (AccessControlDataSize >= sizeof (EFI_GUID)) {
2201 if (CompareGuid (Guid, UserPermissionsGuid)) {
2202 FreePool (UserInfo);
2203 return TRUE;
2204 }
2205
2206 UserPermissionsGuid++;
2207 AccessControlDataSize -= sizeof (EFI_GUID);
2208 }
2209 }
2210
2211 RemainSize -= AccessControl->Size;
2212 AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);
2213 }
2214
2215 FreePool (UserInfo);
2216 }
2217
2218 return FALSE;
2219}
2220
2233 IN HII_FORM *Form,
2234 IN UINT16 QuestionId
2235 )
2236{
2237 LIST_ENTRY *Link;
2238 HII_STATEMENT *Question;
2239
2240 if ((QuestionId == 0) || (Form == NULL)) {
2241 //
2242 // The value of zero is reserved
2243 //
2244 return NULL;
2245 }
2246
2247 Link = GetFirstNode (&Form->StatementListHead);
2248 while (!IsNull (&Form->StatementListHead, Link)) {
2249 Question = HII_STATEMENT_FROM_LINK (Link);
2250
2251 if (Question->QuestionId == QuestionId) {
2252 return Question;
2253 }
2254
2255 Link = GetNextNode (&Form->StatementListHead, Link);
2256 }
2257
2258 return NULL;
2259}
2260
2274 IN HII_FORMSET *FormSet,
2275 IN HII_FORM *Form,
2276 IN UINT16 QuestionId
2277 )
2278{
2279 LIST_ENTRY *Link;
2280 HII_STATEMENT *Question;
2281
2282 if ((FormSet == NULL) || (Form == NULL)) {
2283 return NULL;
2284 }
2285
2286 //
2287 // Search in the form scope first
2288 //
2289 Question = QuestionIdInForm (Form, QuestionId);
2290 if (Question != NULL) {
2291 return Question;
2292 }
2293
2294 //
2295 // Search in the formset scope
2296 //
2297 Link = GetFirstNode (&FormSet->FormListHead);
2298 while (!IsNull (&FormSet->FormListHead, Link)) {
2299 Form = HII_FORM_FROM_LINK (Link);
2300
2301 Question = QuestionIdInForm (Form, QuestionId);
2302 if (Question != NULL) {
2303 //
2304 // EFI variable storage may be updated by Callback() asynchronous,
2305 // to keep synchronous, always reload the Question Value.
2306 //
2307 if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
2308 GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);
2309 }
2310
2311 return Question;
2312 }
2313
2314 Link = GetNextNode (&FormSet->FormListHead, Link);
2315 }
2316
2317 return NULL;
2318}
2319
2333 IN EFI_HII_VALUE *Value
2334 )
2335{
2336 if (Value == NULL) {
2337 return EFI_INVALID_PARAMETER;
2338 }
2339
2340 return PushStack (
2341 &mExpressionEvaluationStack,
2342 &mExpressionEvaluationStackPointer,
2343 &mExpressionEvaluationStackEnd,
2344 Value
2345 );
2346}
2347
2360 OUT EFI_HII_VALUE *Value
2361 )
2362{
2363 if (Value == NULL) {
2364 return EFI_INVALID_PARAMETER;
2365 }
2366
2367 return PopStack (
2368 mExpressionEvaluationStack + mExpressionEvaluationStackOffset,
2369 &mExpressionEvaluationStackPointer,
2370 Value
2371 );
2372}
2373
2379UINTN
2381 VOID
2382 )
2383{
2384 UINTN TempStackOffset;
2385
2386 TempStackOffset = mExpressionEvaluationStackOffset;
2387 mExpressionEvaluationStackOffset = mExpressionEvaluationStackPointer - mExpressionEvaluationStack;
2388 return TempStackOffset;
2389}
2390
2397VOID
2399 UINTN StackOffset
2400 )
2401{
2402 mExpressionEvaluationStackOffset = StackOffset;
2403}
2404
2418 IN HII_FORMSET *FormSet,
2419 IN UINT8 Format,
2420 OUT EFI_HII_VALUE *Result
2421 )
2422{
2423 EFI_STATUS Status;
2424 EFI_HII_VALUE Value;
2425 CHAR16 *String;
2426 CHAR16 *PrintFormat;
2427 CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];
2428 UINT8 *SrcBuf;
2429 UINTN BufferSize;
2430
2431 if ((FormSet == NULL) || (Result == NULL)) {
2432 return EFI_INVALID_PARAMETER;
2433 }
2434
2435 Status = PopExpression (&Value);
2436 if (EFI_ERROR (Status)) {
2437 return Status;
2438 }
2439
2440 switch (Value.Type) {
2441 case EFI_IFR_TYPE_NUM_SIZE_8:
2442 case EFI_IFR_TYPE_NUM_SIZE_16:
2443 case EFI_IFR_TYPE_NUM_SIZE_32:
2444 case EFI_IFR_TYPE_NUM_SIZE_64:
2445 BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);
2446 switch (Format) {
2448 case EFI_IFR_STRING_SIGNED_DEC:
2449 PrintFormat = L"%ld";
2450 break;
2451
2452 case EFI_IFR_STRING_LOWERCASE_HEX:
2453 PrintFormat = L"%lx";
2454 break;
2455
2456 case EFI_IFR_STRING_UPPERCASE_HEX:
2457 PrintFormat = L"%lX";
2458 break;
2459
2460 default:
2461 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2462 return EFI_SUCCESS;
2463 }
2464
2465 UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);
2466 String = Buffer;
2467 break;
2468
2469 case EFI_IFR_TYPE_STRING:
2470 CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
2471 return EFI_SUCCESS;
2472
2473 case EFI_IFR_TYPE_BOOLEAN:
2474 String = (Value.Value.b) ? L"True" : L"False";
2475 break;
2476
2477 case EFI_IFR_TYPE_BUFFER:
2478 case EFI_IFR_TYPE_DATE:
2479 case EFI_IFR_TYPE_TIME:
2480 case EFI_IFR_TYPE_REF:
2481 //
2482 // + 3 is base on the unicode format, the length may be odd number,
2483 // so need 1 byte to align, also need 2 bytes for L'\0'.
2484 //
2485 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
2486 SrcBuf = Value.Buffer;
2487 } else {
2488 SrcBuf = GetBufferForValue (&Value);
2489 }
2490
2491 if (Format == EFI_IFR_STRING_ASCII) {
2492 PrintFormat = L"%a";
2493 } else {
2494 // Format == EFI_IFR_STRING_UNICODE
2495 PrintFormat = L"%s";
2496 }
2497
2498 UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, SrcBuf);
2499 String = Buffer;
2500 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
2501 FreePool (Value.Buffer);
2502 }
2503
2504 break;
2505
2506 default:
2507 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2508 return EFI_SUCCESS;
2509 }
2510
2511 Result->Type = EFI_IFR_TYPE_STRING;
2512 Result->Value.string = NewHiiString (String, FormSet->HiiHandle);
2513 return EFI_SUCCESS;
2514}
2515
2528 IN HII_FORMSET *FormSet,
2529 OUT EFI_HII_VALUE *Result
2530 )
2531{
2532 EFI_STATUS Status;
2533 EFI_HII_VALUE Value;
2534 CHAR16 *String;
2535 CHAR16 *StringPtr;
2536
2537 if ((FormSet == NULL) || (Result == NULL)) {
2538 return EFI_INVALID_PARAMETER;
2539 }
2540
2541 Status = PopExpression (&Value);
2542 if (EFI_ERROR (Status)) {
2543 return Status;
2544 }
2545
2546 if ((Value.Type >= EFI_IFR_TYPE_OTHER) && !IsTypeInBuffer (&Value)) {
2547 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2548 return EFI_SUCCESS;
2549 }
2550
2551 Status = EFI_SUCCESS;
2552 if (Value.Type == EFI_IFR_TYPE_STRING) {
2553 String = GetTokenString (Value.Value.string, FormSet->HiiHandle);
2554 if (String == NULL) {
2555 return EFI_NOT_FOUND;
2556 }
2557
2558 IfrStrToUpper (String);
2559 StringPtr = StrStr (String, L"0X");
2560 if (StringPtr != NULL) {
2561 //
2562 // Hex string
2563 //
2564 Result->Value.u64 = StrHexToUint64 (String);
2565 } else {
2566 //
2567 // decimal string
2568 //
2569 Result->Value.u64 = StrDecimalToUint64 (String);
2570 }
2571
2572 FreePool (String);
2573 } else if (IsTypeInBuffer (&Value)) {
2574 if (GetLengthForValue (&Value) > 8) {
2575 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
2576 FreePool (Value.Buffer);
2577 }
2578
2579 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2580 return EFI_SUCCESS;
2581 }
2582
2583 Result->Value.u64 = *(UINT64 *)GetBufferForValue (&Value);
2584 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
2585 FreePool (Value.Buffer);
2586 }
2587 } else {
2588 CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
2589 }
2590
2591 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;
2592 return Status;
2593}
2594
2607 IN HII_FORMSET *FormSet,
2608 OUT EFI_HII_VALUE *Result
2609 )
2610{
2611 EFI_STATUS Status;
2612 EFI_HII_VALUE Value[2];
2613 CHAR16 *String[2];
2614 UINTN Index;
2615 CHAR16 *StringPtr;
2616 UINTN Size;
2617 UINT16 Length0;
2618 UINT16 Length1;
2619 UINT8 *TmpBuf;
2620 UINTN MaxLen;
2621
2622 if ((FormSet == NULL) || (Result == NULL)) {
2623 return EFI_INVALID_PARAMETER;
2624 }
2625
2626 //
2627 // String[0] - The second string
2628 // String[1] - The first string
2629 //
2630 String[0] = NULL;
2631 String[1] = NULL;
2632 StringPtr = NULL;
2633 Status = EFI_SUCCESS;
2634 ZeroMem (Value, sizeof (Value));
2635
2636 Status = PopExpression (&Value[0]);
2637 if (EFI_ERROR (Status)) {
2638 goto Done;
2639 }
2640
2641 Status = PopExpression (&Value[1]);
2642 if (EFI_ERROR (Status)) {
2643 goto Done;
2644 }
2645
2646 for (Index = 0; Index < 2; Index++) {
2647 if ((Value[Index].Type != EFI_IFR_TYPE_STRING) && !IsTypeInBuffer (&Value[Index])) {
2648 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2649 Status = EFI_SUCCESS;
2650 goto Done;
2651 }
2652
2653 if (Value[Index].Type == EFI_IFR_TYPE_STRING) {
2654 String[Index] = GetTokenString (Value[Index].Value.string, FormSet->HiiHandle);
2655 if (String[Index] == NULL) {
2656 Status = EFI_NOT_FOUND;
2657 goto Done;
2658 }
2659 }
2660 }
2661
2662 if (Value[0].Type == EFI_IFR_TYPE_STRING) {
2663 Size = StrSize (String[0]);
2664 MaxLen = (StrSize (String[1]) + Size) / sizeof (CHAR16);
2665 StringPtr = AllocatePool (MaxLen * sizeof (CHAR16));
2666 ASSERT (StringPtr != NULL);
2667 StrCpyS (StringPtr, MaxLen, String[1]);
2668 StrCatS (StringPtr, MaxLen, String[0]);
2669
2670 Result->Type = EFI_IFR_TYPE_STRING;
2671 Result->Value.string = NewHiiString (StringPtr, FormSet->HiiHandle);
2672 } else {
2673 Result->Type = EFI_IFR_TYPE_BUFFER;
2674 Length0 = GetLengthForValue (&Value[0]);
2675 Length1 = GetLengthForValue (&Value[1]);
2676 Result->BufferLen = (UINT16)(Length0 + Length1);
2677
2678 Result->Buffer = AllocatePool (Result->BufferLen);
2679 ASSERT (Result->Buffer != NULL);
2680
2681 TmpBuf = GetBufferForValue (&Value[0]);
2682 ASSERT (TmpBuf != NULL);
2683 CopyMem (Result->Buffer, TmpBuf, Length0);
2684 TmpBuf = GetBufferForValue (&Value[1]);
2685 ASSERT (TmpBuf != NULL);
2686 CopyMem (&Result->Buffer[Length0], TmpBuf, Length1);
2687 }
2688
2689Done:
2690 if (Value[0].Buffer != NULL) {
2691 FreePool (Value[0].Buffer);
2692 }
2693
2694 if (Value[1].Buffer != NULL) {
2695 FreePool (Value[1].Buffer);
2696 }
2697
2698 if (String[0] != NULL) {
2699 FreePool (String[0]);
2700 }
2701
2702 if (String[1] != NULL) {
2703 FreePool (String[1]);
2704 }
2705
2706 if (StringPtr != NULL) {
2707 FreePool (StringPtr);
2708 }
2709
2710 return Status;
2711}
2712
2725 IN HII_FORMSET *FormSet,
2726 OUT EFI_HII_VALUE *Result
2727 )
2728{
2729 EFI_STATUS Status;
2730 EFI_HII_VALUE Value[2];
2731 CHAR16 *String[2];
2732 UINTN Index;
2733
2734 if ((FormSet == NULL) || (Result == NULL)) {
2735 return EFI_INVALID_PARAMETER;
2736 }
2737
2738 //
2739 // String[0] - The string to search
2740 // String[1] - pattern
2741 //
2742 String[0] = NULL;
2743 String[1] = NULL;
2744 Status = EFI_SUCCESS;
2745 ZeroMem (Value, sizeof (Value));
2746
2747 Status = PopExpression (&Value[0]);
2748 if (EFI_ERROR (Status)) {
2749 goto Done;
2750 }
2751
2752 Status = PopExpression (&Value[1]);
2753 if (EFI_ERROR (Status)) {
2754 goto Done;
2755 }
2756
2757 for (Index = 0; Index < 2; Index++) {
2758 if (Value[Index].Type != EFI_IFR_TYPE_STRING) {
2759 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2760 Status = EFI_SUCCESS;
2761 goto Done;
2762 }
2763
2764 String[Index] = GetTokenString (Value[Index].Value.string, FormSet->HiiHandle);
2765 if (String[Index] == NULL) {
2766 Status = EFI_NOT_FOUND;
2767 goto Done;
2768 }
2769 }
2770
2771 Result->Type = EFI_IFR_TYPE_BOOLEAN;
2772 Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);
2773
2774Done:
2775 if (String[0] != NULL) {
2776 FreePool (String[0]);
2777 }
2778
2779 if (String[1] != NULL) {
2780 FreePool (String[1]);
2781 }
2782
2783 return Status;
2784}
2785
2799 IN HII_FORMSET *FormSet,
2800 IN EFI_GUID *SyntaxType,
2801 OUT EFI_HII_VALUE *Result
2802 )
2803{
2804 EFI_STATUS Status;
2805 EFI_HII_VALUE Value[2];
2806 CHAR16 *String[2];
2807 UINTN Index;
2808 UINTN GuidIndex;
2809 EFI_HANDLE *HandleBuffer;
2810 UINTN BufferSize;
2811 EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
2812 UINTN RegExSyntaxTypeListSize;
2813 EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList;
2814 UINTN CapturesCount;
2815
2816 if ((FormSet == NULL) || (SyntaxType == NULL) || (Result == NULL)) {
2817 return EFI_INVALID_PARAMETER;
2818 }
2819
2820 //
2821 // String[0] - The string to search
2822 // String[1] - pattern
2823 //
2824 String[0] = NULL;
2825 String[1] = NULL;
2826 HandleBuffer = NULL;
2827 RegExSyntaxTypeList = NULL;
2828 Status = EFI_SUCCESS;
2829 ZeroMem (Value, sizeof (Value));
2830
2831 Status = PopExpression (&Value[0]);
2832 if (EFI_ERROR (Status)) {
2833 goto Done;
2834 }
2835
2836 Status = PopExpression (&Value[1]);
2837 if (EFI_ERROR (Status)) {
2838 goto Done;
2839 }
2840
2841 for (Index = 0; Index < 2; Index++) {
2842 if (Value[Index].Type != EFI_IFR_TYPE_STRING) {
2843 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2844 Status = EFI_SUCCESS;
2845 goto Done;
2846 }
2847
2848 String[Index] = GetTokenString (Value[Index].Value.string, FormSet->HiiHandle);
2849 if (String[Index] == NULL) {
2850 Status = EFI_NOT_FOUND;
2851 goto Done;
2852 }
2853 }
2854
2855 BufferSize = 0;
2856 HandleBuffer = NULL;
2857 Status = gBS->LocateHandle (
2858 ByProtocol,
2859 &gEfiRegularExpressionProtocolGuid,
2860 NULL,
2861 &BufferSize,
2862 HandleBuffer
2863 );
2864 if (Status == EFI_BUFFER_TOO_SMALL) {
2865 HandleBuffer = AllocatePool (BufferSize);
2866 if (HandleBuffer == NULL) {
2867 Status = EFI_OUT_OF_RESOURCES;
2868 goto Done;
2869 }
2870
2871 Status = gBS->LocateHandle (
2872 ByProtocol,
2873 &gEfiRegularExpressionProtocolGuid,
2874 NULL,
2875 &BufferSize,
2876 HandleBuffer
2877 );
2878 }
2879
2880 if (EFI_ERROR (Status)) {
2881 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2882 Status = EFI_SUCCESS;
2883 goto Done;
2884 }
2885
2886 ASSERT (HandleBuffer != NULL);
2887 for ( Index = 0; Index < BufferSize / sizeof (EFI_HANDLE); Index++) {
2888 Status = gBS->HandleProtocol (
2889 HandleBuffer[Index],
2890 &gEfiRegularExpressionProtocolGuid,
2891 (VOID **)&RegularExpressionProtocol
2892 );
2893 if (EFI_ERROR (Status)) {
2894 goto Done;
2895 }
2896
2897 RegExSyntaxTypeListSize = 0;
2898 RegExSyntaxTypeList = NULL;
2899
2900 Status = RegularExpressionProtocol->GetInfo (
2901 RegularExpressionProtocol,
2902 &RegExSyntaxTypeListSize,
2903 RegExSyntaxTypeList
2904 );
2905 if (Status == EFI_BUFFER_TOO_SMALL) {
2906 RegExSyntaxTypeList = AllocatePool (RegExSyntaxTypeListSize);
2907 if (RegExSyntaxTypeList == NULL) {
2908 Status = EFI_OUT_OF_RESOURCES;
2909 goto Done;
2910 }
2911
2912 Status = RegularExpressionProtocol->GetInfo (
2913 RegularExpressionProtocol,
2914 &RegExSyntaxTypeListSize,
2915 RegExSyntaxTypeList
2916 );
2917 } else if (EFI_ERROR (Status)) {
2918 goto Done;
2919 }
2920
2921 for (GuidIndex = 0; GuidIndex < RegExSyntaxTypeListSize / sizeof (EFI_GUID); GuidIndex++) {
2922 if (CompareGuid (&RegExSyntaxTypeList[GuidIndex], SyntaxType)) {
2923 //
2924 // Find the match type, return the value.
2925 //
2926 Result->Type = EFI_IFR_TYPE_BOOLEAN;
2927 Status = RegularExpressionProtocol->MatchString (
2928 RegularExpressionProtocol,
2929 String[0],
2930 String[1],
2931 SyntaxType,
2932 &Result->Value.b,
2933 NULL,
2934 &CapturesCount
2935 );
2936 goto Done;
2937 }
2938 }
2939
2940 if (RegExSyntaxTypeList != NULL) {
2941 FreePool (RegExSyntaxTypeList);
2942 }
2943 }
2944
2945 //
2946 // Type specified by SyntaxType is not supported
2947 // in any of the EFI_REGULAR_EXPRESSION_PROTOCOL instances.
2948 //
2949 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2950 Status = EFI_SUCCESS;
2951
2952Done:
2953 if (String[0] != NULL) {
2954 FreePool (String[0]);
2955 }
2956
2957 if (String[1] != NULL) {
2958 FreePool (String[1]);
2959 }
2960
2961 if (RegExSyntaxTypeList != NULL) {
2962 FreePool (RegExSyntaxTypeList);
2963 }
2964
2965 if (HandleBuffer != NULL) {
2966 FreePool (HandleBuffer);
2967 }
2968
2969 return Status;
2970}
2971
2985 IN HII_FORMSET *FormSet,
2986 IN UINT8 Format,
2987 OUT EFI_HII_VALUE *Result
2988 )
2989{
2990 EFI_STATUS Status;
2991 EFI_HII_VALUE Value[3];
2992 CHAR16 *String[2];
2993 UINTN Base;
2994 CHAR16 *StringPtr;
2995 UINTN Index;
2996
2997 if ((FormSet == NULL) || (Result == NULL)) {
2998 return EFI_INVALID_PARAMETER;
2999 }
3000
3001 ZeroMem (Value, sizeof (Value));
3002
3003 if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {
3004 return EFI_INVALID_PARAMETER;
3005 }
3006
3007 Status = PopExpression (&Value[0]);
3008 if (EFI_ERROR (Status)) {
3009 return Status;
3010 }
3011
3012 Status = PopExpression (&Value[1]);
3013 if (EFI_ERROR (Status)) {
3014 return Status;
3015 }
3016
3017 Status = PopExpression (&Value[2]);
3018 if (EFI_ERROR (Status)) {
3019 return Status;
3020 }
3021
3022 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
3023 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3024 return EFI_SUCCESS;
3025 }
3026
3027 Base = (UINTN)Value[0].Value.u64;
3028
3029 //
3030 // String[0] - sub-string
3031 // String[1] - The string to search
3032 //
3033 String[0] = NULL;
3034 String[1] = NULL;
3035 for (Index = 0; Index < 2; Index++) {
3036 if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
3037 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3038 Status = EFI_SUCCESS;
3039 goto Done;
3040 }
3041
3042 String[Index] = GetTokenString (Value[Index + 1].Value.string, FormSet->HiiHandle);
3043 if (String[Index] == NULL) {
3044 Status = EFI_NOT_FOUND;
3045 goto Done;
3046 }
3047
3048 if (Format == EFI_IFR_FF_CASE_INSENSITIVE) {
3049 //
3050 // Case insensitive, convert both string to upper case
3051 //
3052 IfrStrToUpper (String[Index]);
3053 }
3054 }
3055
3056 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;
3057 if (Base >= StrLen (String[1])) {
3058 Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL;
3059 } else {
3060 StringPtr = StrStr (String[1] + Base, String[0]);
3061 Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]);
3062 }
3063
3064Done:
3065 if (String[0] != NULL) {
3066 FreePool (String[0]);
3067 }
3068
3069 if (String[1] != NULL) {
3070 FreePool (String[1]);
3071 }
3072
3073 return Status;
3074}
3075
3088 IN HII_FORMSET *FormSet,
3089 OUT EFI_HII_VALUE *Result
3090 )
3091{
3092 EFI_STATUS Status;
3093 EFI_HII_VALUE Value[3];
3094 CHAR16 *String;
3095 UINTN Base;
3096 UINTN Length;
3097 CHAR16 *SubString;
3098 UINT16 BufferLen;
3099 UINT8 *Buffer;
3100
3101 if ((FormSet == NULL) || (Result == NULL)) {
3102 return EFI_INVALID_PARAMETER;
3103 }
3104
3105 ZeroMem (Value, sizeof (Value));
3106
3107 Status = PopExpression (&Value[0]);
3108 if (EFI_ERROR (Status)) {
3109 return Status;
3110 }
3111
3112 Status = PopExpression (&Value[1]);
3113 if (EFI_ERROR (Status)) {
3114 return Status;
3115 }
3116
3117 Status = PopExpression (&Value[2]);
3118 if (EFI_ERROR (Status)) {
3119 return Status;
3120 }
3121
3122 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
3123 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3124 return EFI_SUCCESS;
3125 }
3126
3127 Length = (UINTN)Value[0].Value.u64;
3128
3129 if (Value[1].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
3130 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3131 return EFI_SUCCESS;
3132 }
3133
3134 Base = (UINTN)Value[1].Value.u64;
3135
3136 if ((Value[2].Type != EFI_IFR_TYPE_STRING) && !IsTypeInBuffer (&Value[2])) {
3137 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3138 return EFI_SUCCESS;
3139 }
3140
3141 if (Value[2].Type == EFI_IFR_TYPE_STRING) {
3142 String = GetTokenString (Value[2].Value.string, FormSet->HiiHandle);
3143 if (String == NULL) {
3144 return EFI_NOT_FOUND;
3145 }
3146
3147 if ((Length == 0) || (Base >= StrLen (String))) {
3148 SubString = gEmptyString;
3149 } else {
3150 SubString = String + Base;
3151 if ((Base + Length) < StrLen (String)) {
3152 SubString[Length] = L'\0';
3153 }
3154 }
3155
3156 Result->Type = EFI_IFR_TYPE_STRING;
3157 Result->Value.string = NewHiiString (SubString, FormSet->HiiHandle);
3158
3159 FreePool (String);
3160 } else {
3161 BufferLen = GetLengthForValue (&Value[2]);
3162 Buffer = GetBufferForValue (&Value[2]);
3163
3164 Result->Type = EFI_IFR_TYPE_BUFFER;
3165 if ((Length == 0) || (Base >= BufferLen)) {
3166 Result->BufferLen = 0;
3167 Result->Buffer = NULL;
3168 } else {
3169 Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length);
3170 Result->Buffer = AllocatePool (Result->BufferLen);
3171 ASSERT (Result->Buffer != NULL);
3172 CopyMem (Result->Buffer, &Buffer[Base], Result->BufferLen);
3173 }
3174
3175 if (Value[2].Type == EFI_IFR_TYPE_BUFFER) {
3176 FreePool (Value[2].Buffer);
3177 }
3178 }
3179
3180 return Status;
3181}
3182
3195 IN HII_FORMSET *FormSet,
3196 OUT EFI_HII_VALUE *Result
3197 )
3198{
3199 EFI_STATUS Status;
3200 EFI_HII_VALUE Value[3];
3201 CHAR16 *String[2];
3202 UINTN Count;
3203 CHAR16 *Delimiter;
3204 CHAR16 *SubString;
3205 CHAR16 *StringPtr;
3206 UINTN Index;
3207
3208 if ((FormSet == NULL) || (Result == NULL)) {
3209 return EFI_INVALID_PARAMETER;
3210 }
3211
3212 ZeroMem (Value, sizeof (Value));
3213
3214 Status = PopExpression (&Value[0]);
3215 if (EFI_ERROR (Status)) {
3216 return Status;
3217 }
3218
3219 Status = PopExpression (&Value[1]);
3220 if (EFI_ERROR (Status)) {
3221 return Status;
3222 }
3223
3224 Status = PopExpression (&Value[2]);
3225 if (EFI_ERROR (Status)) {
3226 return Status;
3227 }
3228
3229 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
3230 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3231 return EFI_SUCCESS;
3232 }
3233
3234 Count = (UINTN)Value[0].Value.u64;
3235
3236 //
3237 // String[0] - Delimiter
3238 // String[1] - The string to search
3239 //
3240 String[0] = NULL;
3241 String[1] = NULL;
3242 for (Index = 0; Index < 2; Index++) {
3243 if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
3244 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3245 Status = EFI_SUCCESS;
3246 goto Done;
3247 }
3248
3249 String[Index] = GetTokenString (Value[Index + 1].Value.string, FormSet->HiiHandle);
3250 if (String[Index] == NULL) {
3251 Status = EFI_NOT_FOUND;
3252 goto Done;
3253 }
3254 }
3255
3256 Delimiter = String[0];
3257 SubString = String[1];
3258 while (Count > 0) {
3259 SubString = StrStr (SubString, Delimiter);
3260 if (SubString != NULL) {
3261 //
3262 // Skip over the delimiter
3263 //
3264 SubString = SubString + StrLen (Delimiter);
3265 } else {
3266 break;
3267 }
3268
3269 Count--;
3270 }
3271
3272 if (SubString == NULL) {
3273 //
3274 // nth delimited sub-string not found, push an empty string
3275 //
3276 SubString = gEmptyString;
3277 } else {
3278 //
3279 // Put a NULL terminator for nth delimited sub-string
3280 //
3281 StringPtr = StrStr (SubString, Delimiter);
3282 if (StringPtr != NULL) {
3283 *StringPtr = L'\0';
3284 }
3285 }
3286
3287 Result->Type = EFI_IFR_TYPE_STRING;
3288 Result->Value.string = NewHiiString (SubString, FormSet->HiiHandle);
3289
3290Done:
3291 if (String[0] != NULL) {
3292 FreePool (String[0]);
3293 }
3294
3295 if (String[1] != NULL) {
3296 FreePool (String[1]);
3297 }
3298
3299 return Status;
3300}
3301
3315 IN HII_FORMSET *FormSet,
3316 IN UINT8 Flags,
3317 OUT EFI_HII_VALUE *Result
3318 )
3319{
3320 EFI_STATUS Status;
3321 EFI_HII_VALUE Value[3];
3322 CHAR16 *String[2];
3323 CHAR16 *Charset;
3324 UINTN Base;
3325 UINTN Index;
3326 CHAR16 *StringPtr;
3327 BOOLEAN Found;
3328
3329 if ((FormSet == NULL) || (Result == NULL)) {
3330 return EFI_INVALID_PARAMETER;
3331 }
3332
3333 ZeroMem (Value, sizeof (Value));
3334
3335 Status = PopExpression (&Value[0]);
3336 if (EFI_ERROR (Status)) {
3337 return Status;
3338 }
3339
3340 Status = PopExpression (&Value[1]);
3341 if (EFI_ERROR (Status)) {
3342 return Status;
3343 }
3344
3345 Status = PopExpression (&Value[2]);
3346 if (EFI_ERROR (Status)) {
3347 return Status;
3348 }
3349
3350 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
3351 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3352 return EFI_SUCCESS;
3353 }
3354
3355 Base = (UINTN)Value[0].Value.u64;
3356
3357 //
3358 // String[0] - Charset
3359 // String[1] - The string to search
3360 //
3361 String[0] = NULL;
3362 String[1] = NULL;
3363 for (Index = 0; Index < 2; Index++) {
3364 if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
3365 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3366 Status = EFI_SUCCESS;
3367 goto Done;
3368 }
3369
3370 String[Index] = GetTokenString (Value[Index + 1].Value.string, FormSet->HiiHandle);
3371 if (String[Index] == NULL) {
3372 Status = EFI_NOT_FOUND;
3373 goto Done;
3374 }
3375 }
3376
3377 if (Base >= StrLen (String[1])) {
3378 Result->Type = EFI_IFR_TYPE_UNDEFINED;
3379 Status = EFI_SUCCESS;
3380 goto Done;
3381 }
3382
3383 Found = FALSE;
3384 StringPtr = String[1] + Base;
3385 Charset = String[0];
3386 while (*StringPtr != 0 && !Found) {
3387 Index = 0;
3388 while (Charset[Index] != 0) {
3389 if ((*StringPtr >= Charset[Index]) && (*StringPtr <= Charset[Index + 1])) {
3390 if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) {
3391 Found = TRUE;
3392 break;
3393 }
3394 } else {
3395 if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) {
3396 Found = TRUE;
3397 break;
3398 }
3399 }
3400
3401 //
3402 // Skip characters pair representing low-end of a range and high-end of a range
3403 //
3404 Index += 2;
3405 }
3406
3407 if (!Found) {
3408 StringPtr++;
3409 }
3410 }
3411
3412 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;
3413 Result->Value.u64 = StringPtr - String[1];
3414
3415Done:
3416 if (String[0] != NULL) {
3417 FreePool (String[0]);
3418 }
3419
3420 if (String[1] != NULL) {
3421 FreePool (String[1]);
3422 }
3423
3424 return Status;
3425}
3426
3439 IN HII_FORM *Form,
3440 IN UINT8 RuleId
3441 )
3442{
3443 LIST_ENTRY *Link;
3444 HII_EXPRESSION *Expression;
3445
3446 if (Form == NULL) {
3447 return NULL;
3448 }
3449
3450 Link = GetFirstNode (&Form->RuleListHead);
3451 while (!IsNull (&Form->RuleListHead, Link)) {
3452 Expression = HII_EXPRESSION_FROM_LINK (Link);
3453
3454 if ((Expression->Type == EFI_HII_EXPRESSION_RULE) && (Expression->ExtraData.RuleId == RuleId)) {
3455 return Expression;
3456 }
3457
3458 Link = GetNextNode (&Form->RuleListHead, Link);
3459 }
3460
3461 return NULL;
3462}
3463
3473 VOID
3474 )
3475{
3476 EFI_STATUS Status;
3477
3478 if (mUnicodeCollation != NULL) {
3479 return EFI_SUCCESS;
3480 }
3481
3482 //
3483 // BUGBUG: Proper implementation is to locate all Unicode Collation Protocol
3484 // instances first and then select one which support English language.
3485 // Current implementation just pick the first instance.
3486 //
3487 Status = gBS->LocateProtocol (
3488 &gEfiUnicodeCollation2ProtocolGuid,
3489 NULL,
3490 (VOID **)&mUnicodeCollation
3491 );
3492 return Status;
3493}
3494
3505BOOLEAN
3507 IN EFI_HII_HANDLE HiiHandle,
3508 IN EFI_GUID *FormSetGuid
3509 )
3510{
3511 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
3512 UINTN BufferSize;
3513 UINT32 Offset;
3514 UINT32 Offset2;
3515 UINT32 PackageListLength;
3516 EFI_HII_PACKAGE_HEADER *PackageHeader;
3517 UINT8 *Package;
3518 UINT8 *OpCodeData;
3519 EFI_STATUS Status;
3520 BOOLEAN FindGuid;
3521 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
3522
3523 if (FormSetGuid == NULL) {
3524 return FALSE;
3525 }
3526
3527 BufferSize = 0;
3528 HiiPackageList = NULL;
3529 FindGuid = FALSE;
3530
3531 //
3532 // Locate required Hii Database protocol
3533 //
3534 Status = gBS->LocateProtocol (
3535 &gEfiHiiDatabaseProtocolGuid,
3536 NULL,
3537 (VOID **)&HiiDatabase
3538 );
3539 if (EFI_ERROR (Status)) {
3540 return FALSE;
3541 }
3542
3543 Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
3544 if (Status == EFI_BUFFER_TOO_SMALL) {
3545 HiiPackageList = AllocatePool (BufferSize);
3546 if (HiiPackageList == NULL) {
3547 ASSERT (HiiPackageList != NULL);
3548 return FALSE;
3549 }
3550
3551 Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
3552 } else {
3553 //
3554 // Fix coverity: 14253 Explicit null dereferenced.
3555 // When calling ExportPackageLists with BufferSize = 0, only EFI_BUFFER_TOO_SMALL is expected.
3556 // Otherwise, return FALSE immediately.
3557 //
3558 return FALSE;
3559 }
3560
3561 if (EFI_ERROR (Status)) {
3562 if (HiiPackageList != NULL) {
3563 FreePool (HiiPackageList);
3564 }
3565
3566 return FALSE;
3567 }
3568
3569 //
3570 // Get Form package from this HII package List
3571 //
3572 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
3573 Offset2 = 0;
3574 PackageListLength = HiiPackageList->PackageLength;
3575
3576 while (Offset < PackageListLength) {
3577 Package = ((UINT8 *)HiiPackageList) + Offset;
3578 PackageHeader = (EFI_HII_PACKAGE_HEADER *)Package;
3579 Offset += PackageHeader->Length;
3580
3581 if (PackageHeader->Type == EFI_HII_PACKAGE_FORMS) {
3582 //
3583 // Search FormSet in this Form Package
3584 //
3585 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
3586 while (Offset2 < PackageHeader->Length) {
3587 OpCodeData = Package + Offset2;
3588
3589 if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
3590 if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
3591 FindGuid = TRUE;
3592 break;
3593 }
3594 }
3595
3596 Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
3597 }
3598 }
3599
3600 if (FindGuid) {
3601 break;
3602 }
3603 }
3604
3605 FreePool (HiiPackageList);
3606
3607 return FindGuid;
3608}
3609
3626 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
3627 IN EFI_GUID *FormsetGuid
3628 )
3629{
3630 EFI_STATUS Status;
3631 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
3632 UINTN Index;
3633 EFI_HANDLE Handle;
3634 EFI_HANDLE DriverHandle;
3635 EFI_HII_HANDLE *HiiHandles;
3636 EFI_HII_HANDLE HiiHandle;
3637 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
3638
3639 if ((DevicePath == NULL) || (FormsetGuid == NULL)) {
3640 return NULL;
3641 }
3642
3643 TmpDevicePath = DevicePath;
3644 //
3645 // Locate Device Path Protocol handle buffer
3646 //
3647 Status = gBS->LocateDevicePath (
3648 &gEfiDevicePathProtocolGuid,
3649 &TmpDevicePath,
3650 &DriverHandle
3651 );
3652 if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {
3653 return NULL;
3654 }
3655
3656 //
3657 // Locate required Hii Database protocol
3658 //
3659 Status = gBS->LocateProtocol (
3660 &gEfiHiiDatabaseProtocolGuid,
3661 NULL,
3662 (VOID **)&HiiDatabase
3663 );
3664 if (EFI_ERROR (Status)) {
3665 return NULL;
3666 }
3667
3668 //
3669 // Retrieve all HII Handles from HII database
3670 //
3671 HiiHandles = HiiGetHiiHandles (NULL);
3672 if (HiiHandles == NULL) {
3673 return NULL;
3674 }
3675
3676 //
3677 // Search Hii Handle by Driver Handle
3678 //
3679 HiiHandle = NULL;
3680 for (Index = 0; HiiHandles[Index] != NULL; Index++) {
3681 Status = HiiDatabase->GetPackageListHandle (
3682 HiiDatabase,
3683 HiiHandles[Index],
3684 &Handle
3685 );
3686 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
3687 if (IsFormsetGuidInHiiHandle (HiiHandles[Index], FormsetGuid)) {
3688 HiiHandle = HiiHandles[Index];
3689 break;
3690 }
3691
3692 if (HiiHandle != NULL) {
3693 break;
3694 }
3695 }
3696 }
3697
3698 FreePool (HiiHandles);
3699 return HiiHandle;
3700}
3701
3714BOOLEAN
3716 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
3717 IN EFI_HII_HANDLE InputHiiHandle,
3718 IN EFI_GUID *FormSetGuid,
3719 IN EFI_QUESTION_ID QuestionId,
3720 OUT EFI_HII_VALUE *Value
3721 )
3722{
3723 EFI_STATUS Status;
3724 EFI_HII_HANDLE HiiHandle;
3725 HII_STATEMENT *Question;
3726 HII_FORMSET *FormSet;
3727 HII_FORM *Form;
3728 BOOLEAN GetTheVal;
3729 LIST_ENTRY *Link;
3730
3731 //
3732 // The input parameter DevicePath or InputHiiHandle must have one valid input.
3733 //
3734 if ((DevicePath == NULL) && (InputHiiHandle == NULL)) {
3735 ASSERT (
3736 (DevicePath != NULL && InputHiiHandle == NULL) ||
3737 (DevicePath == NULL && InputHiiHandle != NULL)
3738 );
3739 return FALSE;
3740 }
3741
3742 if ((FormSetGuid == NULL) || (Value == NULL)) {
3743 return FALSE;
3744 }
3745
3746 GetTheVal = TRUE;
3747 HiiHandle = NULL;
3748 Question = NULL;
3749 Form = NULL;
3750
3751 //
3752 // Get HiiHandle.
3753 //
3754 if (DevicePath != NULL) {
3755 HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);
3756 if (HiiHandle == NULL) {
3757 return FALSE;
3758 }
3759 } else {
3760 HiiHandle = InputHiiHandle;
3761 }
3762
3763 ASSERT (HiiHandle != NULL);
3764
3765 //
3766 // Get the formset data include this question.
3767 //
3768 FormSet = AllocateZeroPool (sizeof (HII_FORMSET));
3769 ASSERT (FormSet != NULL);
3770
3771 Status = CreateFormSetFromHiiHandle (HiiHandle, FormSetGuid, FormSet);
3772 if (EFI_ERROR (Status)) {
3773 GetTheVal = FALSE;
3774 goto Done;
3775 }
3776
3777 InitializeFormSet (FormSet);
3778
3779 //
3780 // Base on the Question Id to get the question info.
3781 //
3782 Question = QuestionIdInFormset (FormSet, NULL, QuestionId);
3783 if (Question == NULL) {
3784 GetTheVal = FALSE;
3785 goto Done;
3786 }
3787
3788 //
3789 // Search form in the formset scope
3790 //
3791 Link = GetFirstNode (&FormSet->FormListHead);
3792 while (!IsNull (&FormSet->FormListHead, Link)) {
3793 Form = HII_FORM_FROM_LINK (Link);
3794
3795 Question = QuestionIdInForm (Form, QuestionId);
3796 if (Question != NULL) {
3797 break;
3798 }
3799
3800 Link = GetNextNode (&FormSet->FormListHead, Link);
3801 Form = NULL;
3802 }
3803
3804 ASSERT (Form != NULL);
3805
3806 //
3807 // Get the question value.
3808 //
3809 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
3810 if (EFI_ERROR (Status)) {
3811 GetTheVal = FALSE;
3812 goto Done;
3813 }
3814
3815 CopyMem (Value, &Question->Value, sizeof (EFI_HII_VALUE));
3816
3817Done:
3818 //
3819 // Clean the formset structure and restore the global parameter.
3820 //
3821 if (FormSet != NULL) {
3822 DestroyFormSet (FormSet);
3823 }
3824
3825 return GetTheVal;
3826}
3827
3843 IN HII_STATEMENT_VALUE *StatementValue,
3844 OUT EFI_HII_VALUE *HiiValue
3845 )
3846{
3847 if ((StatementValue == NULL) || (HiiValue == NULL)) {
3848 return EFI_INVALID_PARAMETER;
3849 }
3850
3851 ZeroMem (HiiValue, sizeof (EFI_HII_VALUE));
3852
3853 HiiValue->Type = StatementValue->Type;
3854 HiiValue->BufferLen = StatementValue->BufferLen;
3855 if ((StatementValue->Buffer != NULL) && (StatementValue->BufferLen > 0)) {
3856 HiiValue->Buffer = AllocateCopyPool (HiiValue->BufferLen, StatementValue->Buffer);
3857 }
3858
3859 CopyMem (&HiiValue->Value, &StatementValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
3860
3861 return EFI_SUCCESS;
3862}
3863
3875 IN EFI_HII_VALUE *HiiValue
3876 )
3877{
3878 if (HiiValue == NULL) {
3879 return EFI_INVALID_PARAMETER;
3880 }
3881
3882 if (HiiValue->Buffer == NULL) {
3883 return EFI_SUCCESS;
3884 }
3885
3886 FreePool (HiiValue->Buffer);
3887 ZeroMem (HiiValue, sizeof (EFI_HII_VALUE));
3888
3889 return EFI_SUCCESS;
3890}
3891
3913 IN HII_FORMSET *FormSet,
3914 IN HII_FORM *Form,
3915 IN OUT HII_EXPRESSION *Expression
3916 )
3917{
3918 EFI_STATUS Status;
3919 LIST_ENTRY *Link;
3920 HII_EXPRESSION_OPCODE *OpCode;
3921 HII_STATEMENT *Question;
3922 HII_STATEMENT *Question2;
3923 UINT16 Index;
3924 EFI_HII_VALUE Data1;
3925 EFI_HII_VALUE Data2;
3926 EFI_HII_VALUE Data3;
3927 HII_EXPRESSION *RuleExpression;
3928 EFI_HII_VALUE *Value;
3929 INTN Result;
3930 CHAR16 *StrPtr;
3931 CHAR16 *NameValue;
3932 UINT32 TempValue;
3933 LIST_ENTRY *SubExpressionLink;
3934 HII_EXPRESSION *SubExpression;
3935 UINTN StackOffset;
3936 UINTN TempLength;
3937 CHAR16 TempStr[5];
3938 UINT8 DigitUint8;
3939 UINT8 *TempBuffer;
3940 EFI_TIME EfiTime;
3941 EFI_HII_VALUE QuestionVal;
3942 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
3944
3945 if ((FormSet == NULL) || (Form == NULL) || (Expression == NULL)) {
3946 return EFI_INVALID_PARAMETER;
3947 }
3948
3949 StrPtr = NULL;
3950 DevicePath = NULL;
3951 PathFromText = NULL;
3952
3953 //
3954 // Save current stack offset.
3955 //
3956 StackOffset = SaveExpressionEvaluationStackOffset ();
3957
3958 ASSERT (Expression != NULL);
3959 Expression->Result.Type = EFI_IFR_TYPE_OTHER;
3960
3961 Link = GetFirstNode (&Expression->OpCodeListHead);
3962 while (!IsNull (&Expression->OpCodeListHead, Link)) {
3963 OpCode = HII_EXPRESSION_OPCODE_FROM_LINK (Link);
3964
3965 Link = GetNextNode (&Expression->OpCodeListHead, Link);
3966
3967 ZeroMem (&Data1, sizeof (EFI_HII_VALUE));
3968 ZeroMem (&Data2, sizeof (EFI_HII_VALUE));
3969 ZeroMem (&Data3, sizeof (EFI_HII_VALUE));
3970
3971 Value = &Data3;
3972 Value->Type = EFI_IFR_TYPE_BOOLEAN;
3973 Status = EFI_SUCCESS;
3974
3975 switch (OpCode->Operand) {
3976 //
3977 // Built-in functions
3978 //
3979 case EFI_IFR_EQ_ID_VAL_OP:
3980 Question = QuestionIdInFormset (FormSet, Form, OpCode->ExtraData.EqIdValData.QuestionId);
3981 if (Question == NULL) {
3982 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3983 break;
3984 }
3985
3986 //
3987 // Load value from storage.
3988 //
3989 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
3990 if (EFI_ERROR (Status)) {
3991 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3992 break;
3993 }
3994
3995 Status = HiiStatementValueToHiiValue (&Question->Value, &Data1);
3996 if (EFI_ERROR (Status)) {
3997 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3998 break;
3999 }
4000
4001 Status = CompareHiiValue (&Data1, &OpCode->ExtraData.EqIdValData.Value, &Result, NULL);
4002 ReleaseHiiValue (&Data1);
4003 if (Status == EFI_UNSUPPORTED) {
4004 Status = EFI_SUCCESS;
4005 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4006 break;
4007 }
4008
4009 if (EFI_ERROR (Status)) {
4010 goto Done;
4011 }
4012
4013 Value->Value.b = (BOOLEAN)((Result == 0) ? TRUE : FALSE);
4014 break;
4015
4016 case EFI_IFR_EQ_ID_ID_OP:
4017 Question = QuestionIdInFormset (FormSet, Form, OpCode->ExtraData.EqIdIdData.QuestionId1);
4018 if (Question == NULL) {
4019 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4020 break;
4021 }
4022
4023 //
4024 // Load value from storage.
4025 //
4026 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
4027 if (EFI_ERROR (Status)) {
4028 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4029 break;
4030 }
4031
4032 Status = HiiStatementValueToHiiValue (&Question->Value, &Data1);
4033 if (EFI_ERROR (Status)) {
4034 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4035 break;
4036 }
4037
4038 Question2 = QuestionIdInFormset (FormSet, Form, OpCode->ExtraData.EqIdIdData.QuestionId2);
4039 if (Question2 == NULL) {
4040 ReleaseHiiValue (&Data1);
4041 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4042 break;
4043 }
4044
4045 //
4046 // Load value from storage.
4047 //
4048 Status = GetQuestionValue (FormSet, Form, Question2, GetSetValueWithBuffer);
4049 if (EFI_ERROR (Status)) {
4050 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4051 break;
4052 }
4053
4054 Status = HiiStatementValueToHiiValue (&Question2->Value, &Data2);
4055 if (EFI_ERROR (Status)) {
4056 ReleaseHiiValue (&Data1);
4057 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4058 break;
4059 }
4060
4061 Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle);
4062 ReleaseHiiValue (&Data1);
4063 ReleaseHiiValue (&Data2);
4064 if (Status == EFI_UNSUPPORTED) {
4065 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4066 Status = EFI_SUCCESS;
4067 break;
4068 }
4069
4070 if (EFI_ERROR (Status)) {
4071 goto Done;
4072 }
4073
4074 Value->Value.b = (BOOLEAN)((Result == 0) ? TRUE : FALSE);
4075 break;
4076
4077 case EFI_IFR_EQ_ID_VAL_LIST_OP:
4078 Question = QuestionIdInFormset (FormSet, Form, OpCode->ExtraData.EqIdListData.QuestionId);
4079 if (Question == NULL) {
4080 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4081 break;
4082 }
4083
4084 //
4085 // Load value from storage.
4086 //
4087 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
4088 if (EFI_ERROR (Status)) {
4089 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4090 break;
4091 }
4092
4093 Value->Value.b = FALSE;
4094 for (Index = 0; Index < OpCode->ExtraData.EqIdListData.ListLength; Index++) {
4095 if (Question->Value.Value.u16 == OpCode->ExtraData.EqIdListData.ValueList[Index]) {
4096 Value->Value.b = TRUE;
4097 break;
4098 }
4099 }
4100
4101 break;
4102
4103 case EFI_IFR_DUP_OP:
4104 Status = PopExpression (Value);
4105 if (EFI_ERROR (Status)) {
4106 goto Done;
4107 }
4108
4109 Status = PushExpression (Value);
4110 break;
4111
4112 case EFI_IFR_QUESTION_REF1_OP:
4113 case EFI_IFR_THIS_OP:
4114 Question = QuestionIdInFormset (FormSet, Form, OpCode->ExtraData.QuestionRef1Data.QuestionId);
4115 if (Question == NULL) {
4116 Status = EFI_NOT_FOUND;
4117 goto Done;
4118 }
4119
4120 //
4121 // Load value from storage.
4122 //
4123 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
4124 if (EFI_ERROR (Status)) {
4125 goto Done;
4126 }
4127
4128 Value = (EFI_HII_VALUE *)&Question->Value;
4129 break;
4130
4131 case EFI_IFR_SECURITY_OP:
4132 Value->Value.b = CheckUserPrivilege (&OpCode->ExtraData.Guid);
4133 break;
4134
4135 case EFI_IFR_GET_OP:
4136 //
4137 // Get Value from VarStore buffer, EFI VarStore, Name/Value VarStore.
4138 //
4139 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4140 Value->Value.u8 = 0;
4141 if (OpCode->ExtraData.GetSetData.VarStorage != NULL) {
4142 switch (OpCode->ExtraData.GetSetData.VarStorage->Type) {
4143 case EFI_HII_VARSTORE_BUFFER:
4144 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
4145 //
4146 // Get value from Edit Buffer
4147 //
4148 Value->Type = OpCode->ExtraData.GetSetData.ValueType;
4149 CopyMem (&Value->Value, OpCode->ExtraData.GetSetData.VarStorage->EditBuffer + OpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, OpCode->ExtraData.GetSetData.ValueWidth);
4150 break;
4151 case EFI_HII_VARSTORE_NAME_VALUE:
4152 if (OpCode->ExtraData.GetSetData.ValueType != EFI_IFR_TYPE_STRING) {
4153 //
4154 // Get value from string except for STRING value.
4155 //
4156 Status = GetValueByName (OpCode->ExtraData.GetSetData.VarStorage, OpCode->ExtraData.GetSetData.ValueName, &StrPtr);
4157 if (!EFI_ERROR (Status)) {
4158 ASSERT (StrPtr != NULL);
4159 TempLength = StrLen (StrPtr);
4160 if (OpCode->ExtraData.GetSetData.ValueWidth >= ((TempLength + 1) / 2)) {
4161 Value->Type = OpCode->ExtraData.GetSetData.ValueType;
4162 TempBuffer = (UINT8 *)&Value->Value;
4163 ZeroMem (TempStr, sizeof (TempStr));
4164 for (Index = 0; Index < TempLength; Index++) {
4165 TempStr[0] = StrPtr[TempLength - Index - 1];
4166 DigitUint8 = (UINT8)StrHexToUint64 (TempStr);
4167 if ((Index & 1) == 0) {
4168 TempBuffer[Index/2] = DigitUint8;
4169 } else {
4170 TempBuffer[Index/2] = (UINT8)((DigitUint8 << 4) + TempBuffer[Index/2]);
4171 }
4172 }
4173 }
4174 }
4175 }
4176
4177 break;
4178 case EFI_HII_VARSTORE_EFI_VARIABLE:
4179 //
4180 // Get value from variable.
4181 //
4182 TempLength = OpCode->ExtraData.GetSetData.ValueWidth;
4183 Value->Type = OpCode->ExtraData.GetSetData.ValueType;
4184 Status = gRT->GetVariable (
4185 OpCode->ExtraData.GetSetData.ValueName,
4186 &OpCode->ExtraData.GetSetData.VarStorage->Guid,
4187 NULL,
4188 &TempLength,
4189 &Value->Value
4190 );
4191 if (EFI_ERROR (Status)) {
4192 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4193 Value->Value.u8 = 0;
4194 }
4195
4196 break;
4197 default:
4198 //
4199 // Not recognize storage.
4200 //
4201 Status = EFI_UNSUPPORTED;
4202 goto Done;
4203 }
4204 } else {
4205 //
4206 // For Time/Date Data
4207 //
4208 if ((OpCode->ExtraData.GetSetData.ValueType != EFI_IFR_TYPE_DATE) && (OpCode->ExtraData.GetSetData.ValueType != EFI_IFR_TYPE_TIME)) {
4209 //
4210 // Only support Data/Time data when storage doesn't exist.
4211 //
4212 Status = EFI_UNSUPPORTED;
4213 goto Done;
4214 }
4215
4216 Status = gRT->GetTime (&EfiTime, NULL);
4217 if (!EFI_ERROR (Status)) {
4218 if (OpCode->ExtraData.GetSetData.ValueType == EFI_IFR_TYPE_DATE) {
4219 switch (OpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset) {
4220 case 0x00:
4221 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
4222 Value->Value.u16 = EfiTime.Year;
4223 break;
4224 case 0x02:
4225 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
4226 Value->Value.u8 = EfiTime.Month;
4227 break;
4228 case 0x03:
4229 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
4230 Value->Value.u8 = EfiTime.Day;
4231 break;
4232 default:
4233 //
4234 // Invalid Date field.
4235 //
4236 Status = EFI_INVALID_PARAMETER;
4237 goto Done;
4238 }
4239 } else {
4240 switch (OpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset) {
4241 case 0x00:
4242 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
4243 Value->Value.u8 = EfiTime.Hour;
4244 break;
4245 case 0x01:
4246 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
4247 Value->Value.u8 = EfiTime.Minute;
4248 break;
4249 case 0x02:
4250 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
4251 Value->Value.u8 = EfiTime.Second;
4252 break;
4253 default:
4254 //
4255 // Invalid Time field.
4256 //
4257 Status = EFI_INVALID_PARAMETER;
4258 goto Done;
4259 }
4260 }
4261 }
4262 }
4263
4264 break;
4265
4266 case EFI_IFR_QUESTION_REF3_OP:
4267 //
4268 // EFI_IFR_QUESTION_REF3
4269 // Pop an expression from the expression stack
4270 //
4271 Status = PopExpression (Value);
4272 if (EFI_ERROR (Status)) {
4273 goto Done;
4274 }
4275
4276 //
4277 // Validate the expression value
4278 //
4279 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
4280 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4281 break;
4282 }
4283
4284 if (OpCode->ExtraData.QuestionRef3Data.DevicePath != 0) {
4285 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4286
4287 Status = gBS->LocateProtocol (
4288 &gEfiDevicePathFromTextProtocolGuid,
4289 NULL,
4290 (VOID **)&PathFromText
4291 );
4292 if (EFI_ERROR (Status)) {
4293 goto Done;
4294 }
4295
4296 StrPtr = GetTokenString (OpCode->ExtraData.QuestionRef3Data.DevicePath, FormSet->HiiHandle);
4297 if ((StrPtr != NULL) && (PathFromText != NULL)) {
4298 DevicePath = PathFromText->ConvertTextToDevicePath (StrPtr);
4299 if ((DevicePath != NULL) && GetQuestionValueFromForm (DevicePath, NULL, &OpCode->ExtraData.Guid, Value->Value.u16, &QuestionVal)) {
4300 Value = &QuestionVal;
4301 }
4302
4303 if (DevicePath != NULL) {
4304 FreePool (DevicePath);
4305 }
4306 }
4307
4308 if (StrPtr != NULL) {
4309 FreePool (StrPtr);
4310 }
4311 } else if (IsZeroGuid (&OpCode->ExtraData.Guid)) {
4312 if (!GetQuestionValueFromForm (NULL, FormSet->HiiHandle, &OpCode->ExtraData.Guid, Value->Value.u16, &QuestionVal)) {
4313 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4314 break;
4315 }
4316
4317 Value = &QuestionVal;
4318 } else {
4319 Question = QuestionIdInFormset (FormSet, Form, Value->Value.u16);
4320 if (Question == NULL) {
4321 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4322 break;
4323 }
4324
4325 //
4326 // Load value from storage.
4327 //
4328 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
4329 if (EFI_ERROR (Status)) {
4330 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4331 break;
4332 }
4333
4334 //
4335 // push the questions' value on to the expression stack
4336 //
4337 Value = (EFI_HII_VALUE *)&Question->Value;
4338 }
4339
4340 break;
4341
4342 case EFI_IFR_RULE_REF_OP:
4343 //
4344 // Find expression for this rule
4345 //
4346 RuleExpression = RuleIdToExpression (Form, OpCode->ExtraData.RuleId);
4347 if (RuleExpression == NULL) {
4348 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4349 break;
4350 }
4351
4352 //
4353 // Evaluate this rule expression
4354 //
4355 Status = EvaluateHiiExpression (FormSet, Form, RuleExpression);
4356 if (EFI_ERROR (Status) || (RuleExpression->Result.Type == EFI_IFR_TYPE_UNDEFINED)) {
4357 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4358 break;
4359 }
4360
4361 Value = &RuleExpression->Result;
4362 break;
4363
4364 case EFI_IFR_STRING_REF1_OP:
4365 Value->Type = EFI_IFR_TYPE_STRING;
4366 Value->Value.string = OpCode->ExtraData.Value.Value.string;
4367 break;
4368
4369 //
4370 // Constant
4371 //
4372 case EFI_IFR_TRUE_OP:
4373 case EFI_IFR_FALSE_OP:
4374 case EFI_IFR_ONE_OP:
4375 case EFI_IFR_ONES_OP:
4376 case EFI_IFR_UINT8_OP:
4377 case EFI_IFR_UINT16_OP:
4378 case EFI_IFR_UINT32_OP:
4379 case EFI_IFR_UINT64_OP:
4380 case EFI_IFR_UNDEFINED_OP:
4381 case EFI_IFR_VERSION_OP:
4382 case EFI_IFR_ZERO_OP:
4383 Value = &OpCode->ExtraData.Value;
4384 break;
4385
4386 //
4387 // unary-op
4388 //
4389 case EFI_IFR_LENGTH_OP:
4390 Status = PopExpression (Value);
4391 if (EFI_ERROR (Status)) {
4392 goto Done;
4393 }
4394
4395 if ((Value->Type != EFI_IFR_TYPE_STRING) && !IsTypeInBuffer (Value)) {
4396 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4397 break;
4398 }
4399
4400 if (Value->Type == EFI_IFR_TYPE_STRING) {
4401 StrPtr = GetTokenString (Value->Value.string, FormSet->HiiHandle);
4402 if (StrPtr == NULL) {
4403 Status = EFI_INVALID_PARAMETER;
4404 goto Done;
4405 }
4406
4407 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
4408 Value->Value.u64 = StrLen (StrPtr);
4409 FreePool (StrPtr);
4410 } else {
4411 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
4412 Value->Value.u64 = GetLengthForValue (Value);
4413 FreePool (Value->Buffer);
4414 }
4415
4416 break;
4417
4418 case EFI_IFR_NOT_OP:
4419 Status = PopExpression (Value);
4420 if (EFI_ERROR (Status)) {
4421 goto Done;
4422 }
4423
4424 if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {
4425 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4426 break;
4427 }
4428
4429 Value->Value.b = (BOOLEAN)(!Value->Value.b);
4430 break;
4431
4432 case EFI_IFR_QUESTION_REF2_OP:
4433 //
4434 // Pop an expression from the expression stack
4435 //
4436 Status = PopExpression (Value);
4437 if (EFI_ERROR (Status)) {
4438 goto Done;
4439 }
4440
4441 //
4442 // Validate the expression value
4443 //
4444 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
4445 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4446 break;
4447 }
4448
4449 Question = QuestionIdInFormset (FormSet, Form, Value->Value.u16);
4450 if (Question == NULL) {
4451 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4452 break;
4453 }
4454
4455 //
4456 // Load value from storage.
4457 //
4458 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
4459 if (EFI_ERROR (Status)) {
4460 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4461 break;
4462 }
4463
4464 Value = (EFI_HII_VALUE *)&Question->Value;
4465 break;
4466
4467 case EFI_IFR_STRING_REF2_OP:
4468 //
4469 // Pop an expression from the expression stack
4470 //
4471 Status = PopExpression (Value);
4472 if (EFI_ERROR (Status)) {
4473 goto Done;
4474 }
4475
4476 //
4477 // Validate the expression value
4478 //
4479 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
4480 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4481 break;
4482 }
4483
4484 Value->Type = EFI_IFR_TYPE_STRING;
4485 StrPtr = GetTokenString (Value->Value.u16, FormSet->HiiHandle);
4486 if (StrPtr == NULL) {
4487 //
4488 // If String not exit, push an empty string
4489 //
4490 Value->Value.string = NewHiiString (gEmptyString, FormSet->HiiHandle);
4491 } else {
4492 Index = (UINT16)Value->Value.u64;
4493 Value->Value.string = Index;
4494 FreePool (StrPtr);
4495 }
4496
4497 break;
4498
4499 case EFI_IFR_TO_BOOLEAN_OP:
4500 //
4501 // Pop an expression from the expression stack
4502 //
4503 Status = PopExpression (Value);
4504 if (EFI_ERROR (Status)) {
4505 goto Done;
4506 }
4507
4508 //
4509 // Convert an expression to a Boolean
4510 //
4511 if (Value->Type <= EFI_IFR_TYPE_DATE) {
4512 //
4513 // When converting from an unsigned integer, zero will be converted to
4514 // FALSE and any other value will be converted to TRUE.
4515 //
4516 Value->Value.b = (BOOLEAN)(HiiValueToUINT64 (Value) != 0);
4517
4518 Value->Type = EFI_IFR_TYPE_BOOLEAN;
4519 } else if (Value->Type == EFI_IFR_TYPE_STRING) {
4520 //
4521 // When converting from a string, if case-insensitive compare
4522 // with "true" is True, then push True. If a case-insensitive compare
4523 // with "false" is True, then push False. Otherwise, push Undefined.
4524 //
4525 StrPtr = GetTokenString (Value->Value.string, FormSet->HiiHandle);
4526 if (StrPtr == NULL) {
4527 Status = EFI_INVALID_PARAMETER;
4528 goto Done;
4529 }
4530
4531 IfrStrToUpper (StrPtr);
4532 if (StrCmp (StrPtr, L"TRUE") == 0) {
4533 Value->Value.b = TRUE;
4534 Value->Type = EFI_IFR_TYPE_BOOLEAN;
4535 } else if (StrCmp (StrPtr, L"FALSE") == 0) {
4536 Value->Value.b = FALSE;
4537 Value->Type = EFI_IFR_TYPE_BOOLEAN;
4538 } else {
4539 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4540 }
4541
4542 FreePool (StrPtr);
4543 } else if (Value->Type == EFI_IFR_TYPE_BUFFER) {
4544 //
4545 // When converting from a buffer, if the buffer is all zeroes,
4546 // then push False. Otherwise push True.
4547 //
4548 for (Index = 0; Index < Value->BufferLen; Index++) {
4549 if (Value->Buffer[Index] != 0) {
4550 break;
4551 }
4552 }
4553
4554 if (Index >= Value->BufferLen) {
4555 Value->Value.b = FALSE;
4556 } else {
4557 Value->Value.b = TRUE;
4558 }
4559
4560 Value->Type = EFI_IFR_TYPE_BOOLEAN;
4561 FreePool (Value->Buffer);
4562 }
4563
4564 break;
4565
4566 case EFI_IFR_TO_STRING_OP:
4567 Status = IfrToString (FormSet, OpCode->ExtraData.Format, Value);
4568 break;
4569
4570 case EFI_IFR_TO_UINT_OP:
4571 Status = IfrToUint (FormSet, Value);
4572 break;
4573
4574 case EFI_IFR_TO_LOWER_OP:
4575 case EFI_IFR_TO_UPPER_OP:
4577 if (EFI_ERROR (Status)) {
4578 goto Done;
4579 }
4580
4581 Status = PopExpression (Value);
4582 if (EFI_ERROR (Status)) {
4583 goto Done;
4584 }
4585
4586 if (Value->Type != EFI_IFR_TYPE_STRING) {
4587 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4588 break;
4589 }
4590
4591 StrPtr = GetTokenString (Value->Value.string, FormSet->HiiHandle);
4592 if (StrPtr == NULL) {
4593 Status = EFI_NOT_FOUND;
4594 goto Done;
4595 }
4596
4597 if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {
4598 mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr);
4599 } else {
4600 mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);
4601 }
4602
4603 Value->Value.string = NewHiiString (StrPtr, FormSet->HiiHandle);
4604 FreePool (StrPtr);
4605 break;
4606
4607 case EFI_IFR_BITWISE_NOT_OP:
4608 //
4609 // Pop an expression from the expression stack
4610 //
4611 Status = PopExpression (Value);
4612 if (EFI_ERROR (Status)) {
4613 goto Done;
4614 }
4615
4616 if (Value->Type > EFI_IFR_TYPE_DATE) {
4617 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4618 break;
4619 }
4620
4621 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
4622 Value->Value.u64 = ~HiiValueToUINT64(Value);
4623 break;
4624
4625 case EFI_IFR_SET_OP:
4626 //
4627 // Pop an expression from the expression stack
4628 //
4629 Status = PopExpression (Value);
4630 if (EFI_ERROR (Status)) {
4631 goto Done;
4632 }
4633
4634 Data1.Type = EFI_IFR_TYPE_BOOLEAN;
4635 Data1.Value.b = FALSE;
4636 //
4637 // Set value to var storage buffer
4638 //
4639 if (OpCode->ExtraData.GetSetData.VarStorage != NULL) {
4640 switch (OpCode->ExtraData.GetSetData.VarStorage->Type) {
4641 case EFI_HII_VARSTORE_BUFFER:
4642 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
4643 CopyMem (OpCode->ExtraData.GetSetData.VarStorage->EditBuffer + OpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, &Value->Value, OpCode->ExtraData.GetSetData.ValueWidth);
4644 Data1.Value.b = TRUE;
4645 break;
4646 case EFI_HII_VARSTORE_NAME_VALUE:
4647 if (OpCode->ExtraData.GetSetData.ValueType != EFI_IFR_TYPE_STRING) {
4648 NameValue = AllocatePool ((OpCode->ExtraData.GetSetData.ValueWidth * 2 + 1) * sizeof (CHAR16));
4649 ASSERT (NameValue != NULL);
4650 //
4651 // Convert Buffer to Hex String
4652 //
4653 TempBuffer = (UINT8 *)&Value->Value + OpCode->ExtraData.GetSetData.ValueWidth - 1;
4654 StrPtr = NameValue;
4655 for (Index = 0; Index < OpCode->ExtraData.GetSetData.ValueWidth; Index++, TempBuffer--) {
4657 StrPtr,
4658 (OpCode->ExtraData.GetSetData.ValueWidth * 2 + 1) * sizeof (CHAR16) - ((UINTN)StrPtr - (UINTN)NameValue),
4659 PREFIX_ZERO | RADIX_HEX,
4660 *TempBuffer,
4661 2
4662 );
4663 StrPtr += StrnLenS (StrPtr, OpCode->ExtraData.GetSetData.ValueWidth * 2 + 1 - ((UINTN)StrPtr - (UINTN)NameValue) / sizeof (CHAR16));
4664 }
4665
4666 Status = SetValueByName (OpCode->ExtraData.GetSetData.VarStorage, OpCode->ExtraData.GetSetData.ValueName, NameValue, NULL);
4667 FreePool (NameValue);
4668 if (!EFI_ERROR (Status)) {
4669 Data1.Value.b = TRUE;
4670 }
4671 }
4672
4673 break;
4674 case EFI_HII_VARSTORE_EFI_VARIABLE:
4675 Status = gRT->SetVariable (
4676 OpCode->ExtraData.GetSetData.ValueName,
4677 &OpCode->ExtraData.GetSetData.VarStorage->Guid,
4678 OpCode->ExtraData.GetSetData.VarStorage->Attributes,
4679 OpCode->ExtraData.GetSetData.ValueWidth,
4680 &Value->Value
4681 );
4682 if (!EFI_ERROR (Status)) {
4683 Data1.Value.b = TRUE;
4684 }
4685
4686 break;
4687 default:
4688 //
4689 // Not recognize storage.
4690 //
4691 Status = EFI_UNSUPPORTED;
4692 goto Done;
4693 }
4694 } else {
4695 //
4696 // For Time/Date Data
4697 //
4698 if ((OpCode->ExtraData.GetSetData.ValueType != EFI_IFR_TYPE_DATE) && (OpCode->ExtraData.GetSetData.ValueType != EFI_IFR_TYPE_TIME)) {
4699 //
4700 // Only support Data/Time data when storage doesn't exist.
4701 //
4702 Status = EFI_UNSUPPORTED;
4703 goto Done;
4704 }
4705
4706 Status = gRT->GetTime (&EfiTime, NULL);
4707 if (!EFI_ERROR (Status)) {
4708 if (OpCode->ExtraData.GetSetData.ValueType == EFI_IFR_TYPE_DATE) {
4709 switch (OpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset) {
4710 case 0x00:
4711 EfiTime.Year = Value->Value.u16;
4712 break;
4713 case 0x02:
4714 EfiTime.Month = Value->Value.u8;
4715 break;
4716 case 0x03:
4717 EfiTime.Day = Value->Value.u8;
4718 break;
4719 default:
4720 //
4721 // Invalid Date field.
4722 //
4723 Status = EFI_INVALID_PARAMETER;
4724 goto Done;
4725 }
4726 } else {
4727 switch (OpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset) {
4728 case 0x00:
4729 EfiTime.Hour = Value->Value.u8;
4730 break;
4731 case 0x01:
4732 EfiTime.Minute = Value->Value.u8;
4733 break;
4734 case 0x02:
4735 EfiTime.Second = Value->Value.u8;
4736 break;
4737 default:
4738 //
4739 // Invalid Time field.
4740 //
4741 Status = EFI_INVALID_PARAMETER;
4742 goto Done;
4743 }
4744 }
4745
4746 Status = gRT->SetTime (&EfiTime);
4747 if (!EFI_ERROR (Status)) {
4748 Data1.Value.b = TRUE;
4749 }
4750 }
4751 }
4752
4753 Value = &Data1;
4754 break;
4755
4756 //
4757 // binary-op
4758 //
4759 case EFI_IFR_ADD_OP:
4760 case EFI_IFR_SUBTRACT_OP:
4761 case EFI_IFR_MULTIPLY_OP:
4762 case EFI_IFR_DIVIDE_OP:
4763 case EFI_IFR_MODULO_OP:
4764 case EFI_IFR_BITWISE_AND_OP:
4765 case EFI_IFR_BITWISE_OR_OP:
4766 case EFI_IFR_SHIFT_LEFT_OP:
4767 case EFI_IFR_SHIFT_RIGHT_OP:
4768 //
4769 // Pop an expression from the expression stack
4770 //
4771 Status = PopExpression (&Data2);
4772 if (EFI_ERROR (Status)) {
4773 goto Done;
4774 }
4775
4776 //
4777 // Pop another expression from the expression stack
4778 //
4779 Status = PopExpression (&Data1);
4780 if (EFI_ERROR (Status)) {
4781 goto Done;
4782 }
4783
4784 if (Data2.Type > EFI_IFR_TYPE_DATE) {
4785 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4786 break;
4787 }
4788
4789 if (Data1.Type > EFI_IFR_TYPE_DATE) {
4790 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4791 break;
4792 }
4793
4794 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
4795
4796 switch (OpCode->Operand) {
4797 case EFI_IFR_ADD_OP:
4798 Value->Value.u64 = HiiValueToUINT64 (&Data1) + HiiValueToUINT64 (&Data2);
4799 break;
4800
4801 case EFI_IFR_SUBTRACT_OP:
4802 Value->Value.u64 = HiiValueToUINT64 (&Data1) - HiiValueToUINT64 (&Data2);
4803 break;
4804
4805 case EFI_IFR_MULTIPLY_OP:
4806 Value->Value.u64 = MultU64x32 (HiiValueToUINT64 (&Data1), (UINT32)HiiValueToUINT64 (&Data2));
4807 break;
4808
4809 case EFI_IFR_DIVIDE_OP:
4810 Value->Value.u64 = DivU64x32 (HiiValueToUINT64 (&Data1), (UINT32)HiiValueToUINT64 (&Data2));
4811 break;
4812
4813 case EFI_IFR_MODULO_OP:
4814 DivU64x32Remainder (HiiValueToUINT64 (&Data1), (UINT32)HiiValueToUINT64 (&Data2), &TempValue);
4815 Value->Value.u64 = TempValue;
4816 break;
4817
4818 case EFI_IFR_BITWISE_AND_OP:
4819 Value->Value.u64 = HiiValueToUINT64 (&Data1) & HiiValueToUINT64 (&Data2);
4820 break;
4821
4822 case EFI_IFR_BITWISE_OR_OP:
4823 Value->Value.u64 = HiiValueToUINT64 (&Data1) | HiiValueToUINT64 (&Data2);
4824 break;
4825
4826 case EFI_IFR_SHIFT_LEFT_OP:
4827 Value->Value.u64 = LShiftU64 (HiiValueToUINT64 (&Data1), (UINTN)HiiValueToUINT64 (&Data2));
4828 break;
4829
4830 case EFI_IFR_SHIFT_RIGHT_OP:
4831 Value->Value.u64 = RShiftU64 (HiiValueToUINT64 (&Data1), (UINTN)HiiValueToUINT64 (&Data2));
4832 break;
4833
4834 default:
4835 break;
4836 }
4837
4838 break;
4839
4840 case EFI_IFR_AND_OP:
4841 case EFI_IFR_OR_OP:
4842 //
4843 // Two Boolean operator
4844 //
4845 Status = PopExpression (&Data2);
4846 if (EFI_ERROR (Status)) {
4847 goto Done;
4848 }
4849
4850 //
4851 // Pop another expression from the expression stack
4852 //
4853 Status = PopExpression (&Data1);
4854 if (EFI_ERROR (Status)) {
4855 goto Done;
4856 }
4857
4858 if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {
4859 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4860 break;
4861 }
4862
4863 if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
4864 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4865 break;
4866 }
4867
4868 if (OpCode->Operand == EFI_IFR_AND_OP) {
4869 Value->Value.b = (BOOLEAN)(Data1.Value.b && Data2.Value.b);
4870 } else {
4871 Value->Value.b = (BOOLEAN)(Data1.Value.b || Data2.Value.b);
4872 }
4873
4874 break;
4875
4876 case EFI_IFR_EQUAL_OP:
4877 case EFI_IFR_NOT_EQUAL_OP:
4878 case EFI_IFR_GREATER_EQUAL_OP:
4879 case EFI_IFR_GREATER_THAN_OP:
4880 case EFI_IFR_LESS_EQUAL_OP:
4881 case EFI_IFR_LESS_THAN_OP:
4882 //
4883 // Compare two integer, string, boolean or date/time
4884 //
4885 Status = PopExpression (&Data2);
4886 if (EFI_ERROR (Status)) {
4887 goto Done;
4888 }
4889
4890 //
4891 // Pop another expression from the expression stack
4892 //
4893 Status = PopExpression (&Data1);
4894 if (EFI_ERROR (Status)) {
4895 goto Done;
4896 }
4897
4898 if ((Data2.Type > EFI_IFR_TYPE_BOOLEAN) &&
4899 (Data2.Type != EFI_IFR_TYPE_STRING) &&
4900 !IsTypeInBuffer (&Data2))
4901 {
4902 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4903 break;
4904 }
4905
4906 if ((Data1.Type > EFI_IFR_TYPE_BOOLEAN) &&
4907 (Data1.Type != EFI_IFR_TYPE_STRING) &&
4908 !IsTypeInBuffer (&Data1))
4909 {
4910 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4911 break;
4912 }
4913
4914 Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle);
4915 if (Data1.Type == EFI_IFR_TYPE_BUFFER) {
4916 FreePool (Data1.Buffer);
4917 }
4918
4919 if (Data2.Type == EFI_IFR_TYPE_BUFFER) {
4920 FreePool (Data2.Buffer);
4921 }
4922
4923 if (Status == EFI_UNSUPPORTED) {
4924 Value->Type = EFI_IFR_TYPE_UNDEFINED;
4925 Status = EFI_SUCCESS;
4926 break;
4927 }
4928
4929 if (EFI_ERROR (Status)) {
4930 goto Done;
4931 }
4932
4933 switch (OpCode->Operand) {
4934 case EFI_IFR_EQUAL_OP:
4935 Value->Value.b = (BOOLEAN)((Result == 0) ? TRUE : FALSE);
4936 break;
4937
4938 case EFI_IFR_NOT_EQUAL_OP:
4939 Value->Value.b = (BOOLEAN)((Result != 0) ? TRUE : FALSE);
4940 break;
4941
4942 case EFI_IFR_GREATER_EQUAL_OP:
4943 Value->Value.b = (BOOLEAN)((Result >= 0) ? TRUE : FALSE);
4944 break;
4945
4946 case EFI_IFR_GREATER_THAN_OP:
4947 Value->Value.b = (BOOLEAN)((Result > 0) ? TRUE : FALSE);
4948 break;
4949
4950 case EFI_IFR_LESS_EQUAL_OP:
4951 Value->Value.b = (BOOLEAN)((Result <= 0) ? TRUE : FALSE);
4952 break;
4953
4954 case EFI_IFR_LESS_THAN_OP:
4955 Value->Value.b = (BOOLEAN)((Result < 0) ? TRUE : FALSE);
4956 break;
4957
4958 default:
4959 break;
4960 }
4961
4962 break;
4963
4964 case EFI_IFR_MATCH_OP:
4966 if (EFI_ERROR (Status)) {
4967 goto Done;
4968 }
4969
4970 Status = IfrMatch (FormSet, Value);
4971 break;
4972
4973 case EFI_IFR_MATCH2_OP:
4974 Status = IfrMatch2 (FormSet, &OpCode->ExtraData.Guid, Value);
4975 break;
4976
4977 case EFI_IFR_CATENATE_OP:
4978 Status = IfrCatenate (FormSet, Value);
4979 break;
4980
4981 //
4982 // ternary-op
4983 //
4984 case EFI_IFR_CONDITIONAL_OP:
4985 //
4986 // Pop third expression from the expression stack
4987 //
4988 Status = PopExpression (&Data3);
4989 if (EFI_ERROR (Status)) {
4990 goto Done;
4991 }
4992
4993 //
4994 // Pop second expression from the expression stack
4995 //
4996 Status = PopExpression (&Data2);
4997 if (EFI_ERROR (Status)) {
4998 goto Done;
4999 }
5000
5001 //
5002 // Pop first expression from the expression stack
5003 //
5004 Status = PopExpression (&Data1);
5005 if (EFI_ERROR (Status)) {
5006 goto Done;
5007 }
5008
5009 if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
5010 Value->Type = EFI_IFR_TYPE_UNDEFINED;
5011 break;
5012 }
5013
5014 if (Data1.Value.b) {
5015 Value = &Data3;
5016 } else {
5017 Value = &Data2;
5018 }
5019
5020 break;
5021
5022 case EFI_IFR_FIND_OP:
5023 Status = IfrFind (FormSet, OpCode->ExtraData.Format, Value);
5024 break;
5025
5026 case EFI_IFR_MID_OP:
5027 Status = IfrMid (FormSet, Value);
5028 break;
5029
5030 case EFI_IFR_TOKEN_OP:
5031 Status = IfrToken (FormSet, Value);
5032 break;
5033
5034 case EFI_IFR_SPAN_OP:
5035 Status = IfrSpan (FormSet, OpCode->ExtraData.Flags, Value);
5036 break;
5037
5038 case EFI_IFR_MAP_OP:
5039 //
5040 // Pop the check value
5041 //
5042 Status = PopExpression (&Data1);
5043 if (EFI_ERROR (Status)) {
5044 goto Done;
5045 }
5046
5047 //
5048 // Check MapExpression list is valid.
5049 //
5050 if (OpCode->MapExpressionList.ForwardLink == NULL) {
5051 Status = EFI_INVALID_PARAMETER;
5052 goto Done;
5053 }
5054
5055 //
5056 // Go through map expression list.
5057 //
5058 SubExpressionLink = GetFirstNode (&OpCode->MapExpressionList);
5059 while (!IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
5060 SubExpression = HII_EXPRESSION_FROM_LINK (SubExpressionLink);
5061 //
5062 // Evaluate the first expression in this pair.
5063 //
5064 Status = EvaluateHiiExpression (FormSet, Form, SubExpression);
5065 if (EFI_ERROR (Status)) {
5066 goto Done;
5067 }
5068
5069 //
5070 // Compare the expression value with current value
5071 //
5072 if ((CompareHiiValue (&Data1, &SubExpression->Result, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
5073 //
5074 // Try get the map value.
5075 //
5076 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);
5077 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
5078 Status = EFI_INVALID_PARAMETER;
5079 goto Done;
5080 }
5081
5082 SubExpression = HII_EXPRESSION_FROM_LINK (SubExpressionLink);
5083 Status = EvaluateHiiExpression (FormSet, Form, SubExpression);
5084 if (EFI_ERROR (Status)) {
5085 goto Done;
5086 }
5087
5088 Value = &SubExpression->Result;
5089 break;
5090 }
5091
5092 //
5093 // Skip the second expression on this pair.
5094 //
5095 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);
5096 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
5097 Status = EFI_INVALID_PARAMETER;
5098 goto Done;
5099 }
5100
5101 //
5102 // Goto the first expression on next pair.
5103 //
5104 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);
5105 }
5106
5107 //
5108 // No map value is found.
5109 //
5110 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
5111 Value->Type = EFI_IFR_TYPE_UNDEFINED;
5112 Value->Value.u8 = 0;
5113 }
5114
5115 break;
5116
5117 default:
5118 break;
5119 }
5120
5121 if (EFI_ERROR (Status) || (Value->Type == EFI_IFR_TYPE_UNDEFINED)) {
5122 goto Done;
5123 }
5124
5125 Status = PushExpression (Value);
5126 if (EFI_ERROR (Status)) {
5127 goto Done;
5128 }
5129 }
5130
5131 //
5132 // Pop the final result from expression stack
5133 //
5134 Value = &Data1;
5135 Status = PopExpression (Value);
5136 if (EFI_ERROR (Status)) {
5137 goto Done;
5138 }
5139
5140 //
5141 // After evaluating an expression, there should be only one value left on the expression stack
5142 //
5143 if (PopExpression (Value) != EFI_ACCESS_DENIED) {
5144 Status = EFI_INVALID_PARAMETER;
5145 }
5146
5147Done:
5149 if (!EFI_ERROR (Status)) {
5150 CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));
5151 }
5152
5153 return Status;
5154}
5155
5165VOID
5167 IN VOID *Array,
5168 IN UINT8 Type,
5169 IN UINTN Index,
5170 IN UINT64 Value
5171 )
5172{
5173 ASSERT (Array != NULL);
5174
5175 switch (Type) {
5176 case EFI_IFR_TYPE_NUM_SIZE_8:
5177 *(((UINT8 *)Array) + Index) = (UINT8)Value;
5178 break;
5179
5180 case EFI_IFR_TYPE_NUM_SIZE_16:
5181 *(((UINT16 *)Array) + Index) = (UINT16)Value;
5182 break;
5183
5184 case EFI_IFR_TYPE_NUM_SIZE_32:
5185 *(((UINT32 *)Array) + Index) = (UINT32)Value;
5186 break;
5187
5188 case EFI_IFR_TYPE_NUM_SIZE_64:
5189 *(((UINT64 *)Array) + Index) = (UINT64)Value;
5190 break;
5191
5192 default:
5193 break;
5194 }
5195}
5196
5209 IN HII_STATEMENT *Question,
5210 IN HII_STATEMENT_VALUE *OptionValue
5211 )
5212{
5213 LIST_ENTRY *Link;
5214 HII_QUESTION_OPTION *Option;
5215 EFI_HII_VALUE Data1;
5216 EFI_HII_VALUE Data2;
5217 INTN Result;
5218 EFI_STATUS Status;
5219
5220 Result = 0;
5221 ZeroMem (&Data1, sizeof (EFI_HII_VALUE));
5222 ZeroMem (&Data2, sizeof (EFI_HII_VALUE));
5223
5224 Status = HiiStatementValueToHiiValue (OptionValue, &Data1);
5225 ASSERT_EFI_ERROR (Status);
5226
5227 Link = GetFirstNode (&Question->OptionListHead);
5228 while (!IsNull (&Question->OptionListHead, Link)) {
5229 Option = HII_QUESTION_OPTION_FROM_LINK (Link);
5230
5231 Status = HiiStatementValueToHiiValue (&Option->Value, &Data2);
5232 ASSERT_EFI_ERROR (Status);
5233
5234 if ((CompareHiiValue (&Data1, &Data2, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
5235 //
5236 // Check the suppressif condition, only a valid option can be return.
5237 //
5238 if ((Option->SuppressExpression == NULL) ||
5239 ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)))
5240 {
5241 return Option;
5242 }
5243 }
5244
5245 Link = GetNextNode (&Question->OptionListHead, Link);
5246 }
5247
5248 return NULL;
5249}
5250
5260CHAR16 *
5262 IN HII_STATEMENT *Question,
5263 IN CHAR16 *ConfigResp
5264 )
5265{
5266 CHAR16 *RequestElement;
5267 CHAR16 *BlockData;
5268
5269 //
5270 // Type is EFI_HII_VARSTORE_NAME_VALUE.
5271 //
5272 if (Question->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
5273 RequestElement = StrStr (ConfigResp, Question->VariableName);
5274 if (RequestElement != NULL) {
5275 //
5276 // Skip the "VariableName=" field.
5277 //
5278 RequestElement += StrLen (Question->VariableName) + 1;
5279 }
5280
5281 return RequestElement;
5282 }
5283
5284 //
5285 // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
5286 //
5287
5288 //
5289 // Convert all hex digits in ConfigResp to lower case before searching.
5290 //
5291 HiiStringToLowercase (ConfigResp);
5292
5293 //
5294 // 1. Directly use Question->BlockName to find.
5295 //
5296 RequestElement = StrStr (ConfigResp, Question->BlockName);
5297 if (RequestElement != NULL) {
5298 //
5299 // Skip the "Question->BlockName&VALUE=" field.
5300 //
5301 RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");
5302 return RequestElement;
5303 }
5304
5305 //
5306 // 2. Change all hex digits in Question->BlockName to lower and compare again.
5307 //
5308 BlockData = AllocateCopyPool (StrSize (Question->BlockName), Question->BlockName);
5309 ASSERT (BlockData != NULL);
5310 HiiStringToLowercase (BlockData);
5311 RequestElement = StrStr (ConfigResp, BlockData);
5312 FreePool (BlockData);
5313
5314 if (RequestElement != NULL) {
5315 //
5316 // Skip the "Question->BlockName&VALUE=" field.
5317 //
5318 RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");
5319 }
5320
5321 return RequestElement;
5322}
5323
5337 IN HII_FORMSET *FormSet,
5338 IN HII_FORM *Form,
5339 IN HII_STATEMENT *Question,
5340 OUT HII_STATEMENT_VALUE *DefaultValue
5341 )
5342{
5343 HII_FORMSET_STORAGE *Storage;
5344 CHAR16 *ConfigResp;
5345 CHAR16 *Value;
5346 LIST_ENTRY *Link;
5347 HII_FORM_CONFIG_REQUEST *ConfigInfo;
5348
5349 Storage = Question->Storage;
5350 if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
5351 return EFI_NOT_FOUND;
5352 }
5353
5354 //
5355 // Try to get AltCfg string from form. If not found it, then
5356 // try to get it from formset.
5357 //
5358 ConfigResp = NULL;
5359 Link = GetFirstNode (&Form->ConfigRequestHead);
5360 while (!IsNull (&Form->ConfigRequestHead, Link)) {
5361 ConfigInfo = HII_FORM_CONFIG_REQUEST_FROM_LINK (Link);
5362 Link = GetNextNode (&Form->ConfigRequestHead, Link);
5363
5364 if (Storage == ConfigInfo->Storage) {
5365 ConfigResp = ConfigInfo->ConfigAltResp;
5366 break;
5367 }
5368 }
5369
5370 if (ConfigResp == NULL) {
5371 return EFI_NOT_FOUND;
5372 }
5373
5374 Value = GetOffsetFromConfigResp (Question, ConfigResp);
5375 if (Value == NULL) {
5376 return EFI_NOT_FOUND;
5377 }
5378
5379 return BufferToQuestionValue (Question, Value, DefaultValue);
5380}
5381
5390INTN
5392 IN UINTN DefaultId
5393 )
5394{
5395 if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {
5396 return EFI_BROWSER_ACTION_DEFAULT_STANDARD;
5397 } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
5398 return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;
5399 } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {
5400 return EFI_BROWSER_ACTION_DEFAULT_SAFE;
5401 } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000)) {
5402 return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;
5403 } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000)) {
5404 return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;
5405 } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000)) {
5406 return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;
5407 } else {
5408 return -1;
5409 }
5410}
5411
5426 IN HII_FORMSET *FormSet,
5427 IN HII_FORM *Form,
5428 IN HII_STATEMENT *Question,
5429 IN UINT16 DefaultId,
5430 OUT HII_STATEMENT_VALUE *DefaultValue
5431 )
5432{
5433 EFI_STATUS Status;
5434 LIST_ENTRY *Link;
5435 HII_QUESTION_DEFAULT *Default;
5436 HII_QUESTION_OPTION *Option;
5437 HII_STATEMENT_VALUE *HiiValue;
5438 UINT8 Index;
5439 EFI_STRING StrValue;
5440 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
5441 EFI_BROWSER_ACTION_REQUEST ActionRequest;
5442 INTN Action;
5444 UINT16 OriginalDefaultId;
5445 HII_FORMSET_DEFAULTSTORE *DefaultStore;
5446 LIST_ENTRY *DefaultLink;
5447
5448 if ((FormSet == NULL) || (Form == NULL) || (Question == NULL) || (DefaultValue == NULL)) {
5449 return EFI_INVALID_PARAMETER;
5450 }
5451
5452 Status = EFI_NOT_FOUND;
5453 StrValue = NULL;
5454 ConfigAccess = NULL;
5455 OriginalDefaultId = DefaultId;
5456 DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);
5457
5458 //
5459 // Statement don't have storage, skip them
5460 //
5461 if (Question->QuestionId == 0) {
5462 DEBUG ((DEBUG_ERROR, "%a: Question has no storage, skip it\n", __func__));
5463 return Status;
5464 }
5465
5466 //
5467 // There are Five ways to specify default value for a Question:
5468 // 1, use call back function (highest priority)
5469 // 2, use ExtractConfig function
5470 // 3, use nested EFI_IFR_DEFAULT
5471 // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
5472 // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
5473 //
5474 CopyMem (DefaultValue, &Question->Value, sizeof (HII_STATEMENT_VALUE));
5475ReGetDefault:
5476 HiiValue = DefaultValue;
5477 TypeValue = &HiiValue->Value;
5478 if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {
5479 //
5480 // For orderedlist, need to pass the BufferValue to Callback function.
5481 //
5482 DefaultValue->BufferLen = Question->Value.BufferLen;
5483 DefaultValue->Buffer = AllocateZeroPool (DefaultValue->BufferLen);
5484 ASSERT (DefaultValue->Buffer != NULL);
5485 if (DefaultValue->Buffer == NULL) {
5486 return EFI_OUT_OF_RESOURCES;
5487 }
5488
5489 TypeValue = (EFI_IFR_TYPE_VALUE *)DefaultValue->Buffer;
5490 }
5491
5492 //
5493 // Get Question default value from call back function.
5494 // The string type of question cause HII driver to set string to its default value.
5495 // So, we don't do this otherwise it will actually set question to default value.
5496 // We only want to get default value of question.
5497 //
5498 if (HiiValue->Type != EFI_IFR_TYPE_STRING) {
5499 ConfigAccess = FormSet->ConfigAccess;
5500 Action = GetDefaultIdForCallBack (DefaultId);
5501 if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {
5502 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
5503 Status = ConfigAccess->Callback (
5504 ConfigAccess,
5505 Action,
5506 Question->QuestionId,
5507 HiiValue->Type,
5508 TypeValue,
5509 &ActionRequest
5510 );
5511 if (!EFI_ERROR (Status)) {
5512 return Status;
5513 }
5514 }
5515 }
5516
5517 //
5518 // Get default value from altcfg string.
5519 //
5520 if (ConfigAccess != NULL) {
5521 Status = GetDefaultValueFromAltCfg (FormSet, Form, Question, DefaultValue);
5522 if (!EFI_ERROR (Status)) {
5523 return Status;
5524 }
5525 }
5526
5527 //
5528 // EFI_IFR_DEFAULT has highest priority
5529 //
5530 if (!IsListEmpty (&Question->DefaultListHead)) {
5531 Link = GetFirstNode (&Question->DefaultListHead);
5532 while (!IsNull (&Question->DefaultListHead, Link)) {
5533 Default = HII_QUESTION_DEFAULT_FROM_LINK (Link);
5534
5535 if (Default->DefaultId == DefaultId) {
5536 if (Default->ValueExpression != NULL) {
5537 //
5538 // Default is provided by an Expression, evaluate it
5539 //
5540 Status = EvaluateHiiExpression (FormSet, Form, Default->ValueExpression);
5541 if (EFI_ERROR (Status)) {
5542 return Status;
5543 }
5544
5545 if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {
5546 ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && DefaultValue->Buffer != NULL);
5547 if (DefaultValue->BufferLen > Default->ValueExpression->Result.BufferLen) {
5548 CopyMem (DefaultValue->Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen);
5549 DefaultValue->BufferLen = Default->ValueExpression->Result.BufferLen;
5550 } else {
5551 CopyMem (DefaultValue->Buffer, Default->ValueExpression->Result.Buffer, DefaultValue->BufferLen);
5552 }
5553
5554 FreePool (Default->ValueExpression->Result.Buffer);
5555 }
5556
5557 HiiValue->Type = Default->ValueExpression->Result.Type;
5558 CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));
5559 } else {
5560 //
5561 // Default value is embedded in EFI_IFR_DEFAULT
5562 //
5563 if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {
5564 ASSERT (HiiValue->Buffer != NULL);
5565 CopyMem (HiiValue->Buffer, Default->Value.Buffer, Default->Value.BufferLen);
5566 } else {
5567 CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));
5568 }
5569 }
5570
5571 if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
5572 StrValue = HiiGetString (FormSet->HiiHandle, HiiValue->Value.string, NULL);
5573 if (StrValue == NULL) {
5574 return EFI_NOT_FOUND;
5575 }
5576
5577 if (DefaultValue->BufferLen > StrSize (StrValue)) {
5578 ZeroMem (DefaultValue->Buffer, DefaultValue->BufferLen);
5579 CopyMem (DefaultValue->Buffer, StrValue, StrSize (StrValue));
5580 } else {
5581 CopyMem (DefaultValue->Buffer, StrValue, DefaultValue->BufferLen);
5582 }
5583 }
5584
5585 return EFI_SUCCESS;
5586 }
5587
5588 Link = GetNextNode (&Question->DefaultListHead, Link);
5589 }
5590 }
5591
5592 //
5593 // EFI_ONE_OF_OPTION
5594 //
5595 if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {
5596 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
5597 //
5598 // OneOfOption could only provide Standard and Manufacturing default
5599 //
5600 Link = GetFirstNode (&Question->OptionListHead);
5601 while (!IsNull (&Question->OptionListHead, Link)) {
5602 Option = HII_QUESTION_OPTION_FROM_LINK (Link);
5603 Link = GetNextNode (&Question->OptionListHead, Link);
5604
5605 if ((Option->SuppressExpression != NULL) &&
5606 (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))
5607 {
5608 continue;
5609 }
5610
5611 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||
5612 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))
5613 )
5614 {
5615 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));
5616
5617 return EFI_SUCCESS;
5618 }
5619 }
5620 }
5621 }
5622
5623 //
5624 // EFI_IFR_CHECKBOX - lowest priority
5625 //
5626 if (Question->Operand == EFI_IFR_CHECKBOX_OP) {
5627 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
5628 //
5629 // Checkbox could only provide Standard and Manufacturing default
5630 //
5631 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->ExtraData.Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||
5632 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->ExtraData.Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))
5633 )
5634 {
5635 HiiValue->Value.b = TRUE;
5636 }
5637
5638 return EFI_SUCCESS;
5639 }
5640 }
5641
5642 //
5643 // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.
5644 // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.
5645 // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.
5646 //
5647 while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {
5648 DefaultStore = HII_FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink);
5649 DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);
5650 DefaultId = DefaultStore->DefaultId;
5651 if (DefaultId == OriginalDefaultId) {
5652 continue;
5653 }
5654
5655 goto ReGetDefault;
5656 }
5657
5658 //
5659 // For Questions without default value for all the default id in the DefaultStoreList.
5660 //
5661 Status = EFI_NOT_FOUND;
5662 switch (Question->Operand) {
5663 case EFI_IFR_CHECKBOX_OP:
5664 HiiValue->Value.b = FALSE;
5665 Status = EFI_SUCCESS;
5666 break;
5667
5668 case EFI_IFR_NUMERIC_OP:
5669 //
5670 // Take minimum value as numeric default value
5671 //
5672 if ((Question->ExtraData.NumData.Flags & EFI_IFR_DISPLAY) == 0) {
5673 //
5674 // In EFI_IFR_DISPLAY_INT_DEC type, should check value with int* type.
5675 //
5676 switch (Question->ExtraData.NumData.Flags & EFI_IFR_NUMERIC_SIZE) {
5677 case EFI_IFR_NUMERIC_SIZE_1:
5678 if (((INT8)HiiValue->Value.u8 < (INT8)Question->ExtraData.NumData.Minimum) || ((INT8)HiiValue->Value.u8 > (INT8)Question->ExtraData.NumData.Maximum)) {
5679 HiiValue->Value.u8 = (UINT8)Question->ExtraData.NumData.Minimum;
5680 Status = EFI_SUCCESS;
5681 }
5682
5683 break;
5684 case EFI_IFR_NUMERIC_SIZE_2:
5685 if (((INT16)HiiValue->Value.u16 < (INT16)Question->ExtraData.NumData.Minimum) || ((INT16)HiiValue->Value.u16 > (INT16)Question->ExtraData.NumData.Maximum)) {
5686 HiiValue->Value.u16 = (UINT16)Question->ExtraData.NumData.Minimum;
5687 Status = EFI_SUCCESS;
5688 }
5689
5690 break;
5691 case EFI_IFR_NUMERIC_SIZE_4:
5692 if (((INT32)HiiValue->Value.u32 < (INT32)Question->ExtraData.NumData.Minimum) || ((INT32)HiiValue->Value.u32 > (INT32)Question->ExtraData.NumData.Maximum)) {
5693 HiiValue->Value.u32 = (UINT32)Question->ExtraData.NumData.Minimum;
5694 Status = EFI_SUCCESS;
5695 }
5696
5697 break;
5698 case EFI_IFR_NUMERIC_SIZE_8:
5699 if (((INT64)HiiValue->Value.u64 < (INT64)Question->ExtraData.NumData.Minimum) || ((INT64)HiiValue->Value.u64 > (INT64)Question->ExtraData.NumData.Maximum)) {
5700 HiiValue->Value.u64 = Question->ExtraData.NumData.Minimum;
5701 Status = EFI_SUCCESS;
5702 }
5703
5704 break;
5705 default:
5706 break;
5707 }
5708 } else {
5709 if ((HiiValue->Value.u64 < Question->ExtraData.NumData.Minimum) || (HiiValue->Value.u64 > Question->ExtraData.NumData.Maximum)) {
5710 HiiValue->Value.u64 = Question->ExtraData.NumData.Minimum;
5711 Status = EFI_SUCCESS;
5712 }
5713 }
5714
5715 break;
5716
5717 case EFI_IFR_ONE_OF_OP:
5718 //
5719 // Take first oneof option as oneof's default value
5720 //
5721 Link = GetFirstNode (&Question->OptionListHead);
5722 while (!IsNull (&Question->OptionListHead, Link)) {
5723 Option = HII_QUESTION_OPTION_FROM_LINK (Link);
5724 Link = GetNextNode (&Question->OptionListHead, Link);
5725
5726 if ((Option->SuppressExpression != NULL) &&
5727 (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))
5728 {
5729 continue;
5730 }
5731
5732 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));
5733 Status = EFI_SUCCESS;
5734 break;
5735 }
5736
5737 break;
5738
5739 case EFI_IFR_ORDERED_LIST_OP:
5740 //
5741 // Take option sequence in IFR as ordered list's default value
5742 //
5743 Index = 0;
5744 Link = GetFirstNode (&Question->OptionListHead);
5745 while (!IsNull (&Question->OptionListHead, Link)) {
5746 Status = EFI_SUCCESS;
5747 Option = HII_QUESTION_OPTION_FROM_LINK (Link);
5748 Link = GetNextNode (&Question->OptionListHead, Link);
5749
5750 if ((Option->SuppressExpression != NULL) &&
5751 (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))
5752 {
5753 continue;
5754 }
5755
5756 SetArrayData (DefaultValue->Buffer, Question->Value.Type, Index, Option->Value.Value.u64);
5757
5758 Index++;
5759 if (Index >= Question->ExtraData.OrderListData.MaxContainers) {
5760 break;
5761 }
5762 }
5763
5764 break;
5765
5766 default:
5767 break;
5768 }
5769
5770 return Status;
5771}
UINT64 UINTN
INT64 INTN
UINT64 EFIAPI StrHexToUint64(IN CONST CHAR16 *String)
Definition: String.c:560
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
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINT64 EFIAPI StrDecimalToUint64(IN CONST CHAR16 *String)
Definition: String.c:456
UINT32 EFIAPI BitFieldWrite32(IN UINT32 Operand, IN UINTN StartBit, IN UINTN EndBit, IN UINT32 Value)
Definition: BitField.c:563
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
UINTN EFIAPI StrnLenS(IN CONST CHAR16 *String, IN UINTN MaxSize)
Definition: SafeString.c:119
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:310
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
UINT32 EFIAPI BitFieldRead32(IN UINT32 Operand, IN UINTN StartBit, IN UINTN EndBit)
Definition: BitField.c:527
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 *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EXPRESS_RESULT EvaluateExpressionList(IN FORM_EXPRESSION_LIST *ExpList, IN BOOLEAN Evaluate, IN FORM_BROWSER_FORMSET *FormSet OPTIONAL, IN FORM_BROWSER_FORM *Form OPTIONAL)
Definition: Expression.c:3732
EFI_HII_HANDLE *EFIAPI HiiGetHiiHandles(IN CONST EFI_GUID *PackageListGuid OPTIONAL)
Definition: HiiLib.c:286
EFI_STRING EFIAPI HiiGetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language OPTIONAL)
Definition: HiiString.c:211
EFI_STRING_ID EFIAPI HiiSetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId OPTIONAL, IN CONST EFI_STRING String, IN CONST CHAR8 *SupportedLanguages OPTIONAL)
Definition: HiiString.c:52
BOOLEAN GetQuestionValueFromForm(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_HII_HANDLE InputHiiHandle, IN EFI_GUID *FormSetGuid, IN EFI_QUESTION_ID QuestionId, OUT EFI_HII_VALUE *Value)
EFI_HII_HANDLE DevicePathToHiiHandle(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_GUID *FormsetGuid)
EFI_STATUS IfrToString(IN HII_FORMSET *FormSet, IN UINT8 Format, OUT EFI_HII_VALUE *Result)
BOOLEAN ElementValidation(IN HII_FORMSET_STORAGE *Storage, IN CHAR16 *RequestElement)
EFI_STATUS CompareHiiValue(IN EFI_HII_VALUE *Value1, IN EFI_HII_VALUE *Value2, OUT INTN *Result, IN EFI_HII_HANDLE HiiHandle OPTIONAL)
VOID AppendConfigRequest(IN OUT CHAR16 **ConfigRequest, IN OUT UINTN *SpareStrLen, IN CHAR16 *RequestElement)
EFI_STATUS EvaluateHiiExpression(IN HII_FORMSET *FormSet, IN HII_FORM *Form, IN OUT HII_EXPRESSION *Expression)
EFI_STATUS IfrMatch2(IN HII_FORMSET *FormSet, IN EFI_GUID *SyntaxType, OUT EFI_HII_VALUE *Result)
UINT8 * GetBufferForValue(IN EFI_HII_VALUE *Value)
BOOLEAN IsFormsetGuidInHiiHandle(IN EFI_HII_HANDLE HiiHandle, IN EFI_GUID *FormSetGuid)
HII_QUESTION_OPTION * ValueToOption(IN HII_STATEMENT *Question, IN HII_STATEMENT_VALUE *OptionValue)
EFI_STATUS IfrToUint(IN HII_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
EFI_STATUS NoSubmitCheck(IN HII_FORMSET *FormSet, IN OUT HII_FORM **CurrentForm, OUT HII_STATEMENT **Statement)
VOID RestoreExpressionEvaluationStackOffset(UINTN StackOffset)
VOID EFIAPI HiiStringToLowercase(IN EFI_STRING ConfigString)
HII_EXPRESSION * RuleIdToExpression(IN HII_FORM *Form, IN UINT8 RuleId)
EFI_STATUS PopExpression(OUT EFI_HII_VALUE *Value)
VOID ExtendValueToU64(IN HII_STATEMENT_VALUE *Value)
EFI_STATUS PushStack(IN OUT EFI_HII_VALUE **Stack, IN OUT EFI_HII_VALUE **StackPtr, IN OUT EFI_HII_VALUE **StackEnd, IN EFI_HII_VALUE *Data)
Definition: Expression.c:122
BOOLEAN IsTypeInUINT64(IN EFI_HII_VALUE *Value)
EFI_STATUS IfrCatenate(IN HII_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
VOID NewStringCopy(IN OUT CHAR16 **Dest, IN CHAR16 *Src)
EFI_STATUS IfrSpan(IN HII_FORMSET *FormSet, IN UINT8 Flags, OUT EFI_HII_VALUE *Result)
UINT64 HiiValueToUINT64(IN EFI_HII_VALUE *Value)
EFI_STRING_ID NewHiiString(IN CHAR16 *String, IN EFI_HII_HANDLE HiiHandle)
CHAR16 * GetOffsetFromConfigResp(IN HII_STATEMENT *Question, IN CHAR16 *ConfigResp)
EFI_STATUS SetValueByName(IN HII_FORMSET_STORAGE *Storage, IN CHAR16 *Name, IN CHAR16 *Value, OUT HII_NAME_VALUE_NODE **ReturnNode)
EFI_STATUS ValidateNoSubmit(IN HII_FORMSET *FormSet, IN HII_FORM *Form, IN HII_STATEMENT *Question)
VOID LoadFormSetStorage(IN HII_FORMSET *FormSet, IN HII_FORMSET_STORAGE *Storage)
EFI_STATUS IfrMatch(IN HII_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
BOOLEAN CheckUserPrivilege(IN EFI_GUID *Guid)
BOOLEAN IsTypeInBuffer(IN EFI_HII_VALUE *Value)
BOOLEAN ConfigRequestAdjust(IN HII_FORMSET_STORAGE *Storage, IN CHAR16 *Request, IN BOOLEAN RespString)
EFI_STATUS CreateFormSetFromHiiHandle(IN EFI_HII_HANDLE Handle, IN OUT EFI_GUID *FormSetGuid, OUT HII_FORMSET *FormSet)
Definition: HiiUtilityLib.c:30
EFI_STATUS StorageToConfigResp(IN HII_FORMSET_STORAGE *Storage, IN CHAR16 **ConfigResp, IN CHAR16 *ConfigRequest)
EFI_STATUS ReleaseHiiValue(IN EFI_HII_VALUE *HiiValue)
EFI_STATUS GetQuestionValue(IN HII_FORMSET *FormSet, IN HII_FORM *Form, IN OUT HII_STATEMENT *Question, IN GET_SET_QUESTION_VALUE_WITH GetValueFrom)
VOID GetBitsQuestionValue(IN HII_STATEMENT *Question, IN UINT8 *Buffer, OUT HII_STATEMENT_VALUE *QuestionValue)
HII_STATEMENT * QuestionIdInFormset(IN HII_FORMSET *FormSet, IN HII_FORM *Form, IN UINT16 QuestionId)
EFI_STATUS GetIfrBinaryData(IN EFI_HII_HANDLE Handle, IN OUT EFI_GUID *FormSetGuid, OUT UINTN *BinaryLength, OUT UINT8 **BinaryData)
HII_STATEMENT * QuestionIdInForm(IN HII_FORM *Form, IN UINT16 QuestionId)
VOID InitializeFormSet(IN OUT HII_FORMSET *FormSet)
VOID IfrStrToUpper(IN CHAR16 *String)
INTN GetDefaultIdForCallBack(IN UINTN DefaultId)
EFI_STATUS HiiStatementValueToHiiValue(IN HII_STATEMENT_VALUE *StatementValue, OUT EFI_HII_VALUE *HiiValue)
EFI_STATUS GetValueByName(IN HII_FORMSET_STORAGE *Storage, IN CHAR16 *Name, IN OUT CHAR16 **Value)
EFI_STATUS GetQuestionDefault(IN HII_FORMSET *FormSet, IN HII_FORM *Form, IN HII_STATEMENT *Question, IN UINT16 DefaultId, OUT HII_STATEMENT_VALUE *DefaultValue)
EFI_STATUS ConfigRespToStorage(IN HII_FORMSET_STORAGE *Storage, IN CHAR16 *ConfigResp)
EFI_STATUS IfrFind(IN HII_FORMSET *FormSet, IN UINT8 Format, OUT EFI_HII_VALUE *Result)
EFI_STATUS GetDefaultValueFromAltCfg(IN HII_FORMSET *FormSet, IN HII_FORM *Form, IN HII_STATEMENT *Question, OUT HII_STATEMENT_VALUE *DefaultValue)
VOID SetArrayData(IN VOID *Array, IN UINT8 Type, IN UINTN Index, IN UINT64 Value)
CHAR16 * GetTokenString(IN EFI_STRING_ID Token, IN EFI_HII_HANDLE HiiHandle)
EFI_STATUS InitializeUnicodeCollationProtocol(VOID)
EFI_STATUS PushExpression(IN EFI_HII_VALUE *Value)
UINT16 GetLengthForValue(IN EFI_HII_VALUE *Value)
VOID NewStringCat(IN OUT CHAR16 **Dest, IN CHAR16 *Src)
BOOLEAN IsHiiValueTrue(IN EFI_HII_VALUE *Result)
EFI_STATUS BufferToQuestionValue(IN HII_STATEMENT *Question, IN CHAR16 *Value, OUT HII_STATEMENT_VALUE *QuestionValue)
UINTN SaveExpressionEvaluationStackOffset(VOID)
VOID SetBitsQuestionValue(IN HII_STATEMENT *Question, IN OUT UINT8 *Buffer, IN UINT32 Value)
EFI_STATUS IfrToken(IN HII_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
EFI_STATUS IfrMid(IN HII_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
EFI_STATUS PopStack(IN EFI_HII_VALUE *Stack, IN OUT EFI_HII_VALUE **StackPtr, OUT EFI_HII_VALUE *Data)
Definition: Expression.c:170
VOID DestroyFormSet(IN OUT FORM_BROWSER_FORMSET *FormSet)
Definition: IfrParse.c:943
FORMSET_STORAGE * GetFstStgFromVarId(IN FORM_BROWSER_FORMSET *FormSet, IN EFI_VARSTORE_ID VarStoreId)
Definition: IfrParse.c:467
RETURN_STATUS EFIAPI UnicodeValueToStringS(IN OUT CHAR16 *Buffer, IN UINTN BufferSize, IN UINTN Flags, IN INT64 Value, IN UINTN Width)
Definition: PrintLib.c:652
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
EFI_RUNTIME_SERVICES * gRT
#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
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define MAXIMUM_VALUE_CHARACTERS
Definition: PrintLib.h:189
GET_SET_QUESTION_VALUE_WITH
Definition: Setup.h:560
@ TypeValue
A flag that has some data following it with a space (IE "-a 1").
Definition: ShellLib.h:700
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define EFI_IFR_STRING_UNSIGNED_DEC
#define EFI_IFR_STRING_ASCII
VOID * EFI_HII_HANDLE
@ ByProtocol
Definition: UefiSpec.h:1518
#define EFI_USER_INFO_ACCESS_SETUP
Definition: UserManager.h:216
#define EFI_USER_INFO_ACCESS_POLICY_RECORD
Definition: UserManager.h:175
HII_FORMSET_STORAGE * Storage
Point to the storage that store this question.
EFI_QUESTION_ID QuestionId
Question id, the value of zero is reserved.
UINT32 Size
Specifies the size of the user access control record, in bytes, including this header.
Definition: UserManager.h:179
UINT32 Type
Specifies the type of user access control.
Definition: UserManager.h:178
UINT8 InfoType
Definition: UserManager.h:57
UINT32 InfoSize
Definition: UserManager.h:69
Definition: Base.h:213
LIST_ENTRY MapExpressionList
nested expressions inside of Map opcode.
EFI_HII_VALUE Result
Expression evaluation result.
UINT8 Type
Type for this expression.
Definition of HII_FORM_CONFIG_REQUEST.
Definition: HiiInternal.h:48
CHAR16 * ConfigAltResp
Alt config response string for this ConfigRequest.
Definition: HiiInternal.h:53
LIST_ENTRY StatementListHead
List of Statements and Questions (HII_STATEMENT)
UINT8 * Buffer
Buffer storage.
Definition: HiiUtilityLib.h:79
UINT8 * EditBuffer
Edit copy for Buffer Storage.
Definition: HiiUtilityLib.h:80
EFI_GUID Guid
VarStore Guid.
Definition: HiiDatabase.h:144
UINT8 Type
Storage type.
Definition: HiiDatabase.h:143
CHAR16 * ConfigHdr
<ConfigHdr>
Definition: HiiUtilityLib.h:92
LIST_ENTRY FormListHead
Form list (HII_FORM_BROWSER_FORM)
HII_EXPRESSION * ValueExpression
Not-NULL indicates default value is provided by EFI_IFR_VALUE.
HII_STATEMENT_VALUE Value
Default value.
HII_EXPRESSION_LIST * SuppressExpression
Non-NULL indicates nested inside of SuppressIf.
EFI_STRING_ID string
EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION.
EFI_HII_VALUE Value
EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_IFR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1.
EFI_GUID Guid
For EFI_IFR_SECURITY, EFI_IFR_MATCH2.
UINT8 RuleId
For EFI_IFR_RULE_REF.
UINT8 Flags
For EFI_IFR_SPAN.
EFI_STRING_ID DevicePath
For EFI_IFR_QUESTION_REF3_3.
EFI_QUESTION_ID QuestionId
For EFI_IFR_EQ_ID_VAL_LIST.
UINT8 Format
For EFI_IFR_TO_STRING, EFI_IFR_FIND.
UINT8 RuleId
For EFI_IFR_RULE only.