1
1
use crate :: os:: windows:: prelude:: * ;
2
2
3
+ use crate :: borrow:: Cow ;
3
4
use crate :: ffi:: OsString ;
4
5
use crate :: fmt;
5
6
use crate :: io:: { self , BorrowedCursor , Error , IoSlice , IoSliceMut , SeekFrom } ;
@@ -719,7 +720,7 @@ impl<'a> DirBuffIter<'a> {
719
720
}
720
721
}
721
722
impl < ' a > Iterator for DirBuffIter < ' a > {
722
- type Item = ( & ' a [ u16 ] , bool ) ;
723
+ type Item = ( Cow < ' a , [ u16 ] > , bool ) ;
723
724
fn next ( & mut self ) -> Option < Self :: Item > {
724
725
use crate :: mem:: size_of;
725
726
let buffer = & self . buffer ?[ self . cursor ..] ;
@@ -742,7 +743,7 @@ impl<'a> Iterator for DirBuffIter<'a> {
742
743
let next_entry = ptr:: addr_of!( ( * info) . NextEntryOffset ) . read_unaligned ( ) as usize ;
743
744
let length = ptr:: addr_of!( ( * info) . FileNameLength ) . read_unaligned ( ) as usize ;
744
745
let attrs = ptr:: addr_of!( ( * info) . FileAttributes ) . read_unaligned ( ) ;
745
- let name = crate :: slice :: from_raw_parts (
746
+ let name = from_maybe_unaligned (
746
747
ptr:: addr_of!( ( * info) . FileName ) . cast :: < u16 > ( ) ,
747
748
length / size_of :: < u16 > ( ) ,
748
749
) ;
@@ -759,13 +760,21 @@ impl<'a> Iterator for DirBuffIter<'a> {
759
760
760
761
// Skip `.` and `..` pseudo entries.
761
762
const DOT : u16 = b'.' as u16 ;
762
- match name {
763
+ match & name[ .. ] {
763
764
[ DOT ] | [ DOT , DOT ] => self . next ( ) ,
764
765
_ => Some ( ( name, is_directory) ) ,
765
766
}
766
767
}
767
768
}
768
769
770
+ unsafe fn from_maybe_unaligned < ' a > ( p : * const u16 , len : usize ) -> Cow < ' a , [ u16 ] > {
771
+ if p. is_aligned ( ) {
772
+ Cow :: Borrowed ( crate :: slice:: from_raw_parts ( p, len) )
773
+ } else {
774
+ Cow :: Owned ( ( 0 ..len) . map ( |i| p. add ( i) . read_unaligned ( ) ) . collect ( ) )
775
+ }
776
+ }
777
+
769
778
/// Open a link relative to the parent directory, ensure no symlinks are followed.
770
779
fn open_link_no_reparse ( parent : & File , name : & [ u16 ] , access : u32 ) -> io:: Result < File > {
771
780
// This is implemented using the lower level `NtCreateFile` function as
@@ -1121,13 +1130,13 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
1121
1130
if is_directory {
1122
1131
let child_dir = open_link_no_reparse (
1123
1132
& dir,
1124
- name,
1133
+ & name,
1125
1134
c:: SYNCHRONIZE | c:: DELETE | c:: FILE_LIST_DIRECTORY ,
1126
1135
) ?;
1127
1136
dirlist. push ( child_dir) ;
1128
1137
} else {
1129
1138
for i in 1 ..=MAX_RETRIES {
1130
- let result = open_link_no_reparse ( & dir, name, c:: SYNCHRONIZE | c:: DELETE ) ;
1139
+ let result = open_link_no_reparse ( & dir, & name, c:: SYNCHRONIZE | c:: DELETE ) ;
1131
1140
match result {
1132
1141
Ok ( f) => delete ( & f) ?,
1133
1142
// Already deleted, so skip.
0 commit comments