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

Contents of /trunk/TSAdminTool/TerminalServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 314 - (show annotations) (download)
Mon Aug 27 20:22:27 2012 UTC (7 years, 6 months ago) by william
File size: 44510 byte(s)
commit uncommited WIp in: TerminalServices.cs

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

  ViewVC Help
Powered by ViewVC 1.1.22