Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion uefi-test-runner/examples/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()? {
Expand Down
7 changes: 3 additions & 4 deletions uefi-test-runner/src/boot/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions uefi-test-runner/src/proto/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<Event>` instead of `&Event`.
returns `Option<Event>` 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)

Expand Down
6 changes: 3 additions & 3 deletions uefi/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
)
}

Expand Down Expand Up @@ -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(),
)
}

Expand All @@ -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<bool> {
pub fn check_event(event: &Event) -> Result<bool> {
let bt = boot_services_raw_panicking();
let bt = unsafe { bt.as_ref() };

Expand Down
9 changes: 3 additions & 6 deletions uefi/src/data_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self> {
/// Create an [`Event`] from a raw pointer. Returns [`None`] if the pointer
/// null.
pub fn from_ptr(ptr: *mut c_void) -> Option<Self> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be a safe operation. While it's true that the body of the function doesn't do anything unsafe, if you create an Event from an invalid pointer and pass it into some other function that expects a valid Event, it may crash or lead to some other UB.

Copy link
Member Author

@phip1611 phip1611 Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your concern, thanks! Let me think about this again and test a little

NonNull::new(ptr).map(Self)
}

Expand Down
7 changes: 3 additions & 4 deletions uefi/src/proto/console/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<Event> {
unsafe { Event::from_ptr(self.0.wait_for_input) }
pub fn wait_for_input_event(&self) -> Result<Event> {
Event::from_ptr(self.0.wait_for_input).ok_or(Error::from(Status::UNSUPPORTED))
}

/// Returns a reference to the pointer device information.
Expand Down
7 changes: 3 additions & 4 deletions uefi/src/proto/console/text/input.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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<Event> {
unsafe { Event::from_ptr(self.0.wait_for_key) }
pub fn wait_for_key_event(&self) -> Result<Event> {
Event::from_ptr(self.0.wait_for_key).ok_or(Error::from(Status::UNSUPPORTED))
}
}

Expand Down
8 changes: 4 additions & 4 deletions uefi/src/proto/network/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<Event> {
unsafe { Event::from_ptr(self.0.wait_for_packet) }
pub fn wait_for_packet_event(&self) -> Result<Event> {
Event::from_ptr(self.0.wait_for_packet).ok_or(Error::from(Status::UNSUPPORTED))
}

/// Returns a reference to the Simple Network mode.
Expand Down