From 54d9c512bf68796d9ade7b06a1a1c6a32beff158 Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Sun, 6 Jan 2019 00:09:05 -0800 Subject: [PATCH 1/3] Add Windows Version Helper functions --- CHANGES.md | 1 + .../com/sun/jna/platform/win32/Kernel32.java | 65 ++++++ .../jna/platform/win32/VersionHelpers.java | 213 ++++++++++++++++++ .../src/com/sun/jna/platform/win32/WinNT.java | 31 ++- .../platform/win32/VersionHelpersTest.java | 66 ++++++ 5 files changed, 369 insertions(+), 7 deletions(-) create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java create mode 100644 contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java diff --git a/CHANGES.md b/CHANGES.md index 61f53c6a8b..9440de9f81 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Next release (5.2.1) Features -------- +* [#1050](https://github.com/java-native-access/jna/pull/1050): Add `c.s.j.p.win32.VersionHelpers` and supporting functions - [@dbwiddis](https://github.com/dbwiddis). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java index 6efed8300b..9f600019f6 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -1413,6 +1413,71 @@ boolean CreateProcessW(String lpApplicationName, char[] lpCommandLine, */ boolean GetVersionEx(OSVERSIONINFOEX lpVersionInfo); + /** + * The VerifyVersionInfoW function compares a set of operating system + * version requirements to the corresponding values for the currently + * running version of the system.This function is subject to manifest-based + * behavior. + * + * @param lpVersionInformation + * A pointer to an OSVERSIONINFOEX structure containing the + * operating system version requirements to compare. The + * dwTypeMask parameter indicates the members of this structure + * that contain information to compare. + * + * You must set the dwOSVersionInfoSize member of this structure + * to sizeof(OSVERSIONINFOEX). You must also specify valid data + * for the members indicated by dwTypeMask. The function ignores + * structure members for which the corresponding dwTypeMask bit + * is not set. + * @param dwTypeMask + * A mask that indicates the members of the OSVERSIONINFOEX + * structure to be tested. + * @param dwlConditionMask + * The type of comparison to be used for each lpVersionInfo + * member being compared. To build this value, call the + * VerSetConditionMask function once for each OSVERSIONINFOEX + * member being compared. + * @return If the currently running operating system satisfies the specified + * requirements, the return value is a nonzero value. + * + * If the current system does not satisfy the requirements, the + * return value is zero and GetLastError returns + * ERROR_OLD_WIN_VERSION. + * + * If the function fails, the return value is zero and GetLastError + * returns an error code other than ERROR_OLD_WIN_VERSION. + */ + boolean VerifyVersionInfoW(OSVERSIONINFOEX lpVersionInformation, int dwTypeMask, long dwlConditionMask); + + /** + * The VerSetConditionMask function sets the bits of a 64-bit value to + * indicate the comparison operator to use for a specified operating system + * version attribute. This function is used to build the dwlConditionMask + * parameter of the VerifyVersionInfo function. + * + * @param conditionMask + * A value to be passed as the dwlConditionMask parameter of the + * VerifyVersionInfo function. The function stores the comparison + * information in the bits of this variable. + * + * Before the first call to VerSetCondition, initialize this + * variable to zero. For subsequent calls, pass in the variable + * used in the previous call. + * @param typeMask + * A mask that indicates the member of the OSVERSIONINFOEX + * structure whose comparison operator is being set. This value + * corresponds to one of the bits specified in the dwTypeMask + * parameter for the VerifyVersionInfo function. + * @param condition + * The operator to be used for the comparison. The + * VerifyVersionInfo function uses this operator to compare a + * specified attribute value to the corresponding value for the + * currently running system. + * @return The function returns the condition mask value. + */ + long VerSetConditionMask(long conditionMask, int typeMask, byte condition); + /** * The GetSystemInfo function returns information about the current system. * diff --git a/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java b/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java new file mode 100644 index 0000000000..4d3b398ae0 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java @@ -0,0 +1,213 @@ +/* Copyright (c) 2019 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.WinNT.OSVERSIONINFOEX; + +/** + * The following functions can be used to determine the current operating system + * version or identify whether it is a Windows or Windows Server release. These + * functions provide simple tests that use the VerifyVersionInfo function and + * the recommended greater than or equal to comparisons that are proven as a + * robust means to determine the operating system version. + */ +public class VersionHelpers { + + /** + * This function is useful in confirming a version of Windows Server that + * doesn't share a version number with a client release. You should only use + * this function if the other provided version helper functions do not fit + * your scenario. + * + * @param wMajorVersion + * The major version to test + * @param wMinorVersion + * The minor version to test + * @param wServicePackMajor + * The service pack to test + * @return True if the current OS version matches, or is greater than, the + * provided version information. + */ + public static boolean IsWindowsVersionOrGreater(int wMajorVersion, int wMinorVersion, int wServicePackMajor) { + OSVERSIONINFOEX osvi = new OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = new DWORD(osvi.size()); + osvi.dwMajorVersion = new DWORD(wMajorVersion); + osvi.dwMinorVersion = new DWORD(wMinorVersion); + osvi.wServicePackMajor = new WORD(wServicePackMajor); + + long dwlConditionMask = 0; + dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(dwlConditionMask, WinNT.VER_MAJORVERSION, + WinNT.VER_GREATER_EQUAL); + dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(dwlConditionMask, WinNT.VER_MINORVERSION, + WinNT.VER_GREATER_EQUAL); + dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(dwlConditionMask, WinNT.VER_SERVICEPACKMAJOR, + WinNT.VER_GREATER_EQUAL); + + return Kernel32.INSTANCE.VerifyVersionInfoW(osvi, + WinNT.VER_MAJORVERSION | WinNT.VER_MINORVERSION | WinNT.VER_SERVICEPACKMAJOR, dwlConditionMask); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows XP version. + */ + public static boolean IsWindowsXPOrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 0); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows XP with Service Pack 1 (SP1) version. + */ + public static boolean IsWindowsXPSP1OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 1); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows XP with Service Pack 2 (SP2) version. + */ + public static boolean IsWindowsXPSP2OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 2); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows XP with Service Pack 3 (SP3) version. + */ + public static boolean IsWindowsXPSP3OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 3); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows Vista version. + */ + public static boolean IsWindowsVistaOrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_VISTA), LOBYTE(WinNT.WIN32_WINNT_VISTA), 0); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows Vista with Service Pack 1 (SP1) version. + */ + public static boolean IsWindowsVistaSP1OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_VISTA), LOBYTE(WinNT.WIN32_WINNT_VISTA), 1); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows Vista with Service Pack 2 (SP2) version. + */ + public static boolean IsWindowsVistaSP2OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_VISTA), LOBYTE(WinNT.WIN32_WINNT_VISTA), 2); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows 7 version. + */ + public static boolean IsWindows7OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN7), LOBYTE(WinNT.WIN32_WINNT_WIN7), 0); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows 7 with Service Pack 1 (SP1) version. + */ + public static boolean IsWindows7SP1OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN7), LOBYTE(WinNT.WIN32_WINNT_WIN7), 1); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows 8 version. + */ + public static boolean IsWindows8OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN8), LOBYTE(WinNT.WIN32_WINNT_WIN8), 0); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows 8.1 version. For Windows 10, IsWindows8Point1OrGreater + * returns false unless the application contains a manifest that + * includes a compatibility section that contains the GUIDs that + * designate Windows 8.1 and/or Windows 10. + */ + public static boolean IsWindows8Point1OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINBLUE), LOBYTE(WinNT.WIN32_WINNT_WINBLUE), 0); + } + + /** + * @return true if the current OS version matches, or is greater than, the + * Windows 10 version. For Windows 10, IsWindows10OrGreater returns + * false unless the application contains a manifest that includes a + * compatibility section that contains the GUID that designates + * Windows 10. + */ + public static boolean IsWindows10OrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN10), LOBYTE(WinNT.WIN32_WINNT_WIN10), 0); + } + + /** + * Applications that need to distinguish between server and client versions + * of Windows should call this function. + * + * @return true if the current OS is a Windows Server release. + */ + public static boolean IsWindowsServer() { + OSVERSIONINFOEX osvi = new OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = new DWORD(osvi.size()); + osvi.wProductType = WinNT.VER_NT_WORKSTATION; + + long dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(0, WinNT.VER_PRODUCT_TYPE, WinNT.VER_EQUAL); + + return !Kernel32.INSTANCE.VerifyVersionInfoW(osvi, WinNT.VER_PRODUCT_TYPE, dwlConditionMask); + } + + /** + * Get the high byte + * + * @param word + * a two-byte value + * @return The most significant byte + */ + private static byte HIBYTE(short word) { + return (byte) ((word >> 8) & 0xFF); + } + + /** + * Get the low byte + * + * @param word + * a two-byte value + * @return The least significant byte + */ + private static byte LOBYTE(short word) { + return (byte) word; + } +} + diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 71a2e64339..860d95a02d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -1988,13 +1988,13 @@ public byte getProductType() { } } - int VER_EQUAL = 1; - int VER_GREATER = 2; - int VER_GREATER_EQUAL = 3; - int VER_LESS = 4; - int VER_LESS_EQUAL = 5; - int VER_AND = 6; - int VER_OR = 7; + byte VER_EQUAL = 1; + byte VER_GREATER = 2; + byte VER_GREATER_EQUAL = 3; + byte VER_LESS = 4; + byte VER_LESS_EQUAL = 5; + byte VER_AND = 6; + byte VER_OR = 7; int VER_CONDITION_MASK = 7; int VER_NUM_BITS_PER_CONDITION_MASK = 3; @@ -2016,6 +2016,23 @@ public byte getProductType() { int VER_PLATFORM_WIN32_WINDOWS = 1; int VER_PLATFORM_WIN32_NT = 2; + /* + * WIN32_WINNT version constants + */ + short WIN32_WINNT_NT4 = 0x0400; // Windows NT 4.0 + short WIN32_WINNT_WIN2K = 0x0500; // Windows 2000 + short WIN32_WINNT_WINXP = 0x0501; // Windows XP + short WIN32_WINNT_WS03 = 0x0502; // Windows Server 2003 + short WIN32_WINNT_WIN6 = 0x0600; // Windows Vista + short WIN32_WINNT_VISTA = 0x0600; // Windows Vista + short WIN32_WINNT_WS08 = 0x0600; // Windows Server 2008 + short WIN32_WINNT_LONGHORN = 0x0600; // Windows Vista + short WIN32_WINNT_WIN7 = 0x0601; // Windows 7 + short WIN32_WINNT_WIN8 = 0x0602; // Windows 8 + short WIN32_WINNT_WINBLUE = 0x0603; // Windows 8.1 + short WIN32_WINNT_WINTHRESHOLD = 0x0A00; // Windows 10 + short WIN32_WINNT_WIN10 = 0x0A00; // Windows 10 + /** * Read the records sequentially. If this is the first read operation, the * EVENTLOG_FORWARDS_READ EVENTLOG_BACKWARDS_READ flags determines which diff --git a/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java b/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java new file mode 100644 index 0000000000..76651693ac --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java @@ -0,0 +1,66 @@ +package com.sun.jna.platform.win32; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class VersionHelpersTest { + @Test + public void testVersionHelpers() { + // All windows versions should be higher than version 0.0! + assertTrue(VersionHelpers.IsWindowsVersionOrGreater(0, 0, 0)); + // All windows versions should be lower than version Short.MAX_VALUE! + assertFalse(VersionHelpers.IsWindowsVersionOrGreater(Short.MAX_VALUE, Short.MAX_VALUE, Short.MAX_VALUE)); + // These tests in order should be true until false; once false never + // true again + boolean lastVersionTest = true; + boolean versionTest = VersionHelpers.IsWindowsXPOrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindowsXPSP1OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindowsXPSP2OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindowsXPSP3OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindowsVistaOrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindowsVistaSP1OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindowsVistaSP2OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindows7OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindows7SP1OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindows8OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindows8Point1OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + + lastVersionTest = versionTest; + versionTest = VersionHelpers.IsWindows10OrGreater(); + assertTrue((lastVersionTest == versionTest) || !versionTest); + } +} + From 3bba92c542dbb2ccd4daf6120ae914a43c297294 Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Mon, 7 Jan 2019 20:48:30 -0800 Subject: [PATCH 2/3] Javadocs, better typecasting --- CHANGES.md | 2 +- .../com/sun/jna/platform/win32/Kernel32.java | 90 ++++++++++--------- .../jna/platform/win32/VersionHelpers.java | 81 ++++++++--------- .../src/com/sun/jna/platform/win32/WinNT.java | 14 +-- 4 files changed, 89 insertions(+), 98 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 9440de9f81..a9cd8f6c97 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ NOTE: as of JNA 4.0, JNA is now dual-licensed under LGPL and AL 2.0 (see LICENSE NOTE: JNI native support is typically incompatible between minor versions, and almost always incompatible between major versions. -Next release (5.2.1) +Next release (5.3.0) ==================== Features diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java index 9f600019f6..e012b1349e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -1414,66 +1414,68 @@ boolean CreateProcessW(String lpApplicationName, char[] lpCommandLine, boolean GetVersionEx(OSVERSIONINFOEX lpVersionInfo); /** - * The VerifyVersionInfoW function compares a set of operating system - * version requirements to the corresponding values for the currently - * running version of the system.This function is subject to manifest-based - * behavior. + * Compares a set of operating system version requirements to the + * corresponding values for the currently running version of the system. + * This function is subject to manifest-based behavior. * * @param lpVersionInformation - * A pointer to an OSVERSIONINFOEX structure containing the - * operating system version requirements to compare. The - * dwTypeMask parameter indicates the members of this structure - * that contain information to compare. - * - * You must set the dwOSVersionInfoSize member of this structure - * to sizeof(OSVERSIONINFOEX). You must also specify valid data - * for the members indicated by dwTypeMask. The function ignores - * structure members for which the corresponding dwTypeMask bit - * is not set. + * A pointer to an {@link WinNT#OSVERSIONINFOEX} structure + * containing the operating system version requirements to + * compare. The {@code dwTypeMask} parameter indicates the + * members of this structure that contain information to compare. + *

+ * You must set the {@code dwOSVersionInfoSize} member of this + * structure to {@code sizeof(OSVERSIONINFOEX)}. You must also + * specify valid data for the members indicated by + * {@code dwTypeMask}. The function ignores structure members for + * which the corresponding {@code dwTypeMask} bit is not set. * @param dwTypeMask - * A mask that indicates the members of the OSVERSIONINFOEX - * structure to be tested. + * A mask that indicates the members of the + * {@link WinNT#OSVERSIONINFOEX} structure to be tested. * @param dwlConditionMask - * The type of comparison to be used for each lpVersionInfo - * member being compared. To build this value, call the - * VerSetConditionMask function once for each OSVERSIONINFOEX - * member being compared. + * The type of comparison to be used for each + * {@code lpVersionInfo} member being compared. To build this + * value, call the {@link #VerSetConditionMask} function once for + * each {@link WinNT#OSVERSIONINFOEX} member being compared. * @return If the currently running operating system satisfies the specified * requirements, the return value is a nonzero value. - * + *

* If the current system does not satisfy the requirements, the - * return value is zero and GetLastError returns - * ERROR_OLD_WIN_VERSION. - * - * If the function fails, the return value is zero and GetLastError - * returns an error code other than ERROR_OLD_WIN_VERSION. + * return value is zero and {@link #GetLastError()} returns + * {@link WinError#ERROR_OLD_WIN_VERSION}. + *

+ * If the function fails, the return value is zero and + * {@link #GetLastError()} returns an error code other than + * {@link WinError#ERROR_OLD_WIN_VERSION}. */ boolean VerifyVersionInfoW(OSVERSIONINFOEX lpVersionInformation, int dwTypeMask, long dwlConditionMask); /** - * The VerSetConditionMask function sets the bits of a 64-bit value to - * indicate the comparison operator to use for a specified operating system - * version attribute. This function is used to build the dwlConditionMask - * parameter of the VerifyVersionInfo function. + * Sets the bits of a 64-bit value to indicate the comparison operator to + * use for a specified operating system version attribute. This function is + * used to build the {@code dwlConditionMask} parameter of the + * {@link #VerifyVersionInfo} function. * * @param conditionMask - * A value to be passed as the dwlConditionMask parameter of the - * VerifyVersionInfo function. The function stores the comparison - * information in the bits of this variable. - * - * Before the first call to VerSetCondition, initialize this - * variable to zero. For subsequent calls, pass in the variable - * used in the previous call. + * A value to be passed as the {@code dwlConditionMask} parameter + * of the {@link #VerifyVersionInfo} function. The function + * stores the comparison information in the bits of this + * variable. + *

+ * Before the first call to {@link #VerSetConditionMask}, + * initialize this variable to zero. For subsequent calls, pass + * in the variable used in the previous call. * @param typeMask - * A mask that indicates the member of the OSVERSIONINFOEX - * structure whose comparison operator is being set. This value - * corresponds to one of the bits specified in the dwTypeMask - * parameter for the VerifyVersionInfo function. + * A mask that indicates the member of the + * {@link WinNT#OSVERSIONINFOEX} structure whose comparison + * operator is being set. This value corresponds to one of the + * bits specified in the {@code dwTypeMask} parameter for the + * {@link #VerifyVersionInfo} function. * @param condition * The operator to be used for the comparison. The - * VerifyVersionInfo function uses this operator to compare a - * specified attribute value to the corresponding value for the - * currently running system. + * {@link #VerifyVersionInfo} function uses this operator to + * compare a specified attribute value to the corresponding value + * for the currently running system. * @return The function returns the condition mask value. */ long VerSetConditionMask(long conditionMask, int typeMask, byte condition); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java b/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java index 4d3b398ae0..2280116aae 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java @@ -60,11 +60,11 @@ public static boolean IsWindowsVersionOrGreater(int wMajorVersion, int wMinorVer long dwlConditionMask = 0; dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(dwlConditionMask, WinNT.VER_MAJORVERSION, - WinNT.VER_GREATER_EQUAL); + (byte) WinNT.VER_GREATER_EQUAL); dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(dwlConditionMask, WinNT.VER_MINORVERSION, - WinNT.VER_GREATER_EQUAL); + (byte) WinNT.VER_GREATER_EQUAL); dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(dwlConditionMask, WinNT.VER_SERVICEPACKMAJOR, - WinNT.VER_GREATER_EQUAL); + (byte) WinNT.VER_GREATER_EQUAL); return Kernel32.INSTANCE.VerifyVersionInfoW(osvi, WinNT.VER_MAJORVERSION | WinNT.VER_MINORVERSION | WinNT.VER_SERVICEPACKMAJOR, dwlConditionMask); @@ -75,7 +75,8 @@ public static boolean IsWindowsVersionOrGreater(int wMajorVersion, int wMinorVer * Windows XP version. */ public static boolean IsWindowsXPOrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 0); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WINXP >>> 8), (byte) Kernel32.WIN32_WINNT_WINXP, + 0); } /** @@ -83,7 +84,8 @@ public static boolean IsWindowsXPOrGreater() { * Windows XP with Service Pack 1 (SP1) version. */ public static boolean IsWindowsXPSP1OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 1); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WINXP >>> 8), (byte) Kernel32.WIN32_WINNT_WINXP, + 1); } /** @@ -91,7 +93,8 @@ public static boolean IsWindowsXPSP1OrGreater() { * Windows XP with Service Pack 2 (SP2) version. */ public static boolean IsWindowsXPSP2OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 2); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WINXP >>> 8), (byte) Kernel32.WIN32_WINNT_WINXP, + 2); } /** @@ -99,7 +102,8 @@ public static boolean IsWindowsXPSP2OrGreater() { * Windows XP with Service Pack 3 (SP3) version. */ public static boolean IsWindowsXPSP3OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINXP), LOBYTE(WinNT.WIN32_WINNT_WINXP), 3); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WINXP >>> 8), (byte) Kernel32.WIN32_WINNT_WINXP, + 3); } /** @@ -107,7 +111,8 @@ public static boolean IsWindowsXPSP3OrGreater() { * Windows Vista version. */ public static boolean IsWindowsVistaOrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_VISTA), LOBYTE(WinNT.WIN32_WINNT_VISTA), 0); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_VISTA >>> 8), (byte) Kernel32.WIN32_WINNT_VISTA, + 0); } /** @@ -115,7 +120,8 @@ public static boolean IsWindowsVistaOrGreater() { * Windows Vista with Service Pack 1 (SP1) version. */ public static boolean IsWindowsVistaSP1OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_VISTA), LOBYTE(WinNT.WIN32_WINNT_VISTA), 1); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_VISTA >>> 8), (byte) Kernel32.WIN32_WINNT_VISTA, + 1); } /** @@ -123,7 +129,8 @@ public static boolean IsWindowsVistaSP1OrGreater() { * Windows Vista with Service Pack 2 (SP2) version. */ public static boolean IsWindowsVistaSP2OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_VISTA), LOBYTE(WinNT.WIN32_WINNT_VISTA), 2); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_VISTA >>> 8), (byte) Kernel32.WIN32_WINNT_VISTA, + 2); } /** @@ -131,7 +138,7 @@ public static boolean IsWindowsVistaSP2OrGreater() { * Windows 7 version. */ public static boolean IsWindows7OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN7), LOBYTE(WinNT.WIN32_WINNT_WIN7), 0); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WIN7 >>> 8), (byte) Kernel32.WIN32_WINNT_WIN7, 0); } /** @@ -139,7 +146,7 @@ public static boolean IsWindows7OrGreater() { * Windows 7 with Service Pack 1 (SP1) version. */ public static boolean IsWindows7SP1OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN7), LOBYTE(WinNT.WIN32_WINNT_WIN7), 1); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WIN7 >>> 8), (byte) Kernel32.WIN32_WINNT_WIN7, 1); } /** @@ -147,29 +154,32 @@ public static boolean IsWindows7SP1OrGreater() { * Windows 8 version. */ public static boolean IsWindows8OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN8), LOBYTE(WinNT.WIN32_WINNT_WIN8), 0); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WIN8 >>> 8), (byte) Kernel32.WIN32_WINNT_WIN8, 0); } /** * @return true if the current OS version matches, or is greater than, the - * Windows 8.1 version. For Windows 10, IsWindows8Point1OrGreater - * returns false unless the application contains a manifest that - * includes a compatibility section that contains the GUIDs that - * designate Windows 8.1 and/or Windows 10. + * Windows 8.1 version. For Windows 8.1 and/or Windows 10, + * {@link #IsWindows8Point1OrGreater} returns false unless the + * application contains a manifest that includes a compatibility + * section that contains the GUIDs that designate Windows 8.1 and/or + * Windows 10. */ public static boolean IsWindows8Point1OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WINBLUE), LOBYTE(WinNT.WIN32_WINNT_WINBLUE), 0); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WINBLUE >>> 8), + (byte) Kernel32.WIN32_WINNT_WINBLUE, 0); } /** * @return true if the current OS version matches, or is greater than, the - * Windows 10 version. For Windows 10, IsWindows10OrGreater returns - * false unless the application contains a manifest that includes a - * compatibility section that contains the GUID that designates - * Windows 10. + * Windows 10 version. For Windows 10, + * {@link #IsWindows8Point1OrGreater} returns false unless the + * application contains a manifest that includes a compatibility + * section that contains the GUID that designates Windows 10. */ public static boolean IsWindows10OrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(WinNT.WIN32_WINNT_WIN10), LOBYTE(WinNT.WIN32_WINNT_WIN10), 0); + return IsWindowsVersionOrGreater((byte) (Kernel32.WIN32_WINNT_WIN10 >>> 8), (byte) Kernel32.WIN32_WINNT_WIN10, + 0); } /** @@ -183,31 +193,10 @@ public static boolean IsWindowsServer() { osvi.dwOSVersionInfoSize = new DWORD(osvi.size()); osvi.wProductType = WinNT.VER_NT_WORKSTATION; - long dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(0, WinNT.VER_PRODUCT_TYPE, WinNT.VER_EQUAL); + long dwlConditionMask = Kernel32.INSTANCE.VerSetConditionMask(0, WinNT.VER_PRODUCT_TYPE, + (byte) WinNT.VER_EQUAL); return !Kernel32.INSTANCE.VerifyVersionInfoW(osvi, WinNT.VER_PRODUCT_TYPE, dwlConditionMask); } - - /** - * Get the high byte - * - * @param word - * a two-byte value - * @return The most significant byte - */ - private static byte HIBYTE(short word) { - return (byte) ((word >> 8) & 0xFF); - } - - /** - * Get the low byte - * - * @param word - * a two-byte value - * @return The least significant byte - */ - private static byte LOBYTE(short word) { - return (byte) word; - } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 860d95a02d..315f8e9b90 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -1988,13 +1988,13 @@ public byte getProductType() { } } - byte VER_EQUAL = 1; - byte VER_GREATER = 2; - byte VER_GREATER_EQUAL = 3; - byte VER_LESS = 4; - byte VER_LESS_EQUAL = 5; - byte VER_AND = 6; - byte VER_OR = 7; + int VER_EQUAL = 1; + int VER_GREATER = 2; + int VER_GREATER_EQUAL = 3; + int VER_LESS = 4; + int VER_LESS_EQUAL = 5; + int VER_AND = 6; + int VER_OR = 7; int VER_CONDITION_MASK = 7; int VER_NUM_BITS_PER_CONDITION_MASK = 3; From 5611ae60cd1b4429efa19c966cadd711171ae74e Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Wed, 9 Jan 2019 18:55:57 -0800 Subject: [PATCH 3/3] Comments and license header --- .../jna/platform/win32/VersionHelpers.java | 16 +++++++++++++ .../platform/win32/VersionHelpersTest.java | 23 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java b/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java index 2280116aae..ae5b9aba27 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java @@ -35,6 +35,10 @@ * robust means to determine the operating system version. */ public class VersionHelpers { + /* + * Code in this class is an attempt to faithfully port the inline macros in + * the versionhelpers.h header file of the Windows 10 SDK. + */ /** * This function is useful in confirming a version of Windows Server that @@ -70,6 +74,15 @@ public static boolean IsWindowsVersionOrGreater(int wMajorVersion, int wMinorVer WinNT.VER_MAJORVERSION | WinNT.VER_MINORVERSION | WinNT.VER_SERVICEPACKMAJOR, dwlConditionMask); } + /* + * The constants Kernel32.WIN32_WINNT_* are 2-byte encodings of windows + * version numbers, for example Windows XP is version 5.1 and is encoded as + * 0x0501. To pass to IsWindowsVersionOrGreater, we pass the HIBYTE (e.g., + * 0x05) as the first argument and LOBYTE (e.g., 0x01) as the second. To get + * the high byte of a short, we shift right 8 bits and cast to byte, e.g., + * (byte) (word>>>8); to get the low byte wse simply cast to byte. + */ + /** * @return true if the current OS version matches, or is greater than, the * Windows XP version. @@ -189,6 +202,9 @@ public static boolean IsWindows10OrGreater() { * @return true if the current OS is a Windows Server release. */ public static boolean IsWindowsServer() { + // This should properly be OSVERSIONINFOEXW which is not defined in JNA. + // The OSVERSIONINFOEX structure in JNA is the (W) Unicode-compliant + // version. OSVERSIONINFOEX osvi = new OSVERSIONINFOEX(); osvi.dwOSVersionInfoSize = new DWORD(osvi.size()); osvi.wProductType = WinNT.VER_NT_WORKSTATION; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java b/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java index 76651693ac..ccc93dd0b3 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/VersionHelpersTest.java @@ -1,3 +1,26 @@ +/* Copyright (c) 2019 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ package com.sun.jna.platform.win32; import static org.junit.Assert.assertFalse;