diff --git a/uefi-test-runner/examples/input.rs b/uefi-test-runner/examples/input.rs index 1d3e6ce31..5862818f6 100644 --- a/uefi-test-runner/examples/input.rs +++ b/uefi-test-runner/examples/input.rs @@ -11,7 +11,8 @@ fn read_keyboard_events(input: &mut Input) -> Result { println!("waiting for key press..."); // Pause until a keyboard event occurs. - let mut events = [input.wait_for_key_event().unwrap()]; + let event = input.wait_for_key_event()?; + let mut events = [event]; boot::wait_for_event(&mut events).discard_errdata()?; match input.read_key()? { diff --git a/uefi-test-runner/src/boot/misc.rs b/uefi-test-runner/src/boot/misc.rs index 21a5b07d2..228af5bf5 100644 --- a/uefi-test-runner/src/boot/misc.rs +++ b/uefi-test-runner/src/boot/misc.rs @@ -45,8 +45,7 @@ fn test_check_event() { unsafe { boot::create_event(EventType::NOTIFY_WAIT, Tpl::CALLBACK, Some(callback), None) } .unwrap(); - let event_clone = unsafe { event.unsafe_clone() }; - let is_signaled = boot::check_event(event_clone).unwrap(); + let is_signaled = boot::check_event(&event).unwrap(); assert!(!is_signaled); boot::close_event(event).unwrap(); @@ -56,8 +55,8 @@ fn test_timer() { let timer_event = unsafe { boot::create_event_ex(EventType::TIMER, Tpl::CALLBACK, None, None, None) } .unwrap(); - let mut events = unsafe { [timer_event.unsafe_clone()] }; boot::set_timer(&timer_event, TimerTrigger::Relative(5_0 /*00 ns */)).unwrap(); + let mut events = [unsafe { timer_event.unsafe_clone() }]; assert_eq!(boot::wait_for_event(&mut events).unwrap(), 0); boot::close_event(timer_event).unwrap(); @@ -89,7 +88,7 @@ fn test_callback_with_ctx() { .expect("Failed to create event with context") }; - boot::check_event(event).expect("Failed to check event"); + boot::check_event(&event).expect("Failed to check event"); // Check that `data` was updated inside the event callback. assert_eq!(data, 456); diff --git a/uefi-test-runner/src/proto/media.rs b/uefi-test-runner/src/proto/media.rs index 87c6572a3..abd77bcf6 100644 --- a/uefi-test-runner/src/proto/media.rs +++ b/uefi-test-runner/src/proto/media.rs @@ -309,7 +309,7 @@ fn test_raw_disk_io2(handle: Handle) { unsafe { // Create the completion event - let mut event = boot::create_event(EventType::empty(), Tpl::NOTIFY, None, None) + let event = boot::create_event(EventType::empty(), Tpl::NOTIFY, None, None) .expect("Failed to create disk I/O completion event"); // Initialise the task context @@ -333,8 +333,7 @@ fn test_raw_disk_io2(handle: Handle) { .expect("Failed to initiate asynchronous disk I/O read"); // Wait for the transaction to complete - boot::wait_for_event(core::slice::from_mut(&mut event)) - .expect("Failed to wait on completion event"); + boot::wait_for_event(&mut [event]).expect("Failed to wait on completion event"); // Verify that the disk's MBR signature is correct assert_eq!(task.token.transaction_status, Status::SUCCESS); diff --git a/uefi/CHANGELOG.md b/uefi/CHANGELOG.md index 06f70bc44..63129a497 100644 --- a/uefi/CHANGELOG.md +++ b/uefi/CHANGELOG.md @@ -11,7 +11,10 @@ - Changed ordering of `proto::pci::PciIoAddress` to (bus -> dev -> fun -> reg -> ext_reg). - Return request with status as error data object for `proto::ata::pass_thru::AtaDevice`. - **Breaking:** `proto::network::snp::SimpleNetwork::wait_for_packet` now - returns `Option` instead of `&Event`. + returns `Option` instead of `&Event`. It has also been renamed to + `wait_for_packet`. +- `boot::check_event` now consumes `&Event` rather than `Event`, removing the + need for unnecessary `Event::unsafe_clone()`s. # uefi - v0.36.1 (2025-11-05) diff --git a/uefi/src/boot.rs b/uefi/src/boot.rs index c6449a42f..228a03cfd 100644 --- a/uefi/src/boot.rs +++ b/uefi/src/boot.rs @@ -424,7 +424,7 @@ pub unsafe fn create_event( unsafe { (bt.create_event)(event_ty, notify_tpl, notify_fn, notify_ctx, &mut event) } .to_result_with_val( // OK to unwrap: event is non-null for Status::SUCCESS. - || unsafe { Event::from_ptr(event) }.unwrap(), + || Event::from_ptr(event).unwrap(), ) } @@ -502,7 +502,7 @@ pub unsafe fn create_event_ex( } .to_result_with_val( // OK to unwrap: event is non-null for Status::SUCCESS. - || unsafe { Event::from_ptr(event) }.unwrap(), + || Event::from_ptr(event).unwrap(), ) } @@ -519,7 +519,7 @@ pub unsafe fn create_event_ex( /// * [`Status::INVALID_PARAMETER`]: `event` is of type [`NOTIFY_SIGNAL`]. /// /// [`NOTIFY_SIGNAL`]: EventType::NOTIFY_SIGNAL -pub fn check_event(event: Event) -> Result { +pub fn check_event(event: &Event) -> Result { let bt = boot_services_raw_panicking(); let bt = unsafe { bt.as_ref() }; diff --git a/uefi/src/data_types/mod.rs b/uefi/src/data_types/mod.rs index a2569db24..e0ded8188 100644 --- a/uefi/src/data_types/mod.rs +++ b/uefi/src/data_types/mod.rs @@ -82,12 +82,9 @@ impl Event { Self(self.0) } - /// Create an `Event` from a raw pointer. - /// - /// # Safety - /// - /// The caller must ensure that the pointer is valid. - pub unsafe fn from_ptr(ptr: *mut c_void) -> Option { + /// Create an [`Event`] from a raw pointer. Returns [`None`] if the pointer + /// null. + pub fn from_ptr(ptr: *mut c_void) -> Option { NonNull::new(ptr).map(Self) } diff --git a/uefi/src/proto/console/pointer/mod.rs b/uefi/src/proto/console/pointer/mod.rs index 35101dc4a..b39cd3847 100644 --- a/uefi/src/proto/console/pointer/mod.rs +++ b/uefi/src/proto/console/pointer/mod.rs @@ -3,7 +3,7 @@ //! Pointer device access. use crate::proto::unsafe_protocol; -use crate::{Event, Result, Status, StatusExt}; +use crate::{Error, Event, Result, Status, StatusExt}; use uefi_raw::protocol::console::SimplePointerProtocol; /// Simple Pointer [`Protocol`]. Provides information about a pointer device. @@ -53,9 +53,8 @@ impl Pointer { /// for input from the pointer device /// /// [`boot::wait_for_event`]: crate::boot::wait_for_event - #[must_use] - pub fn wait_for_input_event(&self) -> Option { - unsafe { Event::from_ptr(self.0.wait_for_input) } + pub fn wait_for_input_event(&self) -> Result { + Event::from_ptr(self.0.wait_for_input).ok_or(Error::from(Status::UNSUPPORTED)) } /// Returns a reference to the pointer device information. diff --git a/uefi/src/proto/console/text/input.rs b/uefi/src/proto/console/text/input.rs index cd44bacdb..4274110c3 100644 --- a/uefi/src/proto/console/text/input.rs +++ b/uefi/src/proto/console/text/input.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use crate::proto::unsafe_protocol; -use crate::{Char16, Event, Result, Status, StatusExt}; +use crate::{Char16, Error, Event, Result, Status, StatusExt}; use core::mem::MaybeUninit; use uefi_raw::protocol::console::{InputKey, SimpleTextInputProtocol}; @@ -84,9 +84,8 @@ impl Input { /// for a key to be available /// /// [`boot::wait_for_event`]: crate::boot::wait_for_event - #[must_use] - pub fn wait_for_key_event(&self) -> Option { - unsafe { Event::from_ptr(self.0.wait_for_key) } + pub fn wait_for_key_event(&self) -> Result { + Event::from_ptr(self.0.wait_for_key).ok_or(Error::from(Status::UNSUPPORTED)) } } diff --git a/uefi/src/proto/network/snp.rs b/uefi/src/proto/network/snp.rs index 75538abff..a1fc00274 100644 --- a/uefi/src/proto/network/snp.rs +++ b/uefi/src/proto/network/snp.rs @@ -16,8 +16,9 @@ use core::ffi::c_void; use core::net::IpAddr; use core::ptr; use core::ptr::NonNull; +use uefi::Error; use uefi_raw::protocol::network::snp::SimpleNetworkProtocol; -use uefi_raw::{Boolean, IpAddress as EfiIpAddr, MacAddress as EfiMacAddr}; +use uefi_raw::{Boolean, IpAddress as EfiIpAddr, MacAddress as EfiMacAddr, Status}; pub use uefi_raw::protocol::network::snp::{ InterruptStatus, NetworkMode, NetworkState, NetworkStatistics, ReceiveFlags, @@ -269,9 +270,8 @@ impl SimpleNetwork { /// /// On QEMU, this event seems to never fire; it is suggested to verify that your implementation /// of UEFI properly implements this event before using it. - #[must_use] - pub fn wait_for_packet(&self) -> Option { - unsafe { Event::from_ptr(self.0.wait_for_packet) } + pub fn wait_for_packet_event(&self) -> Result { + Event::from_ptr(self.0.wait_for_packet).ok_or(Error::from(Status::UNSUPPORTED)) } /// Returns a reference to the Simple Network mode.