1const std = @import("std");
2
3pub const WindowsVersion = std.Target.Os.WindowsVersion;
4
5/// Returns the highest known WindowsVersion deduced from reported runtime information.
6/// Discards information about in-between versions we don't differentiate.
7pub fn detectRuntimeVersion() WindowsVersion {
8    var version_info: std.os.windows.RTL_OSVERSIONINFOW = undefined;
9    version_info.dwOSVersionInfoSize = @sizeOf(@TypeOf(version_info));
10
11    switch (std.os.windows.ntdll.RtlGetVersion(&version_info)) {
12        .SUCCESS => {},
13        else => unreachable,
14    }
15
16    // Starting from the system infos build a NTDDI-like version
17    // constant whose format is:
18    //   B0 B1 B2 B3
19    //   `---` `` ``--> Sub-version (Starting from Windows 10 onwards)
20    //     \    `--> Service pack (Always zero in the constants defined)
21    //      `--> OS version (Major & minor)
22    const os_ver: u16 = @intCast(u16, version_info.dwMajorVersion & 0xff) << 8 |
23        @intCast(u16, version_info.dwMinorVersion & 0xff);
24    const sp_ver: u8 = 0;
25    const sub_ver: u8 = if (os_ver >= 0x0A00) subver: {
26        // There's no other way to obtain this info beside
27        // checking the build number against a known set of
28        // values
29        var last_idx: usize = 0;
30        for (WindowsVersion.known_win10_build_numbers) |build, i| {
31            if (version_info.dwBuildNumber >= build)
32                last_idx = i;
33        }
34        break :subver @truncate(u8, last_idx);
35    } else 0;
36
37    const version: u32 = @as(u32, os_ver) << 16 | @as(u16, sp_ver) << 8 | sub_ver;
38
39    return @intToEnum(WindowsVersion, version);
40}
41