diff --git a/CHANGES.md b/CHANGES.md
index 09ebd6b588..8f6cc65afb 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -19,6 +19,7 @@ Features
* [#1200](https://github.com/java-native-access/jna/pull/1200): Add mappings for `libudev` to `c.s.j.p.linux.Udev` - [@dbwiddis](https://github.com/dbwiddis).
* [#1202](https://github.com/java-native-access/jna/pull/1202): Add mappings supporting shared memory including `c.s.j.p.unix.LibCAPI` types `size_t` and `ssize_t`, `c.s.j.p.linux.LibC` methods `munmap()`, `msync()`, and `close()`, `c.s.j.p.unix.LibCUtil` mapping `mmap()` and `ftruncate()`, and `c.s.j.p.linux.LibRT` methods `shm_open()` and `shm_unlink()` - [@dbwiddis](https://github.com/dbwiddis).
* [#1209](https://github.com/java-native-access/jna/pull/1209): Add mappings for `Thread32First` and `Thread32Next` to `c.s.j.p.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis).
+* [#1214](https://github.com/java-native-access/jna/pull/1214): Add mapping for EnumProcesses to `c.s.j.p.win32.Psapi` - [@T-Svensson](https://github.com/T-Svensson/).
Bug Fixes
---------
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java b/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java
index c6c89c5180..b071617531 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java
@@ -266,6 +266,46 @@ public interface Psapi extends StdCallLibrary {
*/
boolean GetPerformanceInfo(PERFORMANCE_INFORMATION pPerformanceInformation, int cb);
+ /**
+ * Retrieves the process identifier for each process object in the system.
+ *
+ * It is a good idea to use a large array, because it is hard to predict
+ * how many processes there will be at the time you call EnumProcesses.
+ *
+ * To determine how many processes were enumerated, divide the
+ * pBytesReturned value by sizeof(DWORD). There is no indication given
+ * when the buffer is too small to store all process identifiers.
+ * Therefore, if pBytesReturned equals cb, consider retrying the call
+ * with a larger array.
+ *
+ * To obtain process handles for the processes whose identifiers you
+ * have just obtained, call the OpenProcess function.
+ *
+ * Starting with Windows 7 and Windows Server 2008 R2, Psapi.h
+ * establishes version numbers for the PSAPI functions. The PSAPI
+ * version number affects the name used to call the function and the
+ * library that a program must load.
+ *
+ * If PSAPI_VERSION is 2 or greater, this function is defined as
+ * K32EnumProcesses in Psapi.h and exported in Kernel32.lib and
+ * Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as
+ * EnumProcesses in Psapi.h and exported in Psapi.lib and Psapi.dll as a
+ * wrapper that calls K32EnumProcesses.
+ *
+ * @param lpidProcess
+ * A pointer to an array that receives the list of process
+ * identifiers
+ * @param cb
+ * The size of the pProcessIds array, in bytes.
+ * @param lpcbNeeded
+ * The number of bytes returned in the pProcessIds array.
+ * @return If the function succeeds, the return value is nonzero. If the
+ * function fails, the return value is zero. To get extended
+ * error information, call GetLastError.
+ * @see MSDN
+ */
+ boolean EnumProcesses(int[] lpidProcess, int cb, IntByReference lpcbNeeded);
+
@FieldOrder({"lpBaseOfDll", "SizeOfImage", "EntryPoint"})
class MODULEINFO extends Structure {
public Pointer EntryPoint;
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java
new file mode 100644
index 0000000000..0ec32cb191
--- /dev/null
+++ b/contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java
@@ -0,0 +1,58 @@
+/* Copyright (c) 2020 Torbjörn Svensson, All Rights Reserved
+ *
+ * The contents of this file is dual-licensed under 2
+ * alternative Open Source/Free licenses: LGPL 2.1 or later and
+ * Apache License 2.0. (starting with JNA version 4.0.0).
+ *
+ * You can freely decide which license you want to apply to
+ * the project.
+ *
+ * You may obtain a copy of the LGPL License at:
+ *
+ * http://www.gnu.org/licenses/licenses.html
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "LGPL2.1".
+ *
+ * You may obtain a copy of the Apache License at:
+ *
+ * http://www.apache.org/licenses/
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "AL2.0".
+ */
+package com.sun.jna.platform.win32;
+
+import com.sun.jna.Native;
+import com.sun.jna.platform.win32.WinDef.DWORD;
+import com.sun.jna.ptr.IntByReference;
+
+/**
+ * Psapi utility API.
+ *
+ * @author Torbjörn Svensson, azoff[at]svenskalinuxforeninen.se
+ */
+public abstract class PsapiUtil {
+
+ /**
+ * Retrieves the process identifier for each process object in the system.
+ *
+ * @return Array of pids
+ */
+ public static int[] enumProcesses() {
+ int size = 0;
+ int[] lpidProcess = null;
+ IntByReference lpcbNeeded = new IntByReference();
+ do {
+ size = size + 1024;
+ lpidProcess = new int[size];
+ if (!Psapi.INSTANCE.EnumProcesses(lpidProcess, size * DWORD.SIZE, lpcbNeeded)) {
+ throw new Win32Exception(Native.getLastError());
+ }
+ } while (size == lpcbNeeded.getValue() / DWORD.SIZE);
+
+ int[] result = new int[lpcbNeeded.getValue() / DWORD.SIZE];
+ System.arraycopy(lpidProcess, 0, result, 0, result.length);
+ return result;
+ }
+}
diff --git a/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java b/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java
index 44404e896b..dcf30830d7 100644
--- a/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java
+++ b/contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java
@@ -248,4 +248,31 @@ public void testGetPerformanceInfo() {
assertTrue(Psapi.INSTANCE.GetPerformanceInfo(perfInfo, perfInfo.size()));
assertTrue(perfInfo.ProcessCount.intValue() > 0);
}
+
+ @Test
+ public void EnumProcesses() {
+ int size = 0;
+ int[] lpidProcess = null;
+ IntByReference lpcbNeeded = new IntByReference();
+ do {
+ size = size + 1024;
+ lpidProcess = new int[size];
+ if (!Psapi.INSTANCE.EnumProcesses(lpidProcess, size * DWORD.SIZE, lpcbNeeded)) {
+ throw new Win32Exception(Native.getLastError());
+ }
+ } while (size == lpcbNeeded.getValue());
+
+ assertTrue("Size of pid list in bytes should be a multiple of " + DWORD.SIZE, lpcbNeeded.getValue() % DWORD.SIZE == 0);
+ assertTrue("List should contain atleast one pid", lpcbNeeded.getValue() > DWORD.SIZE);
+
+ int myPid = Kernel32.INSTANCE.GetCurrentProcessId();
+ boolean foundMyPid = false;
+ for (int i = 0; i < lpcbNeeded.getValue() / DWORD.SIZE; i++) {
+ if (lpidProcess[i] == myPid) {
+ foundMyPid = true;
+ break;
+ }
+ }
+ assertTrue("List should contain my pid", foundMyPid);
+ }
}
diff --git a/contrib/platform/test/com/sun/jna/platform/win32/PsapiUtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/PsapiUtilTest.java
new file mode 100644
index 0000000000..62ff5fc627
--- /dev/null
+++ b/contrib/platform/test/com/sun/jna/platform/win32/PsapiUtilTest.java
@@ -0,0 +1,52 @@
+/* Copyright (c) 2020 Torbjörn Svensson, All Rights Reserved
+ *
+ * The contents of this file is dual-licensed under 2
+ * alternative Open Source/Free licenses: LGPL 2.1 or later and
+ * Apache License 2.0. (starting with JNA version 4.0.0).
+ *
+ * You can freely decide which license you want to apply to
+ * the project.
+ *
+ * You may obtain a copy of the LGPL License at:
+ *
+ * http://www.gnu.org/licenses/licenses.html
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "LGPL2.1".
+ *
+ * You may obtain a copy of the Apache License at:
+ *
+ * http://www.apache.org/licenses/
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "AL2.0".
+ */
+package com.sun.jna.platform.win32;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Applies API tests on {@link PsapiUtil}.
+ *
+ * @author Torbjörn Svensson, azoff[at]svenskalinuxforeninen.se
+ */
+public class PsapiUtilTest {
+ @Test
+ public void enumProcesses() {
+ int[] pids = PsapiUtil.enumProcesses();
+
+ assertTrue("List should contain atleast one pid", pids.length > 0);
+
+ int myPid = Kernel32.INSTANCE.GetCurrentProcessId();
+ boolean foundMyPid = false;
+ for (int i = 0; i < pids.length; i++) {
+ if (pids[i] == myPid) {
+ foundMyPid = true;
+ break;
+ }
+ }
+ assertTrue("List should contain my pid", foundMyPid);
+ }
+}