Skip to content

Commit 3d7e72a

Browse files
uefi: Replace FileImpl with uefi-raw's FileProtocolV1
1 parent 49fefcb commit 3d7e72a

File tree

2 files changed

+47
-95
lines changed

2 files changed

+47
-95
lines changed

uefi/src/proto/media/file/mod.rs

Lines changed: 42 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ mod dir;
1010
mod info;
1111
mod regular;
1212

13-
use crate::{CStr16, Char16, Guid, Result, Status, StatusExt};
13+
use crate::{CStr16, Result, Status, StatusExt};
1414
use core::ffi::c_void;
1515
use core::fmt::Debug;
1616
use core::{mem, ptr};
17+
use uefi_raw::protocol::file_system::FileProtocolV1;
1718
#[cfg(all(feature = "unstable", feature = "alloc"))]
1819
use {alloc::alloc::Global, core::alloc::Allocator};
1920
#[cfg(feature = "alloc")]
@@ -74,8 +75,8 @@ pub trait File: Sized {
7475
(self.imp().open)(
7576
self.imp(),
7677
&mut ptr,
77-
filename.as_ptr(),
78-
open_mode,
78+
filename.as_ptr().cast(),
79+
uefi_raw::protocol::file_system::FileMode::from_bits_truncate(open_mode as u64),
7980
attributes,
8081
)
8182
}
@@ -93,7 +94,7 @@ pub trait File: Sized {
9394
///
9495
/// * [`uefi::Status::WARN_DELETE_FAILURE`]
9596
fn delete(mut self) -> Result {
96-
let result = (self.imp().delete)(self.imp()).to_result();
97+
let result = unsafe { (self.imp().delete)(self.imp()) }.to_result();
9798
mem::forget(self);
9899
result
99100
}
@@ -128,7 +129,7 @@ pub trait File: Sized {
128129
self.imp(),
129130
&Info::GUID,
130131
&mut buffer_size,
131-
buffer.as_mut_ptr(),
132+
buffer.as_mut_ptr().cast(),
132133
)
133134
}
134135
.to_result_with(
@@ -184,7 +185,7 @@ pub trait File: Sized {
184185
/// * [`uefi::Status::ACCESS_DENIED`]
185186
/// * [`uefi::Status::VOLUME_FULL`]
186187
fn flush(&mut self) -> Result {
187-
(self.imp().flush)(self.imp()).to_result()
188+
unsafe { (self.imp().flush)(self.imp()) }.to_result()
188189
}
189190

190191
/// Read the dynamically allocated info for a file.
@@ -224,7 +225,7 @@ pub trait File: Sized {
224225

225226
// Internal File helper methods to access the function pointer table.
226227
trait FileInternal: File {
227-
fn imp(&mut self) -> &mut FileImpl {
228+
fn imp(&mut self) -> &mut FileProtocolV1 {
228229
unsafe { &mut *self.handle().0 }
229230
}
230231
}
@@ -240,10 +241,10 @@ impl<T: File> FileInternal for T {}
240241
/// Dropping this structure will result in the file handle being closed.
241242
#[repr(transparent)]
242243
#[derive(Debug)]
243-
pub struct FileHandle(*mut FileImpl);
244+
pub struct FileHandle(*mut FileProtocolV1);
244245

245246
impl FileHandle {
246-
pub(super) const unsafe fn new(ptr: *mut FileImpl) -> Self {
247+
pub(super) const unsafe fn new(ptr: *mut FileProtocolV1) -> Self {
247248
Self(ptr)
248249
}
249250

@@ -296,7 +297,7 @@ impl File for FileHandle {
296297
// - get_position fails with EFI_UNSUPPORTED on directories
297298
// - result is an error if the underlying file was already closed or deleted.
298299
let mut pos = 0;
299-
match (this.get_position)(this, &mut pos) {
300+
match unsafe { (this.get_position)(this, &mut pos) } {
300301
Status::SUCCESS => Ok(true),
301302
Status::UNSUPPORTED => Ok(false),
302303
s => Err(s.into()),
@@ -310,65 +311,12 @@ impl File for FileHandle {
310311

311312
impl Drop for FileHandle {
312313
fn drop(&mut self) {
313-
let result: Result = (self.imp().close)(self.imp()).to_result();
314+
let result: Result = unsafe { (self.imp().close)(self.imp()) }.to_result();
314315
// The spec says this always succeeds.
315316
result.expect("Failed to close file");
316317
}
317318
}
318319

319-
/// The function pointer table for the File protocol.
320-
#[repr(C)]
321-
pub(super) struct FileImpl {
322-
revision: u64,
323-
open: unsafe extern "efiapi" fn(
324-
this: &mut FileImpl,
325-
new_handle: &mut *mut FileImpl,
326-
filename: *const Char16,
327-
open_mode: FileMode,
328-
attributes: FileAttribute,
329-
) -> Status,
330-
close: extern "efiapi" fn(this: &mut FileImpl) -> Status,
331-
delete: extern "efiapi" fn(this: &mut FileImpl) -> Status,
332-
/// # Read from Regular Files
333-
/// If `self` is not a directory, the function reads the requested number of bytes from the file
334-
/// at the file’s current position and returns them in `buffer`. If the read goes beyond the end
335-
/// of the file, the read length is truncated to the end of the file. The file’s current
336-
/// position is increased by the number of bytes returned.
337-
///
338-
/// # Read from Directory
339-
/// If `self` is a directory, the function reads the directory entry at the file’s current
340-
/// position and returns the entry in `buffer`. If the `buffer` is not large enough to hold the
341-
/// current directory entry, then `EFI_BUFFER_TOO_SMALL` is returned and the current file
342-
/// position is not updated. `buffer_size` is set to be the size of the buffer needed to read
343-
/// the entry. On success, the current position is updated to the next directory entry. If there
344-
/// are no more directory entries, the read returns a zero-length buffer.
345-
read: unsafe extern "efiapi" fn(
346-
this: &mut FileImpl,
347-
buffer_size: &mut usize,
348-
buffer: *mut u8,
349-
) -> Status,
350-
write: unsafe extern "efiapi" fn(
351-
this: &mut FileImpl,
352-
buffer_size: &mut usize,
353-
buffer: *const u8,
354-
) -> Status,
355-
get_position: extern "efiapi" fn(this: &mut FileImpl, position: &mut u64) -> Status,
356-
set_position: extern "efiapi" fn(this: &mut FileImpl, position: u64) -> Status,
357-
get_info: unsafe extern "efiapi" fn(
358-
this: &mut FileImpl,
359-
information_type: &Guid,
360-
buffer_size: &mut usize,
361-
buffer: *mut u8,
362-
) -> Status,
363-
set_info: unsafe extern "efiapi" fn(
364-
this: &mut FileImpl,
365-
information_type: &Guid,
366-
buffer_size: usize,
367-
buffer: *const c_void,
368-
) -> Status,
369-
flush: extern "efiapi" fn(this: &mut FileImpl) -> Status,
370-
}
371-
372320
/// Disambiguate the file type. Returned by `File::into_type()`.
373321
#[derive(Debug)]
374322
pub enum FileType {
@@ -399,16 +347,17 @@ pub enum FileMode {
399347
mod tests {
400348
use super::*;
401349
use crate::table::runtime::Time;
402-
use crate::{CString16, Identify};
350+
use crate::{CString16, Guid, Identify};
403351
use ::alloc::vec;
352+
use uefi_raw::protocol::file_system::FileProtocolRevision;
404353

405354
// Test `get_boxed_info` by setting up a fake file, which is mostly
406355
// just function pointers. Most of the functions can be empty, only
407356
// get_info is actually implemented to return useful data.
408357
#[test]
409358
fn test_get_boxed_info() {
410-
let mut file_impl = FileImpl {
411-
revision: 0,
359+
let mut file_impl = FileProtocolV1 {
360+
revision: FileProtocolRevision::REVISION_1,
412361
open: stub_open,
413362
close: stub_close,
414363
delete: stub_delete,
@@ -428,13 +377,13 @@ mod tests {
428377
assert_eq!(info.file_name(), CString16::try_from("test_file").unwrap());
429378
}
430379

431-
extern "efiapi" fn stub_get_info(
432-
_this: &mut FileImpl,
433-
information_type: &Guid,
434-
buffer_size: &mut usize,
435-
buffer: *mut u8,
380+
unsafe extern "efiapi" fn stub_get_info(
381+
_this: *mut FileProtocolV1,
382+
information_type: *const Guid,
383+
buffer_size: *mut usize,
384+
buffer: *mut c_void,
436385
) -> Status {
437-
assert_eq!(*information_type, FileInfo::GUID);
386+
assert_eq!(unsafe { *information_type }, FileInfo::GUID);
438387

439388
// Use a temporary buffer to get some file info, then copy that
440389
// data to the output buffer.
@@ -467,57 +416,60 @@ mod tests {
467416
}
468417

469418
extern "efiapi" fn stub_open(
470-
_this: &mut FileImpl,
471-
_new_handle: &mut *mut FileImpl,
472-
_filename: *const Char16,
473-
_open_mode: FileMode,
419+
_this: *mut FileProtocolV1,
420+
_new_handle: *mut *mut FileProtocolV1,
421+
_filename: *const uefi_raw::Char16,
422+
_open_mode: uefi_raw::protocol::file_system::FileMode,
474423
_attributes: FileAttribute,
475424
) -> Status {
476425
Status::UNSUPPORTED
477426
}
478427

479-
extern "efiapi" fn stub_close(_this: &mut FileImpl) -> Status {
428+
extern "efiapi" fn stub_close(_this: *mut FileProtocolV1) -> Status {
480429
Status::SUCCESS
481430
}
482431

483-
extern "efiapi" fn stub_delete(_this: &mut FileImpl) -> Status {
432+
extern "efiapi" fn stub_delete(_this: *mut FileProtocolV1) -> Status {
484433
Status::UNSUPPORTED
485434
}
486435

487436
extern "efiapi" fn stub_read(
488-
_this: &mut FileImpl,
489-
_buffer_size: &mut usize,
490-
_buffer: *mut u8,
437+
_this: *mut FileProtocolV1,
438+
_buffer_size: *mut usize,
439+
_buffer: *mut c_void,
491440
) -> Status {
492441
Status::UNSUPPORTED
493442
}
494443

495444
extern "efiapi" fn stub_write(
496-
_this: &mut FileImpl,
497-
_buffer_size: &mut usize,
498-
_buffer: *const u8,
445+
_this: *mut FileProtocolV1,
446+
_buffer_size: *mut usize,
447+
_buffer: *const c_void,
499448
) -> Status {
500449
Status::UNSUPPORTED
501450
}
502451

503-
extern "efiapi" fn stub_get_position(_this: &mut FileImpl, _position: &mut u64) -> Status {
452+
extern "efiapi" fn stub_get_position(
453+
_this: *const FileProtocolV1,
454+
_position: *mut u64,
455+
) -> Status {
504456
Status::UNSUPPORTED
505457
}
506458

507-
extern "efiapi" fn stub_set_position(_this: &mut FileImpl, _position: u64) -> Status {
459+
extern "efiapi" fn stub_set_position(_this: *mut FileProtocolV1, _position: u64) -> Status {
508460
Status::UNSUPPORTED
509461
}
510462

511463
extern "efiapi" fn stub_set_info(
512-
_this: &mut FileImpl,
513-
_information_type: &Guid,
464+
_this: *mut FileProtocolV1,
465+
_information_type: *const Guid,
514466
_buffer_size: usize,
515467
_buffer: *const c_void,
516468
) -> Status {
517469
Status::UNSUPPORTED
518470
}
519471

520-
extern "efiapi" fn stub_flush(_this: &mut FileImpl) -> Status {
472+
extern "efiapi" fn stub_flush(_this: *mut FileProtocolV1) -> Status {
521473
Status::UNSUPPORTED
522474
}
523475
}

uefi/src/proto/media/file/regular.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl RegularFile {
5050
let chunk_size = 1024 * 1024;
5151

5252
read_chunked(buffer, chunk_size, |buf, buf_size| unsafe {
53-
(self.imp().read)(self.imp(), buf_size, buf)
53+
(self.imp().read)(self.imp(), buf_size, buf.cast())
5454
})
5555
}
5656

@@ -59,7 +59,7 @@ impl RegularFile {
5959
pub(super) fn read_unchunked(&mut self, buffer: &mut [u8]) -> Result<usize, Option<usize>> {
6060
let mut buffer_size = buffer.len();
6161
let status =
62-
unsafe { (self.imp().read)(self.imp(), &mut buffer_size, buffer.as_mut_ptr()) };
62+
unsafe { (self.imp().read)(self.imp(), &mut buffer_size, buffer.as_mut_ptr().cast()) };
6363

6464
status.to_result_with(
6565
|| buffer_size,
@@ -97,7 +97,7 @@ impl RegularFile {
9797
/// * [`uefi::Status::VOLUME_FULL`]
9898
pub fn write(&mut self, buffer: &[u8]) -> Result<(), usize> {
9999
let mut buffer_size = buffer.len();
100-
unsafe { (self.imp().write)(self.imp(), &mut buffer_size, buffer.as_ptr()) }
100+
unsafe { (self.imp().write)(self.imp(), &mut buffer_size, buffer.as_ptr().cast()) }
101101
.to_result_with_err(|_| buffer_size)
102102
}
103103

@@ -110,7 +110,7 @@ impl RegularFile {
110110
/// * [`uefi::Status::DEVICE_ERROR`]
111111
pub fn get_position(&mut self) -> Result<u64> {
112112
let mut pos = 0u64;
113-
(self.imp().get_position)(self.imp(), &mut pos).to_result_with_val(|| pos)
113+
unsafe { (self.imp().get_position)(self.imp(), &mut pos) }.to_result_with_val(|| pos)
114114
}
115115

116116
/// Sets the file's current position
@@ -129,7 +129,7 @@ impl RegularFile {
129129
///
130130
/// * [`uefi::Status::DEVICE_ERROR`]
131131
pub fn set_position(&mut self, position: u64) -> Result {
132-
(self.imp().set_position)(self.imp(), position).to_result()
132+
unsafe { (self.imp().set_position)(self.imp(), position) }.to_result()
133133
}
134134
}
135135

0 commit comments

Comments
 (0)