-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kernel#GetLastError() always returns ERROR_SUCCESS - Native#getLastError() returns the correct code #604
Comments
Just found out a few more locations where this happens:
In both these cases (and I am pretty sure all the other) replacing the call to Kernel32.INSTANCE.GetLastError() with Native.getLastError() seems to fix the problem. This makes me wonder whether some bug was introduced in the Kernel32.INSTANCE.GetLastError() in general or just when it comes to ERROR_INSUFFICIENT_BUFFER. I believe this issue warrants further investigation... |
JNA intercepts calls to GetLastError and replaces them with Native.getLastError(). Perhaps that is now not taking place? Sent from my iPhone
|
Not my area of expertise... - definitely worth looking into it. I am baffled that nobody reported this - is there no continuous integration for Windows APIs... ? |
CI doesn’t currently have windows coverage. It’s mostly DB or myself running checks manually.
|
Then it seems there is such a problem - at least on my setup, all the tests that rely on a specific error code to be returned fail with the exact same value (zero) when they call Kernel#GetLastError(). Just out of curiosity, I have modified some of them to use Native#getLastError() and it fixed the problem. |
I’ll try on my system and see if I get the same failures. Which test class(es)?
|
Here are a few examples:
BTW, since I cannot compile the native code, I am using the jnidispatch.dll that I extracted from the checked in lib/native/win32-x86-64.jar and using -Djna.boot.library.path="path/to/folder/containing/jnidispatch" |
Just out of curiosity, I modified the code for Library.Handler#invoke as follows: // Intercept Object methods
...
} else if ("GetLastError".equals(method.getName())
&& ((inArgs == null) || (inArgs.length == 0))) {
return Integer.valueOf(Native.getLastError());
} and it fixed all the tests. |
The original workaround is in NativeLibrary, which does a similar thing around line 108: https://github.com/java-native-access/jna/blob/master/src/com/sun/jna/NativeLibrary.java#L108
|
This is actually the error line - the wrong invoke method is overridden The original line is Function f = new Function(this, "GetLastError", Function.ALT_CONVENTION, encoding) {
@Override
Object invoke(Object[] args, Class<?> returnType, boolean b) {
return Integer.valueOf(Native.getLastError());
}
}; Whereas the correct code should be Function f = new Function(this, "GetLastError", Function.ALT_CONVENTION, encoding) {
@Override
Object invoke(Method invokingMethod, Class<?>[] paramTypes, Class<?> returnType, Object[] inArgs, Map<String, ?> options) {
return Integer.valueOf(Native.getLastError());
}
}; Although to be on the safe side we should probably override both methods. Would you like me to issue a bugfix pull request or do you want to do it. |
BTW, here is the commit that caused the problem: 50eb820 |
Apparently something not caught in some round of refactoring, and likely not covered by a unit test. Please do fix it.
|
Yup, that would be me. Good catch.
|
Should I create a pull request or just fix and push (do I have push rights to the master...?) |
I think there’s still a gap if you direct-map “kernel32”, but it’d likely have to be patched in native code.
|
Waiting on PR-606 and then will apply the fix directly to the master (unless you want me to do it via a separate PR) |
You have rights on the main repo, so you don’t have to work from a fork, but I still prefer you do a branch->PR->merge.
|
Will do so. |
…rns ERROR_SUCCESS
…turns ERROR_SUCCESS
Fixed issue #604: Kernel32#GetLastError() always returns ERROR_SUCCESS
Motivation: We didnt use the latest java releases on the CI Modifications: Update java releases Result: Use latest java releases on the CI
Advapi32Util has 2 methods that wrap the above mentioned API calls - getAccountBySid/Name respectively. The 2 methods work more or less the same - they make an initial call to the LookupAccountXXX method in order to query how much memory they need to allocate. The code expects the initial call to fail with an error code of ERROR_INSUFFICIENT_BUFFER (122). The code checks this by invoking Kernel32.INSTANCE.GetLastError().
Here is the strange bit: the call to LookupAccountXXX does fail, but the reported error code from the Kernel32.INSTANCE.GetLastError() invocation is zero - i.e., success. If I replace the call to Kernel32.INSTANCE.GetLastError() with Native.getLastError(), then indeed ERROR_INSUFFICIENT_BUFFER is reported and the code continues successfully.
This behavior is reproduced every time on my computer - Windows 10 Home edition 64 bit with VS 2015 update 1 - whenever I run Advapi32UtilTest#testGetAccountBySid/Name (respectively).
The text was updated successfully, but these errors were encountered: