@@ -5,6 +5,7 @@ use crate::fmt;
5
5
use crate :: io;
6
6
use crate :: marker:: PhantomData ;
7
7
use crate :: os:: uefi;
8
+ use crate :: os:: uefi:: ffi:: OsStrExt ;
8
9
use crate :: os:: uefi:: io:: status_to_io_error;
9
10
use crate :: path:: { self , PathBuf } ;
10
11
@@ -96,12 +97,24 @@ pub fn getenv(key: &OsStr) -> Option<OsString> {
96
97
}
97
98
98
99
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
+ }
101
112
}
102
113
103
114
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
+ } {
105
118
Ok ( _) => Ok ( ( ) ) ,
106
119
Err ( e) => match e. kind ( ) {
107
120
// Its fine if the key does not exist
@@ -148,44 +161,40 @@ pub(crate) mod uefi_vars {
148
161
use crate :: os:: uefi:: ffi:: OsStrExt ;
149
162
use crate :: os:: uefi:: io:: status_to_io_error;
150
163
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 ] ,
158
172
) ;
159
173
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 < ( ) > {
165
179
let runtime_services =
166
180
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 ;
172
182
let r = unsafe {
173
183
( ( * runtime_services. as_ptr ( ) ) . set_variable ) (
174
- key . to_ffi_string ( ) . as_mut_ptr ( ) ,
184
+ variable_name ,
175
185
& 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 ,
179
189
)
180
190
} ;
181
-
182
191
if r. is_error ( ) { Err ( status_to_io_error ( r) ) } else { Ok ( ( ) ) }
183
192
}
184
193
185
- pub fn get_variable ( key : & OsStr ) -> Option < OsString > {
194
+ pub ( crate ) fn get_variable ( key : & OsStr ) -> Option < OsString > {
186
195
let runtime_services = uefi:: env:: get_runtime_services ( ) ?;
187
196
let mut buf_size = 0 ;
188
- let mut guid = ENVIRONMENT_GUID ;
197
+ let mut guid = SHELL_VARIABLE_GUID ;
189
198
let r = unsafe {
190
199
( ( * runtime_services. as_ptr ( ) ) . get_variable ) (
191
200
key. to_ffi_string ( ) . as_mut_ptr ( ) ,
@@ -201,7 +210,7 @@ pub(crate) mod uefi_vars {
201
210
}
202
211
203
212
let mut buf: Vec < u8 > = Vec :: with_capacity ( buf_size) ;
204
- let mut guid = ENVIRONMENT_GUID ;
213
+ let mut guid = SHELL_VARIABLE_GUID ;
205
214
let r = unsafe {
206
215
( ( * runtime_services. as_ptr ( ) ) . get_variable ) (
207
216
key. to_ffi_string ( ) . as_mut_ptr ( ) ,
0 commit comments