Rollup merge of #93206 - ChrisDenton:ntopenfile, r=nagisa

Use `NtCreateFile` instead of `NtOpenFile` to open a file

Generally the internal `Nt*` functions should be avoided but when we do need to use one we should stick to the most commonly used for the job. To that end, this PR replaces `NtOpenFile` with `NtCreateFile`.

NOTE: The initial version of this comment hypothesised that this may help with some recent false positives from malware scanners. This hypothesis proved wrong. Sorry for the distraction.
This commit is contained in:
Matthias Krüger 2022-02-08 16:40:49 +01:00 committed by GitHub
commit 9cb39a6083
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 7 deletions

View file

@ -2044,7 +2044,7 @@ pub fn remove_dir<P: AsRef<Path>>(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

View file

@ -88,6 +88,7 @@
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 @@ pub fn WakeByAddressSingle(Address: LPVOID) -> () {
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

View file

@ -712,11 +712,11 @@ fn next(&mut self) -> Option<Self::Item> {
/// 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<File> {
// 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) {