{"record":{"id":"4b3db6de2151a3d6","repo":"java-native-access/jna","slug":"win32exception-from-native-getlasterror-after-4b3db6","errorCode":null,"errorMessage":"Win32Exception from native GetLastError after EnumResourceTypes failed","messagePattern":"Win32Exception from native GetLastError after EnumResourceTypes failed","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":1117,"sourceCode":"                } else {\n                    typeName = type.getWideString(0);\n                }\n\n                if (Pointer.nativeValue(name) < 65535) {\n                    result.get(typeName).add(Pointer.nativeValue(name) + \"\");\n                } else {\n                    result.get(typeName).add(name.getWideString(0));\n                }\n\n                return true;\n            }\n        };\n\n\n        Win32Exception err = null;\n        try {\n            if (!Kernel32.INSTANCE.EnumResourceTypes(target, ertp, null)) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            for (final String typeName : types) {\n                result.put(typeName, new ArrayList<String>());\n\n                // simulate MAKEINTRESOURCE macro in WinUser.h\n                // basically, if the value passed in can be parsed as a number then convert it into one and run with that.\n                // otherwise, assume it's a string and construct a pointer to said string.\n                Pointer pointer = null;\n                try {\n                    pointer = new Pointer(Long.parseLong(typeName));\n                } catch (NumberFormatException e) {\n                    pointer = new Memory(Native.WCHAR_SIZE * (typeName.length() + 1));\n                    pointer.setWideString(0, typeName);\n                }\n\n                boolean callResult = Kernel32.INSTANCE.EnumResourceNames(target, pointer, ernp, null);\n","sourceCodeStart":1099,"sourceCodeEnd":1135,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L1099-L1135","documentation":"Kernel32Util.getResourceNames throws this Win32Exception when Kernel32.INSTANCE.EnumResourceTypes returns false while enumerating the resource types of a module loaded as a datafile. The native GetLastError code indicates why enumeration failed (e.g. ERROR_INVALID_HANDLE 6 if the module handle is invalid, ERROR_NO_MORE_ENTRIES in benign cases).","triggerScenarios":"Calling Kernel32Util.getResourceNames(path) where LoadLibraryEx succeeded but EnumResourceTypes(target, ertp, null) fails — invalid module handle, module unloaded concurrently, or a resource tree the enumerator cannot walk.","commonSituations":"FreeLibrary race conditions from other threads, resource sections stripped by packers/obfuscators, corrupted binaries, or exotic resource layouts in packed executables.","solutions":["Check the Win32Exception errorCode: handle 6 (invalid handle) by re-loading the module","Ensure no other thread frees the module handle during enumeration","If errorCode is ERROR_NO_MORE_ENTRIES-like, treat the module as having no resources and return an empty map","Scan the binary with a resource viewer (e.g. Resource Hacker) to confirm it has resources at all"],"exampleFix":"// before\nMap<String, List<String>> names = Kernel32Util.getResourceNames(path);\n// after\ntry {\n    Map<String, List<String>> names = Kernel32Util.getResourceNames(path);\n} catch (Win32Exception e) {\n    if (e.getErrorCode().intValue() == WinError.ERROR_NO_MORE_ENTRIES) {\n        return Collections.emptyMap(); // module exposes no resource types\n    }\n    throw e;\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 alive for the whole getResourceNames call","typeGuard":"boolean isValidModule(HMODULE h) { return h != null; }","tryCatchPattern":"try {\n    Map<String, List<String>> names = Kernel32Util.getResourceNames(path);\n} catch (Win32Exception e) {\n    if (e.getErrorCode().intValue() == WinError.ERROR_NO_MORE_ENTRIES) {\n        return Collections.emptyMap(); // module has no resource types\n    }\n    throw e;\n}","preventionTips":["Keep the module loaded (no concurrent FreeLibrary) during enumeration","Treat packed/stripped binaries as having no enumerable resources","Check errorCode before deciding it is a hard failure","Verify with a resource viewer that the binary has a resource section"],"tags":["win32","jni","native","enumeration"],"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"}