Replace winapi with windows-sys

winapi didn't have any update for 6 years
This commit is contained in:
Sylvestre Ledru
2026-03-30 19:14:24 +02:00
parent f9f31f89d7
commit 034e3978a9
5 changed files with 161 additions and 54 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ jobs:
echo "PWD='${PWD}'"
# tooling info display
echo "## tooling"
(gcc --version | head -1) || :
command -v gcc >/dev/null 2>&1 && (gcc --version | head -1) || true
rustup -V 2>/dev/null
rustup show active-toolchain
cargo -V
Generated
+63 -12
View File
@@ -29,7 +29,7 @@ version = "2.1.0"
dependencies = [
"libc",
"regex",
"winapi",
"windows-sys",
]
[[package]]
@@ -62,23 +62,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "winapi"
version = "0.3.9"
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
"windows-targets",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+9 -2
View File
@@ -13,13 +13,20 @@ keywords = ["platform", "info", "system"]
categories = ["os"]
license = "MIT"
# spell-checker:ignore (crates) libc winapi (features) libloaderapi processthreadsapi sysinfoapi winbase winver
# spell-checker:ignore (crates) libc (features) libloaderapi processthreadsapi sysinfoapi winbase winver
[target.'cfg(not(target_os = "windows"))'.dependencies]
libc = "0.2.154"
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.9", features = ["libloaderapi", "processthreadsapi", "sysinfoapi", "winbase", "winver"] }
windows-sys = { version = "0.59", features = [
"Win32_Foundation",
"Win32_Storage_FileSystem",
"Win32_System_LibraryLoader",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
] }
[dev-dependencies]
regex = "1.10.4"
+37 -9
View File
@@ -37,9 +37,36 @@ use std::fmt::{Debug, Formatter};
use std::io;
use std::os::windows::ffi::OsStringExt;
use winapi::shared::minwindef::*;
use winapi::um::sysinfoapi::*;
use winapi::um::winnt::*;
use windows_sys::Win32::Foundation::FALSE;
use windows_sys::Win32::System::SystemInformation::{
ComputerNamePhysicalDnsHostname, PROCESSOR_ARCHITECTURE_ALPHA, PROCESSOR_ARCHITECTURE_ALPHA64,
PROCESSOR_ARCHITECTURE_AMD64, PROCESSOR_ARCHITECTURE_ARM, PROCESSOR_ARCHITECTURE_ARM64,
PROCESSOR_ARCHITECTURE_IA64, PROCESSOR_ARCHITECTURE_INTEL, PROCESSOR_ARCHITECTURE_MIPS,
PROCESSOR_ARCHITECTURE_PPC, PROCESSOR_ARCHITECTURE_SHX, SYSTEM_INFO, VER_PRODUCT_TYPE,
VER_SUITENAME,
};
// Windows type aliases not exported by windows-sys
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub(crate) type BYTE = u8;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub(crate) type WORD = u16;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub(crate) type DWORD = u32;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub(crate) type UINT = u32;
// VER_* constants defined locally with types matching their usage context.
// windows-sys exports these as u32, but wProductType is u8 and VerSetConditionMask condition is u8.
const VER_EQUAL: BYTE = 1;
const VER_NT_WORKSTATION: BYTE = 1;
const VER_SUITE_WH_SERVER: DWORD = 32768;
#[cfg(test)]
const VER_NT_SERVER: BYTE = 3;
#[cfg(test)]
const VER_SUITE_PERSONAL: DWORD = 0x00000200;
#[cfg(test)]
const VER_SUITE_SMALLBUSINESS: DWORD = 0x00000001;
use crate::{PlatformInfoAPI, PlatformInfoError, UNameAPI};
@@ -166,8 +193,9 @@ pub mod util {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use winapi::um::winnt::*;
/// WinOS wide character (`wchar_t` / `u16`)
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
pub type WCHAR = u16;
/// WinOS wide-character string buffer
/// <br>Note: `WCHAR` (aka `TCHAR`) == `wchar_t` == `u16`
#[allow(clippy::upper_case_acronyms)]
@@ -427,10 +455,10 @@ fn mmbr_from_file_version(
) -> Result<MmbrVersion, WinOSError> {
let info = WinOsFileVersionInfoQuery_root(&file_version_info)?;
Ok(MmbrVersion {
major: DWORD::from(HIWORD(info.dwProductVersionMS)),
minor: DWORD::from(LOWORD(info.dwProductVersionMS)),
build: DWORD::from(HIWORD(info.dwProductVersionLS)),
release: DWORD::from(LOWORD(info.dwProductVersionLS)),
major: info.dwProductVersionMS >> 16,
minor: info.dwProductVersionMS & 0xffff,
build: info.dwProductVersionLS >> 16,
release: info.dwProductVersionLS & 0xffff,
})
}
+51 -30
View File
@@ -15,16 +15,34 @@ use std::io;
use std::mem::{self, MaybeUninit};
use std::ptr;
use winapi::shared::minwindef::*;
use winapi::shared::ntdef::NTSTATUS;
use winapi::shared::ntstatus::*;
use winapi::um::libloaderapi::*;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::sysinfoapi;
use winapi::um::sysinfoapi::*;
use winapi::um::winbase::*;
use winapi::um::winnt::*;
use winapi::um::winver::*;
use windows_sys::Win32::Foundation::{
FreeLibrary, BOOL, FALSE, FARPROC, HANDLE, HMODULE, NTSTATUS, STATUS_SUCCESS,
};
use windows_sys::Win32::Storage::FileSystem::{
GetFileVersionInfoSizeW, GetFileVersionInfoW, VerQueryValueW,
};
use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW};
use windows_sys::Win32::System::SystemInformation::{
GetComputerNameExW, GetNativeSystemInfo, GetSystemDirectoryW, VerSetConditionMask,
VerifyVersionInfoW, COMPUTER_NAME_FORMAT, OSVERSIONINFOEXW, SYSTEM_INFO,
};
use windows_sys::Win32::System::Threading::GetCurrentProcess;
// Re-use shared type aliases from parent module
use super::{BYTE, DWORD, UINT, WORD};
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
type WCHAR = u16;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
type LPVOID = *mut std::ffi::c_void;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
type LPCVOID = *const std::ffi::c_void;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
type ULONGLONG = u64;
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
type DWORDLONG = u64;
#[allow(non_camel_case_types)]
type RTL_OSVERSIONINFOEXW = OSVERSIONINFOEXW;
use super::util::{to_c_string, to_c_wstring, CWSTR};
use super::{WinApiFileVersionInfo, WinApiSystemInfo};
@@ -68,7 +86,7 @@ impl WinApiSystemInfo {
/// Returns `wProcessorArchitecture` extracted from the [`SYSTEM_INFO`](https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info) structure.
/// <br> Refer to [`SYSTEM_INFO`](https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info) for more information.
pub fn wProcessorArchitecture(&self) -> WORD {
unsafe { self.0.u.s().wProcessorArchitecture }
unsafe { self.0.Anonymous.Anonymous.wProcessorArchitecture }
}
}
@@ -253,7 +271,7 @@ pub fn WinAPI_GetProcAddress<P: AsRef<PathStr>>(
// pub unsafe fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> FARPROC
// ref: <https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress> @@ <https://archive.is/ZPVMr>
let symbol_name_cs = to_c_string(symbol_name.as_ref());
unsafe { GetProcAddress(module, symbol_name_cs.as_ptr()) }
unsafe { GetProcAddress(module, symbol_name_cs.as_ptr().cast()) }
}
// WinAPI_GetSystemDirectoryW
@@ -412,7 +430,7 @@ pub fn WinAPI_VerSetConditionMask(
// type_mask ~ mask indicating the member of version info whose comparison operator is being set
// condition ~ comparison type
// * returns ULONGLONG ~ updated condition_mask
unsafe { sysinfoapi::VerSetConditionMask(condition_mask, type_mask, condition) }
unsafe { VerSetConditionMask(condition_mask, type_mask, condition) }
}
// WinOsFileVersionInfoQuery_root
@@ -474,16 +492,17 @@ pub fn KERNEL32_IsWow64Process(process: HANDLE) -> Result<bool, WinOSError> {
let module_path = super::WinOsGetSystemDirectory()?.join(module_file);
// let func = super::WinOsGetModuleProcAddress(module_path, procedure); // loads module "permanently" (for the life of current process)
let module = WinAPI_LoadLibrary(module_path);
let func = WinAPI_GetProcAddress(module, symbol_name);
if func.is_null() {
return Err(Box::from(format!(
"Unable to find DLL procedure '{}' within '{}'",
symbol_name, module_file
)));
}
let func = match WinAPI_GetProcAddress(module, symbol_name) {
Some(f) => f,
None => {
return Err(Box::from(format!(
"Unable to find DLL procedure '{}' within '{}'",
symbol_name, module_file
)));
}
};
let func: extern "system" fn(HANDLE, *mut BOOL) -> BOOL =
unsafe { mem::transmute(func as *const ()) };
let func: extern "system" fn(HANDLE, *mut BOOL) -> BOOL = unsafe { mem::transmute(func) };
let mut is_wow64: BOOL = FALSE;
let result: BOOL = func(process, &mut is_wow64);
@@ -509,15 +528,17 @@ pub fn NTDLL_RtlGetVersion() -> Result<OSVERSIONINFOEXW, WinOSError> {
let module_path = super::WinOsGetSystemDirectory()?.join(module_file);
// let func = super::WinOsGetModuleProcAddress(module_path, procedure); // loads module "permanently" (for the life of current process)
let module = WinAPI_LoadLibrary(module_path);
let func = WinAPI_GetProcAddress(module, symbol_name);
if func.is_null() {
return Err(Box::from(format!(
"Unable to find DLL procedure '{}' within '{}'",
symbol_name, module_file
)));
}
let func = match WinAPI_GetProcAddress(module, symbol_name) {
Some(f) => f,
None => {
return Err(Box::from(format!(
"Unable to find DLL procedure '{}' within '{}'",
symbol_name, module_file
)));
}
};
let func: extern "system" fn(*mut RTL_OSVERSIONINFOEXW) -> NTSTATUS =
unsafe { mem::transmute(func as *const ()) };
unsafe { mem::transmute(func) };
let mut os_version_info = match create_OSVERSIONINFOEXW() {
Ok(value) => value,