11//! EFI Shell Protocol v2.2
22
3- use core:: { ffi:: c_void, marker:: PhantomData , mem:: MaybeUninit , ptr:: NonNull } ;
3+ use core:: { ffi:: c_void, marker:: PhantomData , mem:: MaybeUninit , ptr} ;
44
55use uefi_macros:: unsafe_protocol;
66
@@ -18,7 +18,9 @@ pub struct Shell {
1818 environment : * const * const CStr16 ,
1919 out_status : * mut Status ,
2020 ) -> Status ,
21- get_env : usize ,
21+ get_env : extern "efiapi" fn (
22+ name : * const Char16 ,
23+ ) -> * const Char16 ,
2224 set_env : usize ,
2325 get_alias : usize ,
2426 set_alias : usize ,
@@ -29,7 +31,7 @@ pub struct Shell {
2931 get_file_path_from_device_path : usize ,
3032 set_map : usize ,
3133
32- get_cur_dir : extern "efiapi" fn ( file_system_mapping : * const Char16 ) -> * const CStr16 ,
34+ get_cur_dir : extern "efiapi" fn ( file_system_mapping : * const Char16 ) -> * const Char16 ,
3335 set_cur_dir : usize ,
3436 open_file_list : usize ,
3537 free_file_list : extern "efiapi" fn ( file_list : * mut * mut ShellFileInfo ) ,
@@ -49,7 +51,7 @@ pub struct Shell {
4951 create_file : extern "efiapi" fn (
5052 file_name : & CStr16 ,
5153 file_attribs : u64 ,
52- out_file_handle : * mut ShellFileHandle ,
54+ out_file_handle : ShellFileHandle ,
5355 ) -> Status ,
5456 read_file : usize ,
5557 write_file : usize ,
@@ -66,7 +68,10 @@ pub struct Shell {
6668 file_dir_handle : ShellFileHandle ,
6769 out_file_list : * mut * mut ShellFileInfo ,
6870 ) -> Status ,
69- get_file_size : usize ,
71+ get_file_size : extern "efiapi" fn (
72+ file_handle : ShellFileHandle ,
73+ size : * mut u64
74+ ) -> Status ,
7075
7176 open_root : usize ,
7277 open_root_by_handle : usize ,
@@ -109,6 +114,29 @@ impl Shell {
109114 . to_result_with_val ( || unsafe { out_status. assume_init ( ) } )
110115 }
111116
117+ /// Gets the environment variable or list of environment variables
118+ ///
119+ /// # Arguments
120+ ///
121+ /// * `name` - The environment variable name of which to retrieve the
122+ /// value
123+ /// If None, will return all defined shell environment
124+ /// variables
125+ ///
126+ /// # Returns
127+ ///
128+ /// * `Some(env_value)` - Value of the environment variable
129+ /// * `None` - Environment variable doesn't exist
130+ pub fn get_env < ' a > ( & ' a self , name : Option < & CStr16 > ) -> Option < & ' a CStr16 > {
131+ let name_ptr: * const Char16 = name. map_or ( core:: ptr:: null ( ) , |x| ( x as * const CStr16 ) . cast ( ) ) ;
132+ let var_val = ( self . get_env ) ( name_ptr) ;
133+ if var_val. is_null ( ) {
134+ None
135+ } else {
136+ unsafe { Some ( CStr16 :: from_ptr ( var_val) ) }
137+ }
138+ }
139+
112140 /// TODO
113141 #[ must_use]
114142 pub fn get_cur_dir < ' a > ( & ' a self , file_system_mapping : Option < & CStr16 > ) -> Option < & ' a CStr16 > {
@@ -118,7 +146,7 @@ impl Shell {
118146 if cur_dir. is_null ( ) {
119147 None
120148 } else {
121- unsafe { Some ( & * cur_dir) }
149+ unsafe { Some ( CStr16 :: from_ptr ( cur_dir) ) }
122150 }
123151 }
124152
@@ -146,20 +174,30 @@ impl Shell {
146174 ( self . close_file ) ( file_handle) . to_result ( )
147175 }
148176
149- /// TODO
177+ /// Creates a file or directory by name
178+ ///
179+ /// # Arguments
180+ ///
181+ /// * `file_name` - Name of the file to be created (null terminated)
182+ /// * `file_attribs` - Attributes of the new file
183+ /// * `file_handle` - On return, points to the created file/directory's
184+ /// handle
150185 pub fn create_file (
151186 & self ,
152187 file_name : & CStr16 ,
153188 file_attribs : u64 ,
154- ) -> Result < Option < ShellFileHandle > > {
189+ ) -> Result < ShellFileHandle > {
155190 // TODO: Find out how we could take a &str instead, or maybe AsRef<str>, though I think it needs `alloc`
156191 // the returned handle can possibly be NULL, so we need to wrap `ShellFileHandle` in an `Option`
157- let mut out_file_handle: MaybeUninit < Option < ShellFileHandle > > = MaybeUninit :: zeroed ( ) ;
192+ //let mut out_file_handle: MaybeUninit<Option<ShellFileHandle>> = MaybeUninit::zeroed();
193+ // let mut file_handle: ShellFileHandle;
194+ let file_handle = ptr:: null ( ) ;
158195
159- ( self . create_file ) ( file_name, file_attribs, out_file_handle. as_mut_ptr ( ) . cast ( ) )
196+ ( self . create_file ) ( file_name, file_attribs, file_handle)
197+ . to_result_with_val ( || file_handle )
160198 // Safety: if this call is successful, `out_file_handle`
161199 // will always be initialized and valid.
162- . to_result_with_val ( || unsafe { out_file_handle. assume_init ( ) } )
200+ // .to_result_with_val(|| unsafe { out_file_handle.assume_init() })
163201 }
164202
165203 /// TODO
@@ -233,12 +271,34 @@ impl Shell {
233271 pub fn flush_file ( & self , file_handle : ShellFileHandle ) -> Result < ( ) > {
234272 ( self . flush_file ) ( file_handle) . to_result ( )
235273 }
274+
275+ /// Gets the size of a file
276+ ///
277+ /// # Arguments
278+ ///
279+ /// * `file_handle` - Handle to the file of which the size will be retrieved
280+ /// * `size` - Pointer to u64 to read into
281+ ///
282+ /// # Errors
283+ ///
284+ /// * [`STATUS::EFI_DEVICE_ERROR] The file could not be accessed
285+ pub fn get_file_size ( & self , file_handle : ShellFileHandle , size : * mut u64 ) -> Result < ( ) > {
286+ ( self . get_file_size ) ( file_handle, size) . to_result ( )
287+ }
236288}
237289
238290/// TODO
239- #[ repr( transparent) ]
240- #[ derive( Debug ) ]
241- pub struct ShellFileHandle ( NonNull < c_void > ) ;
291+ // #[repr(transparent)]
292+ // #[derive(Debug)]
293+ pub type ShellFileHandle = * const c_void ;
294+ // pub struct ShellFileHandle(c_void);
295+ //
296+ // impl ShellFileHandle {
297+ // /// Creates a new ShellFileHandle from a given c_void pointer
298+ // pub const unsafe fn new(ptr: c_void) -> Self {
299+ // Self(ptr)
300+ // }
301+ // }
242302
243303/// TODO
244304#[ repr( C ) ]
0 commit comments