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

Contents of /trunk/TSAdminTool/TerminalServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 236 - (show annotations) (download)
Thu Aug 23 20:48:47 2012 UTC (7 years, 6 months ago) by william
File size: 45723 byte(s)

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

  ViewVC Help
Powered by ViewVC 1.1.22