use std::mem::zeroed;
use crate::FaitheError;
use windows::Win32::{
Foundation::HANDLE,
System::{
Diagnostics::Debug::{GetThreadContext, SetThreadContext},
Threading::{OpenThread, ResumeThread, SuspendThread, THREAD_ACCESS_RIGHTS},
},
};
pub use windows::Win32::System::Diagnostics::Debug::CONTEXT;
mod iter;
pub use iter::*;
pub struct Thread(HANDLE);
impl Thread {
pub fn open(
thread_id: u32,
inherit_handle: bool,
desired_access: THREAD_ACCESS_RIGHTS,
) -> crate::Result<Self> {
unsafe {
OpenThread(desired_access, inherit_handle, thread_id)
.map_err(|_| FaitheError::last_error())
.map(|v| Self(v))
}
}
pub fn suspend(&self) -> crate::Result<u32> {
unsafe {
match SuspendThread(self.0) {
u32::MAX => Err(FaitheError::last_error()),
sus => Ok(sus),
}
}
}
pub fn resume(&self) -> crate::Result<u32> {
unsafe {
match ResumeThread(self.0) {
u32::MAX => Err(FaitheError::last_error()),
sus => Ok(sus),
}
}
}
pub fn get_context(&self) -> crate::Result<CONTEXT> {
unsafe {
let mut ctx = zeroed();
if GetThreadContext(self.0, &mut ctx) == false {
Err(FaitheError::last_error())
} else {
Ok(ctx)
}
}
}
pub fn set_context(&self, ctx: &CONTEXT) -> crate::Result<()> {
unsafe {
if SetThreadContext(self.0, ctx as _) == false {
Err(FaitheError::last_error())
} else {
Ok(())
}
}
}
}