@@ -6,6 +6,7 @@ use crate::proto::unsafe_protocol;
6
6
use crate :: { CStr16 , Char16 , Error , Result , Status , StatusExt } ;
7
7
use core:: ptr;
8
8
use uefi_raw:: protocol:: shell:: ShellProtocol ;
9
+ use alloc:: vec:: Vec ;
9
10
10
11
/// Shell Protocol
11
12
#[ derive( Debug ) ]
@@ -54,4 +55,82 @@ impl Shell {
54
55
let dir_ptr: * const Char16 = directory. map_or ( ptr:: null ( ) , |x| x. as_ptr ( ) ) ;
55
56
unsafe { ( self . 0 . set_cur_dir ) ( fs_ptr. cast ( ) , dir_ptr. cast ( ) ) } . to_result ( )
56
57
}
58
+
59
+ /// Gets the environment variable or list of environment variables
60
+ ///
61
+ /// # Arguments
62
+ ///
63
+ /// * `name` - The environment variable name of which to retrieve the
64
+ /// value
65
+ /// If None, will return all defined shell environment
66
+ /// variables
67
+ ///
68
+ /// # Returns
69
+ ///
70
+ /// * `Some(Vec<env_value>)` - Value of the environment variable
71
+ /// * `Some(Vec<env_names>)` - Vector of environment variable names
72
+ /// * `None` - Environment variable doesn't exist
73
+ #[ must_use]
74
+ pub fn get_env < ' a > ( & ' a self , name : Option < & CStr16 > ) -> Option < Vec < & ' a CStr16 > > {
75
+ let mut env_vec = Vec :: new ( ) ;
76
+ match name {
77
+ Some ( n) => {
78
+ let name_ptr: * const Char16 = core:: ptr:: from_ref :: < CStr16 > ( n) . cast ( ) ;
79
+ let var_val = unsafe { ( self . 0 . get_env ) ( name_ptr. cast ( ) ) } ;
80
+ if var_val. is_null ( ) {
81
+ return None ;
82
+ } else {
83
+ unsafe { env_vec. push ( CStr16 :: from_ptr ( var_val. cast ( ) ) ) } ;
84
+ }
85
+ }
86
+ None => {
87
+ let cur_env_ptr = unsafe { ( self . 0 . get_env ) ( ptr:: null ( ) ) } ;
88
+
89
+ let mut cur_start = cur_env_ptr;
90
+ let mut cur_len = 0 ;
91
+
92
+ let mut i = 0 ;
93
+ let mut null_count = 0 ;
94
+ unsafe {
95
+ while null_count <= 1 {
96
+ if ( * ( cur_env_ptr. add ( i) ) ) == Char16 :: from_u16_unchecked ( 0 ) . into ( ) {
97
+ if cur_len > 0 {
98
+ env_vec. push ( CStr16 :: from_char16_with_nul_unchecked (
99
+ & ( * ptr:: slice_from_raw_parts ( cur_start. cast ( ) , cur_len + 1 ) ) ,
100
+ ) ) ;
101
+ }
102
+ cur_len = 0 ;
103
+ null_count += 1 ;
104
+ } else {
105
+ if null_count > 0 {
106
+ cur_start = cur_env_ptr. add ( i) ;
107
+ }
108
+ null_count = 0 ;
109
+ cur_len += 1 ;
110
+ }
111
+ i += 1 ;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ Some ( env_vec)
117
+ }
118
+
119
+ /// Sets the environment variable
120
+ ///
121
+ /// # Arguments
122
+ ///
123
+ /// * `name` - The environment variable for which to set the value
124
+ /// * `value` - The new value of the environment variable
125
+ /// * `volatile` - Indicates whether or not the variable is volatile or
126
+ /// not
127
+ ///
128
+ /// # Returns
129
+ ///
130
+ /// * `Status::SUCCESS` The variable was successfully set
131
+ pub fn set_env ( & self , name : & CStr16 , value : & CStr16 , volatile : bool ) -> Status {
132
+ let name_ptr: * const Char16 = core:: ptr:: from_ref :: < CStr16 > ( name) . cast ( ) ;
133
+ let value_ptr: * const Char16 = core:: ptr:: from_ref :: < CStr16 > ( value) . cast ( ) ;
134
+ unsafe { ( self . 0 . set_env ) ( name_ptr. cast ( ) , value_ptr. cast ( ) , volatile) }
135
+ }
57
136
}
0 commit comments