use crate::proto::unsafe_protocol;
use crate::util::opt_nonnull_to_ptr;
use crate::{Event, Result, Status, StatusExt};
use core::ptr::NonNull;
use uefi_raw::protocol::disk::{DiskIo2Protocol, DiskIoProtocol};
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(DiskIoProtocol::GUID)]
pub struct DiskIo(DiskIoProtocol);
impl DiskIo {
pub fn read_disk(&self, media_id: u32, offset: u64, buffer: &mut [u8]) -> Result {
unsafe {
(self.0.read_disk)(
&self.0,
media_id,
offset,
buffer.len(),
buffer.as_mut_ptr().cast(),
)
}
.to_result()
}
pub fn write_disk(&mut self, media_id: u32, offset: u64, buffer: &[u8]) -> Result {
unsafe {
(self.0.write_disk)(
&mut self.0,
media_id,
offset,
buffer.len(),
buffer.as_ptr().cast(),
)
}
.to_result()
}
}
#[repr(C)]
#[derive(Debug)]
pub struct DiskIo2Token {
pub event: Option<Event>,
pub transaction_status: Status,
}
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(DiskIo2Protocol::GUID)]
pub struct DiskIo2(DiskIo2Protocol);
impl DiskIo2 {
pub fn cancel(&mut self) -> Result {
unsafe { (self.0.cancel)(&mut self.0) }.to_result()
}
pub unsafe fn read_disk_raw(
&self,
media_id: u32,
offset: u64,
token: Option<NonNull<DiskIo2Token>>,
len: usize,
buffer: *mut u8,
) -> Result {
let token = opt_nonnull_to_ptr(token);
unsafe {
(self.0.read_disk_ex)(&self.0, media_id, offset, token.cast(), len, buffer.cast())
}
.to_result()
}
pub unsafe fn write_disk_raw(
&mut self,
media_id: u32,
offset: u64,
token: Option<NonNull<DiskIo2Token>>,
len: usize,
buffer: *const u8,
) -> Result {
let token = opt_nonnull_to_ptr(token);
unsafe {
(self.0.write_disk_ex)(
&mut self.0,
media_id,
offset,
token.cast(),
len,
buffer.cast(),
)
}
.to_result()
}
pub fn flush_disk(&mut self, token: Option<NonNull<DiskIo2Token>>) -> Result {
let token = opt_nonnull_to_ptr(token);
unsafe { (self.0.flush_disk_ex)(&mut self.0, token.cast()) }.to_result()
}
}