|
@@ -208,81 +208,16 @@ pub use windows_platform::{is_windows_7, windows_version};
|
|
|
|
|
|
#[cfg(windows)]
|
|
|
mod windows_platform {
|
|
|
- use std::{iter::once, os::windows::prelude::OsStrExt};
|
|
|
- use windows::{
|
|
|
- core::{PCSTR, PCWSTR},
|
|
|
- Win32::{
|
|
|
- Foundation::FARPROC,
|
|
|
- System::{
|
|
|
- LibraryLoader::{GetProcAddress, LoadLibraryW},
|
|
|
- SystemInformation::OSVERSIONINFOW,
|
|
|
- },
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
/// Checks if we're running on Windows 7.
|
|
|
pub fn is_windows_7() -> bool {
|
|
|
- if let Some(v) = windows_version() {
|
|
|
- // windows 7 is 6.1
|
|
|
- if v.0 == 6 && v.1 == 1 {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- false
|
|
|
- }
|
|
|
-
|
|
|
- fn encode_wide(string: impl AsRef<std::ffi::OsStr>) -> Vec<u16> {
|
|
|
- string.as_ref().encode_wide().chain(once(0)).collect()
|
|
|
- }
|
|
|
-
|
|
|
- // Helper function to dynamically load function pointer.
|
|
|
- // `library` and `function` must be zero-terminated.
|
|
|
- fn get_function_impl(library: &str, function: &str) -> Option<FARPROC> {
|
|
|
- let library = encode_wide(library);
|
|
|
- assert_eq!(function.chars().last(), Some('\0'));
|
|
|
- let function = PCSTR::from_raw(function.as_ptr());
|
|
|
-
|
|
|
- // Library names we will use are ASCII so we can use the A version to avoid string conversion.
|
|
|
- let module = unsafe { LoadLibraryW(PCWSTR::from_raw(library.as_ptr())) }.unwrap_or_default();
|
|
|
- if module.is_invalid() {
|
|
|
- None
|
|
|
- } else {
|
|
|
- Some(unsafe { GetProcAddress(module, function) })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- macro_rules! get_function {
|
|
|
- ($lib:expr, $func:ident) => {
|
|
|
- get_function_impl(concat!($lib, '\0'), concat!(stringify!($func), '\0'))
|
|
|
- .map(|f| unsafe { std::mem::transmute::<windows::Win32::Foundation::FARPROC, $func>(f) })
|
|
|
- };
|
|
|
+ windows_version()
|
|
|
+ .map(|v| v.0 == 6 && v.1 == 1)
|
|
|
+ .unwrap_or_default()
|
|
|
}
|
|
|
|
|
|
/// Returns a tuple of (major, minor, buildnumber) for the Windows version.
|
|
|
pub fn windows_version() -> Option<(u32, u32, u32)> {
|
|
|
- type RtlGetVersion = unsafe extern "system" fn(*mut OSVERSIONINFOW) -> i32;
|
|
|
- let handle = get_function!("ntdll.dll", RtlGetVersion);
|
|
|
- if let Some(rtl_get_version) = handle {
|
|
|
- unsafe {
|
|
|
- let mut vi = OSVERSIONINFOW {
|
|
|
- dwOSVersionInfoSize: 0,
|
|
|
- dwMajorVersion: 0,
|
|
|
- dwMinorVersion: 0,
|
|
|
- dwBuildNumber: 0,
|
|
|
- dwPlatformId: 0,
|
|
|
- szCSDVersion: [0; 128],
|
|
|
- };
|
|
|
-
|
|
|
- let status = (rtl_get_version)(&mut vi as _);
|
|
|
-
|
|
|
- if status >= 0 {
|
|
|
- Some((vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber))
|
|
|
- } else {
|
|
|
- None
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- None
|
|
|
- }
|
|
|
+ let v = windows_version::OsVersion::current();
|
|
|
+ Some((v.major, v.minor, v.build))
|
|
|
}
|
|
|
}
|