diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-03-05 20:00:15 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-03-06 16:11:29 +0000 |
commit | c4471e3408d85c51a69991974985fe283d869eac (patch) | |
tree | c3e24fa6bb2386dbbcf19993e26dc8ba1b29b685 /src/interface/efi/efi_path.c | |
parent | 636ccb4ca55c73841e634f9d5986087fb3565da4 (diff) | |
download | ipxe-c4471e3408d85c51a69991974985fe283d869eac.tar.gz |
[efi] Add efi_path_guid() utility function
EFI provides no API for determining the partition GUID (if any) for a
specified device handle. The partition GUID appears to be exposed
only as part of the device path.
Add efi_path_guid() to extract the partition GUID (if any) from a
device path.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/efi/efi_path.c')
-rw-r--r-- | src/interface/efi/efi_path.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/interface/efi/efi_path.c b/src/interface/efi/efi_path.c index a78f97fce..d1e22eeaa 100644 --- a/src/interface/efi/efi_path.c +++ b/src/interface/efi/efi_path.c @@ -22,9 +22,11 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stdlib.h> #include <stdarg.h> #include <string.h> +#include <errno.h> #include <byteswap.h> #include <ipxe/netdevice.h> #include <ipxe/vlan.h> +#include <ipxe/uuid.h> #include <ipxe/tcpip.h> #include <ipxe/uri.h> #include <ipxe/iscsi.h> @@ -133,6 +135,47 @@ unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path ) { } /** + * Get partition GUID from device path + * + * @v path Device path + * @v guid Partition GUID to fill in + * @ret rc Return status code + */ +int efi_path_guid ( EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid ) { + EFI_DEVICE_PATH_PROTOCOL *next; + HARDDRIVE_DEVICE_PATH *hd; + int rc; + + /* Search for most specific partition device path */ + rc = -ENOENT; + for ( ; ( next = efi_path_next ( path ) ) ; path = next ) { + + /* Skip non-harddrive device paths */ + if ( path->Type != MEDIA_DEVICE_PATH ) + continue; + if ( path->SubType != MEDIA_HARDDRIVE_DP ) + continue; + + /* Skip non-GUID signatures */ + hd = container_of ( path, HARDDRIVE_DEVICE_PATH, Header ); + if ( hd->SignatureType != SIGNATURE_TYPE_GUID ) + continue; + + /* Extract GUID */ + memcpy ( guid, hd->Signature, sizeof ( *guid ) ); + uuid_mangle ( guid ); + + /* Record success, but continue searching in case + * there exists a more specific GUID (e.g. a partition + * GUID rather than a disk GUID). + */ + rc = 0; + } + + return rc; +} + +/** * Concatenate EFI device paths * * @v ... List of device paths (NULL terminated) |