1 //! Module for importing functions from ntdll.dll. 2 //! The winapi crate does not expose these Windows API functions. 3 4 #![allow(nonstandard_style)] 5 6 use std::ffi::c_void; 7 use std::os::raw::c_ulong; 8 use std::os::windows::prelude::RawHandle; 9 use std::sync::atomic::{AtomicUsize, Ordering}; 10 use winapi::shared::ntdef::NTSTATUS; 11 use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress}; 12 use winapi::um::winnt::ACCESS_MASK; 13 14 #[repr(C)] 15 #[derive(Copy, Clone)] 16 pub(crate) enum FILE_INFORMATION_CLASS { 17 FileAccessInformation = 8, 18 FileModeInformation = 16, 19 } 20 21 #[repr(C)] 22 #[derive(Copy, Clone)] 23 pub(crate) union IO_STATUS_BLOCK_u { 24 pub Status: NTSTATUS, 25 pub Pointer: *mut c_void, 26 } 27 28 #[repr(C)] 29 #[derive(Copy, Clone)] 30 pub(crate) struct IO_STATUS_BLOCK { 31 pub u: IO_STATUS_BLOCK_u, 32 pub Information: *mut c_void, 33 } 34 35 #[repr(C)] 36 #[derive(Copy, Clone, Default)] 37 pub(crate) struct FILE_ACCESS_INFORMATION { 38 pub AccessFlags: ACCESS_MASK, 39 } 40 41 #[repr(C)] 42 #[derive(Copy, Clone, Default)] 43 pub(crate) struct FILE_MODE_INFORMATION { 44 pub Mode: c_ulong, 45 } 46 47 impl Default for IO_STATUS_BLOCK { 48 #[inline] default() -> Self49 fn default() -> Self { 50 unsafe { std::mem::zeroed() } 51 } 52 } 53 54 macro_rules! ntdll_import { 55 { fn $name:ident($($arg:ident: $argty:ty),*) -> $retty:ty; $($tail:tt)* } => { 56 pub(crate) unsafe fn $name($($arg: $argty),*) -> $retty { 57 static ADDRESS: AtomicUsize = AtomicUsize::new(0); 58 let address = match ADDRESS.load(Ordering::Relaxed) { 59 0 => { 60 let ntdll = GetModuleHandleA("ntdll\0".as_ptr() as *const i8); 61 let address = GetProcAddress( 62 ntdll, 63 concat!(stringify!($name), "\0").as_ptr() as *const i8, 64 ) as usize; 65 assert!(address != 0); 66 ADDRESS.store(address, Ordering::Relaxed); 67 address 68 } 69 address => address 70 }; 71 let func: unsafe fn($($argty),*) -> $retty = std::mem::transmute(address); 72 func($($arg),*) 73 } 74 ntdll_import! { $($tail)* } 75 }; 76 {} => {}; 77 } 78 79 ntdll_import! { 80 // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryinformationfile 81 fn NtQueryInformationFile( 82 FileHandle: RawHandle, 83 IoStatusBlock: *mut IO_STATUS_BLOCK, 84 FileInformation: *mut c_void, 85 Length: c_ulong, 86 FileInformationClass: FILE_INFORMATION_CLASS 87 ) -> NTSTATUS; 88 // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-rtlntstatustodoserror 89 fn RtlNtStatusToDosError(status: NTSTATUS) -> c_ulong; 90 } 91