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
- Verify the HANDLE is valid and the process is still running before calling
- Open the process with PROCESS_QUERY_LIMITED_INFORMATION instead of full access to reduce ERROR_ACCESS_DENIED
- Read the error code from Win32Exception: ERROR_INVALID_HANDLE -> fix handle lifecycle; ERROR_ACCESS_DENIED -> permissions issue
- 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
- Open processes with PROCESS_QUERY_LIMITED_INFORMATION to minimize access-denied errors
- Check the process is alive and the handle valid before querying
- Anticipate protected/system processes being unqueryable
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
- Win32Exception(Kernel32.INSTANCE.GetLastError())
- Error occured when trying get Unknown Id
- getUnknownId
- PdhException(result)
- Ras32Exception(err)
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)