{"record":{"id":"ebb5dbdf341823e4","repo":"java-native-access/jna","slug":"win32exception-from-native-getlasterror-after-ebb5db","errorCode":null,"errorMessage":"Win32Exception from native GetLastError after EnumResourceNames failed","messagePattern":"Win32Exception from native GetLastError after EnumResourceNames failed","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":1137,"sourceCode":"\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\n                if (!callResult) {\n                    throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n                }\n            }\n        } catch (Win32Exception e) {\n            err = e;\n        } finally {\n            // from what I can tell on MSDN, the only thing that needs cleanup\n            // on this is the HMODULE from LoadLibrary\n            if (target != null) {\n                if (!Kernel32.INSTANCE.FreeLibrary(target)) {\n                    Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError());\n                    if (err != null) {\n                        we.addSuppressedReflected(err);\n                    }\n                    throw we;\n                }\n            }\n        }\n","sourceCodeStart":1119,"sourceCodeEnd":1155,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L1119-L1155","documentation":"Kernel32Util.getResourceNames throws this Win32Exception when Kernel32.INSTANCE.EnumResourceNames returns false while enumerating resource names for one resource type of the loaded module. The native GetLastError code is wrapped; a return of false with ERROR_SUCCESS or a benign last-error can also occur, but JNA wraps any false return here.","triggerScenarios":"Calling Kernel32Util.getResourceNames(path) where EnumResourceTypes succeeded but a per-type EnumResourceNames(target, pointer, ernp, null) call fails — invalid pointer encoding of the type name, invalid module handle, or enumeration interrupted mid-walk.","commonSituations":"Modules with large or unusual resource trees, resource types whose MAKEINTRESOURCE encoding (integer vs string) is mishandled, concurrent module unload during enumeration.","solutions":["Catch Win32Exception per type and continue enumerating remaining types instead of failing the whole map","Verify the type name pointer encoding matches the resource storage (integer ID vs string)","Ensure the module handle stays valid for the full enumeration (no concurrent FreeLibrary)","Inspect errorCode for ERROR_INVALID_HANDLE (6) and re-load the module before retrying"],"exampleFix":"// before\nfor (String typeName : types) {\n    result.put(typeName, Kernel32Util.enumNames(target, typeName)); // throws on one bad type\n}\n// after\nfor (String typeName : types) {\n    try {\n        result.put(typeName, Kernel32Util.enumNames(target, typeName));\n    } catch (Win32Exception e) {\n        result.put(typeName, Collections.emptyList()); // skip unreadable type\n    }\n}","handlingStrategy":"try-catch","validationCode":"// ensure module handle validity before per-type enumeration\nHANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);\nif (h == null) throw new Win32Exception(Kernel32.INSTANCE.GetLastError());","typeGuard":"null","tryCatchPattern":"try {\n    Map<String, List<String>> names = Kernel32Util.getResourceNames(path);\n} catch (Win32Exception e) {\n    log.warn(\"EnumResourceNames failed for a type; code=\" + e.getErrorCode(), e);\n    // degrade: return the partial result or empty map instead of failing\n}","preventionTips":["Do not free the module while enumeration is running","Match integer-ID vs string type-name encoding (MAKEINTRESOURCE) exactly","Degrade gracefully: skip types that fail enumeration instead of aborting","Check errorCode 6 (invalid handle) and re-load the module on retry"],"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"}