From 16afe23c53f1c795a5d1be05e02a2681a695e86e Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 3 Jul 2023 12:47:01 -0400 Subject: [PATCH] Return a SimpleFileSystem from BootServices::get_image_file_system This reverts a small change from: https://github.com/rust-osdev/uefi-rs/pull/472 If using the library without the `alloc` feature enabled, `FileSystem` isn't available, but you might still want access to the image's file system via the underlying protocol. The high-level API is still easily accessible via `FileSystem::new`. --- CHANGELOG.md | 2 + uefi-test-runner/src/boot/mod.rs | 7 +++- uefi/src/table/boot.rs | 72 ++++++++++++++++---------------- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f745231..a7c4f9633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### Changed - `Input::wait_for_key_event` now returns an `Option`, and is no longer `const`. - `LoadedImage::device` now returns an `Option` and is no longer `const`. +- `BootServices::get_image_file_system` now returns + `ScopedProtocol` instead of `fs::FileSystem`. ## uefi-macros - [Unreleased] diff --git a/uefi-test-runner/src/boot/mod.rs b/uefi-test-runner/src/boot/mod.rs index 89114a7f7..74e817afe 100644 --- a/uefi-test-runner/src/boot/mod.rs +++ b/uefi-test-runner/src/boot/mod.rs @@ -1,4 +1,5 @@ use alloc::string::ToString; +use uefi::fs::FileSystem; use uefi::proto::console::text::Output; use uefi::proto::device_path::media::FilePath; use uefi::proto::device_path::{DevicePath, LoadedImageDevicePath}; @@ -76,11 +77,13 @@ fn test_load_image(bt: &BootServices) { // Variant A: FromBuffer { - let mut fs = bt + let fs = bt .get_image_file_system(bt.image_handle()) .expect("should open file system"); let path = CString16::try_from(image_device_path_file_path.as_str()).unwrap(); - let image_data = fs.read(&*path).expect("should read file content"); + let image_data = FileSystem::new(fs) + .read(&*path) + .expect("should read file content"); let load_source = LoadImageSource::FromBuffer { buffer: image_data.as_slice(), file_path: None, diff --git a/uefi/src/table/boot.rs b/uefi/src/table/boot.rs index 646cd7dac..f7907fd80 100644 --- a/uefi/src/table/boot.rs +++ b/uefi/src/table/boot.rs @@ -3,6 +3,8 @@ use super::Revision; use crate::data_types::{Align, PhysicalAddress}; 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::{Char16, Error, Event, Guid, Handle, Result, Status, StatusExt}; use core::cell::UnsafeCell; @@ -12,12 +14,9 @@ use core::mem::{self, MaybeUninit}; use core::ops::{Deref, DerefMut}; use core::ptr::NonNull; use core::{ptr, slice}; + #[cfg(feature = "alloc")] -use { - crate::fs::FileSystem, - crate::proto::{loaded_image::LoadedImage, media::fs::SimpleFileSystem}, - ::alloc::vec::Vec, -}; +use alloc::vec::Vec; pub use uefi_raw::table::boot::{ EventType, InterfaceType, MemoryAttribute, MemoryDescriptor, MemoryType, Tpl, @@ -1344,6 +1343,38 @@ impl BootServices { pub unsafe fn set_mem(&self, buffer: *mut u8, size: usize, value: u8) { (self.0.set_mem)(buffer, size, value); } + + /// 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. + /// + /// [`open_protocol_exclusive`]: Self::open_protocol_exclusive + /// [`locate_device_path`]: Self::locate_device_path + /// + /// * [`uefi::Status::INVALID_PARAMETER`] + /// * [`uefi::Status::UNSUPPORTED`] + /// * [`uefi::Status::ACCESS_DENIED`] + /// * [`uefi::Status::ALREADY_STARTED`] + /// * [`uefi::Status::NOT_FOUND`] + pub fn get_image_file_system( + &self, + image_handle: Handle, + ) -> Result> { + let loaded_image = self.open_protocol_exclusive::(image_handle)?; + + let device_handle = loaded_image + .device() + .ok_or(Error::new(Status::UNSUPPORTED, ()))?; + let device_path = self.open_protocol_exclusive::(device_handle)?; + + let device_handle = self.locate_device_path::(&mut &*device_path)?; + + self.open_protocol_exclusive(device_handle) + } } #[cfg(feature = "alloc")] @@ -1377,37 +1408,6 @@ impl BootServices { // Emit output, with warnings Ok(handles) } - - /// Retrieves a [`FileSystem`] 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. - /// - /// [`open_protocol_exclusive`]: Self::open_protocol_exclusive - /// [`locate_device_path`]: Self::locate_device_path - /// [`FileSystem`]: uefi::fs::FileSystem - /// - /// * [`uefi::Status::INVALID_PARAMETER`] - /// * [`uefi::Status::UNSUPPORTED`] - /// * [`uefi::Status::ACCESS_DENIED`] - /// * [`uefi::Status::ALREADY_STARTED`] - /// * [`uefi::Status::NOT_FOUND`] - pub fn get_image_file_system(&self, image_handle: Handle) -> Result { - let loaded_image = self.open_protocol_exclusive::(image_handle)?; - - let device_handle = loaded_image - .device() - .ok_or(Error::new(Status::UNSUPPORTED, ()))?; - let device_path = self.open_protocol_exclusive::(device_handle)?; - - let device_handle = self.locate_device_path::(&mut &*device_path)?; - - let protocol = self.open_protocol_exclusive(device_handle)?; - Ok(FileSystem::new(protocol)) - } } impl super::Table for BootServices {