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}