|
|
/*++
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; }
|