{"record":{"id":"093b2416dffb6624","repo":"java-native-access/jna","slug":"win32exception-from-native-getlasterror-after-loadresource","errorCode":null,"errorMessage":"Win32Exception from native GetLastError after LoadResource failed","messagePattern":"Win32Exception from native GetLastError after LoadResource failed","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":1017,"sourceCode":"            }\n\n            Pointer n = null;\n            try {\n                n = new Pointer(Long.parseLong(name));\n            } catch (NumberFormatException e) {\n                n = new Memory(Native.WCHAR_SIZE * (name.length() + 1));\n                n.setWideString(0, name);\n            }\n\n            HRSRC hrsrc = Kernel32.INSTANCE.FindResource(target, n, t);\n            if (hrsrc == null) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            // according to MSDN, on 32 bit Windows or newer, calling FreeResource() is not necessary - and in fact does nothing but return false.\n            HANDLE loaded = Kernel32.INSTANCE.LoadResource(target, hrsrc);\n            if (loaded == null) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            length = Kernel32.INSTANCE.SizeofResource(target, hrsrc);\n            if (length == 0) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            // MSDN: It is not necessary to unlock resources because the system automatically deletes them when the process that created them terminates.\n            // MSDN does not say that LockResource sets GetLastError\n            start = Kernel32.INSTANCE.LockResource(loaded);\n            if (start == null) {\n                throw new IllegalStateException(\"LockResource returned null.\");\n            }\n            // have to capture it into a byte array before you free the library, otherwise bad things happen.\n            results = start.getByteArray(0, length);\n        } catch (Win32Exception we) {\n            err = we;\n        } finally {","sourceCodeStart":999,"sourceCodeEnd":1035,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L999-L1035","documentation":"Kernel32Util throws this Win32Exception when Kernel32.INSTANCE.LoadResource returns null after a successful FindResource. The native GetLastError code is wrapped, surfacing why the resource handle could not be loaded (e.g. the module handle became invalid or the resource data is corrupt).","triggerScenarios":"Calling Kernel32Util.getResource(...) where FindResource succeeded (returned a valid HRSRC) but LoadResource(target, hrsrc) fails, typically because the target module handle is invalid, the library was unloaded concurrently, or the resource data is damaged.","commonSituations":"Freeing/FreeLibrary the module from another thread while getResource runs; passing an HMODULE from a module that failed to fully load as a datafile; corrupt binaries (truncated downloads).","solutions":["Ensure the module handle stays valid (do not call FreeLibrary while reading resources)","Catch Win32Exception and log errorCode to identify the native cause (e.g. ERROR_INVALID_HANDLE 6)","Re-load the module with LoadLibraryEx(path, null, LOAD_LIBRARY_AS_DATAFILE) and retry","Verify the binary is not truncated/corrupt (checksum, file size)"],"exampleFix":"// before\nHANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);\nbyte[] data = Kernel32Util.getResource(h, type, name);\nKernel32.INSTANCE.FreeLibrary(h); // freed while/after use\n// after\nHANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);\ntry {\n    byte[] data = Kernel32Util.getResource(h, type, name);\n} finally {\n    Kernel32.INSTANCE.FreeLibrary(h);\n}","handlingStrategy":"try-catch","validationCode":"HANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);\nif (h == null) throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n// keep h referenced until getResource completes","typeGuard":"boolean isValidHandle(HANDLE h) { return h != null && !Native.INVALID_HANDLE_VALUE.equals(h); }","tryCatchPattern":"try {\n    byte[] data = Kernel32Util.getResource(h, type, name);\n} catch (Win32Exception e) {\n    log.warn(\"LoadResource failed, native code=\" + e.getErrorCode(), e);\n    throw e;\n}","preventionTips":["Never FreeLibrary a module while resource extraction is in flight","Load the module as a datafile in the same scope that reads the resource","Verify the binary is not truncated (compare size/checksum)","Keep a single HMODULE instance for Find/Load/Size/Lock calls"],"tags":["win32","jni","native","resources"],"backgroundTag":"api-error-response","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}