From 83aefa923b321b8ab266f5dfc3b4d0aa596ee835 Mon Sep 17 00:00:00 2001 From: Amer Koleci Date: Tue, 17 Jul 2018 20:09:58 +0200 Subject: [PATCH 1/2] Use RtlVerifyVersionInfo for IsWindowsVersionOrGreater check, fixes #1294 --- src/win32_init.c | 41 ++++++++++++++++++++++++++++++++++------- src/win32_platform.h | 10 +++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/win32_init.c b/src/win32_init.c index a913846d4..658bb56ab 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -62,15 +62,42 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) #endif // _GLFW_BUILD_DLL +typedef LONG NTSTATUS, *PNTSTATUS; +#define STATUS_SUCCESS ((NTSTATUS)0x00000000) +#define STATUS_REVISION_MISMATCH ((NTSTATUS)0xC0000059) +typedef NTSTATUS(WINAPI* RtlVerifyVersionInfoFn)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG); + // HACK: Define versionhelpers.h functions manually as MinGW lacks the header -BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) +BOOL IsWindowsVersionOrGreater(WORD major, WORD minor) { - OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp }; - DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; - ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); - cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); - cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - return VerifyVersionInfoW(&osvi, mask, cond); + static RtlVerifyVersionInfoFn RtlVerifyVersionInfoFn = NULL; + if (!RtlVerifyVersionInfoFn) + { + HMODULE ntdllModule = GetModuleHandleW(L"ntdll.dll"); + if (ntdllModule) + { + RtlVerifyVersionInfoFn = GetProcAddress(ntdllModule, "RtlVerifyVersionInfo"); + } + } + + RTL_OSVERSIONINFOEXW versionInfo = { 0 }; + NTSTATUS status; + ULONGLONG conditionMask = 0; + versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); + versionInfo.dwMajorVersion = major; + versionInfo.dwMinorVersion = minor; + + VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + + status = RtlVerifyVersionInfoFn(&versionInfo, + VER_MAJORVERSION | VER_MINORVERSION, + conditionMask); + + if (status == STATUS_SUCCESS) + return TRUE; + + return FALSE; } // Load necessary libraries (DLLs) diff --git a/src/win32_platform.h b/src/win32_platform.h index 598151468..a3729b442 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -141,19 +141,19 @@ typedef enum #endif /*DPI_ENUMS_DECLARED*/ // HACK: Define versionhelpers.h functions manually as MinGW lacks the header -BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp); +BOOL IsWindowsVersionOrGreater(WORD major, WORD minor); #define IsWindowsVistaOrGreater() \ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), \ - LOBYTE(_WIN32_WINNT_VISTA), 0) + LOBYTE(_WIN32_WINNT_VISTA)) #define IsWindows7OrGreater() \ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), \ - LOBYTE(_WIN32_WINNT_WIN7), 0) + LOBYTE(_WIN32_WINNT_WIN7)) #define IsWindows8OrGreater() \ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), \ - LOBYTE(_WIN32_WINNT_WIN8), 0) + LOBYTE(_WIN32_WINNT_WIN8)) #define IsWindows8Point1OrGreater() \ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), \ - LOBYTE(_WIN32_WINNT_WINBLUE), 0) + LOBYTE(_WIN32_WINNT_WINBLUE)) // HACK: Define macros that some xinput.h variants don't #ifndef XINPUT_CAPS_WIRELESS From 05270ca57db59483101dff330ca5924c1a823b4b Mon Sep 17 00:00:00 2001 From: Amer Koleci Date: Wed, 18 Jul 2018 18:51:50 +0200 Subject: [PATCH 2/2] Fix compilation warnings. --- src/win32_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/win32_init.c b/src/win32_init.c index 658bb56ab..a85ff52fb 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -65,18 +65,18 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) typedef LONG NTSTATUS, *PNTSTATUS; #define STATUS_SUCCESS ((NTSTATUS)0x00000000) #define STATUS_REVISION_MISMATCH ((NTSTATUS)0xC0000059) -typedef NTSTATUS(WINAPI* RtlVerifyVersionInfoFn)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG); +typedef NTSTATUS(WINAPI* PFN_RtlVerifyVersionInfoFn)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG); // HACK: Define versionhelpers.h functions manually as MinGW lacks the header BOOL IsWindowsVersionOrGreater(WORD major, WORD minor) { - static RtlVerifyVersionInfoFn RtlVerifyVersionInfoFn = NULL; + static PFN_RtlVerifyVersionInfoFn RtlVerifyVersionInfoFn = NULL; if (!RtlVerifyVersionInfoFn) { HMODULE ntdllModule = GetModuleHandleW(L"ntdll.dll"); if (ntdllModule) { - RtlVerifyVersionInfoFn = GetProcAddress(ntdllModule, "RtlVerifyVersionInfo"); + RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfoFn)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo"); } }