Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 92e07bb

Browse files
committed
uefi: Implementing wrappers for EFI Shell env and cur_dir functions
This commit implements wrappers for the following EFI Shell Protocol functions: set_env(), get_env(), set_cur_dir(), and get_cur_dir().
1 parent 70a63b8 commit 92e07bb

File tree

1 file changed

+130
-1
lines changed

1 file changed

+130
-1
lines changed

‎uefi/src/proto/shell/mod.rs

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,141 @@
22

33
//! EFI Shell Protocol v2.2
44
5-
use crate::proto::unsafe_protocol;
5+
#![cfg(feature = "alloc")]
6+
7+
use alloc::vec::Vec;
8+
use uefi_macros::unsafe_protocol;
9+
use uefi_raw::Status;
10+
11+
use core::ptr;
612

713
pub use uefi_raw::protocol::shell::ShellProtocol;
814

15+
use crate::{CStr16, Char16};
16+
917
/// Shell Protocol
1018
#[derive(Debug)]
1119
#[repr(transparent)]
1220
#[unsafe_protocol(uefi_raw::protocol::shell::ShellProtocol::GUID)]
1321
pub struct Shell(uefi_raw::protocol::shell::ShellProtocol);
22+
23+
impl Shell {
24+
/// Gets the environment variable or list of environment variables
25+
///
26+
/// # Arguments
27+
///
28+
/// * `name` - The environment variable name of which to retrieve the
29+
/// value
30+
/// If None, will return all defined shell environment
31+
/// variables
32+
///
33+
/// # Returns
34+
///
35+
/// * `Some(Vec<env_value>)` - Value of the environment variable
36+
/// * `Some(Vec<env_names>)` - Vector of environment variable names
37+
/// * `None` - Environment variable doesn't exist
38+
#[must_use]
39+
pub fn get_env<'a>(&'a self, name: Option<&CStr16>) -> Option<Vec<&'a CStr16>> {
40+
let mut env_vec = Vec::new();
41+
match name {
42+
Some(n) => {
43+
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(n).cast();
44+
let var_val = unsafe { (self.0.get_env)(name_ptr.cast()) };
45+
if var_val.is_null() {
46+
return None;
47+
} else {
48+
unsafe { env_vec.push(CStr16::from_ptr(var_val.cast())) };
49+
}
50+
}
51+
None => {
52+
let cur_env_ptr = unsafe { (self.0.get_env)(ptr::null()) };
53+
54+
let mut cur_start = cur_env_ptr;
55+
let mut cur_len = 0;
56+
57+
let mut i = 0;
58+
let mut null_count = 0;
59+
unsafe {
60+
while null_count <= 1 {
61+
if (*(cur_env_ptr.add(i))) == Char16::from_u16_unchecked(0).into() {
62+
if cur_len > 0 {
63+
env_vec.push(CStr16::from_char16_with_nul_unchecked(
64+
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
65+
));
66+
}
67+
cur_len = 0;
68+
null_count += 1;
69+
} else {
70+
if null_count > 0 {
71+
cur_start = cur_env_ptr.add(i);
72+
}
73+
null_count = 0;
74+
cur_len += 1;
75+
}
76+
i += 1;
77+
}
78+
}
79+
}
80+
}
81+
Some(env_vec)
82+
}
83+
84+
/// Sets the environment variable
85+
///
86+
/// # Arguments
87+
///
88+
/// * `name` - The environment variable for which to set the value
89+
/// * `value` - The new value of the environment variable
90+
/// * `volatile` - Indicates whether or not the variable is volatile or
91+
/// not
92+
///
93+
/// # Returns
94+
///
95+
/// * `Status::SUCCESS` The variable was successfully set
96+
pub fn set_env(&self, name: &CStr16, value: &CStr16, volatile: bool) -> Status {
97+
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(name).cast();
98+
let value_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(value).cast();
99+
unsafe { (self.0.set_env)(name_ptr.cast(), value_ptr.cast(), volatile) }
100+
}
101+
102+
/// Returns the current directory on the specified device
103+
///
104+
/// # Arguments
105+
///
106+
/// * `file_system_mapping` - The file system mapping for which to get
107+
/// the current directory
108+
/// # Returns
109+
///
110+
/// * `Some(cwd)` - CStr16 containing the current working directory
111+
/// * `None` - Could not retrieve current directory
112+
#[must_use]
113+
pub fn get_cur_dir<'a>(&'a self, file_system_mapping: Option<&CStr16>) -> Option<&'a CStr16> {
114+
let mapping_ptr: *const Char16 = file_system_mapping.map_or(ptr::null(), |x| (x.as_ptr()));
115+
let cur_dir = unsafe { (self.0.get_cur_dir)(mapping_ptr.cast()) };
116+
if cur_dir.is_null() {
117+
None
118+
} else {
119+
unsafe { Some(CStr16::from_ptr(cur_dir.cast())) }
120+
}
121+
}
122+
123+
/// Changes the current directory on the specified device
124+
///
125+
/// # Arguments
126+
///
127+
/// * `file_system` - Pointer to the file system's mapped name.
128+
/// * `directory` - Points to the directory on the device specified by
129+
/// `file_system`.
130+
/// # Returns
131+
///
132+
/// * `Status::SUCCESS` The directory was successfully set
133+
///
134+
/// # Errors
135+
///
136+
/// * `Status::EFI_NOT_FOUND` The directory does not exist
137+
pub fn set_cur_dir(&self, file_system: Option<&CStr16>, directory: Option<&CStr16>) -> Status {
138+
let fs_ptr: *const Char16 = file_system.map_or(ptr::null(), |x| (x.as_ptr()));
139+
let dir_ptr: *const Char16 = directory.map_or(ptr::null(), |x| (x.as_ptr()));
140+
unsafe { (self.0.set_cur_dir)(fs_ptr.cast(), dir_ptr.cast()) }
141+
}
142+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /