1 |
using System; |
2 |
using System.Collections.Generic; |
3 |
using System.Text; |
4 |
using System.Runtime.InteropServices; |
5 |
using System.Net; |
6 |
using System.Windows.Forms; |
7 |
using System.Data; |
8 |
using log4net; |
9 |
namespace AnywhereTS |
10 |
{ |
11 |
public class TSManager |
12 |
{ |
13 |
// Imports |
14 |
[DllImport("wtsapi32.dll")] |
15 |
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName); |
16 |
|
17 |
[DllImport("wtsapi32.dll")] |
18 |
public static extern void WTSCloseServer(IntPtr hServer); |
19 |
|
20 |
[DllImport("wtsapi32.dll")] |
21 |
public static extern Int32 WTSEnumerateSessions( |
22 |
IntPtr hServer, |
23 |
[MarshalAs(UnmanagedType.U4)] Int32 Reserved, |
24 |
[MarshalAs(UnmanagedType.U4)] Int32 Version, |
25 |
ref IntPtr ppSessionInfo, |
26 |
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount); |
27 |
|
28 |
/// <summary> |
29 |
/// The WTSQuerySessionInformation function retrieves session information for the specified |
30 |
/// session on the specified terminal server. |
31 |
/// It can be used to query session information on local and remote terminal servers. |
32 |
/// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/termserv/wtsquerysessioninformation.asp |
33 |
/// </summary> |
34 |
/// <param name="hServer">Handle to a terminal server. Specify a handle opened by the WTSOpenServer function, |
35 |
/// or specify <see cref="WTS_CURRENT_SERVER_HANDLE"/> to indicate the terminal server on which your application is running.</param> |
36 |
/// <param name="sessionId">A Terminal Services session identifier. To indicate the session in which the calling application is running |
37 |
/// (or the current session) specify <see cref="WTS_CURRENT_SESSION"/>. Only specify <see cref="WTS_CURRENT_SESSION"/> when obtaining session information on the |
38 |
/// local server. If it is specified when querying session information on a remote server, the returned session |
39 |
/// information will be inconsistent. Do not use the returned data in this situation.</param> |
40 |
/// <param name="wtsInfoClass">Specifies the type of information to retrieve. This parameter can be one of the values from the <see cref="WTSInfoClass"/> enumeration type. </param> |
41 |
/// <param name="ppBuffer">Pointer to a variable that receives a pointer to the requested information. The format and contents of the data depend on the information class specified in the <see cref="WTSInfoClass"/> parameter. |
42 |
/// To free the returned buffer, call the <see cref="WTSFreeMemory"/> function. </param> |
43 |
/// <param name="pBytesReturned">Pointer to a variable that receives the size, in bytes, of the data returned in ppBuffer.</param> |
44 |
/// <returns>If the function succeeds, the return value is a nonzero value. |
45 |
/// If the function fails, the return value is zero. To get extended error information, call GetLastError. |
46 |
/// </returns> |
47 |
[DllImport("wtsapi32.dll", EntryPoint = "WTSQuerySessionInformation", CallingConvention = CallingConvention.Cdecl)] |
48 |
public static extern bool WTSQuerySessionInformation( |
49 |
System.IntPtr hServer, |
50 |
uint sessionId, |
51 |
WTSInfoClass wtsInfoClass, |
52 |
out System.IntPtr ppBuffer, |
53 |
out uint pBytesReturned); |
54 |
|
55 |
[DllImport("wtsapi32.dll")] |
56 |
static extern void WTSFreeMemory(IntPtr pMemory); |
57 |
|
58 |
// For Lookup of MAC address |
59 |
[DllImport("iphlpapi.dll", ExactSpelling = true)] |
60 |
public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] |
61 |
pMacAddr, ref int PhyAddrLen); |
62 |
|
63 |
// Consts |
64 |
public const uint WTS_CURRENT_SESSION = 4294967295; // = -1 |
65 |
|
66 |
// Type definitions |
67 |
|
68 |
[StructLayout(LayoutKind.Sequential)] |
69 |
|
70 |
private struct WTS_SESSION_INFO |
71 |
{ |
72 |
public uint SessionID; |
73 |
|
74 |
[MarshalAs(UnmanagedType.LPStr)] |
75 |
public String pWinStationName; |
76 |
|
77 |
public WTS_CONNECTSTATE_CLASS State; |
78 |
} |
79 |
|
80 |
public enum WTS_CONNECTSTATE_CLASS |
81 |
{ |
82 |
WTSActive, // User logged on to WinStation |
83 |
WTSConnected, // WinStation connected to client |
84 |
WTSConnectQuery, // In the process of connecting to client |
85 |
WTSShadow, // Shadowing another WinStation |
86 |
WTSDisconnected, // WinStation logged on without client |
87 |
WTSIdle, // Waiting for client to connect |
88 |
WTSListen, // WinStation is listening for connection |
89 |
WTSReset, // WinStation is being reset |
90 |
WTSDown, // WinStation is down due to error |
91 |
WTSInit, // WinStation in initialization |
92 |
}; |
93 |
|
94 |
/// <summary> |
95 |
/// Contains values that indicate the type of session information to retrieve in a call to the WTSQuerySessionInformation function. |
96 |
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa383861(v=vs.85).aspx |
97 |
/// </summary> |
98 |
public enum WTSInfoClass |
99 |
{ |
100 |
/// <summary> |
101 |
/// A null-terminated string that contains the name of the initial program that Remote Desktop Services runs when the user logs on. |
102 |
/// </summary> |
103 |
WTSInitialProgram, |
104 |
/// <summary> |
105 |
/// A null-terminated string that contains the published name of the application that the session is running. |
106 |
/// </summary> |
107 |
WTSApplicationName, |
108 |
/// <summary> |
109 |
/// A null-terminated string that contains the default directory used when launching the initial program. |
110 |
/// </summary> |
111 |
WTSWorkingDirectory, |
112 |
/// <summary> |
113 |
/// This value is not used. |
114 |
/// </summary> |
115 |
WTSOEMId, |
116 |
/// <summary> |
117 |
/// A ULONG value that contains the session identifier. |
118 |
/// </summary> |
119 |
WTSSessionId, |
120 |
/// <summary> |
121 |
/// A null-terminated string that contains the name of the user associated with the session. |
122 |
/// </summary> |
123 |
WTSUserName, |
124 |
/// <summary> |
125 |
/// A null-terminated string that contains the name of the Remote Desktop Services session. |
126 |
/// Note Despite its name, specifying this type does not return the window station name. Rather, it returns the name of the Remote Desktop Services session. Each Remote Desktop Services session is associated with an interactive window station. Because the only supported window station name for an interactive window station is "WinSta0", each session is associated with its own "WinSta0" window station. For more information, see Window Stations. |
127 |
/// </summary> |
128 |
WTSWinStationName, |
129 |
/// <summary> |
130 |
/// A null-terminated string that contains the name of the domain to which the logged-on user belongs. |
131 |
/// </summary> |
132 |
WTSDomainName, |
133 |
/// <summary> |
134 |
/// The session's current connection state. For more information, see WTS_CONNECTSTATE_CLASS. |
135 |
/// </summary> |
136 |
WTSConnectState, |
137 |
/// <summary> |
138 |
/// A ULONG value that contains the build number of the client. |
139 |
/// </summary> |
140 |
WTSClientBuildNumber, |
141 |
/// <summary> |
142 |
/// A null-terminated string that contains the name of the client. |
143 |
/// </summary> |
144 |
WTSClientName, |
145 |
/// <summary> |
146 |
/// A null-terminated string that contains the directory in which the client is installed. |
147 |
/// </summary> |
148 |
WTSClientDirectory, |
149 |
/// <summary> |
150 |
/// A USHORT client-specific product identifier. |
151 |
/// </summary> |
152 |
WTSClientProductId, |
153 |
/// <summary> |
154 |
/// A ULONG value that contains a client-specific hardware identifier. This option is reserved for future use. WTSQuerySessionInformation will always return a value of 0. |
155 |
/// </summary> |
156 |
WTSClientHardwareId, |
157 |
/// <summary> |
158 |
/// The network type and network address of the client. For more information, see WTS_CLIENT_ADDRESS. |
159 |
/// The IP address is offset by two bytes from the start of the Address member of the WTS_CLIENT_ADDRESS structure. |
160 |
/// </summary> |
161 |
WTSClientAddress, |
162 |
/// <summary> |
163 |
/// Information about the display resolution of the client. For more information, see WTS_CLIENT_DISPLAY. |
164 |
/// </summary> |
165 |
WTSClientDisplay, |
166 |
/// <summary> |
167 |
/// A USHORT value that specifies information about the protocol type for the session. This is one of the following values. |
168 |
/// 0: The console session. |
169 |
/// 1: This value is retained for legacy purposes. |
170 |
/// 2: The RDP protocol. |
171 |
/// </summary> |
172 |
WTSClientProtocolType, |
173 |
/// <summary> |
174 |
/// This value returns FALSE. If you call GetLastError to get extended error information, GetLastError returns ERROR_NOT_SUPPORTED. |
175 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not used. |
176 |
/// </summary> |
177 |
WTSIdleTime, |
178 |
/// <summary> |
179 |
/// This value returns FALSE. If you call GetLastError to get extended error information, GetLastError returns ERROR_NOT_SUPPORTED. |
180 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not used. |
181 |
/// </summary> |
182 |
WTSLogonTime, |
183 |
/// <summary> |
184 |
/// This value returns FALSE. If you call GetLastError to get extended error information, GetLastError returns ERROR_NOT_SUPPORTED. |
185 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not used. |
186 |
/// </summary> |
187 |
WTSIncomingBytes, |
188 |
/// <summary> |
189 |
/// This value returns FALSE. If you call GetLastError to get extended error information, GetLastError returns ERROR_NOT_SUPPORTED. |
190 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not used. |
191 |
/// </summary> |
192 |
WTSOutgoingBytes, |
193 |
/// <summary> |
194 |
/// This value returns FALSE. If you call GetLastError to get extended error information, GetLastError returns ERROR_NOT_SUPPORTED. |
195 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not used. |
196 |
/// </summary> |
197 |
WTSIncomingFrames, |
198 |
/// <summary> |
199 |
/// This value returns FALSE. If you call GetLastError to get extended error information, GetLastError returns ERROR_NOT_SUPPORTED. |
200 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not used. |
201 |
/// </summary> |
202 |
WTSOutgoingFrames, |
203 |
/// <summary> |
204 |
/// Information about a Remote Desktop Connection (RDC) client. For more information, see WTSCLIENT. |
205 |
/// Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not supported. |
206 |
/// This value is supported beginning with Windows Server 2008 and Windows Vista with SP1. |
207 |
/// </summary> |
208 |
WTSClientInfo, |
209 |
/// <summary> |
210 |
/// Information about a client session on an RD Session Host server. For more information, see WTSINFO. |
211 |
/// Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not supported. |
212 |
/// This value is supported beginning with Windows Server 2008 and Windows Vista with SP1. |
213 |
/// </summary> |
214 |
WTSSessionInfo, |
215 |
/// <summary> |
216 |
/// Extended information about a session on an RD Session Host server. For more information, see WTSINFOEX. |
217 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not supported. |
218 |
/// </summary> |
219 |
WTSSessionInfoEx, |
220 |
/// <summary> |
221 |
/// Information about the configuration of an RD Session Host server. |
222 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not supported. |
223 |
/// </summary> |
224 |
WTSConfigInfo, |
225 |
/// <summary> |
226 |
/// This value is not supported. |
227 |
/// </summary> |
228 |
WTSValidationInfo, |
229 |
/// <summary> |
230 |
/// A WTS_SESSION_ADDRESS structure that contains the IPv4 address assigned to the session. If the session does not have a virtual IP address, the WTSQuerySessionInformation function returns ERROR_NOT_SUPPORTED. |
231 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not supported. |
232 |
/// </summary> |
233 |
WTSSessionAddressV4, |
234 |
/// <summary> |
235 |
/// Determines whether the current session is a remote session. The WTSQuerySessionInformation function returns a value of TRUE to indicate that the current session is a remote session, and FALSE to indicate that the current session is a local session. This value can only be used for the local machine, so the hServer parameter of the WTSQuerySessionInformation function must contain WTS_CURRENT_SERVER_HANDLE. |
236 |
/// Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, and Windows 2000: This value is not supported. |
237 |
/// </summary> |
238 |
WTSIsRemoteSession, |
239 |
} ; |
240 |
|
241 |
public struct WTS_CLIENT_ADDRESS |
242 |
{ |
243 |
public uint AddressFamily; // AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC |
244 |
public Byte[] Address; |
245 |
}; |
246 |
|
247 |
public struct WTS_CLIENT_DISPLAY |
248 |
{ |
249 |
public uint HorizontalResolution; // horizontal dimensions, in pixels |
250 |
public uint VerticalResolution; // vertical dimensions, in pixels |
251 |
public uint ColorDepth; // 1=16, 2=256, 4=64K, 8=16M |
252 |
}; |
253 |
|
254 |
|
255 |
// Selected info for terminal server sessions |
256 |
public struct TS_SESSION_INFO |
257 |
{ |
258 |
public uint sessionID; |
259 |
public string ipAddress; // The IP address of the client |
260 |
public string macAddress; // The MAC address of the client |
261 |
public string name; // The (netbios) name of the client |
262 |
public string username; // User logged in to the session, if any. |
263 |
public WTS_CONNECTSTATE_CLASS state; // The state of the session |
264 |
public int HorizontalResolution; // Vertical screen res for the session |
265 |
public int VerticalResolution; // Horiz screen res for the session |
266 |
public int ColorDepth; // Screen color depth for the session |
267 |
}; |
268 |
|
269 |
|
270 |
public static IntPtr OpenServer(String Name) |
271 |
{ |
272 |
IntPtr server = WTSOpenServer(Name); |
273 |
return server; |
274 |
} |
275 |
public static void CloseServer(IntPtr ServerHandle) |
276 |
{ |
277 |
WTSCloseServer(ServerHandle); |
278 |
} |
279 |
|
280 |
|
281 |
// Return address for a terminal server session. |
282 |
// WTSClientAddress gives a pointer to a WTS_CLIENT_ADDRESS structure containing |
283 |
// the network type and network address of the client. If the function is called |
284 |
// from the Terminal Services console, ppBuffer returns a NULL pointer. |
285 |
// Note that the first byte of the IP address returned in the ppBuffer |
286 |
// parameter will be located at an offset of two bytes from the first location |
287 |
// of the buffer. |
288 |
private static string GetTSClientAddress(uint sessionID, IntPtr server) |
289 |
{ |
290 |
System.IntPtr ppBuffer = System.IntPtr.Zero; |
291 |
uint pBytesReturned = 0; |
292 |
StringBuilder builder = new StringBuilder(); |
293 |
|
294 |
// Interface avec API |
295 |
WTS_CLIENT_ADDRESS wtsAdr = new WTS_CLIENT_ADDRESS(); |
296 |
|
297 |
|
298 |
if (WTSQuerySessionInformation( |
299 |
server, |
300 |
sessionID, |
301 |
WTSInfoClass.WTSClientAddress, |
302 |
out ppBuffer, |
303 |
out pBytesReturned)) |
304 |
{ |
305 |
wtsAdr.Address = new Byte[pBytesReturned - 1]; |
306 |
int run = (int)ppBuffer; // pointeur sur les données |
307 |
Type t = typeof(Byte); |
308 |
Type t1 = typeof(uint); |
309 |
|
310 |
int uintSize = Marshal.SizeOf(t1); |
311 |
int byteSize = Marshal.SizeOf(t); |
312 |
|
313 |
wtsAdr.AddressFamily = (uint)Marshal.ReadInt32((System.IntPtr)run); |
314 |
|
315 |
// Address family can be only: |
316 |
// AF_UNSPEC = 0 (unspecified) |
317 |
// AF_INET = 2 (internetwork: UDP, TCP, etc.) |
318 |
// AF_IPX = AF_NS = 6 (IPX protocols: IPX, SPX, etc.) |
319 |
// AF_NETBIOS = 17 (NetBios-style addresses) |
320 |
|
321 |
//run+=uintSize; |
322 |
//run+=dataSize; |
323 |
/*switch(wtsAdr.AddressFamily) |
324 |
{ |
325 |
case 0:builder.Append("AF_UNSPEC"); |
326 |
break; |
327 |
case 1:builder.Append("AF_INET"); |
328 |
break; |
329 |
case 2:builder.Append("AF_IPX"); |
330 |
break; |
331 |
case 3:builder.Append("AF_NETBIOS"); |
332 |
break; |
333 |
}*/ |
334 |
for (int i = 0; i < pBytesReturned - 1; i++) |
335 |
{ |
336 |
wtsAdr.Address[i] = Marshal.ReadByte((System.IntPtr)run); |
337 |
run += byteSize; |
338 |
// TO GET and to SEE ALL the DATA |
339 |
//builder.Append(wtsAdr.Address[i].ToString()+"-"); |
340 |
} |
341 |
//builder.Append("-"); |
342 |
|
343 |
// The IP address is located in bytes 2, 3, 4, and 5. The other bytes are not used. |
344 |
// If AddressFamily returns AF_UNSPEC, the first byte in Address |
345 |
// is initialized to zero. |
346 |
|
347 |
// Check if the returned address is an IP address |
348 |
if (wtsAdr.AddressFamily == 2) |
349 |
{ // It is an IP address |
350 |
builder.Append((wtsAdr.Address[4 + 2]).ToString()); |
351 |
builder.Append("."); |
352 |
builder.Append((wtsAdr.Address[4 + 3]).ToString()); |
353 |
builder.Append("."); |
354 |
builder.Append((wtsAdr.Address[4 + 4]).ToString()); |
355 |
builder.Append("."); |
356 |
builder.Append((wtsAdr.Address[4 + 5]).ToString()); |
357 |
} |
358 |
} |
359 |
WTSFreeMemory(ppBuffer); |
360 |
return builder.ToString(); |
361 |
} |
362 |
|
363 |
// Get display parameters for a user session on a terminal server |
364 |
// In: SessionID = identifier for the session |
365 |
// In: server = server handle for the server that the session resides on. |
366 |
private static void GetTSClientDisplay(uint sessionID, IntPtr server, out int horizontalResolution, out int verticalResolution, out int colorDepth) |
367 |
{ |
368 |
horizontalResolution = 0; |
369 |
verticalResolution = 0; |
370 |
colorDepth = 0; |
371 |
|
372 |
System.IntPtr ppBuffer = System.IntPtr.Zero; |
373 |
uint pBytesReturned = 0; |
374 |
StringBuilder sDisplay = new StringBuilder(); |
375 |
|
376 |
WTS_CLIENT_DISPLAY clientDisplay = new WTS_CLIENT_DISPLAY(); |
377 |
clientDisplay.HorizontalResolution = 0; |
378 |
clientDisplay.VerticalResolution = 0; |
379 |
clientDisplay.ColorDepth = 0; |
380 |
|
381 |
Type dataType = typeof(WTS_CLIENT_DISPLAY); |
382 |
|
383 |
if (WTSQuerySessionInformation( |
384 |
server, |
385 |
sessionID, |
386 |
WTSInfoClass.WTSClientDisplay, |
387 |
out ppBuffer, |
388 |
out pBytesReturned)) |
389 |
{ |
390 |
clientDisplay = (WTS_CLIENT_DISPLAY)Marshal.PtrToStructure(ppBuffer, dataType); |
391 |
horizontalResolution = (int)(clientDisplay.HorizontalResolution); |
392 |
verticalResolution = (int)(clientDisplay.VerticalResolution); |
393 |
colorDepth = (int)(clientDisplay.ColorDepth); |
394 |
} |
395 |
|
396 |
WTSFreeMemory(ppBuffer); |
397 |
} |
398 |
|
399 |
|
400 |
// Get Mac from IP, using ARP |
401 |
private static string GetMACFromIP(string ipString) |
402 |
{ |
403 |
|
404 |
IPAddress ip = IPAddress.Parse(ipString); // Actual IP |
405 |
int rv; |
406 |
string macStr; |
407 |
byte[] mac = new byte[6]; |
408 |
int maclen = mac.Length; |
409 |
|
410 |
rv = SendARP(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 0, mac, ref maclen); |
411 |
if (rv == 0) // If not 0, error |
412 |
{ |
413 |
// macStr = BitConverter.ToString(mac, 0, 6); |
414 |
macStr = BitConverter.ToString(mac, 0, 1)+BitConverter.ToString(mac, 1, 1)+BitConverter.ToString(mac, 2, 1) |
415 |
+BitConverter.ToString(mac, 3, 1)+BitConverter.ToString(mac, 4, 1)+BitConverter.ToString(mac, 5, 1); |
416 |
} |
417 |
else |
418 |
{ |
419 |
macStr = ""; |
420 |
} |
421 |
return macStr; |
422 |
} |
423 |
|
424 |
|
425 |
private static string GetTSUserName(uint sessionID, IntPtr server) |
426 |
{ |
427 |
System.IntPtr ppBuffer = System.IntPtr.Zero; |
428 |
uint pBytesReturned = 0; |
429 |
string currentUserName = ""; |
430 |
|
431 |
if (WTSQuerySessionInformation( |
432 |
server, |
433 |
sessionID, |
434 |
WTSInfoClass.WTSUserName, |
435 |
out ppBuffer, |
436 |
out pBytesReturned)) |
437 |
{ |
438 |
currentUserName = Marshal.PtrToStringAnsi(ppBuffer); |
439 |
} |
440 |
|
441 |
WTSFreeMemory(ppBuffer); |
442 |
|
443 |
return currentUserName; |
444 |
} |
445 |
|
446 |
public static string GetTSClientName(uint sessionID, IntPtr server) |
447 |
{ |
448 |
System.IntPtr ppBuffer = System.IntPtr.Zero; |
449 |
int adrBuffer; |
450 |
uint pBytesReturned = 0; |
451 |
string clientName = ""; |
452 |
|
453 |
if (WTSQuerySessionInformation( |
454 |
server, |
455 |
sessionID, |
456 |
WTSInfoClass.WTSClientName, |
457 |
out ppBuffer, |
458 |
out pBytesReturned)) |
459 |
{ |
460 |
adrBuffer = (int)ppBuffer; |
461 |
clientName = Marshal.PtrToStringAnsi((System.IntPtr)adrBuffer); |
462 |
} |
463 |
|
464 |
WTSFreeMemory(ppBuffer); |
465 |
|
466 |
return clientName; |
467 |
} |
468 |
|
469 |
// List all sessions on all registered terminal servers and return in a list with selected data for each session. |
470 |
public static List<TS_SESSION_INFO> ListSessions() |
471 |
{ |
472 |
List<TS_SESSION_INFO> ret = new List<TS_SESSION_INFO>(); |
473 |
if (ATSGlobals.terminalServerConfig == 0) // This server is a terminal server |
474 |
{ |
475 |
ListSessions(ret, "localhost"); // Add sessions from local server |
476 |
} |
477 |
|
478 |
// Add sessions from other terminal servers |
479 |
atsDataSet.TerminalServerDataTable datatableTerminalServer; |
480 |
datatableTerminalServer = new atsDataSet.TerminalServerDataTable(); |
481 |
ProSupport.terminalServerTableAdapter.Fill(datatableTerminalServer); |
482 |
foreach (DataRow row in datatableTerminalServer.Rows) |
483 |
{ |
484 |
string strError = ""; |
485 |
try |
486 |
{ |
487 |
strError = ListSessions(ret, row["Path"].ToString()); |
488 |
} |
489 |
catch |
490 |
{ |
491 |
//MessageBox.Show("Error: Could not retrieve session data from server '" + row["Path"].ToString() + "'. Error 39092."); |
492 |
} |
493 |
if (strError.Length != 0) |
494 |
{ |
495 |
//MessageBox.Show("Warning: " + strError, "AnywhereTS"); |
496 |
} |
497 |
} |
498 |
return ret; |
499 |
} |
500 |
|
501 |
// List all sessions on the terminal server and return in a list with selected data for each session. |
502 |
public static List<TS_SESSION_INFO> ListSessions(String serverName) |
503 |
{ |
504 |
IntPtr server = IntPtr.Zero; |
505 |
List<TS_SESSION_INFO> ret = new List<TS_SESSION_INFO>(); |
506 |
server = OpenServer(serverName); |
507 |
|
508 |
try |
509 |
{ |
510 |
IntPtr ppSessionInfo = IntPtr.Zero; |
511 |
|
512 |
Int32 count = 0; |
513 |
Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); |
514 |
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); |
515 |
Int32 current = (int)ppSessionInfo; |
516 |
TS_SESSION_INFO CurrentClientInfo; |
517 |
|
518 |
if (retval != 0) |
519 |
{ |
520 |
for (int i = 0; i < count; i++) // Iterate through all sessions on the server |
521 |
{ |
522 |
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); |
523 |
current += dataSize; |
524 |
CurrentClientInfo.sessionID = si.SessionID; |
525 |
CurrentClientInfo.ipAddress = GetTSClientAddress(si.SessionID, server); |
526 |
CurrentClientInfo.name = GetTSClientName(si.SessionID, server); |
527 |
CurrentClientInfo.username = GetTSUserName(si.SessionID, server); |
528 |
CurrentClientInfo.state = si.State; |
529 |
if (CurrentClientInfo.name != "") |
530 |
{ |
531 |
CurrentClientInfo.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(CurrentClientInfo.name); |
532 |
} |
533 |
else |
534 |
{ |
535 |
CurrentClientInfo.macAddress = ""; |
536 |
} |
537 |
|
538 |
GetTSClientDisplay( |
539 |
si.SessionID, |
540 |
server, |
541 |
out CurrentClientInfo.HorizontalResolution, |
542 |
out CurrentClientInfo.VerticalResolution, |
543 |
out CurrentClientInfo.ColorDepth); |
544 |
ret.Add(CurrentClientInfo); |
545 |
} |
546 |
|
547 |
WTSFreeMemory(ppSessionInfo); |
548 |
} |
549 |
} |
550 |
|
551 |
finally |
552 |
{ |
553 |
try |
554 |
{ |
555 |
CloseServer(server); |
556 |
} |
557 |
catch (Exception e) |
558 |
{ |
559 |
MessageBox.Show("Error could not close terminal server connection (63210)"); |
560 |
using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString()))) |
561 |
{ |
562 |
Logging.ATSAdminLog.Error("Error could not close terminal server connection (63210)"); |
563 |
} |
564 |
} |
565 |
} |
566 |
return ret; |
567 |
} |
568 |
|
569 |
// List all sessions on the terminal server and return in a list with selected data for each session. |
570 |
public static List<AtsSession> ListTSsessions(String serverName) |
571 |
{ |
572 |
IntPtr server = IntPtr.Zero; |
573 |
List<AtsSession> ret = new List<AtsSession>(); |
574 |
server = OpenServer(serverName); |
575 |
|
576 |
try |
577 |
{ |
578 |
IntPtr ppSessionInfo = IntPtr.Zero; |
579 |
|
580 |
Int32 count = 0; |
581 |
Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); |
582 |
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); |
583 |
Int32 current = (int)ppSessionInfo; |
584 |
AtsSession CurrentSession = new AtsSession(); |
585 |
|
586 |
if (retval != 0) |
587 |
{ |
588 |
for (int i = 0; i < count; i++) // Iterate through all sessions on the server |
589 |
{ |
590 |
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); |
591 |
current += dataSize; |
592 |
CurrentSession.sessionID = si.SessionID; |
593 |
CurrentSession.ipAddress = GetTSClientAddress(si.SessionID, server); |
594 |
CurrentSession.name = GetTSClientName(si.SessionID, server); |
595 |
CurrentSession.username = GetTSUserName(si.SessionID, server); |
596 |
CurrentSession.state = si.State; |
597 |
if (CurrentSession.name != "") |
598 |
{ |
599 |
CurrentSession.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(CurrentSession.name); |
600 |
} |
601 |
else |
602 |
{ |
603 |
CurrentSession.macAddress = ""; |
604 |
} |
605 |
|
606 |
GetTSClientDisplay( |
607 |
si.SessionID, |
608 |
server, |
609 |
out CurrentSession.HorizontalResolution, |
610 |
out CurrentSession.VerticalResolution, |
611 |
out CurrentSession.ColorDepth); |
612 |
ret.Add(CurrentSession); |
613 |
} |
614 |
|
615 |
WTSFreeMemory(ppSessionInfo); |
616 |
} |
617 |
} |
618 |
|
619 |
finally |
620 |
{ |
621 |
try |
622 |
{ |
623 |
CloseServer(server); |
624 |
} |
625 |
catch(Exception e) |
626 |
{ |
627 |
MessageBox.Show("Error could not close terminal server connection (63210)"); |
628 |
using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString()))) |
629 |
{ |
630 |
Logging.ATSAdminLog.Error("Error could not close terminal server connection (63210)"); |
631 |
} |
632 |
} |
633 |
} |
634 |
return ret; |
635 |
} |
636 |
|
637 |
|
638 |
// List all sessions on the terminal server and adds them to list with selected data for each session. |
639 |
// Returns error message or "" if everything went ok. |
640 |
public static string ListSessions(List<TS_SESSION_INFO> SessionInfo, String serverName) |
641 |
{ |
642 |
IntPtr server = IntPtr.Zero; |
643 |
server = OpenServer(serverName); |
644 |
string strError = "Could not retrieve session data from server '" + serverName + "'"; // Assume something went wrong |
645 |
if (server != IntPtr.Zero) |
646 |
{ |
647 |
try |
648 |
{ |
649 |
IntPtr ppSessionInfo = IntPtr.Zero; |
650 |
|
651 |
Int32 count = 0; |
652 |
Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); |
653 |
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); |
654 |
Int32 current = (int)ppSessionInfo; |
655 |
TS_SESSION_INFO CurrentClientInfo; |
656 |
|
657 |
if (retval != 0) |
658 |
{ |
659 |
for (int i = 0; i < count; i++) |
660 |
{ |
661 |
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); |
662 |
current += dataSize; |
663 |
CurrentClientInfo.sessionID = si.SessionID; |
664 |
CurrentClientInfo.ipAddress = GetTSClientAddress(si.SessionID, server); |
665 |
CurrentClientInfo.name = GetTSClientName(si.SessionID, server); |
666 |
CurrentClientInfo.username = GetTSUserName(si.SessionID, server); |
667 |
CurrentClientInfo.state = si.State; |
668 |
if (CurrentClientInfo.name != "") |
669 |
{ |
670 |
CurrentClientInfo.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(CurrentClientInfo.name); |
671 |
} |
672 |
else |
673 |
{ |
674 |
CurrentClientInfo.macAddress = ""; |
675 |
} |
676 |
GetTSClientDisplay( |
677 |
si.SessionID, |
678 |
server, |
679 |
out CurrentClientInfo.HorizontalResolution, |
680 |
out CurrentClientInfo.VerticalResolution, |
681 |
out CurrentClientInfo.ColorDepth); |
682 |
|
683 |
SessionInfo.Add(CurrentClientInfo); |
684 |
} |
685 |
|
686 |
WTSFreeMemory(ppSessionInfo); |
687 |
} |
688 |
} |
689 |
|
690 |
finally |
691 |
{ |
692 |
try |
693 |
{ |
694 |
CloseServer(server); |
695 |
} |
696 |
finally |
697 |
{ |
698 |
// Catch exeception |
699 |
} |
700 |
} |
701 |
strError = ""; // Everything went ok |
702 |
} // end if (server != null) |
703 |
return strError; |
704 |
} |
705 |
|
706 |
// List all sessions on the terminal server and adds them to list with selected data for each session. |
707 |
// Returns error message or "" if everything went ok. |
708 |
public static string ListSessions(List<AtsSession> SessionInfo, String serverName) |
709 |
{ |
710 |
IntPtr server = IntPtr.Zero; |
711 |
server = OpenServer(serverName); |
712 |
string strError = "Could not retrieve session data from server '" + serverName + "'"; // Assume something went wrong |
713 |
if (server != IntPtr.Zero) |
714 |
{ |
715 |
try |
716 |
{ |
717 |
IntPtr ppSessionInfo = IntPtr.Zero; |
718 |
|
719 |
Int32 count = 0; |
720 |
Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); |
721 |
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); |
722 |
Int32 current = (int)ppSessionInfo; |
723 |
|
724 |
if (retval != 0) |
725 |
{ |
726 |
for (int i = 0; i < count; i++) |
727 |
{ |
728 |
AtsSession currentSession = new AtsSession(); |
729 |
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); |
730 |
current += dataSize; |
731 |
currentSession.TerminalServerName = serverName; |
732 |
currentSession.sessionID = si.SessionID; |
733 |
currentSession.ipAddress = GetTSClientAddress(si.SessionID, server); |
734 |
currentSession.name = GetTSClientName(si.SessionID, server); |
735 |
currentSession.username = GetTSUserName(si.SessionID, server); |
736 |
currentSession.state = si.State; |
737 |
if (currentSession.name != "") |
738 |
{ |
739 |
currentSession.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(currentSession.name); |
740 |
} |
741 |
else |
742 |
{ |
743 |
currentSession.macAddress = ""; |
744 |
} |
745 |
GetTSClientDisplay( |
746 |
si.SessionID, |
747 |
server, |
748 |
out currentSession.HorizontalResolution, |
749 |
out currentSession.VerticalResolution, |
750 |
out currentSession.ColorDepth); |
751 |
|
752 |
SessionInfo.Add(currentSession); |
753 |
} |
754 |
|
755 |
WTSFreeMemory(ppSessionInfo); |
756 |
} |
757 |
} |
758 |
finally |
759 |
{ |
760 |
try |
761 |
{ |
762 |
CloseServer(server); |
763 |
} |
764 |
finally |
765 |
{ |
766 |
// Catch exeception |
767 |
} |
768 |
} |
769 |
strError = ""; // Everything went ok |
770 |
} // end if (server != null) |
771 |
|
772 |
return strError; |
773 |
} |
774 |
|
775 |
// Return matching session for a macAddress, or null, if the mac address is not used in any session. |
776 |
// Called when a child node selected in the tree view |
777 |
public static AtsSession GetSession(string macAddress) |
778 |
{ |
779 |
foreach (AtsTerminalServer ts in AtsEnvironment.TerminalServers) |
780 |
{ |
781 |
foreach (AtsSession session in ts.Session) |
782 |
{ |
783 |
// Try to find the MAC adress for the selected client in any of the sessions. |
784 |
if (session.macAddress == macAddress) |
785 |
{ |
786 |
return session; |
787 |
} |
788 |
} |
789 |
} |
790 |
// Session not found, return null. |
791 |
return null; |
792 |
} |
793 |
|
794 |
// Convert session state to string |
795 |
public static string StateToString(WTS_CONNECTSTATE_CLASS state) |
796 |
{ |
797 |
switch (state) |
798 |
{ |
799 |
case WTS_CONNECTSTATE_CLASS.WTSActive: |
800 |
return "User logged on"; |
801 |
case WTS_CONNECTSTATE_CLASS.WTSConnected: |
802 |
return "Connected to client"; |
803 |
case WTS_CONNECTSTATE_CLASS.WTSConnectQuery: |
804 |
return "Connecting to client"; |
805 |
case WTS_CONNECTSTATE_CLASS.WTSShadow: |
806 |
return "Shadowing"; |
807 |
case WTS_CONNECTSTATE_CLASS.WTSDisconnected: |
808 |
return "Logged on without client"; |
809 |
case WTS_CONNECTSTATE_CLASS.WTSIdle: |
810 |
return "Waiting for client to connect"; |
811 |
case WTS_CONNECTSTATE_CLASS.WTSListen: |
812 |
return "Listening for connection"; |
813 |
case WTS_CONNECTSTATE_CLASS.WTSReset: |
814 |
return "Being reset"; |
815 |
case WTS_CONNECTSTATE_CLASS.WTSDown: |
816 |
return "Down due to error"; |
817 |
case WTS_CONNECTSTATE_CLASS.WTSInit: |
818 |
return "In initialization"; |
819 |
default: |
820 |
return "Unknown state (error!)"; |
821 |
} |
822 |
} |
823 |
public static string GetMyName() |
824 |
{ |
825 |
return GetTSClientName(WTS_CURRENT_SESSION, System.IntPtr.Zero); |
826 |
} |
827 |
|
828 |
} // Class TSManager |
829 |
} // Namespace TerminalServices |