@@ -11,7 +11,15 @@ use core::slice;
1111use  core:: sync:: atomic:: { AtomicPtr ,  Ordering } ; 
1212use  uefi:: { table,  Handle ,  Result ,  Status ,  StatusExt } ; 
1313
14- pub  use  uefi:: table:: boot:: { AllocateType ,  OpenProtocolAttributes ,  OpenProtocolParams ,  SearchType } ; 
14+ #[ cfg( doc) ]  
15+ use  { 
16+     crate :: proto:: device_path:: LoadedImageDevicePath ,  crate :: proto:: loaded_image:: LoadedImage , 
17+     crate :: proto:: media:: fs:: SimpleFileSystem , 
18+ } ; 
19+ 
20+ pub  use  uefi:: table:: boot:: { 
21+     AllocateType ,  LoadImageSource ,  OpenProtocolAttributes ,  OpenProtocolParams ,  SearchType , 
22+ } ; 
1523pub  use  uefi_raw:: table:: boot:: MemoryType ; 
1624
1725/// Global image handle. This is only set by [`set_image_handle`], and it is 
@@ -242,6 +250,111 @@ pub fn open_protocol_exclusive<P: ProtocolPointer + ?Sized>(
242250    } 
243251} 
244252
253+ /// Loads a UEFI image into memory and return a [`Handle`] to the image. 
254+ /// 
255+ /// There are two ways to load the image: by copying raw image data 
256+ /// from a source buffer, or by loading the image via the 
257+ /// [`SimpleFileSystem`] protocol. See [`LoadImageSource`] for more 
258+ /// details of the `source` parameter. 
259+ /// 
260+ /// The `parent_image_handle` is used to initialize the 
261+ /// `parent_handle` field of the [`LoadedImage`] protocol for the 
262+ /// image. 
263+ /// 
264+ /// If the image is successfully loaded, a [`Handle`] supporting the 
265+ /// [`LoadedImage`] and [`LoadedImageDevicePath`] protocols is returned. The 
266+ /// image can be started with [`start_image`] and unloaded with 
267+ /// [`unload_image`]. 
268+ /// 
269+ /// # Errors 
270+ /// 
271+ /// * [`Status::INVALID_PARAMETER`]: `source` contains an invalid value. 
272+ /// * [`Status::UNSUPPORTED`]: the image type is not supported. 
273+ /// * [`Status::OUT_OF_RESOURCES`]: insufficient resources to load the image. 
274+ /// * [`Status::LOAD_ERROR`]: the image is invalid. 
275+ /// * [`Status::DEVICE_ERROR`]: failed to load image due to a read error. 
276+ /// * [`Status::ACCESS_DENIED`]: failed to load image due to a security policy. 
277+ /// * [`Status::SECURITY_VIOLATION`]: a security policy specifies that the image 
278+ ///   should not be started. 
279+ pub  fn  load_image ( parent_image_handle :  Handle ,  source :  LoadImageSource )  -> Result < Handle >  { 
280+     let  bt = boot_services_raw_panicking ( ) ; 
281+     let  bt = unsafe  {  bt. as_ref ( )  } ; 
282+ 
283+     let  boot_policy; 
284+     let  device_path; 
285+     let  source_buffer; 
286+     let  source_size; 
287+     match  source { 
288+         LoadImageSource :: FromBuffer  {  buffer,  file_path }  => { 
289+             // Boot policy is ignored when loading from source buffer. 
290+             boot_policy = 0 ; 
291+ 
292+             device_path = file_path. map ( |p| p. as_ffi_ptr ( ) ) . unwrap_or ( ptr:: null ( ) ) ; 
293+             source_buffer = buffer. as_ptr ( ) ; 
294+             source_size = buffer. len ( ) ; 
295+         } 
296+         LoadImageSource :: FromDevicePath  { 
297+             device_path :  file_path, 
298+             from_boot_manager, 
299+         }  => { 
300+             boot_policy = u8:: from ( from_boot_manager) ; 
301+             device_path = file_path. as_ffi_ptr ( ) ; 
302+             source_buffer = ptr:: null ( ) ; 
303+             source_size = 0 ; 
304+         } 
305+     } ; 
306+ 
307+     let  mut  image_handle = ptr:: null_mut ( ) ; 
308+     unsafe  { 
309+         ( bt. load_image ) ( 
310+             boot_policy, 
311+             parent_image_handle. as_ptr ( ) , 
312+             device_path. cast ( ) , 
313+             source_buffer, 
314+             source_size, 
315+             & mut  image_handle, 
316+         ) 
317+         . to_result_with_val ( 
318+             // OK to unwrap: image handle is non-null for Status::SUCCESS. 
319+             || Handle :: from_ptr ( image_handle) . unwrap ( ) , 
320+         ) 
321+     } 
322+ } 
323+ 
324+ /// Unloads a UEFI image. 
325+ /// 
326+ /// # Errors 
327+ /// 
328+ /// * [`Status::UNSUPPORTED`]: the image has been started, and does not support unload. 
329+ /// * [`Status::INVALID_PARAMETER`]: `image_handle` is not valid. 
330+ pub  fn  unload_image ( image_handle :  Handle )  -> Result  { 
331+     let  bt = boot_services_raw_panicking ( ) ; 
332+     let  bt = unsafe  {  bt. as_ref ( )  } ; 
333+ 
334+     unsafe  {  ( bt. unload_image ) ( image_handle. as_ptr ( ) )  } . to_result ( ) 
335+ } 
336+ 
337+ /// Transfers control to a loaded image's entry point. 
338+ /// 
339+ /// # Errors 
340+ /// 
341+ /// * [`Status::INVALID_PARAMETER`]: `image_handle` is not valid, or the image 
342+ ///   has already been initialized with `start_image`. 
343+ /// * [`Status::SECURITY_VIOLATION`]: a security policy specifies that the image 
344+ ///   should not be started. 
345+ pub  fn  start_image ( image_handle :  Handle )  -> Result  { 
346+     let  bt = boot_services_raw_panicking ( ) ; 
347+     let  bt = unsafe  {  bt. as_ref ( )  } ; 
348+ 
349+     // TODO: implement returning exit data to the caller. 
350+     let  mut  exit_data_size:  usize  = 0 ; 
351+     let  mut  exit_data:  * mut  u16  = ptr:: null_mut ( ) ; 
352+ 
353+     unsafe  { 
354+         ( bt. start_image ) ( image_handle. as_ptr ( ) ,  & mut  exit_data_size,  & mut  exit_data) . to_result ( ) 
355+     } 
356+ } 
357+ 
245358/// A buffer returned by [`locate_handle_buffer`] that contains an array of 
246359/// [`Handle`]s that support the requested protocol. 
247360#[ derive( Debug ,  Eq ,  PartialEq ) ]  
0 commit comments