uefi_std/
exec.rs

1use crate::prelude::*;
2
3use crate::ffi::wstr;
4use crate::fs::load;
5use crate::loaded_image::LoadedImage;
6use crate::proto::Protocol;
7
8pub fn exec_data(data: &[u8], name: &str, args: &[&str]) -> Result<usize> {
9    let handle = crate::handle();
10    let st = crate::system_table();
11
12    let mut image_handle = Handle(0);
13    let status = (st.BootServices.LoadImage)(
14        false,
15        handle,
16        0,
17        data.as_ptr(),
18        data.len(),
19        &mut image_handle,
20    );
21
22    if !status.is_success() {
23        return Err(status);
24    }
25
26    let mut cmdline = format!("\"{}\"", name);
27    for arg in args.iter() {
28        cmdline.push_str(" \"");
29        cmdline.push_str(arg);
30        cmdline.push('"');
31    }
32    cmdline.push('\0');
33
34    let wcmdline = wstr(&cmdline);
35
36    if let Ok(loaded_image) = LoadedImage::handle_protocol(image_handle) {
37        loaded_image.0.LoadOptionsSize = (wcmdline.len() as u32) * 2;
38        loaded_image.0.LoadOptions = wcmdline.as_ptr();
39    }
40
41    let mut exit_size = 0;
42    let mut exit_ptr = ::core::ptr::null_mut();
43    let status = (st.BootServices.StartImage)(image_handle, &mut exit_size, &mut exit_ptr);
44
45    match status {
46        Status::SUCCESS => Ok(status.0),
47        _ => Err(status),
48    }
49}
50
51pub fn exec_path(path: &str, args: &[&str]) -> Result<usize> {
52    let data = load(path)?;
53    exec_data(&data, path, args)
54}