Skip to content

Commit b1b0b0a

Browse files
authored
Merge pull request #1328 from rust-osdev/revert-1327-bishop-dp-text-no-bs
Revert "uefi: Drop BootServices arg from device path <-> text conversions"
2 parents 5f217ed + 89ae42e commit b1b0b0a

File tree

5 files changed

+49
-32
lines changed

5 files changed

+49
-32
lines changed

uefi-test-runner/examples/loaded_image.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ fn print_image_path(boot_services: &BootServices) -> Result {
4949
loaded_image.file_path().expect("File path is not set");
5050
let image_device_path_text = device_path_to_text
5151
.convert_device_path_to_text(
52+
boot_services,
5253
image_device_path,
5354
DisplayOnly(true),
5455
AllowShortcuts(false),

uefi-test-runner/src/proto/device_path.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn test(bt: &BootServices) {
4343
);
4444

4545
let text = device_path_to_text
46-
.convert_device_node_to_text(path, DisplayOnly(true), AllowShortcuts(false))
46+
.convert_device_node_to_text(bt, path, DisplayOnly(true), AllowShortcuts(false))
4747
.expect("Failed to convert device path to text");
4848
let text = &*text;
4949
info!("path name: {text}");
@@ -81,7 +81,7 @@ pub fn test(bt: &BootServices) {
8181

8282
let path_components = device_path
8383
.node_iter()
84-
.map(|node| node.to_string(DisplayOnly(false), AllowShortcuts(false)))
84+
.map(|node| node.to_string(bt, DisplayOnly(false), AllowShortcuts(false)))
8585
.map(|str| str.unwrap().to_string())
8686
.collect::<Vec<_>>();
8787

@@ -107,7 +107,7 @@ pub fn test(bt: &BootServices) {
107107

108108
// Test that to_string works for device_paths
109109
let path = device_path
110-
.to_string(DisplayOnly(false), AllowShortcuts(false))
110+
.to_string(bt, DisplayOnly(false), AllowShortcuts(false))
111111
.unwrap()
112112
.to_string();
113113

uefi/CHANGELOG.md

-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ details of a significant change to the API in this release.
2323

2424
## Changed
2525
- **Breaking:** `uefi::helpers::init` no longer takes an argument.
26-
- **Breaking:** The conversion functions between device paths and text no longer
27-
take a `BootServices` argument. The global system table is used instead.
2826
- The lifetime of the `SearchType` returned from
2927
`BootServices::register_protocol_notify` is now tied to the protocol GUID.
3028
The old `MemoryMap` was renamed to `MemoryMapOwned`.

uefi/src/proto/device_path/mod.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ use ptr_meta::Pointee;
9090

9191
#[cfg(feature = "alloc")]
9292
use {
93-
crate::boot::{self, OpenProtocolAttributes, OpenProtocolParams, ScopedProtocol, SearchType},
9493
crate::proto::device_path::text::{AllowShortcuts, DevicePathToText, DisplayOnly},
94+
crate::table::boot::{
95+
BootServices, OpenProtocolAttributes, OpenProtocolParams, ScopedProtocol, SearchType,
96+
},
9597
crate::{CString16, Identify},
9698
alloc::borrow::ToOwned,
9799
alloc::boxed::Box,
@@ -230,13 +232,14 @@ impl DevicePathNode {
230232
#[cfg(feature = "alloc")]
231233
pub fn to_string(
232234
&self,
235+
bs: &BootServices,
233236
display_only: DisplayOnly,
234237
allow_shortcuts: AllowShortcuts,
235238
) -> Result<CString16, DevicePathToTextError> {
236-
let to_text_protocol = open_text_protocol()?;
239+
let to_text_protocol = open_text_protocol(bs)?;
237240

238241
to_text_protocol
239-
.convert_device_node_to_text(self, display_only, allow_shortcuts)
242+
.convert_device_node_to_text(bs, self, display_only, allow_shortcuts)
240243
.map(|pool_string| {
241244
let cstr16 = &*pool_string;
242245
// Another allocation; pool string is dropped. This overhead
@@ -481,13 +484,14 @@ impl DevicePath {
481484
#[cfg(feature = "alloc")]
482485
pub fn to_string(
483486
&self,
487+
bs: &BootServices,
484488
display_only: DisplayOnly,
485489
allow_shortcuts: AllowShortcuts,
486490
) -> Result<CString16, DevicePathToTextError> {
487-
let to_text_protocol = open_text_protocol()?;
491+
let to_text_protocol = open_text_protocol(bs)?;
488492

489493
to_text_protocol
490-
.convert_device_path_to_text(self, display_only, allow_shortcuts)
494+
.convert_device_path_to_text(bs, self, display_only, allow_shortcuts)
491495
.map(|pool_string| {
492496
let cstr16 = &*pool_string;
493497
// Another allocation; pool string is dropped. This overhead
@@ -874,17 +878,20 @@ impl core::error::Error for DevicePathToTextError {
874878
/// Helper function to open the [`DevicePathToText`] protocol using the boot
875879
/// services.
876880
#[cfg(feature = "alloc")]
877-
fn open_text_protocol() -> Result<ScopedProtocol<DevicePathToText>, DevicePathToTextError> {
878-
let &handle = boot::locate_handle_buffer(SearchType::ByProtocol(&DevicePathToText::GUID))
881+
fn open_text_protocol(
882+
bs: &BootServices,
883+
) -> Result<ScopedProtocol<DevicePathToText>, DevicePathToTextError> {
884+
let &handle = bs
885+
.locate_handle_buffer(SearchType::ByProtocol(&DevicePathToText::GUID))
879886
.map_err(DevicePathToTextError::CantLocateHandleBuffer)?
880887
.first()
881888
.ok_or(DevicePathToTextError::NoHandle)?;
882889

883890
unsafe {
884-
boot::open_protocol::<DevicePathToText>(
891+
bs.open_protocol::<DevicePathToText>(
885892
OpenProtocolParams {
886893
handle,
887-
agent: boot::image_handle(),
894+
agent: bs.image_handle(),
888895
controller: None,
889896
},
890897
OpenProtocolAttributes::GetProtocol,

uefi/src/proto/device_path/text.rs

+29-18
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
use crate::proto::device_path::{DevicePath, DevicePathNode};
1212
use crate::proto::unsafe_protocol;
13-
use crate::{boot, CStr16, Char16, Result, Status};
13+
use crate::table::boot::BootServices;
14+
use crate::{CStr16, Char16, Result, Status};
1415
use core::ops::Deref;
15-
use core::ptr::NonNull;
1616
use uefi_raw::protocol::device_path::{DevicePathFromTextProtocol, DevicePathToTextProtocol};
1717

1818
/// This struct is a wrapper of `display_only` parameter
@@ -42,27 +42,36 @@ pub struct AllowShortcuts(pub bool);
4242
/// Wrapper for a string internally allocated from
4343
/// UEFI boot services memory.
4444
#[derive(Debug)]
45-
pub struct PoolString(NonNull<Char16>);
45+
pub struct PoolString<'a> {
46+
boot_services: &'a BootServices,
47+
text: *const Char16,
48+
}
4649

47-
impl PoolString {
48-
fn new(text: *const Char16) -> Result<Self> {
49-
NonNull::new(text.cast_mut())
50-
.map(Self)
51-
.ok_or(Status::OUT_OF_RESOURCES.into())
50+
impl<'a> PoolString<'a> {
51+
fn new(boot_services: &'a BootServices, text: *const Char16) -> Result<Self> {
52+
if text.is_null() {
53+
Err(Status::OUT_OF_RESOURCES.into())
54+
} else {
55+
Ok(Self {
56+
boot_services,
57+
text,
58+
})
59+
}
5260
}
5361
}
5462

55-
impl Deref for PoolString {
63+
impl<'a> Deref for PoolString<'a> {
5664
type Target = CStr16;
5765

5866
fn deref(&self) -> &Self::Target {
59-
unsafe { CStr16::from_ptr(self.0.as_ptr()) }
67+
unsafe { CStr16::from_ptr(self.text) }
6068
}
6169
}
6270

63-
impl Drop for PoolString {
71+
impl Drop for PoolString<'_> {
6472
fn drop(&mut self) {
65-
unsafe { boot::free_pool(self.0.cast()) }.expect("Failed to free pool [{addr:#?}]");
73+
let addr = self.text as *mut u8;
74+
unsafe { self.boot_services.free_pool(addr) }.expect("Failed to free pool [{addr:#?}]");
6675
}
6776
}
6877

@@ -82,20 +91,21 @@ impl DevicePathToText {
8291
/// memory for the conversion.
8392
///
8493
/// [`OUT_OF_RESOURCES`]: Status::OUT_OF_RESOURCES
85-
pub fn convert_device_node_to_text(
94+
pub fn convert_device_node_to_text<'boot>(
8695
&self,
96+
boot_services: &'boot BootServices,
8797
device_node: &DevicePathNode,
8898
display_only: DisplayOnly,
8999
allow_shortcuts: AllowShortcuts,
90-
) -> Result<PoolString> {
100+
) -> Result<PoolString<'boot>> {
91101
let text_device_node = unsafe {
92102
(self.0.convert_device_node_to_text)(
93103
device_node.as_ffi_ptr().cast(),
94104
display_only.0,
95105
allow_shortcuts.0,
96106
)
97107
};
98-
PoolString::new(text_device_node.cast())
108+
PoolString::new(boot_services, text_device_node.cast())
99109
}
100110

101111
/// Convert a device path to its text representation.
@@ -104,20 +114,21 @@ impl DevicePathToText {
104114
/// memory for the conversion.
105115
///
106116
/// [`OUT_OF_RESOURCES`]: Status::OUT_OF_RESOURCES
107-
pub fn convert_device_path_to_text(
117+
pub fn convert_device_path_to_text<'boot>(
108118
&self,
119+
boot_services: &'boot BootServices,
109120
device_path: &DevicePath,
110121
display_only: DisplayOnly,
111122
allow_shortcuts: AllowShortcuts,
112-
) -> Result<PoolString> {
123+
) -> Result<PoolString<'boot>> {
113124
let text_device_path = unsafe {
114125
(self.0.convert_device_path_to_text)(
115126
device_path.as_ffi_ptr().cast(),
116127
display_only.0,
117128
allow_shortcuts.0,
118129
)
119130
};
120-
PoolString::new(text_device_path.cast())
131+
PoolString::new(boot_services, text_device_path.cast())
121132
}
122133
}
123134

0 commit comments

Comments
 (0)