authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-01 02:53:51-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-03-01 02:53:51-05:00
logae99fabfe41ffab1ea49328a40521a4d76c42cf6
tree28d7ffb1988ea078d4ded17d1919423825563394
parentf082e253b56b98a806e5ec047c5eb197b2c8ab88
parent278f0f8fa97610589dfb28c8fffedca7298e6715
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4585 from LemonBoy/fix-4581

target: Implement OS version detection for Windows

3 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};
1495pub const PPSAPI_WS_WATCH_INFORMATION_EX = *PSAPI_WS_WATCH_INFORMATION_EX;1495pub const PPSAPI_WS_WATCH_INFORMATION_EX = *PSAPI_WS_WATCH_INFORMATION_EX;
1496
1497pub const OSVERSIONINFOW = extern struct {
1498 dwOSVersionInfoSize: ULONG,
1499 dwMajorVersion: ULONG,
1500 dwMinorVersion: ULONG,
1501 dwBuildNumber: ULONG,
1502 dwPlatformId: ULONG,
1503 szCSDVersion: [128]WCHAR,
1504};
1505pub const POSVERSIONINFOW = *OSVERSIONINFOW;
1506pub const LPOSVERSIONINFOW = *OSVERSIONINFOW;
1507pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
1508pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW;
lib/std/os/windows/ntdll.zig+9-1
...@@ -1,6 +1,14 @@...@@ -1,6 +1,14 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD;3pub extern "NtDll" fn RtlGetVersion(
4 lpVersionInformation: PRTL_OSVERSIONINFOW,
5) callconv(.Stdcall) NTSTATUS;
6pub extern "NtDll" fn RtlCaptureStackBackTrace(
7 FramesToSkip: DWORD,
8 FramesToCapture: DWORD,
9 BackTrace: **c_void,
10 BackTraceHash: ?*DWORD,
11) callconv(.Stdcall) WORD;
4pub extern "NtDll" fn NtQueryInformationFile(12pub 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;