@@ -11,6 +11,8 @@ use core::fmt;
11
11
use core:: fmt:: { Debug , Formatter } ;
12
12
use core:: ops:: Deref ;
13
13
use log:: debug;
14
+ use uefi:: CStr16 ;
15
+ use uefi_macros:: cstr16;
14
16
15
17
/// Return type for public [`FileSystem`] operations.
16
18
pub type FileSystemResult < T > = Result < T , Error > ;
@@ -156,6 +158,8 @@ impl<'a> FileSystem<'a> {
156
158
pub fn remove_dir ( & mut self , path : impl AsRef < Path > ) -> FileSystemResult < ( ) > {
157
159
let path = path. as_ref ( ) ;
158
160
161
+ // log::trace!("delete dir {}", path);
162
+
159
163
let file = self
160
164
. open ( path, UefiFileMode :: ReadWrite , false ) ?
161
165
. into_type ( )
@@ -181,16 +185,42 @@ impl<'a> FileSystem<'a> {
181
185
}
182
186
}
183
187
184
- /*/ // Removes a directory at this path, after removing all its contents. Use
188
+ /// Removes a directory at this path, after removing all its contents. Use
185
189
/// carefully!
186
190
pub fn remove_dir_all ( & mut self , path : impl AsRef < Path > ) -> FileSystemResult < ( ) > {
191
+ const SKIP_DIRS : [ & CStr16 ; 2 ] = [ cstr16 ! ( "." ) , cstr16 ! ( ".." ) ] ;
187
192
let path = path. as_ref ( ) ;
188
- }*/
193
+ for file_info in self
194
+ . read_dir ( path) ?
195
+ . filter_map ( |file_info_result| file_info_result. ok ( ) )
196
+ {
197
+ if SKIP_DIRS . contains ( & file_info. file_name ( ) ) {
198
+ continue ;
199
+ }
200
+
201
+ let mut abs_entry_path = PathBuf :: new ( ) ;
202
+ abs_entry_path. push ( path) ;
203
+ abs_entry_path. push ( file_info. file_name ( ) ) ;
204
+ if file_info. is_directory ( ) {
205
+ // delete all inner files
206
+ // This recursion is fine as there are no links in UEFI/FAT file
207
+ // systems. No cycles possible.
208
+ self . remove_dir_all ( & abs_entry_path) ?;
209
+ } else {
210
+ self . remove_file ( abs_entry_path) ?;
211
+ }
212
+ }
213
+ // Now that the dir is empty, we delete it as final step.
214
+ self . remove_dir ( path) ?;
215
+ Ok ( ( ) )
216
+ }
189
217
190
218
/// Removes a file from the filesystem.
191
219
pub fn remove_file ( & mut self , path : impl AsRef < Path > ) -> FileSystemResult < ( ) > {
192
220
let path = path. as_ref ( ) ;
193
221
222
+ // log::trace!("delete file {}", path);
223
+
194
224
let file = self
195
225
. open ( path, UefiFileMode :: ReadWrite , false ) ?
196
226
. into_type ( )
@@ -282,17 +312,17 @@ impl<'a> FileSystem<'a> {
282
312
/// absolute path.
283
313
///
284
314
/// May create a file if [`UefiFileMode::CreateReadWrite`] is set. May
285
- /// create a directory if [`UefiFileMode::CreateReadWrite`] and `is_dir `
286
- /// is set.
315
+ /// create a directory if [`UefiFileMode::CreateReadWrite`] and `create_dir `
316
+ /// is set. The parameter `create_dir` is ignored otherwise.
287
317
fn open (
288
318
& mut self ,
289
319
path : & Path ,
290
320
mode : UefiFileMode ,
291
- is_dir : bool ,
321
+ create_dir : bool ,
292
322
) -> FileSystemResult < UefiFileHandle > {
293
323
validate_path ( path) ?;
294
324
295
- let attr = if mode == UefiFileMode :: CreateReadWrite && is_dir {
325
+ let attr = if mode == UefiFileMode :: CreateReadWrite && create_dir {
296
326
UefiFileAttribute :: DIRECTORY
297
327
} else {
298
328
UefiFileAttribute :: empty ( )
0 commit comments