Skip to content

Commit

Permalink
Return a SimpleFileSystem from BootServices::get_image_file_system
Browse files Browse the repository at this point in the history
This reverts a small change from: rust-osdev#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`.
  • Loading branch information
nicholasbishop committed Jul 3, 2023
1 parent 0fa5207 commit a369edc
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
### Changed
- `Input::wait_for_key_event` now returns an `Option<Event>`, and is no longer `const`.
- `LoadedImage::device` now returns an `Option<Handle>` and is no longer `const`.
- `BootServices::get_image_file_system` now returns
`ScopedProtocol<SimpleFileSystem>` instead of `fs::FileSystem`.

## uefi-macros - [Unreleased]

Expand Down
7 changes: 5 additions & 2 deletions uefi-test-runner/src/boot/mod.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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,
Expand Down
70 changes: 34 additions & 36 deletions uefi/src/table/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use super::Revision;
use crate::data_types::{Align, PhysicalAddress};
use crate::proto::device_path::DevicePath;
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;
Expand All @@ -13,11 +14,7 @@ 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 {crate::proto::loaded_image::LoadedImage, ::alloc::vec::Vec};

pub use uefi_raw::table::boot::{
EventType, InterfaceType, MemoryAttribute, MemoryDescriptor, MemoryType, Tpl,
Expand Down Expand Up @@ -1344,6 +1341,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<ScopedProtocol<SimpleFileSystem>> {
let loaded_image = self.open_protocol_exclusive::<LoadedImage>(image_handle)?;

let device_handle = loaded_image
.device()
.ok_or(Error::new(Status::UNSUPPORTED, ()))?;
let device_path = self.open_protocol_exclusive::<DevicePath>(device_handle)?;

let device_handle = self.locate_device_path::<SimpleFileSystem>(&mut &*device_path)?;

self.open_protocol_exclusive(device_handle)
}
}

#[cfg(feature = "alloc")]
Expand Down Expand Up @@ -1377,37 +1406,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<FileSystem> {
let loaded_image = self.open_protocol_exclusive::<LoadedImage>(image_handle)?;

let device_handle = loaded_image
.device()
.ok_or(Error::new(Status::UNSUPPORTED, ()))?;
let device_path = self.open_protocol_exclusive::<DevicePath>(device_handle)?;

let device_handle = self.locate_device_path::<SimpleFileSystem>(&mut &*device_path)?;

let protocol = self.open_protocol_exclusive(device_handle)?;
Ok(FileSystem::new(protocol))
}
}

impl super::Table for BootServices {
Expand Down

0 comments on commit a369edc

Please sign in to comment.