use core::ptr;
use wdk::println;
use wdk_sys::{
ntddk::{
KeInitializeDpc, KeInitializeTimer, KeSetTimerEx, KeCancelTimer,
KeInitializeEvent, KeWaitForSingleObject,
IoAllocateWorkItem, IoQueueWorkItem, IoFreeWorkItem,
},
KDPC, KTIMER, LARGE_INTEGER, PKDPC, PKTIMER, PVOID, PDEVICE_OBJECT,
PIO_WORKITEM, IO_WORKITEM, WORK_QUEUE_TYPE,
};
pub struct KernelTimer {
timer: KTIMER,
dpc: KDPC,
active: bool,
}
impl KernelTimer {
pub const unsafe fn new_uninit() -> Self {
Self {
timer: unsafe { core::mem::zeroed() },
dpc: unsafe { core::mem::zeroed() },
active: false,
}
}
pub unsafe fn init(&mut self, callback: unsafe extern "C" fn(PKDPC, PVOID, PVOID, PVOID), context: PVOID) {
unsafe {
KeInitializeTimer(&mut self.timer);
KeInitializeDpc(&mut self.dpc, Some(callback), context);
}
}
pub unsafe fn start(&mut self, due_time_ms: i64, period_ms: u32) {
let due_time = LARGE_INTEGER {
QuadPart: -due_time_ms * 10_000,
};
unsafe {
KeSetTimerEx(&mut self.timer, due_time, period_ms as i32, &mut self.dpc);
}
self.active = true;
println!(
"[Leviathan] Timer started: due={}ms, period={}ms",
due_time_ms, period_ms
);
}
pub unsafe fn cancel(&mut self) -> bool {
if !self.active {
return false;
}
let was_queued = unsafe { KeCancelTimer(&mut self.timer) };
self.active = false;
println!("[Leviathan] Timer cancelled");
was_queued != 0
}
pub fn is_active(&self) -> bool {
self.active
}
}
pub unsafe extern "C" fn example_dpc_callback(
_dpc: PKDPC,
context: PVOID,
_arg1: PVOID,
_arg2: PVOID,
) {
let _ = context;
println!("[Leviathan] DPC callback executed");
}
pub struct WorkItem {
work_item: PIO_WORKITEM,
device: PDEVICE_OBJECT,
}
impl WorkItem {
pub unsafe fn new(device: PDEVICE_OBJECT) -> Option<Self> {
let work_item = unsafe { IoAllocateWorkItem(device) };
if work_item.is_null() {
return None;
}
Some(Self { work_item, device })
}
pub unsafe fn queue(
&self,
callback: unsafe extern "C" fn(PDEVICE_OBJECT, PVOID),
context: PVOID,
queue_type: WORK_QUEUE_TYPE,
) {
unsafe {
IoQueueWorkItem(
self.work_item,
Some(callback),
queue_type,
context,
);
}
println!("[Leviathan] Work item queued");
}
}
impl Drop for WorkItem {
fn drop(&mut self) {
if !self.work_item.is_null() {
unsafe { IoFreeWorkItem(self.work_item) };
}
}
}
pub unsafe extern "C" fn example_work_callback(
device: PDEVICE_OBJECT,
context: PVOID,
) {
let _ = (device, context);
println!("[Leviathan] Work item callback executed at PASSIVE_LEVEL");
}
pub struct DeferredWork {
timer: KTIMER,
dpc: KDPC,
}
impl DeferredWork {
pub unsafe fn schedule_after_ms(
delay_ms: u64,
work_callback: unsafe extern "C" fn(PDEVICE_OBJECT, PVOID),
device: PDEVICE_OBJECT,
context: PVOID,
) -> Option<Self> {
let mut deferred = Self {
timer: unsafe { core::mem::zeroed() },
dpc: unsafe { core::mem::zeroed() },
};
unsafe {
KeInitializeTimer(&mut deferred.timer);
KeInitializeDpc(&mut deferred.dpc, Some(deferred_dpc_handler), context);
}
let due_time = LARGE_INTEGER {
QuadPart: -(delay_ms as i64 * 10_000),
};
unsafe {
KeSetTimerEx(&mut deferred.timer, due_time, 0, &mut deferred.dpc);
}
Some(deferred)
}
}
unsafe extern "C" fn deferred_dpc_handler(
_dpc: PKDPC,
context: PVOID,
_arg1: PVOID,
_arg2: PVOID,
) {
let _ = context;
println!("[Leviathan] Deferred DPC -> queueing work item");
}
pub struct PeriodicTask {
timer: KernelTimer,
interval_ms: u32,
}
impl PeriodicTask {
pub unsafe fn new(
interval_ms: u32,
callback: unsafe extern "C" fn(PKDPC, PVOID, PVOID, PVOID),
context: PVOID,
) -> Self {
let mut timer = unsafe { KernelTimer::new_uninit() };
unsafe { timer.init(callback, context) };
Self { timer, interval_ms }
}
pub unsafe fn start(&mut self) {
unsafe {
self.timer.start(self.interval_ms as i64, self.interval_ms);
}
}
pub unsafe fn stop(&mut self) {
unsafe { self.timer.cancel() };
}
}
pub mod tasks {
use super::*;
pub unsafe extern "C" fn heartbeat_callback(
_dpc: PKDPC,
_context: PVOID,
_arg1: PVOID,
_arg2: PVOID,
) {
println!("[Leviathan] Heartbeat - driver alive");
}
pub unsafe extern "C" fn cleanup_callback(
_dpc: PKDPC,
context: PVOID,
_arg1: PVOID,
_arg2: PVOID,
) {
let _ = context;
println!("[Leviathan] Cleanup task triggered");
}
}