Skip to content

Commit 502aecd

Browse files
committed
Move uefi-exts into core as an optional feature
1 parent e9fc29d commit 502aecd

File tree

11 files changed

+99
-126
lines changed

11 files changed

+99
-126
lines changed

Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
[package]
22
name = "uefi"
3-
version = "0.3.1"
3+
version = "0.3.2"
44
authors = ["Gabriel Majeri <[email protected]>"]
55
readme = "README.md"
66
edition = "2018"
7-
exclude = ["uefi-test-runner/**"]
7+
exclude = [
8+
"uefi-macros/**",
9+
"uefi-services/**",
10+
"uefi-test-runner/**",
11+
]
812
description = "Safe and easy-to-use wrapper for building UEFI apps"
913
repository = "https://github.com/rust-osdev/uefi-rs"
1014
keywords = ["uefi", "efi"]
@@ -19,6 +23,7 @@ is-it-maintained-open-issues = { repository = "rust-osdev/uefi-rs" }
1923
[features]
2024
default = []
2125
alloc = []
26+
exts = []
2227
logger = []
2328

2429
[dependencies]
@@ -29,7 +34,6 @@ uefi-macros = "0.2.1"
2934

3035
[workspace]
3136
members = [
32-
"uefi-exts",
3337
"uefi-macros",
3438
"uefi-services",
3539
"uefi-test-runner",

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ This project contains multiple sub-crates:
4444
- `logger`: logging implementation for the standard [log] crate.
4545
- Prints output to console.
4646
- No buffering is done: this is not a high-performance logger.
47-
48-
- `uefi-exts`: extension traits providing utility functions for common patterns.
49-
- Requires the `alloc` crate (either enable the `alloc` optional feature or your own custom allocator).
47+
- `exts`: extensions providing utility functions for common patterns.
48+
- Requires the `alloc` crate (either enable the `alloc` optional feature or your own custom allocator).
5049

5150
- `uefi-macros`: procedural macros that are used to derive some traits in `uefi`.
5251

uefi-exts/src/lib.rs renamed to src/exts.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,16 @@
11
//! Utility functions for the most common UEFI patterns.
2-
//!
3-
//! This crate simply exports some extension traits
4-
//! which add utility functions to various UEFI objects.
52
6-
#![no_std]
7-
#![feature(alloc_layout_extra, allocator_api)]
8-
9-
extern crate alloc;
10-
11-
mod boot;
12-
mod file;
13-
14-
pub use self::boot::BootServicesExt;
15-
pub use self::file::FileExt;
16-
17-
use alloc::{
3+
use alloc_api::{
184
alloc::{handle_alloc_error, Alloc, Global, Layout},
195
boxed::Box,
206
};
217
use core::slice;
228

239
/// Creates a boxed byte buffer using the standard allocator
10+
///
2411
/// # Panics
25-
/// Calls handle_alloc_error if the layout has a size of zero or allocation fails.
12+
///
13+
/// Calls `handle_alloc_error` if the layout has a size of zero or allocation fails.
2614
pub fn allocate_buffer(layout: Layout) -> Box<[u8]> {
2715
if layout.size() == 0 {
2816
handle_alloc_error(layout);

src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@
2323
//! For example, a PC with no network card might not contain a network driver,
2424
//! therefore all the network protocols will be unavailable.
2525
26+
#![cfg_attr(feature = "exts", feature(allocator_api, alloc_layout_extra))]
2627
#![feature(optin_builtin_traits)]
2728
#![feature(try_trait)]
2829
#![no_std]
2930
// Enable some additional warnings and lints.
3031
#![warn(missing_docs, unused)]
3132
#![deny(clippy::all)]
3233

34+
// `uefi-exts` requires access to memory allocation APIs.
35+
#[cfg(feature = "exts")]
36+
extern crate alloc as alloc_api;
37+
3338
#[macro_use]
3439
pub mod data_types;
3540
pub use self::data_types::{unsafe_guid, Identify};
@@ -47,5 +52,8 @@ pub mod prelude;
4752
#[cfg(feature = "alloc")]
4853
pub mod alloc;
4954

55+
#[cfg(feature = "exts")]
56+
pub mod exts;
57+
5058
#[cfg(feature = "logger")]
5159
pub mod logger;

src/proto/media/file/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ mod regular;
1212

1313
use crate::prelude::*;
1414
use crate::{CStr16, Char16, Guid, Result, Status};
15+
#[cfg(feature = "exts")]
16+
use alloc_api::{alloc::Layout, boxed::Box};
1517
use bitflags::bitflags;
1618
use core::ffi::c_void;
1719
use core::mem;
@@ -168,6 +170,47 @@ pub trait File: Sized {
168170
fn flush(&mut self) -> Result {
169171
(self.imp().flush)(self.imp()).into()
170172
}
173+
174+
#[cfg(feature = "exts")]
175+
/// Get the dynamically allocated info for a file
176+
fn get_boxed_info<Info: FileProtocolInfo + ?Sized>(&mut self) -> Result<Box<Info>> {
177+
// Initially try get_info with an empty array, this should always fail
178+
// as all Info types at least need room for a null-terminator.
179+
let size = match self
180+
.get_info::<Info>(&mut [])
181+
.expect_error("zero sized get_info unexpectedly succeeded")
182+
.split()
183+
{
184+
(s, None) => return Err(s.into()),
185+
(_, Some(size)) => size,
186+
};
187+
188+
// We add trailing padding because the size of a rust structure must
189+
// always be a multiple of alignment.
190+
let layout = Layout::from_size_align(size, Info::alignment())
191+
.unwrap()
192+
.pad_to_align()
193+
.unwrap();
194+
let mut buffer = crate::exts::allocate_buffer(layout);
195+
let buffer_start = buffer.as_ptr();
196+
197+
let info = self
198+
.get_info(&mut buffer)
199+
.discard_errdata()?
200+
.map(|info_ref| {
201+
// This operation is safe because info uses the exact memory
202+
// of the provied buffer (so no memory is leaked), and the box
203+
// is created if and only if buffer is leaked (so no memory can
204+
// ever be freed twice).
205+
206+
assert_eq!(mem::size_of_val(info_ref), layout.size());
207+
assert_eq!(info_ref as *const Info as *const u8, buffer_start);
208+
unsafe { Box::from_raw(info_ref as *mut _) }
209+
});
210+
mem::forget(buffer);
211+
212+
Ok(info)
213+
}
171214
}
172215

173216
// Internal File helper methods to access the funciton pointer table.

src/table/boot.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use super::Header;
44
use crate::data_types::Align;
55
use crate::proto::Protocol;
66
use crate::{Event, Guid, Handle, Result, Status};
7+
#[cfg(feature = "exts")]
8+
use alloc_api::vec::Vec;
79
use bitflags::bitflags;
810
use core::cell::UnsafeCell;
911
use core::ffi::c_void;
@@ -485,6 +487,38 @@ impl BootServices {
485487
}
486488
}
487489

490+
#[cfg(feature = "exts")]
491+
impl BootServices {
492+
/// Returns all the handles implementing a certain protocol.
493+
pub fn find_handles<P: Protocol>(&self) -> Result<Vec<Handle>> {
494+
// Search by protocol.
495+
let search_type = SearchType::from_proto::<P>();
496+
497+
// Determine how much we need to allocate.
498+
let (status1, buffer_size) = self.locate_handle(search_type, None)?.split();
499+
500+
// Allocate a large enough buffer.
501+
let mut buffer = Vec::with_capacity(buffer_size);
502+
503+
unsafe {
504+
buffer.set_len(buffer_size);
505+
}
506+
507+
// Perform the search.
508+
let (status2, buffer_size) = self.locate_handle(search_type, Some(&mut buffer))?.split();
509+
510+
// Once the vector has been filled, update its size.
511+
unsafe {
512+
buffer.set_len(buffer_size);
513+
}
514+
515+
// Emit output, with warnings
516+
status1
517+
.into_with_val(|| buffer)
518+
.map(|completion| completion.with_status(status2))
519+
}
520+
}
521+
488522
impl super::Table for BootServices {
489523
const SIGNATURE: u64 = 0x5652_4553_544f_4f42;
490524
}

uefi-exts/Cargo.toml

Lines changed: 0 additions & 9 deletions
This file was deleted.

uefi-exts/src/boot.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.

uefi-exts/src/file.rs

Lines changed: 0 additions & 51 deletions
This file was deleted.

uefi-test-runner/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ publish = false
66
edition = "2018"
77

88
[dependencies]
9-
uefi = { path = ".." }
9+
uefi = { path = "..", features = ['exts'] }
1010
uefi-services = { path = "../uefi-services" }
11-
uefi-exts = { path = "../uefi-exts" }
1211

1312
log = { version = "0.4.8", default-features = false }
1413

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use uefi::prelude::*;
2-
use uefi_exts::BootServicesExt;
32

43
use uefi::proto;
54

0 commit comments

Comments
 (0)