| author | |
| committer | |
| log | ae99fabfe41ffab1ea49328a40521a4d76c42cf6 |
| tree | 28d7ffb1988ea078d4ded17d1919423825563394 |
| parent | f082e253b56b98a806e5ec047c5eb197b2c8ab88 |
| parent | 278f0f8fa97610589dfb28c8fffedca7298e6715 |
| signature |
target: Implement OS version detection for Windows3 files changed, 60 insertions(+), 2 deletions(-)
lib/std/os/windows/bits.zig+13| ... | @@ -1493,3 +1493,16 @@ pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct { | ... | @@ -1493,3 +1493,16 @@ pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct { |
| 1493 | Flags: ULONG_PTR, | 1493 | Flags: ULONG_PTR, |
| 1494 | }; | 1494 | }; |
| 1495 | pub const PPSAPI_WS_WATCH_INFORMATION_EX = *PSAPI_WS_WATCH_INFORMATION_EX; | 1495 | pub const PPSAPI_WS_WATCH_INFORMATION_EX = *PSAPI_WS_WATCH_INFORMATION_EX; |
| 1496 | |||
| 1497 | pub const OSVERSIONINFOW = extern struct { | ||
| 1498 | dwOSVersionInfoSize: ULONG, | ||
| 1499 | dwMajorVersion: ULONG, | ||
| 1500 | dwMinorVersion: ULONG, | ||
| 1501 | dwBuildNumber: ULONG, | ||
| 1502 | dwPlatformId: ULONG, | ||
| 1503 | szCSDVersion: [128]WCHAR, | ||
| 1504 | }; | ||
| 1505 | pub const POSVERSIONINFOW = *OSVERSIONINFOW; | ||
| 1506 | pub const LPOSVERSIONINFOW = *OSVERSIONINFOW; | ||
| 1507 | pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW; | ||
| 1508 | pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW; |
lib/std/os/windows/ntdll.zig+9-1| ... | @@ -1,6 +1,14 @@ | ... | @@ -1,6 +1,14 @@ |
| 1 | usingnamespace @import("bits.zig"); | 1 | usingnamespace @import("bits.zig"); |
| 2 | 2 | ||
| 3 | pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD; | 3 | pub extern "NtDll" fn RtlGetVersion( |
| 4 | lpVersionInformation: PRTL_OSVERSIONINFOW, | ||
| 5 | ) callconv(.Stdcall) NTSTATUS; | ||
| 6 | pub extern "NtDll" fn RtlCaptureStackBackTrace( | ||
| 7 | FramesToSkip: DWORD, | ||
| 8 | FramesToCapture: DWORD, | ||
| 9 | BackTrace: **c_void, | ||
| 10 | BackTraceHash: ?*DWORD, | ||
| 11 | ) callconv(.Stdcall) WORD; | ||
| 4 | pub extern "NtDll" fn NtQueryInformationFile( | 12 | pub extern "NtDll" fn NtQueryInformationFile( |
| 5 | FileHandle: HANDLE, | 13 | FileHandle: HANDLE, |
| 6 | IoStatusBlock: *IO_STATUS_BLOCK, | 14 | IoStatusBlock: *IO_STATUS_BLOCK, |
lib/std/zig/system.zig+38-1| ... | @@ -221,7 +221,44 @@ pub const NativeTargetInfo = struct { | ... | @@ -221,7 +221,44 @@ pub const NativeTargetInfo = struct { |
| 221 | } | 221 | } |
| 222 | }, | 222 | }, |
| 223 | .windows => { | 223 | .windows => { |
| 224 | // TODO Detect native operating system version. | 224 | var version_info: std.os.windows.RTL_OSVERSIONINFOW = undefined; |
| 225 | version_info.dwOSVersionInfoSize = @sizeOf(@TypeOf(version_info)); | ||
| 226 | |||
| 227 | switch (std.os.windows.ntdll.RtlGetVersion(&version_info)) { | ||
| 228 | .SUCCESS => {}, | ||
| 229 | else => unreachable, | ||
| 230 | } | ||
| 231 | |||
| 232 | // Starting from the system infos build a NTDDI-like version | ||
| 233 | // constant whose format is: | ||
| 234 | // B0 B1 B2 B3 | ||
| 235 | // `---` `` ``--> Sub-version (Starting from Windows 10 onwards) | ||
| 236 | // \ `--> Service pack (Always zero in the constants defined) | ||
| 237 | // `--> OS version (Major & minor) | ||
| 238 | const os_ver: u16 = // | ||
| 239 | @intCast(u16, version_info.dwMajorVersion & 0xff) << 8 | | ||
| 240 | @intCast(u16, version_info.dwMinorVersion & 0xff); | ||
| 241 | const sp_ver: u8 = 0; | ||
| 242 | const sub_ver: u8 = if (os_ver >= 0x0A00) subver: { | ||
| 243 | // There's no other way to obtain this info beside | ||
| 244 | // checking the build number against a known set of | ||
| 245 | // values | ||
| 246 | const known_build_numbers = [_]u32{ | ||
| 247 | 10240, 10586, 14393, 15063, 16299, 17134, 17763, | ||
| 248 | 18362, 18363, | ||
| 249 | }; | ||
| 250 | var last_idx: usize = 0; | ||
| 251 | for (known_build_numbers) |build, i| { | ||
| 252 | if (version_info.dwBuildNumber >= build) | ||
| 253 | last_idx = i; | ||
| 254 | } | ||
| 255 | break :subver @truncate(u8, last_idx); | ||
| 256 | } else 0; | ||
| 257 | |||
| 258 | const version: u32 = @as(u32, os_ver) << 16 | @as(u32, sp_ver) << 8 | sub_ver; | ||
| 259 | |||
| 260 | os.version_range.windows.max = @intToEnum(Target.Os.WindowsVersion, version); | ||
| 261 | os.version_range.windows.min = @intToEnum(Target.Os.WindowsVersion, version); | ||
| 225 | }, | 262 | }, |
| 226 | .macosx => { | 263 | .macosx => { |
| 227 | var product_version: [32]u8 = undefined; | 264 | var product_version: [32]u8 = undefined; |