diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2625019575966cb09fba752e345474fbb9f7939f..c6b275a027a6b3462f79be8c285e457add7256d2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,3 +22,17 @@ test:cargo: script: - rustc --version && cargo --version # Print version info for debugging - cargo test --all + +test:windows: + script: + - rustup target add x86_64-pc-windows-gnu + - rustc --version && cargo --version + - | + set -x + apt update -qq + apt install -yqq mingw-w64-x86-64-dev + cat <<-EOF >> $CARGO_HOME/config + [target.x86_64-pc-windows-gnu] + linker = "$GCC-gcc" + EOF + - cargo test --target=x86_64-pc-windows-gnu diff --git a/Cargo.toml b/Cargo.toml index f1ee8da1351d73634757b8f76b029d86e1e74bf4..662cbca0d67acaa47d4edb47ad39fb9cf505418a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [dependencies] log = "0.4" simple_logger = "1.3" -sudo = "0.3.1" +sudo = "0.5" #num_cpus = "1.13.0" diff --git a/src/main.rs b/src/main.rs index 77ab46042bd75fa37e1495c8572923a03d5333a8..549c9e870c7083b291124661978b058ad786a3a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,7 @@ mod unix; use unix::{get_cpu_info, set_process_affinity}; */ -#[cfg(winows)] +#[cfg(windows)] #[path = "windows.rs"] mod plattform; @@ -85,6 +85,13 @@ pub struct ProcessHandle { name: String, } +#[cfg(windows)] +impl Drop for ProcessHandle { + fn drop(&mut self) { + unsafe { winapi::um::handleapi::CloseHandle(self.handle) }; + } +} + #[derive(Debug)] pub struct CpuInfo { all_system_cores: Vec, @@ -101,83 +108,3 @@ pub struct CoreId(u8); #[derive(Debug, Clone, PartialEq)] pub struct Pid(u32); - -#[cfg(windows)] -impl Pid { - //use super::{Pid, K32EnumProcesses, DWORD, size_of}; - - const N_PIDS: usize = 4096; - - pub fn get_system_pids() -> Result, &'static str> { - let mut pids = vec![Pid(0); Self::N_PIDS]; - let mut found_processes: DWORD = 0; - - // https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumprocesses - if 0 == unsafe { - K32EnumProcesses( - pids.as_mut_ptr() as *mut u32, - (Self::N_PIDS * size_of::()) as u32, - &mut found_processes, - ) - } { - return Err("unable to EnumProcesses"); - } - let n_pids = found_processes as usize / size_of::(); - - pids.truncate(n_pids); - - Ok(pids) - } - - pub fn process_handle(self) -> Result { - use winapi::um::winnt::{ - PROCESS_QUERY_INFORMATION, PROCESS_SET_INFORMATION, PROCESS_VM_READ, PROCESS_VM_WRITE, - }; - // https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights - let desired_access = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION; - let inherit_handle = 0; - - // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess - let handle: HANDLE = unsafe { OpenProcess(desired_access, inherit_handle, self.0) }; - if handle.is_null() { - return Err("unable to OpenProcess"); - } - - let mut module_ptr: HMODULE = null_mut(); - let mut module_dyn_needed: DWORD = 0; - let filter_flag = winapi::um::psapi::LIST_MODULES_ALL; - if 0 == unsafe { - K32EnumProcessModulesEx( - handle, - &mut module_ptr as *mut _ as *mut _, - size_of::() as u32, - &mut module_dyn_needed, - filter_flag, - ) - } { - return Err("unable to EnumProcessModulesEx"); - } - - let mut name: Vec = vec![0; winapi::shared::minwindef::MAX_PATH]; - // https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulebasenamew - let len_name = unsafe { - K32GetModuleBaseNameW( - handle, - module_ptr, - name.as_mut_ptr(), - (name.len() / size_of::()) as u32, - ) - }; - if len_name == 0 { - return Err("unable to K32GetModuleBaseNameW"); - } - - let name = String::from_utf16_lossy(&name[0..len_name as usize]); - - Ok(ProcessHandle { - pid: self, - handle, - name, - }) - } -} diff --git a/src/windows.rs b/src/windows.rs index a8795a37c2764525e6b930a1c640a37f40c39134..6b36c19e66cde16b0f075fda60983ac78c94ea3b 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -1,3 +1,5 @@ +use crate::{CoreId, CpuInfo, Pid, ProcessHandle}; + //use winapi::um::winnt::SystemPowerInformation; use std::mem::size_of; // buffer/struct size use std::ptr::null_mut; // NULL @@ -19,13 +21,92 @@ pub struct ProcessHandle { handle: HANDLE, name: String, } -*/ -impl Drop for ProcessHandle { +impl Drop for ProcessHandle { fn drop(&mut self) { unsafe { CloseHandle(self.handle) }; } } +*/ + +impl Pid { + //use super::{Pid, K32EnumProcesses, DWORD, size_of}; + + const N_PIDS: usize = 4096; + + pub fn get_system_pids() -> Result, &'static str> { + let mut pids = vec![Pid(0); Self::N_PIDS]; + let mut found_processes: DWORD = 0; + + // https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumprocesses + if 0 == unsafe { + K32EnumProcesses( + pids.as_mut_ptr() as *mut u32, + (Self::N_PIDS * size_of::()) as u32, + &mut found_processes, + ) + } { + return Err("unable to EnumProcesses"); + } + let n_pids = found_processes as usize / size_of::(); + + pids.truncate(n_pids); + + Ok(pids) + } + + pub fn process_handle(self) -> Result, &'static str> { + use winapi::um::winnt::{ + PROCESS_QUERY_INFORMATION, PROCESS_SET_INFORMATION, PROCESS_VM_READ, PROCESS_VM_WRITE, + }; + // https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights + let desired_access = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION; + let inherit_handle = 0; + + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess + let handle: HANDLE = unsafe { OpenProcess(desired_access, inherit_handle, self.0) }; + if handle.is_null() { + return Err("unable to OpenProcess"); + } + + let mut module_ptr: HMODULE = null_mut(); + let mut module_dyn_needed: DWORD = 0; + let filter_flag = winapi::um::psapi::LIST_MODULES_ALL; + if 0 == unsafe { + K32EnumProcessModulesEx( + handle, + &mut module_ptr as *mut _ as *mut _, + size_of::() as u32, + &mut module_dyn_needed, + filter_flag, + ) + } { + return Err("unable to EnumProcessModulesEx"); + } + + let mut name: Vec = vec![0; winapi::shared::minwindef::MAX_PATH]; + // https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulebasenamew + let len_name = unsafe { + K32GetModuleBaseNameW( + handle, + module_ptr, + name.as_mut_ptr(), + (name.len() / size_of::()) as u32, + ) + }; + if len_name == 0 { + return Err("unable to K32GetModuleBaseNameW"); + } + + let name = String::from_utf16_lossy(&name[0..len_name as usize]); + + Ok(ProcessHandle { + pid: self, + handle, + name, + }) + } +} pub fn get_cpu_info() -> Result { let mut numa_node_count: ULONG = 0xffffffff; @@ -89,7 +170,7 @@ pub fn set_process_affinity(name: &str, cores: &Vec, all_cores: &Vec> = Box::new( + let mut handles: Box>> = Box::new( pids.unwrap() .into_iter() .map(Pid::process_handle)