Skip to content

Commit 970bd10

Browse files
committed
1 parent 5ecb7ec commit 970bd10

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

uefi-raw/src/protocol/media.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use crate::{guid, Guid, Status};
2+
use crate::protocol::device_path::DevicePathProtocol;
3+
use core::ffi::c_void;
4+
5+
/// The UEFI LoadFile2 protocol.
6+
///
7+
/// This protocol has a single method to load a file according to some
8+
/// device path.
9+
///
10+
/// This interface is implemented by many devices, e.g. network and filesystems.
11+
#[derive(Debug)]
12+
#[repr(C)]
13+
pub struct LoadFile2 {
14+
pub load_file: unsafe extern "efiapi" fn(
15+
this: &mut LoadFile2,
16+
file_path: *const DevicePathProtocol,
17+
boot_policy: bool,
18+
buffer_size: *mut usize,
19+
buffer: *mut c_void,
20+
) -> Status,
21+
}
22+
23+
impl LoadFile2 {
24+
pub const GUID: Guid = guid!("4006c0c1-fcb3-403e-996d-4a6c8724e06d");
25+
}

uefi/src/proto/media/load_file.rs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//! Load file support protocols.
2+
3+
#[cfg(feature = "alloc")]
4+
use alloc::vec::Vec;
5+
6+
use crate::proto::device_path::{FfiDevicePath, DevicePath};
7+
use crate::proto::unsafe_protocol;
8+
use crate::{Result, Status};
9+
use core::ffi::c_void;
10+
use core::ptr;
11+
12+
/// The UEFI LoadFile2 protocol.
13+
///
14+
/// This protocol has a single method to load a file according to some
15+
/// device path.
16+
///
17+
/// This interface is implemented by many devices, e.g. network and filesystems.
18+
#[derive(Debug)]
19+
#[repr(transparent)]
20+
#[unsafe_protocol(uefi_raw::protocol::media::LoadFile2::GUID)]
21+
pub struct LoadFile2(uefi_raw::protocol::media::LoadFile2);
22+
23+
impl LoadFile2 {
24+
/// Load file addressed by provided device path
25+
pub fn load_file(&mut self,
26+
file_path: &DevicePath,
27+
buffer: &mut [u8]
28+
) -> Result<(), usize> {
29+
let mut buffer_size = buffer.len();
30+
unsafe {
31+
(self.0.load_file)(self,
32+
file_path,
33+
false,
34+
buffer_size,
35+
buffer.as_mut_ptr()
36+
)
37+
}.to_result_with(
38+
|| debug_assert_eq!(buffer_size, buffer.len()),
39+
|_| buffer_size
40+
)
41+
}
42+
43+
#[cfg(feature = "alloc")]
44+
/// Load file addressed by the provided device path.
45+
pub fn load_file_to_vec(&mut self,
46+
file_path: &DevicePath,
47+
) -> Result<Vec<u8>> {
48+
let mut buffer_size: usize = 0;
49+
let mut status: Status;
50+
unsafe {
51+
status = (self.0.load_file)(self,
52+
file_path.as_ffi_ptr(),
53+
false,
54+
ptr::addr_of_mut!(buffer_size),
55+
ptr::null_mut()
56+
);
57+
}
58+
59+
if status.is_error() {
60+
return Err(status.into());
61+
}
62+
63+
let mut buffer: Vec<u8> = Vec::with_capacity(buffer_size);
64+
unsafe {
65+
status = (self.0.load_file)(self,
66+
file_path.as_ffi_ptr(),
67+
false,
68+
ptr::addr_of_mut!(buffer_size),
69+
buffer.as_mut_ptr() as *mut c_void
70+
);
71+
}
72+
73+
if status.is_error() {
74+
return Err(status.into());
75+
}
76+
77+
Ok(buffer)
78+
}
79+
}

uefi/src/proto/media/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ pub mod block;
1010
pub mod disk;
1111
pub mod fs;
1212
pub mod partition;
13+
pub mod load_file;

0 commit comments

Comments
 (0)