diff --git a/uefi-test-runner/src/main.rs b/uefi-test-runner/src/main.rs index 2f0b4a0ac..569b36e91 100644 --- a/uefi-test-runner/src/main.rs +++ b/uefi-test-runner/src/main.rs @@ -48,12 +48,8 @@ fn efi_main(image: Handle, mut st: SystemTable) -> Status { // Check the `uefi::system` module. check_system(&st); - // Test all the boot services. - let bt = st.boot_services(); - // Try retrieving a handle to the file system the image was booted from. - bt.get_image_file_system(image) - .expect("Failed to retrieve boot file system"); + uefi::boot::get_image_file_system(image).expect("Failed to retrieve boot file system"); boot::test(&st); diff --git a/uefi/src/boot.rs b/uefi/src/boot.rs index 111e8af98..818ccc491 100644 --- a/uefi/src/boot.rs +++ b/uefi/src/boot.rs @@ -6,6 +6,8 @@ use crate::data_types::PhysicalAddress; use crate::mem::memory_map::{MemoryMapBackingMemory, MemoryMapKey, MemoryMapMeta, MemoryMapOwned}; use crate::polyfill::maybe_uninit_slice_assume_init_ref; use crate::proto::device_path::DevicePath; +use crate::proto::loaded_image::LoadedImage; +use crate::proto::media::fs::SimpleFileSystem; use crate::proto::{Protocol, ProtocolPointer}; use crate::table::Revision; use crate::util::opt_nonnull_to_ptr; @@ -22,10 +24,7 @@ use uefi_raw::table::boot::InterfaceType; use {alloc::vec::Vec, uefi::ResultExt}; #[cfg(doc)] -use { - crate::proto::device_path::LoadedImageDevicePath, crate::proto::loaded_image::LoadedImage, - crate::proto::media::fs::SimpleFileSystem, -}; +use crate::proto::device_path::LoadedImageDevicePath; pub use uefi::table::boot::{ AllocateType, EventNotifyFn, LoadImageSource, OpenProtocolAttributes, OpenProtocolParams, @@ -1156,6 +1155,32 @@ pub fn stall(microseconds: usize) { } } +/// Retrieves a [`SimpleFileSystem`] protocol associated with the device the given +/// image was loaded from. +/// +/// # Errors +/// +/// This function can return errors from [`open_protocol_exclusive`] and +/// [`locate_device_path`]. See those functions for more details. +/// +/// * [`Status::INVALID_PARAMETER`] +/// * [`Status::UNSUPPORTED`] +/// * [`Status::ACCESS_DENIED`] +/// * [`Status::ALREADY_STARTED`] +/// * [`Status::NOT_FOUND`] +pub fn get_image_file_system(image_handle: Handle) -> Result> { + let loaded_image = open_protocol_exclusive::(image_handle)?; + + let device_handle = loaded_image + .device() + .ok_or(Error::new(Status::UNSUPPORTED, ()))?; + let device_path = open_protocol_exclusive::(device_handle)?; + + let device_handle = locate_device_path::(&mut &*device_path)?; + + open_protocol_exclusive(device_handle) +} + /// Protocol interface [`Guids`][Guid] that are installed on a [`Handle`] as /// returned by [`protocols_per_handle`]. #[derive(Debug)]