Skip to content

Commit 176361a

Browse files
committed
Improve Envirnoment Variables
Now using the ShellVariableGuid. Thus it is now possible to read shell variables. Signed-off-by: Ayush <ayushsingh1325@gmail.com>
1 parent 3bf5104 commit 176361a

File tree

1 file changed

+37
-28
lines changed
  • library/std/src/sys/uefi

1 file changed

+37
-28
lines changed

library/std/src/sys/uefi/os.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::fmt;
55
use crate::io;
66
use crate::marker::PhantomData;
77
use crate::os::uefi;
8+
use crate::os::uefi::ffi::OsStrExt;
89
use crate::os::uefi::io::status_to_io_error;
910
use crate::path::{self, PathBuf};
1011

@@ -96,12 +97,24 @@ pub fn getenv(key: &OsStr) -> Option<OsString> {
9697
}
9798

9899
pub fn setenv(key: &OsStr, val: &OsStr) -> io::Result<()> {
99-
// UEFI does not support empty variables
100-
if val.is_empty() { Ok(()) } else { uefi_vars::set_variable(key, val) }
100+
// Setting a variable with null value is same as unsetting it in UEFI
101+
if val.is_empty() {
102+
unsetenv(key)
103+
} else {
104+
unsafe {
105+
uefi_vars::set_variable_raw(
106+
key.to_ffi_string().as_mut_ptr(),
107+
val.len(),
108+
val.bytes().as_ptr() as *mut crate::ffi::c_void,
109+
)
110+
}
111+
}
101112
}
102113

103114
pub fn unsetenv(key: &OsStr) -> io::Result<()> {
104-
match uefi_vars::set_variable(key, OsStr::new("")) {
115+
match unsafe {
116+
uefi_vars::set_variable_raw(key.to_ffi_string().as_mut_ptr(), 0, crate::ptr::null_mut())
117+
} {
105118
Ok(_) => Ok(()),
106119
Err(e) => match e.kind() {
107120
// Its fine if the key does not exist
@@ -148,44 +161,40 @@ pub(crate) mod uefi_vars {
148161
use crate::os::uefi::ffi::OsStrExt;
149162
use crate::os::uefi::io::status_to_io_error;
150163

151-
const ENVIRONMENT_GUID: r_efi::efi::Guid = r_efi::efi::Guid::from_fields(
152-
0x49bb4029,
153-
0x7d2b,
154-
0x4bf7,
155-
0xa1,
156-
0x95,
157-
&[0x0f, 0x18, 0xa1, 0xa8, 0x85, 0xc9],
164+
// Using Shell Variable Guid from edk2/ShellPkg
165+
const SHELL_VARIABLE_GUID: r_efi::efi::Guid = r_efi::efi::Guid::from_fields(
166+
0x158def5a,
167+
0xf656,
168+
0x419c,
169+
0xb0,
170+
0x27,
171+
&[0x7a, 0x31, 0x92, 0xc0, 0x79, 0xd2],
158172
);
159173

160-
pub fn set_variable(key: &OsStr, val: &OsStr) -> io::Result<()> {
161-
set_variable_inner(key, val.bytes(), r_efi::efi::VARIABLE_BOOTSERVICE_ACCESS)
162-
}
163-
164-
fn set_variable_inner(key: &OsStr, val: &[u8], attr: u32) -> io::Result<()> {
174+
pub(crate) unsafe fn set_variable_raw(
175+
variable_name: *mut u16,
176+
data_size: usize,
177+
data: *mut crate::ffi::c_void,
178+
) -> io::Result<()> {
165179
let runtime_services =
166180
uefi::env::get_runtime_services().ok_or(common::RUNTIME_SERVICES_ERROR)?;
167-
// Store a copy of data since it is technically possible to manipulate it from other
168-
// applications
169-
let mut val_copy = val.to_vec();
170-
let val_len = val_copy.len();
171-
let mut guid = ENVIRONMENT_GUID;
181+
let mut guid = SHELL_VARIABLE_GUID;
172182
let r = unsafe {
173183
((*runtime_services.as_ptr()).set_variable)(
174-
key.to_ffi_string().as_mut_ptr(),
184+
variable_name,
175185
&mut guid,
176-
attr,
177-
val_len,
178-
val_copy.as_mut_ptr().cast(),
186+
r_efi::efi::VARIABLE_BOOTSERVICE_ACCESS,
187+
data_size,
188+
data,
179189
)
180190
};
181-
182191
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(()) }
183192
}
184193

185-
pub fn get_variable(key: &OsStr) -> Option<OsString> {
194+
pub(crate) fn get_variable(key: &OsStr) -> Option<OsString> {
186195
let runtime_services = uefi::env::get_runtime_services()?;
187196
let mut buf_size = 0;
188-
let mut guid = ENVIRONMENT_GUID;
197+
let mut guid = SHELL_VARIABLE_GUID;
189198
let r = unsafe {
190199
((*runtime_services.as_ptr()).get_variable)(
191200
key.to_ffi_string().as_mut_ptr(),
@@ -201,7 +210,7 @@ pub(crate) mod uefi_vars {
201210
}
202211

203212
let mut buf: Vec<u8> = Vec::with_capacity(buf_size);
204-
let mut guid = ENVIRONMENT_GUID;
213+
let mut guid = SHELL_VARIABLE_GUID;
205214
let r = unsafe {
206215
((*runtime_services.as_ptr()).get_variable)(
207216
key.to_ffi_string().as_mut_ptr(),

0 commit comments

Comments
 (0)