@@ -1035,7 +1035,7 @@ impl Dir {
1035
1035
to_dir : & Self ,
1036
1036
to : Q ,
1037
1037
) -> 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 ) )
1039
1039
}
1040
1040
1041
1041
pub fn symlink < P : AsRef < Path > , Q : AsRef < Path > > ( & self , original : P , link : Q ) -> io:: Result < ( ) > {
@@ -1139,58 +1139,64 @@ impl Dir {
1139
1139
if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
1140
1140
}
1141
1141
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 < ( ) > {
1143
1143
let mut opts = OpenOptions :: new ( ) ;
1144
1144
opts. access_mode ( c:: DELETE ) ;
1145
1145
opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1146
1146
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 `
1148
1148
// This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
1149
1149
const too_long_err: io:: Error =
1150
1150
io:: const_error!( io:: ErrorKind :: InvalidFilename , "Filename too long" ) ;
1151
1151
let struct_size = to
1152
- . count_bytes ( )
1152
+ . len ( )
1153
1153
. 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 ) ) )
1155
1155
. 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 > ( ) )
1157
1157
. map_err ( |_| too_long_err) ?;
1158
1158
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) ?;
1161
1160
1162
1161
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.
1164
1163
unsafe {
1165
- file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFO > ( ) ;
1164
+ file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFORMATION > ( ) ;
1166
1165
if file_rename_info. is_null ( ) {
1167
1166
return Err ( io:: ErrorKind :: OutOfMemory . into ( ) ) ;
1168
1167
}
1169
1168
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 {
1171
1170
Flags : c:: FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c:: FILE_RENAME_FLAG_POSIX_SEMANTICS ,
1172
1171
} ) ;
1173
1172
1174
1173
( & raw mut ( * file_rename_info) . RootDirectory ) . write ( to_dir. handle . as_raw_handle ( ) ) ;
1175
1174
// 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 ) ;
1177
1176
1178
1177
to. as_ptr ( ) . copy_to_nonoverlapping (
1179
1178
( & raw mut ( * file_rename_info) . FileName ) . cast :: < u16 > ( ) ,
1180
- to. count_bytes ( ) ,
1179
+ to. len ( ) ,
1181
1180
) ;
1182
1181
}
1183
1182
1184
- let result = unsafe {
1185
- c:: SetFileInformationByHandle (
1183
+ let status = unsafe {
1184
+ c:: NtSetInformationFile (
1186
1185
handle. as_raw_handle ( ) ,
1187
- c:: FileRenameInfoEx ,
1186
+ & mut c:: IO_STATUS_BLOCK :: default ( ) ,
1188
1187
file_rename_info. cast :: < c_void > ( ) ,
1189
1188
struct_size,
1189
+ c:: FileRenameInformation ,
1190
1190
)
1191
1191
} ;
1192
1192
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 ( )
1194
1200
}
1195
1201
1196
1202
fn symlink_native ( & self , original : & [ u16 ] , link : & Path , relative : bool ) -> io:: Result < ( ) > {
0 commit comments