Skip to content

Commit 411bd64

Browse files
IsaacWoodsGabrielMajeri
authored andcommitted
Add support for the LoadedImage protocol (#113)
Mainly, this adds support for accessing command line arguments from the EFI shell or a boot option.
1 parent a1bce90 commit 411bd64

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ logger = []
2929
[dependencies]
3030
bitflags = "1.1.0"
3131
log = { version = "0.4.8", default-features = false }
32-
ucs2 = "0.2.0"
32+
ucs2 = "0.3.0"
3333
uefi-macros = "0.3.0"
3434

3535
[workspace]

src/proto/loaded_image/mod.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//! Loaded image protocol.
2+
3+
use crate::{
4+
data_types::{CStr16, Char16},
5+
proto::Protocol,
6+
table::boot::MemoryType,
7+
unsafe_guid,
8+
Handle,
9+
Status,
10+
};
11+
use core::ffi::c_void;
12+
13+
/// The Loaded Image protocol. This can be opened on any image handle using the `HandleProtocol` boot service.
14+
#[repr(C)]
15+
#[unsafe_guid("5b1b31a1-9562-11d2-8e3f-00a0c969723b")]
16+
#[derive(Protocol)]
17+
pub struct LoadedImage {
18+
revision: u32,
19+
parent_handle: Handle,
20+
system_table: *const c_void,
21+
22+
// Source location of the image
23+
device_handle: Handle,
24+
_file_path: *const c_void, // TODO: not supported yet
25+
_reserved: *const c_void,
26+
27+
// Image load options
28+
load_options_size: u32,
29+
load_options: *const Char16,
30+
31+
// Location where image was loaded
32+
image_base: usize,
33+
image_size: u64,
34+
image_code_type: MemoryType,
35+
image_data_type: MemoryType,
36+
/// This is a callback that a loaded image can use to do cleanup. It is called by the
37+
/// UnloadImage boot service.
38+
unload: extern "efiapi" fn(image_handle: Handle) -> Status,
39+
}
40+
41+
/// Errors that can be raised during parsing of the load options.
42+
#[derive(Debug)]
43+
pub enum LoadOptionsError {
44+
/// The passed buffer is not large enough to contain the load options.
45+
BufferTooSmall,
46+
/// The load options are not valid UTF-8.
47+
NotValidUtf8,
48+
}
49+
50+
impl LoadedImage {
51+
/// Get the load options of the given image. If the image was executed from the EFI shell, or from a boot
52+
/// option, this is the command line that was used to execute it as a string.
53+
pub fn load_options<'a>(&self, buffer: &'a mut [u8]) -> Result<&'a str, LoadOptionsError> {
54+
let ucs2_slice = unsafe { CStr16::from_ptr(self.load_options).to_u16_slice() };
55+
let length = ucs2::decode(ucs2_slice, buffer).map_err(|_| LoadOptionsError::BufferTooSmall)?;
56+
core::str::from_utf8(&buffer[0..length]).map_err(|_| LoadOptionsError::NotValidUtf8)
57+
}
58+
}

src/proto/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ pub use uefi_macros::Protocol;
2828

2929
pub mod console;
3030
pub mod debug;
31+
pub mod loaded_image;
3132
pub mod media;
3233
pub mod pi;

0 commit comments

Comments
 (0)