Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetProcessTimes and GetProcessIoCounters #959

Merged
merged 2 commits into from
May 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Features
* [#935](https://github.com/java-native-access/jna/pull/935): Add RegConnectRegistry to Advapi32 mappings. - [@cxcorp](https://github.com/cxcorp).
* [#947](https://github.com/java-native-access/jna/pull/947): Allow retrieval of `ACEs` from `com.sun.jna.platform.win32.WinNT.ACL` even if the contained `ACE` is not currently supported - [@jrobhoward](https://github.com/jrobhoward).
* [#954](https://github.com/java-native-access/jna/pull/954): Add `c.s.j.Structure.FieldOrder` annotation to define the field order of a structures without implementing `Structure#getFieldOrder()` - [@idosu](https://github.com/idosu).
* [#959](https://github.com/java-native-access/jna/pull/959): Added `GetProcessTimes` and `GetProcessIoCounters` to `com.sun.jna.platform.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis).

Bug Fixes
---------
Expand Down
52 changes: 52 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
Original file line number Diff line number Diff line change
Expand Up @@ -3596,4 +3596,56 @@ boolean GetVolumePathNamesForVolumeName(String lpszVolumeName,
* information, call GetLastError.</p>
*/
int ExpandEnvironmentStrings(String lpSrc, Pointer lpDst, int nSize);

/**
* Retrieves timing information for the specified process.
*
* @param hProcess
* A handle to the process whose timing information is sought.
* The handle must have the PROCESS_QUERY_INFORMATION or
* PROCESS_QUERY_LIMITED_INFORMATION access right.
* @param lpCreationTime
* A pointer to a FILETIME structure that receives the creation
* time of the process.
* @param lpExitTime
* A pointer to a FILETIME structure that receives the exit time
* of the process. If the process has not exited, the content of
* this structure is undefined.
* @param lpKernelTime
* A pointer to a FILETIME structure that receives the amount of
* time that the process has executed in kernel mode. The time
* that each of the threads of the process has executed in kernel
* mode is determined, and then all of those times are summed
* together to obtain this value.
* @param lpUserTime
* A pointer to a FILETIME structure that receives the amount of
* time that the process has executed in user mode. The time that
* each of the threads of the process has executed in user mode
* is determined, and then all of those times are summed together
* to obtain this value. Note that this value can exceed the
* amount of real time elapsed (between lpCreationTime and
* lpExitTime) if the process executes across multiple CPU cores.
* @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.
*/
boolean GetProcessTimes(HANDLE hProcess, FILETIME lpCreationTime, FILETIME lpExitTime, FILETIME lpKernelTime,
FILETIME lpUserTime);

/**
* Retrieves accounting information for all I/O operations performed by the
* specified process.
*
* @param hProcess
* A handle to the process. The handle must have the
* PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION
* access right.
* @param lpIoCounters
* A pointer to an IO_COUNTERS structure that receives the I/O
* accounting information for the process.
* @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.
*/
boolean GetProcessIoCounters(HANDLE hProcess, WinNT.IO_COUNTERS lpIoCounters);
}
57 changes: 56 additions & 1 deletion contrib/platform/src/com/sun/jna/platform/win32/WinNT.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*/
package com.sun.jna.platform.win32;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -3617,4 +3616,60 @@ public static final int SUBLANGID(int lgid) {
public static final LCID LOCALE_NEUTRAL = LocaleMacros.MAKELCID(LocaleMacros.MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT);

public static final LCID LOCALE_INVARIANT = LocaleMacros.MAKELCID(LocaleMacros.MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT);

/**
* The IO_COUNTERS structure contains I/O accounting information for a
* process or a job object. For a job object, the counters include all
* operations performed by all processes that have ever been associated with
* the job, in addition to all processes currently associated with the job.
*/
public static class IO_COUNTERS extends Structure {
public static final List<String> FIELDS = createFieldsOrder("ReadOperationCount", "WriteOperationCount",
"OtherOperationCount", "ReadTransferCount", "WriteTransferCount", "OtherTransferCount");

/**
* The number of read operations performed.
*/
public long ReadOperationCount;

/**
* The number of write operations performed.
*/
public long WriteOperationCount;

/**
* The number of I/O operations performed, other than read and write
* operations.
*/
public long OtherOperationCount;

/**
* The number of bytes read.
*/
public long ReadTransferCount;

/**
* The number of bytes written.
*/
public long WriteTransferCount;

/**
* The number of bytes transferred during operations other than read and
* write operations.
*/
public long OtherTransferCount;

public IO_COUNTERS() {
super();
}

public IO_COUNTERS(Pointer memory) {
super(memory);
}

@Override
protected List<String> getFieldOrder() {
return FIELDS;
}
}
}
47 changes: 45 additions & 2 deletions contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@
import java.util.List;
import java.util.TimeZone;

import com.sun.jna.Function;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.NativeMappedConverter;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
Expand Down Expand Up @@ -383,6 +381,51 @@ public void testQueryFullProcessImageName() {
}
}

public void testGetProcessTimes() {
int pid = Kernel32.INSTANCE.GetCurrentProcessId();
HANDLE h = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION, false, pid);
assertNotNull("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process ID=" + pid + " handle", h);

try {
FILETIME lpCreationTime = new FILETIME();
FILETIME lpExitTime = new FILETIME();
FILETIME lpKernelTime = new FILETIME();
FILETIME lpUserTime = new FILETIME();
boolean b = Kernel32.INSTANCE.GetProcessTimes(h, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
assertTrue("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process times", b);
// Process must have started before now.
long upTimeMillis = System.currentTimeMillis() - lpCreationTime.toTime();
assertTrue(upTimeMillis >= 0);
// lpExitTime is undefined for a running process, do not test
// Kernel and User time must be < up time (in 100ns ticks)
assertTrue(lpKernelTime.toDWordLong().longValue()
+ lpUserTime.toDWordLong().longValue() < (upTimeMillis + 1L) * 10000L);
} finally {
Kernel32Util.closeHandle(h);
}
}

public void testGetProcessIoCounters() {
int pid = Kernel32.INSTANCE.GetCurrentProcessId();
HANDLE h = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION, false, pid);
assertNotNull("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process ID=" + pid + " handle", h);

try {
WinNT.IO_COUNTERS lpIoCounters = new WinNT.IO_COUNTERS();
boolean b = Kernel32.INSTANCE.GetProcessIoCounters(h, lpIoCounters);
assertTrue("Failed (" + Kernel32.INSTANCE.GetLastError() + ") to get process IO counters", b);
// IO must be nonzero
assertTrue(lpIoCounters.ReadOperationCount >= 0);
assertTrue(lpIoCounters.WriteOperationCount >= 0);
assertTrue(lpIoCounters.OtherOperationCount >= 0);
assertTrue(lpIoCounters.ReadTransferCount >= 0);
assertTrue(lpIoCounters.WriteTransferCount >= 0);
assertTrue(lpIoCounters.OtherTransferCount >= 0);
} finally {
Kernel32Util.closeHandle(h);
}
}

public void testGetTempPath() {
char[] buffer = new char[WinDef.MAX_PATH];
assertTrue(Kernel32.INSTANCE.GetTempPath(new DWORD(WinDef.MAX_PATH), buffer).intValue() > 0);
Expand Down