@@ -1030,7 +1030,7 @@ impl Dir {
10301030 to_dir : & Self ,
10311031 to : Q ,
10321032 ) -> io:: Result < ( ) > {
1033- run_path_with_wcstr ( to. as_ref ( ) , & |to| self . rename_native ( from. as_ref ( ) , to_dir, to, false ) )
1033+ run_path_with_utf16 ( to. as_ref ( ) , & |to| self . rename_native ( from. as_ref ( ) , to_dir, to, false ) )
10341034 }
10351035
10361036 pub fn symlink < P : AsRef < Path > , Q : AsRef < Path > > ( & self , original : P , link : Q ) -> io:: Result < ( ) > {
@@ -1134,58 +1134,64 @@ impl Dir {
11341134 if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
11351135 }
11361136
1137- fn rename_native ( & self , from : & Path , to_dir : & Self , to : & WCStr , dir : bool ) -> io:: Result < ( ) > {
1137+ fn rename_native ( & self , from : & Path , to_dir : & Self , to : & [ u16 ] , dir : bool ) -> io:: Result < ( ) > {
11381138 let mut opts = OpenOptions :: new ( ) ;
11391139 opts. access_mode ( c:: DELETE ) ;
11401140 opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
11411141 let handle = run_path_with_utf16 ( from, & |u| self . open_native ( u, & opts, dir) ) ?;
1142- // Calculate the layout of the `FILE_RENAME_INFO ` we pass to `SetFileInformation `
1142+ // Calculate the layout of the `FILE_RENAME_INFORMATION ` we pass to `NtSetInformationFile `
11431143 // This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
11441144 const too_long_err: io:: Error =
11451145 io:: const_error!( io:: ErrorKind :: InvalidFilename , "Filename too long" ) ;
11461146 let struct_size = to
1147- . count_bytes ( )
1147+ . len ( )
11481148 . checked_mul ( 2 )
1149- . and_then ( |x| x. checked_add ( offset_of ! ( c:: FILE_RENAME_INFO , FileName ) ) )
1149+ . and_then ( |x| x. checked_add ( offset_of ! ( c:: FILE_RENAME_INFORMATION , FileName ) ) )
11501150 . ok_or ( too_long_err) ?;
1151- let layout = Layout :: from_size_align ( struct_size, align_of :: < c:: FILE_RENAME_INFO > ( ) )
1151+ let layout = Layout :: from_size_align ( struct_size, align_of :: < c:: FILE_RENAME_INFORMATION > ( ) )
11521152 . map_err ( |_| too_long_err) ?;
11531153 let struct_size = u32:: try_from ( struct_size) . map_err ( |_| too_long_err) ?;
1154- let to_byte_len_without_nul =
1155- u32:: try_from ( ( to. count_bytes ( ) - 1 ) * 2 ) . map_err ( |_| too_long_err) ?;
1154+ let to_byte_len = u32:: try_from ( to. len ( ) * 2 ) . map_err ( |_| too_long_err) ?;
11561155
11571156 let file_rename_info;
1158- // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename.
1157+ // SAFETY: We allocate enough memory for a full FILE_RENAME_INFORMATION struct and the filename.
11591158 unsafe {
1160- file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFO > ( ) ;
1159+ file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFORMATION > ( ) ;
11611160 if file_rename_info. is_null ( ) {
11621161 return Err ( io:: ErrorKind :: OutOfMemory . into ( ) ) ;
11631162 }
11641163
1165- ( & raw mut ( * file_rename_info) . Anonymous ) . write ( c:: FILE_RENAME_INFO_0 {
1164+ ( & raw mut ( * file_rename_info) . Anonymous ) . write ( c:: FILE_RENAME_INFORMATION_0 {
11661165 Flags : c:: FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c:: FILE_RENAME_FLAG_POSIX_SEMANTICS ,
11671166 } ) ;
11681167
11691168 ( & raw mut ( * file_rename_info) . RootDirectory ) . write ( to_dir. handle . as_raw_handle ( ) ) ;
11701169 // Don't include the NULL in the size
1171- ( & raw mut ( * file_rename_info) . FileNameLength ) . write ( to_byte_len_without_nul ) ;
1170+ ( & raw mut ( * file_rename_info) . FileNameLength ) . write ( to_byte_len ) ;
11721171
11731172 to. as_ptr ( ) . copy_to_nonoverlapping (
11741173 ( & raw mut ( * file_rename_info) . FileName ) . cast :: < u16 > ( ) ,
1175- to. count_bytes ( ) ,
1174+ to. len ( ) ,
11761175 ) ;
11771176 }
11781177
1179- let result = unsafe {
1180- c:: SetFileInformationByHandle (
1178+ let status = unsafe {
1179+ c:: NtSetInformationFile (
11811180 handle. as_raw_handle ( ) ,
1182- c:: FileRenameInfoEx ,
1181+ & mut c:: IO_STATUS_BLOCK :: default ( ) ,
11831182 file_rename_info. cast :: < c_void > ( ) ,
11841183 struct_size,
1184+ c:: FileRenameInformation ,
11851185 )
11861186 } ;
11871187 unsafe { dealloc ( file_rename_info. cast :: < u8 > ( ) , layout) } ;
1188- if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
1188+ if c:: nt_success ( status) {
1189+ // SAFETY: nt_success guarantees that handle is no longer null
1190+ Ok ( ( ) )
1191+ } else {
1192+ Err ( WinError :: new ( unsafe { c:: RtlNtStatusToDosError ( status) } ) )
1193+ }
1194+ . io_result ( )
11891195 }
11901196
11911197 fn symlink_native ( & self , original : & [ u16 ] , link : & Path , relative : bool ) -> io:: Result < ( ) > {
0 commit comments