use std::{ffi::CStr, fmt};
use crate::winapi_bindings::{
CloseHandle, CreateToolhelp32Snapshot, INVALID_HANDLE_VALUE, PROCESSENTRY32, Process32First, Process32Next,
TH32CS_SNAPPROCESS,
};
pub struct Process {
pub name: String,
pub id: u32,
pub architecture: Architecture,
}
pub enum Architecture {
X64 = 64,
X86 = 86,
UNKNOWN = 0,
}
impl fmt::Display for Process {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "x{} | \"{}\" [{}]", self.architecture, self.name, self.id)
}
}
impl fmt::Display for Architecture {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let val = match self {
Architecture::X64 => 64,
Architecture::X86 => 86,
Architecture::UNKNOWN => 0,
};
write!(f, "{}", val)
}
}
pub fn fetch_all_processes() -> Vec<Process> {
let mut procs = Vec::new();
let mut pe32 = PROCESSENTRY32::default();
pe32.dwSize = size_of::<PROCESSENTRY32>() as u32;
let snap = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
if snap == INVALID_HANDLE_VALUE {
panic!("CreateToolhelp32Snapshot failed!");
}
unsafe {
if Process32First(snap, &mut pe32) == 0 {
CloseHandle(snap);
panic!("Process32First failed!");
}
loop {
let pe_name = CStr::from_ptr(pe32.szExeFile.as_ptr()).to_string_lossy();
procs.push(Process {
name: pe_name.to_string(),
id: pe32.th32ProcessID,
architecture: Architecture::UNKNOWN,
});
if Process32Next(snap, &mut pe32) == 0 {
break;
}
}
CloseHandle(snap);
}
procs
}
pub fn fetch_process_id(process_name: String) -> u32 {
let mut pe = PROCESSENTRY32::default();
pe.dwSize = size_of::<PROCESSENTRY32>() as u32;
let snapshot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
if snapshot == INVALID_HANDLE_VALUE {
unsafe {
CloseHandle(snapshot);
}
panic!("CreateToolhelp32Snapshot() failed!");
}
unsafe {
if Process32First(snapshot, &mut pe) == 0 {
unsafe {
CloseHandle(snapshot);
}
panic!("Process32First() failed!");
} else {
let pe_name = CStr::from_ptr(pe.szExeFile.as_ptr()).to_string_lossy();
if pe_name == process_name {
CloseHandle(snapshot);
return pe.th32ProcessID;
}
}
loop {
let pe_name = CStr::from_ptr(pe.szExeFile.as_ptr()).to_string_lossy();
if pe_name == process_name {
CloseHandle(snapshot);
return pe.th32ProcessID;
}
if Process32Next(snapshot, &mut pe) == 0 {
break;
}
}
0
}
}