diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-10-21 19:09:11 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-10-22 14:47:32 +0200 |
| commit | 5b047ea38aff6cf72a4eaba87e87314171241050 (patch) | |
| tree | 2dbdf6074bc22fbb513bb7b2b387096f01d0e2ee | |
| parent | 9308a3f92943565d5ebb9651b2af709cbd8b39fc (diff) | |
| download | mullvadvpn-5b047ea38aff6cf72a4eaba87e87314171241050.tar.xz mullvadvpn-5b047ea38aff6cf72a4eaba87e87314171241050.zip | |
Add Windows version check function
| -rw-r--r-- | talpid-core/src/dns/windows/mod.rs | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/talpid-core/src/dns/windows/mod.rs b/talpid-core/src/dns/windows/mod.rs index 646458aca1..dbebcfc3e9 100644 --- a/talpid-core/src/dns/windows/mod.rs +++ b/talpid-core/src/dns/windows/mod.rs @@ -1,9 +1,13 @@ use crate::logging::windows::{log_sink, LogSink}; use log::{error, trace, warn}; -use std::{io, net::IpAddr, path::Path}; +use std::{io, mem, net::IpAddr, path::Path, ptr}; use talpid_types::ErrorExt; use widestring::WideCString; +use winapi::um::{ + libloaderapi::{GetModuleHandleA, GetProcAddress}, + winnt::RTL_OSVERSIONINFOW, +}; use winreg::{ enums::{HKEY_LOCAL_MACHINE, REG_MULTI_SZ}, transaction::Transaction, @@ -186,6 +190,42 @@ fn reset_dns_cache_policy() -> Result<(), Error> { } } +fn is_minimum_windows10() -> bool { + match is_minimum_windows10_inner() { + Ok(result) => result, + Err(error) => { + error!( + "{}", + error.display_chain_with_msg("OS version check failed") + ); + false + } + } +} + +fn is_minimum_windows10_inner() -> Result<bool, io::Error> { + let rtl_get_version: extern "stdcall" fn(*mut RTL_OSVERSIONINFOW); + + let ntdll = unsafe { GetModuleHandleA(b"ntdll\0" as *const _ as *const i8) }; + if ntdll == ptr::null_mut() { + return Err(io::Error::last_os_error()); + } + + let function_address = + unsafe { GetProcAddress(ntdll, b"RtlGetVersion\0" as *const _ as *const i8) }; + if function_address == ptr::null_mut() { + return Err(io::Error::last_os_error()); + } + + rtl_get_version = unsafe { mem::transmute(function_address) }; + + let mut version_info: RTL_OSVERSIONINFOW = unsafe { std::mem::zeroed() }; + version_info.dwOSVersionInfoSize = mem::size_of_val(&version_info) as u32; + rtl_get_version(&mut version_info); + + Ok(version_info.dwMajorVersion >= 10) +} + ffi_error!(InitializationResult, Error::Initialization); ffi_error!(DeinitializationResult, Error::Deinitialization); |
