@@ -1035,7 +1035,7 @@ impl Dir {
10351035 to_dir : & Self ,
10361036 to : Q ,
10371037 ) -> io:: Result < ( ) > {
1038- run_path_with_wcstr ( to. as_ref ( ) , & |to| self . rename_native ( from. as_ref ( ) , to_dir, to, false ) )
1038+ run_path_with_utf16 ( to. as_ref ( ) , & |to| self . rename_native ( from. as_ref ( ) , to_dir, to, false ) )
10391039 }
10401040
10411041 pub fn symlink < P : AsRef < Path > , Q : AsRef < Path > > ( & self , original : P , link : Q ) -> io:: Result < ( ) > {
@@ -1139,58 +1139,64 @@ impl Dir {
11391139 if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
11401140 }
11411141
1142- fn rename_native ( & self , from : & Path , to_dir : & Self , to : & WCStr , dir : bool ) -> io:: Result < ( ) > {
1142+ fn rename_native ( & self , from : & Path , to_dir : & Self , to : & [ u16 ] , dir : bool ) -> io:: Result < ( ) > {
11431143 let mut opts = OpenOptions :: new ( ) ;
11441144 opts. access_mode ( c:: DELETE ) ;
11451145 opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
11461146 let handle = run_path_with_utf16 ( from, & |u| self . open_native ( u, & opts, dir) ) ?;
1147- // Calculate the layout of the `FILE_RENAME_INFO ` we pass to `SetFileInformation `
1147+ // Calculate the layout of the `FILE_RENAME_INFORMATION ` we pass to `NtSetInformationFile `
11481148 // This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
11491149 const too_long_err: io:: Error =
11501150 io:: const_error!( io:: ErrorKind :: InvalidFilename , "Filename too long" ) ;
11511151 let struct_size = to
1152- . count_bytes ( )
1152+ . len ( )
11531153 . checked_mul ( 2 )
1154- . and_then ( |x| x. checked_add ( offset_of ! ( c:: FILE_RENAME_INFO , FileName ) ) )
1154+ . and_then ( |x| x. checked_add ( offset_of ! ( c:: FILE_RENAME_INFORMATION , FileName ) ) )
11551155 . ok_or ( too_long_err) ?;
1156- let layout = Layout :: from_size_align ( struct_size, align_of :: < c:: FILE_RENAME_INFO > ( ) )
1156+ let layout = Layout :: from_size_align ( struct_size, align_of :: < c:: FILE_RENAME_INFORMATION > ( ) )
11571157 . map_err ( |_| too_long_err) ?;
11581158 let struct_size = u32:: try_from ( struct_size) . map_err ( |_| too_long_err) ?;
1159- let to_byte_len_without_nul =
1160- u32:: try_from ( ( to. count_bytes ( ) - 1 ) * 2 ) . map_err ( |_| too_long_err) ?;
1159+ let to_byte_len = u32:: try_from ( to. len ( ) * 2 ) . map_err ( |_| too_long_err) ?;
11611160
11621161 let file_rename_info;
1163- // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename.
1162+ // SAFETY: We allocate enough memory for a full FILE_RENAME_INFORMATION struct and the filename.
11641163 unsafe {
1165- file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFO > ( ) ;
1164+ file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFORMATION > ( ) ;
11661165 if file_rename_info. is_null ( ) {
11671166 return Err ( io:: ErrorKind :: OutOfMemory . into ( ) ) ;
11681167 }
11691168
1170- ( & raw mut ( * file_rename_info) . Anonymous ) . write ( c:: FILE_RENAME_INFO_0 {
1169+ ( & raw mut ( * file_rename_info) . Anonymous ) . write ( c:: FILE_RENAME_INFORMATION_0 {
11711170 Flags : c:: FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c:: FILE_RENAME_FLAG_POSIX_SEMANTICS ,
11721171 } ) ;
11731172
11741173 ( & raw mut ( * file_rename_info) . RootDirectory ) . write ( to_dir. handle . as_raw_handle ( ) ) ;
11751174 // Don't include the NULL in the size
1176- ( & raw mut ( * file_rename_info) . FileNameLength ) . write ( to_byte_len_without_nul ) ;
1175+ ( & raw mut ( * file_rename_info) . FileNameLength ) . write ( to_byte_len ) ;
11771176
11781177 to. as_ptr ( ) . copy_to_nonoverlapping (
11791178 ( & raw mut ( * file_rename_info) . FileName ) . cast :: < u16 > ( ) ,
1180- to. count_bytes ( ) ,
1179+ to. len ( ) ,
11811180 ) ;
11821181 }
11831182
1184- let result = unsafe {
1185- c:: SetFileInformationByHandle (
1183+ let status = unsafe {
1184+ c:: NtSetInformationFile (
11861185 handle. as_raw_handle ( ) ,
1187- c:: FileRenameInfoEx ,
1186+ & mut c:: IO_STATUS_BLOCK :: default ( ) ,
11881187 file_rename_info. cast :: < c_void > ( ) ,
11891188 struct_size,
1189+ c:: FileRenameInformation ,
11901190 )
11911191 } ;
11921192 unsafe { dealloc ( file_rename_info. cast :: < u8 > ( ) , layout) } ;
1193- if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
1193+ if c:: nt_success ( status) {
1194+ // SAFETY: nt_success guarantees that handle is no longer null
1195+ Ok ( ( ) )
1196+ } else {
1197+ Err ( WinError :: new ( unsafe { c:: RtlNtStatusToDosError ( status) } ) )
1198+ }
1199+ . io_result ( )
11941200 }
11951201
11961202 fn symlink_native ( & self , original : & [ u16 ] , link : & Path , relative : bool ) -> io:: Result < ( ) > {
0 commit comments