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

Contents of /branches/TerminalServices/TSAdminTool/TerminalServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 241 - (show annotations) (download)
Sat Aug 25 16:40:35 2012 UTC (8 years, 6 months ago) by william
File size: 45717 byte(s)
WTS_CLIENT_DISPLAY : these are DWORD (int not uint)

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

  ViewVC Help
Powered by ViewVC 1.1.22