From 4e8199b572f2035b7749cba276ece3a26630d23e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:21 +0200 Subject: Adding upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/sysinfo/src/windows/disk.rs | 36 +++++---- vendor/sysinfo/src/windows/macros.rs | 16 ---- vendor/sysinfo/src/windows/mod.rs | 2 - vendor/sysinfo/src/windows/process.rs | 94 ++++++++++++++++------ vendor/sysinfo/src/windows/system.rs | 147 +++++++++++++++++++++++----------- 5 files changed, 192 insertions(+), 103 deletions(-) delete mode 100644 vendor/sysinfo/src/windows/macros.rs (limited to 'vendor/sysinfo/src/windows') diff --git a/vendor/sysinfo/src/windows/disk.rs b/vendor/sysinfo/src/windows/disk.rs index ae393afb2..215fb8c58 100644 --- a/vendor/sysinfo/src/windows/disk.rs +++ b/vendor/sysinfo/src/windows/disk.rs @@ -16,9 +16,10 @@ 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::{ - DEVICE_TRIM_DESCRIPTOR, IOCTL_STORAGE_QUERY_PROPERTY, STORAGE_PROPERTY_QUERY, + PropertyStandardQuery, StorageDeviceSeekPenaltyProperty, IOCTL_STORAGE_QUERY_PROPERTY, + STORAGE_PROPERTY_QUERY, }; -use winapi::um::winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, HANDLE, ULARGE_INTEGER}; +use winapi::um::winnt::{BOOLEAN, FILE_SHARE_READ, FILE_SHARE_WRITE, HANDLE, ULARGE_INTEGER}; #[doc = include_str!("../../md_doc/disk.md")] pub struct Disk { @@ -122,14 +123,23 @@ unsafe fn get_drive_size(mount_point: &[u16]) -> Option<(u64, u64)> { ) != 0 { Some(( - *total_size.QuadPart() as u64, - *available_space.QuadPart() as u64, + *total_size.QuadPart() as _, + *available_space.QuadPart() as _, )) } else { None } } +// FIXME: To be removed once has been merged. +#[allow(non_snake_case)] +#[repr(C)] +struct DEVICE_SEEK_PENALTY_DESCRIPTOR { + Version: DWORD, + Size: DWORD, + IncursSeekPenalty: BOOLEAN, +} + pub(crate) unsafe fn get_disks() -> Vec { let drives = GetLogicalDrives(); if drives == 0 { @@ -201,16 +211,12 @@ pub(crate) unsafe fn get_disks() -> Vec { if total_space == 0 { return None; } - /*let mut spq_trim: STORAGE_PROPERTY_QUERY = std::mem::zeroed(); - spq_trim.PropertyId = StorageDeviceTrimProperty; - spq_trim.QueryType = PropertyStandardQuery; - let mut dtd: DEVICE_TRIM_DESCRIPTOR = std::mem::zeroed();*/ let mut spq_trim = STORAGE_PROPERTY_QUERY { - PropertyId: 8, - QueryType: 0, + PropertyId: StorageDeviceSeekPenaltyProperty, + QueryType: PropertyStandardQuery, AdditionalParameters: [0], }; - let mut dtd: DEVICE_TRIM_DESCRIPTOR = std::mem::zeroed(); + let mut result: DEVICE_SEEK_PENALTY_DESCRIPTOR = std::mem::zeroed(); let mut dw_size = 0; let type_ = if DeviceIoControl( @@ -218,16 +224,16 @@ pub(crate) unsafe fn get_disks() -> Vec { IOCTL_STORAGE_QUERY_PROPERTY, &mut spq_trim as *mut STORAGE_PROPERTY_QUERY as *mut c_void, size_of::() as DWORD, - &mut dtd as *mut DEVICE_TRIM_DESCRIPTOR 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 + || dw_size != size_of::() as DWORD { DiskType::Unknown(-1) } else { - let is_ssd = dtd.TrimEnabled != 0; + let is_ssd = result.IncursSeekPenalty == 0; if is_ssd { DiskType::SSD } else { diff --git a/vendor/sysinfo/src/windows/macros.rs b/vendor/sysinfo/src/windows/macros.rs deleted file mode 100644 index b0c024c7c..000000000 --- a/vendor/sysinfo/src/windows/macros.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Take a look at the license at the top of the repository in the LICENSE file. - -/// Allows to cast only when needed. -#[macro_export] -macro_rules! auto_cast { - ($t:expr, $cast:ty) => {{ - #[cfg(target_pointer_width = "32")] - { - $t as $cast - } - #[cfg(not(target_pointer_width = "32"))] - { - $t - } - }}; -} diff --git a/vendor/sysinfo/src/windows/mod.rs b/vendor/sysinfo/src/windows/mod.rs index fa5d66beb..805e85269 100644 --- a/vendor/sysinfo/src/windows/mod.rs +++ b/vendor/sysinfo/src/windows/mod.rs @@ -3,8 +3,6 @@ mod component; mod cpu; mod disk; -#[macro_use] -mod macros; mod network; mod process; mod system; diff --git a/vendor/sysinfo/src/windows/process.rs b/vendor/sysinfo/src/windows/process.rs index bdc35c53e..7561c658f 100644 --- a/vendor/sysinfo/src/windows/process.rs +++ b/vendor/sysinfo/src/windows/process.rs @@ -1,5 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. +use crate::sys::system::is_proc_running; use crate::sys::utils::to_str; use crate::{DiskUsage, Gid, Pid, ProcessExt, ProcessRefreshKind, ProcessStatus, Signal, Uid}; @@ -48,8 +49,8 @@ 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_VM_READ, RTL_OSVERSIONINFOEXW, TOKEN_QUERY, TOKEN_USER, - ULARGE_INTEGER, + PROCESS_QUERY_INFORMATION, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_VM_READ, + RTL_OSVERSIONINFOEXW, TOKEN_QUERY, TOKEN_USER, ULARGE_INTEGER, }; impl fmt::Display for ProcessStatus { @@ -67,7 +68,19 @@ fn get_process_handler(pid: Pid) -> Option { } let options = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; - unsafe { HandleWrapper::new(OpenProcess(options, FALSE, pid.0 as DWORD)) } + HandleWrapper::new(unsafe { OpenProcess(options, FALSE, pid.0 as DWORD) }) + .or_else(|| { + sysinfo_debug!("OpenProcess failed, error: {:?}", unsafe { GetLastError() }); + HandleWrapper::new(unsafe { + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid.0 as DWORD) + }) + }) + .or_else(|| { + sysinfo_debug!("OpenProcess limited failed, error: {:?}", unsafe { + GetLastError() + }); + None + }) } unsafe fn get_process_user_id( @@ -266,11 +279,11 @@ unsafe fn get_h_mod(process_handler: &HandleWrapper, h_mod: &mut *mut c_void) -> ) != 0 } -unsafe fn get_exe(process_handler: &HandleWrapper, h_mod: *mut c_void) -> PathBuf { +unsafe fn get_exe(process_handler: &HandleWrapper) -> PathBuf { let mut exe_buf = [0u16; MAX_PATH + 1]; GetModuleFileNameExW( **process_handler, - h_mod as _, + std::ptr::null_mut(), exe_buf.as_mut_ptr(), MAX_PATH as DWORD + 1, ); @@ -306,7 +319,7 @@ impl Process { String::new() }; - let exe = get_exe(&process_handler, h_mod); + let exe = get_exe(&process_handler); let mut root = exe.clone(); root.pop(); let (cmd, environ, cwd) = match get_process_params(&process_handler) { @@ -316,7 +329,7 @@ impl Process { (Vec::new(), Vec::new(), PathBuf::new()) } }; - let (start_time, run_time) = get_start_and_run_time(&process_handler, now); + let (start_time, run_time) = get_start_and_run_time(*process_handler, now); let parent = if info.InheritedFromUniqueProcessId as usize != 0 { Some(Pid(info.InheritedFromUniqueProcessId as _)) } else { @@ -360,14 +373,8 @@ impl Process { refresh_kind: ProcessRefreshKind, ) -> Process { if let Some(handle) = get_process_handler(pid) { - let mut h_mod = null_mut(); - unsafe { - let exe = if get_h_mod(&handle, &mut h_mod) { - get_exe(&handle, h_mod) - } else { - PathBuf::new() - }; + let exe = get_exe(&handle); let mut root = exe.clone(); root.pop(); let (cmd, environ, cwd) = match get_process_params(&handle) { @@ -377,7 +384,7 @@ impl Process { (Vec::new(), Vec::new(), PathBuf::new()) } }; - let (start_time, run_time) = get_start_and_run_time(&handle, now); + let (start_time, run_time) = get_start_and_run_time(*handle, now); let user_id = get_process_user_id(&handle, refresh_kind); Process { handle: Some(Arc::new(handle)), @@ -451,6 +458,10 @@ impl Process { pub(crate) fn get_handle(&self) -> Option { self.handle.as_ref().map(|h| ***h) } + + pub(crate) fn get_start_time(&self) -> Option { + self.handle.as_ref().map(|handle| get_start_time(***handle)) + } } impl ProcessExt for Process { @@ -537,25 +548,60 @@ impl ProcessExt for Process { fn group_id(&self) -> Option { None } + + fn wait(&self) { + if let Some(handle) = self.get_handle() { + while is_proc_running(handle) { + if get_start_time(handle) != self.start_time() { + // PID owner changed so the previous process was finished! + return; + } + std::thread::sleep(std::time::Duration::from_millis(10)); + } + } else { + // In this case, we can't do anything so we just return. + sysinfo_debug!("can't wait on this process so returning"); + } + } } -unsafe fn get_start_and_run_time(handle: &HandleWrapper, now: u64) -> (u64, u64) { +#[inline] +unsafe fn get_process_times(handle: HANDLE) -> u64 { let mut fstart: FILETIME = zeroed(); let mut x = zeroed(); GetProcessTimes( - **handle, + handle, &mut fstart as *mut FILETIME, &mut x as *mut FILETIME, &mut x as *mut FILETIME, &mut x as *mut FILETIME, ); - let tmp = super::utils::filetime_to_u64(fstart); + super::utils::filetime_to_u64(fstart) +} + +#[inline] +fn compute_start(process_times: u64) -> u64 { // 11_644_473_600 is the number of seconds between the Windows epoch (1601-01-01) and // the linux epoch (1970-01-01). - let start = tmp / 10_000_000 - 11_644_473_600; - let run_time = check_sub(now, start); - (start, run_time) + process_times / 10_000_000 - 11_644_473_600 +} + +fn get_start_and_run_time(handle: HANDLE, now: u64) -> (u64, u64) { + unsafe { + let process_times = get_process_times(handle); + let start = compute_start(process_times); + let run_time = check_sub(now, start); + (start, run_time) + } +} + +#[inline] +pub(crate) fn get_start_time(handle: HANDLE) -> u64 { + unsafe { + let process_times = get_process_times(handle); + compute_start(process_times) + } } #[allow(clippy::uninit_vec)] @@ -976,7 +1022,7 @@ pub(crate) fn compute_cpu_usage(p: &mut Process, nb_cpus: u64) { } p.cpu_usage = 100.0 - * (delta_user_time.saturating_add(delta_sys_time) as f32 / denominator as f32) + * (delta_user_time.saturating_add(delta_sys_time) as f32 / denominator) * nb_cpus as f32; } } @@ -1011,8 +1057,8 @@ pub(crate) fn update_memory(p: &mut Process) { size_of::() as DWORD, ) != 0 { - p.memory = (pmc.WorkingSetSize as u64) / 1_000; - p.virtual_memory = (pmc.PrivateUsage as u64) / 1_000; + p.memory = pmc.WorkingSetSize as _; + p.virtual_memory = pmc.PrivateUsage as _; } } } diff --git a/vendor/sysinfo/src/windows/system.rs b/vendor/sysinfo/src/windows/system.rs index 6abd30db5..643a7b4bc 100644 --- a/vendor/sysinfo/src/windows/system.rs +++ b/vendor/sysinfo/src/windows/system.rs @@ -9,7 +9,7 @@ use winapi::um::winreg::HKEY_LOCAL_MACHINE; use crate::sys::component::{self, Component}; use crate::sys::cpu::*; use crate::sys::disk::{get_disks, Disk}; -use crate::sys::process::{update_memory, Process}; +use crate::sys::process::{get_start_time, update_memory, Process}; use crate::sys::tools::*; use crate::sys::users::get_users; use crate::sys::utils::get_now; @@ -64,6 +64,19 @@ pub struct System { users: Vec, } +static WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000; + +impl System { + fn is_windows_eleven(&self) -> bool { + WINDOWS_ELEVEN_BUILD_NUMBER + <= self + .kernel_version() + .unwrap_or_default() + .parse() + .unwrap_or(0) + } +} + // Useful for parallel iterations. struct Wrap(T); @@ -73,7 +86,7 @@ unsafe impl Sync for Wrap {} unsafe fn boot_time() -> u64 { match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { - Ok(n) => n.as_secs().saturating_sub(GetTickCount64()) / 1000, + Ok(n) => n.as_secs().saturating_sub(GetTickCount64() / 1_000), Err(_e) => { sysinfo_debug!("Failed to compute boot time: {:?}", _e); 0 @@ -117,10 +130,10 @@ impl SystemExt for System { ); for (pos, proc_) in self.cpus.iter_mut(refresh_kind).enumerate() { add_english_counter( - format!(r"\Processor({})\% Processor Time", pos), + format!(r"\Processor({pos})\% Processor Time"), query, get_key_used(proc_), - format!("{}_0", pos), + format!("{pos}_0"), ); } } @@ -162,8 +175,8 @@ impl SystemExt for System { let mut mem_info: MEMORYSTATUSEX = zeroed(); mem_info.dwLength = size_of::() as u32; GlobalMemoryStatusEx(&mut mem_info); - self.mem_total = auto_cast!(mem_info.ullTotalPhys, u64) / 1_000; - self.mem_available = auto_cast!(mem_info.ullAvailPhys, u64) / 1_000; + 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 @@ -178,8 +191,8 @@ impl SystemExt for System { .CommitTotal .saturating_sub(perf_info.PhysicalTotal), ); - self.swap_total = (swap_total / 1000) as u64; - self.swap_used = (swap_used / 1000) as u64; + self.swap_total = swap_total as _; + self.swap_used = swap_used as _; } } } @@ -190,12 +203,17 @@ impl SystemExt for System { #[allow(clippy::map_entry)] fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool { - if self.process_list.contains_key(&pid) { - return refresh_existing_process(self, pid, refresh_kind); - } let now = get_now(); + let nb_cpus = self.cpus.len() as u64; + + if let Some(proc_) = self.process_list.get_mut(&pid) { + if let Some(ret) = refresh_existing_process(proc_, nb_cpus, now, refresh_kind) { + return ret; + } + // We need to re-make the process because the PID owner changed. + } if let Some(mut p) = Process::new_from_pid(pid, now, refresh_kind) { - p.update(refresh_kind, self.cpus.len() as u64, now); + p.update(refresh_kind, nb_cpus, now); p.updated = false; self.process_list.insert(pid, p); true @@ -266,10 +284,18 @@ impl SystemExt for System { let pi = *pi.0; let pid = Pid(pi.UniqueProcessId as _); if let Some(proc_) = (*process_list.0.get()).get_mut(&pid) { - proc_.memory = (pi.WorkingSetSize as u64) / 1_000; - proc_.virtual_memory = (pi.VirtualSize as u64) / 1_000; - proc_.update(refresh_kind, nb_cpus, now); - return None; + if proc_ + .get_start_time() + .map(|start| start == proc_.start_time()) + .unwrap_or(true) + { + proc_.memory = pi.WorkingSetSize as _; + proc_.virtual_memory = pi.VirtualSize as _; + proc_.update(refresh_kind, nb_cpus, now); + return None; + } + // If the PID owner changed, we need to recompute the whole process. + sysinfo_debug!("owner changed for PID {}", proc_.pid()); } let name = get_process_name(&pi, pid); let mut p = Process::new_full( @@ -279,8 +305,8 @@ impl SystemExt for System { } else { None }, - (pi.WorkingSetSize as u64) / 1_000, - (pi.VirtualSize as u64) / 1_000, + pi.WorkingSetSize as _, + pi.VirtualSize as _, name, now, refresh_kind, @@ -386,6 +412,13 @@ impl SystemExt for System { &mut self.disks } + fn sort_disks_by(&mut self, compare: F) + where + F: FnMut(&Disk, &Disk) -> std::cmp::Ordering, + { + self.disks.sort_unstable_by(compare); + } + fn users(&self) -> &[User] { &self.users } @@ -399,7 +432,7 @@ impl SystemExt for System { } fn uptime(&self) -> u64 { - unsafe { GetTickCount64() / 1000 } + unsafe { GetTickCount64() / 1_000 } } fn boot_time(&self) -> u64 { @@ -415,6 +448,14 @@ impl SystemExt for System { } fn long_os_version(&self) -> Option { + if self.is_windows_eleven() { + return get_reg_string_value( + HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", + "ProductName", + ) + .map(|product_name| product_name.replace("Windows 10 ", "Windows 11 ")); + } get_reg_string_value( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", @@ -435,23 +476,29 @@ impl SystemExt for System { } fn os_version(&self) -> Option { - let major = get_reg_value_u32( - HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", - "CurrentMajorVersionNumber", - ); - let build_number = get_reg_string_value( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuildNumber", - ); + ) + .unwrap_or_default(); + let major = if self.is_windows_eleven() { + 11u32 + } else { + u32::from_le_bytes( + get_reg_value_u32( + HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", + "CurrentMajorVersionNumber", + ) + .unwrap_or_default(), + ) + }; + Some(format!("{major} ({build_number})")) + } - Some(format!( - "{} ({})", - u32::from_le_bytes(major.unwrap_or_default()), - build_number.unwrap_or_default() - )) + fn distribution_id(&self) -> String { + std::env::consts::OS.to_owned() } } @@ -461,7 +508,7 @@ impl Default for System { } } -fn is_proc_running(handle: HANDLE) -> bool { +pub(crate) fn is_proc_running(handle: HANDLE) -> bool { let mut exit_code = 0; unsafe { let ret = GetExitCodeProcess(handle, &mut exit_code); @@ -469,22 +516,30 @@ fn is_proc_running(handle: HANDLE) -> bool { } } -fn refresh_existing_process(s: &mut System, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool { - if let Some(ref mut entry) = s.process_list.get_mut(&pid) { - if let Some(handle) = entry.get_handle() { - if !is_proc_running(handle) { - return false; - } - } else { - return false; +/// If it returns `None`, it means that the PID owner changed and that the `Process` must be +/// completely recomputed. +fn refresh_existing_process( + proc_: &mut Process, + nb_cpus: u64, + now: u64, + refresh_kind: ProcessRefreshKind, +) -> Option { + if let Some(handle) = proc_.get_handle() { + if get_start_time(handle) != proc_.start_time() { + sysinfo_debug!("owner changed for PID {}", proc_.pid()); + // PID owner changed! + return None; + } + if !is_proc_running(handle) { + return Some(false); } - update_memory(entry); - entry.update(refresh_kind, s.cpus.len() as u64, get_now()); - entry.updated = false; - true } else { - false + return Some(false); } + update_memory(proc_); + proc_.update(refresh_kind, nb_cpus, now); + proc_.updated = false; + Some(true) } #[allow(clippy::size_of_in_element_count)] @@ -495,7 +550,7 @@ pub(crate) fn get_process_name(process: &SYSTEM_PROCESS_INFORMATION, process_id: match process_id.0 { 0 => "Idle".to_owned(), 4 => "System".to_owned(), - _ => format!(" Process {}", process_id), + _ => format!(" Process {process_id}"), } } else { unsafe { -- cgit v1.2.3