TianoCore EDK2 master
Loading...
Searching...
No Matches
BmBoot.c
Go to the documentation of this file.
1
11#include "InternalBm.h"
12
13EFI_RAM_DISK_PROTOCOL *mRamDisk = NULL;
14
15EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION mBmRefreshLegacyBootOption = NULL;
17
23 0xfab7e9e1, 0x39dd, 0x4f2b, { 0x84, 0x08, 0xe2, 0x0e, 0x90, 0x6c, 0xb6, 0xde }
24};
25EFI_GUID mBmAutoCreateBootOptionGuid = {
26 0x8108ac4e, 0x9f11, 0x4d59, { 0x85, 0x0e, 0xe2, 0x1a, 0x52, 0x2c, 0x59, 0xb2 }
27};
28
37VOID
38EFIAPI
40 IN EFI_EVENT Event,
41 IN VOID *Context
42 )
43{
44 //
45 // Record the performance data for End of BDS
46 //
48
49 return;
50}
51
58VOID
59EFIAPI
61 EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION RefreshLegacyBootOption,
63 )
64{
65 mBmRefreshLegacyBootOption = RefreshLegacyBootOption;
66 mBmLegacyBoot = LegacyBoot;
67}
68
77BOOLEAN
80 )
81{
82 if ((BootOption->OptionalDataSize == sizeof (EFI_GUID)) &&
83 CompareGuid ((EFI_GUID *)BootOption->OptionalData, &mBmAutoCreateBootOptionGuid)
84 )
85 {
86 return TRUE;
87 } else {
88 return FALSE;
89 }
90}
91
100UINTN
102 IN EFI_BOOT_MANAGER_LOAD_OPTION *OptionToFind
103 )
104{
105 EFI_STATUS Status;
107 UINTN OptionNumber;
108 CHAR16 OptionName[BM_OPTION_NAME_LEN];
109 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
110 UINTN BootOptionCount;
111 UINTN Index;
112
113 OptionNumber = LoadOptionNumberUnassigned;
114
115 //
116 // Try to match the variable exactly if the option number is assigned
117 //
118 if (OptionToFind->OptionNumber != LoadOptionNumberUnassigned) {
120 OptionName,
121 sizeof (OptionName),
122 L"%s%04x",
123 mBmLoadOptionName[OptionToFind->OptionType],
124 OptionToFind->OptionNumber
125 );
126 Status = EfiBootManagerVariableToLoadOption (OptionName, &BootOption);
127
128 if (!EFI_ERROR (Status)) {
129 ASSERT (OptionToFind->OptionNumber == BootOption.OptionNumber);
130 if ((OptionToFind->Attributes == BootOption.Attributes) &&
131 (StrCmp (OptionToFind->Description, BootOption.Description) == 0) &&
132 (CompareMem (OptionToFind->FilePath, BootOption.FilePath, GetDevicePathSize (OptionToFind->FilePath)) == 0) &&
133 (OptionToFind->OptionalDataSize == BootOption.OptionalDataSize) &&
134 (CompareMem (OptionToFind->OptionalData, BootOption.OptionalData, OptionToFind->OptionalDataSize) == 0)
135 )
136 {
137 OptionNumber = OptionToFind->OptionNumber;
138 }
139
140 EfiBootManagerFreeLoadOption (&BootOption);
141 }
142 }
143
144 //
145 // The option number assigned is either incorrect or unassigned.
146 //
147 if (OptionNumber == LoadOptionNumberUnassigned) {
148 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
149
150 // Only assert if the BootOption is non-zero
151 if ((BootOptions == NULL) && (BootOptionCount > 0)) {
152 ASSERT (BootOptions != NULL);
153 return LoadOptionNumberUnassigned;
154 }
155
156 Index = EfiBootManagerFindLoadOption (OptionToFind, BootOptions, BootOptionCount);
157 if (Index != -1) {
158 OptionNumber = BootOptions[Index].OptionNumber;
159 }
160
161 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
162 }
163
164 return OptionNumber;
165}
166
178 )
179{
180 EFI_STATUS Status;
181 UINTN Index;
182 EFI_DEVICE_PATH_PROTOCOL *FvFileNode;
183 EFI_HANDLE FvHandle;
184 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
185 UINTN FvHandleCount;
186 EFI_HANDLE *FvHandles;
187 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
188 EFI_DEVICE_PATH_PROTOCOL *FullPath;
189
190 //
191 // Get the file buffer by using the exactly FilePath.
192 //
193 FvFileNode = FilePath;
194 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &FvFileNode, &FvHandle);
195 if (!EFI_ERROR (Status)) {
196 return DuplicateDevicePath (FilePath);
197 }
198
199 //
200 // Only wide match other FVs if it's a memory mapped FV file path.
201 //
202 if ((DevicePathType (FilePath) != HARDWARE_DEVICE_PATH) || (DevicePathSubType (FilePath) != HW_MEMMAP_DP)) {
203 return NULL;
204 }
205
206 FvFileNode = NextDevicePathNode (FilePath);
207
208 //
209 // Firstly find the FV file in current FV
210 //
211 gBS->HandleProtocol (
213 &gEfiLoadedImageProtocolGuid,
214 (VOID **)&LoadedImage
215 );
216 NewDevicePath = AppendDevicePathNode (DevicePathFromHandle (LoadedImage->DeviceHandle), FvFileNode);
217 FullPath = BmAdjustFvFilePath (NewDevicePath);
218 FreePool (NewDevicePath);
219 if (FullPath != NULL) {
220 return FullPath;
221 }
222
223 //
224 // Secondly find the FV file in all other FVs
225 //
226 gBS->LocateHandleBuffer (
228 &gEfiFirmwareVolume2ProtocolGuid,
229 NULL,
230 &FvHandleCount,
231 &FvHandles
232 );
233 for (Index = 0; Index < FvHandleCount; Index++) {
234 if (FvHandles[Index] == LoadedImage->DeviceHandle) {
235 //
236 // Skip current FV, it was handed in first step.
237 //
238 continue;
239 }
240
241 NewDevicePath = AppendDevicePathNode (DevicePathFromHandle (FvHandles[Index]), FvFileNode);
242 FullPath = BmAdjustFvFilePath (NewDevicePath);
243 FreePool (NewDevicePath);
244 if (FullPath != NULL) {
245 break;
246 }
247 }
248
249 if (FvHandles != NULL) {
250 FreePool (FvHandles);
251 }
252
253 return FullPath;
254}
255
266BOOLEAN
268 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
269 )
270{
271 EFI_STATUS Status;
272 EFI_HANDLE Handle;
274
275 Node = DevicePath;
276 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &Node, &Handle);
277 if (!EFI_ERROR (Status)) {
278 return TRUE;
279 }
280
281 if ((DevicePathType (DevicePath) == HARDWARE_DEVICE_PATH) && (DevicePathSubType (DevicePath) == HW_MEMMAP_DP)) {
282 DevicePath = NextDevicePathNode (DevicePath);
283 if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MEDIA_PIWG_FW_FILE_DP)) {
284 return IsDevicePathEnd (NextDevicePathNode (DevicePath));
285 }
286 }
287
288 return FALSE;
289}
290
302BOOLEAN
304 IN EFI_USB_IO_PROTOCOL *UsbIo,
305 IN USB_CLASS_DEVICE_PATH *UsbClass
306 )
307{
308 EFI_STATUS Status;
311 UINT8 DeviceClass;
312 UINT8 DeviceSubClass;
313 UINT8 DeviceProtocol;
314
315 if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) ||
316 (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP))
317 {
318 return FALSE;
319 }
320
321 //
322 // Check Vendor Id and Product Id.
323 //
324 Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
325 if (EFI_ERROR (Status)) {
326 return FALSE;
327 }
328
329 if ((UsbClass->VendorId != 0xffff) &&
330 (UsbClass->VendorId != DevDesc.IdVendor))
331 {
332 return FALSE;
333 }
334
335 if ((UsbClass->ProductId != 0xffff) &&
336 (UsbClass->ProductId != DevDesc.IdProduct))
337 {
338 return FALSE;
339 }
340
341 DeviceClass = DevDesc.DeviceClass;
342 DeviceSubClass = DevDesc.DeviceSubClass;
343 DeviceProtocol = DevDesc.DeviceProtocol;
344 if (DeviceClass == 0) {
345 //
346 // If Class in Device Descriptor is set to 0, use the Class, SubClass and
347 // Protocol in Interface Descriptor instead.
348 //
349 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
350 if (EFI_ERROR (Status)) {
351 return FALSE;
352 }
353
354 DeviceClass = IfDesc.InterfaceClass;
355 DeviceSubClass = IfDesc.InterfaceSubClass;
356 DeviceProtocol = IfDesc.InterfaceProtocol;
357 }
358
359 //
360 // Check Class, SubClass and Protocol.
361 //
362 if ((UsbClass->DeviceClass != 0xff) &&
363 (UsbClass->DeviceClass != DeviceClass))
364 {
365 return FALSE;
366 }
367
368 if ((UsbClass->DeviceSubClass != 0xff) &&
369 (UsbClass->DeviceSubClass != DeviceSubClass))
370 {
371 return FALSE;
372 }
373
374 if ((UsbClass->DeviceProtocol != 0xff) &&
375 (UsbClass->DeviceProtocol != DeviceProtocol))
376 {
377 return FALSE;
378 }
379
380 return TRUE;
381}
382
394BOOLEAN
396 IN EFI_USB_IO_PROTOCOL *UsbIo,
397 IN USB_WWID_DEVICE_PATH *UsbWwid
398 )
399{
400 EFI_STATUS Status;
403 UINT16 *LangIdTable;
404 UINT16 TableSize;
405 UINT16 Index;
406 CHAR16 *CompareStr;
407 UINTN CompareLen;
408 CHAR16 *SerialNumberStr;
409 UINTN Length;
410
411 if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) ||
412 (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP))
413 {
414 return FALSE;
415 }
416
417 //
418 // Check Vendor Id and Product Id.
419 //
420 Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
421 if (EFI_ERROR (Status)) {
422 return FALSE;
423 }
424
425 if ((DevDesc.IdVendor != UsbWwid->VendorId) ||
426 (DevDesc.IdProduct != UsbWwid->ProductId))
427 {
428 return FALSE;
429 }
430
431 //
432 // Check Interface Number.
433 //
434 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
435 if (EFI_ERROR (Status)) {
436 return FALSE;
437 }
438
439 if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) {
440 return FALSE;
441 }
442
443 //
444 // Check Serial Number.
445 //
446 if (DevDesc.StrSerialNumber == 0) {
447 return FALSE;
448 }
449
450 //
451 // Get all supported languages.
452 //
453 TableSize = 0;
454 LangIdTable = NULL;
455 Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable, &TableSize);
456 if (EFI_ERROR (Status) || (TableSize == 0) || (LangIdTable == NULL)) {
457 return FALSE;
458 }
459
460 //
461 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
462 //
463 CompareStr = (CHAR16 *)(UINTN)(UsbWwid + 1);
464 CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);
465 if (CompareStr[CompareLen - 1] == L'\0') {
466 CompareLen--;
467 }
468
469 //
470 // Compare serial number in each supported language.
471 //
472 for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) {
473 SerialNumberStr = NULL;
474 Status = UsbIo->UsbGetStringDescriptor (
475 UsbIo,
476 LangIdTable[Index],
477 DevDesc.StrSerialNumber,
478 &SerialNumberStr
479 );
480 if (EFI_ERROR (Status) || (SerialNumberStr == NULL)) {
481 continue;
482 }
483
484 Length = StrLen (SerialNumberStr);
485 if ((Length >= CompareLen) &&
486 (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0))
487 {
488 FreePool (SerialNumberStr);
489 return TRUE;
490 }
491
492 FreePool (SerialNumberStr);
493 }
494
495 return FALSE;
496}
497
515 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
516 IN UINTN ParentDevicePathSize,
517 OUT UINTN *UsbIoHandleCount
518 )
519{
520 EFI_STATUS Status;
521 EFI_HANDLE *UsbIoHandles;
522 EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath;
523 EFI_USB_IO_PROTOCOL *UsbIo;
524 UINTN Index;
525 BOOLEAN Matched;
526
527 ASSERT (UsbIoHandleCount != NULL);
528
529 //
530 // Get all UsbIo Handles.
531 //
532 Status = gBS->LocateHandleBuffer (
534 &gEfiUsbIoProtocolGuid,
535 NULL,
536 UsbIoHandleCount,
537 &UsbIoHandles
538 );
539 if (EFI_ERROR (Status)) {
540 *UsbIoHandleCount = 0;
541 UsbIoHandles = NULL;
542 }
543
544 for (Index = 0; Index < *UsbIoHandleCount; ) {
545 //
546 // Get the Usb IO interface.
547 //
548 Status = gBS->HandleProtocol (
549 UsbIoHandles[Index],
550 &gEfiUsbIoProtocolGuid,
551 (VOID **)&UsbIo
552 );
553 UsbIoDevicePath = DevicePathFromHandle (UsbIoHandles[Index]);
554 Matched = FALSE;
555 if (!EFI_ERROR (Status) && (UsbIoDevicePath != NULL)) {
556 //
557 // Compare starting part of UsbIoHandle's device path with ParentDevicePath.
558 //
559 if (CompareMem (UsbIoDevicePath, DevicePath, ParentDevicePathSize) == 0) {
560 if (BmMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *)((UINTN)DevicePath + ParentDevicePathSize)) ||
561 BmMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *)((UINTN)DevicePath + ParentDevicePathSize)))
562 {
563 Matched = TRUE;
564 }
565 }
566 }
567
568 if (!Matched) {
569 (*UsbIoHandleCount)--;
570 CopyMem (&UsbIoHandles[Index], &UsbIoHandles[Index + 1], (*UsbIoHandleCount - Index) * sizeof (EFI_HANDLE));
571 } else {
572 Index++;
573 }
574 }
575
576 return UsbIoHandles;
577}
578
609 IN EFI_DEVICE_PATH_PROTOCOL *ShortformNode
610 )
611{
612 UINTN ParentDevicePathSize;
613 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
614 EFI_DEVICE_PATH_PROTOCOL *NextFullPath;
615 EFI_HANDLE *Handles;
616 UINTN HandleCount;
617 UINTN Index;
618 BOOLEAN GetNext;
619
620 NextFullPath = NULL;
621 GetNext = (BOOLEAN)(FullPath == NULL);
622 ParentDevicePathSize = (UINTN)ShortformNode - (UINTN)FilePath;
623 RemainingDevicePath = NextDevicePathNode (ShortformNode);
624 Handles = BmFindUsbDevice (FilePath, ParentDevicePathSize, &HandleCount);
625
626 for (Index = 0; Index < HandleCount; Index++) {
627 FilePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), RemainingDevicePath);
628 if (FilePath == NULL) {
629 //
630 // Out of memory.
631 //
632 continue;
633 }
634
635 NextFullPath = BmGetNextLoadOptionDevicePath (FilePath, NULL);
636 FreePool (FilePath);
637 if (NextFullPath == NULL) {
638 //
639 // No BlockIo or SimpleFileSystem under FilePath.
640 //
641 continue;
642 }
643
644 if (GetNext) {
645 break;
646 } else {
647 GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);
648 FreePool (NextFullPath);
649 NextFullPath = NULL;
650 }
651 }
652
653 if (Handles != NULL) {
654 FreePool (Handles);
655 }
656
657 return NextFullPath;
658}
659
675 )
676{
677 EFI_STATUS Status;
678 UINTN Index;
679 UINTN HandleCount;
680 EFI_HANDLE *Handles;
681 EFI_BLOCK_IO_PROTOCOL *BlockIo;
682 UINTN MediaType;
683 EFI_DEVICE_PATH_PROTOCOL *NextFullPath;
684 BOOLEAN GetNext;
685
687 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);
688 if (EFI_ERROR (Status)) {
689 HandleCount = 0;
690 Handles = NULL;
691 }
692
693 GetNext = (BOOLEAN)(FullPath == NULL);
694 NextFullPath = NULL;
695 //
696 // Enumerate all removable media devices followed by all fixed media devices,
697 // followed by media devices which don't layer on block io.
698 //
699 for (MediaType = 0; MediaType < 3; MediaType++) {
700 for (Index = 0; Index < HandleCount; Index++) {
701 Status = gBS->HandleProtocol (Handles[Index], &gEfiBlockIoProtocolGuid, (VOID *)&BlockIo);
702 if (EFI_ERROR (Status)) {
703 BlockIo = NULL;
704 }
705
706 if (((MediaType == 0) && (BlockIo != NULL) && BlockIo->Media->RemovableMedia) ||
707 ((MediaType == 1) && (BlockIo != NULL) && !BlockIo->Media->RemovableMedia) ||
708 ((MediaType == 2) && (BlockIo == NULL))
709 )
710 {
711 NextFullPath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath);
712 if (GetNext) {
713 break;
714 } else {
715 GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);
716 FreePool (NextFullPath);
717 NextFullPath = NULL;
718 }
719 }
720 }
721
722 if (NextFullPath != NULL) {
723 break;
724 }
725 }
726
727 if (Handles != NULL) {
728 FreePool (Handles);
729 }
730
731 return NextFullPath;
732}
733
749 )
750{
751 EFI_STATUS Status;
752 UINTN Index;
753 UINTN HandleCount;
754 EFI_HANDLE *Handles;
755 EFI_DEVICE_PATH_PROTOCOL *NextFullPath;
756 EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;
757 BOOLEAN GetNext;
758
760 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &HandleCount, &Handles);
761 if (EFI_ERROR (Status)) {
762 HandleCount = 0;
763 Handles = NULL;
764 }
765
766 NextFullPath = NULL;
767 GetNext = (BOOLEAN)(FullPath == NULL);
768 for (Index = 0; Index < HandleCount; Index++) {
769 NextFullPath = BmExpandLoadFile (Handles[Index], FilePath);
770
771 if (NextFullPath == NULL) {
772 continue;
773 }
774
775 if (GetNext) {
776 break;
777 } else {
778 GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);
779 //
780 // Free the resource occupied by the RAM disk.
781 //
782 RamDiskDevicePath = BmGetRamDiskDevicePath (NextFullPath);
783 if (RamDiskDevicePath != NULL) {
784 BmDestroyRamDisk (RamDiskDevicePath);
785 FreePool (RamDiskDevicePath);
786 }
787
788 FreePool (NextFullPath);
789 NextFullPath = NULL;
790 }
791 }
792
793 if (Handles != NULL) {
794 FreePool (Handles);
795 }
796
797 return NextFullPath;
798}
799
806VOID
808 IN OUT EFI_DEVICE_PATH_PROTOCOL **CachedDevicePath,
809 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
810 )
811{
812 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
813 UINTN Count;
814
815 if (BmMatchDevicePaths (*CachedDevicePath, DevicePath)) {
816 TempDevicePath = *CachedDevicePath;
817 *CachedDevicePath = BmDelPartMatchInstance (*CachedDevicePath, DevicePath);
818 FreePool (TempDevicePath);
819 }
820
821 if (*CachedDevicePath == NULL) {
822 *CachedDevicePath = DuplicateDevicePath (DevicePath);
823 return;
824 }
825
826 TempDevicePath = *CachedDevicePath;
827 *CachedDevicePath = AppendDevicePathInstance (DevicePath, *CachedDevicePath);
828 if (TempDevicePath != NULL) {
829 FreePool (TempDevicePath);
830 }
831
832 //
833 // Here limit the device path instance number to 12, which is max number for a system support 3 IDE controller
834 // If the user try to boot many OS in different HDs or partitions, in theory, the 'HDDP' variable maybe become larger and larger.
835 //
836 Count = 0;
837 TempDevicePath = *CachedDevicePath;
838 while (!IsDevicePathEnd (TempDevicePath)) {
839 TempDevicePath = NextDevicePathNode (TempDevicePath);
840 //
841 // Parse one instance
842 //
843 while (!IsDevicePathEndType (TempDevicePath)) {
844 TempDevicePath = NextDevicePathNode (TempDevicePath);
845 }
846
847 Count++;
848 //
849 // If the CachedDevicePath variable contain too much instance, only remain 12 instances.
850 //
851 if (Count == 12) {
852 SetDevicePathEndNode (TempDevicePath);
853 break;
854 }
855 }
856}
857
874 )
875{
876 EFI_STATUS Status;
877 UINTN BlockIoHandleCount;
878 EFI_HANDLE *BlockIoBuffer;
879 EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath;
880 UINTN Index;
881 EFI_DEVICE_PATH_PROTOCOL *CachedDevicePath;
882 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
883 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
884 EFI_DEVICE_PATH_PROTOCOL *FullPath;
885 UINTN CachedDevicePathSize;
886 BOOLEAN NeedAdjust;
887 EFI_DEVICE_PATH_PROTOCOL *Instance;
888 UINTN Size;
889 BOOLEAN MatchFound;
890 BOOLEAN ConnectAllAttempted;
891
892 //
893 // Check if there is prestore 'HDDP' variable.
894 // If exist, search the front path which point to partition node in the variable instants.
895 // If fail to find or 'HDDP' not exist, reconnect all and search in all system
896 //
897 GetVariable2 (L"HDDP", &mBmHardDriveBootVariableGuid, (VOID **)&CachedDevicePath, &CachedDevicePathSize);
898
899 //
900 // Delete the invalid 'HDDP' variable.
901 //
902 if ((CachedDevicePath != NULL) && !IsDevicePathValid (CachedDevicePath, CachedDevicePathSize)) {
903 FreePool (CachedDevicePath);
904 CachedDevicePath = NULL;
905 Status = gRT->SetVariable (
906 L"HDDP",
908 0,
909 0,
910 NULL
911 );
912 ASSERT_EFI_ERROR (Status);
913 }
914
915 FullPath = NULL;
916 if (CachedDevicePath != NULL) {
917 TempNewDevicePath = CachedDevicePath;
918 NeedAdjust = FALSE;
919 do {
920 //
921 // Check every instance of the variable
922 // First, check whether the instance contain the partition node, which is needed for distinguishing multi
923 // partial partition boot option. Second, check whether the instance could be connected.
924 //
925 Instance = GetNextDevicePathInstance (&TempNewDevicePath, &Size);
926 if (BmMatchPartitionDevicePathNode (Instance, (HARDDRIVE_DEVICE_PATH *)FilePath)) {
927 //
928 // Connect the device path instance, the device path point to hard drive media device path node
929 // e.g. ACPI() /PCI()/ATA()/Partition()
930 //
931 Status = EfiBootManagerConnectDevicePath (Instance, NULL);
932 if (!EFI_ERROR (Status)) {
933 TempDevicePath = AppendDevicePath (Instance, NextDevicePathNode (FilePath));
934 //
935 // TempDevicePath = ACPI()/PCI()/ATA()/Partition()
936 // or = ACPI()/PCI()/ATA()/Partition()/.../A.EFI
937 //
938 // When TempDevicePath = ACPI()/PCI()/ATA()/Partition(),
939 // it may expand to two potienal full paths (nested partition, rarely happen):
940 // 1. ACPI()/PCI()/ATA()/Partition()/Partition(A1)/EFI/BootX64.EFI
941 // 2. ACPI()/PCI()/ATA()/Partition()/Partition(A2)/EFI/BootX64.EFI
942 // For simplicity, only #1 is returned.
943 //
944 FullPath = BmGetNextLoadOptionDevicePath (TempDevicePath, NULL);
945 FreePool (TempDevicePath);
946
947 if (FullPath != NULL) {
948 //
949 // Adjust the 'HDDP' instances sequence if the matched one is not first one.
950 //
951 if (NeedAdjust) {
952 BmCachePartitionDevicePath (&CachedDevicePath, Instance);
953 //
954 // Save the matching Device Path so we don't need to do a connect all next time
955 // Failing to save only impacts performance next time expanding the short-form device path
956 //
957 Status = gRT->SetVariable (
958 L"HDDP",
960 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
961 GetDevicePathSize (CachedDevicePath),
962 CachedDevicePath
963 );
964 }
965
966 FreePool (Instance);
967 FreePool (CachedDevicePath);
968 return FullPath;
969 }
970 }
971 }
972
973 //
974 // Come here means the first instance is not matched
975 //
976 NeedAdjust = TRUE;
977 FreePool (Instance);
978 } while (TempNewDevicePath != NULL);
979 }
980
981 //
982 // If we get here we fail to find or 'HDDP' not exist, and now we need
983 // to search all devices in the system for a matched partition
984 //
985 BlockIoBuffer = NULL;
986 MatchFound = FALSE;
987 ConnectAllAttempted = FALSE;
988 do {
989 if (BlockIoBuffer != NULL) {
990 FreePool (BlockIoBuffer);
991 }
992
993 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);
994 if (EFI_ERROR (Status)) {
995 BlockIoHandleCount = 0;
996 BlockIoBuffer = NULL;
997 }
998
999 //
1000 // Loop through all the device handles that support the BLOCK_IO Protocol
1001 //
1002 for (Index = 0; Index < BlockIoHandleCount; Index++) {
1003 BlockIoDevicePath = DevicePathFromHandle (BlockIoBuffer[Index]);
1004 if (BlockIoDevicePath == NULL) {
1005 continue;
1006 }
1007
1008 if (BmMatchPartitionDevicePathNode (BlockIoDevicePath, (HARDDRIVE_DEVICE_PATH *)FilePath)) {
1009 //
1010 // Find the matched partition device path
1011 //
1012 TempDevicePath = AppendDevicePath (BlockIoDevicePath, NextDevicePathNode (FilePath));
1013 FullPath = BmGetNextLoadOptionDevicePath (TempDevicePath, NULL);
1014 FreePool (TempDevicePath);
1015
1016 if (FullPath != NULL) {
1017 BmCachePartitionDevicePath (&CachedDevicePath, BlockIoDevicePath);
1018
1019 //
1020 // Save the matching Device Path so we don't need to do a connect all next time
1021 // Failing to save only impacts performance next time expanding the short-form device path
1022 //
1023 Status = gRT->SetVariable (
1024 L"HDDP",
1026 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1028 GetDevicePathSize (CachedDevicePath),
1029 CachedDevicePath
1030 );
1031 MatchFound = TRUE;
1032 break;
1033 }
1034 }
1035 }
1036
1037 //
1038 // If we found a matching BLOCK_IO handle or we've already
1039 // tried a ConnectAll, we are done searching.
1040 //
1041 if (MatchFound || ConnectAllAttempted) {
1042 break;
1043 }
1044
1046 ConnectAllAttempted = TRUE;
1047 } while (1);
1048
1049 if (CachedDevicePath != NULL) {
1050 FreePool (CachedDevicePath);
1051 }
1052
1053 if (BlockIoBuffer != NULL) {
1054 FreePool (BlockIoBuffer);
1055 }
1056
1057 return FullPath;
1058}
1059
1073 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1075 )
1076{
1077 EFI_STATUS Status;
1078 EFI_HANDLE Handle;
1079 EFI_BLOCK_IO_PROTOCOL *BlockIo;
1080 VOID *Buffer;
1081 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
1082 EFI_DEVICE_PATH_PROTOCOL *NextFullPath;
1083 UINTN Size;
1084 UINTN TempSize;
1085 EFI_HANDLE *SimpleFileSystemHandles;
1086 UINTN NumberSimpleFileSystemHandles;
1087 UINTN Index;
1088 BOOLEAN GetNext;
1089
1090 GetNext = (BOOLEAN)(FullPath == NULL);
1091 //
1092 // Check whether the device is connected
1093 //
1094 TempDevicePath = DevicePath;
1095 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &TempDevicePath, &Handle);
1096 if (!EFI_ERROR (Status)) {
1097 ASSERT (IsDevicePathEnd (TempDevicePath));
1098
1099 NextFullPath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);
1100 //
1101 // For device path pointing to simple file system, it only expands to one full path.
1102 //
1103 if (GetNext) {
1104 return NextFullPath;
1105 } else {
1106 FreePool (NextFullPath);
1107 return NULL;
1108 }
1109 }
1110
1111 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);
1112 ASSERT_EFI_ERROR (Status);
1113
1114 //
1115 // For device boot option only pointing to the removable device handle,
1116 // should make sure all its children handles (its child partion or media handles)
1117 // are created and connected.
1118 //
1119 gBS->ConnectController (Handle, NULL, NULL, TRUE);
1120
1121 //
1122 // Issue a dummy read to the device to check for media change.
1123 // When the removable media is changed, any Block IO read/write will
1124 // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
1125 // returned. After the Block IO protocol is reinstalled, subsequent
1126 // Block IO read/write will success.
1127 //
1128 Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
1129 ASSERT_EFI_ERROR (Status);
1130 if (EFI_ERROR (Status)) {
1131 return NULL;
1132 }
1133
1134 Buffer = AllocatePool (BlockIo->Media->BlockSize);
1135 if (Buffer != NULL) {
1136 BlockIo->ReadBlocks (
1137 BlockIo,
1138 BlockIo->Media->MediaId,
1139 0,
1140 BlockIo->Media->BlockSize,
1141 Buffer
1142 );
1143 FreePool (Buffer);
1144 }
1145
1146 //
1147 // Detect the the default boot file from removable Media
1148 //
1149 NextFullPath = NULL;
1150 Size = GetDevicePathSize (DevicePath) - END_DEVICE_PATH_LENGTH;
1151 gBS->LocateHandleBuffer (
1152 ByProtocol,
1153 &gEfiSimpleFileSystemProtocolGuid,
1154 NULL,
1155 &NumberSimpleFileSystemHandles,
1156 &SimpleFileSystemHandles
1157 );
1158 for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) {
1159 //
1160 // Get the device path size of SimpleFileSystem handle
1161 //
1162 TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]);
1163 TempSize = GetDevicePathSize (TempDevicePath) - END_DEVICE_PATH_LENGTH;
1164 //
1165 // Check whether the device path of boot option is part of the SimpleFileSystem handle's device path
1166 //
1167 if ((Size <= TempSize) && (CompareMem (TempDevicePath, DevicePath, Size) == 0)) {
1168 NextFullPath = FileDevicePath (SimpleFileSystemHandles[Index], EFI_REMOVABLE_MEDIA_FILE_NAME);
1169 if (GetNext) {
1170 break;
1171 } else {
1172 GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);
1173 FreePool (NextFullPath);
1174 NextFullPath = NULL;
1175 }
1176 }
1177 }
1178
1179 if (SimpleFileSystemHandles != NULL) {
1180 FreePool (SimpleFileSystemHandles);
1181 }
1182
1183 return NextFullPath;
1184}
1185
1193BOOLEAN
1197 )
1198{
1199 for ( ; !IsDevicePathEnd (Left) && !IsDevicePathEnd (Right)
1200 ; Left = NextDevicePathNode (Left), Right = NextDevicePathNode (Right)
1201 )
1202 {
1203 if (CompareMem (Left, Right, DevicePathNodeLength (Left)) != 0) {
1205 return FALSE;
1206 }
1207
1208 if (DevicePathSubType (Left) == MSG_DNS_DP) {
1209 Left = NextDevicePathNode (Left);
1210 }
1211
1212 if (DevicePathSubType (Right) == MSG_DNS_DP) {
1213 Right = NextDevicePathNode (Right);
1214 }
1215
1216 if (((DevicePathSubType (Left) != MSG_IPv4_DP) || (DevicePathSubType (Right) != MSG_IPv4_DP)) &&
1217 ((DevicePathSubType (Left) != MSG_IPv6_DP) || (DevicePathSubType (Right) != MSG_IPv6_DP)) &&
1218 ((DevicePathSubType (Left) != MSG_URI_DP) || (DevicePathSubType (Right) != MSG_URI_DP))
1219 )
1220 {
1221 return FALSE;
1222 }
1223 }
1224 }
1225
1226 return (BOOLEAN)(IsDevicePathEnd (Left) && IsDevicePathEnd (Right));
1227}
1228
1240 IN EFI_HANDLE LoadFileHandle,
1241 OUT EFI_HANDLE *RamDiskHandle
1242 )
1243{
1244 EFI_STATUS Status;
1245 EFI_HANDLE Handle;
1246 EFI_HANDLE *Handles;
1247 UINTN HandleCount;
1248 UINTN Index;
1250
1251 Status = gBS->LocateHandleBuffer (
1252 ByProtocol,
1253 &gEfiBlockIoProtocolGuid,
1254 NULL,
1255 &HandleCount,
1256 &Handles
1257 );
1258 if (EFI_ERROR (Status)) {
1259 Handles = NULL;
1260 HandleCount = 0;
1261 }
1262
1263 Handle = NULL;
1264 for (Index = 0; Index < HandleCount; Index++) {
1265 Node = DevicePathFromHandle (Handles[Index]);
1266 Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle);
1267 if (!EFI_ERROR (Status) &&
1268 (Handle == LoadFileHandle) &&
1269 (DevicePathType (Node) == MEDIA_DEVICE_PATH) && (DevicePathSubType (Node) == MEDIA_RAM_DISK_DP))
1270 {
1271 //
1272 // Find the BlockIo instance populated from the LoadFile.
1273 //
1274 Handle = Handles[Index];
1275 break;
1276 }
1277 }
1278
1279 if (Handles != NULL) {
1280 FreePool (Handles);
1281 }
1282
1283 if (Index == HandleCount) {
1284 Handle = NULL;
1285 }
1286
1287 *RamDiskHandle = Handle;
1288
1289 if (Handle != NULL) {
1290 //
1291 // Re-use BmExpandMediaDevicePath() to get the full device path of load option.
1292 // But assume only one SimpleFileSystem can be found under the BlockIo.
1293 //
1295 } else {
1296 return NULL;
1297 }
1298}
1299
1310 )
1311{
1312 EFI_STATUS Status;
1313 EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;
1315 EFI_HANDLE Handle;
1316
1317 Node = FilePath;
1318 Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle);
1319 if (!EFI_ERROR (Status) &&
1320 (DevicePathType (Node) == MEDIA_DEVICE_PATH) &&
1322 )
1323 {
1324 //
1325 // Construct the device path pointing to RAM Disk
1326 //
1327 Node = NextDevicePathNode (Node);
1328 RamDiskDevicePath = DuplicateDevicePath (FilePath);
1329 ASSERT (RamDiskDevicePath != NULL);
1330 SetDevicePathEndNode ((VOID *)((UINTN)RamDiskDevicePath + ((UINTN)Node - (UINTN)FilePath)));
1331 return RamDiskDevicePath;
1332 }
1333
1334 return NULL;
1335}
1336
1345VOID *
1347 IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath,
1348 OUT UINTN *RamDiskSizeInPages
1349 )
1350{
1351 EFI_STATUS Status;
1352 EFI_HANDLE Handle;
1353 UINT64 StartingAddr;
1354 UINT64 EndingAddr;
1355
1356 ASSERT (RamDiskDevicePath != NULL);
1357
1358 *RamDiskSizeInPages = 0;
1359
1360 //
1361 // Get the buffer occupied by RAM Disk.
1362 //
1363 Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &RamDiskDevicePath, &Handle);
1364 ASSERT_EFI_ERROR (Status);
1365 ASSERT (
1366 (DevicePathType (RamDiskDevicePath) == MEDIA_DEVICE_PATH) &&
1367 (DevicePathSubType (RamDiskDevicePath) == MEDIA_RAM_DISK_DP)
1368 );
1369 StartingAddr = ReadUnaligned64 ((UINT64 *)((MEDIA_RAM_DISK_DEVICE_PATH *)RamDiskDevicePath)->StartingAddr);
1370 EndingAddr = ReadUnaligned64 ((UINT64 *)((MEDIA_RAM_DISK_DEVICE_PATH *)RamDiskDevicePath)->EndingAddr);
1371 *RamDiskSizeInPages = EFI_SIZE_TO_PAGES ((UINTN)(EndingAddr - StartingAddr + 1));
1372 return (VOID *)(UINTN)StartingAddr;
1373}
1374
1384VOID
1386 IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath
1387 )
1388{
1389 EFI_STATUS Status;
1390 VOID *RamDiskBuffer;
1391 UINTN RamDiskSizeInPages;
1392
1393 ASSERT (RamDiskDevicePath != NULL);
1394
1395 RamDiskBuffer = BmGetRamDiskMemoryInfo (RamDiskDevicePath, &RamDiskSizeInPages);
1396
1397 //
1398 // Destroy RAM Disk.
1399 //
1400 if (mRamDisk == NULL) {
1401 Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID *)&mRamDisk);
1402 ASSERT_EFI_ERROR (Status);
1403 }
1404
1405 Status = mRamDisk->Unregister (RamDiskDevicePath);
1406 ASSERT_EFI_ERROR (Status);
1407 FreePages (RamDiskBuffer, RamDiskSizeInPages);
1408}
1409
1420 IN EFI_HANDLE LoadFileHandle,
1422 )
1423{
1424 EFI_STATUS Status;
1425 EFI_LOAD_FILE_PROTOCOL *LoadFile;
1426 VOID *FileBuffer;
1427 EFI_HANDLE RamDiskHandle;
1428 UINTN BufferSize;
1429 EFI_DEVICE_PATH_PROTOCOL *FullPath;
1430
1431 Status = gBS->OpenProtocol (
1432 LoadFileHandle,
1433 &gEfiLoadFileProtocolGuid,
1434 (VOID **)&LoadFile,
1436 NULL,
1437 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1438 );
1439 ASSERT_EFI_ERROR (Status);
1440
1441 FileBuffer = NULL;
1442 BufferSize = 0;
1443 Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);
1444 if ((Status != EFI_WARN_FILE_SYSTEM) && (Status != EFI_BUFFER_TOO_SMALL)) {
1445 return NULL;
1446 }
1447
1448 if (Status == EFI_BUFFER_TOO_SMALL) {
1449 //
1450 // The load option buffer is directly returned by LoadFile.
1451 //
1452 return DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));
1453 }
1454
1455 //
1456 // The load option resides in a RAM disk.
1457 //
1458 FileBuffer = AllocateReservedPages (EFI_SIZE_TO_PAGES (BufferSize));
1459 if (FileBuffer == NULL) {
1461 EFI_DEVICE_PATH *LoadFilePath;
1462 CHAR16 *LoadFileText;
1463 CHAR16 *FileText;
1464
1465 LoadFilePath = DevicePathFromHandle (LoadFileHandle);
1466 if (LoadFilePath == NULL) {
1467 LoadFileText = NULL;
1468 } else {
1469 LoadFileText = ConvertDevicePathToText (LoadFilePath, FALSE, FALSE);
1470 }
1471
1472 FileText = ConvertDevicePathToText (FilePath, FALSE, FALSE);
1473
1474 DEBUG ((
1475 DEBUG_ERROR,
1476 "%a:%a: failed to allocate reserved pages: "
1477 "BufferSize=%Lu LoadFile=\"%s\" FilePath=\"%s\"\n",
1478 gEfiCallerBaseName,
1479 __func__,
1480 (UINT64)BufferSize,
1481 LoadFileText,
1482 FileText
1483 ));
1484
1485 if (FileText != NULL) {
1486 FreePool (FileText);
1487 }
1488
1489 if (LoadFileText != NULL) {
1490 FreePool (LoadFileText);
1491 }
1492
1493 DEBUG_CODE_END ();
1494 return NULL;
1495 }
1496
1497 Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);
1498 if (EFI_ERROR (Status)) {
1499 FreePages (FileBuffer, EFI_SIZE_TO_PAGES (BufferSize));
1500 return NULL;
1501 }
1502
1503 FullPath = BmExpandNetworkFileSystem (LoadFileHandle, &RamDiskHandle);
1504 if (FullPath == NULL) {
1505 //
1506 // Free the memory occupied by the RAM disk if there is no BlockIo or SimpleFileSystem instance.
1507 //
1508 BmDestroyRamDisk (DevicePathFromHandle (RamDiskHandle));
1509 }
1510
1511 return FullPath;
1512}
1513
1536 )
1537{
1538 EFI_STATUS Status;
1539 EFI_HANDLE Handle;
1540 EFI_HANDLE *Handles;
1541 UINTN HandleCount;
1542 UINTN Index;
1544
1545 //
1546 // Get file buffer from load file instance.
1547 //
1548 Node = FilePath;
1549 Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle);
1550 if (!EFI_ERROR (Status) && IsDevicePathEnd (Node)) {
1551 //
1552 // When wide match happens, pass full device path to LoadFile (),
1553 // otherwise, pass remaining device path to LoadFile ().
1554 //
1555 FilePath = Node;
1556 } else {
1557 Handle = NULL;
1558 //
1559 // Use wide match algorithm to find one when
1560 // cannot find a LoadFile instance to exactly match the FilePath
1561 //
1562 Status = gBS->LocateHandleBuffer (
1563 ByProtocol,
1564 &gEfiLoadFileProtocolGuid,
1565 NULL,
1566 &HandleCount,
1567 &Handles
1568 );
1569 if (EFI_ERROR (Status)) {
1570 Handles = NULL;
1571 HandleCount = 0;
1572 }
1573
1574 for (Index = 0; Index < HandleCount; Index++) {
1575 if (BmMatchHttpBootDevicePath (DevicePathFromHandle (Handles[Index]), FilePath)) {
1576 Handle = Handles[Index];
1577 break;
1578 }
1579 }
1580
1581 if (Handles != NULL) {
1582 FreePool (Handles);
1583 }
1584 }
1585
1586 if (Handle == NULL) {
1587 return NULL;
1588 }
1589
1590 return BmExpandLoadFile (Handle, FilePath);
1591}
1592
1605VOID *
1606EFIAPI
1608 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1609 OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
1610 OUT UINTN *FileSize
1611 )
1612{
1613 *FullPath = NULL;
1614
1616 return BmGetNextLoadOptionBuffer (LoadOptionTypeMax, FilePath, FullPath, FileSize);
1617}
1618
1635 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1637 )
1638{
1639 EFI_HANDLE Handle;
1641 EFI_STATUS Status;
1642
1643 ASSERT (FilePath != NULL);
1644
1645 //
1646 // Boot from media device by adding a default file name \EFI\BOOT\BOOT{machine type short-name}.EFI
1647 //
1648 Node = FilePath;
1649 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &Node, &Handle);
1650 if (EFI_ERROR (Status)) {
1651 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &Node, &Handle);
1652 }
1653
1654 if (!EFI_ERROR (Status) && IsDevicePathEnd (Node)) {
1655 return BmExpandMediaDevicePath (FilePath, FullPath);
1656 }
1657
1658 //
1659 // Expand the short-form device path to full device path
1660 //
1661 if ((DevicePathType (FilePath) == MEDIA_DEVICE_PATH) &&
1662 (DevicePathSubType (FilePath) == MEDIA_HARDDRIVE_DP))
1663 {
1664 //
1665 // Expand the Harddrive device path
1666 //
1667 if (FullPath == NULL) {
1668 return BmExpandPartitionDevicePath (FilePath);
1669 } else {
1670 return NULL;
1671 }
1672 } else if ((DevicePathType (FilePath) == MEDIA_DEVICE_PATH) &&
1673 (DevicePathSubType (FilePath) == MEDIA_FILEPATH_DP))
1674 {
1675 //
1676 // Expand the File-path device path
1677 //
1678 return BmExpandFileDevicePath (FilePath, FullPath);
1679 } else if ((DevicePathType (FilePath) == MESSAGING_DEVICE_PATH) &&
1680 (DevicePathSubType (FilePath) == MSG_URI_DP))
1681 {
1682 //
1683 // Expand the URI device path
1684 //
1685 return BmExpandUriDevicePath (FilePath, FullPath);
1686 } else {
1687 Node = FilePath;
1688 Status = gBS->LocateDevicePath (&gEfiUsbIoProtocolGuid, &Node, &Handle);
1689 if (EFI_ERROR (Status)) {
1690 //
1691 // Only expand the USB WWID/Class device path
1692 // when FilePath doesn't point to a physical UsbIo controller.
1693 // Otherwise, infinite recursion will happen.
1694 //
1695 for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {
1696 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&
1698 {
1699 break;
1700 }
1701 }
1702
1703 //
1704 // Expand the USB WWID/Class device path
1705 //
1706 if (!IsDevicePathEnd (Node)) {
1707 if (FilePath == Node) {
1708 //
1709 // Boot Option device path starts with USB Class or USB WWID device path.
1710 // For Boot Option device path which doesn't begin with the USB Class or
1711 // USB WWID device path, it's not needed to connect again here.
1712 //
1714 }
1715
1716 return BmExpandUsbDevicePath (FilePath, FullPath, Node);
1717 }
1718 }
1719 }
1720
1721 //
1722 // For the below cases, FilePath only expands to one Full path.
1723 // So just handle the case when FullPath == NULL.
1724 //
1725 if (FullPath != NULL) {
1726 return NULL;
1727 }
1728
1729 //
1730 // Load option resides in FV.
1731 //
1732 if (BmIsFvFilePath (FilePath)) {
1733 return BmAdjustFvFilePath (FilePath);
1734 }
1735
1736 //
1737 // Load option resides in Simple File System.
1738 //
1739 Node = FilePath;
1740 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &Node, &Handle);
1741 if (!EFI_ERROR (Status)) {
1742 return DuplicateDevicePath (FilePath);
1743 }
1744
1745 //
1746 // Last chance to try: Load option may be loaded through LoadFile.
1747 //
1748 return BmExpandLoadFiles (FilePath);
1749}
1750
1759BOOLEAN
1761 EFI_DEVICE_PATH_PROTOCOL *DevicePath
1762 )
1763{
1764 EFI_HANDLE FvHandle;
1765 VOID *NameGuid;
1766 EFI_STATUS Status;
1767
1768 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePath, &FvHandle);
1769 if (!EFI_ERROR (Status)) {
1771 if (NameGuid != NULL) {
1772 return CompareGuid (NameGuid, PcdGetPtr (PcdBootManagerMenuFile));
1773 }
1774 }
1775
1776 return FALSE;
1777}
1778
1793VOID
1795 IN UINT32 ErrorCode,
1796 IN EFI_STATUS FailureStatus
1797 )
1798{
1800
1801 if (!ReportErrorCodeEnabled ()) {
1802 return;
1803 }
1804
1805 ASSERT (
1806 (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) ||
1807 (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)
1808 );
1809
1810 ZeroMem (&ExtendedData, sizeof (ExtendedData));
1811 ExtendedData.ReturnStatus = FailureStatus;
1812
1814 (EFI_ERROR_CODE | EFI_ERROR_MINOR),
1815 (EFI_SOFTWARE_DXE_BS_DRIVER | ErrorCode),
1816 0,
1817 NULL,
1818 NULL,
1819 &ExtendedData.DataHeader + 1,
1820 sizeof (ExtendedData) - sizeof (ExtendedData.DataHeader)
1821 );
1822}
1823
1844VOID
1845EFIAPI
1848 )
1849{
1850 EFI_STATUS Status;
1851 EFI_HANDLE ImageHandle;
1852 EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
1853 UINT16 Uint16;
1854 UINTN OptionNumber;
1855 UINTN OriginalOptionNumber;
1856 EFI_DEVICE_PATH_PROTOCOL *FilePath;
1857 EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;
1858 VOID *FileBuffer;
1859 UINTN FileSize;
1860 EFI_BOOT_LOGO_PROTOCOL *BootLogo;
1861 EFI_EVENT LegacyBootEvent;
1862
1863 if (BootOption == NULL) {
1864 return;
1865 }
1866
1867 if ((BootOption->FilePath == NULL) || (BootOption->OptionType != LoadOptionTypeBoot)) {
1868 BootOption->Status = EFI_INVALID_PARAMETER;
1869 return;
1870 }
1871
1872 //
1873 // 1. Create Boot#### for a temporary boot if there is no match Boot#### (i.e. a boot by selected a EFI Shell using "Boot From File")
1874 //
1875 OptionNumber = BmFindBootOptionInVariable (BootOption);
1876 if (OptionNumber == LoadOptionNumberUnassigned) {
1877 Status = BmGetFreeOptionNumber (LoadOptionTypeBoot, &Uint16);
1878 if (!EFI_ERROR (Status)) {
1879 //
1880 // Save the BootOption->OptionNumber to restore later
1881 //
1882 OptionNumber = Uint16;
1883 OriginalOptionNumber = BootOption->OptionNumber;
1884 BootOption->OptionNumber = OptionNumber;
1885 Status = EfiBootManagerLoadOptionToVariable (BootOption);
1886 BootOption->OptionNumber = OriginalOptionNumber;
1887 }
1888
1889 if (EFI_ERROR (Status)) {
1890 DEBUG ((DEBUG_ERROR, "[Bds] Failed to create Boot#### for a temporary boot - %r!\n", Status));
1891 BootOption->Status = Status;
1892 return;
1893 }
1894 }
1895
1896 //
1897 // 2. Set BootCurrent
1898 //
1899 Uint16 = (UINT16)OptionNumber;
1901 L"BootCurrent",
1902 &gEfiGlobalVariableGuid,
1903 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1904 sizeof (UINT16),
1905 &Uint16
1906 );
1907
1908 //
1909 // 3. Signal the EVT_SIGNAL_READY_TO_BOOT event when we are about to load and execute
1910 // the boot option.
1911 //
1912 if (BmIsBootManagerMenuFilePath (BootOption->FilePath)) {
1913 DEBUG ((DEBUG_INFO, "[Bds] Booting Boot Manager Menu.\n"));
1915 } else {
1917 //
1918 // Report Status Code to indicate ReadyToBoot was signalled
1919 //
1920 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
1921 //
1922 // 4. Repair system through DriverHealth protocol
1923 //
1925 }
1926
1927 PERF_START_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32)OptionNumber);
1928
1929 //
1930 // 5. Adjust the different type memory page number just before booting
1931 // and save the updated info into the variable for next boot to use
1932 //
1934 (BOOLEAN)((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_BOOT)
1935 );
1936
1937 //
1938 // 6. Load EFI boot option to ImageHandle
1939 //
1941 if (BootOption->Description == NULL) {
1942 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting from unknown device path\n"));
1943 } else {
1944 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting %s\n", BootOption->Description));
1945 }
1946
1947 DEBUG_CODE_END ();
1948
1949 ImageHandle = NULL;
1950 RamDiskDevicePath = NULL;
1951 if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {
1952 Status = EFI_NOT_FOUND;
1953 FilePath = NULL;
1954 EfiBootManagerConnectDevicePath (BootOption->FilePath, NULL);
1955 FileBuffer = BmGetNextLoadOptionBuffer (LoadOptionTypeBoot, BootOption->FilePath, &FilePath, &FileSize);
1956 if (FileBuffer != NULL) {
1957 RamDiskDevicePath = BmGetRamDiskDevicePath (FilePath);
1958
1959 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
1960 Status = gBS->LoadImage (
1961 TRUE,
1963 FilePath,
1964 FileBuffer,
1965 FileSize,
1966 &ImageHandle
1967 );
1968 }
1969
1970 if (FileBuffer != NULL) {
1971 FreePool (FileBuffer);
1972 }
1973
1974 if (FilePath != NULL) {
1975 FreePool (FilePath);
1976 }
1977
1978 if (EFI_ERROR (Status)) {
1979 //
1980 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
1981 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
1982 // If the caller doesn't have the option to defer the execution of an image, we should
1983 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
1984 //
1985 if (Status == EFI_SECURITY_VIOLATION) {
1986 gBS->UnloadImage (ImageHandle);
1987 }
1988
1989 //
1990 // Destroy the RAM disk
1991 //
1992 if (RamDiskDevicePath != NULL) {
1993 BmDestroyRamDisk (RamDiskDevicePath);
1994 FreePool (RamDiskDevicePath);
1995 }
1996
1997 //
1998 // Report Status Code with the failure status to indicate that the failure to load boot option
1999 //
2000 BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status);
2001 BootOption->Status = Status;
2002 return;
2003 }
2004 }
2005
2006 //
2007 // Check to see if we should legacy BOOT. If yes then do the legacy boot
2008 // Write boot to OS performance data for Legacy boot
2009 //
2010 if ((DevicePathType (BootOption->FilePath) == BBS_DEVICE_PATH) && (DevicePathSubType (BootOption->FilePath) == BBS_BBS_DP)) {
2011 if (mBmLegacyBoot != NULL) {
2012 //
2013 // Write boot to OS performance data for legacy boot.
2014 //
2015 PERF_CODE (
2016 //
2017 // Create an event to be signalled when Legacy Boot occurs to write performance data.
2018 //
2020 TPL_NOTIFY,
2022 NULL,
2023 &LegacyBootEvent
2024 );
2025 ASSERT_EFI_ERROR (Status);
2026 );
2027
2028 mBmLegacyBoot (BootOption);
2029 } else {
2030 BootOption->Status = EFI_UNSUPPORTED;
2031 }
2032
2033 PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32)OptionNumber);
2034 return;
2035 }
2036
2037 //
2038 // Provide the image with its load options
2039 //
2040 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo);
2041 ASSERT_EFI_ERROR (Status);
2042
2043 if (!BmIsAutoCreateBootOption (BootOption)) {
2044 ImageInfo->LoadOptionsSize = BootOption->OptionalDataSize;
2045 ImageInfo->LoadOptions = BootOption->OptionalData;
2046 }
2047
2048 //
2049 // Clean to NULL because the image is loaded directly from the firmwares boot manager.
2050 //
2051 ImageInfo->ParentHandle = NULL;
2052
2053 //
2054 // Before calling the image, enable the Watchdog Timer for 5 minutes period
2055 //
2056 gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
2057
2058 //
2059 // Write boot to OS performance data for UEFI boot
2060 //
2061 PERF_CODE (
2063 );
2064
2065 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderStart));
2066
2067 Status = gBS->StartImage (ImageHandle, &BootOption->ExitDataSize, &BootOption->ExitData);
2068 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status));
2069 BootOption->Status = Status;
2070
2071 //
2072 // Destroy the RAM disk
2073 //
2074 if (RamDiskDevicePath != NULL) {
2075 BmDestroyRamDisk (RamDiskDevicePath);
2076 FreePool (RamDiskDevicePath);
2077 }
2078
2079 if (EFI_ERROR (Status)) {
2080 //
2081 // Report Status Code with the failure status to indicate that boot failure
2082 //
2083 BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED, Status);
2084 }
2085
2086 PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32)OptionNumber);
2087
2088 //
2089 // Clear the Watchdog Timer after the image returns
2090 //
2091 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
2092
2093 //
2094 // Set Logo status invalid after trying one boot option
2095 //
2096 BootLogo = NULL;
2097 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **)&BootLogo);
2098 if (!EFI_ERROR (Status) && (BootLogo != NULL)) {
2099 Status = BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
2100 ASSERT_EFI_ERROR (Status);
2101 }
2102
2103 //
2104 // Clear Boot Current
2105 //
2106 Status = gRT->SetVariable (
2107 L"BootCurrent",
2108 &gEfiGlobalVariableGuid,
2109 0,
2110 0,
2111 NULL
2112 );
2113 //
2114 // Deleting variable with current variable implementation shouldn't fail.
2115 // When BootXXXX (e.g.: BootManagerMenu) boots BootYYYY, exiting BootYYYY causes BootCurrent deleted,
2116 // exiting BootXXXX causes deleting BootCurrent returns EFI_NOT_FOUND.
2117 //
2118 ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);
2119}
2120
2133BOOLEAN
2135 IN EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath,
2136 IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath
2137 )
2138{
2140
2141 if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) {
2142 return FALSE;
2143 }
2144
2145 //
2146 // Match all the partition device path nodes including the nested partition nodes
2147 //
2148 while (!IsDevicePathEnd (BlockIoDevicePath)) {
2149 if ((DevicePathType (BlockIoDevicePath) == MEDIA_DEVICE_PATH) &&
2150 (DevicePathSubType (BlockIoDevicePath) == MEDIA_HARDDRIVE_DP)
2151 )
2152 {
2153 //
2154 // See if the harddrive device path in blockio matches the orig Hard Drive Node
2155 //
2156 Node = (HARDDRIVE_DEVICE_PATH *)BlockIoDevicePath;
2157
2158 //
2159 // Match Signature and PartitionNumber.
2160 // Unused bytes in Signature are initiaized with zeros.
2161 //
2162 if ((Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) &&
2163 (Node->MBRType == HardDriveDevicePath->MBRType) &&
2164 (Node->SignatureType == HardDriveDevicePath->SignatureType) &&
2165 (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0))
2166 {
2167 return TRUE;
2168 }
2169 }
2170
2171 BlockIoDevicePath = NextDevicePathNode (BlockIoDevicePath);
2172 }
2173
2174 return FALSE;
2175}
2176
2196 UINTN *BootOptionCount
2197 )
2198{
2199 EFI_STATUS Status;
2200 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
2201 UINTN HandleCount;
2202 EFI_HANDLE *Handles;
2203 EFI_BLOCK_IO_PROTOCOL *BlkIo;
2204 UINTN Removable;
2205 UINTN Index;
2206 CHAR16 *Description;
2207
2208 ASSERT (BootOptionCount != NULL);
2209
2210 *BootOptionCount = 0;
2211 BootOptions = NULL;
2212
2213 //
2214 // Parse removable block io followed by fixed block io
2215 //
2216 gBS->LocateHandleBuffer (
2217 ByProtocol,
2218 &gEfiBlockIoProtocolGuid,
2219 NULL,
2220 &HandleCount,
2221 &Handles
2222 );
2223
2224 for (Removable = 0; Removable < 2; Removable++) {
2225 for (Index = 0; Index < HandleCount; Index++) {
2226 Status = gBS->HandleProtocol (
2227 Handles[Index],
2228 &gEfiBlockIoProtocolGuid,
2229 (VOID **)&BlkIo
2230 );
2231 if (EFI_ERROR (Status)) {
2232 continue;
2233 }
2234
2235 //
2236 // Skip the logical partitions
2237 //
2238 if (BlkIo->Media->LogicalPartition) {
2239 continue;
2240 }
2241
2242 //
2243 // Skip the fixed block io then the removable block io
2244 //
2245 if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) {
2246 continue;
2247 }
2248
2249 //
2250 // Skip removable media if not present
2251 //
2252 if ((BlkIo->Media->RemovableMedia == TRUE) &&
2253 (BlkIo->Media->MediaPresent == FALSE))
2254 {
2255 continue;
2256 }
2257
2258 Description = BmGetBootDescription (Handles[Index]);
2259 BootOptions = ReallocatePool (
2260 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
2261 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
2262 BootOptions
2263 );
2264 ASSERT (BootOptions != NULL);
2265
2267 &BootOptions[(*BootOptionCount)++],
2268 LoadOptionNumberUnassigned,
2269 LoadOptionTypeBoot,
2270 LOAD_OPTION_ACTIVE,
2271 Description,
2272 DevicePathFromHandle (Handles[Index]),
2273 NULL,
2274 0
2275 );
2276 ASSERT_EFI_ERROR (Status);
2277
2278 FreePool (Description);
2279 }
2280 }
2281
2282 if (HandleCount != 0) {
2283 FreePool (Handles);
2284 }
2285
2286 //
2287 // Parse simple file system not based on block io
2288 //
2289 gBS->LocateHandleBuffer (
2290 ByProtocol,
2291 &gEfiSimpleFileSystemProtocolGuid,
2292 NULL,
2293 &HandleCount,
2294 &Handles
2295 );
2296 for (Index = 0; Index < HandleCount; Index++) {
2297 Status = gBS->HandleProtocol (
2298 Handles[Index],
2299 &gEfiBlockIoProtocolGuid,
2300 (VOID **)&BlkIo
2301 );
2302 if (!EFI_ERROR (Status)) {
2303 //
2304 // Skip if the file system handle supports a BlkIo protocol, which we've handled in above
2305 //
2306 continue;
2307 }
2308
2309 Description = BmGetBootDescription (Handles[Index]);
2310 BootOptions = ReallocatePool (
2311 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
2312 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
2313 BootOptions
2314 );
2315 ASSERT (BootOptions != NULL);
2316
2318 &BootOptions[(*BootOptionCount)++],
2319 LoadOptionNumberUnassigned,
2320 LoadOptionTypeBoot,
2321 LOAD_OPTION_ACTIVE,
2322 Description,
2323 DevicePathFromHandle (Handles[Index]),
2324 NULL,
2325 0
2326 );
2327 ASSERT_EFI_ERROR (Status);
2328 FreePool (Description);
2329 }
2330
2331 if (HandleCount != 0) {
2332 FreePool (Handles);
2333 }
2334
2335 //
2336 // Parse load file protocol
2337 //
2338 gBS->LocateHandleBuffer (
2339 ByProtocol,
2340 &gEfiLoadFileProtocolGuid,
2341 NULL,
2342 &HandleCount,
2343 &Handles
2344 );
2345 for (Index = 0; Index < HandleCount; Index++) {
2346 //
2347 // Ignore BootManagerMenu. its boot option will be created by EfiBootManagerGetBootManagerMenu().
2348 //
2349 if (BmIsBootManagerMenuFilePath (DevicePathFromHandle (Handles[Index]))) {
2350 continue;
2351 }
2352
2353 Description = BmGetBootDescription (Handles[Index]);
2354 BootOptions = ReallocatePool (
2355 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
2356 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
2357 BootOptions
2358 );
2359 ASSERT (BootOptions != NULL);
2360
2362 &BootOptions[(*BootOptionCount)++],
2363 LoadOptionNumberUnassigned,
2364 LoadOptionTypeBoot,
2365 LOAD_OPTION_ACTIVE,
2366 Description,
2367 DevicePathFromHandle (Handles[Index]),
2368 NULL,
2369 0
2370 );
2371 ASSERT_EFI_ERROR (Status);
2372 FreePool (Description);
2373 }
2374
2375 if (HandleCount != 0) {
2376 FreePool (Handles);
2377 }
2378
2379 BmMakeBootOptionDescriptionUnique (BootOptions, *BootOptionCount);
2380 return BootOptions;
2381}
2382
2386VOID
2387EFIAPI
2389 VOID
2390 )
2391{
2392 EFI_STATUS Status;
2393 EFI_BOOT_MANAGER_LOAD_OPTION *NvBootOptions;
2394 UINTN NvBootOptionCount;
2395 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
2396 UINTN BootOptionCount;
2397 EFI_BOOT_MANAGER_LOAD_OPTION *UpdatedBootOptions;
2398 UINTN UpdatedBootOptionCount;
2399 UINTN Index;
2400 EDKII_PLATFORM_BOOT_MANAGER_PROTOCOL *PlatformBootManager;
2401
2402 //
2403 // Optionally refresh the legacy boot option
2404 //
2405 if (mBmRefreshLegacyBootOption != NULL) {
2406 mBmRefreshLegacyBootOption ();
2407 }
2408
2409 BootOptions = BmEnumerateBootOptions (&BootOptionCount);
2410
2411 //
2412 // Mark the boot option as added by BDS by setting OptionalData to a special GUID
2413 //
2414 for (Index = 0; Index < BootOptionCount; Index++) {
2415 BootOptions[Index].OptionalData = AllocateCopyPool (sizeof (EFI_GUID), &mBmAutoCreateBootOptionGuid);
2416 BootOptions[Index].OptionalDataSize = sizeof (EFI_GUID);
2417 }
2418
2419 //
2420 // Locate Platform Boot Options Protocol
2421 //
2422 Status = gBS->LocateProtocol (
2423 &gEdkiiPlatformBootManagerProtocolGuid,
2424 NULL,
2425 (VOID **)&PlatformBootManager
2426 );
2427 if (!EFI_ERROR (Status)) {
2428 //
2429 // If found, call platform specific refresh to all auto enumerated and NV
2430 // boot options.
2431 //
2432 Status = PlatformBootManager->RefreshAllBootOptions (
2433 (CONST EFI_BOOT_MANAGER_LOAD_OPTION *)BootOptions,
2434 (CONST UINTN)BootOptionCount,
2435 &UpdatedBootOptions,
2436 &UpdatedBootOptionCount
2437 );
2438 if (!EFI_ERROR (Status)) {
2439 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
2440 BootOptions = UpdatedBootOptions;
2441 BootOptionCount = UpdatedBootOptionCount;
2442 }
2443 }
2444
2445 NvBootOptions = EfiBootManagerGetLoadOptions (&NvBootOptionCount, LoadOptionTypeBoot);
2446
2447 //
2448 // Remove invalid EFI boot options from NV
2449 //
2450 for (Index = 0; Index < NvBootOptionCount; Index++) {
2451 if (((DevicePathType (NvBootOptions[Index].FilePath) != BBS_DEVICE_PATH) ||
2452 (DevicePathSubType (NvBootOptions[Index].FilePath) != BBS_BBS_DP)
2453 ) && BmIsAutoCreateBootOption (&NvBootOptions[Index])
2454 )
2455 {
2456 //
2457 // Only check those added by BDS
2458 // so that the boot options added by end-user or OS installer won't be deleted
2459 //
2460 if (EfiBootManagerFindLoadOption (&NvBootOptions[Index], BootOptions, BootOptionCount) == -1) {
2461 Status = EfiBootManagerDeleteLoadOptionVariable (NvBootOptions[Index].OptionNumber, LoadOptionTypeBoot);
2462 //
2463 // Deleting variable with current variable implementation shouldn't fail.
2464 //
2465 ASSERT_EFI_ERROR (Status);
2466 }
2467 }
2468 }
2469
2470 //
2471 // Add new EFI boot options to NV
2472 //
2473 for (Index = 0; Index < BootOptionCount; Index++) {
2474 if (EfiBootManagerFindLoadOption (&BootOptions[Index], NvBootOptions, NvBootOptionCount) == -1) {
2475 EfiBootManagerAddLoadOptionVariable (&BootOptions[Index], (UINTN)-1);
2476 //
2477 // Try best to add the boot options so continue upon failure.
2478 //
2479 }
2480 }
2481
2482 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
2483 EfiBootManagerFreeLoadOptions (NvBootOptions, NvBootOptionCount);
2484}
2485
2504 )
2505{
2506 EFI_STATUS Status;
2507 CHAR16 *Description;
2508 UINTN DescriptionLength;
2509 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
2510 UINTN HandleCount;
2511 EFI_HANDLE *Handles;
2512 UINTN Index;
2513
2514 DevicePath = NULL;
2515 Description = NULL;
2516 //
2517 // Try to find BootManagerMenu from LoadFile protocol
2518 //
2519 gBS->LocateHandleBuffer (
2520 ByProtocol,
2521 &gEfiLoadFileProtocolGuid,
2522 NULL,
2523 &HandleCount,
2524 &Handles
2525 );
2526 for (Index = 0; Index < HandleCount; Index++) {
2527 if (BmIsBootManagerMenuFilePath (DevicePathFromHandle (Handles[Index]))) {
2528 DevicePath = DuplicateDevicePath (DevicePathFromHandle (Handles[Index]));
2529 Description = BmGetBootDescription (Handles[Index]);
2530 break;
2531 }
2532 }
2533
2534 if (HandleCount != 0) {
2535 FreePool (Handles);
2536 }
2537
2538 if (DevicePath == NULL) {
2540 PcdGetPtr (PcdBootManagerMenuFile),
2542 0,
2543 &DevicePath
2544 );
2545 if (EFI_ERROR (Status)) {
2546 DEBUG ((DEBUG_WARN, "[Bds]BootManagerMenu FFS section can not be found, skip its boot option registration\n"));
2547 return EFI_NOT_FOUND;
2548 }
2549
2550 ASSERT (DevicePath != NULL);
2551 //
2552 // Get BootManagerMenu application's description from EFI User Interface Section.
2553 //
2554 Status = GetSectionFromAnyFv (
2555 PcdGetPtr (PcdBootManagerMenuFile),
2556 EFI_SECTION_USER_INTERFACE,
2557 0,
2558 (VOID **)&Description,
2559 &DescriptionLength
2560 );
2561 if (EFI_ERROR (Status)) {
2562 Description = NULL;
2563 }
2564 }
2565
2567 BootOption,
2568 LoadOptionNumberUnassigned,
2569 LoadOptionTypeBoot,
2570 LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN,
2571 (Description != NULL) ? Description : L"Boot Manager Menu",
2572 DevicePath,
2573 NULL,
2574 0
2575 );
2576 ASSERT_EFI_ERROR (Status);
2577 FreePool (DevicePath);
2578 if (Description != NULL) {
2579 FreePool (Description);
2580 }
2581
2582 DEBUG_CODE (
2583 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
2584 UINTN BootOptionCount;
2585
2586 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
2587 ASSERT (EfiBootManagerFindLoadOption (BootOption, BootOptions, BootOptionCount) == -1);
2588 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
2589 );
2590
2591 return EfiBootManagerAddLoadOptionVariable (BootOption, (UINTN)-1);
2592}
2593
2607EFIAPI
2610 )
2611{
2612 EFI_STATUS Status;
2613 UINTN BootOptionCount;
2614 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
2615 UINTN Index;
2616
2617 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
2618
2619 for (Index = 0; Index < BootOptionCount; Index++) {
2620 if (BmIsBootManagerMenuFilePath (BootOptions[Index].FilePath)) {
2622 BootOption,
2623 BootOptions[Index].OptionNumber,
2624 BootOptions[Index].OptionType,
2625 BootOptions[Index].Attributes,
2626 BootOptions[Index].Description,
2627 BootOptions[Index].FilePath,
2628 BootOptions[Index].OptionalData,
2629 BootOptions[Index].OptionalDataSize
2630 );
2631 ASSERT_EFI_ERROR (Status);
2632 break;
2633 }
2634 }
2635
2636 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
2637
2638 //
2639 // Automatically create the Boot#### for Boot Manager Menu when not found.
2640 //
2641 if (Index == BootOptionCount) {
2642 return BmRegisterBootManagerMenu (BootOption);
2643 } else {
2644 return EFI_SUCCESS;
2645 }
2646}
2647
2663EFIAPI
2665 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
2667 )
2668{
2669 return BmGetNextLoadOptionDevicePath (FilePath, FullPath);
2670}
UINT64 UINTN
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID * BmGetRamDiskMemoryInfo(IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath, OUT UINTN *RamDiskSizeInPages)
Definition: BmBoot.c:1346
EFI_DEVICE_PATH_PROTOCOL * BmExpandNetworkFileSystem(IN EFI_HANDLE LoadFileHandle, OUT EFI_HANDLE *RamDiskHandle)
Definition: BmBoot.c:1239
EFI_DEVICE_PATH_PROTOCOL * BmExpandFileDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath)
Definition: BmBoot.c:672
VOID EFIAPI EfiBootManagerBoot(IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
Definition: BmBoot.c:1846
EFI_HANDLE * BmFindUsbDevice(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINTN ParentDevicePathSize, OUT UINTN *UsbIoHandleCount)
Definition: BmBoot.c:514
VOID *EFIAPI EfiBootManagerGetLoadOptionBuffer(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, OUT UINTN *FileSize)
Definition: BmBoot.c:1607
BOOLEAN BmIsBootManagerMenuFilePath(EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: BmBoot.c:1760
VOID EFIAPI BmEndOfBdsPerfCode(IN EFI_EVENT Event, IN VOID *Context)
Definition: BmBoot.c:39
EFI_DEVICE_PATH_PROTOCOL * BmExpandUriDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath)
Definition: BmBoot.c:746
EFI_STATUS BmRegisterBootManagerMenu(OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
Definition: BmBoot.c:2502
EFI_DEVICE_PATH_PROTOCOL * BmExpandPartitionDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
Definition: BmBoot.c:872
EFI_DEVICE_PATH_PROTOCOL *EFIAPI EfiBootManagerGetNextLoadOptionDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath)
Definition: BmBoot.c:2664
VOID EFIAPI EfiBootManagerRefreshAllBootOption(VOID)
Definition: BmBoot.c:2388
BOOLEAN BmMatchUsbClass(IN EFI_USB_IO_PROTOCOL *UsbIo, IN USB_CLASS_DEVICE_PATH *UsbClass)
Definition: BmBoot.c:303
EFI_DEVICE_PATH_PROTOCOL * BmExpandUsbDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath, IN EFI_DEVICE_PATH_PROTOCOL *ShortformNode)
Definition: BmBoot.c:606
EFI_DEVICE_PATH_PROTOCOL * BmGetNextLoadOptionDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath)
Definition: BmBoot.c:1634
EFI_DEVICE_PATH_PROTOCOL * BmExpandLoadFiles(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
Definition: BmBoot.c:1534
VOID BmReportLoadFailure(IN UINT32 ErrorCode, IN EFI_STATUS FailureStatus)
Definition: BmBoot.c:1794
VOID EFIAPI EfiBootManagerRegisterLegacyBootSupport(EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION RefreshLegacyBootOption, EFI_BOOT_MANAGER_LEGACY_BOOT LegacyBoot)
Definition: BmBoot.c:60
EFI_BOOT_MANAGER_LOAD_OPTION * BmEnumerateBootOptions(UINTN *BootOptionCount)
Definition: BmBoot.c:2195
UINTN BmFindBootOptionInVariable(IN EFI_BOOT_MANAGER_LOAD_OPTION *OptionToFind)
Definition: BmBoot.c:101
EFI_DEVICE_PATH_PROTOCOL * BmGetRamDiskDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
Definition: BmBoot.c:1308
EFI_GUID mBmHardDriveBootVariableGuid
Definition: BmBoot.c:22
VOID BmDestroyRamDisk(IN EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath)
Definition: BmBoot.c:1385
BOOLEAN BmMatchUsbWwid(IN EFI_USB_IO_PROTOCOL *UsbIo, IN USB_WWID_DEVICE_PATH *UsbWwid)
Definition: BmBoot.c:395
EFI_DEVICE_PATH_PROTOCOL * BmAdjustFvFilePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
Definition: BmBoot.c:176
EFI_STATUS EFIAPI EfiBootManagerGetBootManagerMenu(EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
Definition: BmBoot.c:2608
BOOLEAN BmIsAutoCreateBootOption(EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
Definition: BmBoot.c:78
VOID BmCachePartitionDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL **CachedDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: BmBoot.c:807
EFI_DEVICE_PATH_PROTOCOL * BmExpandMediaDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath)
Definition: BmBoot.c:1072
BOOLEAN BmMatchPartitionDevicePathNode(IN EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath, IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath)
Definition: BmBoot.c:2134
EFI_DEVICE_PATH_PROTOCOL * BmExpandLoadFile(IN EFI_HANDLE LoadFileHandle, IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
Definition: BmBoot.c:1419
BOOLEAN BmMatchHttpBootDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *Left, IN EFI_DEVICE_PATH_PROTOCOL *Right)
Definition: BmBoot.c:1194
BOOLEAN BmIsFvFilePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: BmBoot.c:267
VOID BmMakeBootOptionDescriptionUnique(EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions, UINTN BootOptionCount)
CHAR16 * BmGetBootDescription(IN EFI_HANDLE Handle)
EFI_STATUS BmConnectUsbShortFormDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: BmConnect.c:245
VOID BmRepairAllControllers(UINTN ReconnectRepairCount)
VOID EFIAPI BmStopHotkeyService(IN EFI_EVENT Event, IN VOID *Context)
Definition: BmHotkey.c:850
VOID * BmGetNextLoadOptionBuffer(IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE Type, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, OUT UINTN *FileSize)
EFI_STATUS BmGetFreeOptionNumber(IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType, OUT UINT16 *FreeOptionNumber)
Definition: BmLoadOption.c:85
VOID BmSetMemoryTypeInformationVariable(IN BOOLEAN Boot)
Definition: BmMisc.c:129
EFI_STATUS BmSetVariableAndReportStatusCodeOnError(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
Definition: BmMisc.c:328
EFI_DEVICE_PATH_PROTOCOL * BmDelPartMatchInstance(IN EFI_DEVICE_PATH_PROTOCOL *Multi, IN EFI_DEVICE_PATH_PROTOCOL *Single)
Definition: BmMisc.c:26
BOOLEAN BmMatchDevicePaths(IN EFI_DEVICE_PATH_PROTOCOL *Multi, IN EFI_DEVICE_PATH_PROTOCOL *Single)
Definition: BmMisc.c:82
#define BBS_BBS_DP
Definition: DevicePath.h:1238
#define MSG_IPv6_DP
Definition: DevicePath.h:607
#define MSG_IPv4_DP
Definition: DevicePath.h:566
#define MEDIA_FILEPATH_DP
Definition: DevicePath.h:1098
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define MEDIA_RAM_DISK_DP
Definition: DevicePath.h:1205
#define MSG_URI_DP
Definition: DevicePath.h:879
#define BBS_DEVICE_PATH
Definition: DevicePath.h:1233
#define MEDIA_PIWG_FW_FILE_DP
Definition: DevicePath.h:1130
#define MEDIA_HARDDRIVE_DP
Definition: DevicePath.h:1014
#define MSG_DNS_DP
Definition: DevicePath.h:863
#define MSG_USB_WWID_DP
Definition: DevicePath.h:467
#define MSG_USB_CLASS_DP
Definition: DevicePath.h:434
#define HW_MEMMAP_DP
Definition: DevicePath.h:109
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI FileDevicePath(IN EFI_HANDLE Device OPTIONAL, IN CONST CHAR16 *FileName)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathValid(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINTN MaxSize)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathInstance(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI GetNextDevicePathInstance(IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT UINTN *Size)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
BOOLEAN EFIAPI IsDevicePathEndType(IN CONST VOID *Node)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
BOOLEAN EFIAPI ReportErrorCodeEnabled(VOID)
EFI_STATUS EFIAPI GetFileDevicePathFromAnyFv(IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT EFI_DEVICE_PATH_PROTOCOL **FvFileDevicePath)
EFI_STATUS EFIAPI GetSectionFromAnyFv(IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **Buffer, OUT UINTN *Size)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateReservedPages(IN UINTN Pages)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
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 OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
#define REPORT_STATUS_CODE_EX(Type, Value, Instance, CallerId, ExtendedDataGuid, ExtendedData, ExtendedDataSize)
#define REPORT_STATUS_CODE(Type, Value)
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
#define PERF_CODE(Expression)
#define PERF_START_EX(Handle, Token, Module, TimeStamp, Identifier)
#define PERF_CROSSMODULE_END(MeasurementString)
#define PERF_END_EX(Handle, Token, Module, TimeStamp, Identifier)
#define EFI_SECTION_PE32
#define EFI_ERROR_MINOR
Definition: PiStatusCode.h:58
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_GUID gEfiRamDiskProtocolGuid
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
GUID EFI_GUID
Definition: UefiBaseType.h:25
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI EfiBootManagerLoadOptionToVariable(IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
Definition: BmLoadOption.c:170
EFI_STATUS EFIAPI EfiBootManagerFreeLoadOption(IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
EFI_BOOT_MANAGER_LOAD_OPTION *EFIAPI EfiBootManagerGetLoadOptions(OUT UINTN *LoadOptionCount, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType)
VOID(EFIAPI * EFI_BOOT_MANAGER_LEGACY_BOOT)(IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
EFI_STATUS EFIAPI EfiBootManagerAddLoadOptionVariable(IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN Position)
Definition: BmLoadOption.c:367
EFI_STATUS EFIAPI EfiBootManagerFreeLoadOptions(IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions, IN UINTN LoadOptionCount)
EFI_STATUS EFIAPI EfiBootManagerVariableToLoadOption(IN CHAR16 *VariableName, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
Definition: BmLoadOption.c:998
VOID(EFIAPI * EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION)(VOID)
EFI_STATUS EFIAPI EfiBootManagerConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect, OUT EFI_HANDLE *MatchingHandle OPTIONAL)
Definition: BmConnect.c:108
INTN EFIAPI EfiBootManagerFindLoadOption(IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key, IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array, IN UINTN Count)
Definition: BmLoadOption.c:548
EFI_STATUS EFIAPI EfiBootManagerDeleteLoadOptionVariable(IN UINTN OptionNumber, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType)
Definition: BmLoadOption.c:584
VOID EFIAPI EfiBootManagerConnectAll(VOID)
Definition: BmConnect.c:67
EFI_STATUS EFIAPI EfiBootManagerInitializeLoadOption(IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN OptionNumber, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType, IN UINT32 Attributes, IN CHAR16 *Description, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN UINT8 *OptionalData, IN UINT32 OptionalDataSize)
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiCreateEventLegacyBootEx(IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *LegacyBootEvent)
Definition: UefiNotTiano.c:68
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
VOID EFIAPI EfiSignalEventReadyToBoot(VOID)
Definition: UefiNotTiano.c:219
EFI_GUID *EFIAPI EfiGetNameGuidFromFwVolDevicePathNode(IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode)
Definition: UefiNotTiano.c:292
#define EFI_VARIABLE_NON_VOLATILE
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:224
BOOLEAN RemovableMedia
Definition: BlockIo.h:137
UINT32 BlockSize
Definition: BlockIo.h:167
VOID * LoadOptions
A pointer to the image's binary load options.
Definition: LoadedImage.h:62
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:53
UINT32 LoadOptionsSize
The size in bytes of LoadOptions.
Definition: LoadedImage.h:61
Definition: Base.h:213