summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls Piņķis <emils@mullvad.net>2021-01-28 21:42:16 +0000
committerEmīls Piņķis <emils@mullvad.net>2021-01-29 14:22:01 +0000
commit067f9bc6c599d774a5807a940ca896f9c5866912 (patch)
tree2e062f270a30a880c7a1702e8310c86a49f6a7e1
parent77e2bd23662edbc5cff2c4c747fe75e80c726299 (diff)
downloadmullvadvpn-067f9bc6c599d774a5807a940ca896f9c5866912.tar.xz
mullvadvpn-067f9bc6c599d774a5807a940ca896f9c5866912.zip
Change version info on Windows
-rw-r--r--Cargo.lock2
-rw-r--r--talpid-platform-metadata/Cargo.toml3
-rw-r--r--talpid-platform-metadata/src/lib.rs3
-rw-r--r--talpid-platform-metadata/src/windows.rs122
4 files changed, 91 insertions, 39 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5745394850..a15f06b68e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2609,6 +2609,8 @@ version = "0.1.0"
dependencies = [
"rs-release",
"talpid-dbus",
+ "utf16_lit",
+ "winapi 0.3.9",
]
[[package]]
diff --git a/talpid-platform-metadata/Cargo.toml b/talpid-platform-metadata/Cargo.toml
index d922adf865..d75ae1c3f1 100644
--- a/talpid-platform-metadata/Cargo.toml
+++ b/talpid-platform-metadata/Cargo.toml
@@ -11,3 +11,6 @@ publish = false
[target.'cfg(target_os = "linux")'.dependencies]
rs-release = "0.1.7"
talpid-dbus = { path = "../talpid-dbus" }
+
+[target.'cfg(target_os = "windows")'.dependencies]
+winapi = { version = "0.3.6", features = ["winbase"] }
diff --git a/talpid-platform-metadata/src/lib.rs b/talpid-platform-metadata/src/lib.rs
index f4ba78eaeb..5fd43e62d4 100644
--- a/talpid-platform-metadata/src/lib.rs
+++ b/talpid-platform-metadata/src/lib.rs
@@ -15,3 +15,6 @@ mod imp;
mod imp;
pub use self::imp::{extra_metadata, short_version, version};
+
+#[cfg(target_os = "windows")]
+pub use self::imp::WindowsVersion;
diff --git a/talpid-platform-metadata/src/windows.rs b/talpid-platform-metadata/src/windows.rs
index 41faf0099b..0222f63221 100644
--- a/talpid-platform-metadata/src/windows.rs
+++ b/talpid-platform-metadata/src/windows.rs
@@ -1,54 +1,98 @@
-use std::collections::HashMap;
-
-mod command;
-use command::command_stdout_lossy;
+use std::{
+ ffi::OsString,
+ io, iter,
+ mem::{self, MaybeUninit},
+ os::windows::ffi::OsStrExt,
+ ptr,
+};
+use winapi::um::{
+ libloaderapi::{GetModuleHandleW, GetProcAddress},
+ winnt::RTL_OSVERSIONINFOW,
+};
pub fn version() -> String {
- let system_info = system_info();
- let os_name = system_info.get("OS Name");
- let os_version = system_info.get("OS Version");
- let version = os_name.map(parse_version).unwrap_or(String::from("N/A"));
- let full_version = os_version
- .map(parse_full_version)
- .unwrap_or(String::from("N/A"));
- format!("Windows {} ({})", version, full_version)
+ let (major, minor, build) = WindowsVersion::new()
+ .map(|version_info| {
+ (
+ version_info.major_version().to_string(),
+ version_info.minor_version().to_string(),
+ version_info.build_number().to_string(),
+ )
+ })
+ .unwrap_or_else(|_| ("N/A".to_string(), "N/A".to_string(), "N/A".to_string()));
+
+ format!("Windows {}.{} Build {}", major, minor, build)
}
pub fn short_version() -> String {
- let system_info = system_info();
- let os_name = system_info.get("OS Name");
- let version = os_name.map(parse_version).unwrap_or(String::from("N/A"));
- format!("Windows {}", version)
+ let version_string = WindowsVersion::new()
+ .map(|version| version.major_version().to_string())
+ .unwrap_or("N/A".into());
+ format!("Windows {}", version_string)
}
-fn system_info() -> HashMap<String, String> {
- let system_info =
- command_stdout_lossy("systeminfo", &["/FO", "LIST"]).unwrap_or_else(String::new);
+pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
+ std::iter::empty()
+}
- let mut info_map = HashMap::new();
- system_info.lines().for_each(|line| {
- let mut split = line.split(":");
- if let Some(key) = split.next() {
- if let Some(value) = split.next() {
- info_map.insert(key.to_owned(), value.to_owned());
- }
- }
- });
- info_map
+pub struct WindowsVersion {
+ inner: RTL_OSVERSIONINFOW,
}
-fn parse_version(os_name: &String) -> String {
- os_name
- .trim()
- .trim_start_matches("Microsoft Windows ")
- .to_owned()
-}
+impl WindowsVersion {
+ pub fn new() -> Result<WindowsVersion, io::Error> {
+ let module_name: Vec<u16> = OsString::from("ntdll")
+ .as_os_str()
+ .encode_wide()
+ .chain(iter::once(0u16))
+ .collect();
+
+
+ let ntdll = unsafe { GetModuleHandleW(module_name.as_ptr()) };
+ if ntdll == ptr::null_mut() {
+ return Err(io::Error::last_os_error());
+ }
-fn parse_full_version(os_version: &String) -> String {
- os_version.trim().to_owned()
+ 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());
+ }
+
+ let rtl_get_version: extern "stdcall" fn(*mut RTL_OSVERSIONINFOW) =
+ unsafe { *(&function_address as *const _ as *const _) };
+
+ let mut version_info: MaybeUninit<RTL_OSVERSIONINFOW> = mem::MaybeUninit::zeroed();
+ unsafe {
+ (*version_info.as_mut_ptr()).dwOSVersionInfoSize =
+ mem::size_of_val(&version_info) as u32;
+ rtl_get_version(version_info.as_mut_ptr());
+
+ Ok(WindowsVersion {
+ inner: version_info.assume_init(),
+ })
+ }
+ }
+
+ pub fn major_version(&self) -> u32 {
+ self.inner.dwMajorVersion
+ }
+
+ pub fn minor_version(&self) -> u32 {
+ self.inner.dwMinorVersion
+ }
+
+ pub fn build_number(&self) -> u32 {
+ self.inner.dwBuildNumber
+ }
}
-pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
- std::iter::empty()
+#[cfg(test)]
+mod test {
+ use super::*;
+ #[test]
+ fn test_windows_version() {
+ WindowsVersion::new().unwrap();
+ }
}