1
0
mirror of https://gitlab.gnome.org/GNOME/glib.git synced 2025-05-23 14:00:40 +02:00

gwin32.c: Avoid deprecated Win32 API usage

The VerifyVersionInfo() Win32 API has been deprecated in Windows 10, and
there is no direct replacement for it, except by using a lower-level
RtlGetVersion() that we aquire from the Windows DDK or from ntdll.dll.

Switch g_win32_check_windows_version() to use RtlGetVersion(), and
compare its results with the input parameters.

https://bugzilla.gnome.org/show_bug.cgi?id=756179
This commit is contained in:
Chun-wei Fan 2015-10-07 20:00:50 +08:00
parent 597438f5a2
commit 2b8b9361f9

@ -49,6 +49,18 @@
# include <io.h> # include <io.h>
#endif /* _MSC_VER || __DMC__ */ #endif /* _MSC_VER || __DMC__ */
#define MODERN_API_FAMILY 2
#if WINAPI_FAMILY == MODERN_API_FAMILY
/* This is for modern UI Builds, where we can't use LoadLibraryW()/GetProcAddress() */
/* ntddk.h is found in the WDK, and MinGW */
#include <ntddk.h>
#ifdef _MSC_VER
#pragma comment (lib, "ntoskrnl.lib")
#endif
#endif
#include "glib.h" #include "glib.h"
#include "gthreadprivate.h" #include "gthreadprivate.h"
@ -516,8 +528,6 @@ g_win32_get_package_installation_subdirectory (const gchar *package,
#endif #endif
#define gwin32condmask(base,var) VerSetConditionMask (base, var, VER_GREATER_EQUAL)
/** /**
* g_win32_check_windows_version: * g_win32_check_windows_version:
* @major: major version of Windows * @major: major version of Windows
@ -550,43 +560,76 @@ g_win32_check_windows_version (const gint major,
const GWin32OSType os_type) const GWin32OSType os_type)
{ {
OSVERSIONINFOEXW osverinfo; OSVERSIONINFOEXW osverinfo;
gboolean test_os_type; gboolean is_ver_checked = FALSE;
const DWORDLONG conds = gwin32condmask (gwin32condmask (gwin32condmask (0, VER_MAJORVERSION), VER_MINORVERSION), VER_SERVICEPACKMAJOR); gboolean is_type_checked = FALSE;
#if WINAPI_FAMILY != MODERN_API_FAMILY
/* For non-modern UI Apps, use the LoadLibraryW()/GetProcAddress() thing */
typedef NTSTATUS fRtlGetVersion (PRTL_OSVERSIONINFOEXW);
fRtlGetVersion *RtlGetVersion;
HMODULE hmodule;
#endif
/* We Only Support Checking for XP or later */
g_return_val_if_fail (major >= 5 && (major <=6 || major == 10), FALSE);
g_return_val_if_fail ((major >= 5 && minor >= 1) || major >= 6, FALSE);
/* Check for Service Pack Version >= 0 */
g_return_val_if_fail (spver >= 0, FALSE);
#if WINAPI_FAMILY != MODERN_API_FAMILY
hmodule = LoadLibraryW (L"ntdll.dll");
g_return_val_if_fail (hmodule != NULL, FALSE);
RtlGetVersion = (fRtlGetVersion *) GetProcAddress (hmodule, "RtlGetVersion");
g_return_val_if_fail (RtlGetVersion != NULL, FALSE);
#endif
memset (&osverinfo, 0, sizeof (OSVERSIONINFOEXW)); memset (&osverinfo, 0, sizeof (OSVERSIONINFOEXW));
osverinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW); osverinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
osverinfo.dwPlatformId = VER_PLATFORM_WIN32_NT; RtlGetVersion (&osverinfo);
osverinfo.dwMajorVersion = major;
osverinfo.dwMinorVersion = minor;
osverinfo.wServicePackMajor = spver;
/* check the OS and Service Pack Versions */
if (osverinfo.dwMajorVersion > major)
is_ver_checked = TRUE;
else if (osverinfo.dwMajorVersion == major)
if (osverinfo.dwMinorVersion > minor)
is_ver_checked = TRUE;
else if (osverinfo.dwMinorVersion == minor)
if (osverinfo.wServicePackMajor >= spver)
is_ver_checked = TRUE;
/* Check OS Type */
if (is_ver_checked)
{
switch (os_type) switch (os_type)
{ {
case G_WIN32_OS_ANY:
is_type_checked = TRUE;
break;
case G_WIN32_OS_WORKSTATION: case G_WIN32_OS_WORKSTATION:
osverinfo.wProductType = VER_NT_WORKSTATION; if (osverinfo.wProductType == VER_NT_WORKSTATION)
test_os_type = TRUE; is_type_checked = TRUE;
break; break;
case G_WIN32_OS_SERVER: case G_WIN32_OS_SERVER:
osverinfo.wProductType = VER_NT_SERVER; if (osverinfo.wProductType == VER_NT_SERVER ||
test_os_type = TRUE; osverinfo.wProductType == VER_NT_DOMAIN_CONTROLLER)
is_type_checked = TRUE;
break; break;
default: default:
test_os_type = FALSE; /* shouldn't get here normally */
g_warning ("Invalid os_type specified");
break; break;
} }
}
if (test_os_type) #if WINAPI_FAMILY != MODERN_API_FAMILY
return VerifyVersionInfoW (&osverinfo, FreeLibrary (hmodule);
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_PRODUCT_TYPE, #endif
gwin32condmask (conds, VER_PRODUCT_TYPE));
else return is_ver_checked && is_type_checked;
return VerifyVersionInfoW (&osverinfo,
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
conds);
} }
#undef gwin32condmask
/** /**
* g_win32_get_windows_version: * g_win32_get_windows_version:
* *