-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Wtsapi32Test.java
161 lines (142 loc) · 7.55 KB
/
Wtsapi32Test.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* 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 java.awt.Frame;
import java.util.HashSet;
import java.util.Set;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.Wtsapi32.WTSINFO;
import com.sun.jna.platform.win32.Wtsapi32.WTS_CLIENT_ADDRESS;
import com.sun.jna.platform.win32.Wtsapi32.WTS_CONNECTSTATE_CLASS;
import com.sun.jna.platform.win32.Wtsapi32.WTS_INFO_CLASS;
import com.sun.jna.platform.win32.Wtsapi32.WTS_PROCESS_INFO_EX;
import com.sun.jna.platform.win32.Wtsapi32.WTS_SESSION_INFO;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import junit.framework.TestCase;
public class Wtsapi32Test extends TestCase {
private final HWND hwnd;
public static void main(String[] args) {
junit.textui.TestRunner.run(Wtsapi32Test.class);
}
public Wtsapi32Test() {
Frame frame = new Frame();
frame.setVisible(true);
this.hwnd = new HWND(Native.getWindowPointer(frame));
}
public void testWTSRegisterSessionNotification() {
boolean result = Wtsapi32.INSTANCE.WTSRegisterSessionNotification(hwnd,
Wtsapi32.NOTIFY_FOR_ALL_SESSIONS);
assertEquals(true, result);
}
public void testWTSUnRegisterSessionNotification() {
// needed to register before you can unregister!
testWTSRegisterSessionNotification();
boolean result = Wtsapi32.INSTANCE
.WTSUnRegisterSessionNotification(hwnd);
assertEquals(true, result);
}
public void testWTSEnumerateProcessesEx() {
// Get processes from WTS
PointerByReference ppProcessInfo = new PointerByReference();
IntByReference pCount = new IntByReference(0);
assertTrue(Wtsapi32.INSTANCE.WTSEnumerateProcessesEx(Wtsapi32.WTS_CURRENT_SERVER_HANDLE,
new IntByReference(Wtsapi32.WTS_PROCESS_INFO_LEVEL_1), Wtsapi32.WTS_ANY_SESSION, ppProcessInfo,
pCount));
// extract the pointed-to pointer and create array
Pointer pProcessInfo = ppProcessInfo.getValue();
WTS_PROCESS_INFO_EX processInfoRef = new WTS_PROCESS_INFO_EX(pProcessInfo);
WTS_PROCESS_INFO_EX[] processInfo = (WTS_PROCESS_INFO_EX[]) processInfoRef.toArray(pCount.getValue());
Set<Integer> pidSet = new HashSet<Integer>();
for (WTS_PROCESS_INFO_EX procInfo : processInfo) {
// PIDs should be unique
if (procInfo.ProcessId != 0) {
assertFalse(pidSet.contains(procInfo.ProcessId));
pidSet.add(procInfo.ProcessId);
}
// A process cannot time travel and use negative CPU ticks
assertTrue(procInfo.KernelTime.getValue() >= 0);
assertTrue(procInfo.UserTime.getValue() >= 0);
// Process name should be nonempty except for the Idle process
String name = procInfo.pProcessName;
if (procInfo.ProcessId != 0) {
assertFalse(name.isEmpty());
}
}
// Clean up memory allocated in C
assertTrue(
Wtsapi32.INSTANCE.WTSFreeMemoryEx(Wtsapi32.WTS_PROCESS_INFO_LEVEL_1, pProcessInfo, pCount.getValue()));
}
public void testWTSEnumerateSessions() {
PointerByReference ppSessionInfo = new PointerByReference();
IntByReference pCount = new IntByReference();
assertTrue("Enumerate Sessions failed.", Wtsapi32.INSTANCE
.WTSEnumerateSessions(Wtsapi32.WTS_CURRENT_SERVER_HANDLE, 0, 1, ppSessionInfo, pCount));
Pointer pSessionInfo = ppSessionInfo.getValue();
if (pCount.getValue() > 0) {
WTS_SESSION_INFO sessionInfoRef = new WTS_SESSION_INFO(pSessionInfo);
WTS_SESSION_INFO[] sessionInfo = (WTS_SESSION_INFO[]) sessionInfoRef.toArray(pCount.getValue());
for (WTS_SESSION_INFO session : sessionInfo) {
if (session.State == WTS_CONNECTSTATE_CLASS.WTSActive) {
// Use session id to fetch additional session information
PointerByReference ppBuffer = new PointerByReference();
IntByReference pBytes = new IntByReference();
Wtsapi32.INSTANCE.WTSQuerySessionInformation(Wtsapi32.WTS_CURRENT_SERVER_HANDLE, session.SessionId,
WTS_INFO_CLASS.WTSClientProtocolType, ppBuffer, pBytes);
Pointer pBuffer = ppBuffer.getValue(); // pointer to USHORT
short protocolType = pBuffer.getShort(0); // 0 = console, 2 = RDP
assertTrue("Protocol Type must be between 0 and 2", protocolType >= 0 && protocolType <= 2);
Wtsapi32.INSTANCE.WTSFreeMemory(pBuffer);
Wtsapi32.INSTANCE.WTSQuerySessionInformation(Wtsapi32.WTS_CURRENT_SERVER_HANDLE, session.SessionId,
WTS_INFO_CLASS.WTSSessionInfo, ppBuffer, pBytes);
pBuffer = ppBuffer.getValue(); // returns WTSINFO
WTSINFO wtsInfo = new WTSINFO(pBuffer);
assertEquals("State from WTSINFO must match WTS_SESSION_INFO", session.State, wtsInfo.State);
assertEquals("SessionId from WTSINFO must match WTS_SESSION_INFO", session.SessionId,
wtsInfo.SessionId);
assertEquals("WinStationName from WTSINFO must match WTS_SESSION_INFO", session.pWinStationName,
wtsInfo.getWinStationName());
long logonTimeMillis = new WinBase.FILETIME(wtsInfo.LogonTime).toTime();
assertTrue("Logon Time can't be in the future", logonTimeMillis <= System.currentTimeMillis());
long currentTimeMillis = new WinBase.FILETIME(wtsInfo.CurrentTime).toTime();
assertTrue("Current Time must be after Logon Time", logonTimeMillis <= currentTimeMillis);
Wtsapi32.INSTANCE.WTSFreeMemory(pBuffer);
Wtsapi32.INSTANCE.WTSQuerySessionInformation(Wtsapi32.WTS_CURRENT_SERVER_HANDLE, session.SessionId,
WTS_INFO_CLASS.WTSClientAddress, ppBuffer, pBytes);
pBuffer = ppBuffer.getValue(); // returns WTS_CLIENT_ADDRESS
WTS_CLIENT_ADDRESS addr = new WTS_CLIENT_ADDRESS(pBuffer);
assertTrue("Address family must be AF_INET, AF_INET6, AF_IPX, AF_NETBIOS, or AF_UNSPEC.",
addr.AddressFamily == IPHlpAPI.AF_UNSPEC
|| addr.AddressFamily == IPHlpAPI.AF_INET
|| addr.AddressFamily == IPHlpAPI.AF_INET6
|| addr.AddressFamily == IPHlpAPI.AF_IPX
|| addr.AddressFamily == IPHlpAPI.AF_NETBIOS);
Wtsapi32.INSTANCE.WTSFreeMemory(pBuffer);
}
}
}
Wtsapi32.INSTANCE.WTSFreeMemory(pSessionInfo);
}
}