@@ -1029,7 +1029,7 @@ impl Dir {
1029
1029
to_dir : & Self ,
1030
1030
to : Q ,
1031
1031
) -> io:: Result < ( ) > {
1032
- run_path_with_wcstr ( to. as_ref ( ) , & |to| self . rename_native ( from. as_ref ( ) , to_dir, to, false ) )
1032
+ run_path_with_utf16 ( to. as_ref ( ) , & |to| self . rename_native ( from. as_ref ( ) , to_dir, to, false ) )
1033
1033
}
1034
1034
1035
1035
pub fn symlink < P : AsRef < Path > , Q : AsRef < Path > > ( & self , original : P , link : Q ) -> io:: Result < ( ) > {
@@ -1133,58 +1133,64 @@ impl Dir {
1133
1133
if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
1134
1134
}
1135
1135
1136
- fn rename_native ( & self , from : & Path , to_dir : & Self , to : & WCStr , dir : bool ) -> io:: Result < ( ) > {
1136
+ fn rename_native ( & self , from : & Path , to_dir : & Self , to : & [ u16 ] , dir : bool ) -> io:: Result < ( ) > {
1137
1137
let mut opts = OpenOptions :: new ( ) ;
1138
1138
opts. access_mode ( c:: DELETE ) ;
1139
1139
opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1140
1140
let handle = run_path_with_utf16 ( from, & |u| self . open_native ( u, & opts, dir) ) ?;
1141
- // Calculate the layout of the `FILE_RENAME_INFO ` we pass to `SetFileInformation `
1141
+ // Calculate the layout of the `FILE_RENAME_INFORMATION ` we pass to `NtSetInformationFile `
1142
1142
// This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
1143
1143
const too_long_err: io:: Error =
1144
1144
io:: const_error!( io:: ErrorKind :: InvalidFilename , "Filename too long" ) ;
1145
1145
let struct_size = to
1146
- . count_bytes ( )
1146
+ . len ( )
1147
1147
. checked_mul ( 2 )
1148
- . and_then ( |x| x. checked_add ( offset_of ! ( c:: FILE_RENAME_INFO , FileName ) ) )
1148
+ . and_then ( |x| x. checked_add ( offset_of ! ( c:: FILE_RENAME_INFORMATION , FileName ) ) )
1149
1149
. ok_or ( too_long_err) ?;
1150
- let layout = Layout :: from_size_align ( struct_size, align_of :: < c:: FILE_RENAME_INFO > ( ) )
1150
+ let layout = Layout :: from_size_align ( struct_size, align_of :: < c:: FILE_RENAME_INFORMATION > ( ) )
1151
1151
. map_err ( |_| too_long_err) ?;
1152
1152
let struct_size = u32:: try_from ( struct_size) . map_err ( |_| too_long_err) ?;
1153
- let to_byte_len_without_nul =
1154
- u32:: try_from ( ( to. count_bytes ( ) - 1 ) * 2 ) . map_err ( |_| too_long_err) ?;
1153
+ let to_byte_len = u32:: try_from ( to. len ( ) * 2 ) . map_err ( |_| too_long_err) ?;
1155
1154
1156
1155
let file_rename_info;
1157
- // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename.
1156
+ // SAFETY: We allocate enough memory for a full FILE_RENAME_INFORMATION struct and the filename.
1158
1157
unsafe {
1159
- file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFO > ( ) ;
1158
+ file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFORMATION > ( ) ;
1160
1159
if file_rename_info. is_null ( ) {
1161
1160
return Err ( io:: ErrorKind :: OutOfMemory . into ( ) ) ;
1162
1161
}
1163
1162
1164
- ( & raw mut ( * file_rename_info) . Anonymous ) . write ( c:: FILE_RENAME_INFO_0 {
1163
+ ( & raw mut ( * file_rename_info) . Anonymous ) . write ( c:: FILE_RENAME_INFORMATION_0 {
1165
1164
Flags : c:: FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c:: FILE_RENAME_FLAG_POSIX_SEMANTICS ,
1166
1165
} ) ;
1167
1166
1168
1167
( & raw mut ( * file_rename_info) . RootDirectory ) . write ( to_dir. handle . as_raw_handle ( ) ) ;
1169
1168
// Don't include the NULL in the size
1170
- ( & raw mut ( * file_rename_info) . FileNameLength ) . write ( to_byte_len_without_nul ) ;
1169
+ ( & raw mut ( * file_rename_info) . FileNameLength ) . write ( to_byte_len ) ;
1171
1170
1172
1171
to. as_ptr ( ) . copy_to_nonoverlapping (
1173
1172
( & raw mut ( * file_rename_info) . FileName ) . cast :: < u16 > ( ) ,
1174
- to. count_bytes ( ) ,
1173
+ to. len ( ) ,
1175
1174
) ;
1176
1175
}
1177
1176
1178
- let result = unsafe {
1179
- c:: SetFileInformationByHandle (
1177
+ let status = unsafe {
1178
+ c:: NtSetInformationFile (
1180
1179
handle. as_raw_handle ( ) ,
1181
- c:: FileRenameInfoEx ,
1180
+ & mut c:: IO_STATUS_BLOCK :: default ( ) ,
1182
1181
file_rename_info. cast :: < c_void > ( ) ,
1183
1182
struct_size,
1183
+ c:: FileRenameInformation ,
1184
1184
)
1185
1185
} ;
1186
1186
unsafe { dealloc ( file_rename_info. cast :: < u8 > ( ) , layout) } ;
1187
- if result == 0 { Err ( api:: get_last_error ( ) ) . io_result ( ) } else { Ok ( ( ) ) }
1187
+ if c:: nt_success ( status) {
1188
+ // SAFETY: nt_success guarantees that handle is no longer null
1189
+ Ok ( ( ) )
1190
+ } else {
1191
+ Err ( WinError :: new ( unsafe { c:: RtlNtStatusToDosError ( status) } ) )
1192
+ }
1193
+ . io_result ( )
1188
1194
}
1189
1195
1190
1196
fn symlink_native ( & self , original : & [ u16 ] , link : & Path , relative : bool ) -> io:: Result < ( ) > {
0 commit comments