Skip to content

Commit a7d321b

Browse files
authored
Merge pull request #1316 from nicholasbishop/bishop-locate-dp
boot: Add freestanding locate_device_path
2 parents cf9cadb + f707849 commit a7d321b

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

uefi-test-runner/src/proto/device_path.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use alloc::string::ToString;
22
use alloc::vec::Vec;
3+
use uefi::boot;
34
use uefi::prelude::*;
45
use uefi::proto::device_path::text::*;
56
use uefi::proto::device_path::{DevicePath, LoadedImageDevicePath};
67
use uefi::proto::loaded_image::LoadedImage;
8+
use uefi::proto::media::disk::DiskIo;
79

810
pub fn test(bt: &BootServices) {
911
info!("Running device path protocol test");
@@ -64,6 +66,10 @@ pub fn test(bt: &BootServices) {
6466
{
6567
assert_eq!(n1, n2);
6668
}
69+
70+
// Test `locate_device_path`.
71+
let mut dp = &*device_path;
72+
boot::locate_device_path::<DiskIo>(&mut dp).unwrap();
6773
}
6874

6975
// test 2/2: test high-level to-string api

uefi/src/boot.rs

+34
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,40 @@ pub fn protocols_per_handle(handle: Handle) -> Result<ProtocolsPerHandle> {
633633
})
634634
}
635635

636+
/// Locates the handle of a device on the device path that supports the specified protocol.
637+
///
638+
/// The `device_path` is updated to point at the remaining part of the [`DevicePath`] after
639+
/// the part that matched the protocol. For example, it can be used with a device path
640+
/// that contains a file path to strip off the file system portion of the device path,
641+
/// leaving the file path and handle to the file system driver needed to access the file.
642+
///
643+
/// If the first node of `device_path` matches the protocol, the `device_path`
644+
/// is advanced to the device path terminator node. If `device_path` is a
645+
/// multi-instance device path, the function will operate on the first instance.
646+
///
647+
/// # Errors
648+
///
649+
/// * [`Status::NOT_FOUND`]: no matching handles.
650+
pub fn locate_device_path<P: ProtocolPointer + ?Sized>(
651+
device_path: &mut &DevicePath,
652+
) -> Result<Handle> {
653+
let bt = boot_services_raw_panicking();
654+
let bt = unsafe { bt.as_ref() };
655+
656+
let mut handle = ptr::null_mut();
657+
let mut device_path_ptr: *const uefi_raw::protocol::device_path::DevicePathProtocol =
658+
device_path.as_ffi_ptr().cast();
659+
unsafe {
660+
(bt.locate_device_path)(&P::GUID, &mut device_path_ptr, &mut handle).to_result_with_val(
661+
|| {
662+
*device_path = DevicePath::from_ffi_ptr(device_path_ptr.cast());
663+
// OK to unwrap: handle is non-null for Status::SUCCESS.
664+
Handle::from_ptr(handle).unwrap()
665+
},
666+
)
667+
}
668+
}
669+
636670
/// Returns an array of handles that support the requested protocol in a
637671
/// pool-allocated buffer.
638672
///

0 commit comments

Comments
 (0)