use wdk_sys::{
ntddk::{KeAcquireSpinLockRaiseToDpc, KeGetCurrentIrql, KeReleaseSpinLock},
KIRQL, KSPIN_LOCK,
};
pub struct SpinLock {
raw: KSPIN_LOCK,
old_irql: KIRQL,
}
pub struct SpinLockGuard<'a> {
spinlock: &'a SpinLock,
}
impl SpinLock {
pub fn new() -> Self {
let raw = KSPIN_LOCK::default();
Self {
raw,
old_irql: unsafe { KeGetCurrentIrql() },
}
}
pub fn lock(&mut self) -> SpinLockGuard {
self.old_irql = unsafe { KeAcquireSpinLockRaiseToDpc(&self.raw as *const _ as *mut _) };
SpinLockGuard { spinlock: self }
}
}
impl Drop for SpinLockGuard<'_> {
fn drop(&mut self) {
unsafe {
KeReleaseSpinLock(
&self.spinlock.raw as *const _ as *mut _,
self.spinlock.old_irql,
)
};
}
}