java-native-access/jna · error · Win32Exception

Win32Exception(Native.getLastError())

Error message

Win32Exception(Native.getLastError())

What it means

PsapiUtil.GetProcessImageFileName resolves a process handle to its image path using PSAPI GetProcessImageFileName in a growing-buffer loop. If the call returns length 0 and GetLastError is anything other than ERROR_INSUFFICIENT_BUFFER, the library throws Win32Exception wrapping the native error code.

Solutions

  1. Verify the HANDLE is valid and the process is still running before calling
  2. Open the process with PROCESS_QUERY_LIMITED_INFORMATION instead of full access to reduce ERROR_ACCESS_DENIED
  3. Read the error code from Win32Exception: ERROR_INVALID_HANDLE -> fix handle lifecycle; ERROR_ACCESS_DENIED -> permissions issue
  4. Catch Win32Exception and fall back to another lookup method (e.g. Kernel32 QueryFullProcessImageName via JNA) if unavailable

Example fix

// before
HANDLE h = Kernel32.INSTANCE.OpenProcess(WinBase.PROCESS_ALL_ACCESS, false, pid);
String path = PsapiUtil.GetProcessImageFileName(h);
// after
HANDLE h = Kernel32.INSTANCE.OpenProcess(WinBase.PROCESS_QUERY_LIMITED_INFORMATION, false, pid);
String path = h == null ? null : PsapiUtil.GetProcessImageFileName(h);
Defensive patterns

Strategy: try-catch

Validate before calling

if (hProcess == null) throw new IllegalArgumentException("process handle required");

Type guard

boolean isOpenHandle(HANDLE h) { return h != null && !WinBase.INVALID_HANDLE_VALUE.equals(h); }

Try / catch

try { return PsapiUtil.GetProcessImageFileName(h); } catch (Win32Exception e) { if (e.getErrorCode() == WinError.ERROR_ACCESS_DENIED) return null; throw e; }

Prevention

When it happens

Trigger: Passing an invalid or closed process handle (ERROR_INVALID_HANDLE), lacking PROCESS_QUERY_INFORMATION rights on the target process (ERROR_ACCESS_DENIED — e.g. protected/system processes), or the process exiting mid-call.

Common situations: Inspecting another user's or a protected process (antivirus, services); holding a handle to a process that has since terminated; opening handles with insufficient access masks (OpenProcess without PROCESS_QUERY_LIMITED_INFORMATION).

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java:82

     *            A handle to the process. The handle must have the
     *            PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION
     *            access right. For more information, see Process Security and
     *            Access Rights. <br>
     *            Windows Server 2003 and Windows XP: The handle must have the
     *            PROCESS_QUERY_INFORMATION access right.
     * @return ame of the executable file for the specified process.
     * @throws Win32Exception in case an error occurs
     * @see <a href="http://msdn.microsoft.com/en-us/library/ms683217(VS.85).aspx">MSDN</a>
     */
    public static String GetProcessImageFileName(HANDLE hProcess) {
        int size = 2048;
        while (true) {
            final char[] filePath = new char[size];
            int length = Psapi.INSTANCE.GetProcessImageFileName(hProcess,
                filePath, filePath.length);
            if(length == 0) {
                if(Native.getLastError() != WinError.ERROR_INSUFFICIENT_BUFFER) {
                    throw new Win32Exception(Native.getLastError());
                }
                size += 2048;
            } else {
                return Native.toString(filePath);
            }
        }
    }
}

View on GitHub (pinned to d036ad9781)