/[AnywhereTS-MSSQL]/trunk/TSAdminTool/TerminalServices.cs
ViewVC logotype

Contents of /trunk/TSAdminTool/TerminalServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 189 - (show annotations) (download)
Mon Jul 16 15:54:57 2012 UTC (8 years, 6 months ago) by william
File size: 39747 byte(s)
+ get machinename for TSSession if running from RDP Session

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 string clientName = "";
449 if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
450 {
451 System.IntPtr ppBuffer = System.IntPtr.Zero;
452 int adrBuffer;
453 uint pBytesReturned = 0;
454 if (WTSQuerySessionInformation(
455 server,
456 sessionID,
457 WTSInfoClass.WTSClientName,
458 out ppBuffer,
459 out pBytesReturned))
460 {
461 adrBuffer = (int)ppBuffer;
462 clientName = Marshal.PtrToStringAnsi((System.IntPtr)adrBuffer);
463 }
464
465 WTSFreeMemory(ppBuffer);
466 }
467 else
468 {
469 clientName = System.Environment.MachineName;
470 }
471 return clientName;
472 }
473
474 // List all sessions on all registered terminal servers and return in a list with selected data for each session.
475 public static List<TS_SESSION_INFO> ListSessions()
476 {
477 List<TS_SESSION_INFO> ret = new List<TS_SESSION_INFO>();
478 if (ATSGlobals.terminalServerConfig == 0) // This server is a terminal server
479 {
480 ListSessions(ret, "localhost"); // Add sessions from local server
481 }
482
483 // Add sessions from other terminal servers
484 atsDataSet.TerminalServerDataTable datatableTerminalServer;
485 datatableTerminalServer = new atsDataSet.TerminalServerDataTable();
486 ProSupport.terminalServerTableAdapter.Fill(datatableTerminalServer);
487 foreach (DataRow row in datatableTerminalServer.Rows)
488 {
489 string strError = "";
490 try
491 {
492 strError = ListSessions(ret, row["Path"].ToString());
493 }
494 catch
495 {
496 //MessageBox.Show("Error: Could not retrieve session data from server '" + row["Path"].ToString() + "'. Error 39092.");
497 }
498 if (strError.Length != 0)
499 {
500 //MessageBox.Show("Warning: " + strError, "AnywhereTS");
501 }
502 }
503 return ret;
504 }
505
506 // List all sessions on the terminal server and return in a list with selected data for each session.
507 public static List<TS_SESSION_INFO> ListSessions(String serverName)
508 {
509 IntPtr server = IntPtr.Zero;
510 List<TS_SESSION_INFO> ret = new List<TS_SESSION_INFO>();
511 server = OpenServer(serverName);
512
513 try
514 {
515 IntPtr ppSessionInfo = IntPtr.Zero;
516
517 Int32 count = 0;
518 Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
519 Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
520 Int32 current = (int)ppSessionInfo;
521 TS_SESSION_INFO CurrentClientInfo;
522
523 if (retval != 0)
524 {
525 for (int i = 0; i < count; i++) // Iterate through all sessions on the server
526 {
527 WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
528 current += dataSize;
529 CurrentClientInfo.sessionID = si.SessionID;
530 CurrentClientInfo.ipAddress = GetTSClientAddress(si.SessionID, server);
531 CurrentClientInfo.name = GetTSClientName(si.SessionID, server);
532 CurrentClientInfo.username = GetTSUserName(si.SessionID, server);
533 CurrentClientInfo.state = si.State;
534 if (CurrentClientInfo.name != "")
535 {
536 CurrentClientInfo.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(CurrentClientInfo.name);
537 }
538 else
539 {
540 CurrentClientInfo.macAddress = "";
541 }
542
543 GetTSClientDisplay(
544 si.SessionID,
545 server,
546 out CurrentClientInfo.HorizontalResolution,
547 out CurrentClientInfo.VerticalResolution,
548 out CurrentClientInfo.ColorDepth);
549 ret.Add(CurrentClientInfo);
550 }
551
552 WTSFreeMemory(ppSessionInfo);
553 }
554 }
555
556 finally
557 {
558 try
559 {
560 CloseServer(server);
561 }
562 catch (Exception e)
563 {
564 MessageBox.Show("Error could not close terminal server connection (63210)");
565 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString())))
566 {
567 Logging.ATSAdminLog.Error("Error could not close terminal server connection (63210)");
568 }
569 }
570 }
571 return ret;
572 }
573
574 // List all sessions on the terminal server and return in a list with selected data for each session.
575 public static List<AtsSession> ListTSsessions(String serverName)
576 {
577 IntPtr server = IntPtr.Zero;
578 List<AtsSession> ret = new List<AtsSession>();
579 server = OpenServer(serverName);
580
581 try
582 {
583 IntPtr ppSessionInfo = IntPtr.Zero;
584
585 Int32 count = 0;
586 Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
587 Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
588 Int32 current = (int)ppSessionInfo;
589 AtsSession CurrentSession = new AtsSession();
590
591 if (retval != 0)
592 {
593 for (int i = 0; i < count; i++) // Iterate through all sessions on the server
594 {
595 WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
596 current += dataSize;
597 CurrentSession.sessionID = si.SessionID;
598 CurrentSession.ipAddress = GetTSClientAddress(si.SessionID, server);
599 CurrentSession.name = GetTSClientName(si.SessionID, server);
600 CurrentSession.username = GetTSUserName(si.SessionID, server);
601 CurrentSession.state = si.State;
602 if (CurrentSession.name != "")
603 {
604 CurrentSession.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(CurrentSession.name);
605 }
606 else
607 {
608 CurrentSession.macAddress = "";
609 }
610
611 GetTSClientDisplay(
612 si.SessionID,
613 server,
614 out CurrentSession.HorizontalResolution,
615 out CurrentSession.VerticalResolution,
616 out CurrentSession.ColorDepth);
617 ret.Add(CurrentSession);
618 }
619
620 WTSFreeMemory(ppSessionInfo);
621 }
622 }
623
624 finally
625 {
626 try
627 {
628 CloseServer(server);
629 }
630 catch(Exception e)
631 {
632 MessageBox.Show("Error could not close terminal server connection (63210)");
633 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString())))
634 {
635 Logging.ATSAdminLog.Error("Error could not close terminal server connection (63210)");
636 }
637 }
638 }
639 return ret;
640 }
641
642
643 // List all sessions on the terminal server and adds them to list with selected data for each session.
644 // Returns error message or "" if everything went ok.
645 public static string ListSessions(List<TS_SESSION_INFO> SessionInfo, String serverName)
646 {
647 IntPtr server = IntPtr.Zero;
648 server = OpenServer(serverName);
649 string strError = "Could not retrieve session data from server '" + serverName + "'"; // Assume something went wrong
650 if (server != IntPtr.Zero)
651 {
652 try
653 {
654 IntPtr ppSessionInfo = IntPtr.Zero;
655
656 Int32 count = 0;
657 Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
658 Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
659 Int32 current = (int)ppSessionInfo;
660 TS_SESSION_INFO CurrentClientInfo;
661
662 if (retval != 0)
663 {
664 for (int i = 0; i < count; i++)
665 {
666 WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
667 current += dataSize;
668 CurrentClientInfo.sessionID = si.SessionID;
669 CurrentClientInfo.ipAddress = GetTSClientAddress(si.SessionID, server);
670 CurrentClientInfo.name = GetTSClientName(si.SessionID, server);
671 CurrentClientInfo.username = GetTSUserName(si.SessionID, server);
672 CurrentClientInfo.state = si.State;
673 if (CurrentClientInfo.name != "")
674 {
675 CurrentClientInfo.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(CurrentClientInfo.name);
676 }
677 else
678 {
679 CurrentClientInfo.macAddress = "";
680 }
681 GetTSClientDisplay(
682 si.SessionID,
683 server,
684 out CurrentClientInfo.HorizontalResolution,
685 out CurrentClientInfo.VerticalResolution,
686 out CurrentClientInfo.ColorDepth);
687
688 SessionInfo.Add(CurrentClientInfo);
689 }
690
691 WTSFreeMemory(ppSessionInfo);
692 }
693 }
694
695 finally
696 {
697 try
698 {
699 CloseServer(server);
700 }
701 finally
702 {
703 // Catch exeception
704 }
705 }
706 strError = ""; // Everything went ok
707 } // end if (server != null)
708 return strError;
709 }
710
711 // List all sessions on the terminal server and adds them to list with selected data for each session.
712 // Returns error message or "" if everything went ok.
713 public static string ListSessions(List<AtsSession> SessionInfo, String serverName)
714 {
715 IntPtr server = IntPtr.Zero;
716 server = OpenServer(serverName);
717 string strError = "Could not retrieve session data from server '" + serverName + "'"; // Assume something went wrong
718 if (server != IntPtr.Zero)
719 {
720 try
721 {
722 IntPtr ppSessionInfo = IntPtr.Zero;
723
724 Int32 count = 0;
725 Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
726 Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
727 Int32 current = (int)ppSessionInfo;
728
729 if (retval != 0)
730 {
731 for (int i = 0; i < count; i++)
732 {
733 AtsSession currentSession = new AtsSession();
734 WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
735 current += dataSize;
736 currentSession.TerminalServerName = serverName;
737 currentSession.sessionID = si.SessionID;
738 currentSession.ipAddress = GetTSClientAddress(si.SessionID, server);
739 currentSession.name = GetTSClientName(si.SessionID, server);
740 currentSession.username = GetTSUserName(si.SessionID, server);
741 currentSession.state = si.State;
742 if (currentSession.name != "")
743 {
744 currentSession.macAddress = ProSupport.GetMacAddressFromNameAndDatabase(currentSession.name);
745 }
746 else
747 {
748 currentSession.macAddress = "";
749 }
750 GetTSClientDisplay(
751 si.SessionID,
752 server,
753 out currentSession.HorizontalResolution,
754 out currentSession.VerticalResolution,
755 out currentSession.ColorDepth);
756
757 SessionInfo.Add(currentSession);
758 }
759
760 WTSFreeMemory(ppSessionInfo);
761 }
762 }
763 finally
764 {
765 try
766 {
767 CloseServer(server);
768 }
769 finally
770 {
771 // Catch exeception
772 }
773 }
774 strError = ""; // Everything went ok
775 } // end if (server != null)
776
777 return strError;
778 }
779
780 // Return matching session for a macAddress, or null, if the mac address is not used in any session.
781 // Called when a child node selected in the tree view
782 public static AtsSession GetSession(string macAddress)
783 {
784 foreach (AtsTerminalServer ts in AtsEnvironment.TerminalServers)
785 {
786 foreach (AtsSession session in ts.Session)
787 {
788 // Try to find the MAC adress for the selected client in any of the sessions.
789 if (session.macAddress == macAddress)
790 {
791 return session;
792 }
793 }
794 }
795 // Session not found, return null.
796 return null;
797 }
798
799 // Convert session state to string
800 public static string StateToString(WTS_CONNECTSTATE_CLASS state)
801 {
802 switch (state)
803 {
804 case WTS_CONNECTSTATE_CLASS.WTSActive:
805 return "User logged on";
806 case WTS_CONNECTSTATE_CLASS.WTSConnected:
807 return "Connected to client";
808 case WTS_CONNECTSTATE_CLASS.WTSConnectQuery:
809 return "Connecting to client";
810 case WTS_CONNECTSTATE_CLASS.WTSShadow:
811 return "Shadowing";
812 case WTS_CONNECTSTATE_CLASS.WTSDisconnected:
813 return "Logged on without client";
814 case WTS_CONNECTSTATE_CLASS.WTSIdle:
815 return "Waiting for client to connect";
816 case WTS_CONNECTSTATE_CLASS.WTSListen:
817 return "Listening for connection";
818 case WTS_CONNECTSTATE_CLASS.WTSReset:
819 return "Being reset";
820 case WTS_CONNECTSTATE_CLASS.WTSDown:
821 return "Down due to error";
822 case WTS_CONNECTSTATE_CLASS.WTSInit:
823 return "In initialization";
824 default:
825 return "Unknown state (error!)";
826 }
827 }
828 public static string GetMyName()
829 {
830 return GetTSClientName(WTS_CURRENT_SESSION, System.IntPtr.Zero);
831 }
832
833 } // Class TSManager
834 } // Namespace TerminalServices

  ViewVC Help
Powered by ViewVC 1.1.22