0,0 → 1,1035 |
/*++ |
|
Copyright (c) 1998 Intel Corporation |
|
Module Name: |
|
dpath.c |
|
Abstract: |
MBR & Device Path functions |
|
|
|
Revision History |
|
--*/ |
|
#include "lib.h" |
|
#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) |
|
|
|
EFI_DEVICE_PATH * |
DevicePathFromHandle ( |
IN EFI_HANDLE Handle |
) |
{ |
EFI_STATUS Status; |
EFI_DEVICE_PATH *DevicePath; |
|
Status = BS->HandleProtocol (Handle, &DevicePathProtocol, (VOID*)&DevicePath); |
if (EFI_ERROR(Status)) { |
DevicePath = NULL; |
} |
|
return DevicePath; |
} |
|
|
EFI_DEVICE_PATH * |
DevicePathInstance ( |
IN OUT EFI_DEVICE_PATH **DevicePath, |
OUT UINTN *Size |
) |
{ |
EFI_DEVICE_PATH *Start, *Next, *DevPath; |
UINTN Count; |
|
DevPath = *DevicePath; |
Start = DevPath; |
|
if (!DevPath) { |
return NULL; |
} |
|
// |
// Check for end of device path type |
// |
|
for (Count = 0; ; Count++) { |
Next = NextDevicePathNode(DevPath); |
|
if (IsDevicePathEndType(DevPath)) { |
break; |
} |
|
if (Count > 01000) { |
// |
// BugBug: Debug code to catch bogus device paths |
// |
DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) )); |
DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start); |
break; |
} |
|
DevPath = Next; |
} |
|
ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || |
DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE); |
|
// |
// Set next position |
// |
|
if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { |
Next = NULL; |
} |
|
*DevicePath = Next; |
|
// |
// Return size and start of device path instance |
// |
|
*Size = ((UINT8 *) DevPath) - ((UINT8 *) Start); |
return Start; |
} |
|
UINTN |
DevicePathInstanceCount ( |
IN EFI_DEVICE_PATH *DevicePath |
) |
{ |
UINTN Count, Size; |
|
Count = 0; |
while (DevicePathInstance(&DevicePath, &Size)) { |
Count += 1; |
} |
|
return Count; |
} |
|
|
EFI_DEVICE_PATH * |
AppendDevicePath ( |
IN EFI_DEVICE_PATH *Src1, |
IN EFI_DEVICE_PATH *Src2 |
) |
// Src1 may have multiple "instances" and each instance is appended |
// Src2 is appended to each instance is Src1. (E.g., it's possible |
// to append a new instance to the complete device path by passing |
// it in Src2) |
{ |
UINTN Src1Size, Src1Inst, Src2Size, Size; |
EFI_DEVICE_PATH *Dst, *Inst; |
UINT8 *DstPos; |
|
// |
// If there's only 1 path, just duplicate it |
// |
|
if (!Src1) { |
ASSERT (!IsDevicePathUnpacked (Src2)); |
return DuplicateDevicePath (Src2); |
} |
|
if (!Src2) { |
ASSERT (!IsDevicePathUnpacked (Src1)); |
return DuplicateDevicePath (Src1); |
} |
|
// |
// Verify we're not working with unpacked paths |
// |
|
// ASSERT (!IsDevicePathUnpacked (Src1)); |
// ASSERT (!IsDevicePathUnpacked (Src2)); |
|
// |
// Append Src2 to every instance in Src1 |
// |
|
Src1Size = DevicePathSize(Src1); |
Src1Inst = DevicePathInstanceCount(Src1); |
Src2Size = DevicePathSize(Src2); |
Size = Src1Size * Src1Inst + Src2Size; |
|
Dst = AllocatePool (Size); |
if (Dst) { |
DstPos = (UINT8 *) Dst; |
|
// |
// Copy all device path instances |
// |
|
while ((Inst = DevicePathInstance (&Src1, &Size))) { |
|
CopyMem(DstPos, Inst, Size); |
DstPos += Size; |
|
CopyMem(DstPos, Src2, Src2Size); |
DstPos += Src2Size; |
|
CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH)); |
DstPos += sizeof(EFI_DEVICE_PATH); |
} |
|
// Change last end marker |
DstPos -= sizeof(EFI_DEVICE_PATH); |
CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH)); |
} |
|
return Dst; |
} |
|
|
EFI_DEVICE_PATH * |
AppendDevicePathNode ( |
IN EFI_DEVICE_PATH *Src1, |
IN EFI_DEVICE_PATH *Src2 |
) |
// Src1 may have multiple "instances" and each instance is appended |
// Src2 is a signal device path node (without a terminator) that is |
// appended to each instance is Src1. |
{ |
EFI_DEVICE_PATH *Temp, *Eop; |
UINTN Length; |
|
// |
// Build a Src2 that has a terminator on it |
// |
|
Length = DevicePathNodeLength(Src2); |
Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH)); |
if (!Temp) { |
return NULL; |
} |
|
CopyMem (Temp, Src2, Length); |
Eop = NextDevicePathNode(Temp); |
SetDevicePathEndNode(Eop); |
|
// |
// Append device paths |
// |
|
Src1 = AppendDevicePath (Src1, Temp); |
FreePool (Temp); |
return Src1; |
} |
|
|
EFI_DEVICE_PATH * |
FileDevicePath ( |
IN EFI_HANDLE Device OPTIONAL, |
IN CHAR16 *FileName |
) |
/*++ |
|
N.B. Results are allocated from pool. The caller must FreePool |
the resulting device path structure |
|
--*/ |
{ |
UINTN Size; |
FILEPATH_DEVICE_PATH *FilePath; |
EFI_DEVICE_PATH *Eop, *DevicePath; |
|
Size = StrSize(FileName); |
FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); |
DevicePath = NULL; |
|
if (FilePath) { |
|
// |
// Build a file path |
// |
|
FilePath->Header.Type = MEDIA_DEVICE_PATH; |
FilePath->Header.SubType = MEDIA_FILEPATH_DP; |
SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); |
CopyMem (FilePath->PathName, FileName, Size); |
Eop = NextDevicePathNode(&FilePath->Header); |
SetDevicePathEndNode(Eop); |
|
// |
// Append file path to device's device path |
// |
|
DevicePath = (EFI_DEVICE_PATH *) FilePath; |
if (Device) { |
DevicePath = AppendDevicePath ( |
DevicePathFromHandle(Device), |
DevicePath |
); |
|
FreePool(FilePath); |
} |
} |
|
return DevicePath; |
} |
|
|
|
UINTN |
DevicePathSize ( |
IN EFI_DEVICE_PATH *DevPath |
) |
{ |
EFI_DEVICE_PATH *Start; |
|
// |
// Search for the end of the device path structure |
// |
|
Start = DevPath; |
while (!IsDevicePathEnd(DevPath)) { |
DevPath = NextDevicePathNode(DevPath); |
} |
|
// |
// Compute the size |
// |
|
return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH); |
} |
|
EFI_DEVICE_PATH * |
DuplicateDevicePath ( |
IN EFI_DEVICE_PATH *DevPath |
) |
{ |
EFI_DEVICE_PATH *NewDevPath; |
UINTN Size; |
|
|
// |
// Compute the size |
// |
|
Size = DevicePathSize (DevPath); |
|
// |
// Make a copy |
// |
|
NewDevPath = AllocatePool (Size); |
if (NewDevPath) { |
CopyMem (NewDevPath, DevPath, Size); |
} |
|
return NewDevPath; |
} |
|
EFI_DEVICE_PATH * |
UnpackDevicePath ( |
IN EFI_DEVICE_PATH *DevPath |
) |
{ |
EFI_DEVICE_PATH *Src, *Dest, *NewPath; |
UINTN Size; |
|
// |
// Walk device path and round sizes to valid boundries |
// |
|
Src = DevPath; |
Size = 0; |
for (; ;) { |
Size += DevicePathNodeLength(Src); |
Size += ALIGN_SIZE(Size); |
|
if (IsDevicePathEnd(Src)) { |
break; |
} |
|
Src = NextDevicePathNode(Src); |
} |
|
|
// |
// Allocate space for the unpacked path |
// |
|
NewPath = AllocateZeroPool (Size); |
if (NewPath) { |
|
ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0); |
|
// |
// Copy each node |
// |
|
Src = DevPath; |
Dest = NewPath; |
for (; ;) { |
Size = DevicePathNodeLength(Src); |
CopyMem (Dest, Src, Size); |
Size += ALIGN_SIZE(Size); |
SetDevicePathNodeLength (Dest, Size); |
Dest->Type |= EFI_DP_TYPE_UNPACKED; |
Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size); |
|
if (IsDevicePathEnd(Src)) { |
break; |
} |
|
Src = NextDevicePathNode(Src); |
} |
} |
|
return NewPath; |
} |
|
|
EFI_DEVICE_PATH* |
AppendDevicePathInstance ( |
IN EFI_DEVICE_PATH *Src, |
IN EFI_DEVICE_PATH *Instance |
) |
{ |
UINT8 *Ptr; |
EFI_DEVICE_PATH *DevPath; |
UINTN SrcSize; |
UINTN InstanceSize; |
|
if (Src == NULL) { |
return DuplicateDevicePath (Instance); |
} |
SrcSize = DevicePathSize(Src); |
InstanceSize = DevicePathSize(Instance); |
Ptr = AllocatePool (SrcSize + InstanceSize); |
DevPath = (EFI_DEVICE_PATH *)Ptr; |
ASSERT(DevPath); |
|
CopyMem (Ptr, Src, SrcSize); |
// FreePool (Src); |
|
while (!IsDevicePathEnd(DevPath)) { |
DevPath = NextDevicePathNode(DevPath); |
} |
// |
// Convert the End to an End Instance, since we are |
// appending another instacne after this one its a good |
// idea. |
// |
DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; |
|
DevPath = NextDevicePathNode(DevPath); |
CopyMem (DevPath, Instance, InstanceSize); |
return (EFI_DEVICE_PATH *)Ptr; |
} |
|
EFI_STATUS |
LibDevicePathToInterface ( |
IN EFI_GUID *Protocol, |
IN EFI_DEVICE_PATH *FilePath, |
OUT VOID **Interface |
) |
{ |
EFI_STATUS Status; |
EFI_HANDLE Device; |
|
Status = BS->LocateDevicePath (Protocol, &FilePath, &Device); |
|
if (!EFI_ERROR(Status)) { |
|
// If we didn't get a direct match return not found |
Status = EFI_NOT_FOUND; |
|
if (IsDevicePathEnd(FilePath)) { |
|
// |
// It was a direct match, lookup the protocol interface |
// |
|
Status = BS->HandleProtocol (Device, Protocol, Interface); |
} |
} |
|
// |
// If there was an error, do not return an interface |
// |
|
if (EFI_ERROR(Status)) { |
*Interface = NULL; |
} |
|
return Status; |
} |
|
VOID |
_DevPathPci ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
PCI_DEVICE_PATH *Pci; |
|
Pci = DevPath; |
CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function); |
} |
|
VOID |
_DevPathPccard ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
PCCARD_DEVICE_PATH *Pccard; |
|
Pccard = DevPath; |
CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber); |
} |
|
VOID |
_DevPathMemMap ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
MEMMAP_DEVICE_PATH *MemMap; |
|
MemMap = DevPath; |
CatPrint(Str, L"MemMap(%d:%x-%x)", |
MemMap->MemoryType, |
MemMap->StartingAddress, |
MemMap->EndingAddress |
); |
} |
|
VOID |
_DevPathController ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
CONTROLLER_DEVICE_PATH *Controller; |
|
Controller = DevPath; |
CatPrint(Str, L"Ctrl(%d)", |
Controller->Controller |
); |
} |
|
VOID |
_DevPathVendor ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
VENDOR_DEVICE_PATH *Vendor; |
CHAR16 *Type; |
UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath; |
|
Vendor = DevPath; |
switch (DevicePathType(&Vendor->Header)) { |
case HARDWARE_DEVICE_PATH: Type = L"Hw"; break; |
case MESSAGING_DEVICE_PATH: Type = L"Msg"; break; |
case MEDIA_DEVICE_PATH: Type = L"Media"; break; |
default: Type = L"?"; break; |
} |
|
CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid); |
if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) { |
// |
// GUID used by EFI to enumerate an EDD 1.1 device |
// |
UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor; |
CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter); |
} else { |
CatPrint(Str, L")"); |
} |
} |
|
|
VOID |
_DevPathAcpi ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
ACPI_HID_DEVICE_PATH *Acpi; |
|
Acpi = DevPath; |
if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { |
CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID); |
} else { |
CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID); |
} |
} |
|
|
VOID |
_DevPathAtapi ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
ATAPI_DEVICE_PATH *Atapi; |
|
Atapi = DevPath; |
CatPrint(Str, L"Ata(%s,%s)", |
Atapi->PrimarySecondary ? L"Secondary" : L"Primary", |
Atapi->SlaveMaster ? L"Slave" : L"Master" |
); |
} |
|
VOID |
_DevPathScsi ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
SCSI_DEVICE_PATH *Scsi; |
|
Scsi = DevPath; |
CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun); |
} |
|
|
VOID |
_DevPathFibre ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
FIBRECHANNEL_DEVICE_PATH *Fibre; |
|
Fibre = DevPath; |
CatPrint(Str, L"Fibre(%lx)", Fibre->WWN); |
} |
|
VOID |
_DevPath1394 ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
F1394_DEVICE_PATH *F1394; |
|
F1394 = DevPath; |
CatPrint(Str, L"1394(%g)", &F1394->Guid); |
} |
|
|
|
VOID |
_DevPathUsb ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
USB_DEVICE_PATH *Usb; |
|
Usb = DevPath; |
CatPrint(Str, L"Usb(%x)", Usb->Port); |
} |
|
|
VOID |
_DevPathI2O ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
I2O_DEVICE_PATH *I2O; |
|
I2O = DevPath; |
CatPrint(Str, L"I2O(%x)", I2O->Tid); |
} |
|
VOID |
_DevPathMacAddr ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
MAC_ADDR_DEVICE_PATH *MAC; |
UINTN HwAddressSize; |
UINTN Index; |
|
MAC = DevPath; |
|
HwAddressSize = sizeof(EFI_MAC_ADDRESS); |
if (MAC->IfType == 0x01 || MAC->IfType == 0x00) { |
HwAddressSize = 6; |
} |
|
CatPrint(Str, L"Mac("); |
|
for(Index = 0; Index < HwAddressSize; Index++) { |
CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]); |
} |
CatPrint(Str, L")"); |
} |
|
VOID |
_DevPathIPv4 ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
IPv4_DEVICE_PATH *IP; |
|
IP = DevPath; |
CatPrint(Str, L"IPv4(not-done)"); |
} |
|
VOID |
_DevPathIPv6 ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
IPv6_DEVICE_PATH *IP; |
|
IP = DevPath; |
CatPrint(Str, L"IP-v6(not-done)"); |
} |
|
VOID |
_DevPathInfiniBand ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
INFINIBAND_DEVICE_PATH *InfiniBand; |
|
InfiniBand = DevPath; |
CatPrint(Str, L"InfiniBand(not-done)"); |
} |
|
VOID |
_DevPathUart ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
UART_DEVICE_PATH *Uart; |
CHAR8 Parity; |
|
Uart = DevPath; |
switch (Uart->Parity) { |
case 0 : Parity = 'D'; break; |
case 1 : Parity = 'N'; break; |
case 2 : Parity = 'E'; break; |
case 3 : Parity = 'O'; break; |
case 4 : Parity = 'M'; break; |
case 5 : Parity = 'S'; break; |
default : Parity = 'x'; break; |
} |
|
if (Uart->BaudRate == 0) { |
CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity); |
} else { |
CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity); |
} |
|
if (Uart->DataBits == 0) { |
CatPrint(Str, L"D"); |
} else { |
CatPrint(Str, L"%d",Uart->DataBits); |
} |
|
switch (Uart->StopBits) { |
case 0 : CatPrint(Str, L"D)"); break; |
case 1 : CatPrint(Str, L"1)"); break; |
case 2 : CatPrint(Str, L"1.5)"); break; |
case 3 : CatPrint(Str, L"2)"); break; |
default : CatPrint(Str, L"x)"); break; |
} |
} |
|
|
VOID |
_DevPathHardDrive ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
HARDDRIVE_DEVICE_PATH *Hd; |
|
Hd = DevPath; |
switch (Hd->SignatureType) { |
case SIGNATURE_TYPE_MBR: |
CatPrint(Str, L"HD(Part%d,Sig%08X)", |
Hd->PartitionNumber, |
*((UINT32 *)(&(Hd->Signature[0]))) |
); |
break; |
case SIGNATURE_TYPE_GUID: |
CatPrint(Str, L"HD(Part%d,Sig%g)", |
Hd->PartitionNumber, |
(EFI_GUID *) &(Hd->Signature[0]) |
); |
break; |
default: |
CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)", |
Hd->PartitionNumber, |
Hd->MBRType, |
Hd->SignatureType |
); |
break; |
} |
} |
|
VOID |
_DevPathCDROM ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
CDROM_DEVICE_PATH *Cd; |
|
Cd = DevPath; |
CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry); |
} |
|
VOID |
_DevPathFilePath ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
FILEPATH_DEVICE_PATH *Fp; |
|
Fp = DevPath; |
CatPrint(Str, L"%s", Fp->PathName); |
} |
|
VOID |
_DevPathMediaProtocol ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
MEDIA_PROTOCOL_DEVICE_PATH *MediaProt; |
|
MediaProt = DevPath; |
CatPrint(Str, L"%g", &MediaProt->Protocol); |
} |
|
VOID |
_DevPathBssBss ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
BBS_BBS_DEVICE_PATH *Bss; |
CHAR16 *Type; |
|
Bss = DevPath; |
switch (Bss->DeviceType) { |
case BBS_TYPE_FLOPPY: Type = L"Floppy"; break; |
case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break; |
case BBS_TYPE_CDROM: Type = L"CDROM"; break; |
case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break; |
case BBS_TYPE_USB: Type = L"Usb"; break; |
case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break; |
default: Type = L"?"; break; |
} |
|
CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String); |
} |
|
|
VOID |
_DevPathEndInstance ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
CatPrint(Str, L","); |
} |
|
VOID |
_DevPathNodeUnknown ( |
IN OUT POOL_PRINT *Str, |
IN VOID *DevPath |
) |
{ |
CatPrint(Str, L"?"); |
} |
|
|
struct { |
UINT8 Type; |
UINT8 SubType; |
VOID (*Function)(POOL_PRINT *, VOID *); |
} DevPathTable[] = { |
{ HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, |
{ HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, |
{ HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, |
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor}, |
{ HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController}, |
{ ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi}, |
{ MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi}, |
{ MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi}, |
{ MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre}, |
{ MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394}, |
{ MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb}, |
{ MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O}, |
{ MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr}, |
{ MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4}, |
{ MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6}, |
{ MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand}, |
{ MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart}, |
{ MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor}, |
{ MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive}, |
{ MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM}, |
{ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor}, |
{ MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath}, |
{ MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol}, |
{ BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss}, |
{ END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance}, |
{ 0, 0, NULL} |
}; |
|
|
CHAR16 * |
DevicePathToStr ( |
EFI_DEVICE_PATH *DevPath |
) |
/*++ |
|
Turns the Device Path into a printable string. Allcoates |
the string from pool. The caller must FreePool the returned |
string. |
|
--*/ |
{ |
POOL_PRINT Str; |
EFI_DEVICE_PATH *DevPathNode; |
VOID (*DumpNode)(POOL_PRINT *, VOID *); |
UINTN Index, NewSize; |
|
ZeroMem(&Str, sizeof(Str)); |
|
// |
// Unpacked the device path |
// |
|
DevPath = UnpackDevicePath(DevPath); |
ASSERT (DevPath); |
|
|
// |
// Process each device path node |
// |
|
DevPathNode = DevPath; |
while (!IsDevicePathEnd(DevPathNode)) { |
// |
// Find the handler to dump this device path node |
// |
|
DumpNode = NULL; |
for (Index = 0; DevPathTable[Index].Function; Index += 1) { |
|
if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && |
DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { |
DumpNode = DevPathTable[Index].Function; |
break; |
} |
} |
|
// |
// If not found, use a generic function |
// |
|
if (!DumpNode) { |
DumpNode = _DevPathNodeUnknown; |
} |
|
// |
// Put a path seperator in if needed |
// |
|
if (Str.len && DumpNode != _DevPathEndInstance) { |
CatPrint (&Str, L"/"); |
} |
|
// |
// Print this node of the device path |
// |
|
DumpNode (&Str, DevPathNode); |
|
// |
// Next device path node |
// |
|
DevPathNode = NextDevicePathNode(DevPathNode); |
} |
|
// |
// Shrink pool used for string allocation |
// |
|
FreePool (DevPath); |
NewSize = (Str.len + 1) * sizeof(CHAR16); |
Str.str = ReallocatePool (Str.str, NewSize, NewSize); |
Str.str[Str.len] = 0; |
return Str.str; |
} |
|
BOOLEAN |
LibMatchDevicePaths ( |
IN EFI_DEVICE_PATH *Multi, |
IN EFI_DEVICE_PATH *Single |
) |
{ |
EFI_DEVICE_PATH *DevicePath, *DevicePathInst; |
UINTN Size; |
|
if (!Multi || !Single) { |
return FALSE; |
} |
|
DevicePath = Multi; |
while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) { |
if (CompareMem (Single, DevicePathInst, Size) == 0) { |
return TRUE; |
} |
} |
return FALSE; |
} |
|
EFI_DEVICE_PATH * |
LibDuplicateDevicePathInstance ( |
IN EFI_DEVICE_PATH *DevPath |
) |
{ |
EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp; |
UINTN Size; |
|
// |
// get the size of an instance from the input |
// |
|
Temp = DevPath; |
DevicePathInst = DevicePathInstance (&Temp, &Size); |
|
// |
// Make a copy and set proper end type |
// |
NewDevPath = NULL; |
if (Size) { |
NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH)); |
} |
|
if (NewDevPath) { |
CopyMem (NewDevPath, DevicePathInst, Size); |
Temp = NextDevicePathNode(NewDevPath); |
SetDevicePathEndNode(Temp); |
} |
|
return NewDevPath; |
} |
|