3 * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsInternal.h"
17 #include <Library/NetLib.h>
19 #include <Protocol/BlockIo.h>
20 #include <Protocol/DevicePathToText.h>
21 #include <Protocol/FirmwareVolumeBlock.h>
22 #include <Protocol/PxeBaseCode.h>
23 #include <Protocol/SimpleFileSystem.h>
24 #include <Protocol/SimpleNetwork.h>
25 #include <Protocol/Dhcp4.h>
26 #include <Protocol/Mtftp4.h>
28 #include <Guid/FileSystemInfo.h>
30 #define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
33 BdsLoadOptionFileSystemList (
34 IN OUT LIST_ENTRY
* BdsLoadOptionList
38 BdsLoadOptionFileSystemCreateDevicePath (
40 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
44 BdsLoadOptionFileSystemUpdateDevicePath (
45 IN EFI_DEVICE_PATH
*OldDevicePath
,
47 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
51 BdsLoadOptionFileSystemIsSupported (
52 IN EFI_DEVICE_PATH
*DevicePath
56 BdsLoadOptionMemMapList (
57 IN OUT LIST_ENTRY
* BdsLoadOptionList
61 BdsLoadOptionMemMapCreateDevicePath (
63 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
67 BdsLoadOptionMemMapUpdateDevicePath (
68 IN EFI_DEVICE_PATH
*OldDevicePath
,
70 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
74 BdsLoadOptionMemMapIsSupported (
75 IN EFI_DEVICE_PATH
*DevicePath
79 BdsLoadOptionPxeList (
80 IN OUT LIST_ENTRY
* BdsLoadOptionList
84 BdsLoadOptionPxeCreateDevicePath (
86 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
90 BdsLoadOptionPxeUpdateDevicePath (
91 IN EFI_DEVICE_PATH
*OldDevicePath
,
93 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
97 BdsLoadOptionPxeIsSupported (
98 IN EFI_DEVICE_PATH
*DevicePath
102 BdsLoadOptionTftpList (
103 IN OUT LIST_ENTRY
* BdsLoadOptionList
107 BdsLoadOptionTftpCreateDevicePath (
109 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
113 BdsLoadOptionTftpUpdateDevicePath (
114 IN EFI_DEVICE_PATH
*OldDevicePath
,
116 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
120 BdsLoadOptionTftpIsSupported (
121 IN EFI_DEVICE_PATH
*DevicePath
124 BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList
[] = {
126 BDS_DEVICE_FILESYSTEM
,
127 BdsLoadOptionFileSystemList
,
128 BdsLoadOptionFileSystemIsSupported
,
129 BdsLoadOptionFileSystemCreateDevicePath
,
130 BdsLoadOptionFileSystemUpdateDevicePath
,
135 BdsLoadOptionMemMapList
,
136 BdsLoadOptionMemMapIsSupported
,
137 BdsLoadOptionMemMapCreateDevicePath
,
138 BdsLoadOptionMemMapUpdateDevicePath
,
143 BdsLoadOptionPxeList
,
144 BdsLoadOptionPxeIsSupported
,
145 BdsLoadOptionPxeCreateDevicePath
,
146 BdsLoadOptionPxeUpdateDevicePath
,
151 BdsLoadOptionTftpList
,
152 BdsLoadOptionTftpIsSupported
,
153 BdsLoadOptionTftpCreateDevicePath
,
154 BdsLoadOptionTftpUpdateDevicePath
,
160 BootDeviceListSupportedInit (
161 IN OUT LIST_ENTRY
*SupportedDeviceList
166 // Initialize list of supported devices
167 InitializeListHead (SupportedDeviceList
);
169 for (Index
= 0; Index
< BDS_DEVICE_MAX
; Index
++) {
170 BdsLoadOptionSupportList
[Index
].ListDevices (SupportedDeviceList
);
177 BootDeviceListSupportedFree (
178 IN LIST_ENTRY
*SupportedDeviceList
,
179 IN BDS_SUPPORTED_DEVICE
*Except
183 BDS_SUPPORTED_DEVICE
* SupportedDevice
;
185 Entry
= GetFirstNode (SupportedDeviceList
);
186 while (Entry
!= SupportedDeviceList
) {
187 SupportedDevice
= SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry
);
188 Entry
= RemoveEntryList (Entry
);
189 if (SupportedDevice
!= Except
) {
190 FreePool (SupportedDevice
);
198 BootDeviceGetDeviceSupport (
199 IN EFI_DEVICE_PATH
*DevicePath
,
200 OUT BDS_LOAD_OPTION_SUPPORT
**DeviceSupport
205 // Find which supported device is the most appropriate
206 for (Index
= 0; Index
< BDS_DEVICE_MAX
; Index
++) {
207 if (BdsLoadOptionSupportList
[Index
].IsSupported (DevicePath
)) {
208 *DeviceSupport
= &BdsLoadOptionSupportList
[Index
];
213 return EFI_UNSUPPORTED
;
218 IN EFI_DEVICE_PATH
* DevicePath
,
219 OUT ARM_BDS_LOADER_TYPE
*BootType
,
220 OUT UINT32
*Attributes
225 BOOLEAN IsBootLoader
;
226 BOOLEAN HasFDTSupport
;
228 EFI_DEVICE_PATH
* PrevDevicePathNode
;
229 EFI_DEVICE_PATH
* DevicePathNode
;
230 EFI_PHYSICAL_ADDRESS Image
;
232 EFI_IMAGE_DOS_HEADER
* DosHeader
;
233 UINTN PeCoffHeaderOffset
;
234 EFI_IMAGE_NT_HEADERS32
* NtHeader
;
237 // Check if the last node of the device path is a FilePath node
239 PrevDevicePathNode
= NULL
;
240 DevicePathNode
= DevicePath
;
241 while ((DevicePathNode
!= NULL
) && !IsDevicePathEnd (DevicePathNode
)) {
242 PrevDevicePathNode
= DevicePathNode
;
243 DevicePathNode
= NextDevicePathNode (DevicePathNode
);
246 if ((PrevDevicePathNode
!= NULL
) &&
247 (PrevDevicePathNode
->Type
== MEDIA_DEVICE_PATH
) &&
248 (PrevDevicePathNode
->SubType
== MEDIA_FILEPATH_DP
))
250 FileName
= ((FILEPATH_DEVICE_PATH
*)PrevDevicePathNode
)->PathName
;
255 if (FileName
== NULL
) {
256 Print(L
"Is an EFI Application? ");
257 Status
= GetHIInputBoolean (&IsEfiApp
);
258 if (EFI_ERROR(Status
)) {
261 } else if (HasFilePathEfiExtension(FileName
)) {
264 // Check if the file exist
265 Status
= BdsLoadImage (DevicePath
, AllocateAnyPages
, &Image
, &FileSize
);
266 if (!EFI_ERROR (Status
)) {
268 DosHeader
= (EFI_IMAGE_DOS_HEADER
*)(UINTN
) Image
;
269 if (DosHeader
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
271 // DOS image header is present,
272 // so read the PE header after the DOS image header.
274 PeCoffHeaderOffset
= DosHeader
->e_lfanew
;
276 PeCoffHeaderOffset
= 0;
280 // Check PE/COFF image.
282 NtHeader
= (EFI_IMAGE_NT_HEADERS32
*)(UINTN
) (Image
+ PeCoffHeaderOffset
);
283 if (NtHeader
->Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
290 gBS
->FreePages (Image
, EFI_SIZE_TO_PAGES(FileSize
));
292 // If we did not manage to open it then ask for the type
293 Print(L
"Is an EFI Application? ");
294 Status
= GetHIInputBoolean (&IsEfiApp
);
295 if (EFI_ERROR(Status
)) {
302 Print(L
"Is your application an OS loader? ");
303 Status
= GetHIInputBoolean (&IsBootLoader
);
304 if (EFI_ERROR(Status
)) {
308 *Attributes
|= LOAD_OPTION_CATEGORY_APP
;
310 *BootType
= BDS_LOADER_EFI_APPLICATION
;
312 Print(L
"Has FDT support? ");
313 Status
= GetHIInputBoolean (&HasFDTSupport
);
314 if (EFI_ERROR(Status
)) {
318 *BootType
= BDS_LOADER_KERNEL_LINUX_FDT
;
320 *BootType
= BDS_LOADER_KERNEL_LINUX_ATAG
;
328 BdsLoadOptionFileSystemList (
329 IN OUT LIST_ENTRY
* BdsLoadOptionList
334 EFI_HANDLE
*HandleBuffer
;
336 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
337 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
* FileProtocol
;
340 EFI_FILE_SYSTEM_INFO
* FsInfo
;
341 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
343 // List all the Simple File System Protocols
344 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiSimpleFileSystemProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
345 if (EFI_ERROR (Status
)) {
349 for (Index
= 0; Index
< HandleCount
; Index
++) {
350 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
351 if (!EFI_ERROR(Status
)) {
352 // Allocate BDS Supported Device structure
353 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE
));
356 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)&FileProtocol
);
357 ASSERT_EFI_ERROR(Status
);
359 FileProtocol
->OpenVolume (FileProtocol
, &Fs
);
361 // Generate a Description from the file system
364 Status
= Fs
->GetInfo (Fs
, &gEfiFileSystemInfoGuid
, &Size
, FsInfo
);
365 if (Status
== EFI_BUFFER_TOO_SMALL
) {
366 FsInfo
= AllocatePool (Size
);
367 Status
= Fs
->GetInfo (Fs
, &gEfiFileSystemInfoGuid
, &Size
, FsInfo
);
369 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"%s (%d MB)",FsInfo
->VolumeLabel
,(UINT32
)(FsInfo
->VolumeSize
/ (1024 * 1024)));
373 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
374 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_FILESYSTEM
];
376 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
384 BdsLoadOptionFileSystemCreateDevicePath (
386 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
390 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
391 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
392 UINTN BootFilePathSize
;
394 Print(L
"File path of the %s: ", FileName
);
395 Status
= GetHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
396 if (EFI_ERROR(Status
)) {
400 BootFilePathSize
= StrSize (BootFilePath
);
401 if (BootFilePathSize
== 2) {
402 *DevicePathNodes
= NULL
;
403 return EFI_NOT_FOUND
;
406 // Create the FilePath Device Path node
407 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
+ END_DEVICE_PATH_LENGTH
);
408 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
409 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
410 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
411 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
412 SetDevicePathEndNode ((VOID
*)((UINTN
)FilePathDevicePath
+ SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
));
413 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*)FilePathDevicePath
;
419 BdsLoadOptionFileSystemUpdateDevicePath (
420 IN EFI_DEVICE_PATH
*OldDevicePath
,
422 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
426 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
427 UINTN BootFilePathSize
;
428 FILEPATH_DEVICE_PATH
* EndingDevicePath
;
429 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
430 EFI_DEVICE_PATH
* DevicePath
;
432 DevicePath
= DuplicateDevicePath (OldDevicePath
);
434 EndingDevicePath
= (FILEPATH_DEVICE_PATH
*)GetLastDevicePathNode (DevicePath
);
436 Print(L
"File path of the %s: ", FileName
);
437 StrnCpy (BootFilePath
, EndingDevicePath
->PathName
, BOOT_DEVICE_FILEPATH_MAX
);
438 Status
= EditHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
439 if (EFI_ERROR(Status
)) {
443 BootFilePathSize
= StrSize(BootFilePath
);
444 if (BootFilePathSize
== 2) {
445 *NewDevicePath
= NULL
;
446 return EFI_NOT_FOUND
;
449 // Create the FilePath Device Path node
450 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
451 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
452 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
453 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
454 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
456 // Generate the new Device Path by replacing the last node by the updated node
457 SetDevicePathEndNode (EndingDevicePath
);
458 *NewDevicePath
= AppendDevicePathNode (DevicePath
, (CONST EFI_DEVICE_PATH_PROTOCOL
*)FilePathDevicePath
);
459 FreePool(DevicePath
);
465 Check if a boot option path is a file system boot option path or not.
467 The device specified by the beginning of the path has to support the Simple File
468 System protocol. Furthermore, the remaining part of the path has to be composed of
469 a single node of type MEDIA_DEVICE_PATH and sub-type MEDIA_FILEPATH_DP.
471 @param[in] DevicePath Complete device path of a boot option.
473 @retval FALSE The boot option path has not been identified as that of a
474 file system boot option.
475 @retval TRUE The boot option path is a file system boot option.
478 BdsLoadOptionFileSystemIsSupported (
479 IN EFI_DEVICE_PATH
*DevicePath
484 EFI_DEVICE_PATH
*RemainingDevicePath
;
485 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*FileProtocol
;
487 Status
= BdsConnectDevicePath (DevicePath
, &Handle
, &RemainingDevicePath
);
488 if (EFI_ERROR (Status
)) {
492 Status
= gBS
->HandleProtocol (
494 &gEfiSimpleFileSystemProtocolGuid
,
495 (VOID
**)(&FileProtocol
)
497 if (EFI_ERROR (Status
)) {
501 if (!IS_DEVICE_PATH_NODE (RemainingDevicePath
, MEDIA_DEVICE_PATH
, MEDIA_FILEPATH_DP
))
510 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
511 IN EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
517 ParentSize
= GetDevicePathSize (ParentDevicePath
);
518 ChildSize
= GetDevicePathSize (ChildDevicePath
);
520 if (ParentSize
> ChildSize
) {
524 if (CompareMem (ParentDevicePath
, ChildDevicePath
, ParentSize
- END_DEVICE_PATH_LENGTH
) != 0) {
532 BdsLoadOptionMemMapList (
533 IN OUT LIST_ENTRY
* BdsLoadOptionList
538 EFI_HANDLE
*HandleBuffer
;
539 UINTN DevicePathHandleCount
;
540 EFI_HANDLE
*DevicePathHandleBuffer
;
544 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
545 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
546 EFI_DEVICE_PATH
* DevicePath
;
547 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*FileProtocol
;
548 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvbProtocol
;
550 // List all the BlockIo Protocols
551 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
552 if (EFI_ERROR (Status
)) {
556 for (Index
= 0; Index
< HandleCount
; Index
++) {
557 // We only select handles WITH a Device Path AND not part of Media (to
558 // avoid duplication with HardDisk, CDROM, etc). Skip handles used by
559 // Simple Filesystem or used for Variable Storage.
562 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
],
563 &gEfiSimpleFileSystemProtocolGuid
,
564 (VOID
*)&FileProtocol
);
565 if (!EFI_ERROR(Status
)) {
566 // SimpleFilesystem supported on this handle, skip
570 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
],
571 &gEfiFirmwareVolumeBlockProtocolGuid
,
572 (VOID
*)&FvbProtocol
);
573 if (!EFI_ERROR(Status
)) {
574 // Firmware Volme Block / Variable storage supported on this handle, skip
578 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
],
579 &gEfiFirmwareVolumeBlock2ProtocolGuid
,
580 (VOID
*)&FvbProtocol
);
581 if (!EFI_ERROR(Status
)) {
582 // Firmware Volme Block / Variable storage supported on this handle, skip
586 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
587 if (!EFI_ERROR(Status
)) {
588 // BlockIo is not part of Media Device Path
589 DevicePath
= DevicePathProtocol
;
590 while (!IsDevicePathEndType (DevicePath
) && (DevicePathType (DevicePath
) != MEDIA_DEVICE_PATH
)) {
591 DevicePath
= NextDevicePathNode (DevicePath
);
593 if (DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) {
597 // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child
598 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiDevicePathProtocolGuid
, NULL
, &DevicePathHandleCount
, &DevicePathHandleBuffer
);
599 ASSERT_EFI_ERROR (Status
);
601 for (Index2
= 0; (Index2
< DevicePathHandleCount
) && !IsParent
; Index2
++) {
602 if (HandleBuffer
[Index
] != DevicePathHandleBuffer
[Index2
]) {
603 gBS
->HandleProtocol (DevicePathHandleBuffer
[Index2
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePath
);
604 if (IsParentDevicePath (DevicePathProtocol
, DevicePath
)) {
613 // Allocate BDS Supported Device structure
614 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
616 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], SupportedDevice
->Description
);
617 ASSERT_EFI_ERROR (Status
);
619 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
620 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_MEMMAP
];
622 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
630 BdsLoadOptionMemMapCreateDevicePath (
632 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
636 MEMMAP_DEVICE_PATH
*MemMapDevicePath
;
637 CHAR16 StrStartingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
638 CHAR16 StrEndingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
640 Print(L
"Starting Address of the %s: ", FileName
);
641 Status
= GetHIInputStr (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
642 if (EFI_ERROR(Status
)) {
646 Print(L
"Ending Address of the %s: ", FileName
);
647 Status
= GetHIInputStr (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
648 if (EFI_ERROR(Status
)) {
652 // Create the MemMap Device Path Node
653 MemMapDevicePath
= (MEMMAP_DEVICE_PATH
*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH
) + END_DEVICE_PATH_LENGTH
);
654 MemMapDevicePath
->Header
.Type
= HARDWARE_DEVICE_PATH
;
655 MemMapDevicePath
->Header
.SubType
= HW_MEMMAP_DP
;
656 SetDevicePathNodeLength (MemMapDevicePath
, sizeof(MEMMAP_DEVICE_PATH
));
657 MemMapDevicePath
->MemoryType
= EfiBootServicesData
;
658 MemMapDevicePath
->StartingAddress
= StrHexToUint64 (StrStartingAddress
);
659 MemMapDevicePath
->EndingAddress
= StrHexToUint64 (StrEndingAddress
);
661 // Set a Device Path End Node after the Memory Map Device Path Node
662 SetDevicePathEndNode (MemMapDevicePath
+ 1);
663 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*)MemMapDevicePath
;
669 BdsLoadOptionMemMapUpdateDevicePath (
670 IN EFI_DEVICE_PATH
*OldDevicePath
,
672 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
676 CHAR16 StrStartingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
677 CHAR16 StrEndingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
678 MEMMAP_DEVICE_PATH
* EndingDevicePath
;
679 EFI_DEVICE_PATH
* DevicePath
;
681 DevicePath
= DuplicateDevicePath (OldDevicePath
);
682 EndingDevicePath
= (MEMMAP_DEVICE_PATH
*)GetLastDevicePathNode (DevicePath
);
684 Print(L
"Starting Address of the %s: ", FileName
);
685 UnicodeSPrint (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
, L
"0x%X", (UINTN
)EndingDevicePath
->StartingAddress
);
686 Status
= EditHIInputStr (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
687 if (EFI_ERROR(Status
)) {
691 Print(L
"Ending Address of the %s: ", FileName
);
692 UnicodeSPrint (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
, L
"0x%X", (UINTN
)EndingDevicePath
->EndingAddress
);
693 Status
= EditHIInputStr (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
694 if (EFI_ERROR(Status
)) {
698 EndingDevicePath
->StartingAddress
= StrHexToUint64 (StrStartingAddress
);
699 EndingDevicePath
->EndingAddress
= StrHexToUint64 (StrEndingAddress
);
701 if (EFI_ERROR(Status
)) {
702 FreePool(DevicePath
);
704 *NewDevicePath
= DevicePath
;
711 Check if a boot option path is a memory map boot option path or not.
713 The device specified by the beginning of the path has to support the BlockIo
714 protocol. Furthermore, the remaining part of the path has to be composed of
715 a single node of type HARDWARE_DEVICE_PATH and sub-type HW_MEMMAP_DP.
717 @param[in] DevicePath Complete device path of a boot option.
719 @retval FALSE The boot option path has not been identified as that of a
720 memory map boot option.
721 @retval TRUE The boot option path is a a memory map boot option.
724 BdsLoadOptionMemMapIsSupported (
725 IN EFI_DEVICE_PATH
*DevicePath
730 EFI_DEVICE_PATH
*RemainingDevicePath
;
731 EFI_BLOCK_IO_PROTOCOL
*BlockIoProtocol
;
733 Status
= BdsConnectDevicePath (DevicePath
, &Handle
, &RemainingDevicePath
);
734 if (EFI_ERROR (Status
)) {
738 Status
= gBS
->HandleProtocol (
740 &gEfiBlockIoProtocolGuid
,
741 (VOID
**)(&BlockIoProtocol
)
743 if (EFI_ERROR (Status
)) {
747 if (!IS_DEVICE_PATH_NODE (RemainingDevicePath
, HARDWARE_DEVICE_PATH
, HW_MEMMAP_DP
))
754 BdsLoadOptionPxeList (
755 IN OUT LIST_ENTRY
* BdsLoadOptionList
760 EFI_HANDLE
*HandleBuffer
;
762 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
763 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
764 EFI_SIMPLE_NETWORK_PROTOCOL
* SimpleNet
;
765 CHAR16 DeviceDescription
[BOOT_DEVICE_DESCRIPTION_MAX
];
766 EFI_MAC_ADDRESS
*Mac
;
768 // List all the PXE Protocols
769 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiPxeBaseCodeProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
770 if (EFI_ERROR (Status
)) {
774 for (Index
= 0; Index
< HandleCount
; Index
++) {
775 // We only select the handle WITH a Device Path AND the PXE Protocol
776 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
777 if (!EFI_ERROR(Status
)) {
778 // Allocate BDS Supported Device structure
779 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
781 Status
= gBS
->LocateProtocol (&gEfiSimpleNetworkProtocolGuid
, NULL
, (VOID
**)&SimpleNet
);
782 if (!EFI_ERROR(Status
)) {
783 Mac
= &SimpleNet
->Mode
->CurrentAddress
;
784 UnicodeSPrint (DeviceDescription
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac
->Addr
[0], Mac
->Addr
[1], Mac
->Addr
[2], Mac
->Addr
[3], Mac
->Addr
[4], Mac
->Addr
[5]);
786 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], DeviceDescription
);
787 ASSERT_EFI_ERROR (Status
);
789 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"PXE on %s",DeviceDescription
);
791 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
792 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_PXE
];
794 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
802 BdsLoadOptionPxeCreateDevicePath (
804 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
807 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*) AllocatePool (END_DEVICE_PATH_LENGTH
);
808 SetDevicePathEndNode (*DevicePathNodes
);
814 Update the parameters of a Pxe boot option
816 @param[in] OldDevicePath Current complete device path of the Pxe boot option.
817 This has to be a valid complete Pxe boot option path.
818 @param[in] FileName Description of the file the path is asked for
819 @param[out] NewDevicePath Pointer to the new complete device path.
821 @retval EFI_SUCCESS Update completed
822 @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource
825 BdsLoadOptionPxeUpdateDevicePath (
826 IN EFI_DEVICE_PATH
*OldDevicePath
,
828 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
832 // Make a copy of the complete device path that is made of :
833 // the device path of the device supporting the Pxe base code protocol
834 // followed by an end node.
836 *NewDevicePath
= DuplicateDevicePath (OldDevicePath
);
837 if (*NewDevicePath
== NULL
) {
838 return EFI_OUT_OF_RESOURCES
;
845 BdsLoadOptionPxeIsSupported (
846 IN EFI_DEVICE_PATH
*DevicePath
851 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
852 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBcProtocol
;
854 Status
= BdsConnectDevicePath (DevicePath
, &Handle
, &RemainingDevicePath
);
855 if (EFI_ERROR(Status
)) {
859 if (!IsDevicePathEnd(RemainingDevicePath
)) {
863 Status
= gBS
->HandleProtocol (Handle
, &gEfiPxeBaseCodeProtocolGuid
, (VOID
**)&PxeBcProtocol
);
864 if (EFI_ERROR (Status
)) {
872 Add to the list of boot devices the devices allowing a TFTP boot
874 @param[in] BdsLoadOptionList List of devices to boot from
876 @retval EFI_SUCCESS Update completed
877 @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource
880 BdsLoadOptionTftpList (
881 IN OUT LIST_ENTRY
* BdsLoadOptionList
886 EFI_HANDLE
*HandleBuffer
;
889 EFI_DEVICE_PATH_PROTOCOL
*DevicePathProtocol
;
891 EFI_SIMPLE_NETWORK_PROTOCOL
*SimpleNetworkProtocol
;
892 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
893 EFI_MAC_ADDRESS
*Mac
;
896 // List all the handles on which the Simple Network Protocol is installed.
898 Status
= gBS
->LocateHandleBuffer (
900 &gEfiSimpleNetworkProtocolGuid
,
905 if (EFI_ERROR (Status
)) {
909 for (Index
= 0; Index
< HandleCount
; Index
++) {
910 Handle
= HandleBuffer
[Index
];
912 // We select the handles that support :
913 // . the Device Path Protocol
914 // . the MTFTP4 Protocol
916 Status
= gBS
->HandleProtocol (
918 &gEfiDevicePathProtocolGuid
,
919 (VOID
**)&DevicePathProtocol
921 if (EFI_ERROR (Status
)) {
925 Status
= gBS
->HandleProtocol (
927 &gEfiMtftp4ServiceBindingProtocolGuid
,
930 if (EFI_ERROR (Status
)) {
934 Status
= gBS
->HandleProtocol (
936 &gEfiSimpleNetworkProtocolGuid
,
937 (VOID
**)&SimpleNetworkProtocol
939 if (EFI_ERROR (Status
)) {
943 // Allocate BDS Supported Device structure
944 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE
));
945 if (SupportedDevice
== NULL
) {
949 Mac
= &SimpleNetworkProtocol
->Mode
->CurrentAddress
;
951 SupportedDevice
->Description
,
952 BOOT_DEVICE_DESCRIPTION_MAX
,
953 L
"TFTP on MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
954 Mac
->Addr
[0], Mac
->Addr
[1], Mac
->Addr
[2], Mac
->Addr
[3], Mac
->Addr
[4], Mac
->Addr
[5]
957 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
958 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_TFTP
];
960 InsertTailList (BdsLoadOptionList
, &SupportedDevice
->Link
);
967 BdsLoadOptionTftpCreateDevicePath (
969 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
974 EFI_IP_ADDRESS LocalIp
;
975 EFI_IP_ADDRESS SubnetMask
;
976 EFI_IP_ADDRESS GatewayIp
;
977 EFI_IP_ADDRESS RemoteIp
;
978 IPv4_DEVICE_PATH
*IPv4DevicePathNode
;
979 FILEPATH_DEVICE_PATH
*FilePathDevicePath
;
980 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
981 UINTN BootFilePathSize
;
983 Print (L
"Get the IP address from DHCP: ");
984 Status
= GetHIInputBoolean (&IsDHCP
);
985 if (EFI_ERROR (Status
)) {
990 Print (L
"Local static IP address: ");
991 Status
= GetHIInputIP (&LocalIp
);
992 if (EFI_ERROR (Status
)) {
995 Print (L
"Get the network mask: ");
996 Status
= GetHIInputIP (&SubnetMask
);
997 if (EFI_ERROR (Status
)) {
1000 Print (L
"Get the gateway IP address: ");
1001 Status
= GetHIInputIP (&GatewayIp
);
1002 if (EFI_ERROR (Status
)) {
1007 Print (L
"Get the TFTP server IP address: ");
1008 Status
= GetHIInputIP (&RemoteIp
);
1009 if (EFI_ERROR (Status
)) {
1013 Print (L
"File path of the %s : ", FileName
);
1014 Status
= GetHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
1015 if (EFI_ERROR (Status
)) {
1019 BootFilePathSize
= StrSize(BootFilePath
);
1020 if (BootFilePathSize
== 2) {
1021 return EFI_NOT_FOUND
;
1024 // Allocate the memory for the IPv4 + File Path Device Path Nodes
1025 IPv4DevicePathNode
= (IPv4_DEVICE_PATH
*)AllocatePool(sizeof(IPv4_DEVICE_PATH
) + SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
+ END_DEVICE_PATH_LENGTH
);
1027 // Create the IPv4 Device Path
1028 IPv4DevicePathNode
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1029 IPv4DevicePathNode
->Header
.SubType
= MSG_IPv4_DP
;
1030 SetDevicePathNodeLength (&IPv4DevicePathNode
->Header
, sizeof(IPv4_DEVICE_PATH
));
1033 CopyMem (&IPv4DevicePathNode
->LocalIpAddress
, &LocalIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1034 CopyMem (&IPv4DevicePathNode
->SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1035 CopyMem (&IPv4DevicePathNode
->GatewayIpAddress
, &GatewayIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1038 CopyMem (&IPv4DevicePathNode
->RemoteIpAddress
, &RemoteIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1039 IPv4DevicePathNode
->LocalPort
= 0;
1040 IPv4DevicePathNode
->RemotePort
= 0;
1041 IPv4DevicePathNode
->Protocol
= EFI_IP_PROTO_TCP
;
1042 IPv4DevicePathNode
->StaticIpAddress
= (IsDHCP
!= TRUE
);
1044 // Create the FilePath Device Path node
1045 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)(IPv4DevicePathNode
+ 1);
1046 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
1047 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
1048 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
1049 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
1051 // Set the End Device Path Node
1052 SetDevicePathEndNode ((VOID
*)((UINTN
)FilePathDevicePath
+ SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
));
1053 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*)IPv4DevicePathNode
;
1059 Update the parameters of a TFTP boot option
1061 The function asks sequentially to update the IPv4 parameters as well as the boot file path,
1062 providing the previously set value if any.
1064 @param[in] OldDevicePath Current complete device path of the Tftp boot option.
1065 This has to be a valid complete Tftp boot option path.
1066 By complete, we mean that it is not only the Tftp
1067 specific end part built by the
1068 "BdsLoadOptionTftpCreateDevicePath()" function.
1069 This path is handled as read only.
1070 @param[in] FileName Description of the file the path is asked for
1071 @param[out] NewDevicePath Pointer to the new complete device path.
1073 @retval EFI_SUCCESS Update completed
1074 @retval EFI_ABORTED Update aborted by the user
1075 @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource
1078 BdsLoadOptionTftpUpdateDevicePath (
1079 IN EFI_DEVICE_PATH
*OldDevicePath
,
1080 IN CHAR16
*FileName
,
1081 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
1085 EFI_DEVICE_PATH
*DevicePath
;
1086 EFI_DEVICE_PATH
*DevicePathNode
;
1088 IPv4_DEVICE_PATH Ipv4Node
;
1090 EFI_IP_ADDRESS OldIp
;
1091 EFI_IP_ADDRESS OldSubnetMask
;
1092 EFI_IP_ADDRESS OldGatewayIp
;
1093 EFI_IP_ADDRESS LocalIp
;
1094 EFI_IP_ADDRESS SubnetMask
;
1095 EFI_IP_ADDRESS GatewayIp
;
1096 EFI_IP_ADDRESS RemoteIp
;
1098 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
1100 UINTN BootFilePathSize
;
1101 FILEPATH_DEVICE_PATH
*NewFilePathNode
;
1106 // Make a copy of the complete device path that is made of :
1107 // the device path of the device that support the Simple Network protocol
1108 // followed by an IPv4 node (type IPv4_DEVICE_PATH),
1109 // followed by a file path node (type FILEPATH_DEVICE_PATH) and ended up
1110 // by an end node. The IPv6 case is not handled yet.
1113 DevicePath
= DuplicateDevicePath (OldDevicePath
);
1114 if (DevicePath
== NULL
) {
1115 Status
= EFI_OUT_OF_RESOURCES
;
1120 // Because of the check done by "BdsLoadOptionTftpIsSupported()" prior to the
1121 // call to this function, we know that the device path ends with an IPv4 node
1122 // followed by a file path node and finally an end node. To get the address of
1123 // the last IPv4 node, we loop over the whole device path, noting down the
1124 // address of each encountered IPv4 node.
1127 for (DevicePathNode
= DevicePath
;
1128 !IsDevicePathEnd (DevicePathNode
);
1129 DevicePathNode
= NextDevicePathNode (DevicePathNode
))
1131 if (IS_DEVICE_PATH_NODE (DevicePathNode
, MESSAGING_DEVICE_PATH
, MSG_IPv4_DP
)) {
1132 Ipv4NodePtr
= (UINT8
*)DevicePathNode
;
1136 // Copy for alignment of the IPv4 node data
1137 CopyMem (&Ipv4Node
, Ipv4NodePtr
, sizeof (IPv4_DEVICE_PATH
));
1139 Print (L
"Get the IP address from DHCP: ");
1140 Status
= GetHIInputBoolean (&IsDHCP
);
1141 if (EFI_ERROR (Status
)) {
1146 Print (L
"Local static IP address: ");
1147 if (Ipv4Node
.StaticIpAddress
) {
1148 CopyMem (&OldIp
.v4
, &Ipv4Node
.LocalIpAddress
, sizeof (EFI_IPv4_ADDRESS
));
1149 Status
= EditHIInputIP (&OldIp
, &LocalIp
);
1151 Status
= GetHIInputIP (&LocalIp
);
1153 if (EFI_ERROR (Status
)) {
1157 Print (L
"Get the network mask: ");
1158 if (Ipv4Node
.StaticIpAddress
) {
1159 CopyMem (&OldSubnetMask
.v4
, &Ipv4Node
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
1160 Status
= EditHIInputIP (&OldSubnetMask
, &SubnetMask
);
1162 Status
= GetHIInputIP (&SubnetMask
);
1164 if (EFI_ERROR (Status
)) {
1168 Print (L
"Get the gateway IP address: ");
1169 if (Ipv4Node
.StaticIpAddress
) {
1170 CopyMem (&OldGatewayIp
.v4
, &Ipv4Node
.GatewayIpAddress
, sizeof (EFI_IPv4_ADDRESS
));
1171 Status
= EditHIInputIP (&OldGatewayIp
, &GatewayIp
);
1173 Status
= GetHIInputIP (&GatewayIp
);
1175 if (EFI_ERROR (Status
)) {
1180 Print (L
"TFTP server IP address: ");
1181 // Copy remote IPv4 address into IPv4 or IPv6 union
1182 CopyMem (&OldIp
.v4
, &Ipv4Node
.RemoteIpAddress
, sizeof (EFI_IPv4_ADDRESS
));
1184 Status
= EditHIInputIP (&OldIp
, &RemoteIp
);
1185 if (EFI_ERROR (Status
)) {
1189 // Get the path of the boot file and its size in number of bytes
1190 FileNodePtr
= Ipv4NodePtr
+ sizeof (IPv4_DEVICE_PATH
);
1191 BootFilePathSize
= DevicePathNodeLength (FileNodePtr
) - SIZE_OF_FILEPATH_DEVICE_PATH
;
1194 // Ask for update of the boot file path
1197 // Copy for 2-byte alignment of the Unicode string
1199 BootFilePath
, FileNodePtr
+ SIZE_OF_FILEPATH_DEVICE_PATH
,
1200 MIN (BootFilePathSize
, BOOT_DEVICE_FILEPATH_MAX
)
1202 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
- 1] = L
'\0';
1204 Print (L
"File path of the %s: ", FileName
);
1205 Status
= EditHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
1206 if (EFI_ERROR (Status
)) {
1209 PathSize
= StrSize (BootFilePath
);
1213 // Empty string, give the user another try
1214 Print (L
"Empty string - Invalid path\n");
1215 } while (PathSize
<= 2) ;
1218 // Update the IPv4 node. IPv6 case not handled yet.
1221 Ipv4Node
.StaticIpAddress
= FALSE
;
1222 ZeroMem (&Ipv4Node
.LocalIpAddress
, sizeof (EFI_IPv4_ADDRESS
));
1223 ZeroMem (&Ipv4Node
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
1224 ZeroMem (&Ipv4Node
.GatewayIpAddress
, sizeof (EFI_IPv4_ADDRESS
));
1226 Ipv4Node
.StaticIpAddress
= TRUE
;
1227 CopyMem (&Ipv4Node
.LocalIpAddress
, &LocalIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1228 CopyMem (&Ipv4Node
.SubnetMask
, &SubnetMask
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1229 CopyMem (&Ipv4Node
.GatewayIpAddress
, &GatewayIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1232 CopyMem (&Ipv4Node
.RemoteIpAddress
, &RemoteIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
1233 CopyMem (Ipv4NodePtr
, &Ipv4Node
, sizeof (IPv4_DEVICE_PATH
));
1236 // Create the new file path node
1238 NewFilePathNode
= (FILEPATH_DEVICE_PATH
*)AllocatePool (
1239 SIZE_OF_FILEPATH_DEVICE_PATH
+
1242 NewFilePathNode
->Header
.Type
= MEDIA_DEVICE_PATH
;
1243 NewFilePathNode
->Header
.SubType
= MEDIA_FILEPATH_DP
;
1244 SetDevicePathNodeLength (
1246 SIZE_OF_FILEPATH_DEVICE_PATH
+ PathSize
1248 CopyMem (NewFilePathNode
->PathName
, BootFilePath
, PathSize
);
1251 // Generate the new Device Path by replacing the file path node at address
1252 // "FileNodePtr" by the new one "NewFilePathNode" and return its address.
1254 SetDevicePathEndNode (FileNodePtr
);
1255 *NewDevicePath
= AppendDevicePathNode (
1257 (CONST EFI_DEVICE_PATH_PROTOCOL
*)NewFilePathNode
1261 if (DevicePath
!= NULL
) {
1262 FreePool (DevicePath
) ;
1269 BdsLoadOptionTftpIsSupported (
1270 IN EFI_DEVICE_PATH
*DevicePath
1275 EFI_DEVICE_PATH
*RemainingDevicePath
;
1276 EFI_DEVICE_PATH
*NextDevicePath
;
1277 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBcProtocol
;
1279 Status
= BdsConnectDevicePath (DevicePath
, &Handle
, &RemainingDevicePath
);
1280 if (EFI_ERROR(Status
)) {
1284 // Validate the Remaining Device Path
1285 if (IsDevicePathEnd(RemainingDevicePath
)) {
1288 if (!IS_DEVICE_PATH_NODE(RemainingDevicePath
,MESSAGING_DEVICE_PATH
,MSG_IPv4_DP
) &&
1289 !IS_DEVICE_PATH_NODE(RemainingDevicePath
,MESSAGING_DEVICE_PATH
,MSG_IPv6_DP
)) {
1292 NextDevicePath
= NextDevicePathNode (RemainingDevicePath
);
1293 if (IsDevicePathEnd(NextDevicePath
)) {
1296 if (!IS_DEVICE_PATH_NODE(NextDevicePath
,MEDIA_DEVICE_PATH
,MEDIA_FILEPATH_DP
)) {
1300 Status
= gBS
->HandleProtocol (Handle
, &gEfiPxeBaseCodeProtocolGuid
, (VOID
**)&PxeBcProtocol
);
1301 if (EFI_ERROR (Status
)) {