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 55cc76a

Browse files
committed
change rename implementation
1 parent be60aa1 commit 55cc76a

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
@@ -1030,7 +1030,7 @@ impl Dir {
10301030
to_dir: &Self,
10311031
to: Q,
10321032
) -> io::Result<()> {
1033-
run_path_with_wcstr(to.as_ref(), &|to| self.rename_native(from.as_ref(), to_dir, to, false))
1033+
run_path_with_utf16(to.as_ref(), &|to| self.rename_native(from.as_ref(), to_dir, to, false))
10341034
}
10351035

10361036
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(&self, original: P, link: Q) -> io::Result<()> {
@@ -1134,58 +1134,64 @@ impl Dir {
11341134
if result == 0 { Err(api::get_last_error()).io_result() } else { Ok(()) }
11351135
}
11361136

1137-
fn rename_native(&self, from: &Path, to_dir: &Self, to: &WCStr, dir: bool) -> io::Result<()> {
1137+
fn rename_native(&self, from: &Path, to_dir: &Self, to: &[u16], dir: bool) -> io::Result<()> {
11381138
let mut opts = OpenOptions::new();
11391139
opts.access_mode(c::DELETE);
11401140
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
11411141
let handle = run_path_with_utf16(from, &|u| self.open_native(u, &opts, dir))?;
1142-
// Calculate the layout of the `FILE_RENAME_INFO` we pass to `SetFileInformation`
1142+
// Calculate the layout of the `FILE_RENAME_INFORMATION` we pass to `NtSetInformationFile`
11431143
// This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
11441144
const too_long_err: io::Error =
11451145
io::const_error!(io::ErrorKind::InvalidFilename, "Filename too long");
11461146
let struct_size = to
1147-
.count_bytes()
1147+
.len()
11481148
.checked_mul(2)
1149-
.and_then(|x| x.checked_add(offset_of!(c::FILE_RENAME_INFO, FileName)))
1149+
.and_then(|x| x.checked_add(offset_of!(c::FILE_RENAME_INFORMATION, FileName)))
11501150
.ok_or(too_long_err)?;
1151-
let layout = Layout::from_size_align(struct_size, align_of::<c::FILE_RENAME_INFO>())
1151+
let layout = Layout::from_size_align(struct_size, align_of::<c::FILE_RENAME_INFORMATION>())
11521152
.map_err(|_| too_long_err)?;
11531153
let struct_size = u32::try_from(struct_size).map_err(|_| too_long_err)?;
1154-
let to_byte_len_without_nul =
1155-
u32::try_from((to.count_bytes() - 1) * 2).map_err(|_| too_long_err)?;
1154+
let to_byte_len = u32::try_from(to.len() * 2).map_err(|_| too_long_err)?;
11561155

11571156
let file_rename_info;
1158-
// 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.
11591158
unsafe {
1160-
file_rename_info = alloc(layout).cast::<c::FILE_RENAME_INFO>();
1159+
file_rename_info = alloc(layout).cast::<c::FILE_RENAME_INFORMATION>();
11611160
if file_rename_info.is_null() {
11621161
return Err(io::ErrorKind::OutOfMemory.into());
11631162
}
11641163

1165-
(&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 {
11661165
Flags: c::FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c::FILE_RENAME_FLAG_POSIX_SEMANTICS,
11671166
});
11681167

11691168
(&raw mut (*file_rename_info).RootDirectory).write(to_dir.handle.as_raw_handle());
11701169
// Don't include the NULL in the size
1171-
(&raw mut (*file_rename_info).FileNameLength).write(to_byte_len_without_nul);
1170+
(&raw mut (*file_rename_info).FileNameLength).write(to_byte_len);
11721171

11731172
to.as_ptr().copy_to_nonoverlapping(
11741173
(&raw mut (*file_rename_info).FileName).cast::<u16>(),
1175-
to.count_bytes(),
1174+
to.len(),
11761175
);
11771176
}
11781177

1179-
let result = unsafe {
1180-
c::SetFileInformationByHandle(
1178+
let status = unsafe {
1179+
c::NtSetInformationFile(
11811180
handle.as_raw_handle(),
1182-
c::FileRenameInfoEx,
1181+
&mutc::IO_STATUS_BLOCK::default(),
11831182
file_rename_info.cast::<c_void>(),
11841183
struct_size,
1184+
c::FileRenameInformation,
11851185
)
11861186
};
11871187
unsafe { dealloc(file_rename_info.cast::<u8>(), layout) };
1188-
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+
Ok(())
1191+
} else {
1192+
Err(WinError::new(unsafe { c::RtlNtStatusToDosError(status) }))
1193+
}
1194+
.io_result()
11891195
}
11901196

11911197
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
@@ -2300,6 +2303,7 @@ NTCREATEFILE_CREATE_DISPOSITION
23002303
NTCREATEFILE_CREATE_OPTIONS
23012304
NtOpenFile
23022305
NtReadFile
2306+
NtSetInformationFile
23032307
NTSTATUS
23042308
NtWriteFile
23052309
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
@@ -73,6 +73,7 @@ windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage :
7373
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);
7474
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);
7575
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);
76+
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);
7677
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);
7778
windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle : HANDLE, desiredaccess : TOKEN_ACCESS_MASK, tokenhandle : *mut HANDLE) -> BOOL);
7879
windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL);
@@ -2529,6 +2530,7 @@ impl Default for FILE_ID_BOTH_DIR_INFO {
25292530
unsafe { core::mem::zeroed() }
25302531
}
25312532
}
2533+
pub type FILE_INFORMATION_CLASS = i32;
25322534
pub type FILE_INFO_BY_HANDLE_CLASS = i32;
25332535
#[repr(C)]
25342536
#[derive(Clone, Copy, Default)]
@@ -2590,6 +2592,30 @@ impl Default for FILE_RENAME_INFO_0 {
25902592
unsafe { core::mem::zeroed() }
25912593
}
25922594
}
2595+
#[repr(C)]
2596+
#[derive(Clone, Copy)]
2597+
pub struct FILE_RENAME_INFORMATION {
2598+
pub Anonymous: FILE_RENAME_INFORMATION_0,
2599+
pub RootDirectory: HANDLE,
2600+
pub FileNameLength: u32,
2601+
pub FileName: [u16; 1],
2602+
}
2603+
impl Default for FILE_RENAME_INFORMATION {
2604+
fn default() -> Self {
2605+
unsafe { core::mem::zeroed() }
2606+
}
2607+
}
2608+
#[repr(C)]
2609+
#[derive(Clone, Copy)]
2610+
pub union FILE_RENAME_INFORMATION_0 {
2611+
pub ReplaceIfExists: bool,
2612+
pub Flags: u32,
2613+
}
2614+
impl Default for FILE_RENAME_INFORMATION_0 {
2615+
fn default() -> Self {
2616+
unsafe { core::mem::zeroed() }
2617+
}
2618+
}
25932619
pub const FILE_RESERVE_OPFILTER: NTCREATEFILE_CREATE_OPTIONS = 1048576u32;
25942620
pub const FILE_SEQUENTIAL_ONLY: NTCREATEFILE_CREATE_OPTIONS = 4u32;
25952621
pub const FILE_SESSION_AWARE: NTCREATEFILE_CREATE_OPTIONS = 262144u32;
@@ -2697,6 +2723,8 @@ pub const FileNormalizedNameInfo: FILE_INFO_BY_HANDLE_CLASS = 24i32;
26972723
pub const FileRemoteProtocolInfo: FILE_INFO_BY_HANDLE_CLASS = 13i32;
26982724
pub const FileRenameInfo: FILE_INFO_BY_HANDLE_CLASS = 3i32;
26992725
pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32;
2726+
pub const FileRenameInformation: FILE_INFORMATION_CLASS = 10i32;
2727+
pub const FileRenameInformationEx: FILE_INFORMATION_CLASS = 65i32;
27002728
pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32;
27012729
pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32;
27022730
pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32;

0 commit comments

Comments
(0)

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