@@ -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,35 +1133,35 @@ 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
1153
let to_byte_len_without_nul =
1154
- u32:: try_from ( ( to. count_bytes ( ) - 1 ) * 2 ) . map_err ( |_| too_long_err) ?;
1154
+ u32:: try_from ( ( to. len ( ) - 1 ) * 2 ) . map_err ( |_| too_long_err) ?;
1155
1155
1156
1156
let file_rename_info;
1157
- // 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.
1158
1158
unsafe {
1159
- file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFO > ( ) ;
1159
+ file_rename_info = alloc ( layout) . cast :: < c:: FILE_RENAME_INFORMATION > ( ) ;
1160
1160
if file_rename_info. is_null ( ) {
1161
1161
return Err ( io:: ErrorKind :: OutOfMemory . into ( ) ) ;
1162
1162
}
1163
1163
1164
- ( & 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 {
1165
1165
Flags : c:: FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c:: FILE_RENAME_FLAG_POSIX_SEMANTICS ,
1166
1166
} ) ;
1167
1167
@@ -1171,20 +1171,27 @@ impl Dir {
1171
1171
1172
1172
to. as_ptr ( ) . copy_to_nonoverlapping (
1173
1173
( & raw mut ( * file_rename_info) . FileName ) . cast :: < u16 > ( ) ,
1174
- to. count_bytes ( ) ,
1174
+ to. len ( ) ,
1175
1175
) ;
1176
1176
}
1177
1177
1178
- let result = unsafe {
1179
- c:: SetFileInformationByHandle (
1178
+ let status = unsafe {
1179
+ c:: NtSetInformationFile (
1180
1180
handle. as_raw_handle ( ) ,
1181
- c:: FileRenameInfoEx ,
1181
+ & mut c:: IO_STATUS_BLOCK :: default ( ) ,
1182
1182
file_rename_info. cast :: < c_void > ( ) ,
1183
1183
struct_size,
1184
+ c:: FileRenameInformation ,
1184
1185
)
1185
1186
} ;
1186
1187
unsafe { dealloc ( file_rename_info. cast :: < u8 > ( ) , layout) } ;
1187
- 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
+ unsafe { Ok ( ( ) ) }
1191
+ } else {
1192
+ Err ( WinError :: new ( unsafe { c:: RtlNtStatusToDosError ( status) } ) )
1193
+ }
1194
+ . io_result ( )
1188
1195
}
1189
1196
1190
1197
fn symlink_native ( & self , original : & [ u16 ] , link : & Path , relative : bool ) -> io:: Result < ( ) > {
0 commit comments