Skip to content

Commit e6eeb4e

Browse files
committed
uefi: Add process
Signed-off-by: Ayush Singh <[email protected]>
1 parent c99ebd4 commit e6eeb4e

File tree

3 files changed

+399
-2
lines changed

3 files changed

+399
-2
lines changed

std/src/sys/pal/uefi/helpers.rs

+71-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use r_efi::efi::{self, Guid};
1313
use r_efi::protocols::{device_path, device_path_to_text};
1414

15-
use crate::ffi::OsString;
15+
use crate::ffi::{OsString, OsStr};
1616
use crate::io::{self, const_io_error};
1717
use crate::mem::{size_of, MaybeUninit};
1818
use crate::os::uefi::{self, env::boot_services, ffi::OsStringExt};
@@ -221,3 +221,73 @@ pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>>
221221
let runtime_services = unsafe { (*system_table.as_ptr()).runtime_services };
222222
NonNull::new(runtime_services)
223223
}
224+
225+
pub(crate) struct DevicePath(NonNull<r_efi::protocols::device_path::Protocol>);
226+
227+
impl DevicePath {
228+
pub(crate) fn from_text(p: &OsStr) -> io::Result<Self> {
229+
fn inner(
230+
p: &OsStr,
231+
protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,
232+
) -> io::Result<DevicePath> {
233+
let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>();
234+
let path =
235+
unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };
236+
237+
NonNull::new(path).map(DevicePath).ok_or_else(|| {
238+
const_io_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")
239+
})
240+
}
241+
242+
static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
243+
AtomicPtr::new(crate::ptr::null_mut());
244+
245+
if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
246+
if let Ok(protocol) = open_protocol::<r_efi::protocols::device_path_from_text::Protocol>(
247+
handle,
248+
r_efi::protocols::device_path_from_text::PROTOCOL_GUID,
249+
) {
250+
return inner(p, protocol);
251+
}
252+
}
253+
254+
let handles = locate_handles(r_efi::protocols::device_path_from_text::PROTOCOL_GUID)?;
255+
for handle in handles {
256+
if let Ok(protocol) = open_protocol::<r_efi::protocols::device_path_from_text::Protocol>(
257+
handle,
258+
r_efi::protocols::device_path_from_text::PROTOCOL_GUID,
259+
) {
260+
LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
261+
return inner(p, protocol);
262+
}
263+
}
264+
265+
io::Result::Err(const_io_error!(
266+
io::ErrorKind::NotFound,
267+
"DevicePathFromText Protocol not found"
268+
))
269+
}
270+
}
271+
272+
impl AsRef<r_efi::protocols::device_path::Protocol> for DevicePath {
273+
fn as_ref(&self) -> &r_efi::protocols::device_path::Protocol {
274+
unsafe { self.0.as_ref() }
275+
}
276+
}
277+
278+
impl AsMut<r_efi::protocols::device_path::Protocol> for DevicePath {
279+
fn as_mut(&mut self) -> &mut r_efi::protocols::device_path::Protocol {
280+
unsafe { self.0.as_mut() }
281+
}
282+
}
283+
284+
impl Drop for DevicePath {
285+
fn drop(&mut self) {
286+
if let Some(bt) = boot_services() {
287+
let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
288+
unsafe {
289+
((*bt.as_ptr()).free_pool)(self.0.as_ptr() as *mut crate::ffi::c_void);
290+
}
291+
}
292+
}
293+
}

std/src/sys/pal/uefi/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ pub mod net;
2525
pub mod os;
2626
#[path = "../unsupported/pipe.rs"]
2727
pub mod pipe;
28-
#[path = "../unsupported/process.rs"]
2928
pub mod process;
3029
pub mod stdio;
3130
pub mod thread;

0 commit comments

Comments
 (0)