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