Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5951166

Browse files
committed
change rename implementation
1 parent a7bc6c3 commit 5951166

File tree

3 files changed

+55
-17
lines changed

3 files changed

+55
-17
lines changed

‎library/std/src/sys/fs/windows.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
&mutc::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<()> {

‎library/std/src/sys/pal/windows/c/bindings.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,6 +2075,7 @@ FILE_READ_EA
20752075
FILE_RENAME_FLAG_POSIX_SEMANTICS
20762076
FILE_RENAME_FLAG_REPLACE_IF_EXISTS
20772077
FILE_RENAME_INFO
2078+
FILE_RENAME_INFORMATION
20782079
FILE_RESERVE_OPFILTER
20792080
FILE_SEQUENTIAL_ONLY
20802081
FILE_SESSION_AWARE
@@ -2120,6 +2121,8 @@ FileNormalizedNameInfo
21202121
FileRemoteProtocolInfo
21212122
FileRenameInfo
21222123
FileRenameInfoEx
2124+
FileRenameInformation
2125+
FileRenameInformationEx
21232126
FileStandardInfo
21242127
FileStorageInfo
21252128
FileStreamInfo
@@ -2301,6 +2304,7 @@ NTCREATEFILE_CREATE_DISPOSITION
23012304
NTCREATEFILE_CREATE_OPTIONS
23022305
NtOpenFile
23032306
NtReadFile
2307+
NtSetInformationFile
23042308
NTSTATUS
23052309
NtWriteFile
23062310
OBJ_CASE_INSENSITIVE

‎library/std/src/sys/pal/windows/c/windows_sys.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage :
7474
windows_targets::link!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
7575
windows_targets::link!("ntdll.dll" "system" fn NtOpenFile(filehandle : *mut HANDLE, desiredaccess : u32, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, shareaccess : u32, openoptions : u32) -> NTSTATUS);
7676
windows_targets::link!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
77+
windows_targets::link!("ntdll.dll" "system" fn NtSetInformationFile(filehandle : HANDLE, iostatusblock : *mut IO_STATUS_BLOCK, fileinformation : *const core::ffi::c_void, length : u32, fileinformationclass : FILE_INFORMATION_CLASS) -> NTSTATUS);
7778
windows_targets::link!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
7879
windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle : HANDLE, desiredaccess : TOKEN_ACCESS_MASK, tokenhandle : *mut HANDLE) -> BOOL);
7980
windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL);
@@ -2530,6 +2531,7 @@ impl Default for FILE_ID_BOTH_DIR_INFO {
25302531
unsafe { core::mem::zeroed() }
25312532
}
25322533
}
2534+
pub type FILE_INFORMATION_CLASS = i32;
25332535
pub type FILE_INFO_BY_HANDLE_CLASS = i32;
25342536
#[repr(C)]
25352537
#[derive(Clone, Copy, Default)]
@@ -2591,6 +2593,30 @@ impl Default for FILE_RENAME_INFO_0 {
25912593
unsafe { core::mem::zeroed() }
25922594
}
25932595
}
2596+
#[repr(C)]
2597+
#[derive(Clone, Copy)]
2598+
pub struct FILE_RENAME_INFORMATION {
2599+
pub Anonymous: FILE_RENAME_INFORMATION_0,
2600+
pub RootDirectory: HANDLE,
2601+
pub FileNameLength: u32,
2602+
pub FileName: [u16; 1],
2603+
}
2604+
impl Default for FILE_RENAME_INFORMATION {
2605+
fn default() -> Self {
2606+
unsafe { core::mem::zeroed() }
2607+
}
2608+
}
2609+
#[repr(C)]
2610+
#[derive(Clone, Copy)]
2611+
pub union FILE_RENAME_INFORMATION_0 {
2612+
pub ReplaceIfExists: bool,
2613+
pub Flags: u32,
2614+
}
2615+
impl Default for FILE_RENAME_INFORMATION_0 {
2616+
fn default() -> Self {
2617+
unsafe { core::mem::zeroed() }
2618+
}
2619+
}
25942620
pub const FILE_RESERVE_OPFILTER: NTCREATEFILE_CREATE_OPTIONS = 1048576u32;
25952621
pub const FILE_SEQUENTIAL_ONLY: NTCREATEFILE_CREATE_OPTIONS = 4u32;
25962622
pub const FILE_SESSION_AWARE: NTCREATEFILE_CREATE_OPTIONS = 262144u32;
@@ -2698,6 +2724,8 @@ pub const FileNormalizedNameInfo: FILE_INFO_BY_HANDLE_CLASS = 24i32;
26982724
pub const FileRemoteProtocolInfo: FILE_INFO_BY_HANDLE_CLASS = 13i32;
26992725
pub const FileRenameInfo: FILE_INFO_BY_HANDLE_CLASS = 3i32;
27002726
pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32;
2727+
pub const FileRenameInformation: FILE_INFORMATION_CLASS = 10i32;
2728+
pub const FileRenameInformationEx: FILE_INFORMATION_CLASS = 65i32;
27012729
pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32;
27022730
pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32;
27032731
pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /