From ac02fcc4d8b5cc0f1d727b30f8f2142dc9bacc8e Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 22 Jan 2022 14:50:08 +0000 Subject: [PATCH] Use `NtCreateFile` instead of `NtOpenFile` to open a file --- library/std/src/fs.rs | 2 +- library/std/src/sys/windows/c.rs | 12 +++++++++--- library/std/src/sys/windows/fs.rs | 11 ++++++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 9d6b2fe8c25d8..4751995556422 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2044,7 +2044,7 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions /// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`, -/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtOpenFile` functions on +/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on /// Windows. Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 09d3661e4fd52..dfcd6124454a4 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -88,6 +88,7 @@ pub const FILE_SHARE_DELETE: DWORD = 0x4; pub const FILE_SHARE_READ: DWORD = 0x1; pub const FILE_SHARE_WRITE: DWORD = 0x2; +pub const FILE_OPEN: ULONG = 0x00000001; pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000; pub const OBJ_DONT_REPARSE: ULONG = 0x1000; @@ -1228,15 +1229,20 @@ compat_fn! { compat_fn! { "ntdll": - pub fn NtOpenFile( + pub fn NtCreateFile( FileHandle: *mut HANDLE, DesiredAccess: ACCESS_MASK, ObjectAttributes: *const OBJECT_ATTRIBUTES, IoStatusBlock: *mut IO_STATUS_BLOCK, + AllocationSize: *mut i64, + FileAttributes: ULONG, ShareAccess: ULONG, - OpenOptions: ULONG + CreateDisposition: ULONG, + CreateOptions: ULONG, + EaBuffer: *mut c_void, + EaLength: ULONG ) -> NTSTATUS { - panic!("`NtOpenFile` not available"); + panic!("`NtCreateFile` not available"); } pub fn RtlNtStatusToDosError( Status: NTSTATUS diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index dd21c6b43891f..a7fb7c32f7cbe 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -712,11 +712,11 @@ impl<'a> Iterator for DirBuffIter<'a> { /// Open a link relative to the parent directory, ensure no symlinks are followed. fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result { - // This is implemented using the lower level `NtOpenFile` function as + // This is implemented using the lower level `NtCreateFile` function as // unfortunately opening a file relative to a parent is not supported by // win32 functions. It is however a fundamental feature of the NT kernel. // - // See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntopenfile + // See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile unsafe { let mut handle = ptr::null_mut(); let mut io_status = c::IO_STATUS_BLOCK::default(); @@ -732,14 +732,19 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result< Attributes: ATTRIBUTES.load(Ordering::Relaxed), ..c::OBJECT_ATTRIBUTES::default() }; - let status = c::NtOpenFile( + let status = c::NtCreateFile( &mut handle, access, &object, &mut io_status, + crate::ptr::null_mut(), + 0, c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE, + c::FILE_OPEN, // If `name` is a symlink then open the link rather than the target. c::FILE_OPEN_REPARSE_POINT, + crate::ptr::null_mut(), + 0, ); // Convert an NTSTATUS to the more familiar Win32 error codes (aka "DosError") if c::nt_success(status) {