diff --git a/Cargo.lock b/Cargo.lock index 5d58db1..77c6a90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,7 +169,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -427,6 +427,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -443,6 +458,17 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -478,6 +504,7 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1266,9 +1293,12 @@ dependencies = [ "serde", "serde_json", "serde_with", + "shlex", "simple-websockets", "sysinfo", "winapi", + "windows 0.62.2", + "wmi", ] [[package]] @@ -1566,7 +1596,7 @@ dependencies = [ "memchr", "ntapi", "rayon", - "windows", + "windows 0.57.0", ] [[package]] @@ -1588,7 +1618,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", ] [[package]] @@ -1602,6 +1641,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.3.41" @@ -1760,7 +1810,7 @@ dependencies = [ "log", "rand", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", ] @@ -1961,6 +2011,27 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core 0.62.2", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + [[package]] name = "windows-core" version = "0.57.0" @@ -1979,13 +2050,37 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement 0.60.0", - "windows-interface 0.59.1", - "windows-link", + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", ] +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.57.0" @@ -1999,9 +2094,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -2021,9 +2116,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -2032,9 +2127,25 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", +] [[package]] name = "windows-registry" @@ -2062,7 +2173,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -2071,7 +2191,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -2080,7 +2200,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -2133,6 +2262,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -2238,6 +2376,21 @@ dependencies = [ "bitflags", ] +[[package]] +name = "wmi" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120d8c2b6a7c96c27bf4a7947fd7f02d73ca7f5958b8bd72a696e46cb5521ee6" +dependencies = [ + "chrono", + "futures", + "log", + "serde", + "thiserror 2.0.17", + "windows 0.62.2", + "windows-core 0.62.2", +] + [[package]] name = "writeable" version = "0.6.1" diff --git a/cli/src/main.rs b/cli/src/main.rs index 179e96a..715ab2d 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -30,7 +30,6 @@ pub fn main() { .expect("Failed to create RPCServer") }; - // Starts the other threads (process detector, client connector, etc) client.start(); diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 27fe520..acc1bd9 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -5,7 +5,6 @@ edition = "2018" authors = ["spikehd"] [dependencies] -sysinfo = "0.33" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_with = "3.11" @@ -16,3 +15,9 @@ interprocess = "2.2" [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3", features = ["namedpipeapi", "winbase"] } +wmi = "0.17" +shlex = "1.3" +windows = { version = "0.62", features = ["Win32_Foundation", "Win32_System_Threading", "Win32_System_ProcessStatus"] } + +[target.'cfg(not(any(target_os = "linux", target_os = "windows")))'.dependencies] +sysinfo = "0.33" diff --git a/lib/src/server/process.rs b/lib/src/server/process.rs index c400220..8f93bdb 100644 --- a/lib/src/server/process.rs +++ b/lib/src/server/process.rs @@ -203,7 +203,7 @@ impl ProcessServer { }); } - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "windows")))] pub fn process_list() -> Result, Box> { use std::path::Path; use sysinfo::UpdateKind; @@ -220,7 +220,7 @@ impl ProcessServer { processes.push(Exec { pid: proc.0.to_string().parse::()?, path: proc.1.exe().unwrap_or(Path::new("")).display().to_string(), - arguments: if let Some(_) = cmd.next() { + arguments: if cmd.next().is_some() { Some( cmd .map(|x| x.to_string_lossy()) @@ -236,6 +236,95 @@ impl ProcessServer { Ok(processes) } + #[cfg(target_os = "windows")] + pub fn process_list() -> Result, Box> { + use serde::Deserialize; + use wmi::{COMLibrary, WMIConnection}; + + let con = WMIConnection::new(COMLibrary::new()?)?; + + #[allow(non_camel_case_types)] + #[allow(non_snake_case)] + #[derive(Deserialize, Debug)] + struct Win32_Process { + Name: String, + CommandLine: Option, + ExecutablePath: Option, + ProcessId: u32, + } + + fn get_process_path(pid: u32) -> Option { + use windows::Win32::Foundation::CloseHandle; + use windows::Win32::System::ProcessStatus::GetModuleFileNameExW; + use windows::Win32::System::Threading::{ + OpenProcess, PROCESS_QUERY_INFORMATION, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_VM_READ, + }; + unsafe { + // Open the process with necessary access rights + if let Ok(process_handle) = OpenProcess( + PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + false, + pid, + ) + .or(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid)) + { + // Buffer to store the file name + let mut filename_buf = [0u16; 260]; // MAX_PATH is typically 260 + + // Get the module file name + let filename_len = GetModuleFileNameExW(Some(process_handle), None, &mut filename_buf); + + // Close the process handle + let _ = CloseHandle(process_handle); + + if filename_len == 0 { + return None; + } + + // Convert the UTF-16 buffer to a Rust String + let path = String::from_utf16_lossy(&filename_buf[..filename_len as usize]); + Some(path) + } else { + None + } + } + } + + let procs: Vec = con.query()?; + + let mut processes = Vec::new(); + + for proc in procs { + let pid = proc.ProcessId as u64; + let (mut path, arguments) = proc + .CommandLine + .clone() + .map(|x| { + if let Some(args) = shlex::split(&x) { + if !args.is_empty() { + return (Some(args[0].clone()), Some(args[1..].join(" "))); + } + } + (None, None) + }) + .unwrap_or((None, None)); + + if proc.ExecutablePath.is_some() { + path = proc.ExecutablePath.clone(); + } else if let Some(_path) = get_process_path(proc.ProcessId) { + path = Some(_path); + } + + processes.push(Exec { + pid, + path: path.unwrap_or(format!("\\{}", proc.Name)), + arguments, + }); + } + + Ok(processes) + } + #[cfg(target_os = "linux")] pub fn process_list() -> Result, Box> { use std::fs;