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

Contents of /trunk/TSAdminTool/TerminalServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 188 - (show annotations) (download)
Mon Jul 16 15:48:04 2012 UTC (8 years, 7 months ago) by william
File size: 39475 byte(s)
+ add meaning to enum values in WTSInfoClass

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

  ViewVC Help
Powered by ViewVC 1.1.22