Files
portmaster/windows_kext/wdk/src/spin_lock.rs
2024-04-29 17:04:08 +03:00

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);
}
}
}