java-native-access/jna · error · Win32Exception

Win32Exception from native GetLastError after EnumResourceNa

Error message

Win32Exception from native GetLastError after EnumResourceNames failed

What it means

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.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:1137

            for (final String typeName : types) {
                result.put(typeName, new ArrayList<String>());

                // simulate MAKEINTRESOURCE macro in WinUser.h
                // basically, if the value passed in can be parsed as a number then convert it into one and run with that.
                // otherwise, assume it's a string and construct a pointer to said string.
                Pointer pointer = null;
                try {
                    pointer = new Pointer(Long.parseLong(typeName));
                } catch (NumberFormatException e) {
                    pointer = new Memory(Native.WCHAR_SIZE * (typeName.length() + 1));
                    pointer.setWideString(0, typeName);
                }

                boolean callResult = Kernel32.INSTANCE.EnumResourceNames(target, pointer, ernp, null);

                if (!callResult) {
                    throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
                }
            }
        } catch (Win32Exception e) {
            err = e;
        } finally {
            // from what I can tell on MSDN, the only thing that needs cleanup
            // on this is the HMODULE from LoadLibrary
            if (target != null) {
                if (!Kernel32.INSTANCE.FreeLibrary(target)) {
                    Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError());
                    if (err != null) {
                        we.addSuppressedReflected(err);
                    }
                    throw we;
                }
            }
        }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Catch Win32Exception per type and continue enumerating remaining types instead of failing the whole map
  2. Verify the type name pointer encoding matches the resource storage (integer ID vs string)
  3. Ensure the module handle stays valid for the full enumeration (no concurrent FreeLibrary)
  4. Inspect errorCode for ERROR_INVALID_HANDLE (6) and re-load the module before retrying

Example fix

// before
for (String typeName : types) {
    result.put(typeName, Kernel32Util.enumNames(target, typeName)); // throws on one bad type
}
// after
for (String typeName : types) {
    try {
        result.put(typeName, Kernel32Util.enumNames(target, typeName));
    } catch (Win32Exception e) {
        result.put(typeName, Collections.emptyList()); // skip unreadable type
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure module handle validity before per-type enumeration
HANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);
if (h == null) throw new Win32Exception(Kernel32.INSTANCE.GetLastError());

Type guard

null

Try / catch

try {
    Map<String, List<String>> names = Kernel32Util.getResourceNames(path);
} catch (Win32Exception e) {
    log.warn("EnumResourceNames failed for a type; code=" + e.getErrorCode(), e);
    // degrade: return the partial result or empty map instead of failing
}

Prevention

When it happens

Trigger: 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.

Common situations: Modules with large or unusual resource trees, resource types whose MAKEINTRESOURCE encoding (integer vs string) is mishandled, concurrent module unload during enumeration.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/ebb5dbdf341823e4. Report an issue: GitHub.