21
21
import java .lang .foreign .*;
22
22
23
23
public class WindowsVersionHelper {
24
-
25
- // Constants for VerSetConditionMask dwTypeBitMask parameter
26
24
private static final int VER_MINORVERSION = 0x0000001 ;
27
25
private static final int VER_MAJORVERSION = 0x0000002 ;
28
26
private static final int VER_SERVICEPACKMAJOR = 0x0000020 ;
29
-
30
- // Constants for VerSetConditionMask dwCondition parameter
31
27
private static final byte VER_GREATER_EQUAL = 3 ;
32
28
33
29
private static final GroupLayout OSVERSIONINFOEXW_LAYOUT = MemoryLayout .structLayout (
@@ -48,30 +44,30 @@ public class WindowsVersionHelper {
48
44
49
45
50
46
public static boolean IsWindows10OrGreater () throws Throwable {
51
- return isWindowsVersionOrGreater (10 ,0 , 0 );
47
+ return isWindowsVersionOrGreater (10 , 0 , 0 );
52
48
}
53
49
54
50
public static boolean isWindowsVersionOrGreater (int major , int minor , int servicePackMajor ) throws Throwable {
55
51
try (Arena arena = Arena .ofConfined ()) {
56
52
SymbolLookup kernel32 = SymbolLookup .libraryLookup ("kernel32.dll" , Arena .global ());
57
53
58
- var NATIVE_LINKER = Linker .nativeLinker ();
59
- var MH_VerSetConditionMask = NATIVE_LINKER .downcallHandle (
54
+ var nativeLinker = Linker .nativeLinker ();
55
+ var MH_VerSetConditionMask = nativeLinker .downcallHandle (
60
56
kernel32 .find ("VerSetConditionMask" ).orElseThrow (() -> new UnsatisfiedLinkError ("VerSetConditionMask not found" )),
61
57
FunctionDescriptor .of (ValueLayout .JAVA_LONG , ValueLayout .JAVA_LONG , ValueLayout .JAVA_INT , ValueLayout .JAVA_BYTE )
62
58
);
63
59
64
- var MH_VerifyVersionInfoW = NATIVE_LINKER .downcallHandle (
60
+ var MH_VerifyVersionInfoW = nativeLinker .downcallHandle (
65
61
kernel32 .find ("VerifyVersionInfoW" ).orElseThrow (() -> new UnsatisfiedLinkError ("VerifyVersionInfoW not found" )),
66
62
FunctionDescriptor .of (ValueLayout .JAVA_INT , ValueLayout .ADDRESS , ValueLayout .JAVA_INT , ValueLayout .JAVA_LONG )
67
63
);
68
- MemorySegment osvi = arena .allocate (OSVERSIONINFOEXW_LAYOUT );
69
64
70
65
var VH_dwOSVersionInfoSize = OSVERSIONINFOEXW_LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("dwOSVersionInfoSize" ));
71
66
var VH_dwMajorVersion = OSVERSIONINFOEXW_LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("dwMajorVersion" ));
72
67
var VH_dwMinorVersion = OSVERSIONINFOEXW_LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("dwMinorVersion" ));
73
68
var VH_wServicePackMajor = OSVERSIONINFOEXW_LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("wServicePackMajor" ));
74
69
70
+ var osvi = arena .allocate (OSVERSIONINFOEXW_LAYOUT );
75
71
VH_dwOSVersionInfoSize .set (osvi , 0L , (int ) OSVERSIONINFOEXW_STRUCT_SIZE );
76
72
VH_dwMajorVersion .set (osvi , 0L , major );
77
73
VH_dwMinorVersion .set (osvi , 0L , minor );
@@ -82,9 +78,7 @@ public static boolean isWindowsVersionOrGreater(int major, int minor, int servic
82
78
conditionMask = (long ) MH_VerSetConditionMask .invokeExact (conditionMask , VER_MINORVERSION , VER_GREATER_EQUAL );
83
79
conditionMask = (long ) MH_VerSetConditionMask .invokeExact (conditionMask , VER_SERVICEPACKMAJOR , VER_GREATER_EQUAL );
84
80
85
- int typeMask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR ;
86
-
87
- int result = (int ) MH_VerifyVersionInfoW .invokeExact (osvi , typeMask , conditionMask );
81
+ int result = (int ) MH_VerifyVersionInfoW .invokeExact (osvi , VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR , conditionMask );
88
82
89
83
return result != 0 ;
90
84
}
@@ -107,7 +101,8 @@ public static void main(String[] args) {
107
101
boolean isFutureVersion = v .isWindowsVersionOrGreater (99 , 0 , 0 );
108
102
System .out .println ("Is current OS Windows 99.0 SP0 or greater? " + isFutureVersion );
109
103
110
- } catch (Throwable t ) {
104
+ }
105
+ catch (Throwable t ) {
111
106
System .err .println ("An error occurred during the Windows version check:" );
112
107
t .printStackTrace ();
113
108
}
0 commit comments