11//! Module for [`FileSystem`].
22
33use super :: * ;
4+ use crate :: fs;
5+ use crate :: fs:: path:: validation:: { validate_path, PathError } ;
46use crate :: proto:: media:: file:: { FileAttribute , FileInfo , FileType } ;
57use crate :: table:: boot:: ScopedProtocol ;
68use alloc:: boxed:: Box ;
@@ -12,6 +14,7 @@ use core::fmt::{Debug, Formatter};
1214use core:: ops:: Deref ;
1315use derive_more:: Display ;
1416use log:: info;
17+ use uefi:: Char16 ;
1518
1619/// All errors that can happen when working with the [`FileSystem`].
1720#[ derive( Debug , Clone , Display , PartialEq , Eq ) ]
@@ -40,12 +43,26 @@ pub enum FileSystemError {
4043 ReadFailure ,
4144 /// Can't parse file content as UTF-8.
4245 Utf8Error ( FromUtf8Error ) ,
43- /// Could not open the given path.
44- OpenError ( String ) ,
46+ /// Could not open the given path. Carries the path that could not be opened
47+ /// and the underlying UEFI error.
48+ #[ display( fmt = "{path:?}" ) ]
49+ OpenError {
50+ path : String ,
51+ error : crate :: Error < >
52+ } ,
4553}
4654
4755#[ cfg( feature = "unstable" ) ]
48- impl core:: error:: Error for FileSystemError { }
56+ impl core:: error:: Error for FileSystemError {
57+ fn source ( & self ) -> Option < & ( dyn Error + ' static ) > {
58+ match self {
59+ FileSystemError :: IllegalPath ( e) => Some ( e) ,
60+ FileSystemError :: Utf8Error ( e) => Some ( e) ,
61+ FileSystemError :: OpenError ( _path, e) => Some ( e) ,
62+ _ => None ,
63+ }
64+ }
65+ }
4966
5067impl From < PathError > for FileSystemError {
5168 fn from ( err : PathError ) -> Self {
@@ -90,16 +107,13 @@ impl<'a> FileSystem<'a> {
90107 let path = path. as_ref ( ) ;
91108 self . open ( path, UefiFileMode :: CreateReadWrite , true )
92109 . map ( |_| ( ) )
93- . map_err ( |err| {
94- log:: debug!( "failed to fetch file info: {err:#?}" ) ;
95- FileSystemError :: OpenError ( path. to_string ( ) )
96- } )
97110 }
98111
99112 /// Recursively create a directory and all of its parent components if they
100113 /// are missing.
101114 pub fn create_dir_all ( & mut self , path : impl AsRef < Path > ) -> FileSystemResult < ( ) > {
102- let path = path. as_ref ( ) ;
115+ todo ! ( )
116+ /*let path = path.as_ref();
103117
104118 let normalized_path = NormalizedPath::new("\\", path)?;
105119 let normalized_path_string = normalized_path.to_string();
@@ -115,19 +129,21 @@ impl<'a> FileSystem<'a> {
115129 info!("path_acc: {path_acc}, component: {component}");
116130 Some((component, path_acc.clone()))
117131 })
118- . try_for_each ( |( _component, full_path) | self . create_dir ( full_path. as_str ( ) ) )
132+ .try_for_each(|(_component, full_path)| self.create_dir(full_path.to_cstr16 ()))*/
119133 }
120134
121135 /// Given a path, query the file system to get information about a file,
122136 /// directory, etc. Returns [`UefiFileInfo`].
123137 pub fn metadata ( & mut self , path : impl AsRef < Path > ) -> FileSystemResult < Box < UefiFileInfo > > {
124138 let path = path. as_ref ( ) ;
125139 let file = self . open ( path, UefiFileMode :: Read , false ) ?;
126- log:: debug!( "{:#?}" , & file. into_type( ) . unwrap( ) ) ;
127140 let mut file = self . open ( path, UefiFileMode :: Read , false ) ?;
128141 file. get_boxed_info ( ) . map_err ( |err| {
129142 log:: debug!( "failed to fetch file info: {err:#?}" ) ;
130- FileSystemError :: OpenError ( path. to_string ( ) )
143+ FileSystemError :: OpenError {
144+ path : path. to_cstr16 ( ) . to_string ( ) ,
145+ error : err
146+ }
131147 } )
132148 }
133149
@@ -138,10 +154,12 @@ impl<'a> FileSystem<'a> {
138154 let mut file = self
139155 . open ( path, UefiFileMode :: Read , false ) ?
140156 . into_regular_file ( )
141- . ok_or ( FileSystemError :: NotAFile ( path. as_str ( ) . to_string ( ) ) ) ?;
142- let info = file. get_boxed_info :: < FileInfo > ( ) . map_err ( |e| {
143- log:: error!( "get info failed: {e:?}" ) ;
144- FileSystemError :: OpenError ( path. as_str ( ) . to_string ( ) )
157+ . ok_or ( FileSystemError :: NotAFile ( path. to_cstr16 ( ) . to_string ( ) ) ) ?;
158+ let info = file. get_boxed_info :: < FileInfo > ( ) . map_err ( |err| {
159+ FileSystemError :: OpenError {
160+ path : path. to_cstr16 ( ) . to_string ( ) ,
161+ error : err
162+ }
145163 } ) ?;
146164
147165 let mut vec = vec ! [ 0 ; info. file_size( ) as usize ] ;
@@ -164,7 +182,7 @@ impl<'a> FileSystem<'a> {
164182 let dir = self
165183 . open ( path, UefiFileMode :: Read , false ) ?
166184 . into_directory ( )
167- . ok_or ( FileSystemError :: NotADirectory ( path. as_str ( ) . to_string ( ) ) ) ?;
185+ . ok_or ( FileSystemError :: NotADirectory ( path. to_cstr16 ( ) . to_string ( ) ) ) ?;
168186 Ok ( UefiDirectoryIter :: new ( dir) )
169187 }
170188
@@ -185,9 +203,9 @@ impl<'a> FileSystem<'a> {
185203 match file {
186204 FileType :: Dir ( dir) => dir. delete ( ) . map_err ( |e| {
187205 log:: error!( "error removing dir: {e:?}" ) ;
188- FileSystemError :: CantDeleteDirectory ( path. as_str ( ) . to_string ( ) )
206+ FileSystemError :: CantDeleteDirectory ( path. to_cstr16 ( ) . to_string ( ) )
189207 } ) ,
190- FileType :: Regular ( _) => Err ( FileSystemError :: NotADirectory ( path. as_str ( ) . to_string ( ) ) ) ,
208+ FileType :: Regular ( _) => Err ( FileSystemError :: NotADirectory ( path. to_cstr16 ( ) . to_string ( ) ) ) ,
191209 }
192210 }
193211
@@ -209,9 +227,9 @@ impl<'a> FileSystem<'a> {
209227 match file {
210228 FileType :: Regular ( file) => file. delete ( ) . map_err ( |e| {
211229 log:: error!( "error removing file: {e:?}" ) ;
212- FileSystemError :: CantDeleteFile ( path. as_str ( ) . to_string ( ) )
230+ FileSystemError :: CantDeleteFile ( path. to_cstr16 ( ) . to_string ( ) )
213231 } ) ,
214- FileType :: Dir ( _) => Err ( FileSystemError :: NotAFile ( path. as_str ( ) . to_string ( ) ) ) ,
232+ FileType :: Dir ( _) => Err ( FileSystemError :: NotAFile ( path. to_cstr16 ( ) . to_string ( ) ) ) ,
215233 }
216234 }
217235
@@ -278,19 +296,24 @@ impl<'a> FileSystem<'a> {
278296 mode : UefiFileMode ,
279297 is_dir : bool ,
280298 ) -> FileSystemResult < UefiFileHandle > {
281- let path = NormalizedPath :: new ( " \\ " , path) ?;
282- log:: debug !( "normalized path: {path}" ) ;
299+ validate_path ( path) ?;
300+ log:: trace !( "open validated path: {path}" ) ;
283301
284302 let attr = if mode == UefiFileMode :: CreateReadWrite && is_dir {
285303 FileAttribute :: DIRECTORY
286304 } else {
287305 FileAttribute :: empty ( )
288306 } ;
289307
290- self . open_root ( ) ?. open ( & path, mode, attr) . map_err ( |x| {
291- log:: trace!( "Can't open file {path}: {x:?}" ) ;
292- FileSystemError :: OpenError ( path. to_string ( ) )
293- } )
308+ self . open_root ( ) ?
309+ . open ( path. to_cstr16 ( ) , mode, attr)
310+ . map_err ( |err| {
311+ log:: trace!( "Can't open file {path}: {err:?}" ) ;
312+ FileSystemError :: OpenError {
313+ path : path. to_cstr16 ( ) . to_string ( ) ,
314+ error : err
315+ }
316+ } )
294317 }
295318}
296319
0 commit comments