use core::ffi::c_void;
use core::sync::atomic::{AtomicPtr, Ordering};
use wdk_sys::{
ntddk::MmMapLockedPagesSpecifyCache, DRIVER_CANCEL, LARGE_INTEGER, PIO_STACK_LOCATION, PIRP,
PMDL,
};
extern "C" {
pub fn KeQueryPerformanceCounter(performance_frequency: *mut LARGE_INTEGER) -> LARGE_INTEGER;
}
#[allow(non_snake_case)]
pub fn KeQuerySystemTime() -> u64 {
const SYSTEM_TIME_PTR: *const u32 = 0xFFFF_F780_0000_0014usize as *const u32;
loop {
let h1 = unsafe { SYSTEM_TIME_PTR.add(1).read_volatile() } as u64;
let lo = unsafe { SYSTEM_TIME_PTR.add(0).read_volatile() } as u64;
let h2 = unsafe { SYSTEM_TIME_PTR.add(2).read_volatile() } as u64;
if h1 == h2 {
return (h1 << 32) | lo;
}
}
}
const MDL_MAPPED_TO_SYSTEM_VA: i16 = 0x0001;
const MDL_SOURCE_IS_NONPAGED_POOL: i16 = 0x0004;
const NORMAL_PAGE_PRIORITY: u32 = 16;
#[allow(non_snake_case)]
pub unsafe fn IoGetCurrentIrpStackLocation(irp: PIRP) -> PIO_STACK_LOCATION {
(*irp)
.Tail
.Overlay
.__bindgen_anon_2
.__bindgen_anon_1
.CurrentStackLocation
}
#[allow(non_snake_case)]
pub unsafe fn IoGetNextIrpStackLocation(irp: PIRP) -> PIO_STACK_LOCATION {
(*irp)
.Tail
.Overlay
.__bindgen_anon_2
.__bindgen_anon_1
.CurrentStackLocation
.offset(-1)
}
#[allow(non_snake_case)]
pub unsafe fn MmGetSystemAddressForMdlSafe(mdl: PMDL) -> *mut c_void {
if mdl.is_null() {
return core::ptr::null_mut();
}
let flags = (*mdl).MdlFlags;
if flags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL) != 0 {
return (*mdl).MappedSystemVa;
}
MmMapLockedPagesSpecifyCache(
mdl,
0, 1, core::ptr::null_mut(),
0,
NORMAL_PAGE_PRIORITY,
)
}
#[allow(non_snake_case)]
pub unsafe fn IoSetCancelRoutine(irp: PIRP, routine: DRIVER_CANCEL) -> DRIVER_CANCEL {
let new_ptr = match routine {
Some(r) => r as *mut c_void,
None => core::ptr::null_mut(),
};
let slot = &raw mut (*irp).CancelRoutine as *mut _ as *mut AtomicPtr<c_void>;
let old_ptr = (*slot).swap(new_ptr, Ordering::SeqCst);
if old_ptr.is_null() {
None
} else {
Some(core::mem::transmute::<
*mut c_void,
unsafe extern "C" fn(*mut wdk_sys::_DEVICE_OBJECT, *mut wdk_sys::_IRP),
>(old_ptr))
}
}