@@ -11,7 +11,16 @@ use core::slice;
11
11
use core:: sync:: atomic:: { AtomicPtr , Ordering } ;
12
12
use uefi:: { table, Handle , Result , Status , StatusExt } ;
13
13
14
- pub use uefi:: table:: boot:: { AllocateType , OpenProtocolAttributes , OpenProtocolParams , SearchType } ;
14
+ #[ cfg( doc) ]
15
+ use {
16
+ crate :: proto:: media:: fs:: SimpleFileSystem ,
17
+ crate :: proto:: loaded_image:: LoadedImage ,
18
+ crate :: proto:: device_path:: LoadedImageDevicePath ,
19
+ } ;
20
+
21
+ pub use uefi:: table:: boot:: {
22
+ AllocateType , LoadImageSource , OpenProtocolAttributes , OpenProtocolParams , SearchType ,
23
+ } ;
15
24
pub use uefi_raw:: table:: boot:: MemoryType ;
16
25
17
26
/// Global image handle. This is only set by [`set_image_handle`], and it is
@@ -242,6 +251,77 @@ pub fn open_protocol_exclusive<P: ProtocolPointer + ?Sized>(
242
251
}
243
252
}
244
253
254
+ /// Loads a UEFI image into memory and return a [`Handle`] to the image.
255
+ ///
256
+ /// There are two ways to load the image: by copying raw image data
257
+ /// from a source buffer, or by loading the image via the
258
+ /// [`SimpleFileSystem`] protocol. See [`LoadImageSource`] for more
259
+ /// details of the `source` parameter.
260
+ ///
261
+ /// The `parent_image_handle` is used to initialize the
262
+ /// `parent_handle` field of the [`LoadedImage`] protocol for the
263
+ /// image.
264
+ ///
265
+ /// If the image is successfully loaded, a [`Handle`] supporting the
266
+ /// [`LoadedImage`] and [`LoadedImageDevicePath`] protocols is returned. The
267
+ /// image can be started with `start_image` and unloaded with
268
+ /// `unload_image`.
269
+ ///
270
+ /// # Errors
271
+ ///
272
+ /// * [`Status::INVALID_PARAMETER`]: `source` contains an invalid value.
273
+ /// * [`Status::UNSUPPORTED`]: the image type is not supported.
274
+ /// * [`Status::OUT_OF_RESOURCES`]: insufficient resources to load the image.
275
+ /// * [`Status::LOAD_ERROR`]: the image is invalid.
276
+ /// * [`Status::DEVICE_ERROR`]: failed to load image due to a read error.
277
+ /// * [`Status::ACCESS_DENIED`]: failed to load image due to a security policy.
278
+ /// * [`Status::SECURITY_VIOLATION`]: a security policy specifies that the image
279
+ /// should not be started.
280
+ pub fn load_image ( parent_image_handle : Handle , source : LoadImageSource ) -> Result < Handle > {
281
+ let bt = boot_services_raw_panicking ( ) ;
282
+ let bt = unsafe { bt. as_ref ( ) } ;
283
+
284
+ let boot_policy;
285
+ let device_path;
286
+ let source_buffer;
287
+ let source_size;
288
+ match source {
289
+ LoadImageSource :: FromBuffer { buffer, file_path } => {
290
+ // Boot policy is ignored when loading from source buffer.
291
+ boot_policy = 0 ;
292
+
293
+ device_path = file_path. map ( |p| p. as_ffi_ptr ( ) ) . unwrap_or ( ptr:: null ( ) ) ;
294
+ source_buffer = buffer. as_ptr ( ) ;
295
+ source_size = buffer. len ( ) ;
296
+ }
297
+ LoadImageSource :: FromDevicePath {
298
+ device_path : file_path,
299
+ from_boot_manager,
300
+ } => {
301
+ boot_policy = u8:: from ( from_boot_manager) ;
302
+ device_path = file_path. as_ffi_ptr ( ) ;
303
+ source_buffer = ptr:: null ( ) ;
304
+ source_size = 0 ;
305
+ }
306
+ } ;
307
+
308
+ let mut image_handle = ptr:: null_mut ( ) ;
309
+ unsafe {
310
+ ( bt. load_image ) (
311
+ boot_policy,
312
+ parent_image_handle. as_ptr ( ) ,
313
+ device_path. cast ( ) ,
314
+ source_buffer,
315
+ source_size,
316
+ & mut image_handle,
317
+ )
318
+ . to_result_with_val (
319
+ // OK to unwrap: image handle is non-null for Status::SUCCESS.
320
+ || Handle :: from_ptr ( image_handle) . unwrap ( ) ,
321
+ )
322
+ }
323
+ }
324
+
245
325
/// A buffer returned by [`locate_handle_buffer`] that contains an array of
246
326
/// [`Handle`]s that support the requested protocol.
247
327
#[ derive( Debug , Eq , PartialEq ) ]
0 commit comments