{"record":{"id":"bb1904094cea79e9","repo":"java-native-access/jna","slug":"win32exception-from-native-getlasterror-after-findresource","errorCode":null,"errorMessage":"Win32Exception from native GetLastError after FindResource failed","messagePattern":"Win32Exception from native GetLastError after FindResource failed","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":1011,"sourceCode":"            Pointer t = null;\n            try {\n                t = new Pointer(Long.parseLong(type));\n            } catch (NumberFormatException e) {\n                t = new Memory(Native.WCHAR_SIZE * (type.length() + 1));\n                t.setWideString(0, type);\n            }\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.\");","sourceCodeStart":993,"sourceCodeEnd":1029,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L993-L1029","documentation":"Kernel32Util throws this Win32Exception when Kernel32.INSTANCE.FindResource returns null while looking up a resource in a loaded module. GetLastError is read immediately after the native call and its code is wrapped into a Win32Exception, so the exception's error code is the native Win32 error (e.g. ERROR_RESOURCE_TYPE_NOT_FOUND 1813 / ERROR_RESOURCE_NAME_NOT_FOUND 1814). It means the requested resource type/name could not be located in the target module.","triggerScenarios":"Calling Kernel32Util.getResource(target, resType, resName, langId) (or overload) where the module contains no resource matching the given type and name, e.g. requesting a VERSIONINFO ('#1') from a DLL that has no version resource, or passing a string name when the resource is stored under an integer ID.","commonSituations":"Passing a plain executable path whose resources use integer IDs while the caller passes names (or vice versa), querying a resource in a library that was stripped of resources, typos in resource type/name constants, wrong language ID variant.","solutions":["Check the actual resource names/types present via Kernel32Util.getResourceNames(path) before calling getResource","Use MAKEINTRESOURCE-style integer IDs (new Pointer(id)) when the resource is stored by integer ID instead of a name string","Verify the module path points to the right binary that actually contains the resource","Inspect the Win32Exception's errorCode for ERROR_RESOURCE_TYPE_NOT_FOUND (1813) or ERROR_RESOURCE_NAME_NOT_FOUND (1814) and adjust the query accordingly"],"exampleFix":"// before\nbyte[] data = Kernel32Util.getResource(path, \"VERSIONINFO\", \"#1\");\n// after\nMap<String, List<String>> names = Kernel32Util.getResourceNames(path);\nif (names.containsKey(\"VERSIONINFO\")) {\n    byte[] data = Kernel32Util.getResource(path, \"VERSIONINFO\", \"#1\");\n} else {\n    throw new IllegalStateException(\"No VERSIONINFO resource in \" + path);\n}","handlingStrategy":"try-catch","validationCode":"// Java: verify resource exists before extraction\nMap<String, List<String>> names = Kernel32Util.getResourceNames(path);\nif (!names.containsKeyOrDefault) { } // check names.get(\"VERSIONINFO\") contains \"#1\" before getResource","typeGuard":"boolean hasResource(String path, String type, String name) {\n    List<String> n = Kernel32Util.getResourceNames(path).get(type);\n    return n != null && n.contains(name);\n}","tryCatchPattern":"try {\n    byte[] data = Kernel32Util.getResource(target, type, name);\n} catch (Win32Exception e) {\n    if (e.getErrorCode().intValue() == 1813 || e.getErrorCode().intValue() == 1814) {\n        // resource type/name not found — handle absence\n    } else {\n        throw e;\n    }\n}","preventionTips":["Call getResourceNames(path) first and check the type/name exists","Match integer-ID vs string-name encoding to how the resource was compiled","Verify the target binary actually contains the needed resource with a resource viewer","Log the Win32Exception errorCode to distinguish 1813 vs 1814"],"tags":["win32","jni","native","resources"],"backgroundTag":"resource-not-found","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"}