use crate::{
memory::{MemoryBasicInformation, MemoryProtection},
size_of, FaitheError,
};
use std::mem::zeroed;
use windows::Win32::System::Memory::{
VirtualAlloc, VirtualFree, VirtualQuery, VIRTUAL_ALLOCATION_TYPE, VIRTUAL_FREE_TYPE,
};
#[rustfmt::skip]
pub fn protect(
address: *mut (),
size: usize,
new_protection: MemoryProtection,
) -> crate::Result<MemoryProtection> {
use windows::Win32::System::Memory::VirtualProtect;
unsafe {
let mut old = zeroed();
if VirtualProtect(
address as _,
size,
new_protection.to_os(),
&mut old
) == false {
Err(FaitheError::last_error())
} else {
MemoryProtection::from_os(old).ok_or(FaitheError::UnknownProtection(old.0))
}
}
}
#[rustfmt::skip]
pub fn allocate(
address: usize,
size: usize,
allocation_type: VIRTUAL_ALLOCATION_TYPE,
protection: MemoryProtection,
) -> crate::Result<*mut ()> {
unsafe {
let region = VirtualAlloc(
address as _,
size,
allocation_type,
protection.to_os()
);
if region.is_null() {
Err(FaitheError::last_error())
} else {
Ok(region as _)
}
}
}
#[rustfmt::skip]
pub fn free(
address: usize,
size: usize,
free_type: VIRTUAL_FREE_TYPE
) -> crate::Result<()>
{
unsafe {
if VirtualFree(
address as _,
size,
free_type
) == false {
Err(FaitheError::last_error())
} else {
Ok(())
}
}
}
#[cfg(windows)]
pub fn query(address: usize) -> crate::Result<MemoryBasicInformation> {
unsafe {
let mut mem_info = zeroed();
if VirtualQuery(address as _, &mut mem_info, size_of!(@ mem_info)) == 0 {
Err(FaitheError::last_error())
} else {
Ok(mem_info.into())
}
}
}