diff --git a/Cargo.toml b/Cargo.toml index 271f1a85f..ea2e18bc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,36 @@ winapi = { version = "0.3.9", features = [ "sddl", ]} ntapi = "0.4" +windows = { version = "0.44", features = [ + "Win32_Foundation", + "Win32_NetworkManagement_IpHelper", + "Win32_NetworkManagement_NetManagement", + "Win32_NetworkManagement_Ndis", + "Win32_Networking_WinSock", + "Win32_Security", + "Win32_Security_Authentication_Identity", + "Win32_Security_Authorization", + "Win32_Storage_FileSystem", + "Win32_System_Com", + "Win32_System_Diagnostics_Debug", + "Win32_System_IO", + "Win32_System_Ioctl", + "Win32_System_Kernel", + "Win32_System_Memory", + "Win32_System_Ole", + "Win32_System_Performance", + "Win32_System_Power", + "Win32_System_ProcessStatus", + "Win32_System_Registry", + "Win32_System_RemoteDesktop", + "Win32_System_Rpc", + "Win32_System_SystemInformation", + "Win32_System_SystemServices", + "Win32_System_Threading", + "Win32_System_WindowsProgramming", + "Win32_System_Wmi", + "Win32_UI_Shell", +]} [target.'cfg(not(any(target_os = "unknown", target_arch = "wasm32")))'.dependencies] libc = "^0.2.112" diff --git a/src/common.rs b/src/common.rs index 3e9200acd..9bc236bbb 100644 --- a/src/common.rs +++ b/src/common.rs @@ -969,7 +969,7 @@ pub fn get_current_pid() -> Result { } } else if #[cfg(windows)] { fn inner() -> Result { - use winapi::um::processthreadsapi::GetCurrentProcessId; + use windows::Win32::System::Threading::GetCurrentProcessId; unsafe { Ok(Pid(GetCurrentProcessId() as _)) } } diff --git a/src/lib.rs b/src/lib.rs index aa725d697..99f47ea4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,7 @@ cfg_if::cfg_if! { pub(crate) const MIN_USERS: usize = 1; } else if #[cfg(windows)] { mod windows; - use windows as sys; + use self::windows as sys; mod network_helper_win; use network_helper_win as network_helper; mod network; diff --git a/src/network_helper_win.rs b/src/network_helper_win.rs index 1d7470804..29455db51 100644 --- a/src/network_helper_win.rs +++ b/src/network_helper_win.rs @@ -1,33 +1,20 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use std::ffi::OsString; -use std::os::windows::prelude::OsStringExt; -use std::ptr::null_mut; - -use winapi::shared::winerror::{ERROR_BUFFER_OVERFLOW, ERROR_SUCCESS}; -use winapi::shared::ws2def::AF_UNSPEC; -use winapi::um::iphlpapi::GetAdaptersAddresses; -use winapi::um::iptypes::{ - GAA_FLAG_SKIP_ANYCAST, GAA_FLAG_SKIP_DNS_SERVER, GAA_FLAG_SKIP_MULTICAST, PIP_ADAPTER_ADDRESSES, +use windows::Win32::Foundation::{ERROR_BUFFER_OVERFLOW, ERROR_SUCCESS}; +use windows::Win32::NetworkManagement::IpHelper::{ + GetAdaptersAddresses, GAA_FLAG_SKIP_ANYCAST, GAA_FLAG_SKIP_DNS_SERVER, GAA_FLAG_SKIP_MULTICAST, + IP_ADAPTER_ADDRESSES_LH, }; +use windows::Win32::Networking::WinSock::AF_UNSPEC; use crate::common::MacAddr; /// this iterator yields an interface name and address pub(crate) struct InterfaceAddressIterator { /// The first item in the linked list - buf: PIP_ADAPTER_ADDRESSES, + buf: *mut IP_ADAPTER_ADDRESSES_LH, /// The current adapter - adapter: PIP_ADAPTER_ADDRESSES, -} - -// Need a function to convert u16 pointer into String -// https://stackoverflow.com/a/48587463/8706476 -unsafe fn u16_ptr_to_string(ptr: *const u16) -> OsString { - let len = (0..).take_while(|&i| *ptr.offset(i) != 0).count(); - let slice = std::slice::from_raw_parts(ptr, len); - - OsString::from_wide(slice) + adapter: *mut IP_ADAPTER_ADDRESSES_LH, } impl Iterator for InterfaceAddressIterator { @@ -41,7 +28,7 @@ impl Iterator for InterfaceAddressIterator { let adapter = self.adapter; // Move to the next adapter self.adapter = (*adapter).Next; - if let Ok(interface_name) = u16_ptr_to_string((*adapter).FriendlyName).into_string() { + if let Ok(interface_name) = (*adapter).FriendlyName.to_string() { // take the first 6 bytes and return the MAC address instead let [mac @ .., _, _] = (*adapter).PhysicalAddress; Some((interface_name, MacAddr(mac))) @@ -66,12 +53,12 @@ pub(crate) fn get_interface_address() -> Result Result Vec { } } -struct Instance(*mut IWbemLocator); - -impl Drop for Instance { - fn drop(&mut self) { - if !self.0.is_null() { - unsafe { - (*self.0).Release(); - } - } - } -} - -struct ServerConnection(*mut IWbemServices); - -impl Drop for ServerConnection { - fn drop(&mut self) { - if !self.0.is_null() { - unsafe { - (*self.0).Release(); - } - } - } -} - -struct Enumerator(*mut IEnumWbemClassObject); - -impl Drop for Enumerator { - fn drop(&mut self) { - if !self.0.is_null() { - unsafe { - (*self.0).Release(); - } - } - } -} - macro_rules! bstr { - ($($x:expr),*) => {{ - let x: &[u16] = &[$($x as u16),*, 0]; - SysAllocString(x.as_ptr()) - }} + ($x:literal) => {{ + SysAllocString(w!($x)) + }}; } struct Connection { - instance: Option, - server_connection: Option, - enumerator: Option, + instance: Option, + server_connection: Option, + enumerator: Option, initialized: bool, } @@ -156,157 +117,111 @@ unsafe impl Sync for Connection {} impl Connection { #[allow(clippy::unnecessary_wraps)] fn new() -> Option { - unsafe { - let val = CoInitializeEx(null_mut(), 0); - Some(Connection { - instance: None, - server_connection: None, - enumerator: None, - initialized: val == S_OK || val == S_FALSE, - }) - } + let val = unsafe { CoInitializeEx(None, Default::default()) }; + Some(Connection { + instance: None, + server_connection: None, + enumerator: None, + initialized: val.is_ok(), + }) } fn initialize_security(self) -> Option { unsafe { - if FAILED(CoInitializeSecurity( - null_mut(), + CoInitializeSecurity( + PSECURITY_DESCRIPTOR::default(), -1, - null_mut(), - null_mut(), + None, + None, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, - null_mut(), + None, EOAC_NONE, - null_mut(), - )) { - None - } else { - Some(self) - } + None, + ) } + .map_or(None, |_| Some(self)) } fn create_instance(mut self) -> Option { - let mut p_loc = null_mut(); - - unsafe { - if FAILED(CoCreateInstance( - &CLSID_WbemLocator as *const _, - null_mut(), - CLSCTX_INPROC_SERVER, - &IID_IWbemLocator as *const _, - &mut p_loc as *mut _ as *mut _, - )) { - None - } else { - self.instance = Some(Instance(p_loc)); - Some(self) - } - } + let instance = + unsafe { CoCreateInstance(&WbemLocator, None, CLSCTX_INPROC_SERVER) }.ok()?; + self.instance = Some(instance); + Some(self) } fn connect_server(mut self) -> Option { - let mut p_svc = null_mut(); - - if let Some(ref instance) = self.instance { - unsafe { - // "root\WMI" - let s = bstr!('r', 'o', 'o', 't', '\\', 'W', 'M', 'I'); - let res = (*instance.0).ConnectServer( - s, - null_mut(), - null_mut(), - null_mut(), - 0, - null_mut(), - null_mut(), - &mut p_svc as *mut _, - ); - SysFreeString(s); - if FAILED(res) { - return None; - } - } - } else { - return None; + let instance = self.instance.as_ref()?; + let svc = unsafe { + let s = bstr!("root\\WMI"); + let res = instance.ConnectServer( + &s, + &Default::default(), + &Default::default(), + &Default::default(), + 0, + &Default::default(), + None, + ); + SysFreeString(&s); + res } - self.server_connection = Some(ServerConnection(p_svc)); + .ok()?; + + self.server_connection = Some(svc); Some(self) } fn set_proxy_blanket(self) -> Option { - if let Some(ref server_connection) = self.server_connection { - unsafe { - if FAILED(CoSetProxyBlanket( - server_connection.0 as *mut _, - RPC_C_AUTHN_WINNT, - RPC_C_AUTHZ_NONE, - null_mut(), - RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, - null_mut(), - EOAC_NONE, - )) { - return None; - } - } - } else { - return None; + unsafe { + CoSetProxyBlanket( + self.server_connection.as_ref()?, + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + None, + RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, + None, + EOAC_NONE, + ) } + .ok()?; + Some(self) } fn exec_query(mut self) -> Option { - let mut p_enumerator = null_mut(); - - if let Some(ref server_connection) = self.server_connection { - unsafe { - // "WQL" - let s = bstr!('W', 'Q', 'L'); // query kind - // "SELECT * FROM MSAcpi_ThermalZoneTemperature" - let query = bstr!( - 'S', 'E', 'L', 'E', 'C', 'T', ' ', '*', ' ', 'F', 'R', 'O', 'M', ' ', 'M', 'S', - 'A', 'c', 'p', 'i', '_', 'T', 'h', 'e', 'r', 'm', 'a', 'l', 'Z', 'o', 'n', 'e', - 'T', 'e', 'm', 'p', 'e', 'r', 'a', 't', 'u', 'r', 'e' - ); - let hres = (*server_connection.0).ExecQuery( - s, - query, - (WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY) as _, - null_mut(), - &mut p_enumerator as *mut _, - ); - SysFreeString(s); - SysFreeString(query); - if FAILED(hres) { - return None; - } - } - } else { - return None; + let server_connection = self.server_connection.as_ref()?; + + let enumerator = unsafe { + let s = bstr!("WQL"); // query kind + let query = bstr!("SELECT * FROM MSAcpi_ThermalZoneTemperature"); + let hres = server_connection.ExecQuery( + &s, + &query, + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + None, + ); + SysFreeString(&s); + SysFreeString(&query); + hres } - self.enumerator = Some(Enumerator(p_enumerator)); + .ok()?; + + self.enumerator = Some(enumerator); Some(self) } fn temperature(&mut self, get_critical: bool) -> Option<(f32, Option)> { - use winapi::um::wbemcli::WBEM_INFINITE; + let enumerator = self.enumerator.take()?; - let p_enum = match self.enumerator.take() { - Some(x) => x, - None => { - return None; - } - }; - let mut p_obj: *mut IWbemClassObject = null_mut(); let mut nb_returned = 0; + let mut obj = [None; 1]; unsafe { - (*p_enum.0).Next( - WBEM_INFINITE as _, // Time out - 1, // One object - &mut p_obj as *mut _, + let _r = enumerator.Next( + WBEM_INFINITE, // Time out + obj.as_mut_slice(), &mut nb_returned, ); @@ -314,46 +229,50 @@ impl Connection { return None; // not enough rights I suppose... } - (*p_obj).BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY as _); + let class_obj = match &mut obj { + [Some(co)] => co, + _ => return None, + }; - let mut p_val = std::mem::MaybeUninit::::uninit(); - // "CurrentTemperature" - let temp = bstr!( - 'C', 'u', 'r', 'r', 'e', 'n', 't', 'T', 'e', 'm', 'p', 'e', 'r', 'a', 't', 'u', - 'r', 'e' - ); - let res = (*p_obj).Get(temp, 0, p_val.as_mut_ptr(), null_mut(), null_mut()); - let mut p_val = p_val.assume_init(); + let _r = class_obj.BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY.0); + + let mut variant = std::mem::MaybeUninit::::uninit(); + // `Get` only initializes the variant if it succeeds, early returning is not a problem + // + // + class_obj + .Get( + w!("CurrentTemperature"), + 0, + variant.as_mut_ptr(), + null_mut(), + null_mut(), + ) + .ok()?; - SysFreeString(temp); - VariantClear(&mut p_val as *mut _ as *mut _); + let mut variant = variant.assume_init(); - let temp = if SUCCEEDED(res) { - // temperature is given in tenth of degrees Kelvin - (p_val.n1.decVal().Lo64 / 10) as f32 - 273.15 - } else { - (*p_obj).Release(); - return None; - }; + // temperature is given in tenth of degrees Kelvin + let temp = (variant.Anonymous.decVal.Anonymous2.Lo64 / 10) as f32 - 273.15; + let _r = VariantClear(&mut variant); let mut critical = None; if get_critical { - // "CriticalPoint" - let crit = bstr!( - 'C', 'r', 'i', 't', 'i', 'c', 'a', 'l', 'T', 'r', 'i', 'p', 'P', 'o', 'i', 'n', - 't' - ); - let res = (*p_obj).Get(crit, 0, &mut p_val, null_mut(), null_mut()); - - SysFreeString(crit); - VariantClear(&mut p_val as *mut _ as *mut _); - - if SUCCEEDED(res) { - // temperature is given in tenth of degrees Kelvin - critical = Some((p_val.n1.decVal().Lo64 / 10) as f32 - 273.15); - } + class_obj + .Get( + w!("CriticalTripPoint"), + 0, + &mut variant, + null_mut(), + null_mut(), + ) + .ok()?; + + // temperature is given in tenth of degrees Kelvin + critical = Some((variant.Anonymous.decVal.Anonymous2.Lo64 / 10) as f32 - 273.15); + let _r = VariantClear(&mut variant); } - (*p_obj).Release(); + Some((temp, critical)) } } @@ -366,9 +285,7 @@ impl Drop for Connection { self.server_connection.take(); self.instance.take(); if self.initialized { - unsafe { - CoUninitialize(); - } + unsafe { CoUninitialize() }; } } } diff --git a/src/windows/cpu.rs b/src/windows/cpu.rs index 5a9edfd03..f63f0c53f 100644 --- a/src/windows/cpu.rs +++ b/src/windows/cpu.rs @@ -4,31 +4,46 @@ use crate::sys::tools::KeyHandler; use crate::{CpuExt, CpuRefreshKind, LoadAvg}; use std::collections::HashMap; +use std::ffi::c_void; use std::io::Error; use std::mem; use std::ops::DerefMut; -use std::ptr::null_mut; use std::sync::Mutex; -use ntapi::ntpoapi::PROCESSOR_POWER_INFORMATION; - -use winapi::shared::minwindef::FALSE; -use winapi::shared::winerror::{ERROR_INSUFFICIENT_BUFFER, ERROR_SUCCESS}; -use winapi::um::handleapi::CloseHandle; -use winapi::um::pdh::{ +use windows::core::{PCSTR, PCWSTR}; +use windows::s; +use windows::Win32::Foundation::{ + CloseHandle, BOOLEAN, ERROR_INSUFFICIENT_BUFFER, ERROR_SUCCESS, FALSE, HANDLE, +}; +use windows::Win32::System::Diagnostics::Debug; +use windows::Win32::System::Performance::{ PdhAddEnglishCounterA, PdhAddEnglishCounterW, PdhCloseQuery, PdhCollectQueryData, PdhCollectQueryDataEx, PdhGetFormattedCounterValue, PdhOpenQueryA, PdhRemoveCounter, - PDH_FMT_COUNTERVALUE, PDH_FMT_DOUBLE, PDH_HCOUNTER, PDH_HQUERY, + PDH_FMT_COUNTERVALUE, PDH_FMT_DOUBLE, +}; +use windows::Win32::System::Power::{ + CallNtPowerInformation, ProcessorInformation, PROCESSOR_POWER_INFORMATION, +}; +use windows::Win32::System::SystemInformation::{ + GetLogicalProcessorInformationEx, RelationAll, RelationProcessorCore, SYSTEM_INFO, + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, +}; +use windows::Win32::System::SystemServices::{ + PROCESSOR_ARCHITECTURE_ALPHA, PROCESSOR_ARCHITECTURE_ALPHA64, + PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64, PROCESSOR_ARCHITECTURE_ARM64, + PROCESSOR_ARCHITECTURE_IA32_ON_ARM64, PROCESSOR_ARCHITECTURE_IA32_ON_WIN64, + PROCESSOR_ARCHITECTURE_MIPS, PROCESSOR_ARCHITECTURE_MSIL, PROCESSOR_ARCHITECTURE_NEUTRAL, + PROCESSOR_ARCHITECTURE_PPC, PROCESSOR_ARCHITECTURE_SHX, }; -use winapi::um::powerbase::CallNtPowerInformation; -use winapi::um::synchapi::CreateEventA; -use winapi::um::sysinfoapi::GetLogicalProcessorInformationEx; -use winapi::um::sysinfoapi::SYSTEM_INFO; -use winapi::um::winbase::{RegisterWaitForSingleObject, INFINITE}; -use winapi::um::winnt::{ - ProcessorInformation, RelationAll, RelationProcessorCore, BOOLEAN, HANDLE, - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PVOID, WT_EXECUTEDEFAULT, +use windows::Win32::System::Threading::{ + CreateEventA, RegisterWaitForSingleObject, WT_EXECUTEDEFAULT, }; +use windows::Win32::System::WindowsProgramming::INFINITE; + +const PROCESSOR_ARCHITECTURE_INTEL: u32 = Debug::PROCESSOR_ARCHITECTURE_INTEL.0 as _; +const PROCESSOR_ARCHITECTURE_ARM: u32 = Debug::PROCESSOR_ARCHITECTURE_ARM.0 as _; +const PROCESSOR_ARCHITECTURE_IA64: u32 = Debug::PROCESSOR_ARCHITECTURE_IA64.0 as _; +const PROCESSOR_ARCHITECTURE_AMD64: u32 = Debug::PROCESSOR_ARCHITECTURE_AMD64.0 as _; // This formula comes from Linux's include/linux/sched/loadavg.h // https://github.com/torvalds/linux/blob/345671ea0f9258f410eb057b9ced9cefbbe5dc78/include/linux/sched/loadavg.h#L20-L23 @@ -54,22 +69,22 @@ pub(crate) fn get_load_average() -> LoadAvg { LoadAvg::default() } -unsafe extern "system" fn load_avg_callback(counter: PVOID, _: BOOLEAN) { +unsafe extern "system" fn load_avg_callback(counter: *mut c_void, _: BOOLEAN) { let mut display_value = mem::MaybeUninit::::uninit(); if PdhGetFormattedCounterValue( counter as _, PDH_FMT_DOUBLE, - null_mut(), + None, display_value.as_mut_ptr(), - ) != ERROR_SUCCESS as _ + ) != ERROR_SUCCESS.0 { return; } let display_value = display_value.assume_init(); if let Ok(mut avg) = LOAD_AVG.lock() { if let Some(avg) = avg.deref_mut() { - let current_load = display_value.u.doubleValue(); + let current_load = display_value.Anonymous.doubleValue; avg.one = avg.one * LOADAVG_FACTOR_1F + current_load * (1.0 - LOADAVG_FACTOR_1F); avg.five = avg.five * LOADAVG_FACTOR_5F + current_load * (1.0 - LOADAVG_FACTOR_5F); @@ -81,62 +96,61 @@ unsafe extern "system" fn load_avg_callback(counter: PVOID, _: BOOLEAN) { unsafe fn init_load_avg() -> Mutex> { // You can see the original implementation here: https://github.com/giampaolo/psutil - let mut query = null_mut(); + let mut query = 0; - if PdhOpenQueryA(null_mut(), 0, &mut query) != ERROR_SUCCESS as _ { + if PdhOpenQueryA(PCSTR::null(), 0, &mut query) != ERROR_SUCCESS.0 { sysinfo_debug!("init_load_avg: PdhOpenQueryA failed"); return Mutex::new(None); } - let mut counter: PDH_HCOUNTER = mem::zeroed(); - if PdhAddEnglishCounterA( - query, - b"\\System\\Cpu Queue Length\0".as_ptr() as _, - 0, - &mut counter, - ) != ERROR_SUCCESS as _ + let mut counter = 0; + if PdhAddEnglishCounterA(query, s!("\\System\\Cpu Queue Length"), 0, &mut counter) + != ERROR_SUCCESS.0 { PdhCloseQuery(query); sysinfo_debug!("init_load_avg: failed to get CPU queue length"); return Mutex::new(None); } - let event = CreateEventA(null_mut(), FALSE, FALSE, b"LoadUpdateEvent\0".as_ptr() as _); - if event.is_null() { - PdhCloseQuery(query); - sysinfo_debug!("init_load_avg: failed to create event `LoadUpdateEvent`"); - return Mutex::new(None); - } + let event = match CreateEventA(None, FALSE, FALSE, s!("LoadUpdateEvent")) { + Ok(ev) => ev, + Err(_) => { + PdhCloseQuery(query); + sysinfo_debug!("init_load_avg: failed to create event `LoadUpdateEvent`"); + return Mutex::new(None); + } + }; - if PdhCollectQueryDataEx(query, SAMPLING_INTERVAL as _, event) != ERROR_SUCCESS as _ { + if PdhCollectQueryDataEx(query, SAMPLING_INTERVAL as _, event) != ERROR_SUCCESS.0 { PdhCloseQuery(query); sysinfo_debug!("init_load_avg: PdhCollectQueryDataEx failed"); return Mutex::new(None); } - let mut wait_handle = null_mut(); + let mut wait_handle = HANDLE::default(); if RegisterWaitForSingleObject( &mut wait_handle, event, Some(load_avg_callback), - counter as _, + Some(counter as *const c_void), INFINITE, WT_EXECUTEDEFAULT, - ) == 0 + ) + .as_bool() { + Mutex::new(Some(LoadAvg::default())) + } else { PdhRemoveCounter(counter); PdhCloseQuery(query); sysinfo_debug!("init_load_avg: RegisterWaitForSingleObject failed"); Mutex::new(None) - } else { - Mutex::new(Some(LoadAvg::default())) } } struct InternalQuery { - query: PDH_HQUERY, + query: HANDLE, event: HANDLE, - data: HashMap, + data: HashMap, } unsafe impl Send for InternalQuery {} @@ -146,15 +160,15 @@ impl Drop for InternalQuery { fn drop(&mut self) { unsafe { for (_, counter) in self.data.iter() { - PdhRemoveCounter(*counter); + PdhRemoveCounter(counter.0); } - if !self.event.is_null() { + if !self.event.is_invalid() { CloseHandle(self.event); } - if !self.query.is_null() { - PdhCloseQuery(self.query); + if !self.query.is_invalid() { + PdhCloseQuery(self.query.0); } } } @@ -166,12 +180,12 @@ pub(crate) struct Query { impl Query { pub fn new() -> Option { - let mut query = null_mut(); + let mut query = 0; unsafe { - if PdhOpenQueryA(null_mut(), 0, &mut query) == ERROR_SUCCESS as i32 { + if PdhOpenQueryA(PCSTR::null(), 0, &mut query) == ERROR_SUCCESS.0 { let q = InternalQuery { - query, - event: null_mut(), + query: HANDLE(query), + event: HANDLE::default(), data: HashMap::new(), }; Some(Query { internal: q }) @@ -187,18 +201,16 @@ impl Query { if let Some(counter) = self.internal.data.get(name) { unsafe { let mut display_value = mem::MaybeUninit::::uninit(); - let counter: PDH_HCOUNTER = *counter; let ret = PdhGetFormattedCounterValue( - counter, + counter.0, PDH_FMT_DOUBLE, - null_mut(), + None, display_value.as_mut_ptr(), - ) as u32; - let display_value = display_value.assume_init(); - return if ret == ERROR_SUCCESS as _ { - let data = *display_value.u.doubleValue(); - Some(data as f32) + ); + return if ret == ERROR_SUCCESS.0 { + let display_value = display_value.assume_init(); + Some(display_value.Anonymous.doubleValue as f32) } else { sysinfo_debug!("Query::get: PdhGetFormattedCounterValue failed"); Some(0.) @@ -215,10 +227,15 @@ impl Query { return false; } unsafe { - let mut counter: PDH_HCOUNTER = std::mem::zeroed(); - let ret = PdhAddEnglishCounterW(self.internal.query, getter.as_ptr(), 0, &mut counter); - if ret == ERROR_SUCCESS as _ { - self.internal.data.insert(name.clone(), counter); + let mut counter = 0; + let ret = PdhAddEnglishCounterW( + self.internal.query.0, + PCWSTR::from_raw(getter.as_ptr()), + 0, + &mut counter, + ); + if ret == ERROR_SUCCESS.0 { + self.internal.data.insert(name.clone(), HANDLE(counter)); } else { sysinfo_debug!( "Query::add_english_counter: failed to add counter '{}': {:x}...", @@ -233,7 +250,7 @@ impl Query { pub fn refresh(&self) { unsafe { - if PdhCollectQueryData(self.internal.query) != ERROR_SUCCESS as _ { + if PdhCollectQueryData(self.internal.query.0) != ERROR_SUCCESS.0 { sysinfo_debug!("failed to refresh CPU data"); } } @@ -359,25 +376,24 @@ impl Cpu { } fn get_vendor_id_not_great(info: &SYSTEM_INFO) -> String { - use winapi::um::winnt; // https://docs.microsoft.com/fr-fr/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info unsafe { - match info.u.s().wProcessorArchitecture { - winnt::PROCESSOR_ARCHITECTURE_INTEL => "Intel x86", - winnt::PROCESSOR_ARCHITECTURE_MIPS => "MIPS", - winnt::PROCESSOR_ARCHITECTURE_ALPHA => "RISC Alpha", - winnt::PROCESSOR_ARCHITECTURE_PPC => "PPC", - winnt::PROCESSOR_ARCHITECTURE_SHX => "SHX", - winnt::PROCESSOR_ARCHITECTURE_ARM => "ARM", - winnt::PROCESSOR_ARCHITECTURE_IA64 => "Intel Itanium-based x64", - winnt::PROCESSOR_ARCHITECTURE_ALPHA64 => "RISC Alpha x64", - winnt::PROCESSOR_ARCHITECTURE_MSIL => "MSIL", - winnt::PROCESSOR_ARCHITECTURE_AMD64 => "(Intel or AMD) x64", - winnt::PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 => "Intel Itanium-based x86", - winnt::PROCESSOR_ARCHITECTURE_NEUTRAL => "unknown", - winnt::PROCESSOR_ARCHITECTURE_ARM64 => "ARM x64", - winnt::PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 => "ARM", - winnt::PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 => "Intel Itanium-based x86", + match info.Anonymous.Anonymous.wProcessorArchitecture.0 as u32 { + self::PROCESSOR_ARCHITECTURE_INTEL => "Intel x86", + self::PROCESSOR_ARCHITECTURE_MIPS => "MIPS", + self::PROCESSOR_ARCHITECTURE_ALPHA => "RISC Alpha", + self::PROCESSOR_ARCHITECTURE_PPC => "PPC", + self::PROCESSOR_ARCHITECTURE_SHX => "SHX", + self::PROCESSOR_ARCHITECTURE_ARM => "ARM", + self::PROCESSOR_ARCHITECTURE_IA64 => "Intel Itanium-based x64", + self::PROCESSOR_ARCHITECTURE_ALPHA64 => "RISC Alpha x64", + self::PROCESSOR_ARCHITECTURE_MSIL => "MSIL", + self::PROCESSOR_ARCHITECTURE_AMD64 => "(Intel or AMD) x64", + self::PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 => "Intel Itanium-based x86", + self::PROCESSOR_ARCHITECTURE_NEUTRAL => "unknown", + self::PROCESSOR_ARCHITECTURE_ARM64 => "ARM x64", + self::PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 => "ARM", + self::PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 => "Intel Itanium-based x86", _ => "unknown", } .to_owned() @@ -475,11 +491,12 @@ pub(crate) fn get_frequencies(nb_cpus: usize) -> Vec { unsafe { if CallNtPowerInformation( ProcessorInformation, - null_mut(), + None, 0, - infos.as_mut_ptr() as _, + Some(infos.as_mut_ptr() as _), size as _, - ) == 0 + ) + .is_ok() { infos.set_len(nb_cpus); // infos.Number @@ -502,21 +519,24 @@ pub(crate) fn get_physical_core_count() -> Option { let mut needed_size = 0; unsafe { - GetLogicalProcessorInformationEx(RelationAll, null_mut(), &mut needed_size); + GetLogicalProcessorInformationEx(RelationAll, None, &mut needed_size); let mut buf: Vec = Vec::with_capacity(needed_size as _); loop { if GetLogicalProcessorInformationEx( RelationAll, - buf.as_mut_ptr() as *mut _, + Some(buf.as_mut_ptr().cast()), &mut needed_size, - ) == FALSE + ) + .as_bool() { + break; + } else { let e = Error::last_os_error(); // For some reasons, the function might return a size not big enough... match e.raw_os_error() { - Some(value) if value == ERROR_INSUFFICIENT_BUFFER as _ => {} + Some(value) if value == ERROR_INSUFFICIENT_BUFFER.0 as _ => {} _ => { sysinfo_debug!( "get_physical_core_count: GetLogicalCpuInformationEx failed" @@ -524,8 +544,6 @@ pub(crate) fn get_physical_core_count() -> Option { return None; } } - } else { - break; } buf.reserve(needed_size as usize - buf.capacity()); } @@ -536,7 +554,7 @@ pub(crate) fn get_physical_core_count() -> Option { let raw_buf = buf.as_ptr(); let mut count = 0; while i < buf.len() { - let p = &*(raw_buf.add(i) as PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX); + let p = &*(raw_buf.add(i) as *const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX); i += p.Size as usize; if p.Relationship == RelationProcessorCore { // Only count the physical cores. diff --git a/src/windows/disk.rs b/src/windows/disk.rs index 215fb8c58..0b7bfd0eb 100644 --- a/src/windows/disk.rs +++ b/src/windows/disk.rs @@ -2,24 +2,22 @@ use crate::{DiskExt, DiskType}; -use std::ffi::{OsStr, OsString}; +use std::ffi::{c_void, OsStr, OsString}; use std::mem::size_of; use std::path::Path; -use winapi::ctypes::c_void; -use winapi::shared::minwindef::{DWORD, MAX_PATH}; -use winapi::um::fileapi::{ +use windows::core::PCWSTR; +use windows::Win32::Foundation::{CloseHandle, BOOLEAN, HANDLE, MAX_PATH}; +use windows::Win32::Storage::FileSystem::{ CreateFileW, GetDiskFreeSpaceExW, GetDriveTypeW, GetLogicalDrives, GetVolumeInformationW, - OPEN_EXISTING, + FILE_ACCESS_FLAGS, FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING, }; -use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE}; -use winapi::um::ioapiset::DeviceIoControl; -use winapi::um::winbase::{DRIVE_FIXED, DRIVE_REMOVABLE}; -use winapi::um::winioctl::{ +use windows::Win32::System::Ioctl::{ PropertyStandardQuery, StorageDeviceSeekPenaltyProperty, IOCTL_STORAGE_QUERY_PROPERTY, STORAGE_PROPERTY_QUERY, }; -use winapi::um::winnt::{BOOLEAN, FILE_SHARE_READ, FILE_SHARE_WRITE, HANDLE, ULARGE_INTEGER}; +use windows::Win32::System::WindowsProgramming::{DRIVE_FIXED, DRIVE_REMOVABLE}; +use windows::Win32::System::IO::DeviceIoControl; #[doc = include_str!("../../md_doc/disk.md")] pub struct Disk { @@ -65,15 +63,10 @@ impl DiskExt for Disk { fn refresh(&mut self) -> bool { if self.total_space != 0 { unsafe { - let mut tmp: ULARGE_INTEGER = std::mem::zeroed(); - if GetDiskFreeSpaceExW( - self.mount_point.as_ptr(), - std::ptr::null_mut(), - std::ptr::null_mut(), - &mut tmp, - ) != 0 - { - self.available_space = *tmp.QuadPart(); + let mut tmp = 0; + let lpdirectoryname = PCWSTR::from_raw(self.mount_point.as_ptr()); + if GetDiskFreeSpaceExW(lpdirectoryname, None, None, Some(&mut tmp)).as_bool() { + self.available_space = tmp; return true; } } @@ -85,47 +78,41 @@ impl DiskExt for Disk { struct HandleWrapper(HANDLE); impl HandleWrapper { - unsafe fn new(drive_name: &[u16], open_rights: DWORD) -> Option { + unsafe fn new(drive_name: &[u16], open_rights: FILE_ACCESS_FLAGS) -> Option { + let lpfilename = PCWSTR::from_raw(drive_name.as_ptr()); let handle = CreateFileW( - drive_name.as_ptr(), + lpfilename, open_rights, FILE_SHARE_READ | FILE_SHARE_WRITE, - std::ptr::null_mut(), + None, OPEN_EXISTING, - 0, - std::ptr::null_mut(), - ); - if handle == INVALID_HANDLE_VALUE { - CloseHandle(handle); - None - } else { - Some(Self(handle)) - } + Default::default(), + HANDLE::default(), + ) + .ok()?; + Some(Self(handle)) } } impl Drop for HandleWrapper { fn drop(&mut self) { - unsafe { - CloseHandle(self.0); - } + unsafe { CloseHandle(self.0) }; } } unsafe fn get_drive_size(mount_point: &[u16]) -> Option<(u64, u64)> { - let mut total_size: ULARGE_INTEGER = std::mem::zeroed(); - let mut available_space: ULARGE_INTEGER = std::mem::zeroed(); + let mut total_size = 0; + let mut available_space = 0; + let lpdirectoryname = PCWSTR::from_raw(mount_point.as_ptr()); if GetDiskFreeSpaceExW( - mount_point.as_ptr(), - std::ptr::null_mut(), - &mut total_size, - &mut available_space, - ) != 0 + lpdirectoryname, + None, + Some(&mut total_size), + Some(&mut available_space), + ) + .as_bool() { - Some(( - *total_size.QuadPart() as _, - *available_space.QuadPart() as _, - )) + Some((total_size, available_space)) } else { None } @@ -135,8 +122,8 @@ unsafe fn get_drive_size(mount_point: &[u16]) -> Option<(u64, u64)> { #[allow(non_snake_case)] #[repr(C)] struct DEVICE_SEEK_PENALTY_DESCRIPTOR { - Version: DWORD, - Size: DWORD, + Version: u32, + Size: u32, IncursSeekPenalty: BOOLEAN, } @@ -149,33 +136,33 @@ pub(crate) unsafe fn get_disks() -> Vec { #[cfg(feature = "multithread")] use rayon::iter::ParallelIterator; - crate::utils::into_iter(0..DWORD::BITS) + crate::utils::into_iter(0..u32::BITS) .filter_map(|x| { if (drives >> x) & 1 == 0 { return None; } let mount_point = [b'A' as u16 + x as u16, b':' as u16, b'\\' as u16, 0]; - let drive_type = GetDriveTypeW(mount_point.as_ptr()); + let raw_mount_point = PCWSTR::from_raw(mount_point.as_ptr()); + let drive_type = GetDriveTypeW(raw_mount_point); let is_removable = drive_type == DRIVE_REMOVABLE; if drive_type != DRIVE_FIXED && drive_type != DRIVE_REMOVABLE { return None; } - let mut name = [0u16; MAX_PATH + 1]; + let mut name = [0u16; MAX_PATH as usize + 1]; let mut file_system = [0u16; 32]; - if GetVolumeInformationW( - mount_point.as_ptr(), - name.as_mut_ptr(), - name.len() as DWORD, - std::ptr::null_mut(), - std::ptr::null_mut(), - std::ptr::null_mut(), - file_system.as_mut_ptr(), - file_system.len() as DWORD, - ) == 0 - { + let volume_info_res = GetVolumeInformationW( + raw_mount_point, + Some(&mut name), + None, + None, + None, + Some(&mut file_system), + ) + .as_bool(); + if !volume_info_res { return None; } let mut pos = 0; @@ -206,12 +193,12 @@ pub(crate) unsafe fn get_disks() -> Vec { b':' as u16, 0, ]; - let handle = HandleWrapper::new(&drive_name, 0)?; + let handle = HandleWrapper::new(&drive_name, Default::default())?; let (total_space, available_space) = get_drive_size(&mount_point)?; if total_space == 0 { return None; } - let mut spq_trim = STORAGE_PROPERTY_QUERY { + let spq_trim = STORAGE_PROPERTY_QUERY { PropertyId: StorageDeviceSeekPenaltyProperty, QueryType: PropertyStandardQuery, AdditionalParameters: [0], @@ -219,25 +206,27 @@ pub(crate) unsafe fn get_disks() -> Vec { let mut result: DEVICE_SEEK_PENALTY_DESCRIPTOR = std::mem::zeroed(); let mut dw_size = 0; - let type_ = if DeviceIoControl( + let device_io_control = DeviceIoControl( handle.0, IOCTL_STORAGE_QUERY_PROPERTY, - &mut spq_trim as *mut STORAGE_PROPERTY_QUERY as *mut c_void, - size_of::() as DWORD, - &mut result as *mut DEVICE_SEEK_PENALTY_DESCRIPTOR as *mut c_void, - size_of::() as DWORD, - &mut dw_size, - std::ptr::null_mut(), - ) == 0 - || dw_size != size_of::() as DWORD + Some(&spq_trim as *const STORAGE_PROPERTY_QUERY as *const c_void), + size_of::() as u32, + Some(&mut result as *mut DEVICE_SEEK_PENALTY_DESCRIPTOR as *mut c_void), + size_of::() as u32, + Some(&mut dw_size), + None, + ) + .as_bool(); + let type_ = if !device_io_control + || dw_size != size_of::() as u32 { DiskType::Unknown(-1) } else { - let is_ssd = result.IncursSeekPenalty == 0; - if is_ssd { - DiskType::SSD - } else { + let is_hdd = result.IncursSeekPenalty.as_bool(); + if is_hdd { DiskType::HDD + } else { + DiskType::SSD } }; Some(Disk { diff --git a/src/windows/network.rs b/src/windows/network.rs index fb832d4bd..7d40189d6 100644 --- a/src/windows/network.rs +++ b/src/windows/network.rs @@ -6,11 +6,10 @@ use crate::{NetworkExt, NetworksExt, NetworksIter}; use std::collections::{hash_map, HashMap}; -use winapi::shared::ifdef::{MediaConnectStateDisconnected, NET_LUID}; -use winapi::shared::netioapi::{ - FreeMibTable, GetIfEntry2, GetIfTable2, MIB_IF_ROW2, PMIB_IF_TABLE2, +use windows::Win32::NetworkManagement::IpHelper::{ + FreeMibTable, GetIfEntry2, GetIfTable2, MIB_IF_ROW2, MIB_IF_TABLE2, }; -use winapi::shared::winerror::NO_ERROR; +use windows::Win32::NetworkManagement::Ndis::{MediaConnectStateDisconnected, NET_LUID_LH}; macro_rules! old_and_new { ($ty_:expr, $name:ident, $old:ident, $new_val:expr) => {{ @@ -39,10 +38,10 @@ impl NetworksExt for Networks { } fn refresh_networks_list(&mut self) { - let mut table: PMIB_IF_TABLE2 = std::ptr::null_mut(); + let mut table: *mut MIB_IF_TABLE2 = std::ptr::null_mut(); unsafe { - if GetIfTable2(&mut table) != NO_ERROR { + if GetIfTable2(&mut table).is_err() { return; } @@ -66,16 +65,16 @@ impl NetworksExt for Networks { continue; } let id = vec![ - ptr.InterfaceGuid.Data2, - ptr.InterfaceGuid.Data3, - ptr.InterfaceGuid.Data4[0] as _, - ptr.InterfaceGuid.Data4[1] as _, - ptr.InterfaceGuid.Data4[2] as _, - ptr.InterfaceGuid.Data4[3] as _, - ptr.InterfaceGuid.Data4[4] as _, - ptr.InterfaceGuid.Data4[5] as _, - ptr.InterfaceGuid.Data4[6] as _, - ptr.InterfaceGuid.Data4[7] as _, + ptr.InterfaceGuid.data2, + ptr.InterfaceGuid.data3, + ptr.InterfaceGuid.data4[0] as _, + ptr.InterfaceGuid.data4[1] as _, + ptr.InterfaceGuid.data4[2] as _, + ptr.InterfaceGuid.data4[3] as _, + ptr.InterfaceGuid.data4[4] as _, + ptr.InterfaceGuid.data4[5] as _, + ptr.InterfaceGuid.data4[6] as _, + ptr.InterfaceGuid.data4[7] as _, ]; let entry = groups.entry(id.clone()).or_insert(0); *entry += 1; @@ -161,7 +160,7 @@ impl NetworksExt for Networks { for (_, interface) in self.interfaces.iter_mut() { entry.InterfaceLuid = interface.id; entry.InterfaceIndex = 0; // to prevent the function to pick this one as index - if GetIfEntry2(&mut entry) != NO_ERROR { + if GetIfEntry2(&mut entry).is_err() { continue; } old_and_new!(interface, current_out, old_out, entry.OutOctets); @@ -187,7 +186,7 @@ impl NetworksExt for Networks { #[doc = include_str!("../../md_doc/network_data.md")] pub struct NetworkData { - id: NET_LUID, + id: NET_LUID_LH, current_out: u64, old_out: u64, current_in: u64, diff --git a/src/windows/process.rs b/src/windows/process.rs index 1e3289529..0d99bb1ab 100644 --- a/src/windows/process.rs +++ b/src/windows/process.rs @@ -21,39 +21,41 @@ use std::sync::Arc; use libc::{c_void, memcpy}; use ntapi::ntpebteb::PEB; -use ntapi::ntwow64::{PEB32, PRTL_USER_PROCESS_PARAMETERS32, RTL_USER_PROCESS_PARAMETERS32}; +use ntapi::ntwow64::{PEB32, RTL_USER_PROCESS_PARAMETERS32}; use once_cell::sync::Lazy; -use ntapi::ntpsapi::{ - NtQueryInformationProcess, ProcessBasicInformation, ProcessCommandLineInformation, - ProcessWow64Information, PROCESSINFOCLASS, PROCESS_BASIC_INFORMATION, +use ntapi::ntpsapi::{ProcessCommandLineInformation, PROCESS_BASIC_INFORMATION}; +use ntapi::ntrtl::{RtlGetVersion, RTL_USER_PROCESS_PARAMETERS}; +use winapi::um::winnt::ULARGE_INTEGER; +use windows::core::PCWSTR; +use windows::Win32::Foundation::{ + CloseHandle, GetLastError, ERROR_INSUFFICIENT_BUFFER, FILETIME, HANDLE, HINSTANCE, MAX_PATH, + STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL, STATUS_INFO_LENGTH_MISMATCH, UNICODE_STRING, }; -use ntapi::ntrtl::{RtlGetVersion, PRTL_USER_PROCESS_PARAMETERS, RTL_USER_PROCESS_PARAMETERS}; -use winapi::shared::basetsd::SIZE_T; -use winapi::shared::minwindef::{DWORD, FALSE, FILETIME, LPVOID, MAX_PATH, TRUE, ULONG}; -use winapi::shared::ntdef::{NT_SUCCESS, UNICODE_STRING}; -use winapi::shared::ntstatus::{ - STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL, STATUS_INFO_LENGTH_MISMATCH, +use windows::Win32::Security::{GetTokenInformation, TokenUser, TOKEN_QUERY, TOKEN_USER}; +use windows::Win32::System::Diagnostics::Debug::ReadProcessMemory; +use windows::Win32::System::Memory::{ + GetProcessHeap, HeapAlloc, HeapFree, LocalFree, VirtualQueryEx, HEAP_ZERO_MEMORY, + MEMORY_BASIC_INFORMATION, }; -use winapi::shared::winerror::ERROR_INSUFFICIENT_BUFFER; -use winapi::um::errhandlingapi::GetLastError; -use winapi::um::handleapi::CloseHandle; -use winapi::um::heapapi::{GetProcessHeap, HeapAlloc, HeapFree}; -use winapi::um::memoryapi::{ReadProcessMemory, VirtualQueryEx}; -use winapi::um::processthreadsapi::{ - GetProcessTimes, GetSystemTimes, OpenProcess, OpenProcessToken, ProcessIdToSessionId, +use windows::Win32::System::ProcessStatus::{ + K32EnumProcessModulesEx, K32GetModuleBaseNameW, K32GetModuleFileNameExW, + K32GetProcessMemoryInfo, LIST_MODULES_ALL, PROCESS_MEMORY_COUNTERS_EX, }; -use winapi::um::psapi::{ - EnumProcessModulesEx, GetModuleBaseNameW, GetModuleFileNameExW, GetProcessMemoryInfo, - LIST_MODULES_ALL, PROCESS_MEMORY_COUNTERS, PROCESS_MEMORY_COUNTERS_EX, -}; -use winapi::um::securitybaseapi::GetTokenInformation; -use winapi::um::winbase::{GetProcessIoCounters, CREATE_NO_WINDOW}; -use winapi::um::winnt::{ - TokenUser, HANDLE, HEAP_ZERO_MEMORY, IO_COUNTERS, MEMORY_BASIC_INFORMATION, - PROCESS_QUERY_INFORMATION, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_VM_READ, - RTL_OSVERSIONINFOEXW, TOKEN_QUERY, TOKEN_USER, ULARGE_INTEGER, +use windows::Win32::System::RemoteDesktop::ProcessIdToSessionId; +use windows::Win32::System::SystemInformation::OSVERSIONINFOEXW; +use windows::Win32::System::Threading::{ + GetProcessIoCounters, GetProcessTimes, GetSystemTimes, NtQueryInformationProcess, OpenProcess, + OpenProcessToken, ProcessBasicInformation, ProcessWow64Information, CREATE_NO_WINDOW, + IO_COUNTERS, PROCESSINFOCLASS, PROCESS_QUERY_INFORMATION, PROCESS_QUERY_LIMITED_INFORMATION, + PROCESS_VM_READ, }; +use windows::Win32::UI::Shell::CommandLineToArgvW; + +#[inline] +const fn is_failed(st: i32) -> bool { + st < 0 +} impl fmt::Display for ProcessStatus { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -70,11 +72,12 @@ fn get_process_handler(pid: Pid) -> Option { } let options = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; - HandleWrapper::new(unsafe { OpenProcess(options, FALSE, pid.0 as DWORD) }) + HandleWrapper::new(unsafe { OpenProcess(options, false, pid.0 as u32).unwrap_or_default() }) .or_else(|| { sysinfo_debug!("OpenProcess failed, error: {:?}", unsafe { GetLastError() }); HandleWrapper::new(unsafe { - OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid.0 as DWORD) + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid.0 as u32) + .unwrap_or_default() }) }) .or_else(|| { @@ -92,8 +95,8 @@ unsafe fn get_process_user_id( struct HeapWrap(*mut T); impl HeapWrap { - unsafe fn new(size: DWORD) -> Option { - let ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size as _) as *mut T; + unsafe fn new(size: u32) -> Option { + let ptr = HeapAlloc(GetProcessHeap().ok()?, HEAP_ZERO_MEMORY, size as _) as *mut T; if ptr.is_null() { sysinfo_debug!("HeapAlloc failed"); None @@ -107,7 +110,9 @@ unsafe fn get_process_user_id( fn drop(&mut self) { if !self.0.is_null() { unsafe { - HeapFree(GetProcessHeap(), 0, self.0 as *mut _); + if let Ok(heap) = GetProcessHeap() { + HeapFree(heap, Default::default(), Some(self.0.cast())); + } } } } @@ -117,9 +122,10 @@ unsafe fn get_process_user_id( return None; } - let mut token = null_mut(); + let mut token = Default::default(); - if OpenProcessToken(**handle, TOKEN_QUERY, &mut token) == 0 { + let ret = OpenProcessToken(**handle, TOKEN_QUERY, &mut token).as_bool(); + if !ret { sysinfo_debug!("OpenProcessToken failed"); return None; } @@ -128,7 +134,8 @@ unsafe fn get_process_user_id( let mut size = 0; - if GetTokenInformation(*token, TokenUser, null_mut(), 0, &mut size) == 0 { + let ret = GetTokenInformation(*token, TokenUser, None, 0, &mut size); + if !ret.as_bool() { let err = GetLastError(); if err != ERROR_INSUFFICIENT_BUFFER { sysinfo_debug!("GetTokenInformation failed, error: {:?}", err); @@ -138,7 +145,8 @@ unsafe fn get_process_user_id( let ptu: HeapWrap = HeapWrap::new(size)?; - if GetTokenInformation(*token, TokenUser, ptu.0 as *mut _, size, &mut size) == 0 { + let ret = GetTokenInformation(*token, TokenUser, Some(ptu.0.cast()), size, &mut size); + if !ret.as_bool() { sysinfo_debug!("GetTokenInformation failed, error: {:?}", GetLastError()); return None; } @@ -150,7 +158,7 @@ struct HandleWrapper(HANDLE); impl HandleWrapper { fn new(handle: HANDLE) -> Option { - if handle.is_null() { + if handle.is_invalid() { None } else { Some(Self(handle)) @@ -222,11 +230,11 @@ impl CPUsageCalculationValues { } } static WINDOWS_8_1_OR_NEWER: Lazy = Lazy::new(|| unsafe { - let mut version_info: RTL_OSVERSIONINFOEXW = MaybeUninit::zeroed().assume_init(); + let mut version_info: OSVERSIONINFOEXW = MaybeUninit::zeroed().assume_init(); - version_info.dwOSVersionInfoSize = std::mem::size_of::() as u32; - if !NT_SUCCESS(RtlGetVersion( - &mut version_info as *mut RTL_OSVERSIONINFOEXW as *mut _, + version_info.dwOSVersionInfoSize = std::mem::size_of::() as u32; + if is_failed(RtlGetVersion( + (&mut version_info as *mut OSVERSIONINFOEXW).cast(), )) { return true; } @@ -236,36 +244,31 @@ static WINDOWS_8_1_OR_NEWER: Lazy = Lazy::new(|| unsafe { || version_info.dwMajorVersion == 6 && version_info.dwMinorVersion >= 3 }); -unsafe fn get_process_name(process_handler: &HandleWrapper, h_mod: *mut c_void) -> String { - let mut process_name = [0u16; MAX_PATH + 1]; +unsafe fn get_process_name(process_handler: &HandleWrapper, h_mod: HINSTANCE) -> String { + let mut process_name = [0u16; MAX_PATH as usize + 1]; - GetModuleBaseNameW( - **process_handler, - h_mod as _, - process_name.as_mut_ptr(), - MAX_PATH as DWORD + 1, - ); + K32GetModuleBaseNameW(**process_handler, h_mod, process_name.as_mut_slice()); null_terminated_wchar_to_string(&process_name) } -unsafe fn get_h_mod(process_handler: &HandleWrapper, h_mod: &mut *mut c_void) -> bool { +unsafe fn get_h_mod(process_handler: &HandleWrapper, h_mod: &mut HINSTANCE) -> bool { let mut cb_needed = 0; - EnumProcessModulesEx( + K32EnumProcessModulesEx( **process_handler, - h_mod as *mut *mut c_void as _, - size_of::() as DWORD, + h_mod, + size_of::() as u32, &mut cb_needed, LIST_MODULES_ALL, - ) != 0 + ) + .as_bool() } unsafe fn get_exe(process_handler: &HandleWrapper) -> PathBuf { - let mut exe_buf = [0u16; MAX_PATH + 1]; - GetModuleFileNameExW( + let mut exe_buf = [0u16; MAX_PATH as usize + 1]; + K32GetModuleFileNameExW( **process_handler, - std::ptr::null_mut(), - exe_buf.as_mut_ptr(), - MAX_PATH as DWORD + 1, + HINSTANCE::default(), + exe_buf.as_mut_slice(), ); PathBuf::from(null_terminated_wchar_to_string(&exe_buf)) @@ -281,17 +284,18 @@ impl Process { let process_handler = get_process_handler(pid)?; let mut info: MaybeUninit = MaybeUninit::uninit(); if NtQueryInformationProcess( - *process_handler, + process_handler.0, ProcessBasicInformation, - info.as_mut_ptr() as *mut _, + info.as_mut_ptr().cast(), size_of::() as _, null_mut(), - ) != 0 + ) + .is_err() { return None; } let info = info.assume_init(); - let mut h_mod = null_mut(); + let mut h_mod = HINSTANCE::default(); let name = if get_h_mod(&process_handler, &mut h_mod) { get_process_name(&process_handler, h_mod) @@ -449,7 +453,7 @@ impl ProcessExt for Process { super::system::convert_signal(signal)?; let mut kill = process::Command::new("taskkill.exe"); kill.arg("/PID").arg(self.pid.to_string()).arg("/F"); - kill.creation_flags(CREATE_NO_WINDOW); + kill.creation_flags(CREATE_NO_WINDOW.0); match kill.output() { Ok(o) => Some(o.status.success()), Err(_) => Some(false), @@ -547,7 +551,7 @@ impl ProcessExt for Process { fn session_id(&self) -> Option { unsafe { let mut out = 0; - if ProcessIdToSessionId(self.pid.as_u32(), &mut out) != 0 { + if ProcessIdToSessionId(self.pid.as_u32(), &mut out).as_bool() { return Some(Pid(out as _)); } sysinfo_debug!("ProcessIdToSessionId failed, error: {:?}", GetLastError()); @@ -599,21 +603,26 @@ unsafe fn ph_query_process_variable_size( process_handle: &HandleWrapper, process_information_class: PROCESSINFOCLASS, ) -> Option> { - let mut return_length = MaybeUninit::::uninit(); + let mut return_length = MaybeUninit::::uninit(); let mut status = NtQueryInformationProcess( **process_handle, - process_information_class, + process_information_class as _, null_mut(), 0, return_length.as_mut_ptr() as *mut _, ); - if status != STATUS_BUFFER_OVERFLOW - && status != STATUS_BUFFER_TOO_SMALL - && status != STATUS_INFO_LENGTH_MISMATCH - { - return None; + if let Err(err) = status { + if ![ + STATUS_BUFFER_OVERFLOW.into(), + STATUS_BUFFER_TOO_SMALL.into(), + STATUS_INFO_LENGTH_MISMATCH.into(), + ] + .contains(&err.code()) + { + return None; + } } let mut return_length = return_length.assume_init(); @@ -621,12 +630,12 @@ unsafe fn ph_query_process_variable_size( let mut buffer: Vec = Vec::with_capacity(buf_len + 1); status = NtQueryInformationProcess( **process_handle, - process_information_class, + process_information_class as _, buffer.as_mut_ptr() as *mut _, return_length, &mut return_length as *mut _, ); - if !NT_SUCCESS(status) { + if status.is_err() { return None; } buffer.set_len(buf_len); @@ -634,10 +643,10 @@ unsafe fn ph_query_process_variable_size( Some(buffer) } -unsafe fn get_cmdline_from_buffer(buffer: *const u16) -> Vec { +unsafe fn get_cmdline_from_buffer(buffer: PCWSTR) -> Vec { // Get argc and argv from the command line let mut argc = MaybeUninit::::uninit(); - let argv_p = winapi::um::shellapi::CommandLineToArgvW(buffer, argc.as_mut_ptr()); + let argv_p = CommandLineToArgvW(buffer, argc.as_mut_ptr()); if argv_p.is_null() { return Vec::new(); } @@ -646,22 +655,23 @@ unsafe fn get_cmdline_from_buffer(buffer: *const u16) -> Vec { let mut res = Vec::new(); for arg in argv { - let len = libc::wcslen(*arg); - let str_slice = std::slice::from_raw_parts(*arg, len); - res.push(String::from_utf16_lossy(str_slice)); + res.push(String::from_utf16_lossy(arg.as_wide())); } - winapi::um::winbase::LocalFree(argv_p as *mut _); + LocalFree(argv_p as _); res } -unsafe fn get_region_size(handle: &HandleWrapper, ptr: LPVOID) -> Result { +unsafe fn get_region_size( + handle: &HandleWrapper, + ptr: *const c_void, +) -> Result { let mut meminfo = MaybeUninit::::uninit(); if VirtualQueryEx( **handle, - ptr, - meminfo.as_mut_ptr() as *mut _, + Some(ptr), + meminfo.as_mut_ptr().cast(), size_of::(), ) == 0 { @@ -673,20 +683,21 @@ unsafe fn get_region_size(handle: &HandleWrapper, ptr: LPVOID) -> Result Result, &'static str> { let mut buffer: Vec = Vec::with_capacity(size / 2 + 1); let mut bytes_read = 0; - if ReadProcessMemory( + let ret = ReadProcessMemory( **handle, - ptr as *mut _, - buffer.as_mut_ptr() as *mut _, + ptr, + buffer.as_mut_ptr().cast(), size, - &mut bytes_read, - ) == FALSE - { + Some(&mut bytes_read), + ) + .as_bool(); + if !ret { return Err("Unable to read process data"); } @@ -721,7 +732,7 @@ macro_rules! impl_RtlUserProcessParameters { fn get_environ(&self, handle: &HandleWrapper) -> Result, &'static str> { let ptr = self.Environment; unsafe { - let size = get_region_size(handle, ptr as LPVOID)?; + let size = get_region_size(handle, ptr as _)?; get_process_data(handle, ptr as _, size as _) } } @@ -740,15 +751,15 @@ unsafe fn get_process_params( } // First check if target process is running in wow64 compatibility emulator - let mut pwow32info = MaybeUninit::::uninit(); + let mut pwow32info = MaybeUninit::<*const c_void>::uninit(); let result = NtQueryInformationProcess( **handle, ProcessWow64Information, - pwow32info.as_mut_ptr() as *mut _, - size_of::() as u32, + pwow32info.as_mut_ptr().cast(), + size_of::<*const c_void>() as u32, null_mut(), ); - if !NT_SUCCESS(result) { + if result.is_err() { return Err("Unable to check WOW64 information about the process"); } let pwow32info = pwow32info.assume_init(); @@ -760,38 +771,40 @@ unsafe fn get_process_params( let result = NtQueryInformationProcess( **handle, ProcessBasicInformation, - pbasicinfo.as_mut_ptr() as *mut _, + pbasicinfo.as_mut_ptr().cast(), size_of::() as u32, null_mut(), ); - if !NT_SUCCESS(result) { + if result.is_err() { return Err("Unable to get basic process information"); } let pinfo = pbasicinfo.assume_init(); let mut peb = MaybeUninit::::uninit(); - if ReadProcessMemory( + let ret = ReadProcessMemory( **handle, - pinfo.PebBaseAddress as *mut _, - peb.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - null_mut(), - ) != TRUE - { + pinfo.PebBaseAddress.cast(), + peb.as_mut_ptr().cast(), + size_of::(), + None, + ) + .as_bool(); + if !ret { return Err("Unable to read process PEB"); } let peb = peb.assume_init(); let mut proc_params = MaybeUninit::::uninit(); - if ReadProcessMemory( + let ret = ReadProcessMemory( **handle, - peb.ProcessParameters as *mut PRTL_USER_PROCESS_PARAMETERS as *mut _, - proc_params.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - null_mut(), - ) != TRUE - { + peb.ProcessParameters.cast(), + proc_params.as_mut_ptr().cast(), + size_of::(), + None, + ) + .as_bool(); + if !ret { return Err("Unable to read process parameters"); } @@ -805,27 +818,29 @@ unsafe fn get_process_params( // target is a 32 bit process in wow64 mode let mut peb32 = MaybeUninit::::uninit(); - if ReadProcessMemory( + let ret = ReadProcessMemory( **handle, pwow32info, - peb32.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - null_mut(), - ) != TRUE - { + peb32.as_mut_ptr().cast(), + size_of::(), + None, + ) + .as_bool(); + if !ret { return Err("Unable to read PEB32"); } let peb32 = peb32.assume_init(); let mut proc_params = MaybeUninit::::uninit(); - if ReadProcessMemory( + let ret = ReadProcessMemory( **handle, - peb32.ProcessParameters as *mut PRTL_USER_PROCESS_PARAMETERS32 as *mut _, - proc_params.as_mut_ptr() as *mut _, - size_of::() as SIZE_T, - null_mut(), - ) != TRUE - { + peb32.ProcessParameters as *mut _, + proc_params.as_mut_ptr().cast(), + size_of::(), + None, + ) + .as_bool(); + if !ret { return Err("Unable to read 32 bit process parameters"); } let proc_params = proc_params.assume_init(); @@ -860,7 +875,7 @@ fn get_cmd_line_old( handle: &HandleWrapper, ) -> Vec { match params.get_cmdline(handle) { - Ok(buffer) => unsafe { get_cmdline_from_buffer(buffer.as_ptr()) }, + Ok(buffer) => unsafe { get_cmdline_from_buffer(PCWSTR::from_raw(buffer.as_ptr())) }, Err(_e) => { sysinfo_debug!("get_cmd_line_old failed to get data: {}", _e); Vec::new() @@ -871,11 +886,13 @@ fn get_cmd_line_old( #[allow(clippy::cast_ptr_alignment)] fn get_cmd_line_new(handle: &HandleWrapper) -> Vec { unsafe { - if let Some(buffer) = ph_query_process_variable_size(handle, ProcessCommandLineInformation) - { + if let Some(buffer) = ph_query_process_variable_size( + handle, + PROCESSINFOCLASS(ProcessCommandLineInformation as _), + ) { let buffer = (*(buffer.as_ptr() as *const UNICODE_STRING)).Buffer; - get_cmdline_from_buffer(buffer) + get_cmdline_from_buffer(PCWSTR::from_raw(buffer.as_ptr())) } else { vec![] } @@ -965,9 +982,9 @@ pub(crate) fn compute_cpu_usage(p: &mut Process, nb_cpus: u64) { // FIXME: should these values be stored in one place to make use of // `MINIMUM_CPU_UPDATE_INTERVAL`? GetSystemTimes( - &mut fglobal_idle_time as *mut FILETIME, - &mut fglobal_kernel_time as *mut FILETIME, - &mut fglobal_user_time as *mut FILETIME, + Some(&mut fglobal_idle_time), + Some(&mut fglobal_kernel_time), + Some(&mut fglobal_user_time), ); let mut sys: ULARGE_INTEGER = std::mem::zeroed(); @@ -1030,8 +1047,8 @@ pub(crate) fn update_disk_usage(p: &mut Process) { if let Some(handle) = p.get_handle() { unsafe { - let ret = GetProcessIoCounters(handle, counters.as_mut_ptr()); - if ret == 0 { + let ret = GetProcessIoCounters(handle, counters.as_mut_ptr()).as_bool(); + if !ret { sysinfo_debug!("GetProcessIoCounters call failed on process {}", p.pid()); } else { let counters = counters.assume_init(); @@ -1048,13 +1065,13 @@ pub(crate) fn update_memory(p: &mut Process) { if let Some(handle) = p.get_handle() { unsafe { let mut pmc: PROCESS_MEMORY_COUNTERS_EX = zeroed(); - if GetProcessMemoryInfo( + let ret = K32GetProcessMemoryInfo( handle, - &mut pmc as *mut PROCESS_MEMORY_COUNTERS_EX as *mut c_void - as *mut PROCESS_MEMORY_COUNTERS, - size_of::() as DWORD, - ) != 0 - { + (&mut pmc as *mut PROCESS_MEMORY_COUNTERS_EX).cast(), + size_of::() as u32, + ) + .as_bool(); + if ret { p.memory = pmc.WorkingSetSize as _; p.virtual_memory = pmc.PrivateUsage as _; } diff --git a/src/windows/sid.rs b/src/windows/sid.rs index 44d94f2f5..6529f1801 100644 --- a/src/windows/sid.rs +++ b/src/windows/sid.rs @@ -2,18 +2,13 @@ use std::{fmt::Display, str::FromStr}; -use winapi::{ - shared::{ - sddl::{ConvertSidToStringSidW, ConvertStringSidToSidW}, - winerror::ERROR_INSUFFICIENT_BUFFER, - }, - um::{ - errhandlingapi::GetLastError, - securitybaseapi::{CopySid, GetLengthSid, IsValidSid}, - winbase::{LocalFree, LookupAccountSidW}, - winnt::{SidTypeUnknown, LPWSTR, PSID}, - }, +use windows::core::{PCWSTR, PWSTR}; +use windows::Win32::Foundation::{GetLastError, ERROR_INSUFFICIENT_BUFFER, PSID}; +use windows::Win32::Security::Authorization::{ConvertSidToStringSidW, ConvertStringSidToSidW}; +use windows::Win32::Security::{ + CopySid, GetLengthSid, IsValidSid, LookupAccountSidW, SidTypeUnknown, }; +use windows::Win32::System::Memory::LocalFree; use crate::sys::utils::to_str; @@ -26,11 +21,11 @@ pub struct Sid { impl Sid { /// Creates an `Sid` by making a copy of the given raw SID. pub(crate) unsafe fn from_psid(psid: PSID) -> Option { - if psid.is_null() { + if psid.is_invalid() { return None; } - if IsValidSid(psid) == 0 { + if !IsValidSid(psid).as_bool() { return None; } @@ -38,7 +33,8 @@ impl Sid { let mut sid = vec![0; length as usize]; - if CopySid(length, sid.as_mut_ptr() as *mut _, psid) == 0 { + let ret = CopySid(length, PSID(sid.as_mut_ptr().cast()), psid).as_bool(); + if !ret { sysinfo_debug!("CopySid failed: {:?}", GetLastError()); return None; } @@ -68,16 +64,18 @@ impl Sid { let mut domain_len = 0; let mut name_use = SidTypeUnknown; - if LookupAccountSidW( - std::ptr::null_mut(), - self.sid.as_ptr() as *mut _, - std::ptr::null_mut(), + let sid = PSID(self.sid.as_ptr().cast_mut().cast()); + let ret = LookupAccountSidW( + PCWSTR::null(), + sid, + PWSTR::null(), &mut name_len, - std::ptr::null_mut(), + PWSTR::null(), &mut domain_len, &mut name_use, - ) == 0 - { + ) + .as_bool(); + if !ret { let error = GetLastError(); if error != ERROR_INSUFFICIENT_BUFFER { sysinfo_debug!("LookupAccountSidW failed: {:?}", error); @@ -91,21 +89,22 @@ impl Sid { // for the domain. domain_len = 0; - if LookupAccountSidW( - std::ptr::null_mut(), - self.sid.as_ptr() as *mut _, - name.as_mut_ptr(), + let ret = LookupAccountSidW( + PCWSTR::null(), + sid, + PWSTR::from_raw(name.as_mut_ptr()), &mut name_len, - std::ptr::null_mut(), + PWSTR::null(), &mut domain_len, &mut name_use, - ) == 0 - { + ) + .as_bool(); + if !ret { sysinfo_debug!("LookupAccountSidW failed: {:?}", GetLastError()); return None; } - Some(to_str(name.as_mut_ptr())) + Some(to_str(PWSTR::from_raw(name.as_mut_ptr()))) } } } @@ -113,17 +112,18 @@ impl Sid { impl Display for Sid { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { unsafe fn convert_sid_to_string_sid(sid: PSID) -> Option { - let mut string_sid: LPWSTR = std::ptr::null_mut(); - if ConvertSidToStringSidW(sid, &mut string_sid) == 0 { + let mut string_sid = PWSTR::null(); + if !ConvertSidToStringSidW(sid, &mut string_sid).as_bool() { sysinfo_debug!("ConvertSidToStringSidW failed: {:?}", GetLastError()); return None; } let result = to_str(string_sid); - LocalFree(string_sid as *mut _); + LocalFree(string_sid.0 as _); Some(result) } - let string_sid = unsafe { convert_sid_to_string_sid(self.sid.as_ptr() as *mut _) }; + let string_sid = + unsafe { convert_sid_to_string_sid(PSID(self.sid.as_ptr().cast_mut().cast())) }; let string_sid = string_sid.ok_or(std::fmt::Error)?; write!(f, "{string_sid}") @@ -138,15 +138,15 @@ impl FromStr for Sid { let mut string_sid: Vec = s.encode_utf16().collect(); string_sid.push(0); - let mut psid: PSID = std::ptr::null_mut(); - if ConvertStringSidToSidW(string_sid.as_ptr(), &mut psid) == 0 { + let mut psid = PSID::default(); + if !ConvertStringSidToSidW(PCWSTR::from_raw(string_sid.as_ptr()), &mut psid).as_bool() { return Err(format!( "ConvertStringSidToSidW failed: {:?}", GetLastError() )); } let sid = Self::from_psid(psid); - LocalFree(psid as *mut _); + LocalFree(psid.0 as _); // Unwrapping because ConvertStringSidToSidW should've performed // all the necessary validations. If it returned an invalid SID, diff --git a/src/windows/system.rs b/src/windows/system.rs index 0fc62677e..7ce966626 100644 --- a/src/windows/system.rs +++ b/src/windows/system.rs @@ -4,7 +4,6 @@ use crate::{ CpuRefreshKind, LoadAvg, Networks, Pid, ProcessExt, ProcessRefreshKind, RefreshKind, SystemExt, User, }; -use winapi::um::winreg::HKEY_LOCAL_MACHINE; use crate::sys::component::{self, Component}; use crate::sys::cpu::*; @@ -18,24 +17,23 @@ use crate::utils::into_iter; use std::cell::UnsafeCell; use std::collections::HashMap; +use std::ffi::c_void; use std::mem::{size_of, zeroed}; use std::time::{Duration, SystemTime}; -use ntapi::ntexapi::{ - NtQuerySystemInformation, SystemProcessInformation, SYSTEM_PROCESS_INFORMATION, -}; -use winapi::ctypes::wchar_t; -use winapi::shared::minwindef::{FALSE, TRUE}; -use winapi::shared::ntdef::{PVOID, ULONG}; -use winapi::shared::ntstatus::STATUS_INFO_LENGTH_MISMATCH; -use winapi::um::minwinbase::STILL_ACTIVE; -use winapi::um::processthreadsapi::GetExitCodeProcess; -use winapi::um::psapi::{GetPerformanceInfo, PERFORMANCE_INFORMATION}; -use winapi::um::sysinfoapi::{ +use ntapi::ntexapi::SYSTEM_PROCESS_INFORMATION; +use windows::core::PWSTR; +use windows::Win32::Foundation::{HANDLE, STATUS_INFO_LENGTH_MISMATCH, STILL_ACTIVE}; +use windows::Win32::System::ProcessStatus::{K32GetPerformanceInfo, PERFORMANCE_INFORMATION}; +use windows::Win32::System::Registry::HKEY_LOCAL_MACHINE; +use windows::Win32::System::SystemInformation::{ ComputerNamePhysicalDnsHostname, GetComputerNameExW, GetTickCount64, GlobalMemoryStatusEx, MEMORYSTATUSEX, }; -use winapi::um::winnt::HANDLE; +use windows::Win32::System::Threading::GetExitCodeProcess; +use windows::Win32::System::WindowsProgramming::{ + NtQuerySystemInformation, SystemProcessInformation, +}; declare_signals! { (), @@ -174,8 +172,8 @@ impl SystemExt for System { self.mem_total = mem_info.ullTotalPhys as _; self.mem_available = mem_info.ullAvailPhys as _; let mut perf_info: PERFORMANCE_INFORMATION = zeroed(); - if GetPerformanceInfo(&mut perf_info, size_of::() as u32) - == TRUE + if K32GetPerformanceInfo(&mut perf_info, size_of::() as u32) + .as_bool() { let swap_total = perf_info.PageSize.saturating_mul( perf_info @@ -232,13 +230,13 @@ impl SystemExt for System { process_information.set_len(buffer_size); let ntstatus = NtQuerySystemInformation( SystemProcessInformation, - process_information.as_mut_ptr() as PVOID, - buffer_size as ULONG, + process_information.as_mut_ptr() as *mut c_void, + buffer_size as u32, &mut cb_needed, ); - if ntstatus != STATUS_INFO_LENGTH_MISMATCH { - if ntstatus < 0 { + if ntstatus != Err(STATUS_INFO_LENGTH_MISMATCH.into()) { + if ntstatus.is_err() { sysinfo_debug!( "Couldn't get process infos: NtQuerySystemInformation returned {}", ntstatus @@ -506,10 +504,8 @@ impl Default for System { pub(crate) fn is_proc_running(handle: HANDLE) -> bool { let mut exit_code = 0; - unsafe { - let ret = GetExitCodeProcess(handle, &mut exit_code); - !(ret == FALSE || exit_code != STILL_ACTIVE) - } + let ret = unsafe { GetExitCodeProcess(handle, &mut exit_code).as_bool() }; + !ret && exit_code == STILL_ACTIVE.0 as u32 } /// If it returns `None`, it means that the PID owner changed and that the `Process` must be @@ -569,7 +565,7 @@ fn get_dns_hostname() -> Option { unsafe { GetComputerNameExW( ComputerNamePhysicalDnsHostname, - std::ptr::null_mut(), + PWSTR::null(), &mut buffer_size, ); @@ -579,9 +575,10 @@ fn get_dns_hostname() -> Option { // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ne-sysinfoapi-computer_name_format if GetComputerNameExW( ComputerNamePhysicalDnsHostname, - buffer.as_mut_ptr() as *mut wchar_t, + PWSTR::from_raw(buffer.as_mut_ptr()), &mut buffer_size, - ) == TRUE + ) + .as_bool() { if let Some(pos) = buffer.iter().position(|c| *c == 0) { buffer.resize(pos, 0); diff --git a/src/windows/tools.rs b/src/windows/tools.rs index a0c334010..b41e0b607 100644 --- a/src/windows/tools.rs +++ b/src/windows/tools.rs @@ -3,9 +3,7 @@ use crate::sys::cpu::{self, Cpu, Query}; use crate::CpuRefreshKind; -use std::mem::zeroed; - -use winapi::um::sysinfoapi::{GetSystemInfo, SYSTEM_INFO}; +use windows::Win32::System::SystemInformation::{GetSystemInfo, SYSTEM_INFO}; pub(crate) struct KeyHandler { pub unique_id: String, @@ -19,7 +17,7 @@ impl KeyHandler { pub(crate) fn init_cpus(refresh_kind: CpuRefreshKind) -> (Vec, String, String) { unsafe { - let mut sys_info: SYSTEM_INFO = zeroed(); + let mut sys_info = SYSTEM_INFO::default(); GetSystemInfo(&mut sys_info); let (vendor_id, brand) = cpu::get_vendor_id_and_brand(&sys_info); let nb_cpus = sys_info.dwNumberOfProcessors as usize; diff --git a/src/windows/users.rs b/src/windows/users.rs index 8a8625b37..de051c2d8 100644 --- a/src/windows/users.rs +++ b/src/windows/users.rs @@ -8,33 +8,26 @@ use crate::{ }; use std::ptr::null_mut; -use winapi::shared::lmcons::{MAX_PREFERRED_LENGTH, NET_API_STATUS}; -use winapi::shared::minwindef::{DWORD, LPBYTE}; -use winapi::shared::ntstatus::STATUS_SUCCESS; -use winapi::shared::winerror::ERROR_MORE_DATA; -use winapi::um::lmaccess::{ - NetUserEnum, NetUserGetInfo, NetUserGetLocalGroups, LOCALGROUP_USERS_INFO_0, USER_INFO_23, + +use windows::core::PCWSTR; +use windows::w; +use windows::Win32::Foundation::{ERROR_MORE_DATA, LUID}; +use windows::Win32::NetworkManagement::NetManagement::{ + NERR_Success, NetApiBufferFree, NetUserEnum, NetUserGetInfo, NetUserGetLocalGroups, + FILTER_NORMAL_ACCOUNT, LG_INCLUDE_INDIRECT, LOCALGROUP_USERS_INFO_0, MAX_PREFERRED_LENGTH, + USER_INFO_0, USER_INFO_23, }; -use winapi::um::lmaccess::{FILTER_NORMAL_ACCOUNT, LG_INCLUDE_INDIRECT, USER_INFO_0}; -use winapi::um::lmapibuf::NetApiBufferFree; -use winapi::um::ntlsa::{ +use windows::Win32::Security::Authentication::Identity::{ LsaEnumerateLogonSessions, LsaFreeReturnBuffer, LsaGetLogonSessionData, - SECURITY_LOGON_SESSION_DATA, + SECURITY_LOGON_SESSION_DATA, SECURITY_LOGON_TYPE, }; -use winapi::um::winnt::{LPWSTR, LUID}; - -// FIXME: once this is mreged in winapi, it can be removed. -#[allow(non_upper_case_globals)] -const NERR_Success: NET_API_STATUS = 0; struct NetApiBuffer(*mut T); impl Drop for NetApiBuffer { fn drop(&mut self) { - unsafe { - if !self.0.is_null() { - NetApiBufferFree(self.0 as *mut _); - } + if !self.0.is_null() { + unsafe { NetApiBufferFree(Some(self.0.cast())) }; } } } @@ -51,10 +44,10 @@ impl NetApiBuffer { &mut self.0 } - pub unsafe fn inner_mut_as_bytes(&mut self) -> &mut LPBYTE { + pub unsafe fn inner_mut_as_bytes(&mut self) -> &mut *mut u8 { // https://doc.rust-lang.org/std/mem/fn.transmute.html // Turning an &mut T into an &mut U: - &mut *(self.inner_mut() as *mut *mut T as *mut LPBYTE) + &mut *(self.inner_mut() as *mut *mut T as *mut *mut u8) } } @@ -62,10 +55,8 @@ struct LsaBuffer(*mut T); impl Drop for LsaBuffer { fn drop(&mut self) { - unsafe { - if !self.0.is_null() { - LsaFreeReturnBuffer(self.0 as *mut _); - } + if !self.0.is_null() { + let _r = unsafe { LsaFreeReturnBuffer(self.0 as *mut _) }; } } } @@ -83,14 +74,14 @@ impl LsaBuffer { } } -unsafe fn get_groups_for_user(username: LPWSTR) -> Vec { +unsafe fn get_groups_for_user(username: PCWSTR) -> Vec { let mut buf: NetApiBuffer = Default::default(); let mut nb_entries = 0; let mut total_entries = 0; let mut groups; let status = NetUserGetLocalGroups( - [0u16].as_ptr(), + w!(""), username, 0, LG_INCLUDE_INDIRECT, @@ -117,22 +108,22 @@ unsafe fn get_groups_for_user(username: LPWSTR) -> Vec { pub unsafe fn get_users() -> Vec { let mut users = Vec::new(); - let mut resume_handle: DWORD = 0; + let mut resume_handle: u32 = 0; loop { let mut buffer: NetApiBuffer = Default::default(); let mut nb_read = 0; let mut total = 0; let status = NetUserEnum( - null_mut(), + PCWSTR::null(), 0, FILTER_NORMAL_ACCOUNT, buffer.inner_mut_as_bytes(), MAX_PREFERRED_LENGTH, &mut nb_read, &mut total, - &mut resume_handle, + Some(&mut resume_handle), ); - if status == NERR_Success || status == ERROR_MORE_DATA { + if status == NERR_Success || status == ERROR_MORE_DATA.0 { let entries = std::slice::from_raw_parts(buffer.0, nb_read as _); for entry in entries { if entry.usri0_name.is_null() { @@ -140,8 +131,12 @@ pub unsafe fn get_users() -> Vec { } let mut user: NetApiBuffer = Default::default(); - if NetUserGetInfo(null_mut(), entry.usri0_name, 23, user.inner_mut_as_bytes()) - == NERR_Success + if NetUserGetInfo( + PCWSTR::null(), + PCWSTR::from_raw(entry.usri0_name.as_ptr()), + 23, + user.inner_mut_as_bytes(), + ) == NERR_Success { if let Some(sid) = Sid::from_psid((*user.0).usri23_user_sid) { // Get the account name from the SID (because it's usually @@ -154,7 +149,9 @@ pub unsafe fn get_users() -> Vec { uid: Uid(sid), gid: Gid(0), name, - groups: get_groups_for_user(entry.usri0_name), + groups: get_groups_for_user(PCWSTR::from_raw( + entry.usri0_name.as_ptr(), + )), }); } } @@ -162,16 +159,16 @@ pub unsafe fn get_users() -> Vec { } else { sysinfo_debug!( "NetUserEnum error: {}", - if status == winapi::shared::winerror::ERROR_ACCESS_DENIED { + if status == windows::Win32::Foundation::ERROR_ACCESS_DENIED.0 { "access denied" - } else if status == winapi::shared::winerror::ERROR_INVALID_LEVEL { + } else if status == windows::Win32::Foundation::ERROR_INVALID_LEVEL.0 { "invalid level" } else { "unknown error" } ); } - if status != ERROR_MORE_DATA { + if status != ERROR_MORE_DATA.0 { break; } } @@ -179,17 +176,15 @@ pub unsafe fn get_users() -> Vec { // First part done. Second part now! let mut nb_sessions = 0; let mut uids: LsaBuffer = Default::default(); - if LsaEnumerateLogonSessions(&mut nb_sessions, uids.inner_mut()) != STATUS_SUCCESS { + if LsaEnumerateLogonSessions(&mut nb_sessions, uids.inner_mut()).is_err() { sysinfo_debug!("LsaEnumerateLogonSessions failed"); } else { let entries = std::slice::from_raw_parts_mut(uids.0, nb_sessions as _); for entry in entries { let mut data: LsaBuffer = Default::default(); - if LsaGetLogonSessionData(entry, data.inner_mut()) == STATUS_SUCCESS - && !data.0.is_null() - { + if LsaGetLogonSessionData(entry, data.inner_mut()).is_ok() && !data.0.is_null() { let data = *data.0; - if data.LogonType == winapi::um::ntlsa::Network { + if data.LogonType == SECURITY_LOGON_TYPE::Network.0 as _ { continue; } @@ -207,7 +202,7 @@ pub unsafe fn get_users() -> Vec { // if this fails. let name = sid.account_name().unwrap_or_else(|| { String::from_utf16(std::slice::from_raw_parts( - data.UserName.Buffer, + data.UserName.Buffer.as_ptr(), data.UserName.Length as usize / std::mem::size_of::(), )) .unwrap_or_else(|_err| { diff --git a/src/windows/utils.rs b/src/windows/utils.rs index 96132117e..0d4577854 100644 --- a/src/windows/utils.rs +++ b/src/windows/utils.rs @@ -1,10 +1,10 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use winapi::shared::minwindef::FILETIME; -use winapi::shared::minwindef::{DWORD, HKEY}; -use winapi::shared::winerror; -use winapi::um::winnt::{KEY_READ, LPWSTR}; -use winapi::um::winreg::{RegCloseKey, RegOpenKeyExW, RegQueryValueExW}; +use windows::core::{PCWSTR, PWSTR}; +use windows::Win32::Foundation::{self, FILETIME}; +use windows::Win32::System::Registry::{ + RegCloseKey, RegOpenKeyExW, RegQueryValueExW, HKEY, KEY_READ, REG_NONE, +}; use std::ffi::OsStr; use std::os::windows::ffi::OsStrExt; @@ -23,18 +23,8 @@ pub(crate) fn get_now() -> u64 { .unwrap_or(0) } -pub(crate) unsafe fn to_str(p: LPWSTR) -> String { - let mut i = 0; - - loop { - let c = *p.offset(i); - if c == 0 { - break; - } - i += 1; - } - let s = std::slice::from_raw_parts(p, i as _); - String::from_utf16(s).unwrap_or_else(|_e| { +pub(crate) unsafe fn to_str(p: PWSTR) -> String { + String::from_utf16(p.as_wide()).unwrap_or_else(|_e| { sysinfo_debug!("Failed to convert to UTF-16 string: {}", _e); String::new() }) @@ -51,24 +41,36 @@ struct RegKey(HKEY); impl RegKey { unsafe fn open(hkey: HKEY, path: &[u16]) -> Option { - let mut new_hkey: HKEY = std::ptr::null_mut(); - if RegOpenKeyExW(hkey, path.as_ptr(), 0, KEY_READ, &mut new_hkey) != 0 { + let mut new_hkey = Default::default(); + if RegOpenKeyExW( + hkey, + PCWSTR::from_raw(path.as_ptr()), + 0, + KEY_READ, + &mut new_hkey, + ) != Foundation::ERROR_SUCCESS + { return None; } Some(Self(new_hkey)) } - unsafe fn get_value(&self, field_name: &[u16], buf: &mut [u8], buf_len: &mut DWORD) -> DWORD { - let mut buf_type: DWORD = 0; + unsafe fn get_value( + &self, + field_name: &[u16], + buf: &mut [u8], + buf_len: &mut u32, + ) -> Foundation::WIN32_ERROR { + let mut buf_type = REG_NONE; RegQueryValueExW( self.0, - field_name.as_ptr(), - std::ptr::null_mut(), - &mut buf_type, - buf.as_mut_ptr() as _, - buf_len, - ) as DWORD + PCWSTR::from_raw(field_name.as_ptr()), + None, + Some(&mut buf_type), + Some(buf.as_mut_ptr()), + Some(buf_len), + ) } } @@ -86,13 +88,13 @@ pub(crate) fn get_reg_string_value(hkey: HKEY, path: &str, field_name: &str) -> unsafe { let new_key = RegKey::open(hkey, &c_path)?; - let mut buf_len: DWORD = 2048; + let mut buf_len: u32 = 2048; let mut buf: Vec = Vec::with_capacity(buf_len as usize); loop { match new_key.get_value(&c_field_name, &mut buf, &mut buf_len) { - winerror::ERROR_SUCCESS => break, - winerror::ERROR_MORE_DATA => { + Foundation::ERROR_SUCCESS => break, + Foundation::ERROR_MORE_DATA => { buf.reserve(buf_len as _); } _ => return None, @@ -116,11 +118,11 @@ pub(crate) fn get_reg_value_u32(hkey: HKEY, path: &str, field_name: &str) -> Opt unsafe { let new_key = RegKey::open(hkey, &c_path)?; - let mut buf_len: DWORD = 4; + let mut buf_len: u32 = 4; let mut buf = [0u8; 4]; match new_key.get_value(&c_field_name, &mut buf, &mut buf_len) { - winerror::ERROR_SUCCESS => Some(buf), + Foundation::ERROR_SUCCESS => Some(buf), _ => None, } }