diff --git a/CHANGES.md b/CHANGES.md index 8ff77416d2..65be473d70 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -52,6 +52,7 @@ Bug Fixes * [#578](https://github.com/java-native-access/jna/pull/578): Fix COM CallbackHandlers, allow usage of VARIANTs directly in c.s.j.p.w.COM.util.ProxyObject and fix native memory leak in c.s.j.p.w.COM.util.ProxyObject - [@matthiasblaesing](https://github.com/matthiasblaesing) * [#601](https://github.com/java-native-access/jna/pull/601): Remove COMThread and COM initialization from objects and require callers to initialize COM themselves. Asserts are added to guard correct usage. - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#602] https://github.com/java-native-access/jna/pull/602): Make sure SID related memory is properly released once no longer required [@lgoldstein](https://github.com/lgoldstein). +* [#610](https://github.com/java-native-access/jna/pull/610): Fixed issue #604: Kernel32#GetLastError() always returns ERROR_SUCCESS [@lgoldstein](https://github.com/lgoldstein). Release 4.2.1 ============= diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java index 5db76e98b1..57cbb19090 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -61,6 +61,12 @@ public static void main(String[] args) { junit.textui.TestRunner.run(Kernel32Test.class); } + // see https://github.com/java-native-access/jna/issues/604 + public void testGetLastErrorNativeLibraryOverride() { + assertFalse("Unexpected success", Kernel32.INSTANCE.CloseHandle(null)); + assertEquals("Mismatched error code", WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + } + // see https://github.com/twall/jna/issues/482 public void testNoDuplicateMethodsNames() { Collection dupSet = AbstractWin32TestSupport.detectDuplicateMethods(Kernel32.class); @@ -295,11 +301,10 @@ public void testGetCurrentThreadId() { public void testGetCurrentThread() { HANDLE h = Kernel32.INSTANCE.GetCurrentThread(); - assertNotNull(h); - assertFalse(h.equals(0)); - // CloseHandle does not need to be called for a thread handle - assertFalse(Kernel32.INSTANCE.CloseHandle(h)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + assertNotNull("No current thread handle", h); + assertFalse("Null current thread handle", h.equals(0)); + // Calling the CloseHandle function with this handle has no effect + assertTrue(Kernel32.INSTANCE.CloseHandle(h)); } public void testOpenThread() { @@ -316,11 +321,10 @@ public void testGetCurrentProcessId() { public void testGetCurrentProcess() { HANDLE h = Kernel32.INSTANCE.GetCurrentProcess(); - assertNotNull(h); - assertFalse(h.equals(0)); - // CloseHandle does not need to be called for a process handle - assertFalse(Kernel32.INSTANCE.CloseHandle(h)); - assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); + assertNotNull("No current process handle", h); + assertFalse("Null current process handle", h.equals(0)); + // Calling the CloseHandle function with a pseudo handle has no effect + assertTrue(Kernel32.INSTANCE.CloseHandle(h)); } public void testOpenProcess() { @@ -332,8 +336,9 @@ public void testOpenProcess() { } public void testQueryFullProcessImageName() { - HANDLE h = Kernel32.INSTANCE.OpenProcess(0, false, Kernel32.INSTANCE.GetCurrentProcessId()); - assertNotNull("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process handle", h); + int pid = Kernel32.INSTANCE.GetCurrentProcessId(); + HANDLE h = Kernel32.INSTANCE.OpenProcess(0, false, pid); + assertNotNull("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process ID=" + pid + " handle", h); try { char[] path = new char[WinDef.MAX_PATH]; diff --git a/src/com/sun/jna/NativeLibrary.java b/src/com/sun/jna/NativeLibrary.java index ea753cb222..d2ee5a4e20 100644 --- a/src/com/sun/jna/NativeLibrary.java +++ b/src/com/sun/jna/NativeLibrary.java @@ -109,7 +109,12 @@ private NativeLibrary(String libraryName, String libraryPath, long handle, Map returnType, boolean b) { + Object invoke(Object[] args, Class returnType, boolean b, int fixedArgs) { + return Integer.valueOf(Native.getLastError()); + } + + @Override + Object invoke(Method invokingMethod, Class[] paramTypes, Class returnType, Object[] inArgs, Map options) { return Integer.valueOf(Native.getLastError()); } };