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
This commit is contained in:
Chun-wei Fan 2015-01-26 11:11:48 +08:00
parent be2d9b4f58
commit bcbf80c355
2 changed files with 105 additions and 3 deletions

View File

@ -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,
@ -531,7 +605,11 @@ g_win32_get_package_installation_subdirectory (const gchar *package,
*
* 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)

View File

@ -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__ */