54 lines
1.3 KiB
Rust
54 lines
1.3 KiB
Rust
use core::{ffi::c_void, mem::MaybeUninit, ptr};
|
|
|
|
use windows_sys::Wdk::System::SystemServices::{
|
|
KeAcquireInStackQueuedSpinLock, KeInitializeSpinLock, KeReleaseInStackQueuedSpinLock,
|
|
KLOCK_QUEUE_HANDLE,
|
|
};
|
|
|
|
// Copy of KSPIN_LOCK_QUEUE WDK C struct
|
|
#[repr(C)]
|
|
#[allow(dead_code)]
|
|
struct KSpinLockQueue {
|
|
next: *mut c_void, // struct _KSPIN_LOCK_QUEUE * volatile Next;
|
|
lock: *mut c_void, // PKSPIN_LOCK volatile Lock;
|
|
}
|
|
|
|
// Copy of KLOCK_QUEUE_HANDLE WDK C struct
|
|
pub struct KLockQueueHandle {
|
|
lock: KLOCK_QUEUE_HANDLE,
|
|
}
|
|
|
|
// Copy of KSpinLock WDK C struct
|
|
#[repr(C)]
|
|
pub struct KSpinLock {
|
|
ptr: *mut usize,
|
|
}
|
|
|
|
impl KSpinLock {
|
|
pub fn create() -> Self {
|
|
unsafe {
|
|
let p: KSpinLock = KSpinLock {
|
|
ptr: ptr::null_mut(),
|
|
};
|
|
KeInitializeSpinLock(p.ptr);
|
|
return p;
|
|
}
|
|
}
|
|
|
|
pub fn lock(&mut self) -> KLockQueueHandle {
|
|
unsafe {
|
|
let mut handle = MaybeUninit::zeroed().assume_init();
|
|
KeAcquireInStackQueuedSpinLock(self.ptr, &mut handle);
|
|
KLockQueueHandle { lock: handle }
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Drop for KLockQueueHandle {
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
KeReleaseInStackQueuedSpinLock(&mut self.lock);
|
|
}
|
|
}
|
|
}
|