use super::macros::err;
use crate::error::CustomError;
use crate::Result;
use core::ops::Deref;
use log::{info, trace};
use winapi::shared::minwindef::FALSE;
use winapi::shared::ntdef::HANDLE;
use winapi::um::synchapi::WaitForSingleObject;
use winapi::um::winbase::INFINITE;
#[repr(transparent)]
pub struct Thread {
thread: HANDLE,
}
impl Thread {
pub(crate) unsafe fn new(thread: HANDLE) -> Result<Thread> {
if thread.is_null() {
return Err(err("CreateThread"));
}
Ok(Thread { thread })
}
pub(crate) fn wait_for_thread(&self) -> Result<()> {
info!("Waiting for thread");
return match unsafe { WaitForSingleObject(self.thread, INFINITE) } {
0x0 => {
info!("Dll eject success? IDK?! Hopefully? WaitForSingleObject returned WAIT_OBJECT_0");
Ok(())
} e => Err(CustomError::WaitForSingleObject(e))?,
};
}
}
impl Deref for Thread {
type Target = HANDLE;
fn deref(&self) -> &Self::Target {
&self.thread
}
}
impl Drop for Thread {
fn drop(&mut self) {
trace!("Cleaning Thread Handle");
if unsafe { winapi::um::handleapi::CloseHandle(self.thread) } == FALSE {
log::error!("Error during cleanup!");
err("CloseHandle of Thread");
}
}
}