From bcbf80c35580142216f4b1ed2f71717efb2de99d Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Mon, 26 Jan 2015 11:11:48 +0800 Subject: [PATCH] gwin32: Add g_win32_check_windows_version() API This adds a public API where one can use to see whether the running version of Windows where the code is run is at least the specified version, service pack level, and the type (non-server, server, any) of the running Windows OS. This API is done as: -GetVersion()/GetVersionEx() changed in the way they work since Windows 8.1 [1][2], so a newer mechanism to check the version of the running Windows operating system is needed. MSDN also states that GetVersion() might be further changed or removed after Windows 8.1. This provides a wrapper for VerfyVersionInfo() as well in GLib for most cases, which was recommended in place of g_win32_get_windows_version() for more detailed Windows version checking. -Provides an OS-level functionality check, for those that we don't need to venture into GetProcAddress(), and also to determine system API behavior changes due to differences in OS versions. Also added a note for the g_win32_get_windows_version() API that since the behavior of GetVersion() which it uses, is changed since Windows 8.1, users of the API should be aware. [1]: http://msdn.microsoft.com/zh-tw/library/windows/desktop/ms724451%28v=vs.85%29.aspx [2]: http://msdn.microsoft.com/zh-tw/library/windows/desktop/ms724451%28v=vs.85%29.aspx https://bugzilla.gnome.org/show_bug.cgi?id=741895 --- glib/gwin32.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- glib/gwin32.h | 26 ++++++++++++++++++- 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/glib/gwin32.c b/glib/gwin32.c index ffc5fe2..fc4416b 100644 --- a/glib/gwin32.c +++ b/glib/gwin32.c @@ -516,9 +516,83 @@ g_win32_get_package_installation_subdirectory (const gchar *package, #endif +#define gwin32condmask(base,var) VerSetConditionMask (base, var, VER_GREATER_EQUAL) + +/** + * g_win32_check_windows_version: + * @major: major version of Windows + * @minor: minor version of Windows + * @spver: Windows Service Pack Level, 0 if none + * @os_type: Type of Windows OS + * + * Returns whether the version of the Windows operating system the + * code is running on is at least the specified major, minor and + * service pack versions. See MSDN documentation for the Operating + * System Version. Software that needs even more detailed version and + * feature information should use the Win32 API VerifyVersionInfo() + * directly. + * + * Successive calls of this function can be used for enabling or + * disabling features at run-time for a range of Windows versions, + * as per the VerifyVersionInfo() API documentation. + * + * Returns: %TRUE if the Windows Version is the same or greater than + * the specified major, minor and service pack versions, and + * whether the running Windows is a workstation or server edition + * of Windows, if specifically specified. + * + * Since: 2.44 + **/ +gboolean +g_win32_check_windows_version (const gint major, + const gint minor, + const gint spver, + const GWin32OSType os_type) +{ + OSVERSIONINFOEXW osverinfo; + gboolean test_os_type; + const DWORDLONG conds = gwin32condmask (gwin32condmask (gwin32condmask (0, VER_MAJORVERSION), VER_MINORVERSION), VER_SERVICEPACKMAJOR); + + memset (&osverinfo, 0, sizeof (OSVERSIONINFOEXW)); + osverinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW); + osverinfo.dwPlatformId = VER_PLATFORM_WIN32_NT; + osverinfo.dwMajorVersion = major; + osverinfo.dwMinorVersion = minor; + osverinfo.wServicePackMajor = spver; + + switch (os_type) + { + case G_WIN32_OS_WORKSTATION: + osverinfo.wProductType = VER_NT_WORKSTATION; + test_os_type = TRUE; + break; + case G_WIN32_OS_SERVER: + osverinfo.wProductType = VER_NT_SERVER; + test_os_type = TRUE; + break; + default: + test_os_type = FALSE; + break; + } + + if (test_os_type) + return VerifyVersionInfoW (&osverinfo, + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_PRODUCT_TYPE, + gwin32condmask (conds, VER_PRODUCT_TYPE)); + else + return VerifyVersionInfoW (&osverinfo, + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, + conds); +} + +#undef gwin32condmask + /** * g_win32_get_windows_version: * + * This function is deprecated. Use + * g_win32_check_windows_version() instead. + * * Returns version information for the Windows operating system the * code is running on. See MSDN documentation for the GetVersion() * function. To summarize, the most significant bit is one on Win9x, @@ -530,8 +604,12 @@ g_win32_get_package_installation_subdirectory (const gchar *package, * GetVersionEx() and VerifyVersionInfo(). * * Returns: The version information. - * - * Since: 2.6 + * + * Deprecated: 2.44: Be aware that for Windows 8.1 and Windows Server + * 2012 R2 and later, this will return 62 unless the application is + * manifested for Windows 8.1/Windows Server 2012 R2, for example. + * MSDN stated that GetVersion(), which is used here, is subject to + * further change or removal after Windows 8.1. **/ guint g_win32_get_windows_version (void) diff --git a/glib/gwin32.h b/glib/gwin32.h index c7575c4..f6e457d 100644 --- a/glib/gwin32.h +++ b/glib/gwin32.h @@ -98,7 +98,7 @@ gchar* g_win32_get_package_installation_subdirectory (const gchar *pack GLIB_AVAILABLE_IN_ALL gchar* g_win32_get_package_installation_directory_of_module (gpointer hmodule); -GLIB_AVAILABLE_IN_ALL +GLIB_DEPRECATED_IN_2_44_FOR(g_win32_check_windows_version) guint g_win32_get_windows_version (void); GLIB_AVAILABLE_IN_ALL @@ -130,6 +130,30 @@ gchar *g_win32_get_package_installation_subdirectory_utf8 (const gchar *package, const gchar *dll_name, const gchar *subdir); +/** + * GWin32OSType: + * @G_WIN32_OS_ANY: The running system can be a workstation or a server edition of + * Windows. The type of the running system is therefore not checked. + * @G_WIN32_OS_WORKSTATION: The running system is a workstation edition of Windows, + * such as Windows 7 Professional. + * @G_WIN32_OS_SERVER: The running system is a server edition of Windows, such as + * Windows Server 2008 R2. + * + * Type of Windows edition to check for at run-time. + **/ +typedef enum +{ + G_WIN32_OS_ANY, + G_WIN32_OS_WORKSTATION, + G_WIN32_OS_SERVER, +} GWin32OSType; + +GLIB_AVAILABLE_IN_2_44 +gboolean g_win32_check_windows_version (const gint major, + const gint minor, + const gint spver, + const GWin32OSType os_type); + #endif /* G_OS_WIN32 */ #endif /* __GTK_DOC_IGNORE__ */ -- 2.7.4