diff --git a/os_info/Cargo.toml b/os_info/Cargo.toml index 3fbfeada..353a4d72 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..e2de40d7 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(); @@ -72,13 +65,8 @@ fn bitness() -> Bitness { #[cfg(target_pointer_width = "32")] fn bitness() -> Bitness { - use winapi::{ - shared::{ - minwindef::{BOOL, FALSE, PBOOL}, - ntdef::HANDLE, - }, - um::processthreadsapi::GetCurrentProcess, - }; + use windows_sys::Win32::Foundation::{BOOL, FALSE, HANDLE}; + use windows_sys::Win32::System::Threading::GetCurrentProcess; // IsWow64Process is not available on all supported versions of Windows. Use GetModuleHandle to // get a handle to the DLL that contains the function and GetProcAddress to get a pointer to the @@ -88,7 +76,7 @@ fn bitness() -> Bitness { Some(val) => val, }; - type IsWow64 = unsafe extern "system" fn(HANDLE, PBOOL) -> BOOL; + type IsWow64 = unsafe extern "system" fn(HANDLE, *mut BOOL) -> BOOL; let is_wow_64: IsWow64 = unsafe { mem::transmute(is_wow_64) }; let mut result = FALSE; @@ -116,7 +104,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 +114,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 +132,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 +143,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 +160,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 +189,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 +199,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 +226,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 +254,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 +263,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 +308,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);