Skip to content

Commit 22616fb

Browse files
authored
Merge pull request #1314 from nicholasbishop/bishop-get-handle-for-proto
boot: Add freestanding get_handle_for_protocol
2 parents 09d1645 + a8e77f3 commit 22616fb

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

uefi-test-runner/src/main.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,9 @@ fn reconnect_serial_to_console(serial_handle: Handle) {
167167
/// Send the `request` string to the host via the `serial` device, then
168168
/// wait up to 10 seconds to receive a reply. Returns an error if the
169169
/// reply is not `"OK\n"`.
170-
fn send_request_to_host(bt: &BootServices, request: HostRequest) {
171-
let serial_handle = bt
172-
.get_handle_for_protocol::<Serial>()
173-
.expect("Failed to get serial handle");
170+
fn send_request_to_host(request: HostRequest) {
171+
let serial_handle =
172+
uefi::boot::get_handle_for_protocol::<Serial>().expect("Failed to get serial handle");
174173

175174
// Open the serial protocol in exclusive mode.
176175
//
@@ -183,8 +182,7 @@ fn send_request_to_host(bt: &BootServices, request: HostRequest) {
183182
// end with `connect_controller`.
184183
//
185184
// [console splitter driver]: https://github.com/tianocore/edk2/blob/HEAD/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
186-
let mut serial = bt
187-
.open_protocol_exclusive::<Serial>(serial_handle)
185+
let mut serial = uefi::boot::open_protocol_exclusive::<Serial>(serial_handle)
188186
.expect("Could not open serial protocol");
189187

190188
// Send the request, but don't check the result yet so that first
@@ -211,7 +209,7 @@ fn shutdown(mut st: SystemTable<Boot>) -> ! {
211209
// Tell the host that tests are done. We are about to exit boot
212210
// services, so we can't easily communicate with the host any later
213211
// than this.
214-
send_request_to_host(st.boot_services(), HostRequest::TestsComplete);
212+
send_request_to_host(HostRequest::TestsComplete);
215213

216214
// Send a special log to the host so that we can verify that logging works
217215
// up until exiting boot services. See `reconnect_serial_to_console` for the

uefi-test-runner/src/proto/console/gop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub unsafe fn test(bt: &BootServices) {
2828

2929
// `draw_fb` is skipped on aarch64, so the screenshot doesn't match.
3030
if cfg!(not(target_arch = "aarch64")) {
31-
send_request_to_host(bt, HostRequest::Screenshot("gop_test"));
31+
send_request_to_host(HostRequest::Screenshot("gop_test"));
3232
}
3333
}
3434

uefi/src/boot.rs

+38
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,44 @@ pub fn locate_handle_buffer(search_ty: SearchType) -> Result<HandleBuffer> {
664664
})
665665
}
666666

667+
/// Find an arbitrary handle that supports a particular [`Protocol`]. Returns
668+
/// [`NOT_FOUND`] if no handles support the protocol.
669+
///
670+
/// This method is a convenient wrapper around [`locate_handle_buffer`] for
671+
/// getting just one handle. This is useful when you don't care which handle the
672+
/// protocol is opened on. For example, [`DevicePathToText`] isn't tied to a
673+
/// particular device, so only a single handle is expected to exist.
674+
///
675+
/// [`NOT_FOUND`]: Status::NOT_FOUND
676+
/// [`DevicePathToText`]: uefi::proto::device_path::text::DevicePathToText
677+
///
678+
/// # Example
679+
///
680+
/// ```
681+
/// use uefi::proto::device_path::text::DevicePathToText;
682+
/// use uefi::{boot, Handle};
683+
/// # use uefi::Result;
684+
///
685+
/// # fn get_fake_val<T>() -> T { todo!() }
686+
/// # fn test() -> Result {
687+
/// # let image_handle: Handle = get_fake_val();
688+
/// let handle = boot::get_handle_for_protocol::<DevicePathToText>()?;
689+
/// let device_path_to_text = boot::open_protocol_exclusive::<DevicePathToText>(handle)?;
690+
/// # Ok(())
691+
/// # }
692+
/// ```
693+
///
694+
/// # Errors
695+
///
696+
/// * [`Status::NOT_FOUND`]: no matching handle.
697+
/// * [`Status::OUT_OF_RESOURCES`]: out of memory.
698+
pub fn get_handle_for_protocol<P: ProtocolPointer + ?Sized>() -> Result<Handle> {
699+
locate_handle_buffer(SearchType::ByProtocol(&P::GUID))?
700+
.first()
701+
.cloned()
702+
.ok_or_else(|| Status::NOT_FOUND.into())
703+
}
704+
667705
/// Opens a protocol interface for a handle.
668706
///
669707
/// See also [`open_protocol_exclusive`], which provides a safe subset of this

0 commit comments

Comments
 (0)