Skip to content

Commit

Permalink
Add Windows Version Helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
dbwiddis committed Jan 6, 2019
1 parent 50af8e8 commit 9849f56
Show file tree
Hide file tree
Showing 4 changed files with 368 additions and 7 deletions.
65 changes: 65 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 i
* 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 i, 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.
*
Expand Down
213 changes: 213 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/VersionHelpers.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

31 changes: 24 additions & 7 deletions contrib/platform/src/com/sun/jna/platform/win32/WinNT.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 9849f56

Please sign in to comment.