1
2
3
4
5 package oshi.driver.windows.registry;
6
7 import java.util.Collection;
8 import java.util.HashMap;
9 import java.util.Map;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import com.sun.jna.Pointer;
15 import com.sun.jna.platform.win32.Kernel32;
16 import com.sun.jna.platform.win32.VersionHelpers;
17 import com.sun.jna.platform.win32.Wtsapi32;
18 import com.sun.jna.platform.win32.Wtsapi32.WTS_PROCESS_INFO_EX;
19 import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiResult;
20
21 import oshi.annotation.concurrent.Immutable;
22 import oshi.annotation.concurrent.ThreadSafe;
23 import oshi.driver.windows.wmi.Win32Process;
24 import oshi.driver.windows.wmi.Win32Process.ProcessXPProperty;
25 import oshi.jna.ByRef.CloseableIntByReference;
26 import oshi.jna.ByRef.CloseablePointerByReference;
27 import oshi.util.platform.windows.WmiUtil;
28
29
30
31
32 @ThreadSafe
33 public final class ProcessWtsData {
34
35 private static final Logger LOG = LoggerFactory.getLogger(ProcessWtsData.class);
36
37 private static final boolean IS_WINDOWS7_OR_GREATER = VersionHelpers.IsWindows7OrGreater();
38
39 private ProcessWtsData() {
40 }
41
42
43
44
45
46
47
48 public static Map<Integer, WtsInfo> queryProcessWtsMap(Collection<Integer> pids) {
49 if (IS_WINDOWS7_OR_GREATER) {
50
51 return queryProcessWtsMapFromWTS(pids);
52 }
53
54
55 return queryProcessWtsMapFromPerfMon(pids);
56 }
57
58 private static Map<Integer, WtsInfo> queryProcessWtsMapFromWTS(Collection<Integer> pids) {
59 Map<Integer, WtsInfo> wtsMap = new HashMap<>();
60 try (CloseableIntByReference pCount = new CloseableIntByReference(0);
61 CloseablePointerByReference ppProcessInfo = new CloseablePointerByReference();
62 CloseableIntByReference infoLevel1 = new CloseableIntByReference(Wtsapi32.WTS_PROCESS_INFO_LEVEL_1)) {
63 if (!Wtsapi32.INSTANCE.WTSEnumerateProcessesEx(Wtsapi32.WTS_CURRENT_SERVER_HANDLE, infoLevel1,
64 Wtsapi32.WTS_ANY_SESSION, ppProcessInfo, pCount)) {
65 LOG.error("Failed to enumerate Processes. Error code: {}", Kernel32.INSTANCE.GetLastError());
66 return wtsMap;
67 }
68
69 Pointer pProcessInfo = ppProcessInfo.getValue();
70 final WTS_PROCESS_INFO_EX processInfoRef = new WTS_PROCESS_INFO_EX(pProcessInfo);
71 WTS_PROCESS_INFO_EX[] processInfo = (WTS_PROCESS_INFO_EX[]) processInfoRef.toArray(pCount.getValue());
72 for (WTS_PROCESS_INFO_EX info : processInfo) {
73 if (pids == null || pids.contains(info.ProcessId)) {
74 wtsMap.put(info.ProcessId,
75 new WtsInfo(info.pProcessName, "", info.NumberOfThreads, info.PagefileUsage & 0xffff_ffffL,
76 info.KernelTime.getValue() / 10_000L, info.UserTime.getValue() / 10_000,
77 info.HandleCount));
78 }
79 }
80
81 if (!Wtsapi32.INSTANCE.WTSFreeMemoryEx(Wtsapi32.WTS_PROCESS_INFO_LEVEL_1, pProcessInfo,
82 pCount.getValue())) {
83 LOG.warn("Failed to Free Memory for Processes. Error code: {}", Kernel32.INSTANCE.GetLastError());
84 }
85 }
86 return wtsMap;
87 }
88
89 private static Map<Integer, WtsInfo> queryProcessWtsMapFromPerfMon(Collection<Integer> pids) {
90 Map<Integer, WtsInfo> wtsMap = new HashMap<>();
91 WmiResult<ProcessXPProperty> processWmiResult = Win32Process.queryProcesses(pids);
92 for (int i = 0; i < processWmiResult.getResultCount(); i++) {
93 wtsMap.put(WmiUtil.getUint32(processWmiResult, ProcessXPProperty.PROCESSID, i), new WtsInfo(
94 WmiUtil.getString(processWmiResult, ProcessXPProperty.NAME, i),
95 WmiUtil.getString(processWmiResult, ProcessXPProperty.EXECUTABLEPATH, i),
96 WmiUtil.getUint32(processWmiResult, ProcessXPProperty.THREADCOUNT, i),
97
98 1024 * (WmiUtil.getUint32(processWmiResult, ProcessXPProperty.PAGEFILEUSAGE, i) & 0xffff_ffffL),
99 WmiUtil.getUint64(processWmiResult, ProcessXPProperty.KERNELMODETIME, i) / 10_000L,
100 WmiUtil.getUint64(processWmiResult, ProcessXPProperty.USERMODETIME, i) / 10_000L,
101 WmiUtil.getUint32(processWmiResult, ProcessXPProperty.HANDLECOUNT, i)));
102 }
103 return wtsMap;
104 }
105
106
107
108
109 @Immutable
110 public static class WtsInfo {
111 private final String name;
112 private final String path;
113 private final int threadCount;
114 private final long virtualSize;
115 private final long kernelTime;
116 private final long userTime;
117 private final long openFiles;
118
119 public WtsInfo(String name, String path, int threadCount, long virtualSize, long kernelTime, long userTime,
120 long openFiles) {
121 this.name = name;
122 this.path = path;
123 this.threadCount = threadCount;
124 this.virtualSize = virtualSize;
125 this.kernelTime = kernelTime;
126 this.userTime = userTime;
127 this.openFiles = openFiles;
128 }
129
130
131
132
133 public String getName() {
134 return name;
135 }
136
137
138
139
140 public String getPath() {
141 return path;
142 }
143
144
145
146
147 public int getThreadCount() {
148 return threadCount;
149 }
150
151
152
153
154 public long getVirtualSize() {
155 return virtualSize;
156 }
157
158
159
160
161 public long getKernelTime() {
162 return kernelTime;
163 }
164
165
166
167
168 public long getUserTime() {
169 return userTime;
170 }
171
172
173
174
175 public long getOpenFiles() {
176 return openFiles;
177 }
178 }
179 }