TianoCore EDK2 master
Loading...
Searching...
No Matches
ConfigRouting.c
Go to the documentation of this file.
1
9#include "HiiDatabase.h"
10extern HII_DATABASE_PRIVATE_DATA mPrivate;
11
26 IN EFI_STRING String
27 )
28{
29 EFI_STRING TmpPtr;
30
31 //
32 // "GUID=" should be the first element of incoming string.
33 //
34 ASSERT (String != NULL);
35 ASSERT (StrnCmp (String, L"GUID=", StrLen (L"GUID=")) == 0);
36
37 //
38 // The beginning of next <ConfigRequest>/<ConfigResp> should be "&GUID=".
39 // Will meet '\0' if there is only one <ConfigRequest>/<ConfigResp>.
40 //
41 TmpPtr = StrStr (String, L"&GUID=");
42 if (TmpPtr == NULL) {
43 return StrLen (String);
44 }
45
46 return (TmpPtr - String);
47}
48
67 IN EFI_STRING String,
68 OUT UINT8 **DevicePathData
69 )
70{
71 UINTN Length;
72 EFI_STRING PathHdr;
73 UINT8 *DevicePathBuffer;
74 CHAR16 TemStr[2];
75 UINTN Index;
76 UINT8 DigitUint8;
77 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
78
79 if ((String == NULL) || (DevicePathData == NULL)) {
80 return EFI_INVALID_PARAMETER;
81 }
82
83 //
84 // Find the 'PATH=' of <PathHdr> and skip it.
85 //
86 for ( ; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++) {
87 }
88
89 if (*String == 0) {
90 return EFI_INVALID_PARAMETER;
91 }
92
93 //
94 // Check whether path data does exist.
95 //
96 String += StrLen (L"PATH=");
97 if (*String == 0) {
98 return EFI_INVALID_PARAMETER;
99 }
100
101 PathHdr = String;
102
103 //
104 // The content between 'PATH=' of <ConfigHdr> and '&' of next element
105 // or '\0' (end of configuration string) is the UNICODE %02x bytes encoding
106 // of UEFI device path.
107 //
108 for (Length = 0; *String != 0 && *String != L'&'; String++, Length++) {
109 }
110
111 //
112 // Check DevicePath Length
113 //
114 if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
115 return EFI_NOT_FOUND;
116 }
117
118 //
119 // The data in <PathHdr> is encoded as hex UNICODE %02x bytes in the same order
120 // as the device path resides in RAM memory.
121 // Translate the data into binary.
122 //
123 DevicePathBuffer = (UINT8 *)AllocateZeroPool ((Length + 1) / 2);
124 if (DevicePathBuffer == NULL) {
125 return EFI_OUT_OF_RESOURCES;
126 }
127
128 //
129 // Convert DevicePath
130 //
131 ZeroMem (TemStr, sizeof (TemStr));
132 for (Index = 0; Index < Length; Index++) {
133 TemStr[0] = PathHdr[Index];
134 DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
135 if ((Index & 1) == 0) {
136 DevicePathBuffer[Index/2] = DigitUint8;
137 } else {
138 DevicePathBuffer[Index/2] = (UINT8)((DevicePathBuffer[Index/2] << 4) + DigitUint8);
139 }
140 }
141
142 //
143 // Validate DevicePath
144 //
145 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathBuffer;
146 while (!IsDevicePathEnd (DevicePath)) {
147 if ((DevicePath->Type == 0) || (DevicePath->SubType == 0) || (DevicePathNodeLength (DevicePath) < sizeof (EFI_DEVICE_PATH_PROTOCOL))) {
148 //
149 // Invalid device path
150 //
151 FreePool (DevicePathBuffer);
152 return EFI_NOT_FOUND;
153 }
154
155 DevicePath = NextDevicePathNode (DevicePath);
156 }
157
158 //
159 // return the device path
160 //
161 *DevicePathData = DevicePathBuffer;
162 return EFI_SUCCESS;
163}
164
172VOID
173EFIAPI
175 IN EFI_STRING ConfigString
176 )
177{
178 EFI_STRING String;
179 BOOLEAN Lower;
180
181 ASSERT (ConfigString != NULL);
182
183 //
184 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
185 //
186 for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
187 if (*String == L'=') {
188 Lower = TRUE;
189 } else if (*String == L'&') {
190 Lower = FALSE;
191 } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
192 *String = (CHAR16)(*String - L'A' + L'a');
193 }
194 }
195
196 return;
197}
198
221VOID
223 IN CONST EFI_STRING String,
224 IN UINTN BufferLen,
225 IN VOID *Buffer,
226 IN UINT8 Flag,
227 OUT EFI_STRING *SubStr
228 )
229{
230 UINTN Length;
231 EFI_STRING Str;
232 EFI_STRING StringHeader;
233 CHAR16 *TemString;
234 CHAR16 *TemName;
235 UINT8 *TemBuffer;
236 UINTN Index;
237
238 ASSERT (String != NULL && SubStr != NULL);
239
240 if (Buffer == NULL) {
241 *SubStr = AllocateCopyPool (StrSize (String), String);
242 ASSERT (*SubStr != NULL);
243 return;
244 }
245
246 //
247 // Header + Data + '&' + '\0'
248 //
249 Length = StrLen (String) + BufferLen * 2 + 1 + 1;
250 Str = AllocateZeroPool (Length * sizeof (CHAR16));
251 ASSERT (Str != NULL);
252
253 StrCpyS (Str, Length, String);
254
255 StringHeader = Str + StrLen (String);
256 TemString = (CHAR16 *)StringHeader;
257
258 switch (Flag) {
259 case 1:
260 //
261 // Convert Buffer to Hex String in reverse order
262 //
263 TemBuffer = ((UINT8 *)Buffer);
264 for (Index = 0; Index < BufferLen; Index++, TemBuffer++) {
266 TemString,
267 sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),
268 PREFIX_ZERO | RADIX_HEX,
269 *TemBuffer,
270 2
271 );
272 TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));
273 }
274
275 break;
276 case 2:
277 //
278 // Check buffer is enough
279 //
280 TemName = (CHAR16 *)Buffer;
281 ASSERT ((BufferLen * 2 + 1) >= (StrLen (TemName) * 4 + 1));
282 //
283 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
284 //
285 for ( ; *TemName != L'\0'; TemName++) {
287 TemString,
288 sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),
289 PREFIX_ZERO | RADIX_HEX,
290 *TemName,
291 4
292 );
293 TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));
294 }
295
296 break;
297 case 3:
298 //
299 // Convert Buffer to Hex String
300 //
301 TemBuffer = ((UINT8 *)Buffer) + BufferLen - 1;
302 for (Index = 0; Index < BufferLen; Index++, TemBuffer--) {
304 TemString,
305 sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),
306 PREFIX_ZERO | RADIX_HEX,
307 *TemBuffer,
308 2
309 );
310 TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));
311 }
312
313 break;
314 default:
315 break;
316 }
317
318 //
319 // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
320 //
321 StrCatS (Str, Length, L"&");
322 HiiToLower (Str);
323
324 *SubStr = Str;
325}
326
344 IN EFI_STRING String,
345 OUT EFI_STRING *ConfigBody
346 )
347{
348 EFI_STRING TmpPtr;
349 EFI_STRING Result;
350 UINTN Length;
351
352 if ((String == NULL) || (ConfigBody == NULL)) {
353 return EFI_INVALID_PARAMETER;
354 }
355
356 //
357 // The setting information should start OFFSET, not ALTCFG.
358 //
359 if (StrnCmp (String, L"&ALTCFG=", StrLen (L"&ALTCFG=")) == 0) {
360 return EFI_INVALID_PARAMETER;
361 }
362
363 TmpPtr = StrStr (String, L"GUID=");
364 if (TmpPtr == NULL) {
365 //
366 // It is the last <ConfigResp> of the incoming configuration string.
367 //
368 Result = AllocateCopyPool (StrSize (String), String);
369 if (Result == NULL) {
370 return EFI_OUT_OF_RESOURCES;
371 } else {
372 *ConfigBody = Result;
373 return EFI_SUCCESS;
374 }
375 }
376
377 Length = TmpPtr - String;
378 if (Length == 0) {
379 return EFI_NOT_FOUND;
380 }
381
382 Result = AllocateCopyPool (Length * sizeof (CHAR16), String);
383 if (Result == NULL) {
384 return EFI_OUT_OF_RESOURCES;
385 }
386
387 *(Result + Length - 1) = 0;
388 *ConfigBody = Result;
389 return EFI_SUCCESS;
390}
391
410 IN OUT EFI_STRING *MultiString,
411 IN EFI_STRING AppendString
412 )
413{
414 UINTN AppendStringSize;
415 UINTN MultiStringSize;
416 UINTN MaxLen;
417
418 if ((MultiString == NULL) || (*MultiString == NULL) || (AppendString == NULL)) {
419 return EFI_INVALID_PARAMETER;
420 }
421
422 AppendStringSize = StrSize (AppendString);
423 MultiStringSize = StrSize (*MultiString);
424 MaxLen = MAX_STRING_LENGTH / sizeof (CHAR16);
425
426 //
427 // Enlarge the buffer each time when length exceeds MAX_STRING_LENGTH.
428 //
429 if ((MultiStringSize + AppendStringSize > MAX_STRING_LENGTH) ||
430 (MultiStringSize > MAX_STRING_LENGTH))
431 {
432 *MultiString = (EFI_STRING)ReallocatePool (
433 MultiStringSize,
434 MultiStringSize + AppendStringSize,
435 (VOID *)(*MultiString)
436 );
437 MaxLen = (MultiStringSize + AppendStringSize) / sizeof (CHAR16);
438 ASSERT (*MultiString != NULL);
439 }
440
441 //
442 // Append the incoming string
443 //
444 StrCatS (*MultiString, MaxLen, AppendString);
445
446 return EFI_SUCCESS;
447}
448
470 IN EFI_STRING StringPtr,
471 OUT UINT8 **Number,
472 OUT UINTN *Len
473 )
474{
475 EFI_STRING TmpPtr;
476 UINTN Length;
477 EFI_STRING Str;
478 UINT8 *Buf;
479 EFI_STATUS Status;
480 UINT8 DigitUint8;
481 UINTN Index;
482 CHAR16 TemStr[2];
483
484 if ((StringPtr == NULL) || (*StringPtr == L'\0') || (Number == NULL) || (Len == NULL)) {
485 return EFI_INVALID_PARAMETER;
486 }
487
488 Buf = NULL;
489
490 TmpPtr = StringPtr;
491 while (*StringPtr != L'\0' && *StringPtr != L'&') {
492 StringPtr++;
493 }
494
495 *Len = StringPtr - TmpPtr;
496 Length = *Len + 1;
497
498 Str = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));
499 if (Str == NULL) {
500 Status = EFI_OUT_OF_RESOURCES;
501 goto Exit;
502 }
503
504 CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));
505 *(Str + *Len) = L'\0';
506
507 Length = (Length + 1) / 2;
508 Buf = (UINT8 *)AllocateZeroPool (Length);
509 if (Buf == NULL) {
510 Status = EFI_OUT_OF_RESOURCES;
511 goto Exit;
512 }
513
514 Length = *Len;
515 ZeroMem (TemStr, sizeof (TemStr));
516 for (Index = 0; Index < Length; Index++) {
517 TemStr[0] = Str[Length - Index - 1];
518 DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
519 if ((Index & 1) == 0) {
520 Buf[Index/2] = DigitUint8;
521 } else {
522 Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);
523 }
524 }
525
526 *Number = Buf;
527 Status = EFI_SUCCESS;
528
529Exit:
530 if (Str != NULL) {
531 FreePool (Str);
532 }
533
534 return Status;
535}
536
552 IN EFI_STRING String,
553 IN EFI_STRING BlockName,
554 IN UINT8 *Buffer,
555 OUT BOOLEAN *Found,
556 IN UINTN BufferLen
557 )
558{
559 EFI_STRING BlockPtr;
560 UINTN Length;
561 UINT8 *TempBuffer;
562 EFI_STATUS Status;
563
564 TempBuffer = NULL;
565 *Found = FALSE;
566 BlockPtr = StrStr (String, BlockName);
567
568 while (BlockPtr != NULL) {
569 BlockPtr += StrLen (BlockName);
570 Status = GetValueOfNumber (BlockPtr, &TempBuffer, &Length);
571 if (EFI_ERROR (Status)) {
572 return Status;
573 }
574
575 ASSERT (TempBuffer != NULL);
576 if ((BufferLen == Length) && (0 == CompareMem (Buffer, TempBuffer, Length))) {
577 *Found = TRUE;
578 FreePool (TempBuffer);
579 TempBuffer = NULL;
580 return EFI_SUCCESS;
581 } else {
582 FreePool (TempBuffer);
583 TempBuffer = NULL;
584 BlockPtr = StrStr (BlockPtr + 1, BlockName);
585 }
586 }
587
588 return EFI_SUCCESS;
589}
590
610 IN EFI_STRING DefaultAltCfgResp,
611 IN OUT EFI_STRING *ConfigAltResp,
612 IN EFI_STRING AltConfigHdr,
613 IN OUT BOOLEAN *ConfigAltRespChanged
614 )
615{
616 EFI_STATUS Status;
617 EFI_STRING BlockPtr;
618 EFI_STRING BlockPtrStart;
619 EFI_STRING StringPtr;
620 EFI_STRING AppendString;
621 EFI_STRING AltConfigHdrPtr;
622 UINT8 *TempBuffer;
623 UINTN OffsetLength;
624 UINTN AppendSize;
625 UINTN TotalSize;
626 BOOLEAN FoundOffset;
627
628 AppendString = NULL;
629 TempBuffer = NULL;
630 //
631 // Make BlockPtr point to the first <BlockConfig> with AltConfigHdr in DefaultAltCfgResp.
632 //
633 AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);
634 ASSERT (AltConfigHdrPtr != NULL);
635 BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");
636 //
637 // Make StringPtr point to the AltConfigHdr in ConfigAltResp.
638 //
639 StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);
640 ASSERT (StringPtr != NULL);
641
642 while (BlockPtr != NULL) {
643 //
644 // Find the "&OFFSET=<Number>" block and get the value of the Number with AltConfigHdr in DefaultAltCfgResp.
645 //
646 BlockPtrStart = BlockPtr;
647 BlockPtr += StrLen (L"&OFFSET=");
648 Status = GetValueOfNumber (BlockPtr, &TempBuffer, &OffsetLength);
649 if (EFI_ERROR (Status)) {
650 Status = EFI_OUT_OF_RESOURCES;
651 goto Exit;
652 }
653
654 //
655 // To find the same "&OFFSET=<Number>" block in ConfigAltResp.
656 //
657 Status = FindSameBlockElement (StringPtr, L"&OFFSET=", TempBuffer, &FoundOffset, OffsetLength);
658 if (TempBuffer != NULL) {
659 FreePool (TempBuffer);
660 TempBuffer = NULL;
661 }
662
663 if (EFI_ERROR (Status)) {
664 Status = EFI_OUT_OF_RESOURCES;
665 goto Exit;
666 }
667
668 if (!FoundOffset) {
669 //
670 // Don't find the same "&OFFSET=<Number>" block in ConfigAltResp.
671 // Calculate the size of <BlockConfig>.
672 // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number>.
673 //
674 BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");
675 if (BlockPtr != NULL) {
676 AppendSize = (BlockPtr - BlockPtrStart) * sizeof (CHAR16);
677 } else {
678 AppendSize = StrSize (BlockPtrStart);
679 }
680
681 //
682 // Copy the <BlockConfig> to AppendString.
683 //
684 if (AppendString == NULL) {
685 AppendString = (EFI_STRING)AllocateZeroPool (AppendSize + sizeof (CHAR16));
686 StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, BlockPtrStart, AppendSize / sizeof (CHAR16));
687 } else {
688 TotalSize = StrSize (AppendString) + AppendSize + sizeof (CHAR16);
689 AppendString = (EFI_STRING)ReallocatePool (
690 StrSize (AppendString),
691 TotalSize,
692 AppendString
693 );
694 if (AppendString == NULL) {
695 Status = EFI_OUT_OF_RESOURCES;
696 goto Exit;
697 }
698
699 StrnCatS (AppendString, TotalSize / sizeof (CHAR16), BlockPtrStart, AppendSize / sizeof (CHAR16));
700 }
701 } else {
702 //
703 // To find next "&OFFSET=<Number>" block with AltConfigHdr in DefaultAltCfgResp.
704 //
705 BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");
706 }
707 }
708
709 if (AppendString != NULL) {
710 //
711 // Reallocate ConfigAltResp to copy the AppendString.
712 //
713 TotalSize = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);
714 *ConfigAltResp = (EFI_STRING)ReallocatePool (
715 StrSize (*ConfigAltResp),
716 TotalSize,
717 *ConfigAltResp
718 );
719 if (*ConfigAltResp == NULL) {
720 Status = EFI_OUT_OF_RESOURCES;
721 goto Exit;
722 }
723
724 StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);
725 *ConfigAltRespChanged = TRUE;
726 }
727
728 Status = EFI_SUCCESS;
729
730Exit:
731 if (AppendString != NULL) {
732 FreePool (AppendString);
733 }
734
735 return Status;
736}
737
757 IN EFI_STRING DefaultAltCfgResp,
758 IN OUT EFI_STRING *ConfigAltResp,
759 IN EFI_STRING AltConfigHdr,
760 IN OUT BOOLEAN *ConfigAltRespChanged
761 )
762{
763 EFI_STATUS Status;
764 EFI_STRING NvConfigPtr;
765 EFI_STRING NvConfigStart;
766 EFI_STRING NvConfigValuePtr;
767 EFI_STRING StringPtr;
768 EFI_STRING NvConfigExist;
769 EFI_STRING AppendString;
770 CHAR16 TempChar;
771 UINTN AppendSize;
772 UINTN TotalSize;
773
774 AppendString = NULL;
775 NvConfigExist = NULL;
776 //
777 // Make NvConfigPtr point to the first <NvConfig> with AltConfigHdr in DefaultAltCfgResp.
778 //
779 NvConfigPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);
780 ASSERT (NvConfigPtr != NULL);
781 NvConfigPtr = StrStr (NvConfigPtr + StrLen (AltConfigHdr), L"&");
782 //
783 // Make StringPtr point to the first <NvConfig> with AltConfigHdr in ConfigAltResp.
784 //
785 StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);
786 ASSERT (StringPtr != NULL);
787 StringPtr = StrStr (StringPtr + StrLen (AltConfigHdr), L"&");
788 ASSERT (StringPtr != NULL);
789
790 while (NvConfigPtr != NULL) {
791 //
792 // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number>.
793 // Get the <Label> with AltConfigHdr in DefaultAltCfgResp.
794 //
795 NvConfigStart = NvConfigPtr;
796 NvConfigValuePtr = StrStr (NvConfigPtr + 1, L"=");
797 ASSERT (NvConfigValuePtr != NULL);
798 TempChar = *NvConfigValuePtr;
799 *NvConfigValuePtr = L'\0';
800 //
801 // Get the <Label> with AltConfigHdr in ConfigAltResp.
802 //
803 NvConfigExist = StrStr (StringPtr, NvConfigPtr);
804 if (NvConfigExist == NULL) {
805 //
806 // Don't find same <Label> in ConfigAltResp.
807 // Calculate the size of <NvConfig>.
808 //
809 *NvConfigValuePtr = TempChar;
810 NvConfigPtr = StrStr (NvConfigPtr + 1, L"&");
811 if (NvConfigPtr != NULL) {
812 AppendSize = (NvConfigPtr - NvConfigStart) * sizeof (CHAR16);
813 } else {
814 AppendSize = StrSize (NvConfigStart);
815 }
816
817 //
818 // Copy the <NvConfig> to AppendString.
819 //
820 if (AppendString == NULL) {
821 AppendString = (EFI_STRING)AllocateZeroPool (AppendSize + sizeof (CHAR16));
822 StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, NvConfigStart, AppendSize / sizeof (CHAR16));
823 } else {
824 TotalSize = StrSize (AppendString) + AppendSize + sizeof (CHAR16);
825 AppendString = (EFI_STRING)ReallocatePool (
826 StrSize (AppendString),
827 TotalSize,
828 AppendString
829 );
830 if (AppendString == NULL) {
831 Status = EFI_OUT_OF_RESOURCES;
832 goto Exit;
833 }
834
835 StrnCatS (AppendString, TotalSize / sizeof (CHAR16), NvConfigStart, AppendSize / sizeof (CHAR16));
836 }
837 } else {
838 //
839 // To find next <Label> in DefaultAltCfgResp.
840 //
841 *NvConfigValuePtr = TempChar;
842 NvConfigPtr = StrStr (NvConfigPtr + 1, L"&");
843 }
844 }
845
846 if (AppendString != NULL) {
847 //
848 // Reallocate ConfigAltResp to copy the AppendString.
849 //
850 TotalSize = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);
851 *ConfigAltResp = (EFI_STRING)ReallocatePool (
852 StrSize (*ConfigAltResp),
853 StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16),
854 *ConfigAltResp
855 );
856 if (*ConfigAltResp == NULL) {
857 Status = EFI_OUT_OF_RESOURCES;
858 goto Exit;
859 }
860
861 StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);
862 *ConfigAltRespChanged = TRUE;
863 }
864
865 Status = EFI_SUCCESS;
866
867Exit:
868 if (AppendString != NULL) {
869 FreePool (AppendString);
870 }
871
872 return Status;
873}
874
894 IN OUT EFI_STRING *AltCfgResp,
895 IN EFI_STRING DefaultAltCfgResp,
896 IN EFI_STRING AltConfigHdr
897 )
898{
899 EFI_STATUS Status;
900 EFI_STRING AltCfgRespBackup;
901 EFI_STRING AltConfigHdrPtr;
902 EFI_STRING AltConfigHdrPtrNext;
903 EFI_STRING ConfigAltResp;
904 EFI_STRING StringPtr;
905 EFI_STRING StringPtrNext;
906 EFI_STRING BlockPtr;
907 UINTN ReallocateSize;
908 CHAR16 TempChar;
909 CHAR16 TempCharA;
910 BOOLEAN ConfigAltRespChanged;
911
912 Status = EFI_OUT_OF_RESOURCES;
913 BlockPtr = NULL;
914 AltConfigHdrPtrNext = NULL;
915 StringPtrNext = NULL;
916 ConfigAltResp = NULL;
917 AltCfgRespBackup = NULL;
918 TempChar = L'\0';
919 TempCharA = L'\0';
920 ConfigAltRespChanged = FALSE;
921
922 //
923 // To find the <AltResp> with AltConfigHdr in DefaultAltCfgResp, ignore other <AltResp> which follow it.
924 //
925 AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);
926 ASSERT (AltConfigHdrPtr != NULL);
927 AltConfigHdrPtrNext = StrStr (AltConfigHdrPtr + 1, L"&GUID");
928 if (AltConfigHdrPtrNext != NULL) {
929 TempChar = *AltConfigHdrPtrNext;
930 *AltConfigHdrPtrNext = L'\0';
931 }
932
933 //
934 // To find the <AltResp> with AltConfigHdr in AltCfgResp, ignore other <AltResp> which follow it.
935 //
936 StringPtr = StrStr (*AltCfgResp, AltConfigHdr);
937 ASSERT (StringPtr != NULL);
938 StringPtrNext = StrStr (StringPtr + 1, L"&GUID");
939 if (StringPtrNext != NULL) {
940 TempCharA = *StringPtrNext;
941 *StringPtrNext = L'\0';
942 }
943
944 //
945 // Copy the content of <ConfigAltResp> which contain current AltConfigHdr in AltCfgResp.
946 //
947 ConfigAltResp = AllocateCopyPool (StrSize (*AltCfgResp), *AltCfgResp);
948 if (ConfigAltResp == NULL) {
949 goto Exit;
950 }
951
952 //
953 // To find the <ConfigBody> with AltConfigHdr in DefaultAltCfgResp.
954 //
955 BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");
956 if (BlockPtr != NULL) {
957 //
958 // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number> style.
959 // Call function CompareBlockElementDefault to compare the <BlockConfig> in DefaultAltCfgResp and ConfigAltResp.
960 // The ConfigAltResp which may contain the new <BlockConfig> get from DefaultAltCfgResp.
961 //
962 Status = CompareBlockElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);
963 if (EFI_ERROR (Status)) {
964 goto Exit;
965 }
966 } else {
967 //
968 // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number> style.
969 // Call function CompareNameElementDefault to compare the <NvConfig> in DefaultAltCfgResp and ConfigAltResp.
970 // The ConfigAltResp which may contain the new <NvConfig> get from DefaultAltCfgResp.
971 //
972 Status = CompareNameElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);
973 if (EFI_ERROR (Status)) {
974 goto Exit;
975 }
976 }
977
978 //
979 // Restore the AltCfgResp.
980 //
981 if (StringPtrNext != NULL) {
982 *StringPtrNext = TempCharA;
983 }
984
985 //
986 // If the ConfigAltResp has no change,no need to update the content in AltCfgResp.
987 //
988 if (!ConfigAltRespChanged) {
989 Status = EFI_SUCCESS;
990 goto Exit;
991 }
992
993 //
994 // ConfigAltResp has been changed, need to update the content in AltCfgResp.
995 //
996 if (StringPtrNext != NULL) {
997 ReallocateSize = StrSize (ConfigAltResp) + StrSize (StringPtrNext) + sizeof (CHAR16);
998 } else {
999 ReallocateSize = StrSize (ConfigAltResp) + sizeof (CHAR16);
1000 }
1001
1002 AltCfgRespBackup = (EFI_STRING)AllocateZeroPool (ReallocateSize);
1003 if (AltCfgRespBackup == NULL) {
1004 goto Exit;
1005 }
1006
1007 StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), ConfigAltResp);
1008 if (StringPtrNext != NULL) {
1009 StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), StringPtrNext);
1010 }
1011
1012 FreePool (*AltCfgResp);
1013 *AltCfgResp = AltCfgRespBackup;
1014
1015 Status = EFI_SUCCESS;
1016
1017Exit:
1018 if (ConfigAltResp != NULL) {
1019 FreePool (ConfigAltResp);
1020 }
1021
1022 //
1023 // Restore the DefaultAltCfgResp.
1024 //
1025 if ( AltConfigHdrPtrNext != NULL) {
1026 *AltConfigHdrPtrNext = TempChar;
1027 AltConfigHdrPtrNext = NULL;
1028 }
1029
1030 return Status;
1031}
1032
1049EFIAPI
1051 IN OUT EFI_STRING *AltCfgResp,
1052 IN EFI_STRING DefaultAltCfgResp
1053 )
1054{
1055 EFI_STRING StringPtrDefault;
1056 EFI_STRING StringPtrEnd;
1057 CHAR16 TempChar;
1058 EFI_STRING StringPtr;
1059 EFI_STRING AltConfigHdr;
1060 UINTN HeaderLength;
1061 UINTN SizeAltCfgResp;
1062 UINTN MaxLen;
1063 UINTN TotalSize;
1064
1065 if (*AltCfgResp == NULL) {
1066 return EFI_INVALID_PARAMETER;
1067 }
1068
1069 //
1070 // Get the request ConfigHdr
1071 //
1072 SizeAltCfgResp = 0;
1073 StringPtr = *AltCfgResp;
1074
1075 //
1076 // Find <ConfigHdr> GUID=...&NAME=...&PATH=...
1077 //
1078 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
1079 return EFI_INVALID_PARAMETER;
1080 }
1081
1082 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
1083 StringPtr++;
1084 }
1085
1086 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
1087 StringPtr++;
1088 }
1089
1090 if (*StringPtr == L'\0') {
1091 return EFI_INVALID_PARAMETER;
1092 }
1093
1094 StringPtr += StrLen (L"&PATH=");
1095 while (*StringPtr != L'\0' && *StringPtr != L'&') {
1096 StringPtr++;
1097 }
1098
1099 HeaderLength = StringPtr - *AltCfgResp;
1100
1101 //
1102 // Construct AltConfigHdr string "&<ConfigHdr>&ALTCFG=XXXX\0"
1103 // |1| StrLen (ConfigHdr) | 8 | 4 | 1 |
1104 //
1105 MaxLen = 1 + HeaderLength + 8 + 4 + 1;
1106 AltConfigHdr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
1107 if (AltConfigHdr == NULL) {
1108 return EFI_OUT_OF_RESOURCES;
1109 }
1110
1111 StrCpyS (AltConfigHdr, MaxLen, L"&");
1112 StrnCatS (AltConfigHdr, MaxLen, *AltCfgResp, HeaderLength);
1113 StrCatS (AltConfigHdr, MaxLen, L"&ALTCFG=");
1114 HeaderLength = StrLen (AltConfigHdr);
1115
1116 StringPtrDefault = StrStr (DefaultAltCfgResp, AltConfigHdr);
1117 while (StringPtrDefault != NULL) {
1118 //
1119 // Get AltCfg Name
1120 //
1121 StrnCatS (AltConfigHdr, MaxLen, StringPtrDefault + HeaderLength, 4);
1122 StringPtr = StrStr (*AltCfgResp, AltConfigHdr);
1123
1124 //
1125 // Append the found default value string to the input AltCfgResp
1126 //
1127 if (StringPtr == NULL) {
1128 StringPtrEnd = StrStr (StringPtrDefault + 1, L"&GUID");
1129 SizeAltCfgResp = StrSize (*AltCfgResp);
1130 if (StringPtrEnd == NULL) {
1131 //
1132 // No more default string is found.
1133 //
1134 TotalSize = SizeAltCfgResp + StrSize (StringPtrDefault);
1135 *AltCfgResp = (EFI_STRING)ReallocatePool (
1136 SizeAltCfgResp,
1137 TotalSize,
1138 (VOID *)(*AltCfgResp)
1139 );
1140 if (*AltCfgResp == NULL) {
1141 FreePool (AltConfigHdr);
1142 return EFI_OUT_OF_RESOURCES;
1143 }
1144
1145 StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);
1146 break;
1147 } else {
1148 TempChar = *StringPtrEnd;
1149 *StringPtrEnd = L'\0';
1150 TotalSize = SizeAltCfgResp + StrSize (StringPtrDefault);
1151 *AltCfgResp = (EFI_STRING)ReallocatePool (
1152 SizeAltCfgResp,
1153 TotalSize,
1154 (VOID *)(*AltCfgResp)
1155 );
1156 if (*AltCfgResp == NULL) {
1157 FreePool (AltConfigHdr);
1158 return EFI_OUT_OF_RESOURCES;
1159 }
1160
1161 StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);
1162 *StringPtrEnd = TempChar;
1163 }
1164 } else {
1165 //
1166 // The AltCfgResp contains <AltCfgResp>.
1167 // If the <ConfigElement> in <AltCfgResp> in the DefaultAltCfgResp but not in the
1168 // related <AltCfgResp> in AltCfgResp, merge it to AltCfgResp. else no need to merge.
1169 //
1170 CompareAndMergeDefaultString (AltCfgResp, DefaultAltCfgResp, AltConfigHdr);
1171 }
1172
1173 //
1174 // Find next AltCfg String
1175 //
1176 *(AltConfigHdr + HeaderLength) = L'\0';
1177 StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);
1178 }
1179
1180 FreePool (AltConfigHdr);
1181 return EFI_SUCCESS;
1182}
1183
1191VOID
1193 IN IFR_BLOCK_DATA *BlockData,
1194 IN IFR_DEFAULT_DATA *DefaultValueData
1195 )
1196{
1197 LIST_ENTRY *Link;
1198 IFR_DEFAULT_DATA *DefaultValueArray;
1199 LIST_ENTRY *DefaultLink;
1200
1201 DefaultLink = &BlockData->DefaultValueEntry;
1202
1203 for (Link = DefaultLink->ForwardLink; Link != DefaultLink; Link = Link->ForwardLink) {
1204 DefaultValueArray = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
1205 if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {
1206 //
1207 // DEFAULT_VALUE_FROM_OPCODE has high priority, DEFAULT_VALUE_FROM_DEFAULT has low priority.
1208 // When default types are DEFAULT_VALUE_FROM_OTHER_DEFAULT, the default value can be overrode.
1209 //
1210 if ((DefaultValueData->Type > DefaultValueArray->Type) || ((DefaultValueData->Type == DefaultValueArray->Type) && (DefaultValueData->Type == DefaultValueFromOtherDefault))) {
1211 //
1212 // Update the default value array in BlockData.
1213 //
1214 CopyMem (&DefaultValueArray->Value, &DefaultValueData->Value, sizeof (EFI_IFR_TYPE_VALUE));
1215 DefaultValueArray->Type = DefaultValueData->Type;
1216 DefaultValueArray->Cleaned = DefaultValueData->Cleaned;
1217 }
1218
1219 return;
1220 }
1221 }
1222
1223 //
1224 // Insert new default value data in tail.
1225 //
1226 DefaultValueArray = AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));
1227 ASSERT (DefaultValueArray != NULL);
1228 CopyMem (DefaultValueArray, DefaultValueData, sizeof (IFR_DEFAULT_DATA));
1229 InsertTailList (Link, &DefaultValueArray->Entry);
1230}
1231
1239VOID
1241 IN LIST_ENTRY *BlockLink,
1242 IN IFR_BLOCK_DATA **BlockData
1243 )
1244{
1245 LIST_ENTRY *Link;
1246 IFR_BLOCK_DATA *BlockArray;
1247 IFR_BLOCK_DATA *BlockSingleData;
1248
1249 BlockSingleData = *BlockData;
1250
1251 if (BlockSingleData->Name != NULL) {
1252 InsertTailList (BlockLink, &BlockSingleData->Entry);
1253 return;
1254 }
1255
1256 //
1257 // Insert block data in its Offset and Width order.
1258 //
1259 for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
1260 BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
1261 if (BlockArray->Offset == BlockSingleData->Offset) {
1262 if ((BlockArray->Width > BlockSingleData->Width) || (BlockSingleData->IsBitVar && (BlockArray->Width == BlockSingleData->Width))) {
1263 //
1264 // Insert this block data in the front of block array
1265 //
1266 InsertTailList (Link, &BlockSingleData->Entry);
1267 return;
1268 }
1269
1270 if ((!BlockSingleData->IsBitVar) && (BlockArray->Width == BlockSingleData->Width)) {
1271 //
1272 // The same block array has been added.
1273 //
1274 if (BlockSingleData != BlockArray) {
1275 FreePool (BlockSingleData);
1276 *BlockData = BlockArray;
1277 }
1278
1279 return;
1280 }
1281 } else if (BlockArray->Offset > BlockSingleData->Offset) {
1282 //
1283 // Insert new block data in the front of block array
1284 //
1285 InsertTailList (Link, &BlockSingleData->Entry);
1286 return;
1287 }
1288 }
1289
1290 //
1291 // Add new block data into the tail.
1292 //
1293 InsertTailList (Link, &BlockSingleData->Entry);
1294}
1295
1314CHAR8 *
1316 IN EFI_HII_HANDLE HiiHandle
1317 )
1318{
1319 EFI_STATUS Status;
1320 UINTN LanguageSize;
1321 CHAR8 TempSupportedLanguages;
1322 CHAR8 *SupportedLanguages;
1323
1324 ASSERT (HiiHandle != NULL);
1325
1326 //
1327 // Retrieve the size required for the supported languages buffer.
1328 //
1329 LanguageSize = 0;
1330 Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize);
1331
1332 //
1333 // If GetLanguages() returns EFI_SUCCESS for a zero size,
1334 // then there are no supported languages registered for HiiHandle. If GetLanguages()
1335 // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
1336 // in the HII Database
1337 //
1338 if (Status != EFI_BUFFER_TOO_SMALL) {
1339 //
1340 // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database
1341 //
1342 return NULL;
1343 }
1344
1345 //
1346 // Allocate the supported languages buffer.
1347 //
1348 SupportedLanguages = AllocateZeroPool (LanguageSize);
1349 if (SupportedLanguages == NULL) {
1350 //
1351 // Return NULL if allocation fails.
1352 //
1353 return NULL;
1354 }
1355
1356 //
1357 // Retrieve the supported languages string
1358 //
1359 Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, SupportedLanguages, &LanguageSize);
1360 if (EFI_ERROR (Status)) {
1361 //
1362 // Free the buffer and return NULL if the supported languages can not be retrieved.
1363 //
1364 FreePool (SupportedLanguages);
1365 return NULL;
1366 }
1367
1368 //
1369 // Return the Null-terminated ASCII string of supported languages
1370 //
1371 return SupportedLanguages;
1372}
1373
1388EFI_STRING
1390 IN EFI_HII_HANDLE HiiHandle,
1391 IN EFI_STRING_ID StringId
1392 )
1393{
1394 EFI_STATUS Status;
1395 UINTN StringSize;
1396 CHAR16 TempString;
1397 EFI_STRING String;
1398 CHAR8 *SupportedLanguages;
1399 CHAR8 *PlatformLanguage;
1400 CHAR8 *BestLanguage;
1401 CHAR8 *Language;
1402
1403 ASSERT (HiiHandle != NULL);
1404 ASSERT (StringId != 0);
1405
1406 //
1407 // Initialize all allocated buffers to NULL
1408 //
1409 SupportedLanguages = NULL;
1410 PlatformLanguage = NULL;
1411 BestLanguage = NULL;
1412 String = NULL;
1413 Language = "";
1414
1415 //
1416 // Get the languages that the package specified by HiiHandle supports
1417 //
1418 SupportedLanguages = GetSupportedLanguages (HiiHandle);
1419 if (SupportedLanguages == NULL) {
1420 goto Error;
1421 }
1422
1423 //
1424 // Get the current platform language setting
1425 //
1426 GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL);
1427
1428 //
1429 // Get the best matching language from SupportedLanguages
1430 //
1431 BestLanguage = GetBestLanguage (
1432 SupportedLanguages,
1433 FALSE, // RFC 4646 mode
1434 Language, // Highest priority
1435 PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority
1436 SupportedLanguages, // Lowest priority
1437 NULL
1438 );
1439 if (BestLanguage == NULL) {
1440 goto Error;
1441 }
1442
1443 //
1444 // Retrieve the size of the string in the string package for the BestLanguage
1445 //
1446 StringSize = 0;
1447 Status = mPrivate.HiiString.GetString (
1448 &mPrivate.HiiString,
1449 BestLanguage,
1450 HiiHandle,
1451 StringId,
1452 &TempString,
1453 &StringSize,
1454 NULL
1455 );
1456 //
1457 // If GetString() returns EFI_SUCCESS for a zero size,
1458 // then there are no supported languages registered for HiiHandle. If GetString()
1459 // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
1460 // in the HII Database
1461 //
1462 if (Status != EFI_BUFFER_TOO_SMALL) {
1463 goto Error;
1464 }
1465
1466 //
1467 // Allocate a buffer for the return string
1468 //
1469 String = AllocateZeroPool (StringSize);
1470 if (String == NULL) {
1471 goto Error;
1472 }
1473
1474 //
1475 // Retrieve the string from the string package
1476 //
1477 Status = mPrivate.HiiString.GetString (
1478 &mPrivate.HiiString,
1479 BestLanguage,
1480 HiiHandle,
1481 StringId,
1482 String,
1483 &StringSize,
1484 NULL
1485 );
1486 if (EFI_ERROR (Status)) {
1487 //
1488 // Free the buffer and return NULL if the supported languages can not be retrieved.
1489 //
1490 FreePool (String);
1491 String = NULL;
1492 }
1493
1494Error:
1495 //
1496 // Free allocated buffers
1497 //
1498 if (SupportedLanguages != NULL) {
1499 FreePool (SupportedLanguages);
1500 }
1501
1502 if (PlatformLanguage != NULL) {
1503 FreePool (PlatformLanguage);
1504 }
1505
1506 if (BestLanguage != NULL) {
1507 FreePool (BestLanguage);
1508 }
1509
1510 //
1511 // Return the Null-terminated Unicode string
1512 //
1513 return String;
1514}
1515
1528BOOLEAN
1530 IN IFR_BLOCK_DATA *RequestBlockArray,
1531 IN UINT16 VarOffset,
1532 IN UINT16 VarWidth,
1533 IN BOOLEAN IsNameValueType,
1534 IN EFI_HII_HANDLE HiiHandle
1535 )
1536{
1537 LIST_ENTRY *Link;
1538 IFR_BLOCK_DATA *BlockData;
1539 EFI_STRING Name;
1540
1541 //
1542 // No Request Block array, all vars are got.
1543 //
1544 if (RequestBlockArray == NULL) {
1545 return TRUE;
1546 }
1547
1548 //
1549 // Check the input var is in the request block range.
1550 //
1551 for (Link = RequestBlockArray->Entry.ForwardLink; Link != &RequestBlockArray->Entry; Link = Link->ForwardLink) {
1552 BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
1553
1554 if (IsNameValueType) {
1555 Name = InternalGetString (HiiHandle, VarOffset);
1556 ASSERT (Name != NULL);
1557
1558 if (StrnCmp (BlockData->Name, Name, StrLen (Name)) == 0) {
1559 FreePool (Name);
1560 return TRUE;
1561 }
1562
1563 FreePool (Name);
1564 } else {
1565 if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {
1566 return TRUE;
1567 }
1568 }
1569 }
1570
1571 return FALSE;
1572}
1573
1584 IN HII_DATABASE_RECORD *DataBaseRecord,
1585 IN OUT UINT8 **HiiFormPackage,
1586 OUT UINTN *PackageSize
1587 )
1588{
1589 EFI_STATUS Status;
1590 UINTN Size;
1591 UINTN ResultSize;
1592
1593 if ((DataBaseRecord == NULL) || (HiiFormPackage == NULL) || (PackageSize == NULL)) {
1594 return EFI_INVALID_PARAMETER;
1595 }
1596
1597 Size = 0;
1598 ResultSize = 0;
1599 //
1600 // 0. Get Hii Form Package by HiiHandle
1601 //
1602 Status = ExportFormPackages (
1603 &mPrivate,
1604 DataBaseRecord->Handle,
1605 DataBaseRecord->PackageList,
1606 0,
1607 Size,
1608 HiiFormPackage,
1609 &ResultSize
1610 );
1611 if (EFI_ERROR (Status)) {
1612 return Status;
1613 }
1614
1615 (*HiiFormPackage) = AllocatePool (ResultSize);
1616 if (*HiiFormPackage == NULL) {
1617 Status = EFI_OUT_OF_RESOURCES;
1618 return Status;
1619 }
1620
1621 //
1622 // Get HiiFormPackage by HiiHandle
1623 //
1624 Size = ResultSize;
1625 ResultSize = 0;
1626 Status = ExportFormPackages (
1627 &mPrivate,
1628 DataBaseRecord->Handle,
1629 DataBaseRecord->PackageList,
1630 0,
1631 Size,
1632 *HiiFormPackage,
1633 &ResultSize
1634 );
1635 if (EFI_ERROR (Status)) {
1636 FreePool (*HiiFormPackage);
1637 }
1638
1639 *PackageSize = Size;
1640
1641 return Status;
1642}
1643
1655 IN HII_DATABASE_RECORD *DataBaseRecord,
1656 IN EFI_STRING ConfigHdr,
1657 OUT BOOLEAN *IsEfiVarstore,
1658 OUT EFI_IFR_VARSTORE_EFI **EfiVarStore
1659 )
1660{
1661 EFI_STATUS Status;
1662 UINTN IfrOffset;
1663 UINTN PackageOffset;
1664 EFI_IFR_OP_HEADER *IfrOpHdr;
1665 CHAR16 *VarStoreName;
1666 UINTN NameSize;
1667 EFI_STRING GuidStr;
1668 EFI_STRING NameStr;
1669 EFI_STRING TempStr;
1670 UINTN LengthString;
1671 UINT8 *HiiFormPackage;
1672 UINTN PackageSize;
1673 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
1674 EFI_HII_PACKAGE_HEADER *PackageHeader;
1675
1676 HiiFormPackage = NULL;
1677 LengthString = 0;
1678 Status = EFI_SUCCESS;
1679 GuidStr = NULL;
1680 NameStr = NULL;
1681 TempStr = NULL;
1682 *IsEfiVarstore = FALSE;
1683
1684 Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
1685 if (EFI_ERROR (Status)) {
1686 return Status;
1687 }
1688
1689 IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);
1690 PackageOffset = IfrOffset;
1691 PackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiFormPackage;
1692
1693 while (IfrOffset < PackageSize) {
1694 //
1695 // More than one form packages exist.
1696 //
1697 if (PackageOffset >= PackageHeader->Length) {
1698 //
1699 // Process the new form package.
1700 //
1701 PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
1702 IfrOffset += PackageOffset;
1703 PackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiFormPackage + IfrOffset);
1704 }
1705
1706 IfrOpHdr = (EFI_IFR_OP_HEADER *)(HiiFormPackage + IfrOffset);
1707 IfrOffset += IfrOpHdr->Length;
1708 PackageOffset += IfrOpHdr->Length;
1709
1710 if (IfrOpHdr->OpCode == EFI_IFR_VARSTORE_EFI_OP ) {
1711 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
1712 //
1713 // If the length is small than the structure, this is from old efi
1714 // varstore definition. Old efi varstore get config directly from
1715 // GetVariable function.
1716 //
1717 if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
1718 continue;
1719 }
1720
1721 NameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);
1722 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
1723 if (VarStoreName == NULL) {
1724 Status = EFI_OUT_OF_RESOURCES;
1725 goto Done;
1726 }
1727
1728 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);
1729
1730 GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)&IfrEfiVarStore->Guid, 1, &GuidStr);
1731 GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *)VarStoreName, 2, &NameStr);
1732 LengthString = StrLen (GuidStr);
1733 LengthString = LengthString + StrLen (NameStr) + 1;
1734 TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
1735 if (TempStr == NULL) {
1736 FreePool (GuidStr);
1737 FreePool (NameStr);
1738 FreePool (VarStoreName);
1739 Status = EFI_OUT_OF_RESOURCES;
1740 goto Done;
1741 }
1742
1743 StrCpyS (TempStr, LengthString, GuidStr);
1744 StrCatS (TempStr, LengthString, NameStr);
1745 if ((ConfigHdr == NULL) || (StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0)) {
1746 *EfiVarStore = (EFI_IFR_VARSTORE_EFI *)AllocateZeroPool (IfrOpHdr->Length);
1747 if (*EfiVarStore == NULL) {
1748 FreePool (VarStoreName);
1749 FreePool (GuidStr);
1750 FreePool (NameStr);
1751 FreePool (TempStr);
1752 Status = EFI_OUT_OF_RESOURCES;
1753 goto Done;
1754 }
1755
1756 *IsEfiVarstore = TRUE;
1757 CopyMem (*EfiVarStore, IfrEfiVarStore, IfrOpHdr->Length);
1758 }
1759
1760 //
1761 // Free allocated temp string.
1762 //
1763 FreePool (VarStoreName);
1764 FreePool (GuidStr);
1765 FreePool (NameStr);
1766 FreePool (TempStr);
1767
1768 //
1769 // Already found the varstore, break;
1770 //
1771 if (*IsEfiVarstore) {
1772 break;
1773 }
1774 }
1775 }
1776
1777Done:
1778 if (HiiFormPackage != NULL) {
1779 FreePool (HiiFormPackage);
1780 }
1781
1782 return Status;
1783}
1784
1796BOOLEAN
1798 IN EFI_STRING ConfigRequest
1799 )
1800{
1801 EFI_STRING TmpRequest;
1802
1803 TmpRequest = StrStr (ConfigRequest, L"PATH=");
1804 ASSERT (TmpRequest != NULL);
1805
1806 if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {
1807 return TRUE;
1808 }
1809
1810 return FALSE;
1811}
1812
1824BOOLEAN
1826 IN EFI_GUID *VarstoreGuid,
1827 IN CHAR16 *Name,
1828 IN CHAR16 *ConfigHdr
1829 )
1830{
1831 EFI_STRING GuidStr;
1832 EFI_STRING NameStr;
1833 EFI_STRING TempStr;
1834 UINTN LengthString;
1835 BOOLEAN RetVal;
1836
1837 RetVal = FALSE;
1838 GuidStr = NULL;
1839 TempStr = NULL;
1840
1841 //
1842 // If ConfigHdr has name field and varstore not has name, return FALSE.
1843 //
1844 if ((Name == NULL) && (ConfigHdr != NULL) && (StrStr (ConfigHdr, L"NAME=&") == NULL)) {
1845 return FALSE;
1846 }
1847
1848 GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);
1849 if (Name != NULL) {
1850 GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *)Name, 2, &NameStr);
1851 } else {
1852 GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);
1853 }
1854
1855 LengthString = StrLen (GuidStr);
1856 LengthString = LengthString + StrLen (NameStr) + 1;
1857 TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));
1858 if (TempStr == NULL) {
1859 goto Done;
1860 }
1861
1862 StrCpyS (TempStr, LengthString, GuidStr);
1863 StrCatS (TempStr, LengthString, NameStr);
1864
1865 if ((ConfigHdr == NULL) || (StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0)) {
1866 RetVal = TRUE;
1867 }
1868
1869Done:
1870 if (GuidStr != NULL) {
1871 FreePool (GuidStr);
1872 }
1873
1874 if (NameStr != NULL) {
1875 FreePool (NameStr);
1876 }
1877
1878 if (TempStr != NULL) {
1879 FreePool (TempStr);
1880 }
1881
1882 return RetVal;
1883}
1884
1894BOOLEAN
1896 IN HII_DATABASE_RECORD *DataBaseRecord,
1897 IN EFI_STRING ConfigHdr
1898 )
1899{
1900 EFI_STATUS Status;
1901 UINTN IfrOffset;
1902 UINTN PackageOffset;
1903 EFI_IFR_OP_HEADER *IfrOpHdr;
1904 CHAR16 *VarStoreName;
1905 UINTN NameSize;
1906 UINT8 *HiiFormPackage;
1907 UINTN PackageSize;
1908 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
1909 EFI_HII_PACKAGE_HEADER *PackageHeader;
1910 EFI_IFR_VARSTORE *IfrVarStore;
1911 EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;
1912 BOOLEAN FindVarstore;
1913
1914 HiiFormPackage = NULL;
1915 VarStoreName = NULL;
1916 Status = EFI_SUCCESS;
1917 FindVarstore = FALSE;
1918
1919 Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
1920 if (EFI_ERROR (Status)) {
1921 return FALSE;
1922 }
1923
1924 IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);
1925 PackageOffset = IfrOffset;
1926 PackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiFormPackage;
1927
1928 while (IfrOffset < PackageSize) {
1929 //
1930 // More than one form packages exist.
1931 //
1932 if (PackageOffset >= PackageHeader->Length) {
1933 //
1934 // Process the new form package.
1935 //
1936 PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
1937 IfrOffset += PackageOffset;
1938 PackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiFormPackage + IfrOffset);
1939 }
1940
1941 IfrOpHdr = (EFI_IFR_OP_HEADER *)(HiiFormPackage + IfrOffset);
1942 IfrOffset += IfrOpHdr->Length;
1943 PackageOffset += IfrOpHdr->Length;
1944
1945 switch (IfrOpHdr->OpCode) {
1946 case EFI_IFR_VARSTORE_OP:
1947 IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;
1948
1949 NameSize = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);
1950 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
1951 if (VarStoreName == NULL) {
1952 goto Done;
1953 }
1954
1955 AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);
1956
1957 if (IsThisVarstore ((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {
1958 FindVarstore = TRUE;
1959 goto Done;
1960 } else {
1961 FreePool (VarStoreName);
1962 VarStoreName = NULL;
1963 }
1964
1965 break;
1966
1967 case EFI_IFR_VARSTORE_EFI_OP:
1968 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
1969 NameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);
1970 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
1971 if (VarStoreName == NULL) {
1972 goto Done;
1973 }
1974
1975 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);
1976
1977 if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {
1978 FindVarstore = TRUE;
1979 goto Done;
1980 } else {
1981 FreePool (VarStoreName);
1982 VarStoreName = NULL;
1983 }
1984
1985 break;
1986
1987 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1988 IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;
1989
1990 if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {
1991 FindVarstore = TRUE;
1992 goto Done;
1993 }
1994
1995 break;
1996
1997 case EFI_IFR_FORM_OP:
1998 case EFI_IFR_FORM_MAP_OP:
1999 //
2000 // No matched varstore is found and directly return.
2001 //
2002 goto Done;
2003
2004 default:
2005 break;
2006 }
2007 }
2008
2009Done:
2010 if (HiiFormPackage != NULL) {
2011 FreePool (HiiFormPackage);
2012 }
2013
2014 if (VarStoreName != NULL) {
2015 FreePool (VarStoreName);
2016 }
2017
2018 return FindVarstore;
2019}
2020
2039 IN IFR_BLOCK_DATA *RequestBlockArray,
2040 IN EFI_HII_HANDLE HiiHandle,
2041 IN OUT IFR_VARSTORAGE_DATA *VarStorageData,
2042 IN EFI_IFR_OP_HEADER *IfrOpHdr,
2043 IN UINT16 VarWidth,
2044 OUT IFR_BLOCK_DATA **ReturnData,
2045 IN BOOLEAN IsBitVar
2046 )
2047{
2048 IFR_BLOCK_DATA *BlockData;
2049 UINT16 VarOffset;
2050 EFI_STRING_ID NameId;
2051 EFI_IFR_QUESTION_HEADER *IfrQuestionHdr;
2052 UINT16 BitOffset;
2053 UINT16 BitWidth;
2054 UINT16 TotalBits;
2055
2056 NameId = 0;
2057 VarOffset = 0;
2058 BitOffset = 0;
2059 BitWidth = 0;
2060 IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)((CHAR8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));
2061
2062 if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
2063 NameId = IfrQuestionHdr->VarStoreInfo.VarName;
2064
2065 //
2066 // Check whether this question is in requested block array.
2067 //
2068 if (!BlockArrayCheck (RequestBlockArray, NameId, 0, TRUE, HiiHandle)) {
2069 //
2070 // This question is not in the requested string. Skip it.
2071 //
2072 return EFI_NOT_FOUND;
2073 }
2074 } else {
2075 //
2076 // Get the byte offset/with and bit offset/width
2077 //
2078 if (IsBitVar) {
2079 BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
2080 BitWidth = VarWidth;
2081 VarOffset = BitOffset / 8;
2082 //
2083 // Use current bit width and the bit width before current bit (with same byte offset) to calculate the byte width.
2084 //
2085 TotalBits = BitOffset % 8 + BitWidth;
2086 VarWidth = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
2087 } else {
2088 VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
2089 BitWidth = VarWidth;
2090 BitOffset = VarOffset * 8;
2091 }
2092
2093 //
2094 // Check whether this question is in requested block array.
2095 //
2096 if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth, FALSE, HiiHandle)) {
2097 //
2098 // This question is not in the requested string. Skip it.
2099 //
2100 return EFI_NOT_FOUND;
2101 }
2102
2103 //
2104 // Check this var question is in the var storage
2105 //
2106 if (((VarOffset + VarWidth) > VarStorageData->Size)) {
2107 return EFI_INVALID_PARAMETER;
2108 }
2109 }
2110
2111 BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
2112 if (BlockData == NULL) {
2113 return EFI_OUT_OF_RESOURCES;
2114 }
2115
2116 if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
2117 BlockData->Name = InternalGetString (HiiHandle, NameId);
2118 } else {
2119 BlockData->Offset = VarOffset;
2120 }
2121
2122 BlockData->Width = VarWidth;
2123 BlockData->QuestionId = IfrQuestionHdr->QuestionId;
2124 BlockData->OpCode = IfrOpHdr->OpCode;
2125 BlockData->Scope = IfrOpHdr->Scope;
2126 BlockData->IsBitVar = IsBitVar;
2127 BlockData->BitOffset = BitOffset;
2128 BlockData->BitWidth = BitWidth;
2129 InitializeListHead (&BlockData->DefaultValueEntry);
2130 //
2131 // Add Block Data into VarStorageData BlockEntry
2132 //
2133 InsertBlockData (&VarStorageData->BlockEntry, &BlockData);
2134 *ReturnData = BlockData;
2135
2136 return EFI_SUCCESS;
2137}
2138
2158EFIAPI
2160 IN EFI_HII_HANDLE HiiHandle,
2161 IN UINT8 *Package,
2162 IN UINT32 PackageLength,
2163 IN EFI_STRING ConfigHdr,
2164 IN IFR_BLOCK_DATA *RequestBlockArray,
2165 IN OUT IFR_VARSTORAGE_DATA *VarStorageData,
2166 OUT IFR_DEFAULT_DATA *DefaultIdArray
2167 )
2168{
2169 EFI_STATUS Status;
2170 UINTN IfrOffset;
2171 UINTN PackageOffset;
2172 EFI_IFR_VARSTORE *IfrVarStore;
2173 EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
2174 EFI_IFR_VARSTORE_EFI *IfrEfiVarStoreTmp;
2175 EFI_IFR_OP_HEADER *IfrOpHdr;
2176 EFI_IFR_ONE_OF *IfrOneOf;
2177 EFI_IFR_REF4 *IfrRef;
2178 EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;
2179 EFI_IFR_DEFAULT *IfrDefault;
2180 EFI_IFR_ORDERED_LIST *IfrOrderedList;
2181 EFI_IFR_CHECKBOX *IfrCheckBox;
2182 EFI_IFR_PASSWORD *IfrPassword;
2183 EFI_IFR_STRING *IfrString;
2184 EFI_IFR_DATE *IfrDate;
2185 EFI_IFR_TIME *IfrTime;
2186 IFR_DEFAULT_DATA DefaultData;
2187 IFR_DEFAULT_DATA *DefaultDataPtr;
2188 IFR_BLOCK_DATA *BlockData;
2189 CHAR16 *VarStoreName;
2190 UINTN NameSize;
2191 UINTN NvDefaultStoreSize;
2192 UINT16 VarWidth;
2193 UINT16 VarDefaultId;
2194 BOOLEAN FirstOneOfOption;
2195 BOOLEAN FirstOrderedList;
2196 LIST_ENTRY *LinkData;
2197 LIST_ENTRY *LinkDefault;
2198 EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;
2199 EFI_HII_PACKAGE_HEADER *PackageHeader;
2200 EFI_VARSTORE_ID VarStoreId;
2201 UINT16 SmallestDefaultId;
2202 BOOLEAN SmallestIdFromFlag;
2203 BOOLEAN FromOtherDefaultOpcode;
2204 BOOLEAN QuestionReferBitField;
2205
2206 Status = EFI_SUCCESS;
2207 BlockData = NULL;
2208 DefaultDataPtr = NULL;
2209 FirstOneOfOption = FALSE;
2210 VarStoreId = 0;
2211 FirstOrderedList = FALSE;
2212 VarStoreName = NULL;
2213 ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));
2214 SmallestDefaultId = 0xFFFF;
2215 FromOtherDefaultOpcode = FALSE;
2216 QuestionReferBitField = FALSE;
2217 IfrEfiVarStoreTmp = NULL;
2218
2219 //
2220 // Go through the form package to parse OpCode one by one.
2221 //
2222 PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
2223 PackageHeader = (EFI_HII_PACKAGE_HEADER *)Package;
2224 IfrOffset = PackageOffset;
2225 while (IfrOffset < PackageLength) {
2226 //
2227 // More than one form package found.
2228 //
2229 if (PackageOffset >= PackageHeader->Length) {
2230 //
2231 // Already found varstore for this request, break;
2232 //
2233 if (VarStoreId != 0) {
2234 VarStoreId = 0;
2235 }
2236
2237 //
2238 // Get next package header info.
2239 //
2240 IfrOffset += sizeof (EFI_HII_PACKAGE_HEADER);
2241 PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
2242 PackageHeader = (EFI_HII_PACKAGE_HEADER *)(Package + IfrOffset);
2243 }
2244
2245 IfrOpHdr = (EFI_IFR_OP_HEADER *)(Package + IfrOffset);
2246 switch (IfrOpHdr->OpCode) {
2247 case EFI_IFR_VARSTORE_OP:
2248 //
2249 // VarStore is found. Don't need to search any more.
2250 //
2251 if (VarStoreId != 0) {
2252 break;
2253 }
2254
2255 IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;
2256
2257 NameSize = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);
2258 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
2259 if (VarStoreName == NULL) {
2260 Status = EFI_OUT_OF_RESOURCES;
2261 goto Done;
2262 }
2263
2264 AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);
2265
2266 if (IsThisVarstore ((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {
2267 //
2268 // Find the matched VarStore
2269 //
2270 CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrVarStore->Guid);
2271 VarStorageData->Size = IfrVarStore->Size;
2272 VarStorageData->Name = VarStoreName;
2273 VarStorageData->Type = EFI_HII_VARSTORE_BUFFER;
2274 VarStoreId = IfrVarStore->VarStoreId;
2275 } else {
2276 FreePool (VarStoreName);
2277 VarStoreName = NULL;
2278 }
2279
2280 break;
2281
2282 case EFI_IFR_VARSTORE_EFI_OP:
2283 //
2284 // VarStore is found. Don't need to search any more.
2285 //
2286 if (VarStoreId != 0) {
2287 break;
2288 }
2289
2290 IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
2291
2292 //
2293 // If the length is small than the structure, this is from old efi
2294 // varstore definition. Old efi varstore get config directly from
2295 // GetVariable function.
2296 //
2297 if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
2298 break;
2299 }
2300
2301 NameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);
2302 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
2303 if (VarStoreName == NULL) {
2304 Status = EFI_OUT_OF_RESOURCES;
2305 goto Done;
2306 }
2307
2308 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);
2309 if (IfrEfiVarStoreTmp != NULL) {
2310 FreePool (IfrEfiVarStoreTmp);
2311 }
2312
2313 IfrEfiVarStoreTmp = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));
2314 if (IfrEfiVarStoreTmp == NULL) {
2315 Status = EFI_OUT_OF_RESOURCES;
2316 goto Done;
2317 }
2318
2319 CopyMem (IfrEfiVarStoreTmp, IfrEfiVarStore, IfrEfiVarStore->Header.Length);
2320 AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *)&(IfrEfiVarStoreTmp->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
2321
2322 if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {
2323 //
2324 // Find the matched VarStore
2325 //
2326 CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrEfiVarStore->Guid);
2327 VarStorageData->Size = IfrEfiVarStore->Size;
2328 VarStorageData->Name = VarStoreName;
2329 VarStorageData->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;
2330 VarStoreId = IfrEfiVarStore->VarStoreId;
2331 } else {
2332 FreePool (VarStoreName);
2333 VarStoreName = NULL;
2334 }
2335
2336 break;
2337
2338 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
2339 //
2340 // VarStore is found. Don't need to search any more.
2341 //
2342 if (VarStoreId != 0) {
2343 break;
2344 }
2345
2346 IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;
2347
2348 if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {
2349 //
2350 // Find the matched VarStore
2351 //
2352 CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrNameValueVarStore->Guid);
2353 VarStorageData->Type = EFI_HII_VARSTORE_NAME_VALUE;
2354 VarStoreId = IfrNameValueVarStore->VarStoreId;
2355 }
2356
2357 break;
2358
2359 case EFI_IFR_DEFAULTSTORE_OP:
2360 //
2361 // Add new the map between default id and default name.
2362 //
2363 DefaultDataPtr = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));
2364 if (DefaultDataPtr == NULL) {
2365 Status = EFI_OUT_OF_RESOURCES;
2366 goto Done;
2367 }
2368
2369 DefaultDataPtr->DefaultId = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;
2370 InsertTailList (&DefaultIdArray->Entry, &DefaultDataPtr->Entry);
2371 DefaultDataPtr = NULL;
2372 break;
2373
2374 case EFI_IFR_FORM_OP:
2375 case EFI_IFR_FORM_MAP_OP:
2376 //
2377 // No matched varstore is found and directly return.
2378 //
2379 if ( VarStoreId == 0) {
2380 Status = EFI_SUCCESS;
2381 goto Done;
2382 }
2383
2384 break;
2385
2386 case EFI_IFR_REF_OP:
2387 //
2388 // Ref question is not in IFR Form. This IFR form is not valid.
2389 //
2390 if ( VarStoreId == 0) {
2391 Status = EFI_INVALID_PARAMETER;
2392 goto Done;
2393 }
2394
2395 //
2396 // Check whether this question is for the requested varstore.
2397 //
2398 IfrRef = (EFI_IFR_REF4 *)IfrOpHdr;
2399 if (IfrRef->Question.VarStoreId != VarStoreId) {
2400 break;
2401 }
2402
2403 VarWidth = (UINT16)(sizeof (EFI_HII_REF));
2404
2405 //
2406 // The BlockData may allocate by other opcode,need to clean.
2407 //
2408 if (BlockData != NULL) {
2409 BlockData = NULL;
2410 }
2411
2412 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
2413 if (EFI_ERROR (Status)) {
2414 if (Status == EFI_NOT_FOUND) {
2415 //
2416 // The opcode is not required,exit and parse other opcode.
2417 //
2418 break;
2419 }
2420
2421 goto Done;
2422 }
2423
2424 break;
2425
2426 case EFI_IFR_ONE_OF_OP:
2427 case EFI_IFR_NUMERIC_OP:
2428 //
2429 // Numeric and OneOf has the same opcode structure.
2430 //
2431
2432 //
2433 // Numeric and OneOf question is not in IFR Form. This IFR form is not valid.
2434 //
2435 if (VarStoreId == 0) {
2436 Status = EFI_INVALID_PARAMETER;
2437 goto Done;
2438 }
2439
2440 //
2441 // Check whether this question is for the requested varstore.
2442 //
2443 IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpHdr;
2444 if (IfrOneOf->Question.VarStoreId != VarStoreId) {
2445 break;
2446 }
2447
2448 if (QuestionReferBitField) {
2449 VarWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
2450 } else {
2451 VarWidth = (UINT16)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
2452 }
2453
2454 //
2455 // The BlockData may allocate by other opcode,need to clean.
2456 //
2457 if (BlockData != NULL) {
2458 BlockData = NULL;
2459 }
2460
2461 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);
2462 if (EFI_ERROR (Status)) {
2463 if (Status == EFI_NOT_FOUND) {
2464 //
2465 // The opcode is not required,exit and parse other opcode.
2466 //
2467 break;
2468 }
2469
2470 goto Done;
2471 }
2472
2473 //
2474 // when go to there,BlockData can't be NULLL.
2475 //
2476 ASSERT (BlockData != NULL);
2477
2478 if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {
2479 //
2480 // Set this flag to TRUE for the first oneof option.
2481 //
2482 FirstOneOfOption = TRUE;
2483 } else if (IfrOpHdr->OpCode == EFI_IFR_NUMERIC_OP) {
2484 //
2485 // Numeric minimum value will be used as default value when no default is specified.
2486 //
2487 DefaultData.Type = DefaultValueFromDefault;
2488 if (QuestionReferBitField) {
2489 //
2490 // Since default value in bit field was stored as UINT32 type.
2491 //
2492 CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));
2493 } else {
2494 switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {
2495 case EFI_IFR_NUMERIC_SIZE_1:
2496 DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;
2497 break;
2498
2499 case EFI_IFR_NUMERIC_SIZE_2:
2500 CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));
2501 break;
2502
2503 case EFI_IFR_NUMERIC_SIZE_4:
2504 CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));
2505 break;
2506
2507 case EFI_IFR_NUMERIC_SIZE_8:
2508 CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));
2509 break;
2510
2511 default:
2512 Status = EFI_INVALID_PARAMETER;
2513 goto Done;
2514 }
2515 }
2516
2517 //
2518 // Set default value base on the DefaultId list get from IFR data.
2519 //
2520 NvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);
2521 for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
2522 DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
2523 DefaultData.DefaultId = DefaultDataPtr->DefaultId;
2524 if (NvDefaultStoreSize > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
2525 FindQuestionDefaultSetting (DefaultData.DefaultId, IfrEfiVarStoreTmp, &(IfrOneOf->Question), &DefaultData.Value, VarWidth, QuestionReferBitField);
2526 }
2527
2528 InsertDefaultValue (BlockData, &DefaultData);
2529 }
2530 }
2531
2532 break;
2533
2534 case EFI_IFR_ORDERED_LIST_OP:
2535 //
2536 // offset by question header
2537 // width by EFI_IFR_ORDERED_LIST MaxContainers * OneofOption Type
2538 //
2539
2540 FirstOrderedList = TRUE;
2541 //
2542 // OrderedList question is not in IFR Form. This IFR form is not valid.
2543 //
2544 if (VarStoreId == 0) {
2545 Status = EFI_INVALID_PARAMETER;
2546 goto Done;
2547 }
2548
2549 //
2550 // Check whether this question is for the requested varstore.
2551 //
2552 IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpHdr;
2553 if (IfrOrderedList->Question.VarStoreId != VarStoreId) {
2554 BlockData = NULL;
2555 break;
2556 }
2557
2558 VarWidth = IfrOrderedList->MaxContainers;
2559
2560 //
2561 // The BlockData may allocate by other opcode,need to clean.
2562 //
2563 if (BlockData != NULL) {
2564 BlockData = NULL;
2565 }
2566
2567 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
2568 if (EFI_ERROR (Status)) {
2569 if (Status == EFI_NOT_FOUND) {
2570 //
2571 // The opcode is not required,exit and parse other opcode.
2572 //
2573 break;
2574 }
2575
2576 goto Done;
2577 }
2578
2579 break;
2580
2581 case EFI_IFR_CHECKBOX_OP:
2582 //
2583 // EFI_IFR_DEFAULT_OP
2584 // offset by question header
2585 // width is 1 sizeof (BOOLEAN)
2586 // default id by CheckBox Flags if CheckBox flags (Default or Mau) is set, the default value is 1 to be set.
2587 // value by DefaultOption
2588 // default id by DeaultOption DefaultId can override CheckBox Flags and Default value.
2589 //
2590
2591 //
2592 // CheckBox question is not in IFR Form. This IFR form is not valid.
2593 //
2594 if (VarStoreId == 0) {
2595 Status = EFI_INVALID_PARAMETER;
2596 goto Done;
2597 }
2598
2599 //
2600 // Check whether this question is for the requested varstore.
2601 //
2602 IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr;
2603 if (IfrCheckBox->Question.VarStoreId != VarStoreId) {
2604 break;
2605 }
2606
2607 VarWidth = (UINT16)sizeof (BOOLEAN);
2608
2609 //
2610 // The BlockData may allocate by other opcode,need to clean.
2611 //
2612 if (BlockData != NULL) {
2613 BlockData = NULL;
2614 }
2615
2616 if (QuestionReferBitField) {
2617 VarWidth = 1;
2618 }
2619
2620 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);
2621 if (EFI_ERROR (Status)) {
2622 if (Status == EFI_NOT_FOUND) {
2623 //
2624 // The opcode is not required,exit and parse other opcode.
2625 //
2626 break;
2627 }
2628
2629 goto Done;
2630 }
2631
2632 //
2633 // when go to there,BlockData can't be NULLL.
2634 //
2635 ASSERT (BlockData != NULL);
2636
2637 SmallestIdFromFlag = FALSE;
2638
2639 //
2640 // Add default value for standard ID by CheckBox Flag
2641 //
2642 VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
2643 //
2644 // Prepare new DefaultValue
2645 //
2646 DefaultData.DefaultId = VarDefaultId;
2647 if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {
2648 //
2649 // When flag is set, default value is TRUE.
2650 //
2651 DefaultData.Type = DefaultValueFromFlag;
2652 if (QuestionReferBitField) {
2653 DefaultData.Value.u32 = TRUE;
2654 } else {
2655 DefaultData.Value.b = TRUE;
2656 }
2657
2658 InsertDefaultValue (BlockData, &DefaultData);
2659
2660 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
2661 //
2662 // Record the SmallestDefaultId and update the SmallestIdFromFlag.
2663 //
2664 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
2665 SmallestIdFromFlag = TRUE;
2666 }
2667 }
2668
2669 //
2670 // Add default value for Manufacture ID by CheckBox Flag
2671 //
2672 VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2673 //
2674 // Prepare new DefaultValue
2675 //
2676 DefaultData.DefaultId = VarDefaultId;
2677 if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {
2678 //
2679 // When flag is set, default value is TRUE.
2680 //
2681 DefaultData.Type = DefaultValueFromFlag;
2682 if (QuestionReferBitField) {
2683 DefaultData.Value.u32 = TRUE;
2684 } else {
2685 DefaultData.Value.b = TRUE;
2686 }
2687
2688 InsertDefaultValue (BlockData, &DefaultData);
2689
2690 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
2691 //
2692 // Record the SmallestDefaultId and update the SmallestIdFromFlag.
2693 //
2694 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2695 SmallestIdFromFlag = TRUE;
2696 }
2697 }
2698
2699 if (SmallestIdFromFlag) {
2700 //
2701 // When smallest default Id is given by the flag of CheckBox, set default value with TRUE for other default Id in the DefaultId list.
2702 //
2703 DefaultData.Type = DefaultValueFromOtherDefault;
2704 if (QuestionReferBitField) {
2705 DefaultData.Value.u32 = TRUE;
2706 } else {
2707 DefaultData.Value.b = TRUE;
2708 }
2709
2710 //
2711 // Set default value for all the default id in the DefaultId list.
2712 //
2713 for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
2714 DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
2715 DefaultData.DefaultId = DefaultDataPtr->DefaultId;
2716 InsertDefaultValue (BlockData, &DefaultData);
2717 }
2718 } else {
2719 //
2720 // When flag is not set, default value is FASLE.
2721 //
2722 DefaultData.Type = DefaultValueFromDefault;
2723 if (QuestionReferBitField) {
2724 DefaultData.Value.u32 = FALSE;
2725 } else {
2726 DefaultData.Value.b = FALSE;
2727 }
2728
2729 //
2730 // Set default value for all the default id in the DefaultId list.
2731 //
2732 for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
2733 DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
2734 DefaultData.DefaultId = DefaultDataPtr->DefaultId;
2735 InsertDefaultValue (BlockData, &DefaultData);
2736 }
2737 }
2738
2739 break;
2740
2741 case EFI_IFR_DATE_OP:
2742 //
2743 // offset by question header
2744 // width MaxSize * sizeof (CHAR16)
2745 // no default value, only block array
2746 //
2747
2748 //
2749 // Date question is not in IFR Form. This IFR form is not valid.
2750 //
2751 if (VarStoreId == 0) {
2752 Status = EFI_INVALID_PARAMETER;
2753 goto Done;
2754 }
2755
2756 //
2757 // Check whether this question is for the requested varstore.
2758 //
2759 IfrDate = (EFI_IFR_DATE *)IfrOpHdr;
2760 if (IfrDate->Question.VarStoreId != VarStoreId) {
2761 break;
2762 }
2763
2764 //
2765 // The BlockData may allocate by other opcode,need to clean.
2766 //
2767 if (BlockData != NULL) {
2768 BlockData = NULL;
2769 }
2770
2771 VarWidth = (UINT16)sizeof (EFI_HII_DATE);
2772 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
2773 if (EFI_ERROR (Status)) {
2774 if (Status == EFI_NOT_FOUND) {
2775 //
2776 // The opcode is not required,exit and parse other opcode.
2777 //
2778 break;
2779 }
2780
2781 goto Done;
2782 }
2783
2784 break;
2785
2786 case EFI_IFR_TIME_OP:
2787 //
2788 // offset by question header
2789 // width MaxSize * sizeof (CHAR16)
2790 // no default value, only block array
2791 //
2792
2793 //
2794 // Time question is not in IFR Form. This IFR form is not valid.
2795 //
2796 if (VarStoreId == 0) {
2797 Status = EFI_INVALID_PARAMETER;
2798 goto Done;
2799 }
2800
2801 //
2802 // Check whether this question is for the requested varstore.
2803 //
2804 IfrTime = (EFI_IFR_TIME *)IfrOpHdr;
2805 if (IfrTime->Question.VarStoreId != VarStoreId) {
2806 break;
2807 }
2808
2809 //
2810 // The BlockData may allocate by other opcode,need to clean.
2811 //
2812 if (BlockData != NULL) {
2813 BlockData = NULL;
2814 }
2815
2816 VarWidth = (UINT16)sizeof (EFI_HII_TIME);
2817 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
2818 if (EFI_ERROR (Status)) {
2819 if (Status == EFI_NOT_FOUND) {
2820 //
2821 // The opcode is not required,exit and parse other opcode.
2822 //
2823 break;
2824 }
2825
2826 goto Done;
2827 }
2828
2829 break;
2830
2831 case EFI_IFR_STRING_OP:
2832 //
2833 // offset by question header
2834 // width MaxSize * sizeof (CHAR16)
2835 // no default value, only block array
2836 //
2837
2838 //
2839 // String question is not in IFR Form. This IFR form is not valid.
2840 //
2841 if (VarStoreId == 0) {
2842 Status = EFI_INVALID_PARAMETER;
2843 goto Done;
2844 }
2845
2846 //
2847 // Check whether this question is for the requested varstore.
2848 //
2849 IfrString = (EFI_IFR_STRING *)IfrOpHdr;
2850 if (IfrString->Question.VarStoreId != VarStoreId) {
2851 break;
2852 }
2853
2854 //
2855 // The BlockData may allocate by other opcode,need to clean.
2856 //
2857 if (BlockData != NULL) {
2858 BlockData = NULL;
2859 }
2860
2861 VarWidth = (UINT16)(IfrString->MaxSize * sizeof (UINT16));
2862 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
2863 if (EFI_ERROR (Status)) {
2864 if (Status == EFI_NOT_FOUND) {
2865 //
2866 // The opcode is not required,exit and parse other opcode.
2867 //
2868 break;
2869 }
2870
2871 goto Done;
2872 }
2873
2874 break;
2875
2876 case EFI_IFR_PASSWORD_OP:
2877 //
2878 // offset by question header
2879 // width MaxSize * sizeof (CHAR16)
2880 // no default value, only block array
2881 //
2882
2883 //
2884 // Password question is not in IFR Form. This IFR form is not valid.
2885 //
2886 if (VarStoreId == 0) {
2887 Status = EFI_INVALID_PARAMETER;
2888 goto Done;
2889 }
2890
2891 //
2892 // Check whether this question is for the requested varstore.
2893 //
2894 IfrPassword = (EFI_IFR_PASSWORD *)IfrOpHdr;
2895 if (IfrPassword->Question.VarStoreId != VarStoreId) {
2896 break;
2897 }
2898
2899 //
2900 // The BlockData may allocate by other opcode,need to clean.
2901 //
2902 if (BlockData != NULL) {
2903 BlockData = NULL;
2904 }
2905
2906 VarWidth = (UINT16)(IfrPassword->MaxSize * sizeof (UINT16));
2907 Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
2908 if (EFI_ERROR (Status)) {
2909 if (Status == EFI_NOT_FOUND) {
2910 //
2911 // The opcode is not required,exit and parse other opcode.
2912 //
2913 break;
2914 }
2915
2916 goto Done;
2917 }
2918
2919 //
2920 // No default value for string.
2921 //
2922 BlockData = NULL;
2923 break;
2924
2925 case EFI_IFR_ONE_OF_OPTION_OP:
2926 //
2927 // No matched block data is ignored.
2928 //
2929 if ((BlockData == NULL) || (BlockData->Scope == 0)) {
2930 break;
2931 }
2932
2933 IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;
2934 if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {
2935 if (!FirstOrderedList) {
2936 break;
2937 }
2938
2939 //
2940 // Get ordered list option data type.
2941 //
2942 if ((IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrOneOfOption->Type == EFI_IFR_TYPE_BOOLEAN)) {
2943 VarWidth = 1;
2944 } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_16) {
2945 VarWidth = 2;
2946 } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_32) {
2947 VarWidth = 4;
2948 } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
2949 VarWidth = 8;
2950 } else {
2951 //
2952 // Invalid ordered list option data type.
2953 //
2954 Status = EFI_INVALID_PARAMETER;
2955 if (BlockData->Name != NULL) {
2956 FreePool (BlockData->Name);
2957 }
2958
2959 FreePool (BlockData);
2960 goto Done;
2961 }
2962
2963 //
2964 // Calculate Ordered list QuestionId width.
2965 //
2966 BlockData->Width = (UINT16)(BlockData->Width * VarWidth);
2967 //
2968 // Check whether this question is in requested block array.
2969 //
2970 if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, (BOOLEAN)(BlockData->Name != NULL), HiiHandle)) {
2971 //
2972 // This question is not in the requested string. Skip it.
2973 //
2974 if (BlockData->Name != NULL) {
2975 FreePool (BlockData->Name);
2976 }
2977
2978 FreePool (BlockData);
2979 BlockData = NULL;
2980 break;
2981 }
2982
2983 //
2984 // Check this var question is in the var storage
2985 //
2986 if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {
2987 Status = EFI_INVALID_PARAMETER;
2988 FreePool (BlockData);
2989 goto Done;
2990 }
2991
2992 //
2993 // Add Block Data into VarStorageData BlockEntry
2994 //
2995 InsertBlockData (&VarStorageData->BlockEntry, &BlockData);
2996
2997 FirstOrderedList = FALSE;
2998
2999 break;
3000 }
3001
3002 //
3003 // 1. Set default value for OneOf option when flag field has default attribute.
3004 // And set the default value with the smallest default id for other default id in the DefaultId list.
3005 //
3006 if (((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) ||
3007 ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG))
3008 {
3009 //
3010 // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.
3011 // The first oneof option value will be used as default value when no default value is specified.
3012 //
3013 FirstOneOfOption = FALSE;
3014
3015 SmallestIdFromFlag = FALSE;
3016
3017 // Prepare new DefaultValue
3018 //
3019 DefaultData.Type = DefaultValueFromFlag;
3020 CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
3021 if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {
3022 DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
3023 InsertDefaultValue (BlockData, &DefaultData);
3024 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
3025 //
3026 // Record the SmallestDefaultId and update the SmallestIdFromFlag.
3027 //
3028 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
3029 SmallestIdFromFlag = TRUE;
3030 }
3031 }
3032
3033 if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {
3034 DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
3035 InsertDefaultValue (BlockData, &DefaultData);
3036 if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
3037 //
3038 // Record the SmallestDefaultId and update the SmallestIdFromFlag.
3039 //
3040 SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
3041 SmallestIdFromFlag = TRUE;
3042 }
3043 }
3044
3045 if (SmallestIdFromFlag) {
3046 //
3047 // When smallest default Id is given by the flag of oneofOption, set this option value for other default Id in the DefaultId list.
3048 //
3049 DefaultData.Type = DefaultValueFromOtherDefault;
3050 //
3051 // Set default value for other default id in the DefaultId list.
3052 //
3053 for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
3054 DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
3055 DefaultData.DefaultId = DefaultDataPtr->DefaultId;
3056 InsertDefaultValue (BlockData, &DefaultData);
3057 }
3058 }
3059 }
3060
3061 //
3062 // 2. Set as the default value when this is the first option.
3063 // The first oneof option value will be used as default value when no default value is specified.
3064 //
3065 if (FirstOneOfOption) {
3066 // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.
3067 FirstOneOfOption = FALSE;
3068
3069 //
3070 // Prepare new DefaultValue
3071 //
3072 DefaultData.Type = DefaultValueFromDefault;
3073 CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
3074 for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
3075 DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
3076 DefaultData.DefaultId = DefaultDataPtr->DefaultId;
3077 InsertDefaultValue (BlockData, &DefaultData);
3078 }
3079 }
3080
3081 break;
3082
3083 case EFI_IFR_DEFAULT_OP:
3084 //
3085 // Update Current BlockData to the default value.
3086 //
3087 if ((BlockData == NULL) || (BlockData->Scope == 0)) {
3088 //
3089 // No matched block data is ignored.
3090 //
3091 break;
3092 }
3093
3094 //
3095 // Get the DefaultId
3096 //
3097 IfrDefault = (EFI_IFR_DEFAULT *)IfrOpHdr;
3098 VarDefaultId = IfrDefault->DefaultId;
3099 //
3100 // Prepare new DefaultValue
3101 //
3102 DefaultData.Type = DefaultValueFromOpcode;
3103 DefaultData.DefaultId = VarDefaultId;
3104 if (QuestionReferBitField) {
3105 CopyMem (&DefaultData.Value.u32, &IfrDefault->Value.u32, sizeof (UINT32));
3106 } else {
3107 CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));
3108 }
3109
3110 // If the value field is expression, set the cleaned flag.
3111 if (IfrDefault->Type == EFI_IFR_TYPE_OTHER) {
3112 DefaultData.Cleaned = TRUE;
3113 }
3114
3115 //
3116 // Add DefaultValue into current BlockData
3117 //
3118 InsertDefaultValue (BlockData, &DefaultData);
3119
3120 //
3121 // Set default value for other default id in the DefaultId list.
3122 // when SmallestDefaultId == VarDefaultId means there are two defaults with same default Id.
3123 // If the two defaults are both from default opcode, use the first default as the default value of other default Id.
3124 // If one from flag and the other form default opcode, use the default opcode value as the default value of other default Id.
3125 //
3126 if ((SmallestDefaultId > VarDefaultId) || ((SmallestDefaultId == VarDefaultId) && !FromOtherDefaultOpcode)) {
3127 FromOtherDefaultOpcode = TRUE;
3128 SmallestDefaultId = VarDefaultId;
3129 for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
3130 DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
3131 if (DefaultDataPtr->DefaultId != DefaultData.DefaultId) {
3132 DefaultData.Type = DefaultValueFromOtherDefault;
3133 DefaultData.DefaultId = DefaultDataPtr->DefaultId;
3134 InsertDefaultValue (BlockData, &DefaultData);
3135 }
3136 }
3137 }
3138
3139 //
3140 // After insert the default value, reset the cleaned value for next
3141 // time used. If not set here, need to set the value before every time.
3142 // use it.
3143 //
3144 DefaultData.Cleaned = FALSE;
3145 break;
3146
3147 case EFI_IFR_END_OP:
3148 //
3149 // End Opcode is for Var question.
3150 //
3151 QuestionReferBitField = FALSE;
3152 if (BlockData != NULL) {
3153 if (BlockData->Scope > 0) {
3154 BlockData->Scope--;
3155 }
3156
3157 if (BlockData->Scope == 0) {
3158 BlockData = NULL;
3159 //
3160 // when finishing parsing a question, clean the SmallestDefaultId and GetDefaultFromDefaultOpcode.
3161 //
3162 SmallestDefaultId = 0xFFFF;
3163 FromOtherDefaultOpcode = FALSE;
3164 }
3165 }
3166
3167 break;
3168
3169 case EFI_IFR_GUID_OP:
3170 if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
3171 QuestionReferBitField = TRUE;
3172 }
3173
3174 break;
3175
3176 default:
3177 if (BlockData != NULL) {
3178 if (BlockData->Scope > 0) {
3179 BlockData->Scope = (UINT8)(BlockData->Scope + IfrOpHdr->Scope);
3180 }
3181
3182 if (BlockData->Scope == 0) {
3183 BlockData = NULL;
3184 }
3185 }
3186
3187 break;
3188 }
3189
3190 IfrOffset += IfrOpHdr->Length;
3191 PackageOffset += IfrOpHdr->Length;
3192 }
3193
3194 //
3195 // if Status == EFI_NOT_FOUND, just means the opcode is not required,not contain any error,
3196 // so set the Status to EFI_SUCCESS.
3197 //
3198 if (Status == EFI_NOT_FOUND) {
3199 Status = EFI_SUCCESS;
3200 }
3201
3202Done:
3203 for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {
3204 BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);
3205 for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; ) {
3206 DefaultDataPtr = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
3207 LinkDefault = LinkDefault->ForwardLink;
3208 if (DefaultDataPtr->Cleaned == TRUE) {
3209 RemoveEntryList (&DefaultDataPtr->Entry);
3210 FreePool (DefaultDataPtr);
3211 }
3212 }
3213 }
3214
3215 if (IfrEfiVarStoreTmp != NULL) {
3216 FreePool (IfrEfiVarStoreTmp);
3217 }
3218
3219 return Status;
3220}
3221
3232 IN EFI_STRING ConfigRequest,
3233 OUT EFI_STRING *Progress
3234 )
3235{
3236 EFI_STRING StringPtr;
3237 IFR_BLOCK_DATA *BlockData;
3238 IFR_BLOCK_DATA *RequestBlockArray;
3239 EFI_STATUS Status;
3240 UINT8 *TmpBuffer;
3241 UINT16 Offset;
3242 UINT16 Width;
3243 LIST_ENTRY *Link;
3244 IFR_BLOCK_DATA *NextBlockData;
3245 UINTN Length;
3246
3247 TmpBuffer = NULL;
3248
3249 //
3250 // Init RequestBlockArray
3251 //
3252 RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
3253 if (RequestBlockArray == NULL) {
3254 goto Done;
3255 }
3256
3257 InitializeListHead (&RequestBlockArray->Entry);
3258
3259 //
3260 // Get the request Block array from the request string
3261 // Offset and Width
3262 //
3263
3264 //
3265 // Parse each <RequestElement> if exists
3266 // Only <BlockName> format is supported by this help function.
3267 // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>
3268 //
3269 StringPtr = ConfigRequest;
3270 while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {
3271 //
3272 // Skip the OFFSET string
3273 //
3274 *Progress = StringPtr;
3275 StringPtr += StrLen (L"&OFFSET=");
3276 //
3277 // Get Offset
3278 //
3279 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
3280 if (EFI_ERROR (Status)) {
3281 goto Done;
3282 }
3283
3284 Offset = 0;
3285 CopyMem (
3286 &Offset,
3287 TmpBuffer,
3288 (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)
3289 );
3290 FreePool (TmpBuffer);
3291
3292 StringPtr += Length;
3293 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
3294 goto Done;
3295 }
3296
3297 StringPtr += StrLen (L"&WIDTH=");
3298
3299 //
3300 // Get Width
3301 //
3302 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
3303 if (EFI_ERROR (Status)) {
3304 goto Done;
3305 }
3306
3307 Width = 0;
3308 CopyMem (
3309 &Width,
3310 TmpBuffer,
3311 (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)
3312 );
3313 FreePool (TmpBuffer);
3314
3315 StringPtr += Length;
3316 if ((*StringPtr != 0) && (*StringPtr != L'&')) {
3317 goto Done;
3318 }
3319
3320 //
3321 // Set Block Data
3322 //
3323 BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
3324 if (BlockData == NULL) {
3325 goto Done;
3326 }
3327
3328 BlockData->Offset = Offset;
3329 BlockData->Width = Width;
3330 InsertBlockData (&RequestBlockArray->Entry, &BlockData);
3331
3332 //
3333 // Skip &VALUE string if &VALUE does exists.
3334 //
3335 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) == 0) {
3336 StringPtr += StrLen (L"&VALUE=");
3337
3338 //
3339 // Get Value
3340 //
3341 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
3342 if (EFI_ERROR (Status)) {
3343 goto Done;
3344 }
3345
3346 FreePool (TmpBuffer);
3347 StringPtr += Length;
3348 if ((*StringPtr != 0) && (*StringPtr != L'&')) {
3349 goto Done;
3350 }
3351 }
3352
3353 //
3354 // If '\0', parsing is finished.
3355 //
3356 if (*StringPtr == 0) {
3357 break;
3358 }
3359 }
3360
3361 //
3362 // Merge the requested block data.
3363 //
3364 Link = RequestBlockArray->Entry.ForwardLink;
3365 while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {
3366 BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
3367 NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);
3368 if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {
3369 if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {
3370 BlockData->Width = (UINT16)(NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);
3371 }
3372
3373 RemoveEntryList (Link->ForwardLink);
3374 FreePool (NextBlockData);
3375 continue;
3376 }
3377
3378 Link = Link->ForwardLink;
3379 }
3380
3381 return RequestBlockArray;
3382
3383Done:
3384 if (RequestBlockArray != NULL) {
3385 //
3386 // Free Link Array RequestBlockArray
3387 //
3388 while (!IsListEmpty (&RequestBlockArray->Entry)) {
3389 BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
3390 RemoveEntryList (&BlockData->Entry);
3391 FreePool (BlockData);
3392 }
3393
3394 FreePool (RequestBlockArray);
3395 }
3396
3397 return NULL;
3398}
3399
3410 IN EFI_STRING ConfigRequest,
3411 OUT EFI_STRING *Progress
3412 )
3413{
3414 EFI_STRING StringPtr;
3415 EFI_STRING NextTag;
3416 IFR_BLOCK_DATA *BlockData;
3417 IFR_BLOCK_DATA *RequestBlockArray;
3418 BOOLEAN HasValue;
3419
3420 StringPtr = ConfigRequest;
3421
3422 //
3423 // Init RequestBlockArray
3424 //
3425 RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
3426 if (RequestBlockArray == NULL) {
3427 goto Done;
3428 }
3429
3430 InitializeListHead (&RequestBlockArray->Entry);
3431
3432 //
3433 // Get the request Block array from the request string
3434 //
3435
3436 //
3437 // Parse each <RequestElement> if exists
3438 // Only <BlockName> format is supported by this help function.
3439 // <BlockName> ::= &'Name***=***
3440 //
3441 while (StringPtr != NULL && *StringPtr == L'&') {
3442 *Progress = StringPtr;
3443 //
3444 // Skip the L"&" string
3445 //
3446 StringPtr += 1;
3447
3448 HasValue = FALSE;
3449 if ((NextTag = StrStr (StringPtr, L"=")) != NULL) {
3450 *NextTag = L'\0';
3451 HasValue = TRUE;
3452 } else if ((NextTag = StrStr (StringPtr, L"&")) != NULL) {
3453 *NextTag = L'\0';
3454 }
3455
3456 //
3457 // Set Block Data
3458 //
3459 BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
3460 if (BlockData == NULL) {
3461 goto Done;
3462 }
3463
3464 //
3465 // Get Name
3466 //
3467 BlockData->Name = AllocateCopyPool (StrSize (StringPtr), StringPtr);
3468 InsertBlockData (&RequestBlockArray->Entry, &BlockData);
3469
3470 if (HasValue) {
3471 //
3472 // If has value, skip the value.
3473 //
3474 StringPtr = NextTag + 1;
3475 *NextTag = L'=';
3476 StringPtr = StrStr (StringPtr, L"&");
3477 } else if (NextTag != NULL) {
3478 //
3479 // restore the '&' text.
3480 //
3481 StringPtr = NextTag;
3482 *NextTag = L'&';
3483 }
3484 }
3485
3486 return RequestBlockArray;
3487
3488Done:
3489 if (RequestBlockArray != NULL) {
3490 //
3491 // Free Link Array RequestBlockArray
3492 //
3493 while (!IsListEmpty (&RequestBlockArray->Entry)) {
3494 BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
3495 RemoveEntryList (&BlockData->Entry);
3496 if (BlockData->Name != NULL) {
3497 FreePool (BlockData->Name);
3498 }
3499
3500 FreePool (BlockData);
3501 }
3502
3503 FreePool (RequestBlockArray);
3504 }
3505
3506 return NULL;
3507}
3508
3520BOOLEAN
3522 IN CHAR16 *ConfigHdr,
3523 IN IFR_VARSTORAGE_DATA *VarStorageData,
3524 OUT EFI_STATUS *Status,
3525 IN OUT EFI_STRING *ConfigRequest
3526 )
3527{
3528 BOOLEAN DataExist;
3529 UINTN Length;
3530 LIST_ENTRY *Link;
3531 CHAR16 *FullConfigRequest;
3532 CHAR16 *StringPtr;
3533 IFR_BLOCK_DATA *BlockData;
3534
3535 //
3536 // Append VarStorageData BlockEntry into *Request string
3537 // Now support only one varstore in a form package.
3538 //
3539
3540 //
3541 // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package
3542 // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig
3543 //
3544
3545 //
3546 // Compute the length of the entire request starting with <ConfigHdr> and a
3547 // Null-terminator
3548 //
3549 DataExist = FALSE;
3550 Length = StrLen (ConfigHdr) + 1;
3551
3552 for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {
3553 DataExist = TRUE;
3554 BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
3555 if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
3556 //
3557 // Add <BlockName> length for each Name
3558 //
3559 // <BlockName> ::= &Name1&Name2&...
3560 // |1| StrLen(Name1)
3561 //
3562 Length = Length + (1 + StrLen (BlockData->Name));
3563 } else {
3564 //
3565 // Add <BlockName> length for each Offset/Width pair
3566 //
3567 // <BlockName> ::= &OFFSET=1234&WIDTH=1234
3568 // | 8 | 4 | 7 | 4 |
3569 //
3570 Length = Length + (8 + 4 + 7 + 4);
3571 }
3572 }
3573
3574 //
3575 // No any request block data is found. The request string can't be constructed.
3576 //
3577 if (!DataExist) {
3578 *Status = EFI_SUCCESS;
3579 return FALSE;
3580 }
3581
3582 //
3583 // Allocate buffer for the entire <ConfigRequest>
3584 //
3585 FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));
3586 if (FullConfigRequest == NULL) {
3587 *Status = EFI_OUT_OF_RESOURCES;
3588 return FALSE;
3589 }
3590
3591 StringPtr = FullConfigRequest;
3592
3593 //
3594 // Start with <ConfigHdr>
3595 //
3596 StrCpyS (StringPtr, Length, ConfigHdr);
3597 StringPtr += StrLen (StringPtr);
3598
3599 //
3600 // Loop through all the Offset/Width pairs and append them to ConfigRequest
3601 //
3602 for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {
3603 BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
3604 if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
3605 //
3606 // Append &Name1\0
3607 //
3609 StringPtr,
3610 (1 + StrLen (BlockData->Name) + 1) * sizeof (CHAR16),
3611 L"&%s",
3612 BlockData->Name
3613 );
3614 } else {
3615 //
3616 // Append &OFFSET=XXXX&WIDTH=YYYY\0
3617 //
3619 StringPtr,
3620 (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
3621 L"&OFFSET=%04X&WIDTH=%04X",
3622 BlockData->Offset,
3623 BlockData->Width
3624 );
3625 }
3626
3627 StringPtr += StrLen (StringPtr);
3628 }
3629
3630 //
3631 // Set to the got full request string.
3632 //
3633 HiiToLower (FullConfigRequest);
3634
3635 if (*ConfigRequest != NULL) {
3636 FreePool (*ConfigRequest);
3637 }
3638
3639 *ConfigRequest = FullConfigRequest;
3640
3641 return TRUE;
3642}
3643
3656 IN IFR_VARSTORAGE_DATA *VarStorageData,
3657 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
3658 OUT EFI_STRING *ConfigHdr
3659 )
3660{
3661 EFI_STRING GuidStr;
3662 EFI_STRING NameStr;
3663 EFI_STRING PathStr;
3664 UINTN Length;
3665 EFI_STATUS Status;
3666
3667 Status = EFI_SUCCESS;
3668 NameStr = NULL;
3669 GuidStr = NULL;
3670 PathStr = NULL;
3671
3672 //
3673 // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle
3674 //
3675 GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)&VarStorageData->Guid, 1, &GuidStr);
3676 if (VarStorageData->Name != NULL) {
3677 GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *)VarStorageData->Name, 2, &NameStr);
3678 } else {
3679 GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);
3680 }
3681
3683 L"PATH=",
3685 (VOID *)DevicePath,
3686 1,
3687 &PathStr
3688 );
3689 Length = StrLen (GuidStr) + StrLen (NameStr) + StrLen (PathStr) + 1;
3690 if (VarStorageData->Name == NULL) {
3691 Length += 1;
3692 }
3693
3694 *ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));
3695 if (*ConfigHdr == NULL) {
3696 Status = EFI_OUT_OF_RESOURCES;
3697 goto Done;
3698 }
3699
3700 StrCpyS (*ConfigHdr, Length, GuidStr);
3701 StrCatS (*ConfigHdr, Length, NameStr);
3702 if (VarStorageData->Name == NULL) {
3703 StrCatS (*ConfigHdr, Length, L"&");
3704 }
3705
3706 StrCatS (*ConfigHdr, Length, PathStr);
3707
3708 //
3709 // Remove the last character L'&'
3710 //
3711 *(*ConfigHdr + StrLen (*ConfigHdr) - 1) = L'\0';
3712
3713Done:
3714 if (GuidStr != NULL) {
3715 FreePool (GuidStr);
3716 }
3717
3718 if (NameStr != NULL) {
3719 FreePool (NameStr);
3720 }
3721
3722 if (PathStr != NULL) {
3723 FreePool (PathStr);
3724 }
3725
3726 return Status;
3727}
3728
3753VOID
3755 IN LIST_ENTRY *BlockLink
3756 )
3757{
3758 LIST_ENTRY *Link;
3759 LIST_ENTRY *ListEntry;
3760 LIST_ENTRY *LinkDefault;
3761 IFR_BLOCK_DATA *BlockData;
3762 IFR_DEFAULT_DATA *DefaultValueData;
3763 UINTN StartBit;
3764 UINTN EndBit;
3765 UINT32 BitFieldDefaultValue;
3766
3767 for ( Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
3768 BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
3769 if (!BlockData->IsBitVar) {
3770 continue;
3771 }
3772
3773 ListEntry = &BlockData->DefaultValueEntry;
3774 //
3775 // Update the default value in the block data with all existing default id.
3776 //
3777 for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {
3778 //
3779 // Get the default data, and the value of the default data is for some field in the block.
3780 // Note: Default value for bit field question is stored as UINT32.
3781 //
3782 DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
3783 BitFieldDefaultValue = DefaultValueData->Value.u32;
3784
3785 StartBit = BlockData->BitOffset % 8;
3786 EndBit = StartBit + BlockData->BitWidth - 1;
3787
3788 //
3789 // Set the bit field default value to related bit filed, then we will got the new default vaule for the block data.
3790 //
3791 DefaultValueData->Value.u32 = BitFieldWrite32 (0, StartBit, EndBit, BitFieldDefaultValue);
3792 }
3793 }
3794}
3795
3833VOID
3835 IN OUT IFR_BLOCK_DATA *FirstBlock,
3836 IN OUT IFR_BLOCK_DATA *SecondBlock
3837 )
3838{
3839 LIST_ENTRY *FirstListEntry;
3840 LIST_ENTRY *SecondListEntry;
3841 LIST_ENTRY *FirstDefaultLink;
3842 LIST_ENTRY *SecondDefaultLink;
3843 IFR_DEFAULT_DATA *FirstDefaultValueData;
3844 IFR_DEFAULT_DATA *SecondDefaultValueData;
3845 UINT32 *FirstDefaultValue;
3846 UINT32 *SecondDefaultValue;
3847 UINT64 TotalValue;
3848 UINT64 ShiftedValue;
3849 UINT16 OffsetShift;
3850
3851 FirstListEntry = &FirstBlock->DefaultValueEntry;
3852 for (FirstDefaultLink = FirstListEntry->ForwardLink; FirstDefaultLink != FirstListEntry; FirstDefaultLink = FirstDefaultLink->ForwardLink) {
3853 FirstDefaultValueData = BASE_CR (FirstDefaultLink, IFR_DEFAULT_DATA, Entry);
3854 SecondListEntry = &SecondBlock->DefaultValueEntry;
3855 for (SecondDefaultLink = SecondListEntry->ForwardLink; SecondDefaultLink != SecondListEntry; SecondDefaultLink = SecondDefaultLink->ForwardLink) {
3856 SecondDefaultValueData = BASE_CR (SecondDefaultLink, IFR_DEFAULT_DATA, Entry);
3857 if (FirstDefaultValueData->DefaultId != SecondDefaultValueData->DefaultId) {
3858 continue;
3859 }
3860
3861 //
3862 // Find default value with same default id in the two blocks.
3863 // Note: Default value for bit field question is stored as UINT32 type.
3864 //
3865 FirstDefaultValue = &FirstDefaultValueData->Value.u32;
3866 SecondDefaultValue = &SecondDefaultValueData->Value.u32;
3867 //
3868 // 1. Get the default value of the whole blcok that can just cover FirstBlock and SecondBlock.
3869 // 2. Get the default value of FirstBlock and SecondBlock form the value of whole block based
3870 // on the offset and width of FirstBlock and SecondBlock.
3871 //
3872 if (FirstBlock->Offset > SecondBlock->Offset) {
3873 OffsetShift = FirstBlock->Offset - SecondBlock->Offset;
3874 ShiftedValue = LShiftU64 ((UINT64)(*FirstDefaultValue), OffsetShift * 8);
3875 TotalValue = ShiftedValue | (UINT64)(*SecondDefaultValue);
3876 *SecondDefaultValue = (UINT32)BitFieldRead64 (TotalValue, 0, SecondBlock->Width * 8 -1);
3877 *FirstDefaultValue = (UINT32)BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + FirstBlock->Width *8 -1);
3878 } else {
3879 OffsetShift = SecondBlock->Offset -FirstBlock->Offset;
3880 ShiftedValue = LShiftU64 ((UINT64)(*SecondDefaultValue), OffsetShift * 8);
3881 TotalValue = ShiftedValue | (UINT64)(*FirstDefaultValue);
3882 *FirstDefaultValue = (UINT32)BitFieldRead64 (TotalValue, 0, FirstBlock->Width * 8 -1);
3883 *SecondDefaultValue = (UINT32)BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + SecondBlock->Width *8 -1);
3884 }
3885 }
3886 }
3887}
3888
3896VOID
3898 IN LIST_ENTRY *BlockLink
3899 )
3900{
3901 LIST_ENTRY *Link;
3902 LIST_ENTRY *TempLink;
3903 IFR_BLOCK_DATA *BlockData;
3904 IFR_BLOCK_DATA *NextBlockData;
3905
3906 //
3907 // 1. Update default value in BitVar block data.
3908 // Sine some block datas are used as BitVarStore, then the default value recored in the block
3909 // is for related bit field in the block. so we need to set the default value to the related bit
3910 // fields in the block data if the block data is used as bit varstore, then the default value of
3911 // the block will be updated.
3912 //
3913 UpdateDefaultValue (BlockLink);
3914
3915 //
3916 // 2.Update default value for overlap BitVar blcok datas.
3917 // For block datas have overlap region, we need to merge the default value in different blocks.
3918 //
3919 for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
3920 BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
3921 if (!BlockData->IsBitVar) {
3922 continue;
3923 }
3924
3925 for (TempLink = Link->ForwardLink; TempLink != BlockLink; TempLink = TempLink->ForwardLink) {
3926 NextBlockData = BASE_CR (TempLink, IFR_BLOCK_DATA, Entry);
3927 if (!NextBlockData->IsBitVar || (NextBlockData->Offset >= BlockData->Offset + BlockData->Width) || (BlockData->Offset >= NextBlockData->Offset + NextBlockData->Width)) {
3928 continue;
3929 }
3930
3931 //
3932 // Find two blocks are used as bit VarStore and have overlap region, so need to merge default value of these two blocks.
3933 //
3934 MergeBlockDefaultValue (BlockData, NextBlockData);
3935 }
3936 }
3937}
3938
3953 IN EFI_HII_HANDLE HiiHandle,
3954 IN CHAR16 *ConfigHdr,
3955 IN IFR_VARSTORAGE_DATA *VarStorageData,
3956 IN IFR_DEFAULT_DATA *DefaultIdArray,
3957 IN OUT EFI_STRING *DefaultAltCfgResp
3958 )
3959{
3960 BOOLEAN DataExist;
3961 UINTN Length;
3962 LIST_ENTRY *Link;
3963 LIST_ENTRY *LinkData;
3964 LIST_ENTRY *LinkDefault;
3965 LIST_ENTRY *ListEntry;
3966 CHAR16 *StringPtr;
3967 IFR_BLOCK_DATA *BlockData;
3968 IFR_DEFAULT_DATA *DefaultId;
3969 IFR_DEFAULT_DATA *DefaultValueData;
3970 UINTN Width;
3971 UINT8 *TmpBuffer;
3972 CHAR16 *DefaultString;
3973 UINTN StrSize;
3974
3975 BlockData = NULL;
3976 DataExist = FALSE;
3977 DefaultString = NULL;
3978 //
3979 // Add length for <ConfigHdr> + '\0'
3980 //
3981 Length = StrLen (ConfigHdr) + 1;
3982
3983 UpdateBlockDataArray (&VarStorageData->BlockEntry);
3984
3985 for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {
3986 DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
3987 //
3988 // Add length for "&<ConfigHdr>&ALTCFG=XXXX"
3989 // |1| StrLen (ConfigHdr) | 8 | 4 |
3990 //
3991 Length += (1 + StrLen (ConfigHdr) + 8 + 4);
3992
3993 for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {
3994 BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);
3995 ListEntry = &BlockData->DefaultValueEntry;
3996 for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {
3997 DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
3998 if (DefaultValueData->DefaultId != DefaultId->DefaultId) {
3999 continue;
4000 }
4001
4002 if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
4003 //
4004 // Add length for "&Name1=zzzzzzzzzzzz"
4005 // |1|Name|1|Value|
4006 //
4007 Length += (1 + StrLen (BlockData->Name) + 1 + BlockData->Width * 2);
4008 } else {
4009 //
4010 // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"
4011 // | 8 | 4 | 7 | 4 | 7 | Width * 2 |
4012 //
4013 Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);
4014 }
4015
4016 DataExist = TRUE;
4017 }
4018 }
4019 }
4020
4021 //
4022 // No default value is found. The default string doesn't exist.
4023 //
4024 if (!DataExist) {
4025 return EFI_SUCCESS;
4026 }
4027
4028 //
4029 // Allocate buffer for the entire <DefaultAltCfgResp>
4030 //
4031 *DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));
4032 if (*DefaultAltCfgResp == NULL) {
4033 return EFI_OUT_OF_RESOURCES;
4034 }
4035
4036 StringPtr = *DefaultAltCfgResp;
4037
4038 //
4039 // Start with <ConfigHdr>
4040 //
4041 StrCpyS (StringPtr, Length, ConfigHdr);
4042 StringPtr += StrLen (StringPtr);
4043
4044 for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {
4045 DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
4046 //
4047 // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"
4048 // |1| StrLen (ConfigHdr) | 8 | 4 |
4049 //
4051 StringPtr,
4052 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),
4053 L"&%s&ALTCFG=%04X",
4054 ConfigHdr,
4055 DefaultId->DefaultId
4056 );
4057 StringPtr += StrLen (StringPtr);
4058
4059 for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {
4060 BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);
4061 ListEntry = &BlockData->DefaultValueEntry;
4062 for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {
4063 DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
4064 if (DefaultValueData->DefaultId != DefaultId->DefaultId) {
4065 continue;
4066 }
4067
4068 if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
4070 StringPtr,
4071 (1 + StrLen (ConfigHdr) + 1) * sizeof (CHAR16),
4072 L"&%s=",
4073 BlockData->Name
4074 );
4075 StringPtr += StrLen (StringPtr);
4076 } else {
4077 //
4078 // Add <BlockConfig>
4079 // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
4080 //
4082 StringPtr,
4083 (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),
4084 L"&OFFSET=%04X&WIDTH=%04X&VALUE=",
4085 BlockData->Offset,
4086 BlockData->Width
4087 );
4088 StringPtr += StrLen (StringPtr);
4089 }
4090
4091 Width = BlockData->Width;
4092 //
4093 // Convert Value to a hex string in "%x" format
4094 // NOTE: This is in the opposite byte that GUID and PATH use
4095 //
4096 if (BlockData->OpCode == EFI_IFR_STRING_OP) {
4097 DefaultString = InternalGetString (HiiHandle, DefaultValueData->Value.string);
4098 TmpBuffer = AllocateZeroPool (Width);
4099 ASSERT (TmpBuffer != NULL);
4100 if (DefaultString != NULL) {
4101 StrSize = StrLen (DefaultString)* sizeof (CHAR16);
4102 if (StrSize > Width) {
4103 StrSize = Width;
4104 }
4105
4106 CopyMem (TmpBuffer, (UINT8 *)DefaultString, StrSize);
4107 }
4108 } else {
4109 TmpBuffer = (UINT8 *)&(DefaultValueData->Value);
4110 }
4111
4112 for ( ; Width > 0 && (TmpBuffer != NULL); Width--) {
4114 StringPtr,
4115 Length * sizeof (CHAR16) - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp),
4116 PREFIX_ZERO | RADIX_HEX,
4117 TmpBuffer[Width - 1],
4118 2
4119 );
4120 StringPtr += StrnLenS (StringPtr, Length - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp) / sizeof (CHAR16));
4121 }
4122
4123 if (DefaultString != NULL) {
4124 FreePool (DefaultString);
4125 DefaultString = NULL;
4126 }
4127
4128 if ((BlockData->OpCode == EFI_IFR_STRING_OP) && (TmpBuffer != NULL)) {
4129 FreePool (TmpBuffer);
4130 TmpBuffer = NULL;
4131 }
4132 }
4133 }
4134 }
4135
4136 HiiToLower (*DefaultAltCfgResp);
4137
4138 return EFI_SUCCESS;
4139}
4140
4185EFIAPI
4187 IN HII_DATABASE_RECORD *DataBaseRecord,
4188 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
4189 IN OUT EFI_STRING *Request,
4190 IN OUT EFI_STRING *AltCfgResp,
4191 OUT EFI_STRING *PointerProgress OPTIONAL
4192 )
4193{
4194 EFI_STATUS Status;
4195 UINT8 *HiiFormPackage;
4196 UINTN PackageSize;
4197 IFR_BLOCK_DATA *RequestBlockArray;
4198 IFR_BLOCK_DATA *BlockData;
4199 IFR_DEFAULT_DATA *DefaultValueData;
4200 IFR_DEFAULT_DATA *DefaultId;
4201 IFR_DEFAULT_DATA *DefaultIdArray;
4202 IFR_VARSTORAGE_DATA *VarStorageData;
4203 EFI_STRING DefaultAltCfgResp;
4204 EFI_STRING ConfigHdr;
4205 EFI_STRING StringPtr;
4206 EFI_STRING Progress;
4207
4208 if ((DataBaseRecord == NULL) || (DevicePath == NULL) || (Request == NULL) || (AltCfgResp == NULL)) {
4209 return EFI_INVALID_PARAMETER;
4210 }
4211
4212 //
4213 // Initialize the local variables.
4214 //
4215 RequestBlockArray = NULL;
4216 DefaultIdArray = NULL;
4217 VarStorageData = NULL;
4218 DefaultAltCfgResp = NULL;
4219 ConfigHdr = NULL;
4220 HiiFormPackage = NULL;
4221 PackageSize = 0;
4222 Progress = *Request;
4223
4224 Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
4225 if (EFI_ERROR (Status)) {
4226 goto Done;
4227 }
4228
4229 //
4230 // 1. Get the request block array by Request String when Request string contains the block array.
4231 //
4232 StringPtr = NULL;
4233 if (*Request != NULL) {
4234 StringPtr = *Request;
4235 //
4236 // Jump <ConfigHdr>
4237 //
4238 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
4239 Status = EFI_INVALID_PARAMETER;
4240 goto Done;
4241 }
4242
4243 StringPtr += StrLen (L"GUID=");
4244 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
4245 StringPtr++;
4246 }
4247
4248 if (*StringPtr == L'\0') {
4249 Status = EFI_INVALID_PARAMETER;
4250 goto Done;
4251 }
4252
4253 StringPtr += StrLen (L"&NAME=");
4254 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
4255 StringPtr++;
4256 }
4257
4258 if (*StringPtr == L'\0') {
4259 Status = EFI_INVALID_PARAMETER;
4260 goto Done;
4261 }
4262
4263 StringPtr += StrLen (L"&PATH=");
4264 while (*StringPtr != L'\0' && *StringPtr != L'&') {
4265 StringPtr++;
4266 }
4267
4268 if (*StringPtr == L'\0') {
4269 //
4270 // No request block is found.
4271 //
4272 StringPtr = NULL;
4273 }
4274 }
4275
4276 //
4277 // If StringPtr != NULL, get the request elements.
4278 //
4279 if (StringPtr != NULL) {
4280 if (StrStr (StringPtr, L"&OFFSET=") != NULL) {
4281 RequestBlockArray = GetBlockElement (StringPtr, &Progress);
4282 } else {
4283 RequestBlockArray = GetNameElement (StringPtr, &Progress);
4284 }
4285
4286 if (RequestBlockArray == NULL) {
4287 Status = EFI_INVALID_PARAMETER;
4288 goto Done;
4289 }
4290 }
4291
4292 //
4293 // Initialize DefaultIdArray to store the map between DeaultId and DefaultName
4294 //
4295 DefaultIdArray = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));
4296 if (DefaultIdArray == NULL) {
4297 Status = EFI_OUT_OF_RESOURCES;
4298 goto Done;
4299 }
4300
4301 InitializeListHead (&DefaultIdArray->Entry);
4302
4303 //
4304 // Initialize VarStorageData to store the var store Block and Default value information.
4305 //
4306 VarStorageData = (IFR_VARSTORAGE_DATA *)AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));
4307 if (VarStorageData == NULL) {
4308 Status = EFI_OUT_OF_RESOURCES;
4309 goto Done;
4310 }
4311
4312 InitializeListHead (&VarStorageData->Entry);
4313 InitializeListHead (&VarStorageData->BlockEntry);
4314
4315 //
4316 // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.
4317 //
4318
4319 //
4320 // Parse the opcode in form package to get the default setting.
4321 //
4322 Status = ParseIfrData (
4323 DataBaseRecord->Handle,
4324 HiiFormPackage,
4325 (UINT32)PackageSize,
4326 *Request,
4327 RequestBlockArray,
4328 VarStorageData,
4329 DefaultIdArray
4330 );
4331 if (EFI_ERROR (Status)) {
4332 goto Done;
4333 }
4334
4335 //
4336 // No requested varstore in IFR data and directly return
4337 //
4338 if ((VarStorageData->Type == 0) && (VarStorageData->Name == NULL)) {
4339 Status = EFI_SUCCESS;
4340 goto Done;
4341 }
4342
4343 //
4344 // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.
4345 //
4346 Status = GenerateHdr (VarStorageData, DevicePath, &ConfigHdr);
4347 if (EFI_ERROR (Status)) {
4348 goto Done;
4349 }
4350
4351 if (RequestBlockArray == NULL) {
4352 if (!GenerateConfigRequest (ConfigHdr, VarStorageData, &Status, Request)) {
4353 goto Done;
4354 }
4355 }
4356
4357 //
4358 // 4. Construct Default Value string in AltResp according to request element.
4359 // Go through all VarStorageData Entry and get the DefaultId array for each one
4360 // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody
4361 //
4362 Status = GenerateAltConfigResp (DataBaseRecord->Handle, ConfigHdr, VarStorageData, DefaultIdArray, &DefaultAltCfgResp);
4363 if (EFI_ERROR (Status)) {
4364 goto Done;
4365 }
4366
4367 //
4368 // 5. Merge string into the input AltCfgResp if the input *AltCfgResp is not NULL.
4369 //
4370 if ((*AltCfgResp != NULL) && (DefaultAltCfgResp != NULL)) {
4371 Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);
4372 FreePool (DefaultAltCfgResp);
4373 } else if (*AltCfgResp == NULL) {
4374 *AltCfgResp = DefaultAltCfgResp;
4375 }
4376
4377Done:
4378 if (RequestBlockArray != NULL) {
4379 //
4380 // Free Link Array RequestBlockArray
4381 //
4382 while (!IsListEmpty (&RequestBlockArray->Entry)) {
4383 BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
4384 RemoveEntryList (&BlockData->Entry);
4385 if (BlockData->Name != NULL) {
4386 FreePool (BlockData->Name);
4387 }
4388
4389 FreePool (BlockData);
4390 }
4391
4392 FreePool (RequestBlockArray);
4393 }
4394
4395 if (VarStorageData != NULL) {
4396 //
4397 // Free link array VarStorageData
4398 //
4399 while (!IsListEmpty (&VarStorageData->BlockEntry)) {
4400 BlockData = BASE_CR (VarStorageData->BlockEntry.ForwardLink, IFR_BLOCK_DATA, Entry);
4401 RemoveEntryList (&BlockData->Entry);
4402 if (BlockData->Name != NULL) {
4403 FreePool (BlockData->Name);
4404 }
4405
4406 //
4407 // Free default value link array
4408 //
4409 while (!IsListEmpty (&BlockData->DefaultValueEntry)) {
4410 DefaultValueData = BASE_CR (BlockData->DefaultValueEntry.ForwardLink, IFR_DEFAULT_DATA, Entry);
4411 RemoveEntryList (&DefaultValueData->Entry);
4412 FreePool (DefaultValueData);
4413 }
4414
4415 FreePool (BlockData);
4416 }
4417
4418 if (VarStorageData->Name != NULL) {
4419 FreePool (VarStorageData->Name);
4420 VarStorageData->Name = NULL;
4421 }
4422
4423 FreePool (VarStorageData);
4424 }
4425
4426 if (DefaultIdArray != NULL) {
4427 //
4428 // Free DefaultId Array
4429 //
4430 while (!IsListEmpty (&DefaultIdArray->Entry)) {
4431 DefaultId = BASE_CR (DefaultIdArray->Entry.ForwardLink, IFR_DEFAULT_DATA, Entry);
4432 RemoveEntryList (&DefaultId->Entry);
4433 FreePool (DefaultId);
4434 }
4435
4436 FreePool (DefaultIdArray);
4437 }
4438
4439 //
4440 // Free the allocated string
4441 //
4442 if (ConfigHdr != NULL) {
4443 FreePool (ConfigHdr);
4444 }
4445
4446 //
4447 // Free Package data
4448 //
4449 if (HiiFormPackage != NULL) {
4450 FreePool (HiiFormPackage);
4451 }
4452
4453 if (PointerProgress != NULL) {
4454 if (*Request == NULL) {
4455 *PointerProgress = NULL;
4456 } else if (EFI_ERROR (Status)) {
4457 *PointerProgress = *Request;
4458 } else {
4459 *PointerProgress = *Request + StrLen (*Request);
4460 }
4461 }
4462
4463 return Status;
4464}
4465
4495 IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo,
4496 IN EFI_STRING Request,
4497 OUT EFI_STRING *RequestResp,
4498 OUT EFI_STRING *AccessProgress
4499 )
4500{
4501 EFI_STATUS Status;
4502 EFI_STRING VarStoreName;
4503 UINTN NameSize;
4504 UINT8 *VarStore;
4505 UINTN BufferSize;
4506
4507 Status = EFI_SUCCESS;
4508 BufferSize = 0;
4509 VarStore = NULL;
4510 VarStoreName = NULL;
4511 *AccessProgress = Request;
4512
4513 NameSize = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);
4514 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
4515 if (VarStoreName == NULL) {
4516 Status = EFI_OUT_OF_RESOURCES;
4517 goto Done;
4518 }
4519
4520 AsciiStrToUnicodeStrS ((CHAR8 *)EfiVarStoreInfo->Name, VarStoreName, NameSize);
4521
4522 Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);
4523 if (Status != EFI_BUFFER_TOO_SMALL) {
4524 goto Done;
4525 }
4526
4527 VarStore = AllocateZeroPool (BufferSize);
4528 ASSERT (VarStore != NULL);
4529 Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);
4530 if (EFI_ERROR (Status)) {
4531 goto Done;
4532 }
4533
4534 Status = HiiBlockToConfig (This, Request, VarStore, BufferSize, RequestResp, AccessProgress);
4535 if (EFI_ERROR (Status)) {
4536 goto Done;
4537 }
4538
4539Done:
4540 if (VarStoreName != NULL) {
4541 FreePool (VarStoreName);
4542 }
4543
4544 if (VarStore != NULL) {
4545 FreePool (VarStore);
4546 }
4547
4548 return Status;
4549}
4550
4572 IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo,
4573 IN EFI_STRING RequestResp,
4574 OUT EFI_STRING *Result
4575 )
4576{
4577 EFI_STATUS Status;
4578 EFI_STRING VarStoreName;
4579 UINTN NameSize;
4580 UINT8 *VarStore;
4581 UINTN BufferSize;
4582 UINTN BlockSize;
4583
4584 Status = EFI_SUCCESS;
4585 BufferSize = 0;
4586 VarStore = NULL;
4587 VarStoreName = NULL;
4588 *Result = RequestResp;
4589
4590 NameSize = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);
4591 VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
4592 if (VarStoreName == NULL) {
4593 Status = EFI_OUT_OF_RESOURCES;
4594 goto Done;
4595 }
4596
4597 AsciiStrToUnicodeStrS ((CHAR8 *)EfiVarStoreInfo->Name, VarStoreName, NameSize);
4598
4599 Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);
4600 if (Status != EFI_BUFFER_TOO_SMALL) {
4601 DEBUG ((DEBUG_ERROR, "The variable does not exist!"));
4602 goto Done;
4603 }
4604
4605 BlockSize = BufferSize;
4606 VarStore = AllocateZeroPool (BufferSize);
4607 ASSERT (VarStore != NULL);
4608 Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);
4609 if (EFI_ERROR (Status)) {
4610 goto Done;
4611 }
4612
4613 Status = HiiConfigToBlock (This, RequestResp, VarStore, &BlockSize, Result);
4614 if (EFI_ERROR (Status)) {
4615 goto Done;
4616 }
4617
4618 Status = gRT->SetVariable (VarStoreName, &EfiVarStoreInfo->Guid, EfiVarStoreInfo->Attributes, BufferSize, VarStore);
4619 if (EFI_ERROR (Status)) {
4620 *Result = RequestResp;
4621 goto Done;
4622 }
4623
4624Done:
4625 if (VarStoreName != NULL) {
4626 FreePool (VarStoreName);
4627 }
4628
4629 if (VarStore != NULL) {
4630 FreePool (VarStore);
4631 }
4632
4633 return Status;
4634}
4635
4645CHAR16 *
4647 CHAR16 *ConfigElements
4648 )
4649{
4650 CHAR16 *StringPtr;
4651 CHAR16 *RetVal;
4652
4653 StringPtr = ConfigElements;
4654
4655 while (1) {
4656 RetVal = StringPtr;
4657 if (StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {
4658 return RetVal;
4659 }
4660
4661 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
4662 StringPtr++;
4663 }
4664
4665 if (*StringPtr == L'\0') {
4666 return RetVal;
4667 }
4668
4669 StringPtr += StrLen (L"&WIDTH=");
4670 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {
4671 StringPtr++;
4672 }
4673
4674 if (*StringPtr == L'\0') {
4675 return NULL;
4676 }
4677 }
4678}
4679
4690CHAR16 *
4692 CHAR16 *ConfigElements
4693 )
4694{
4695 CHAR16 *StringPtr;
4696 CHAR16 *RetVal;
4697
4698 StringPtr = ConfigElements;
4699
4700 while (1) {
4701 RetVal = StringPtr;
4702 if (*StringPtr != L'&') {
4703 return RetVal;
4704 }
4705
4706 StringPtr += 1;
4707
4708 StringPtr = StrStr (StringPtr, L"&");
4709
4710 if (StringPtr == NULL) {
4711 return NULL;
4712 }
4713 }
4714}
4715
4725CHAR16 *
4727 CHAR16 *ConfigRequest
4728 )
4729{
4730 BOOLEAN HasNameField;
4731 CHAR16 *StringPtr;
4732
4733 HasNameField = TRUE;
4734 StringPtr = ConfigRequest;
4735
4736 //
4737 // Check <ConfigHdr>
4738 //
4739 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
4740 return ConfigRequest;
4741 }
4742
4743 StringPtr += StrLen (L"GUID=");
4744 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
4745 StringPtr++;
4746 }
4747
4748 if (*StringPtr == L'\0') {
4749 return ConfigRequest;
4750 }
4751
4752 StringPtr += StrLen (L"&NAME=");
4753 if (*StringPtr == L'&') {
4754 HasNameField = FALSE;
4755 }
4756
4757 while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
4758 StringPtr++;
4759 }
4760
4761 if (*StringPtr == L'\0') {
4762 return ConfigRequest;
4763 }
4764
4765 StringPtr += StrLen (L"&PATH=");
4766 while (*StringPtr != L'\0' && *StringPtr != L'&') {
4767 StringPtr++;
4768 }
4769
4770 if (*StringPtr == L'\0') {
4771 return NULL;
4772 }
4773
4774 if (HasNameField) {
4775 //
4776 // Should be Buffer varstore, config request should be "OFFSET/Width" pairs.
4777 //
4778 return OffsetWidthValidate (StringPtr);
4779 } else {
4780 //
4781 // Should be Name/Value varstore, config request should be "&name1&name2..." pairs.
4782 //
4783 return NameValueValidate (StringPtr);
4784 }
4785}
4786
4829EFIAPI
4832 IN CONST EFI_STRING Request,
4833 OUT EFI_STRING *Progress,
4834 OUT EFI_STRING *Results
4835 )
4836{
4838 EFI_STRING StringPtr;
4839 EFI_STRING ConfigRequest;
4840 UINTN Length;
4841 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
4842 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
4843 EFI_STATUS Status;
4844 LIST_ENTRY *Link;
4845 HII_DATABASE_RECORD *Database;
4846 UINT8 *DevicePathPkg;
4847 UINT8 *CurrentDevicePath;
4848 EFI_HANDLE DriverHandle;
4849 EFI_HII_HANDLE HiiHandle;
4850 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
4851 EFI_STRING AccessProgress;
4852 EFI_STRING AccessResults;
4853 EFI_STRING AccessProgressBackup;
4854 EFI_STRING AccessResultsBackup;
4855 EFI_STRING DefaultResults;
4856 BOOLEAN FirstElement;
4857 BOOLEAN IfrDataParsedFlag;
4858 BOOLEAN IsEfiVarStore;
4859 EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
4860 EFI_STRING ErrorPtr;
4861 UINTN DevicePathSize;
4862 UINTN ConigStringSize;
4863 UINTN ConigStringSizeNewsize;
4864 EFI_STRING ConfigStringPtr;
4865
4866 if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {
4867 return EFI_INVALID_PARAMETER;
4868 }
4869
4870 if (Request == NULL) {
4871 *Progress = NULL;
4872 return EFI_INVALID_PARAMETER;
4873 }
4874
4875 Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
4876 StringPtr = Request;
4877 *Progress = StringPtr;
4878 DefaultResults = NULL;
4879 ConfigRequest = NULL;
4880 Status = EFI_SUCCESS;
4881 AccessResults = NULL;
4882 AccessProgress = NULL;
4883 AccessResultsBackup = NULL;
4884 AccessProgressBackup = NULL;
4885 DevicePath = NULL;
4886 IfrDataParsedFlag = FALSE;
4887 IsEfiVarStore = FALSE;
4888 EfiVarStoreInfo = NULL;
4889
4890 //
4891 // The first element of <MultiConfigRequest> should be
4892 // <GuidHdr>, which is in 'GUID='<Guid> syntax.
4893 //
4894 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
4895 return EFI_INVALID_PARAMETER;
4896 }
4897
4898 FirstElement = TRUE;
4899
4900 //
4901 // Allocate a fix length of memory to store Results. Reallocate memory for
4902 // Results if this fix length is insufficient.
4903 //
4904 *Results = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);
4905 if (*Results == NULL) {
4906 return EFI_OUT_OF_RESOURCES;
4907 }
4908
4909 while (*StringPtr != 0 && StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) == 0) {
4910 //
4911 // If parsing error, set Progress to the beginning of the <MultiConfigRequest>
4912 // or most recent & before the error.
4913 //
4914 if (StringPtr == Request) {
4915 *Progress = StringPtr;
4916 } else {
4917 *Progress = StringPtr - 1;
4918 }
4919
4920 //
4921 // Process each <ConfigRequest> of <MultiConfigRequest>
4922 //
4923 Length = CalculateConfigStringLen (StringPtr);
4924 ConfigRequest = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), StringPtr);
4925 if (ConfigRequest == NULL) {
4926 Status = EFI_OUT_OF_RESOURCES;
4927 goto Done;
4928 }
4929
4930 *(ConfigRequest + Length) = 0;
4931
4932 //
4933 // Get the UEFI device path
4934 //
4935 Status = GetDevicePath (ConfigRequest, (UINT8 **)&DevicePath);
4936 if (EFI_ERROR (Status)) {
4937 goto Done;
4938 }
4939
4940 //
4941 // Find driver which matches the routing data.
4942 //
4943 DriverHandle = NULL;
4944 HiiHandle = NULL;
4945 Database = NULL;
4946 for (Link = Private->DatabaseList.ForwardLink;
4947 Link != &Private->DatabaseList;
4948 Link = Link->ForwardLink
4949 )
4950 {
4951 Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
4952 if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
4953 CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
4954 DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);
4955 if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0) && IsThisPackageList (Database, ConfigRequest)) {
4956 DriverHandle = Database->DriverHandle;
4957 HiiHandle = Database->Handle;
4958 break;
4959 }
4960 }
4961 }
4962
4963 //
4964 // Try to find driver handle by device path.
4965 //
4966 if (DriverHandle == NULL) {
4967 TempDevicePath = DevicePath;
4968 Status = gBS->LocateDevicePath (
4969 &gEfiDevicePathProtocolGuid,
4970 &TempDevicePath,
4971 &DriverHandle
4972 );
4973 if (EFI_ERROR (Status) || (DriverHandle == NULL)) {
4974 //
4975 // Routing data does not match any known driver.
4976 // Set Progress to the 'G' in "GUID" of the routing header.
4977 //
4978 *Progress = StringPtr;
4979 Status = EFI_NOT_FOUND;
4980 goto Done;
4981 }
4982 }
4983
4984 //
4985 // Validate ConfigRequest String.
4986 //
4987 ErrorPtr = ConfigRequestValidate (ConfigRequest);
4988 if (ErrorPtr != NULL) {
4989 *Progress = StrStr (StringPtr, ErrorPtr);
4990 Status = EFI_INVALID_PARAMETER;
4991 goto Done;
4992 }
4993
4994 //
4995 // Check whether ConfigRequest contains request string.
4996 //
4997 IfrDataParsedFlag = FALSE;
4998 if ((HiiHandle != NULL) && !GetElementsFromRequest (ConfigRequest)) {
4999 //
5000 // Get the full request string from IFR when HiiPackage is registered to HiiHandle
5001 //
5002 IfrDataParsedFlag = TRUE;
5003 Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, &AccessProgress);
5004 if (EFI_ERROR (Status)) {
5005 //
5006 // AccessProgress indicates the parsing progress on <ConfigRequest>.
5007 // Map it to the progress on <MultiConfigRequest> then return it.
5008 //
5009 ASSERT (AccessProgress != NULL);
5010 *Progress = StrStr (StringPtr, AccessProgress);
5011 goto Done;
5012 }
5013
5014 //
5015 // Not any request block is found.
5016 //
5017 if (!GetElementsFromRequest (ConfigRequest)) {
5018 AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);
5019 goto NextConfigString;
5020 }
5021 }
5022
5023 //
5024 // Check whether this ConfigRequest is search from Efi varstore type storage.
5025 //
5026 Status = GetVarStoreType (Database, ConfigRequest, &IsEfiVarStore, &EfiVarStoreInfo);
5027 if (EFI_ERROR (Status)) {
5028 goto Done;
5029 }
5030
5031 if (IsEfiVarStore) {
5032 //
5033 // Call the GetVariable function to extract settings.
5034 //
5035 Status = GetConfigRespFromEfiVarStore (This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);
5036 FreePool (EfiVarStoreInfo);
5037 if (EFI_ERROR (Status)) {
5038 //
5039 // AccessProgress indicates the parsing progress on <ConfigRequest>.
5040 // Map it to the progress on <MultiConfigRequest> then return it.
5041 //
5042 *Progress = StrStr (StringPtr, AccessProgress);
5043 goto Done;
5044 }
5045
5046 //
5047 // For EfiVarstore, call corresponding ConfigAccess protocol to get the AltCfgResp from driver.
5048 //
5049 Status = gBS->HandleProtocol (
5050 DriverHandle,
5051 &gEfiHiiConfigAccessProtocolGuid,
5052 (VOID **)&ConfigAccess
5053 );
5054 if (EFI_ERROR (Status)) {
5055 //
5056 // The driver has EfiVarStore, may not install ConfigAccess protocol.
5057 // So ignore the error status in this case.
5058 //
5059 Status = EFI_SUCCESS;
5060 } else {
5061 Status = ConfigAccess->ExtractConfig (
5062 ConfigAccess,
5063 ConfigRequest,
5064 &AccessProgressBackup,
5065 &AccessResultsBackup
5066 );
5067 if (!EFI_ERROR (Status)) {
5068 //
5069 // Merge the AltCfgResp in AccessResultsBackup to AccessResults
5070 //
5071 if ((AccessResultsBackup != NULL) && (StrStr (AccessResultsBackup, L"&ALTCFG=") != NULL)) {
5072 ConigStringSize = StrSize (AccessResults);
5073 ConfigStringPtr = StrStr (AccessResultsBackup, L"&GUID=");
5074 ConigStringSizeNewsize = StrSize (ConfigStringPtr) + ConigStringSize + sizeof (CHAR16);
5075 AccessResults = (EFI_STRING)ReallocatePool (
5076 ConigStringSize,
5077 ConigStringSizeNewsize,
5078 AccessResults
5079 );
5080 StrCatS (AccessResults, ConigStringSizeNewsize / sizeof (CHAR16), ConfigStringPtr);
5081 }
5082 } else {
5083 //
5084 // In the ExtractConfig function of some driver may not support EfiVarStore,
5085 // may return error status, just ignore the error status in this case.
5086 //
5087 Status = EFI_SUCCESS;
5088 }
5089
5090 if (AccessResultsBackup != NULL) {
5091 FreePool (AccessResultsBackup);
5092 AccessResultsBackup = NULL;
5093 }
5094 }
5095 } else {
5096 //
5097 // Call corresponding ConfigAccess protocol to extract settings
5098 //
5099 Status = gBS->HandleProtocol (
5100 DriverHandle,
5101 &gEfiHiiConfigAccessProtocolGuid,
5102 (VOID **)&ConfigAccess
5103 );
5104 if (EFI_ERROR (Status)) {
5105 goto Done;
5106 }
5107
5108 Status = ConfigAccess->ExtractConfig (
5109 ConfigAccess,
5110 ConfigRequest,
5111 &AccessProgress,
5112 &AccessResults
5113 );
5114 }
5115
5116 if (EFI_ERROR (Status)) {
5117 //
5118 // AccessProgress indicates the parsing progress on <ConfigRequest>.
5119 // Map it to the progress on <MultiConfigRequest> then return it.
5120 //
5121 *Progress = StrStr (StringPtr, AccessProgress);
5122 goto Done;
5123 }
5124
5125 //
5126 // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'
5127 // which separates the first <ConfigAltResp> and the following ones.
5128 //
5129 ASSERT (*AccessProgress == 0);
5130
5131 //
5132 // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle
5133 //
5134 if (!IfrDataParsedFlag && (HiiHandle != NULL)) {
5135 Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);
5136 ASSERT_EFI_ERROR (Status);
5137 }
5138
5139 FreePool (DevicePath);
5140 DevicePath = NULL;
5141
5142 if (DefaultResults != NULL) {
5143 Status = MergeDefaultString (&AccessResults, DefaultResults);
5144 ASSERT_EFI_ERROR (Status);
5145 FreePool (DefaultResults);
5146 DefaultResults = NULL;
5147 }
5148
5149NextConfigString:
5150 if (!FirstElement) {
5151 Status = AppendToMultiString (Results, L"&");
5152 ASSERT_EFI_ERROR (Status);
5153 }
5154
5155 Status = AppendToMultiString (Results, AccessResults);
5156 ASSERT_EFI_ERROR (Status);
5157
5158 FirstElement = FALSE;
5159
5160 FreePool (AccessResults);
5161 AccessResults = NULL;
5162 FreePool (ConfigRequest);
5163 ConfigRequest = NULL;
5164
5165 //
5166 // Go to next <ConfigRequest> (skip '&').
5167 //
5168 StringPtr += Length;
5169 if (*StringPtr == 0) {
5170 *Progress = StringPtr;
5171 break;
5172 }
5173
5174 StringPtr++;
5175 }
5176
5177Done:
5178 if (EFI_ERROR (Status)) {
5179 FreePool (*Results);
5180 *Results = NULL;
5181 }
5182
5183 if (ConfigRequest != NULL) {
5184 FreePool (ConfigRequest);
5185 }
5186
5187 if (AccessResults != NULL) {
5188 FreePool (AccessResults);
5189 }
5190
5191 if (DefaultResults != NULL) {
5192 FreePool (DefaultResults);
5193 }
5194
5195 if (DevicePath != NULL) {
5196 FreePool (DevicePath);
5197 }
5198
5199 return Status;
5200}
5201
5225EFIAPI
5228 OUT EFI_STRING *Results
5229 )
5230{
5231 EFI_STATUS Status;
5232 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
5233 EFI_STRING AccessResults;
5234 EFI_STRING Progress;
5235 EFI_STRING StringPtr;
5236 EFI_STRING ConfigRequest;
5237 UINTN Index;
5238 EFI_HANDLE *ConfigAccessHandles;
5239 UINTN NumberConfigAccessHandles;
5240 BOOLEAN FirstElement;
5241 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
5242 EFI_HII_HANDLE HiiHandle;
5243 EFI_STRING DefaultResults;
5245 LIST_ENTRY *Link;
5246 HII_DATABASE_RECORD *Database;
5247 UINT8 *DevicePathPkg;
5248 UINT8 *CurrentDevicePath;
5249 BOOLEAN IfrDataParsedFlag;
5250
5251 if ((This == NULL) || (Results == NULL)) {
5252 return EFI_INVALID_PARAMETER;
5253 }
5254
5255 Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
5256
5257 //
5258 // Allocate a fix length of memory to store Results. Reallocate memory for
5259 // Results if this fix length is insufficient.
5260 //
5261 *Results = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);
5262 if (*Results == NULL) {
5263 return EFI_OUT_OF_RESOURCES;
5264 }
5265
5266 NumberConfigAccessHandles = 0;
5267 Status = gBS->LocateHandleBuffer (
5268 ByProtocol,
5269 &gEfiHiiConfigAccessProtocolGuid,
5270 NULL,
5271 &NumberConfigAccessHandles,
5272 &ConfigAccessHandles
5273 );
5274 if (EFI_ERROR (Status)) {
5275 return Status;
5276 }
5277
5278 FirstElement = TRUE;
5279
5280 for (Index = 0; Index < NumberConfigAccessHandles; Index++) {
5281 Status = gBS->HandleProtocol (
5282 ConfigAccessHandles[Index],
5283 &gEfiHiiConfigAccessProtocolGuid,
5284 (VOID **)&ConfigAccess
5285 );
5286 if (EFI_ERROR (Status)) {
5287 continue;
5288 }
5289
5290 //
5291 // Get DevicePath and HiiHandle for this ConfigAccess driver handle
5292 //
5293 IfrDataParsedFlag = FALSE;
5294 Progress = NULL;
5295 HiiHandle = NULL;
5296 DefaultResults = NULL;
5297 Database = NULL;
5298 ConfigRequest = NULL;
5299 DevicePath = DevicePathFromHandle (ConfigAccessHandles[Index]);
5300 if (DevicePath != NULL) {
5301 for (Link = Private->DatabaseList.ForwardLink;
5302 Link != &Private->DatabaseList;
5303 Link = Link->ForwardLink
5304 )
5305 {
5306 Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
5307 if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
5308 CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
5309 if (CompareMem (
5310 DevicePath,
5311 CurrentDevicePath,
5312 GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath)
5313 ) == 0)
5314 {
5315 HiiHandle = Database->Handle;
5316 break;
5317 }
5318 }
5319 }
5320 }
5321
5322 Status = ConfigAccess->ExtractConfig (
5323 ConfigAccess,
5324 NULL,
5325 &Progress,
5326 &AccessResults
5327 );
5328 if (EFI_ERROR (Status)) {
5329 //
5330 // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle
5331 //
5332 if ((HiiHandle != NULL) && (DevicePath != NULL)) {
5333 IfrDataParsedFlag = TRUE;
5334 Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);
5335 //
5336 // Get the full request string to get the Current setting again.
5337 //
5338 if (!EFI_ERROR (Status) && (ConfigRequest != NULL)) {
5339 Status = ConfigAccess->ExtractConfig (
5340 ConfigAccess,
5341 ConfigRequest,
5342 &Progress,
5343 &AccessResults
5344 );
5345 FreePool (ConfigRequest);
5346 } else {
5347 Status = EFI_NOT_FOUND;
5348 }
5349 }
5350 }
5351
5352 if (!EFI_ERROR (Status)) {
5353 //
5354 // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle
5355 //
5356 if (!IfrDataParsedFlag && (HiiHandle != NULL) && (DevicePath != NULL)) {
5357 StringPtr = StrStr (AccessResults, L"&GUID=");
5358 if (StringPtr != NULL) {
5359 *StringPtr = 0;
5360 }
5361
5362 if (GetElementsFromRequest (AccessResults)) {
5363 Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);
5364 ASSERT_EFI_ERROR (Status);
5365 }
5366
5367 if (StringPtr != NULL) {
5368 *StringPtr = L'&';
5369 }
5370 }
5371
5372 //
5373 // Merge the default sting from IFR code into the got setting from driver.
5374 //
5375 if (DefaultResults != NULL) {
5376 Status = MergeDefaultString (&AccessResults, DefaultResults);
5377 ASSERT_EFI_ERROR (Status);
5378 FreePool (DefaultResults);
5379 DefaultResults = NULL;
5380 }
5381
5382 //
5383 // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'
5384 // which separates the first <ConfigAltResp> and the following ones.
5385 //
5386 if (!FirstElement) {
5387 Status = AppendToMultiString (Results, L"&");
5388 ASSERT_EFI_ERROR (Status);
5389 }
5390
5391 Status = AppendToMultiString (Results, AccessResults);
5392 ASSERT_EFI_ERROR (Status);
5393
5394 FirstElement = FALSE;
5395
5396 FreePool (AccessResults);
5397 AccessResults = NULL;
5398 }
5399 }
5400
5401 FreePool (ConfigAccessHandles);
5402
5403 return EFI_SUCCESS;
5404}
5405
5432EFIAPI
5435 IN CONST EFI_STRING Configuration,
5436 OUT EFI_STRING *Progress
5437 )
5438{
5440 EFI_STRING StringPtr;
5441 EFI_STRING ConfigResp;
5442 UINTN Length;
5443 EFI_STATUS Status;
5444 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
5445 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
5446 LIST_ENTRY *Link;
5447 HII_DATABASE_RECORD *Database;
5448 UINT8 *DevicePathPkg;
5449 UINT8 *CurrentDevicePath;
5450 EFI_HANDLE DriverHandle;
5451 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
5452 EFI_STRING AccessProgress;
5453 EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
5454 BOOLEAN IsEfiVarstore;
5455 UINTN DevicePathSize;
5456
5457 if ((This == NULL) || (Progress == NULL)) {
5458 return EFI_INVALID_PARAMETER;
5459 }
5460
5461 if (Configuration == NULL) {
5462 *Progress = NULL;
5463 return EFI_INVALID_PARAMETER;
5464 }
5465
5466 Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
5467 StringPtr = Configuration;
5468 *Progress = StringPtr;
5469 Database = NULL;
5470 AccessProgress = NULL;
5471 EfiVarStoreInfo = NULL;
5472 IsEfiVarstore = FALSE;
5473
5474 //
5475 // The first element of <MultiConfigResp> should be
5476 // <GuidHdr>, which is in 'GUID='<Guid> syntax.
5477 //
5478 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
5479 return EFI_INVALID_PARAMETER;
5480 }
5481
5482 while (*StringPtr != 0 && StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) == 0) {
5483 //
5484 // If parsing error, set Progress to the beginning of the <MultiConfigResp>
5485 // or most recent & before the error.
5486 //
5487 if (StringPtr == Configuration) {
5488 *Progress = StringPtr;
5489 } else {
5490 *Progress = StringPtr - 1;
5491 }
5492
5493 //
5494 // Process each <ConfigResp> of <MultiConfigResp>
5495 //
5496 Length = CalculateConfigStringLen (StringPtr);
5497 ConfigResp = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), StringPtr);
5498 if (ConfigResp == NULL) {
5499 return EFI_OUT_OF_RESOURCES;
5500 }
5501
5502 //
5503 // Append '\0' to the end of ConfigRequest
5504 //
5505 *(ConfigResp + Length) = 0;
5506
5507 //
5508 // Get the UEFI device path
5509 //
5510 Status = GetDevicePath (ConfigResp, (UINT8 **)&DevicePath);
5511 if (EFI_ERROR (Status)) {
5512 FreePool (ConfigResp);
5513 return Status;
5514 }
5515
5516 //
5517 // Find driver which matches the routing data.
5518 //
5519 DriverHandle = NULL;
5520 for (Link = Private->DatabaseList.ForwardLink;
5521 Link != &Private->DatabaseList;
5522 Link = Link->ForwardLink
5523 )
5524 {
5525 Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
5526
5527 if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
5528 CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
5529 DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);
5530 if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0) && IsThisPackageList (Database, ConfigResp)) {
5531 DriverHandle = Database->DriverHandle;
5532 break;
5533 }
5534 }
5535 }
5536
5537 //
5538 // Try to find driver handle by device path.
5539 //
5540 if (DriverHandle == NULL) {
5541 TempDevicePath = DevicePath;
5542 Status = gBS->LocateDevicePath (
5543 &gEfiDevicePathProtocolGuid,
5544 &TempDevicePath,
5545 &DriverHandle
5546 );
5547 if (EFI_ERROR (Status) || (DriverHandle == NULL)) {
5548 //
5549 // Routing data does not match any known driver.
5550 // Set Progress to the 'G' in "GUID" of the routing header.
5551 //
5552 FreePool (DevicePath);
5553 *Progress = StringPtr;
5554 FreePool (ConfigResp);
5555 return EFI_NOT_FOUND;
5556 }
5557 }
5558
5559 FreePool (DevicePath);
5560
5561 //
5562 // Check whether this ConfigRequest is search from Efi varstore type storage.
5563 //
5564 Status = GetVarStoreType (Database, ConfigResp, &IsEfiVarstore, &EfiVarStoreInfo);
5565 if (EFI_ERROR (Status)) {
5566 return Status;
5567 }
5568
5569 if (IsEfiVarstore) {
5570 //
5571 // Call the SetVariable function to route settings.
5572 //
5573 Status = RouteConfigRespForEfiVarStore (This, EfiVarStoreInfo, ConfigResp, &AccessProgress);
5574 FreePool (EfiVarStoreInfo);
5575 } else {
5576 //
5577 // Call corresponding ConfigAccess protocol to route settings
5578 //
5579 Status = gBS->HandleProtocol (
5580 DriverHandle,
5581 &gEfiHiiConfigAccessProtocolGuid,
5582 (VOID **)&ConfigAccess
5583 );
5584 if (EFI_ERROR (Status)) {
5585 *Progress = StringPtr;
5586 FreePool (ConfigResp);
5587 return EFI_NOT_FOUND;
5588 }
5589
5590 Status = ConfigAccess->RouteConfig (
5591 ConfigAccess,
5592 ConfigResp,
5593 &AccessProgress
5594 );
5595 }
5596
5597 if (EFI_ERROR (Status)) {
5598 ASSERT (AccessProgress != NULL);
5599 //
5600 // AccessProgress indicates the parsing progress on <ConfigResp>.
5601 // Map it to the progress on <MultiConfigResp> then return it.
5602 //
5603 *Progress = StrStr (StringPtr, AccessProgress);
5604
5605 FreePool (ConfigResp);
5606 return Status;
5607 }
5608
5609 FreePool (ConfigResp);
5610 ConfigResp = NULL;
5611
5612 //
5613 // Go to next <ConfigResp> (skip '&').
5614 //
5615 StringPtr += Length;
5616 if (*StringPtr == 0) {
5617 *Progress = StringPtr;
5618 break;
5619 }
5620
5621 StringPtr++;
5622 }
5623
5624 return EFI_SUCCESS;
5625}
5626
5663EFIAPI
5666 IN CONST EFI_STRING ConfigRequest,
5667 IN CONST UINT8 *Block,
5668 IN CONST UINTN BlockSize,
5669 OUT EFI_STRING *Config,
5670 OUT EFI_STRING *Progress
5671 )
5672{
5674 EFI_STRING StringPtr;
5675 UINTN Length;
5676 EFI_STATUS Status;
5677 EFI_STRING TmpPtr;
5678 UINT8 *TmpBuffer;
5679 UINTN Offset;
5680 UINTN Width;
5681 UINT8 *Value;
5682 EFI_STRING ValueStr;
5683 EFI_STRING ConfigElement;
5684 UINTN Index;
5685 UINT8 *TemBuffer;
5686 CHAR16 *TemString;
5687
5688 TmpBuffer = NULL;
5689
5690 if ((This == NULL) || (Progress == NULL) || (Config == NULL)) {
5691 return EFI_INVALID_PARAMETER;
5692 }
5693
5694 if ((Block == NULL) || (ConfigRequest == NULL)) {
5695 *Progress = ConfigRequest;
5696 return EFI_INVALID_PARAMETER;
5697 }
5698
5699 Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
5700 ASSERT (Private != NULL);
5701
5702 StringPtr = ConfigRequest;
5703 ValueStr = NULL;
5704 Value = NULL;
5705 ConfigElement = NULL;
5706
5707 //
5708 // Allocate a fix length of memory to store Results. Reallocate memory for
5709 // Results if this fix length is insufficient.
5710 //
5711 *Config = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);
5712 if (*Config == NULL) {
5713 return EFI_OUT_OF_RESOURCES;
5714 }
5715
5716 //
5717 // Jump <ConfigHdr>
5718 //
5719 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
5720 *Progress = StringPtr;
5721 Status = EFI_INVALID_PARAMETER;
5722 goto Exit;
5723 }
5724
5725 while (*StringPtr != 0 && StrnCmp (StringPtr, L"PATH=", StrLen (L"PATH=")) != 0) {
5726 StringPtr++;
5727 }
5728
5729 if (*StringPtr == 0) {
5730 *Progress = StringPtr - 1;
5731 Status = EFI_INVALID_PARAMETER;
5732 goto Exit;
5733 }
5734
5735 while (*StringPtr != L'&' && *StringPtr != 0) {
5736 StringPtr++;
5737 }
5738
5739 if (*StringPtr == 0) {
5740 *Progress = StringPtr;
5741
5742 AppendToMultiString (Config, ConfigRequest);
5743 HiiToLower (*Config);
5744
5745 return EFI_SUCCESS;
5746 }
5747
5748 //
5749 // Skip '&'
5750 //
5751 StringPtr++;
5752
5753 //
5754 // Copy <ConfigHdr> and an additional '&' to <ConfigResp>
5755 //
5756 TemString = AllocateCopyPool (sizeof (CHAR16) * (StringPtr - ConfigRequest + 1), ConfigRequest);
5757 if (TemString == NULL) {
5758 return EFI_OUT_OF_RESOURCES;
5759 }
5760
5761 TemString[StringPtr - ConfigRequest] = '\0';
5762 AppendToMultiString (Config, TemString);
5763 FreePool (TemString);
5764
5765 //
5766 // Parse each <RequestElement> if exists
5767 // Only <BlockName> format is supported by this help function.
5768 // <BlockName> ::= 'OFFSET='<Number>&'WIDTH='<Number>
5769 //
5770 while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
5771 //
5772 // Back up the header of one <BlockName>
5773 //
5774 TmpPtr = StringPtr;
5775
5776 StringPtr += StrLen (L"OFFSET=");
5777 //
5778 // Get Offset
5779 //
5780 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
5781 if (EFI_ERROR (Status)) {
5782 *Progress = TmpPtr - 1;
5783 goto Exit;
5784 }
5785
5786 Offset = 0;
5787 CopyMem (
5788 &Offset,
5789 TmpBuffer,
5790 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
5791 );
5792 FreePool (TmpBuffer);
5793
5794 StringPtr += Length;
5795 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
5796 *Progress = TmpPtr - 1;
5797 Status = EFI_INVALID_PARAMETER;
5798 goto Exit;
5799 }
5800
5801 StringPtr += StrLen (L"&WIDTH=");
5802
5803 //
5804 // Get Width
5805 //
5806 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
5807 if (EFI_ERROR (Status)) {
5808 *Progress = TmpPtr - 1;
5809 goto Exit;
5810 }
5811
5812 Width = 0;
5813 CopyMem (
5814 &Width,
5815 TmpBuffer,
5816 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
5817 );
5818 FreePool (TmpBuffer);
5819
5820 StringPtr += Length;
5821 if ((*StringPtr != 0) && (*StringPtr != L'&')) {
5822 *Progress = TmpPtr - 1;
5823 Status = EFI_INVALID_PARAMETER;
5824 goto Exit;
5825 }
5826
5827 //
5828 // Calculate Value and convert it to hex string.
5829 //
5830 if (Offset + Width > BlockSize) {
5831 *Progress = StringPtr;
5832 Status = EFI_DEVICE_ERROR;
5833 goto Exit;
5834 }
5835
5836 Value = (UINT8 *)AllocateZeroPool (Width);
5837 if (Value == NULL) {
5838 *Progress = ConfigRequest;
5839 Status = EFI_OUT_OF_RESOURCES;
5840 goto Exit;
5841 }
5842
5843 CopyMem (Value, (UINT8 *)Block + Offset, Width);
5844
5845 Length = Width * 2 + 1;
5846 ValueStr = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));
5847 if (ValueStr == NULL) {
5848 *Progress = ConfigRequest;
5849 Status = EFI_OUT_OF_RESOURCES;
5850 goto Exit;
5851 }
5852
5853 TemString = ValueStr;
5854 TemBuffer = Value + Width - 1;
5855 for (Index = 0; Index < Width; Index++, TemBuffer--) {
5857 TemString,
5858 Length * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),
5859 PREFIX_ZERO | RADIX_HEX,
5860 *TemBuffer,
5861 2
5862 );
5863 TemString += StrnLenS (TemString, Length - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));
5864 }
5865
5866 FreePool (Value);
5867 Value = NULL;
5868
5869 //
5870 // Build a ConfigElement
5871 //
5872 Length += StringPtr - TmpPtr + 1 + StrLen (L"VALUE=");
5873 ConfigElement = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));
5874 if (ConfigElement == NULL) {
5875 Status = EFI_OUT_OF_RESOURCES;
5876 goto Exit;
5877 }
5878
5879 CopyMem (ConfigElement, TmpPtr, (StringPtr - TmpPtr + 1) * sizeof (CHAR16));
5880 if (*StringPtr == 0) {
5881 *(ConfigElement + (StringPtr - TmpPtr)) = L'&';
5882 }
5883
5884 *(ConfigElement + (StringPtr - TmpPtr) + 1) = 0;
5885 StrCatS (ConfigElement, Length, L"VALUE=");
5886 StrCatS (ConfigElement, Length, ValueStr);
5887
5888 AppendToMultiString (Config, ConfigElement);
5889
5890 FreePool (ConfigElement);
5891 FreePool (ValueStr);
5892 ConfigElement = NULL;
5893 ValueStr = NULL;
5894
5895 //
5896 // If '\0', parsing is finished. Otherwise skip '&' to continue
5897 //
5898 if (*StringPtr == 0) {
5899 break;
5900 }
5901
5902 AppendToMultiString (Config, L"&");
5903 StringPtr++;
5904 }
5905
5906 if (*StringPtr != 0) {
5907 *Progress = StringPtr - 1;
5908 Status = EFI_INVALID_PARAMETER;
5909 goto Exit;
5910 }
5911
5912 HiiToLower (*Config);
5913 *Progress = StringPtr;
5914 return EFI_SUCCESS;
5915
5916Exit:
5917 if (*Config != NULL) {
5918 FreePool (*Config);
5919 *Config = NULL;
5920 }
5921
5922 if (ValueStr != NULL) {
5923 FreePool (ValueStr);
5924 }
5925
5926 if (Value != NULL) {
5927 FreePool (Value);
5928 }
5929
5930 if (ConfigElement != NULL) {
5931 FreePool (ConfigElement);
5932 }
5933
5934 return Status;
5935}
5936
5985EFIAPI
5988 IN CONST EFI_STRING ConfigResp,
5989 IN OUT UINT8 *Block,
5990 IN OUT UINTN *BlockSize,
5991 OUT EFI_STRING *Progress
5992 )
5993{
5995 EFI_STRING StringPtr;
5996 EFI_STRING TmpPtr;
5997 UINTN Length;
5998 EFI_STATUS Status;
5999 UINT8 *TmpBuffer;
6000 UINTN Offset;
6001 UINTN Width;
6002 UINT8 *Value;
6003 UINTN BufferSize;
6004 UINTN MaxBlockSize;
6005
6006 TmpBuffer = NULL;
6007
6008 if ((This == NULL) || (BlockSize == NULL) || (Progress == NULL)) {
6009 return EFI_INVALID_PARAMETER;
6010 }
6011
6012 *Progress = ConfigResp;
6013 if (ConfigResp == NULL) {
6014 return EFI_INVALID_PARAMETER;
6015 }
6016
6017 Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
6018 ASSERT (Private != NULL);
6019
6020 StringPtr = ConfigResp;
6021 BufferSize = *BlockSize;
6022 Value = NULL;
6023 MaxBlockSize = 0;
6024
6025 //
6026 // Jump <ConfigHdr>
6027 //
6028 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
6029 *Progress = StringPtr;
6030 Status = EFI_INVALID_PARAMETER;
6031 goto Exit;
6032 }
6033
6034 while (*StringPtr != 0 && StrnCmp (StringPtr, L"PATH=", StrLen (L"PATH=")) != 0) {
6035 StringPtr++;
6036 }
6037
6038 if (*StringPtr == 0) {
6039 *Progress = StringPtr;
6040 Status = EFI_INVALID_PARAMETER;
6041 goto Exit;
6042 }
6043
6044 while (*StringPtr != L'&' && *StringPtr != 0) {
6045 StringPtr++;
6046 }
6047
6048 if (*StringPtr == 0) {
6049 *Progress = StringPtr;
6050 Status = EFI_INVALID_PARAMETER;
6051 goto Exit;
6052 }
6053
6054 //
6055 // Parse each <ConfigElement> if exists
6056 // Only '&'<BlockConfig> format is supported by this help function.
6057 // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE='<Number>
6058 //
6059 while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {
6060 TmpPtr = StringPtr;
6061 StringPtr += StrLen (L"&OFFSET=");
6062 //
6063 // Get Offset
6064 //
6065 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
6066 if (EFI_ERROR (Status)) {
6067 *Progress = TmpPtr;
6068 goto Exit;
6069 }
6070
6071 Offset = 0;
6072 CopyMem (
6073 &Offset,
6074 TmpBuffer,
6075 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
6076 );
6077 FreePool (TmpBuffer);
6078
6079 StringPtr += Length;
6080 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
6081 *Progress = TmpPtr;
6082 Status = EFI_INVALID_PARAMETER;
6083 goto Exit;
6084 }
6085
6086 StringPtr += StrLen (L"&WIDTH=");
6087
6088 //
6089 // Get Width
6090 //
6091 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
6092 if (EFI_ERROR (Status)) {
6093 *Progress = TmpPtr;
6094 goto Exit;
6095 }
6096
6097 Width = 0;
6098 CopyMem (
6099 &Width,
6100 TmpBuffer,
6101 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
6102 );
6103 FreePool (TmpBuffer);
6104
6105 StringPtr += Length;
6106 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
6107 *Progress = TmpPtr;
6108 Status = EFI_INVALID_PARAMETER;
6109 goto Exit;
6110 }
6111
6112 StringPtr += StrLen (L"&VALUE=");
6113
6114 //
6115 // Get Value
6116 //
6117 Status = GetValueOfNumber (StringPtr, &Value, &Length);
6118 if (EFI_ERROR (Status)) {
6119 *Progress = TmpPtr;
6120 goto Exit;
6121 }
6122
6123 StringPtr += Length;
6124 if ((*StringPtr != 0) && (*StringPtr != L'&')) {
6125 *Progress = TmpPtr;
6126 Status = EFI_INVALID_PARAMETER;
6127 goto Exit;
6128 }
6129
6130 //
6131 // Update the Block with configuration info
6132 //
6133 if ((Block != NULL) && (Offset + Width <= BufferSize)) {
6134 CopyMem (Block + Offset, Value, Width);
6135 }
6136
6137 if (Offset + Width > MaxBlockSize) {
6138 MaxBlockSize = Offset + Width;
6139 }
6140
6141 FreePool (Value);
6142 Value = NULL;
6143
6144 //
6145 // If '\0', parsing is finished.
6146 //
6147 if (*StringPtr == 0) {
6148 break;
6149 }
6150 }
6151
6152 //
6153 // The input string is not ConfigResp format, return error.
6154 //
6155 if (*StringPtr != 0) {
6156 *Progress = StringPtr;
6157 Status = EFI_INVALID_PARAMETER;
6158 goto Exit;
6159 }
6160
6161 *Progress = StringPtr + StrLen (StringPtr);
6162 *BlockSize = MaxBlockSize - 1;
6163
6164 if (MaxBlockSize > BufferSize) {
6165 *BlockSize = MaxBlockSize;
6166 if (Block != NULL) {
6167 return EFI_BUFFER_TOO_SMALL;
6168 }
6169 }
6170
6171 if (Block == NULL) {
6172 *Progress = ConfigResp;
6173 return EFI_INVALID_PARAMETER;
6174 }
6175
6176 return EFI_SUCCESS;
6177
6178Exit:
6179
6180 if (Value != NULL) {
6181 FreePool (Value);
6182 }
6183
6184 return Status;
6185}
6186
6228EFIAPI
6231 IN CONST EFI_STRING Configuration,
6232 IN CONST EFI_GUID *Guid,
6233 IN CONST EFI_STRING Name,
6234 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
6235 IN CONST UINT16 *AltCfgId,
6236 OUT EFI_STRING *AltCfgResp
6237 )
6238{
6239 EFI_STATUS Status;
6240 EFI_STRING StringPtr;
6241 EFI_STRING HdrStart;
6242 EFI_STRING HdrEnd;
6243 EFI_STRING TmpPtr;
6244 UINTN Length;
6245 EFI_STRING GuidStr;
6246 EFI_STRING NameStr;
6247 EFI_STRING PathStr;
6248 EFI_STRING AltIdStr;
6249 EFI_STRING Result;
6250 BOOLEAN GuidFlag;
6251 BOOLEAN NameFlag;
6252 BOOLEAN PathFlag;
6253
6254 HdrStart = NULL;
6255 HdrEnd = NULL;
6256 GuidStr = NULL;
6257 NameStr = NULL;
6258 PathStr = NULL;
6259 AltIdStr = NULL;
6260 Result = NULL;
6261 GuidFlag = FALSE;
6262 NameFlag = FALSE;
6263 PathFlag = FALSE;
6264
6265 if ((This == NULL) || (Configuration == NULL) || (AltCfgResp == NULL)) {
6266 return EFI_INVALID_PARAMETER;
6267 }
6268
6269 StringPtr = Configuration;
6270 if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
6271 return EFI_INVALID_PARAMETER;
6272 }
6273
6274 //
6275 // Generate the sub string for later matching.
6276 //
6277 GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)Guid, 1, &GuidStr);
6279 L"PATH=",
6281 (VOID *)DevicePath,
6282 1,
6283 &PathStr
6284 );
6285 if (AltCfgId != NULL) {
6286 GenerateSubStr (L"ALTCFG=", sizeof (UINT16), (VOID *)AltCfgId, 3, &AltIdStr);
6287 }
6288
6289 if (Name != NULL) {
6290 GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *)Name, 2, &NameStr);
6291 } else {
6292 GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);
6293 }
6294
6295 while (*StringPtr != 0) {
6296 //
6297 // Try to match the GUID
6298 //
6299 if (!GuidFlag) {
6300 TmpPtr = StrStr (StringPtr, GuidStr);
6301 if (TmpPtr == NULL) {
6302 Status = EFI_NOT_FOUND;
6303 goto Exit;
6304 }
6305
6306 HdrStart = TmpPtr;
6307
6308 //
6309 // Jump to <NameHdr>
6310 //
6311 if (Guid != NULL) {
6312 StringPtr = TmpPtr + StrLen (GuidStr);
6313 } else {
6314 StringPtr = StrStr (TmpPtr, L"NAME=");
6315 if (StringPtr == NULL) {
6316 Status = EFI_NOT_FOUND;
6317 goto Exit;
6318 }
6319 }
6320
6321 GuidFlag = TRUE;
6322 }
6323
6324 //
6325 // Try to match the NAME
6326 //
6327 if (GuidFlag && !NameFlag) {
6328 if (StrnCmp (StringPtr, NameStr, StrLen (NameStr)) != 0) {
6329 GuidFlag = FALSE;
6330 } else {
6331 //
6332 // Jump to <PathHdr>
6333 //
6334 if (Name != NULL) {
6335 StringPtr += StrLen (NameStr);
6336 } else {
6337 StringPtr = StrStr (StringPtr, L"PATH=");
6338 if (StringPtr == NULL) {
6339 Status = EFI_NOT_FOUND;
6340 goto Exit;
6341 }
6342 }
6343
6344 NameFlag = TRUE;
6345 }
6346 }
6347
6348 //
6349 // Try to match the DevicePath
6350 //
6351 if (GuidFlag && NameFlag && !PathFlag) {
6352 if (StrnCmp (StringPtr, PathStr, StrLen (PathStr)) != 0) {
6353 GuidFlag = FALSE;
6354 NameFlag = FALSE;
6355 } else {
6356 //
6357 // Jump to '&' before <DescHdr> or <ConfigBody>
6358 //
6359 if (DevicePath != NULL) {
6360 StringPtr += StrLen (PathStr);
6361 } else {
6362 StringPtr = StrStr (StringPtr, L"&");
6363 if (StringPtr == NULL) {
6364 Status = EFI_NOT_FOUND;
6365 goto Exit;
6366 }
6367
6368 StringPtr++;
6369 }
6370
6371 PathFlag = TRUE;
6372 HdrEnd = StringPtr;
6373 }
6374 }
6375
6376 //
6377 // Try to match the AltCfgId
6378 //
6379 if (GuidFlag && NameFlag && PathFlag) {
6380 if (AltCfgId == NULL) {
6381 //
6382 // Return Current Setting when AltCfgId is NULL.
6383 //
6384 Status = OutputConfigBody (StringPtr, &Result);
6385 goto Exit;
6386 }
6387
6388 //
6389 // Search the <ConfigAltResp> to get the <AltResp> with AltCfgId.
6390 //
6391 if (StrnCmp (StringPtr, AltIdStr, StrLen (AltIdStr)) != 0) {
6392 GuidFlag = FALSE;
6393 NameFlag = FALSE;
6394 PathFlag = FALSE;
6395 } else {
6396 //
6397 // Skip AltIdStr and &
6398 //
6399 StringPtr = StringPtr + StrLen (AltIdStr);
6400 Status = OutputConfigBody (StringPtr, &Result);
6401 goto Exit;
6402 }
6403 }
6404 }
6405
6406 Status = EFI_NOT_FOUND;
6407
6408Exit:
6409 *AltCfgResp = NULL;
6410 if (!EFI_ERROR (Status) && (Result != NULL)) {
6411 //
6412 // Copy the <ConfigHdr> and <ConfigBody>
6413 //
6414 Length = HdrEnd - HdrStart + StrLen (Result) + 1;
6415 *AltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));
6416 if (*AltCfgResp == NULL) {
6417 Status = EFI_OUT_OF_RESOURCES;
6418 } else {
6419 StrnCpyS (*AltCfgResp, Length, HdrStart, HdrEnd - HdrStart);
6420 StrCatS (*AltCfgResp, Length, Result);
6421 Status = EFI_SUCCESS;
6422 }
6423 }
6424
6425 if (GuidStr != NULL) {
6426 FreePool (GuidStr);
6427 }
6428
6429 if (NameStr != NULL) {
6430 FreePool (NameStr);
6431 }
6432
6433 if (PathStr != NULL) {
6434 FreePool (PathStr);
6435 }
6436
6437 if (AltIdStr != NULL) {
6438 FreePool (AltIdStr);
6439 }
6440
6441 if (Result != NULL) {
6442 FreePool (Result);
6443 }
6444
6445 return Status;
6446}
UINT64 UINTN
UINT64 EFIAPI StrHexToUint64(IN CONST CHAR16 *String)
Definition: String.c:560
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
UINT32 EFIAPI BitFieldWrite32(IN UINT32 Operand, IN UINTN StartBit, IN UINTN EndBit, IN UINT32 Value)
Definition: BitField.c:563
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
INTN EFIAPI StrnCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString, IN UINTN Length)
Definition: String.c:162
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
RETURN_STATUS EFIAPI StrnCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:507
UINT64 EFIAPI BitFieldRead64(IN UINT64 Operand, IN UINTN StartBit, IN UINTN EndBit)
Definition: BitField.c:719
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2873
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
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
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS RouteConfigRespForEfiVarStore(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo, IN EFI_STRING RequestResp, OUT EFI_STRING *Result)
VOID UpdateDefaultValue(IN LIST_ENTRY *BlockLink)
EFI_STRING InternalGetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId)
CHAR8 * GetSupportedLanguages(IN EFI_HII_HANDLE HiiHandle)
IFR_BLOCK_DATA * GetNameElement(IN EFI_STRING ConfigRequest, OUT EFI_STRING *Progress)
EFI_STATUS EFIAPI HiiConfigRoutingExportConfig(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, OUT EFI_STRING *Results)
EFI_STATUS CompareBlockElementDefault(IN EFI_STRING DefaultAltCfgResp, IN OUT EFI_STRING *ConfigAltResp, IN EFI_STRING AltConfigHdr, IN OUT BOOLEAN *ConfigAltRespChanged)
EFI_STATUS FindSameBlockElement(IN EFI_STRING String, IN EFI_STRING BlockName, IN UINT8 *Buffer, OUT BOOLEAN *Found, IN UINTN BufferLen)
BOOLEAN GenerateConfigRequest(IN CHAR16 *ConfigHdr, IN IFR_VARSTORAGE_DATA *VarStorageData, OUT EFI_STATUS *Status, IN OUT EFI_STRING *ConfigRequest)
IFR_BLOCK_DATA * GetBlockElement(IN EFI_STRING ConfigRequest, OUT EFI_STRING *Progress)
EFI_STATUS AppendToMultiString(IN OUT EFI_STRING *MultiString, IN EFI_STRING AppendString)
BOOLEAN IsThisVarstore(IN EFI_GUID *VarstoreGuid, IN CHAR16 *Name, IN CHAR16 *ConfigHdr)
EFI_STATUS EFIAPI HiiGetAltCfg(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING Configuration, IN CONST EFI_GUID *Guid, IN CONST EFI_STRING Name, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST UINT16 *AltCfgId, OUT EFI_STRING *AltCfgResp)
EFI_STATUS CompareNameElementDefault(IN EFI_STRING DefaultAltCfgResp, IN OUT EFI_STRING *ConfigAltResp, IN EFI_STRING AltConfigHdr, IN OUT BOOLEAN *ConfigAltRespChanged)
CHAR16 * OffsetWidthValidate(CHAR16 *ConfigElements)
EFI_STATUS IsThisOpcodeRequired(IN IFR_BLOCK_DATA *RequestBlockArray, IN EFI_HII_HANDLE HiiHandle, IN OUT IFR_VARSTORAGE_DATA *VarStorageData, IN EFI_IFR_OP_HEADER *IfrOpHdr, IN UINT16 VarWidth, OUT IFR_BLOCK_DATA **ReturnData, IN BOOLEAN IsBitVar)
EFI_STATUS EFIAPI ParseIfrData(IN EFI_HII_HANDLE HiiHandle, IN UINT8 *Package, IN UINT32 PackageLength, IN EFI_STRING ConfigHdr, IN IFR_BLOCK_DATA *RequestBlockArray, IN OUT IFR_VARSTORAGE_DATA *VarStorageData, OUT IFR_DEFAULT_DATA *DefaultIdArray)
BOOLEAN IsThisPackageList(IN HII_DATABASE_RECORD *DataBaseRecord, IN EFI_STRING ConfigHdr)
VOID GenerateSubStr(IN CONST EFI_STRING String, IN UINTN BufferLen, IN VOID *Buffer, IN UINT8 Flag, OUT EFI_STRING *SubStr)
EFI_STATUS EFIAPI HiiConfigRoutingRouteConfig(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING Configuration, OUT EFI_STRING *Progress)
EFI_STATUS GetVarStoreType(IN HII_DATABASE_RECORD *DataBaseRecord, IN EFI_STRING ConfigHdr, OUT BOOLEAN *IsEfiVarstore, OUT EFI_IFR_VARSTORE_EFI **EfiVarStore)
VOID InsertBlockData(IN LIST_ENTRY *BlockLink, IN IFR_BLOCK_DATA **BlockData)
CHAR16 * NameValueValidate(CHAR16 *ConfigElements)
VOID UpdateBlockDataArray(IN LIST_ENTRY *BlockLink)
VOID EFIAPI HiiToLower(IN EFI_STRING ConfigString)
EFI_STATUS GenerateHdr(IN IFR_VARSTORAGE_DATA *VarStorageData, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT EFI_STRING *ConfigHdr)
EFI_STATUS EFIAPI HiiConfigRoutingExtractConfig(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING Request, OUT EFI_STRING *Progress, OUT EFI_STRING *Results)
EFI_STATUS GetConfigRespFromEfiVarStore(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo, IN EFI_STRING Request, OUT EFI_STRING *RequestResp, OUT EFI_STRING *AccessProgress)
EFI_STATUS EFIAPI GetFullStringFromHiiFormPackages(IN HII_DATABASE_RECORD *DataBaseRecord, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN OUT EFI_STRING *Request, IN OUT EFI_STRING *AltCfgResp, OUT EFI_STRING *PointerProgress OPTIONAL)
EFI_STATUS EFIAPI HiiBlockToConfig(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING ConfigRequest, IN CONST UINT8 *Block, IN CONST UINTN BlockSize, OUT EFI_STRING *Config, OUT EFI_STRING *Progress)
EFI_STATUS OutputConfigBody(IN EFI_STRING String, OUT EFI_STRING *ConfigBody)
EFI_STATUS CompareAndMergeDefaultString(IN OUT EFI_STRING *AltCfgResp, IN EFI_STRING DefaultAltCfgResp, IN EFI_STRING AltConfigHdr)
EFI_STATUS GetDevicePath(IN EFI_STRING String, OUT UINT8 **DevicePathData)
Definition: ConfigRouting.c:66
EFI_STATUS GetValueOfNumber(IN EFI_STRING StringPtr, OUT UINT8 **Number, OUT UINTN *Len)
BOOLEAN BlockArrayCheck(IN IFR_BLOCK_DATA *RequestBlockArray, IN UINT16 VarOffset, IN UINT16 VarWidth, IN BOOLEAN IsNameValueType, IN EFI_HII_HANDLE HiiHandle)
EFI_STATUS GenerateAltConfigResp(IN EFI_HII_HANDLE HiiHandle, IN CHAR16 *ConfigHdr, IN IFR_VARSTORAGE_DATA *VarStorageData, IN IFR_DEFAULT_DATA *DefaultIdArray, IN OUT EFI_STRING *DefaultAltCfgResp)
BOOLEAN GetElementsFromRequest(IN EFI_STRING ConfigRequest)
EFI_STATUS GetFormPackageData(IN HII_DATABASE_RECORD *DataBaseRecord, IN OUT UINT8 **HiiFormPackage, OUT UINTN *PackageSize)
CHAR16 * ConfigRequestValidate(CHAR16 *ConfigRequest)
VOID InsertDefaultValue(IN IFR_BLOCK_DATA *BlockData, IN IFR_DEFAULT_DATA *DefaultValueData)
UINTN CalculateConfigStringLen(IN EFI_STRING String)
Definition: ConfigRouting.c:25
EFI_STATUS EFIAPI HiiConfigToBlock(IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN CONST EFI_STRING ConfigResp, IN OUT UINT8 *Block, IN OUT UINTN *BlockSize, OUT EFI_STRING *Progress)
EFI_STATUS EFIAPI MergeDefaultString(IN OUT EFI_STRING *AltCfgResp, IN EFI_STRING DefaultAltCfgResp)
VOID MergeBlockDefaultValue(IN OUT IFR_BLOCK_DATA *FirstBlock, IN OUT IFR_BLOCK_DATA *SecondBlock)
EFI_STATUS ExportFormPackages(IN HII_DATABASE_PRIVATE_DATA *Private, IN EFI_HII_HANDLE Handle, IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, IN UINTN UsedSize, IN UINTN BufferSize, IN OUT VOID *Buffer, IN OUT UINTN *ResultSize)
Definition: Database.c:1279
EFI_STATUS FindQuestionDefaultSetting(IN UINT16 DefaultId, IN EFI_IFR_VARSTORE_EFI *EfiVarStore, IN EFI_IFR_QUESTION_HEADER *IfrQuestionHdr, OUT VOID *ValueBuffer, IN UINTN Width, IN BOOLEAN BitFieldQuestion)
Definition: Database.c:659
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
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 CONST
Definition: Base.h:259
#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 BASE_CR(Record, TYPE, Field)
Definition: Base.h:891
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
#define PcdGetSize(TokenName)
Definition: PcdLib.h:440
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
VOID * EFI_HII_HANDLE
EFI_STATUS EFIAPI GetEfiGlobalVariable2(IN CONST CHAR16 *Name, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1470
CHAR8 *EFIAPI GetBestLanguage(IN CONST CHAR8 *SupportedLanguages, IN UINTN Iso639Language,...)
Definition: UefiLib.c:1522
@ ByProtocol
Definition: UefiSpec.h:1518
Definition: Base.h:213
EFI_STRING_ID string
EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION.