use crate::windows_bindings::{
CloseHandle, CreateToolhelp32Snapshot, Process32First, Process32Next, INVALID_HANDLE_VALUE,
PROCESSENTRY32, TH32CS_SNAPPROCESS, TRUE,
};
use core::mem::size_of;
use core::ptr::addr_of_mut;
pub(crate) struct ProcSnapshot {
snapshot: *mut core::ffi::c_void,
entry_buf: PROCESSENTRY32,
}
impl ProcSnapshot {
pub fn new() -> Option<Self> {
let snapshot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
if snapshot == INVALID_HANDLE_VALUE {
return None;
}
Some(Self {
snapshot,
entry_buf: PROCESSENTRY32 {
dwSize: size_of::<PROCESSENTRY32>() as u32,
cntUsage: 0,
th32ProcessID: 0,
th32DefaultHeapID: 0,
th32ModuleID: 0,
cntThreads: 0,
th32ParentProcessID: 0,
pcPriClassBase: 0,
dwFlags: 0,
szExeFile: core::array::from_fn(|_| 0),
},
})
}
pub fn find(mut self, predicate: impl Fn(&PROCESSENTRY32) -> bool) -> Option<PROCESSENTRY32> {
if (unsafe { Process32First(self.snapshot, addr_of_mut!(self.entry_buf)) } != TRUE) {
return None;
}
loop {
if predicate(&self.entry_buf) {
return Some(self.entry_buf);
}
if unsafe { Process32Next(self.snapshot, addr_of_mut!(self.entry_buf)) } != TRUE {
break;
}
}
None
}
}
impl Drop for ProcSnapshot {
fn drop(&mut self) {
unsafe { CloseHandle(self.snapshot) };
}
}