- Version of JNA and related jars - any since 93ebb9f
- Version and vendor of the java virtual machine - any
- Operating system - any Windows
- System architecture (CPU type, bitness of the JVM) - any
Example snippet:
public interface Dwmapi extends StdCallLibrary {
}
public interface Kernel32_2 extends StdCallLibrary {
Pointer AddDllDirectory(WString NewDirectory);
boolean SetDefaultDllDirectories(int DirectoryFlags);
}
public static void main(String[] args) {
final Kernel32_2 kernel32 = Native.loadLibrary("kernel32", Kernel32_2.class);
final int LOAD_LIBRARY_DEFAULT_DIRS = 0x00001000;
// SetDefaultDllDirectories() is used to supply another DLL search path.
// But it causes JNA to fail later.
Path pluginsPath = Paths.get("plugins").toAbsolutePath();
kernel32.SetDefaultDllDirectories(LOAD_LIBRARY_DEFAULT_DIRS);
kernel32.AddDllDirectory(new WString(pluginsPath.toString()));
// This is perfectly fine, but fails after SetDefaultDllDirectories().
Native.load("dwmapi", Dwmapi.class);
}
Explanation:
- Since 93ebb9f, JNA uses
LOAD_WITH_ALTERED_SEARCH_PATH in LoadLibraryExW().
- MSDN says:
If this value is used and lpFileName specifies a relative path, the behavior is undefined
- When library name is given like
"dwmapi", this is a relative path.
- Windows logs this error, but still tries to proceed - set WinDBG breakpoint to see for yourself:
bp ntdll!LdrpLogRelativePathWithAlteredSearchError "du @rcx" (here, even the function's name is already a proof)
- However, if
SetDefaultDllDirectories() was also used, ntdll!LdrpGetDllPath considers this a fatal error and returns STATUS_INVALID_PARAMETER
TLDR: JNA uses LOAD_WITH_ALTERED_SEARCH_PATH and this is a bug to use it with non-absolute path. However, in most cases it still works, because Windows is kind to interlopers.
Example snippet:
Explanation:
LOAD_WITH_ALTERED_SEARCH_PATHinLoadLibraryExW().If this value is used and lpFileName specifies a relative path, the behavior is undefined"dwmapi", this is a relative path.bp ntdll!LdrpLogRelativePathWithAlteredSearchError "du @rcx"(here, even the function's name is already a proof)SetDefaultDllDirectories()was also used,ntdll!LdrpGetDllPathconsiders this a fatal error and returnsSTATUS_INVALID_PARAMETERTLDR: JNA uses
LOAD_WITH_ALTERED_SEARCH_PATHand this is a bug to use it with non-absolute path. However, in most cases it still works, because Windows is kind to interlopers.