From 43ade3858cf6d8b17c5ae5a29341250f575261fe Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Mon, 6 Mar 2023 18:23:53 +0100 Subject: [PATCH] `winapi` is in maintenance mode and the new blessed way to access Windows APIs are the `windows` and `windows-sys` crates. I don't think any types of `winapi` were exposed in the public API so I used `windows-sys` since it has much faster compile times. --- os_info/Cargo.toml | 10 +++++- os_info/src/windows/winapi.rs | 68 ++++++++++++++++------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/os_info/Cargo.toml b/os_info/Cargo.toml index 9907ca0a..bcf4b181 100644 --- a/os_info/Cargo.toml +++ b/os_info/Cargo.toml @@ -21,7 +21,15 @@ log = "0.4.5" serde = { version = "1", features = ["derive"], optional = true } [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.8", features = ["minwindef", "ntdef", "ntstatus", "sysinfoapi", "winnt", "winuser", "libloaderapi", "processthreadsapi", "winerror", "winreg"] } +windows-sys = { version = "0.45", features = [ + "Win32_Foundation", + "Win32_System_Diagnostics_Debug", + "Win32_System_LibraryLoader", + "Win32_System_SystemInformation", + "Win32_UI_WindowsAndMessaging", + "Win32_System_Registry", + "Win32_System_SystemServices", +]} [dev-dependencies] pretty_assertions = "1" diff --git a/os_info/src/windows/winapi.rs b/os_info/src/windows/winapi.rs index dea5ba25..91acb810 100644 --- a/os_info/src/windows/winapi.rs +++ b/os_info/src/windows/winapi.rs @@ -12,32 +12,25 @@ use std::{ ptr, }; -use winapi::{ - shared::{ - minwindef::{DWORD, FARPROC, LPBYTE}, - ntdef::{LPCSTR, NTSTATUS}, - ntstatus::STATUS_SUCCESS, - winerror::ERROR_SUCCESS, - }, - um::{ - libloaderapi::{GetModuleHandleA, GetProcAddress}, - sysinfoapi::{GetSystemInfo, SYSTEM_INFO}, - winnt::{ - KEY_READ, PROCESSOR_ARCHITECTURE_AMD64, REG_SZ, VER_NT_WORKSTATION, - VER_SUITE_WH_SERVER, WCHAR, - }, - winreg::{RegOpenKeyExW, RegQueryValueExW, HKEY_LOCAL_MACHINE, LSTATUS}, - winuser::{GetSystemMetrics, SM_SERVERR2}, +use windows_sys::Win32::{ + Foundation::{ERROR_SUCCESS, FARPROC, NTSTATUS, STATUS_SUCCESS}, + System::{ + Diagnostics::Debug::PROCESSOR_ARCHITECTURE_AMD64, + LibraryLoader::{GetModuleHandleA, GetProcAddress}, + Registry::{RegOpenKeyExW, RegQueryValueExW, HKEY_LOCAL_MACHINE, KEY_READ, REG_SZ}, + SystemInformation::{GetSystemInfo, SYSTEM_INFO}, + SystemServices::{VER_NT_WORKSTATION, VER_SUITE_WH_SERVER}, }, + UI::WindowsAndMessaging::{GetSystemMetrics, SM_SERVERR2}, }; use crate::{Bitness, Info, Type, Version}; #[cfg(target_arch = "x86")] -type OSVERSIONINFOEX = winapi::um::winnt::OSVERSIONINFOEXA; +type OSVERSIONINFOEX = windows_sys::Win32::System::SystemInformation::OSVERSIONINFOEXA; #[cfg(not(target_arch = "x86"))] -type OSVERSIONINFOEX = winapi::um::winnt::OSVERSIONINFOEXW; +type OSVERSIONINFOEX = windows_sys::Win32::System::SystemInformation::OSVERSIONINFOEXW; pub fn get() -> Info { let (version, edition) = version(); @@ -116,7 +109,7 @@ fn version_info() -> Option { let rtl_get_version: RtlGetVersion = unsafe { mem::transmute(rtl_get_version) }; let mut info: OSVERSIONINFOEX = unsafe { mem::zeroed() }; - info.dwOSVersionInfoSize = mem::size_of::() as DWORD; + info.dwOSVersionInfoSize = mem::size_of::() as u32; if unsafe { rtl_get_version(&mut info) } == STATUS_SUCCESS { Some(info) @@ -126,13 +119,11 @@ fn version_info() -> Option { } fn product_name(info: &OSVERSIONINFOEX) -> Option { - const REG_SUCCESS: LSTATUS = ERROR_SUCCESS as LSTATUS; - let sub_key = to_wide("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"); - let mut key = ptr::null_mut(); + let mut key = Default::default(); if unsafe { RegOpenKeyExW(HKEY_LOCAL_MACHINE, sub_key.as_ptr(), 0, KEY_READ, &mut key) } - != REG_SUCCESS - || key.is_null() + != ERROR_SUCCESS + || key == 0 { log::error!("RegOpenKeyExW(HKEY_LOCAL_MACHINE, ...) failed"); return None; @@ -146,8 +137,8 @@ fn product_name(info: &OSVERSIONINFOEX) -> Option { } else { "ProductName" }); - let mut data_type: DWORD = 0; - let mut data_size: DWORD = 0; + let mut data_type = 0; + let mut data_size = 0; if unsafe { RegQueryValueExW( key, @@ -157,7 +148,7 @@ fn product_name(info: &OSVERSIONINFOEX) -> Option { ptr::null_mut(), &mut data_size, ) - } != REG_SUCCESS + } != ERROR_SUCCESS || data_type != REG_SZ || data_size == 0 || data_size % 2 != 0 @@ -174,10 +165,10 @@ fn product_name(info: &OSVERSIONINFOEX) -> Option { name.as_ptr(), ptr::null_mut(), ptr::null_mut(), - data.as_mut_ptr() as LPBYTE, + data.as_mut_ptr().cast(), &mut data_size, ) - } != REG_SUCCESS + } != ERROR_SUCCESS || data_size as usize != data.len() * 2 { return None; @@ -203,7 +194,7 @@ fn product_name(info: &OSVERSIONINFOEX) -> Option { } } -fn to_wide(value: &str) -> Vec { +fn to_wide(value: &str) -> Vec { OsStr::new(value).encode_wide().chain(Some(0)).collect() } @@ -213,7 +204,7 @@ fn edition(version_info: &OSVERSIONINFOEX) -> Option { match ( version_info.dwMajorVersion, version_info.dwMinorVersion, - version_info.wProductType, + version_info.wProductType as u32, ) { // Windows 10. (10, 0, VER_NT_WORKSTATION) => { @@ -240,12 +231,13 @@ fn edition(version_info: &OSVERSIONINFOEX) -> Option { let mut info: SYSTEM_INFO = unsafe { mem::zeroed() }; unsafe { GetSystemInfo(&mut info) }; - if Into::::into(version_info.wSuiteMask) & VER_SUITE_WH_SERVER + if Into::::into(version_info.wSuiteMask) & VER_SUITE_WH_SERVER == VER_SUITE_WH_SERVER { Some("Windows Home Server") - } else if version_info.wProductType == VER_NT_WORKSTATION - && unsafe { info.u.s().wProcessorArchitecture } == PROCESSOR_ARCHITECTURE_AMD64 + } else if version_info.wProductType == VER_NT_WORKSTATION as u8 + && unsafe { info.Anonymous.Anonymous.wProcessorArchitecture } + == PROCESSOR_ARCHITECTURE_AMD64 { Some("Windows XP Professional x64 Edition") } else { @@ -267,8 +259,8 @@ fn get_proc_address(module: &[u8], proc: &[u8]) -> Option { "Procedure name should be zero-terminated" ); - let handle = unsafe { GetModuleHandleA(module.as_ptr() as LPCSTR) }; - if handle.is_null() { + let handle = unsafe { GetModuleHandleA(module.as_ptr()) }; + if handle == 0 { log::error!( "GetModuleHandleA({}) failed", String::from_utf8_lossy(module) @@ -276,7 +268,7 @@ fn get_proc_address(module: &[u8], proc: &[u8]) -> Option { return None; } - unsafe { Some(GetProcAddress(handle, proc.as_ptr() as LPCSTR)) } + unsafe { Some(GetProcAddress(handle, proc.as_ptr())) } } #[cfg(test)] @@ -321,7 +313,7 @@ mod tests { for &(major, minor, product_type, expected_edition) in &test_data { info.dwMajorVersion = major; info.dwMinorVersion = minor; - info.wProductType = product_type; + info.wProductType = product_type as u8; let edition = edition(&info).unwrap(); assert_eq!(edition, expected_edition);