Skip to content

Commit 2bb2a2b

Browse files
committed
[Win32] Add explicit supported OS version check and set to build 14393
Currently, there is no explicit minimum version required for executing SWT applications. However, some versions are implicitly not supported anymore as library methods are linked that are not present in older OS versions. In addition, we still have some methods dynamically linked and their execution guarded by a version constraint for version that are out of support. In particular, this holds for every Windows version older than build 14393, which is the 1607 update for Windows 10 and the release of Windows Server 2016, the latter being the latest still supported server version of Windows except for the extended support of Windows Server 2012. This change adds an explicit Windows version check at initialization to avoid that applications fail to start with incomprehensible linkage errors but a proper error message. It sets the minimum required Windows version to build 14393. To this end, it adds an additional SWT DLL only for retrieving the OS version, as the required Windows API call will no be executable on unsupported OS versions otherwise, as the ordinary SWT DLL will fail to load before executing the version check. This change also adds a check for SWT libraries being loadable (in particular in terms of a matching OS) on startup for every OS.
1 parent 2a50eae commit 2bb2a2b

File tree

17 files changed

+506
-3
lines changed

17 files changed

+506
-3
lines changed

bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.properties

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ org.eclipse.swt.internal.gtk3.GTK3,../org.eclipse.swt/Eclipse SWT PI/gtk/library
4444
org.eclipse.swt.internal.gtk4.GTK4,../org.eclipse.swt/Eclipse SWT PI/gtk/library/,\
4545
org.eclipse.swt.internal.ole.win32.COM,../org.eclipse.swt/Eclipse SWT PI/win32/library/,\
4646
org.eclipse.swt.internal.win32.OS,../org.eclipse.swt/Eclipse SWT PI/win32/library/,\
47+
org.eclipse.swt.internal.win32.version.OsVersion,../org.eclipse.swt/Eclipse SWT PI/win32/library/,\
4748
org.eclipse.swt.internal.gdip.Gdip,../org.eclipse.swt/Eclipse SWT PI/win32/library/,\
4849
org.eclipse.swt.internal.cairo.Cairo,../org.eclipse.swt/Eclipse SWT PI/cairo/library/,\
4950
org.eclipse.swt.internal.opengl.glx.GLX,../org.eclipse.swt/Eclipse SWT OpenGL/glx/library/,\

bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/Platform.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.internal;
1515

16-
1716
public class Platform {
1817
public static final String PLATFORM = "cocoa"; //$NON-NLS-1$
1918

2019
public static boolean isLoadable () {
2120
return Library.isLoadable ();
2221
}
2322

23+
public static void exitIfNotLoadable() {
24+
if (!Library.isLoadable ()) {
25+
System.err.println("Libraries für platform " + Platform.PLATFORM + " cannot be loaded because of incompatible environment");
26+
System.exit(1);
27+
}
28+
}
29+
2430
}

bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/C.java

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
public class C extends Platform {
1717

1818
static {
19+
exitIfNotLoadable();
1920
Library.loadLibrary ("swt"); //$NON-NLS-1$
2021
}
2122

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/Platform.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@
1414
*******************************************************************************/
1515
package org.eclipse.swt.internal;
1616

17-
1817
public class Platform {
1918
public static final String PLATFORM = "gtk"; //$NON-NLS-1$
2019

2120
public static boolean isLoadable () {
2221
return Library.isLoadable ();
2322
}
2423

24+
public static void exitIfNotLoadable() {
25+
if (!Library.isLoadable ()) {
26+
System.err.println("Libraries für platform " + Platform.PLATFORM + " cannot be loaded because of incompatible environment");
27+
System.exit(1);
28+
}
29+
}
30+
2531
}

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak

+16-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ SWT_OBJS = swt.obj callback.obj c.obj c_stats.obj \
3131
os.obj os_structs.obj os_custom.obj os_stats.obj \
3232
com_structs.obj com.obj com_stats.obj com_custom.obj
3333

34+
OSVERSION_PREFIX = swt-osversion
35+
OSVERSION_LIB = $(OSVERSION_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).dll
36+
OSVERSION_OBJS = osversion.obj osversion_structs.obj osversion_stats.obj
37+
3438
GDIP_PREFIX = swt-gdip
3539
GDIP_LIB = $(GDIP_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).dll
3640
GDIP_LIBS = gdiplus.lib
@@ -57,7 +61,7 @@ dlllflags = -dll /WX
5761
guilibsmt = kernel32.lib ws2_32.lib mswsock.lib advapi32.lib bufferoverflowu.lib user32.lib gdi32.lib comdlg32.lib winspool.lib
5862
olelibsmt = ole32.lib uuid.lib oleaut32.lib $(guilibsmt)
5963

60-
all: make_swt make_awt make_gdip make_wgl
64+
all: make_osversion make_swt make_awt make_gdip make_wgl
6165

6266
.c.obj:
6367
cl $(CFLAGS) $*.c
@@ -74,6 +78,14 @@ make_swt: $(SWT_OBJS) swt.res
7478
link @templrf
7579
del templrf
7680

81+
make_osversion: $(OSVERSION_OBJS) swt_osversion.res
82+
echo $(ldebug) $(dlllflags) $(guilibsmt) >templrf
83+
echo $(OSVERSION_OBJS) >>templrf
84+
echo swt_osversion.res >>templrf
85+
echo -out:$(OSVERSION_LIB) >>templrf
86+
link @templrf
87+
del templrf
88+
7789
make_gdip: $(GDIP_OBJS) swt_gdip.res
7890
echo $(ldebug) $(dlllflags) $(guilibsmt) >templrf
7991
echo $(GDIP_LIBS) >>templrf
@@ -104,6 +116,9 @@ make_wgl: $(WGL_OBJS) swt_wgl.res
104116
swt.res:
105117
rc $(RCFLAGS) -DSWT_ORG_FILENAME=\"$(SWT_LIB)\" -r -fo swt.res swt.rc
106118

119+
swt_osversion.res:
120+
rc $(RCFLAGS) -DSWT_ORG_FILENAME=\"$(OSVERSION_LIB)\" -r -fo swt_osversion.res swt_osversion.rc
121+
107122
swt_gdip.res:
108123
rc $(RCFLAGS) -DSWT_ORG_FILENAME=\"$(GDIP_LIB)\" -r -fo swt_gdip.res swt_gdip.rc
109124

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
/* Note: This file was auto-generated by org.eclipse.swt.tools.internal.JNIGenerator */
16+
/* DO NOT EDIT - your changes will be lost. */
17+
18+
#include "swt.h"
19+
#include "osversion_structs.h"
20+
#include "osversion_stats.h"
21+
22+
#ifndef OsVersion_NATIVE
23+
#define OsVersion_NATIVE(func) Java_org_eclipse_swt_internal_win32_version_OsVersion_##func
24+
#endif
25+
26+
#ifdef _WIN32
27+
/* Many methods don't use their 'env' and 'that' arguments */
28+
#pragma warning (disable: 4100)
29+
#endif
30+
31+
#ifndef NO_OSVERSIONINFOEX_1sizeof
32+
JNIEXPORT jint JNICALL OsVersion_NATIVE(OSVERSIONINFOEX_1sizeof)
33+
(JNIEnv *env, jclass that)
34+
{
35+
jint rc = 0;
36+
OsVersion_NATIVE_ENTER(env, that, OSVERSIONINFOEX_1sizeof_FUNC);
37+
rc = (jint)OSVERSIONINFOEX_sizeof();
38+
OsVersion_NATIVE_EXIT(env, that, OSVERSIONINFOEX_1sizeof_FUNC);
39+
return rc;
40+
}
41+
#endif
42+
43+
#ifndef NO_RtlGetVersion
44+
JNIEXPORT jint JNICALL OsVersion_NATIVE(RtlGetVersion)
45+
(JNIEnv *env, jclass that, jobject arg0)
46+
{
47+
OSVERSIONINFOEX _arg0, *lparg0=NULL;
48+
jint rc = 0;
49+
OsVersion_NATIVE_ENTER(env, that, RtlGetVersion_FUNC);
50+
if (arg0) if ((lparg0 = getOSVERSIONINFOEXFields(env, arg0, &_arg0)) == NULL) goto fail;
51+
/*
52+
rc = (jint)RtlGetVersion(lparg0);
53+
*/
54+
{
55+
OsVersion_LOAD_FUNCTION(fp, RtlGetVersion)
56+
if (fp) {
57+
rc = (jint)((jint (CALLING_CONVENTION*)(OSVERSIONINFOEX *))fp)(lparg0);
58+
}
59+
}
60+
fail:
61+
if (arg0 && lparg0) setOSVERSIONINFOEXFields(env, arg0, lparg0);
62+
OsVersion_NATIVE_EXIT(env, that, RtlGetVersion_FUNC);
63+
return rc;
64+
}
65+
#endif
66+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Vector Informatik GmbH and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
12+
#ifndef INC_osversion_H
13+
#define INC_osversion_H
14+
15+
/*
16+
* Windows headers will sometimes have warnings above level 2, just
17+
* ignore all of them, we can't do anything about it anyway.
18+
*/
19+
#pragma warning(push, 2)
20+
21+
#include <windows.h>
22+
23+
/* Restore warnings */
24+
#pragma warning(pop)
25+
26+
/* Optional custom definitions to exclude some types */
27+
#include "defines.h"
28+
29+
#define OsVersion_LOAD_FUNCTION LOAD_FUNCTION
30+
31+
#include "osversion_custom.h"
32+
33+
#endif /* INC_osversion_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2000, 2008 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
#include "swt.h"
16+
#include "winversion_structs.h"
17+
#include "winversion_stats.h"
18+
19+
#define WinVersion_NATIVE(func) Java_org_eclipse_swt_internal_win32_version_WinVersion_##func
20+
21+
HINSTANCE g_hInstance = NULL;
22+
BOOL WINAPI DllMain(HANDLE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
23+
{
24+
/* Suppress warnings about unreferenced parameters */
25+
(void)lpvReserved;
26+
27+
if (dwReason == DLL_PROCESS_ATTACH) {
28+
if (g_hInstance == NULL) g_hInstance = hInstDLL;
29+
}
30+
return TRUE;
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Vector Informatik GmbH and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
/* Libraries for dynamic loaded functions */
16+
#define RtlGetVersion_LIB "ntdll.dll"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
/* Note: This file was auto-generated by org.eclipse.swt.tools.internal.JNIGenerator */
16+
/* DO NOT EDIT - your changes will be lost. */
17+
18+
#include "swt.h"
19+
#include "osversion_stats.h"
20+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
/* Note: This file was auto-generated by org.eclipse.swt.tools.internal.JNIGenerator */
16+
/* DO NOT EDIT - your changes will be lost. */
17+
18+
#ifndef OsVersion_NATIVE_ENTER
19+
#define OsVersion_NATIVE_ENTER(env, that, func)
20+
#endif
21+
#ifndef OsVersion_NATIVE_EXIT
22+
#define OsVersion_NATIVE_EXIT(env, that, func)
23+
#endif
24+
25+
typedef enum {
26+
OSVERSIONINFOEX_1sizeof_FUNC,
27+
RtlGetVersion_FUNC,
28+
} OsVersion_FUNCS;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
15+
/* Note: This file was auto-generated by org.eclipse.swt.tools.internal.JNIGenerator */
16+
/* DO NOT EDIT - your changes will be lost. */
17+
18+
#include "swt.h"
19+
#include "osversion_structs.h"
20+
21+
#ifndef NO_OSVERSIONINFOEX
22+
typedef struct OSVERSIONINFOEX_FID_CACHE {
23+
int cached;
24+
jclass clazz;
25+
jfieldID dwOSVersionInfoSize, dwMajorVersion, dwMinorVersion, dwBuildNumber, dwPlatformId, szCSDVersion, wServicePackMajor, wServicePackMinor, wSuiteMask, wProductType, wReserved;
26+
} OSVERSIONINFOEX_FID_CACHE;
27+
28+
OSVERSIONINFOEX_FID_CACHE OSVERSIONINFOEXFc;
29+
30+
void cacheOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject)
31+
{
32+
if (OSVERSIONINFOEXFc.cached) return;
33+
OSVERSIONINFOEXFc.clazz = (*env)->GetObjectClass(env, lpObject);
34+
OSVERSIONINFOEXFc.dwOSVersionInfoSize = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwOSVersionInfoSize", "I");
35+
OSVERSIONINFOEXFc.dwMajorVersion = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwMajorVersion", "I");
36+
OSVERSIONINFOEXFc.dwMinorVersion = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwMinorVersion", "I");
37+
OSVERSIONINFOEXFc.dwBuildNumber = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwBuildNumber", "I");
38+
OSVERSIONINFOEXFc.dwPlatformId = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwPlatformId", "I");
39+
OSVERSIONINFOEXFc.szCSDVersion = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "szCSDVersion", "[C");
40+
OSVERSIONINFOEXFc.wServicePackMajor = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wServicePackMajor", "I");
41+
OSVERSIONINFOEXFc.wServicePackMinor = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wServicePackMinor", "I");
42+
OSVERSIONINFOEXFc.wSuiteMask = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wSuiteMask", "I");
43+
OSVERSIONINFOEXFc.wProductType = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wProductType", "I");
44+
OSVERSIONINFOEXFc.wReserved = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wReserved", "I");
45+
OSVERSIONINFOEXFc.cached = 1;
46+
}
47+
48+
OSVERSIONINFOEX *getOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject, OSVERSIONINFOEX *lpStruct)
49+
{
50+
if (!OSVERSIONINFOEXFc.cached) cacheOSVERSIONINFOEXFields(env, lpObject);
51+
lpStruct->dwOSVersionInfoSize = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwOSVersionInfoSize);
52+
lpStruct->dwMajorVersion = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMajorVersion);
53+
lpStruct->dwMinorVersion = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMinorVersion);
54+
lpStruct->dwBuildNumber = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwBuildNumber);
55+
lpStruct->dwPlatformId = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwPlatformId);
56+
{
57+
jcharArray lpObject1 = (jcharArray)(*env)->GetObjectField(env, lpObject, OSVERSIONINFOEXFc.szCSDVersion);
58+
(*env)->GetCharArrayRegion(env, lpObject1, 0, sizeof(lpStruct->szCSDVersion) / sizeof(jchar), (jchar *)lpStruct->szCSDVersion);
59+
}
60+
lpStruct->wServicePackMajor = (WORD)(*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMajor);
61+
lpStruct->wServicePackMinor = (WORD)(*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMinor);
62+
lpStruct->wSuiteMask = (WORD)(*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wSuiteMask);
63+
lpStruct->wProductType = (BYTE)(*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wProductType);
64+
lpStruct->wReserved = (BYTE)(*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wReserved);
65+
return lpStruct;
66+
}
67+
68+
void setOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject, OSVERSIONINFOEX *lpStruct)
69+
{
70+
if (!OSVERSIONINFOEXFc.cached) cacheOSVERSIONINFOEXFields(env, lpObject);
71+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwOSVersionInfoSize, (jint)lpStruct->dwOSVersionInfoSize);
72+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMajorVersion, (jint)lpStruct->dwMajorVersion);
73+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMinorVersion, (jint)lpStruct->dwMinorVersion);
74+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwBuildNumber, (jint)lpStruct->dwBuildNumber);
75+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwPlatformId, (jint)lpStruct->dwPlatformId);
76+
{
77+
jcharArray lpObject1 = (jcharArray)(*env)->GetObjectField(env, lpObject, OSVERSIONINFOEXFc.szCSDVersion);
78+
(*env)->SetCharArrayRegion(env, lpObject1, 0, sizeof(lpStruct->szCSDVersion) / sizeof(jchar), (jchar *)lpStruct->szCSDVersion);
79+
}
80+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMajor, (jint)lpStruct->wServicePackMajor);
81+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMinor, (jint)lpStruct->wServicePackMinor);
82+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wSuiteMask, (jint)lpStruct->wSuiteMask);
83+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wProductType, (jint)lpStruct->wProductType);
84+
(*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wReserved, (jint)lpStruct->wReserved);
85+
}
86+
#endif
87+

0 commit comments

Comments
 (0)