Skip to content

Commit f6670c6

Browse files
Merge pull request #1603 from matthiasblaesing/stabilize
Stabilisation fixes for JNA (and Tests)
2 parents 40f0a12 + d84bfc4 commit f6670c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+302
-134
lines changed

.github/workflows/ci.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ jobs:
3838
brew update
3939
brew install automake --force
4040
brew install libtool --force
41+
brew install texinfo --force
4142
- name: Checkstyle
4243
if: contains(matrix.os, 'ubuntu') && contains(matrix.java, '8')
4344
run: |

.github/workflows/native-libraries-macOS.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
brew update
3030
brew install automake --force
3131
brew install libtool --force
32+
brew install texinfo --force
3233
- name: Build native code
3334
run: |
3435
ant -Dos.prefix=darwin-aarch64

common.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<!-- jnidispatch library release version -->
2424
<property name="jni.major" value="7"/>
2525
<property name="jni.minor" value="0"/>
26-
<property name="jni.revision" value="1"/>
26+
<property name="jni.revision" value="2"/>
2727
<property name="jni.build" value="0"/> <!--${build.number}-->
2828
<property name="jni.version" value="${jni.major}.${jni.minor}.${jni.revision}"/>
2929
<property name="jni.md5" value="5fb98531302accd485c534c452dd952a"/>

contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java

100755100644
+8-5
Original file line numberDiff line numberDiff line change
@@ -1950,12 +1950,14 @@ public void testDecryptFile() throws Exception {
19501950

19511951
// decrypt a read only file
19521952
file.setWritable(false);
1953-
assertFalse(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
1954-
assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError());
1953+
boolean successful = Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0));
1954+
if(! successful) {
1955+
assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError());
19551956

1956-
// decrypt
1957-
file.setWritable(true);
1958-
assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
1957+
// decrypt
1958+
file.setWritable(true);
1959+
assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
1960+
}
19591961

19601962
file.delete();
19611963
}
@@ -2170,4 +2172,5 @@ public void testCreateProcessWithLogonW() {
21702172
// should fail with "the user name or password is incorrect" (error 1326)
21712173
assertEquals("GetLastError() should have returned ERROR_LOGON_FAILURE because the username was bogus.", W32Errors.ERROR_LOGON_FAILURE, Native.getLastError());
21722174
}
2175+
21732176
}

contrib/platform/test/com/sun/jna/platform/win32/COM/ShellApplicationWindowsTest.java

+37-6
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@
2323
package com.sun.jna.platform.win32.COM;
2424

2525
import com.sun.jna.Pointer;
26+
import com.sun.jna.platform.win32.Guid;
2627
import com.sun.jna.platform.win32.Ole32;
27-
import java.util.Iterator;
28-
import java.util.NoSuchElementException;
29-
28+
import com.sun.jna.platform.win32.OleAuto;
3029
import com.sun.jna.platform.win32.Variant;
3130
import com.sun.jna.platform.win32.Variant.VARIANT;
31+
import com.sun.jna.platform.win32.WTypes;
3232
import com.sun.jna.platform.win32.WinDef.LONG;
33+
import com.sun.jna.platform.win32.WinNT;
34+
import com.sun.jna.ptr.PointerByReference;
35+
36+
import java.util.Iterator;
37+
import java.util.NoSuchElementException;
3338

3439
import org.junit.After;
3540
import org.junit.Before;
@@ -39,16 +44,41 @@
3944

4045
public class ShellApplicationWindowsTest {
4146

47+
private static final Guid.CLSID CLSID_InternetExplorer = new Guid.CLSID("{0002DF01-0000-0000-C000-000000000046}");
48+
4249
static {
4350
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
4451
}
4552

53+
private PointerByReference ieApp;
54+
private Dispatch ieDispatch;
55+
4656
@Before
4757
public void setUp() throws Exception {
48-
Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
58+
WinNT.HRESULT hr;
4959

50-
// Launch IE in a manner that should ensure it opens even if the system default browser is Chrome, Firefox, or something else.
51-
Runtime.getRuntime().exec("cmd /c start iexplore.exe -nohome \"about:blank\"");
60+
hr = Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED);
61+
COMUtils.checkRC(hr);
62+
63+
// IE can not be launched directly anymore - so load it via COM
64+
65+
ieApp = new PointerByReference();
66+
hr = Ole32.INSTANCE
67+
.CoCreateInstance(CLSID_InternetExplorer, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ieApp);
68+
COMUtils.checkRC(hr);
69+
70+
ieDispatch = new Dispatch(ieApp.getValue());
71+
InternetExplorer ie = new InternetExplorer(ieDispatch);
72+
73+
ie.setProperty("Visible", true);
74+
COMUtils.checkRC(hr);
75+
76+
VARIANT url = new VARIANT("about:blank");
77+
VARIANT result = ie.invoke("Navigate", url);
78+
OleAuto.INSTANCE.VariantClear(url);
79+
OleAuto.INSTANCE.VariantClear(result);
80+
81+
ieDispatch.Release();
5282

5383
// Even when going to "about:blank", IE still needs a few seconds to start up and add itself to Shell.Application.Windows
5484
// Removing this delay will cause the test to fail even on the fastest boxes I can find.
@@ -85,6 +115,7 @@ public void testWindowsCount()
85115
@After
86116
public void tearDown() throws Exception
87117
{
118+
Ole32.INSTANCE.CoUninitialize();
88119
Runtime.getRuntime().exec("taskkill.exe /f /im iexplore.exe");
89120
}
90121

contrib/platform/test/com/sun/jna/platform/win32/Crypt32Test.java

-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ private void enumerateRootCertificates(HCERTSTORE hCertStore) {
468468
assertNotNull(ctx.pCertInfo.Subject);
469469
assertFalse(decodeName(ctx.pCertInfo.Issuer).isEmpty());
470470
assertFalse(decodeName(ctx.pCertInfo.Subject).isEmpty());
471-
assertEquals(decodeName(ctx.pCertInfo.Issuer), decodeName(ctx.pCertInfo.Subject));
472471
// System.out.printf("%20s: %s%n", "Issuer", decodeName(ctx.pCertInfo.Issuer));
473472
// System.out.printf("%20s: %s%n", "Subject", decodeName(ctx.pCertInfo.Subject));
474473
readCertificates++;

contrib/platform/test/com/sun/jna/platform/win32/IPHlpAPITest.java

+33-8
Original file line numberDiff line numberDiff line change
@@ -163,26 +163,51 @@ public void testGetTcpStatistics() {
163163

164164
@Test
165165
public void testGetUdpStatistics() {
166+
// The Math.min constructs when checking dwNoPorts + dwInErrors in
167+
// comparison to dwInDatagramsis is used, because at least on
168+
// appveyor inconsistent numbers were observed, rendering harder
169+
// constaints useless.
170+
// Sample:
171+
// Datagrams received with errors (332) or no port (2) should be less than inbound datagrams (97).
172+
166173
MIB_UDPSTATS stats = new MIB_UDPSTATS();
167174
int err = IPHlpAPI.INSTANCE.GetUdpStatistics(stats);
168175
assertEquals(String.format("Error %d calling GetUdpStatistics.", err), WinError.NO_ERROR, err);
169-
assertTrue("Datagrams received with errors or no port should be less than inbound datagrams.",
170-
stats.dwNoPorts + stats.dwInErrors <= stats.dwInDatagrams);
176+
assertTrue(
177+
String.format("Datagrams received with errors (%d) or no port (%d) should be less than inbound datagrams (%d).",
178+
stats.dwNoPorts, stats.dwInErrors, stats.dwInDatagrams
179+
),
180+
Math.min(1, stats.dwNoPorts + stats.dwInErrors) <= stats.dwInDatagrams
181+
);
171182

172183
// Above should roughly match IPv4 stats with Ex version
173184
MIB_UDPSTATS stats4 = new MIB_UDPSTATS();
174185
err = IPHlpAPI.INSTANCE.GetUdpStatisticsEx(stats4, IPHlpAPI.AF_INET);
175186
assertEquals(String.format("Error %d calling GetUdpStatistics.", err), WinError.NO_ERROR, err);
176187
assertTrue(
177-
"Datagrams received with no port should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx",
178-
stats.dwNoPorts <= stats4.dwNoPorts);
188+
String.format(
189+
"Datagrams received with no port should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)",
190+
stats.dwNoPorts,stats4.dwNoPorts
191+
),
192+
stats.dwNoPorts <= stats4.dwNoPorts
193+
);
179194
assertTrue(
180-
"Datagrams received with errors should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx",
195+
String.format(
196+
"Datagrams received with errors should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)",
197+
stats.dwInErrors, stats4.dwInErrors
198+
),
181199
stats.dwInErrors <= stats4.dwInErrors);
182-
assertTrue("Datagrams received should not decrease between calls to GetUdpStatistics and GetUdpStatisticsEx",
200+
assertTrue(
201+
String.format(
202+
"Datagrams received should not decrease between calls to GetUdpStatistics (%d) and GetUdpStatisticsEx (%d)",
203+
stats.dwInDatagrams, stats4.dwInDatagrams
204+
),
183205
stats.dwInDatagrams <= stats4.dwInDatagrams);
184-
assertTrue("Datagrams received with errors or no port should be less than inbound datagrams.",
185-
stats4.dwNoPorts + stats4.dwInErrors <= stats4.dwInDatagrams);
206+
assertTrue(
207+
String.format("Datagrams received with errors (%d) or no port (%d) should be less than inbound datagrams (%d). (Ex-Version)",
208+
stats4.dwNoPorts, stats4.dwInErrors, stats4.dwInDatagrams
209+
),
210+
Math.min(1, stats4.dwNoPorts + stats4.dwInErrors) <= stats4.dwInDatagrams);
186211
}
187212

188213
@Test

contrib/platform/test/com/sun/jna/platform/win32/Secur32Test.java

-78
Original file line numberDiff line numberDiff line change
@@ -190,84 +190,6 @@ public void testAcceptSecurityContext() {
190190
phClientCredential));
191191
}
192192

193-
public void testImpersonateRevertSecurityContext() {
194-
// client ----------- acquire outbound credential handle
195-
CredHandle phClientCredential = new CredHandle();
196-
TimeStamp ptsClientExpiry = new TimeStamp();
197-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
198-
null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null,
199-
null, phClientCredential, ptsClientExpiry));
200-
// client ----------- security context
201-
CtxtHandle phClientContext = new CtxtHandle();
202-
IntByReference pfClientContextAttr = new IntByReference();
203-
// server ----------- acquire inbound credential handle
204-
CredHandle phServerCredential = new CredHandle();
205-
TimeStamp ptsServerExpiry = new TimeStamp();
206-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
207-
null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null,
208-
null, phServerCredential, ptsServerExpiry));
209-
// server ----------- security context
210-
CtxtHandle phServerContext = new CtxtHandle();
211-
ManagedSecBufferDesc pbServerToken = null;
212-
IntByReference pfServerContextAttr = new IntByReference();
213-
int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED;
214-
int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED;
215-
do {
216-
// client ----------- initialize security context, produce a client token
217-
// client token returned is always new
218-
ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
219-
if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
220-
// server token is empty the first time
221-
ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null
222-
? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes());
223-
clientRc = Secur32.INSTANCE.InitializeSecurityContext(
224-
phClientCredential,
225-
phClientContext.isNull() ? null : phClientContext,
226-
Advapi32Util.getUserName(),
227-
Sspi.ISC_REQ_CONNECTION,
228-
0,
229-
Sspi.SECURITY_NATIVE_DREP,
230-
pbServerTokenCopy,
231-
0,
232-
phClientContext,
233-
pbClientToken,
234-
pfClientContextAttr,
235-
null);
236-
assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK);
237-
}
238-
// server ----------- accept security context, produce a server token
239-
if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
240-
pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
241-
ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes());
242-
serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential,
243-
phServerContext.isNull() ? null : phServerContext,
244-
pbClientTokenByValue,
245-
Sspi.ISC_REQ_CONNECTION,
246-
Sspi.SECURITY_NATIVE_DREP,
247-
phServerContext,
248-
pbServerToken,
249-
pfServerContextAttr,
250-
ptsServerExpiry);
251-
assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK);
252-
}
253-
} while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK);
254-
// impersonate
255-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext(
256-
phServerContext));
257-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext(
258-
phServerContext));
259-
// release server context
260-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
261-
phServerContext));
262-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
263-
phServerCredential));
264-
// release client context
265-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
266-
phClientContext));
267-
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
268-
phClientCredential));
269-
}
270-
271193
public void testEnumerateSecurityPackages() {
272194
IntByReference pcPackages = new IntByReference();
273195
PSecPkgInfo.ByReference pPackageInfo = new PSecPkgInfo.ByReference();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna.platform.win32;
25+
26+
import com.sun.jna.ptr.IntByReference;
27+
import org.junit.Test;
28+
29+
import static junit.framework.TestCase.assertEquals;
30+
import static junit.framework.TestCase.assertTrue;
31+
32+
33+
public class Secur32_Impersonate_Test {
34+
35+
@Test
36+
public void testImpersonateRevertSecurityContext() {
37+
// client ----------- acquire outbound credential handle
38+
Sspi.CredHandle phClientCredential = new Sspi.CredHandle();
39+
Sspi.TimeStamp ptsClientExpiry = new Sspi.TimeStamp();
40+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
41+
null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null,
42+
null, phClientCredential, ptsClientExpiry));
43+
// client ----------- security context
44+
Sspi.CtxtHandle phClientContext = new Sspi.CtxtHandle();
45+
IntByReference pfClientContextAttr = new IntByReference();
46+
// server ----------- acquire inbound credential handle
47+
Sspi.CredHandle phServerCredential = new Sspi.CredHandle();
48+
Sspi.TimeStamp ptsServerExpiry = new Sspi.TimeStamp();
49+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(
50+
null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null,
51+
null, phServerCredential, ptsServerExpiry));
52+
// server ----------- security context
53+
Sspi.CtxtHandle phServerContext = new Sspi.CtxtHandle();
54+
SspiUtil.ManagedSecBufferDesc pbServerToken = null;
55+
IntByReference pfServerContextAttr = new IntByReference();
56+
int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED;
57+
int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED;
58+
do {
59+
// client ----------- initialize security context, produce a client token
60+
// client token returned is always new
61+
SspiUtil.ManagedSecBufferDesc pbClientToken = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
62+
if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
63+
// server token is empty the first time
64+
SspiUtil.ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null
65+
? null : new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes());
66+
clientRc = Secur32.INSTANCE.InitializeSecurityContext(
67+
phClientCredential,
68+
phClientContext.isNull() ? null : phClientContext,
69+
Advapi32Util.getUserName(),
70+
Sspi.ISC_REQ_CONNECTION,
71+
0,
72+
Sspi.SECURITY_NATIVE_DREP,
73+
pbServerTokenCopy,
74+
0,
75+
phClientContext,
76+
pbClientToken,
77+
pfClientContextAttr,
78+
null);
79+
assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK);
80+
}
81+
// server ----------- accept security context, produce a server token
82+
if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) {
83+
pbServerToken = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
84+
SspiUtil.ManagedSecBufferDesc pbClientTokenByValue = new SspiUtil.ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes());
85+
serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential,
86+
phServerContext.isNull() ? null : phServerContext,
87+
pbClientTokenByValue,
88+
Sspi.ISC_REQ_CONNECTION,
89+
Sspi.SECURITY_NATIVE_DREP,
90+
phServerContext,
91+
pbServerToken,
92+
pfServerContextAttr,
93+
ptsServerExpiry);
94+
assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK);
95+
}
96+
} while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK);
97+
// impersonate
98+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext(
99+
phServerContext));
100+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext(
101+
phServerContext));
102+
// release server context
103+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
104+
phServerContext));
105+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
106+
phServerCredential));
107+
// release client context
108+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(
109+
phClientContext));
110+
assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(
111+
phClientCredential));
112+
}
113+
}

0 commit comments

Comments
 (0)