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

Annotation of /trunk/TSAdminTool/TerminalServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


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

1 william 4 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 william 47 using log4net;
9 william 4 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 william 188 /// <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 william 4 [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 william 188
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 william 4 public enum WTSInfoClass
99     {
100 william 188 /// <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 william 4 WTSInitialProgram,
104 william 188 /// <summary>
105     /// A null-terminated string that contains the published name of the application that the session is running.
106     /// </summary>
107 william 4 WTSApplicationName,
108 william 188 /// <summary>
109     /// A null-terminated string that contains the default directory used when launching the initial program.
110     /// </summary>
111 william 4 WTSWorkingDirectory,
112 william 188 /// <summary>
113     /// This value is not used.
114     /// </summary>
115 william 4 WTSOEMId,
116 william 188 /// <summary>
117     /// A ULONG value that contains the session identifier.
118     /// </summary>
119 william 4 WTSSessionId,
120 william 188 /// <summary>
121     /// A null-terminated string that contains the name of the user associated with the session.
122     /// </summary>
123 william 4 WTSUserName,
124 william 188 /// <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 william 4 WTSWinStationName,
129 william 188 /// <summary>
130     /// A null-terminated string that contains the name of the domain to which the logged-on user belongs.
131     /// </summary>
132 william 4 WTSDomainName,
133 william 188 /// <summary>
134     /// The session's current connection state. For more information, see WTS_CONNECTSTATE_CLASS.
135     /// </summary>
136 william 4 WTSConnectState,
137 william 188 /// <summary>
138     /// A ULONG value that contains the build number of the client.
139     /// </summary>
140 william 4 WTSClientBuildNumber,
141 william 188 /// <summary>
142     /// A null-terminated string that contains the name of the client.
143     /// </summary>
144 william 4 WTSClientName,
145 william 188 /// <summary>
146     /// A null-terminated string that contains the directory in which the client is installed.
147     /// </summary>
148 william 4 WTSClientDirectory,
149 william 188 /// <summary>
150     /// A USHORT client-specific product identifier.
151     /// </summary>
152 william 4 WTSClientProductId,
153 william 188 /// <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 william 4 WTSClientHardwareId,
157 william 188 /// <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 william 4 WTSClientAddress,
162 william 188 /// <summary>
163     /// Information about the display resolution of the client. For more information, see WTS_CLIENT_DISPLAY.
164     /// </summary>
165 william 4 WTSClientDisplay,
166 william 188 /// <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 william 4 WTSClientProtocolType,
173 william 188 /// <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 william 4 } ;
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 william 189 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 william 4
465 william 189 WTSFreeMemory(ppBuffer);
466     }
467     else
468 william 4 {
469 william 189 clientName = System.Environment.MachineName;
470 william 4 }
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 william 46 catch (Exception e)
563 william 4 {
564     MessageBox.Show("Error could not close terminal server connection (63210)");
565 william 46 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 william 4 }
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 william 46 catch(Exception e)
631 william 4 {
632     MessageBox.Show("Error could not close terminal server connection (63210)");
633 william 46 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 william 4 }
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