Add rust kext to the mono repo
This commit is contained in:
70
windows_kext/wdk/src/allocator.rs
Normal file
70
windows_kext/wdk/src/allocator.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
extern crate alloc;
|
||||
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
|
||||
use alloc::alloc::handle_alloc_error;
|
||||
use windows_sys::Wdk::System::SystemServices::{ExAllocatePool2, ExFreePoolWithTag};
|
||||
|
||||
// For reference: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/pool_flags
|
||||
#[allow(dead_code)]
|
||||
#[repr(u64)]
|
||||
enum PoolType {
|
||||
RequiredStartUseQuota = 0x0000000000000001,
|
||||
Uninitialized = 0x0000000000000002, // Don't zero-initialize allocation
|
||||
Session = 0x0000000000000004, // Use session specific pool
|
||||
CacheAligned = 0x0000000000000008, // Cache aligned allocation
|
||||
RaiseOnFailure = 0x0000000000000020, // Raise exception on failure
|
||||
NonPaged = 0x0000000000000040, // Non paged pool NX
|
||||
NonPagedExecute = 0x0000000000000080, // Non paged pool executable
|
||||
Paged = 0x0000000000000100, // Paged pool
|
||||
RequiredEnd = 0x0000000080000000,
|
||||
OptionalStart = 0x0000000100000000,
|
||||
OptionalEnd = 0x8000000000000000,
|
||||
}
|
||||
|
||||
pub struct WindowsAllocator {}
|
||||
|
||||
unsafe impl Sync for WindowsAllocator {}
|
||||
|
||||
pub(crate) const POOL_TAG: u32 = u32::from_ne_bytes(*b"PMrs");
|
||||
|
||||
unsafe impl GlobalAlloc for WindowsAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
let pool = ExAllocatePool2(PoolType::NonPaged as u64, layout.size(), POOL_TAG);
|
||||
if pool.is_null() {
|
||||
handle_alloc_error(layout);
|
||||
}
|
||||
|
||||
pool as *mut u8
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {
|
||||
ExFreePoolWithTag(ptr as _, POOL_TAG);
|
||||
}
|
||||
|
||||
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
|
||||
let pool = self.alloc(layout);
|
||||
pool
|
||||
}
|
||||
|
||||
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
|
||||
// SAFETY: the caller must ensure that the `new_size` does not overflow.
|
||||
// `layout.align()` comes from a `Layout` and is thus guaranteed to be valid.
|
||||
let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
|
||||
// SAFETY: the caller must ensure that `new_layout` is greater than zero.
|
||||
let new_ptr = unsafe { self.alloc(new_layout) };
|
||||
if !new_ptr.is_null() {
|
||||
// SAFETY: the previously allocated block cannot overlap the newly allocated block.
|
||||
// The safety contract for `dealloc` must be upheld by the caller.
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
ptr,
|
||||
new_ptr,
|
||||
core::cmp::min(layout.size(), new_size),
|
||||
);
|
||||
self.dealloc(ptr, layout);
|
||||
}
|
||||
}
|
||||
new_ptr
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user