winpty_rs_windows_version/
lib.rs1#![doc = include_str!("../readme.md")]
2#![cfg(windows)]
3#![cfg_attr(not(test), no_std)]
4
5mod bindings;
6use bindings::*;
7
8#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub struct OsVersion {
11 pub major: u32,
13
14 pub minor: u32,
16
17 pub pack: u32,
19
20 pub build: u32,
22}
23
24impl OsVersion {
25 pub const fn new(major: u32, minor: u32, pack: u32, build: u32) -> Self {
27 Self {
28 major,
29 minor,
30 pack,
31 build,
32 }
33 }
34
35 #[cfg(not(test))]
37 pub fn current() -> Self {
38 let mut info = OSVERSIONINFOEXW::new();
39
40 unsafe {
41 RtlGetVersion(&mut info as *mut _ as *mut _);
42 }
43
44 OsVersion {
45 major: info.dwMajorVersion,
46 minor: info.dwMinorVersion,
47 pack: info.wServicePackMajor as u32,
48 build: info.dwBuildNumber,
49 }
50 }
51
52 #[cfg(test)]
54 fn current() -> Self {
55 test::test_current()
56 }
57}
58
59pub fn is_server() -> bool {
61 let mut info = OSVERSIONINFOEXW::new();
62
63 unsafe {
64 RtlGetVersion(&mut info as *mut _ as *mut _);
65 }
66
67 info.wProductType as u32 != VER_NT_WORKSTATION
68}
69
70impl OSVERSIONINFOEXW {
71 fn new() -> Self {
72 Self {
73 dwOSVersionInfoSize: core::mem::size_of::<Self>() as u32,
74 ..Default::default()
75 }
76 }
77}
78
79#[cfg(test)]
80mod test {
81 use super::OsVersion;
82 use std::sync::RwLock;
83
84 static TEST_CURRENT: RwLock<OsVersion> = RwLock::new(OsVersion::new(0, 0, 0, 0));
85
86 pub fn test_current() -> OsVersion {
87 *TEST_CURRENT.read().unwrap()
88 }
89
90 fn set_current(version: OsVersion) {
91 *TEST_CURRENT.write().unwrap() = version;
92 }
93
94 #[test]
95 fn test() {
96 assert_eq!(OsVersion::current(), OsVersion::new(0, 0, 0, 0));
97
98 set_current(OsVersion::new(1, 2, 3, 4));
99 assert_eq!(OsVersion::current(), OsVersion::new(1, 2, 3, 4));
100
101 set_current(OsVersion::new(10, 0, 0, 0));
102 assert!(OsVersion::current() >= OsVersion::new(9, 0, 0, 0));
103 assert!(OsVersion::current() >= OsVersion::new(10, 0, 0, 0));
104 assert!(!(OsVersion::current() >= OsVersion::new(11, 0, 0, 0)));
105
106 set_current(OsVersion::new(10, 100, 0, 0));
107 assert!(OsVersion::current() >= OsVersion::new(10, 99, 0, 0));
108 assert!(OsVersion::current() >= OsVersion::new(10, 100, 0, 0));
109 assert!(!(OsVersion::current() >= OsVersion::new(10, 101, 0, 0)));
110
111 set_current(OsVersion::new(10, 100, 1000, 0));
112 assert!(OsVersion::current() >= OsVersion::new(10, 100, 999, 0));
113 assert!(OsVersion::current() >= OsVersion::new(10, 100, 1000, 0));
114 assert!(!(OsVersion::current() >= OsVersion::new(10, 100, 1001, 0)));
115
116 set_current(OsVersion::new(10, 100, 1_000, 10_000));
117 assert!(OsVersion::current() >= OsVersion::new(10, 100, 1_000, 9_999));
118 assert!(OsVersion::current() >= OsVersion::new(10, 100, 1_000, 10_000));
119 assert!(!(OsVersion::current() >= OsVersion::new(10, 100, 1_000, 10_001)));
120 }
121}