@@ -6,6 +6,7 @@ use crate::proto::unsafe_protocol;
66use crate :: { CStr16 , Char16 , Error , Result , Status , StatusExt } ;
77use core:: ptr;
88use uefi_raw:: protocol:: shell:: ShellProtocol ;
9+ use alloc:: vec:: Vec ;
910
1011/// Shell Protocol
1112#[ derive( Debug ) ]
@@ -54,4 +55,82 @@ impl Shell {
5455 let dir_ptr: * const Char16 = directory. map_or ( ptr:: null ( ) , |x| x. as_ptr ( ) ) ;
5556 unsafe { ( self . 0 . set_cur_dir ) ( fs_ptr. cast ( ) , dir_ptr. cast ( ) ) } . to_result ( )
5657 }
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+ }
57136}
0 commit comments