Pagine

lunedì 13 luglio 2015

C# - Sessioni Terminal Service

 Utilizzando le api della libreria di sistema Wtsapi32.dll è possibile elencare e gestire le sessioni aperte in un server Windows sia locale che remoto.
Il prerequisito è ovviamente che l'utente abbia garantito l'accesso a quel server, in caso contrario sarebbe necessario avviare le api impersonando un utente che abbia
le autorizzazioni necessarie ad accedere al server remoto.
Le funzioni principali  (e come si integrano un C#) sono le seguenti:

[code] [DllImport("Wtsapi32.dll")] static extern bool WTSQuerySessionInformation( System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned); [DllImport("wtsapi32.dll", SetLastError=true)] static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName); [DllImport("wtsapi32.dll")] static extern void WTSCloseServer(IntPtr hServer); [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSLogoffSession(IntPtr hServer, int SessionId, bool bWait); [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSDisconnectSession(IntPtr hServer, int SessionId, bool bWait); [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSTerminateProcess(IntPtr hServer, int ProcessId, bool bWait); [/code]
WTSQuerySessionInformation: recupera i dati delle sessioni presenti in quel momento sul server
WTSOpenServer: apre la connessione al server target
WTSCloseServer: chiude la connessione al server al termine dell'operazione di enumerazione delle sessioni
WTSLogoffSession: esegue il logoff della sessione specificata tramite SESSIONID
WTSDisconnectSession: esegue la disconnessione della sessione specificata
WTSTerminateProcess: termina un processo per quella sessione

Un esempio è mostrato nel listato seguente:

[code] [DllImport("Wtsapi32.dll")] static extern bool WTSQuerySessionInformation( System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned); [DllImport("wtsapi32.dll", SetLastError=true)] static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName); [DllImport("wtsapi32.dll")] static extern void WTSCloseServer(IntPtr hServer); [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSLogoffSession(IntPtr hServer, int SessionId, bool bWait); [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSDisconnectSession(IntPtr hServer, int SessionId, bool bWait); [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSTerminateProcess(IntPtr hServer, int ProcessId, bool bWait); [DllImport("kernel32.dll", SetLastError = true)] static extern bool GetLastError(); [DllImport("wtsapi32.dll", SetLastError=true)] static extern Int32 WTSEnumerateSessions( IntPtr hServer, [MarshalAs(UnmanagedType.U4)] Int32 Reserved, [MarshalAs(UnmanagedType.U4)] Int32 Version, ref IntPtr ppSessionInfo, [MarshalAs(UnmanagedType.U4)] ref Int32 pCount); [DllImport("wtsapi32.dll")] static extern void WTSFreeMemory(IntPtr pMemory); [StructLayout(LayoutKind.Sequential)] private struct WTS_SESSION_INFO { public Int32 SessionID; [MarshalAs(UnmanagedType.LPStr)] public String pWinStationName; public WTS_CONNECTSTATE_CLASS State; } public enum WTS_INFO_CLASS { WTSInitialProgram, WTSApplicationName, WTSWorkingDirectory, WTSOEMId, WTSSessionId, WTSUserName, WTSWinStationName, WTSDomainName, WTSConnectState, WTSClientBuildNumber, WTSClientName, WTSClientDirectory, WTSClientProductId, WTSClientHardwareId, WTSClientAddress, WTSClientDisplay, WTSClientProtocolType } public enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } public static IntPtr OpenServer(String Name) { IntPtr server = WTSOpenServer(Name); return server; } public static void CloseServer(IntPtr ServerHandle) { WTSCloseServer(ServerHandle); } public static IntPtr serverHandle = IntPtr.Zero; public static List ListSessions(String ServerName) { List resultList = new List(); serverHandle = OpenServer(ServerName); try { IntPtr SessionInfoPtr = IntPtr.Zero; IntPtr userPtr = IntPtr.Zero; IntPtr domainPtr = IntPtr.Zero; IntPtr ClientName = IntPtr.Zero; IntPtr ClientDisp = IntPtr.Zero; Int32 sessionCount = 0; Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount); Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); Int32 currentSession = (int)SessionInfoPtr; uint bytes = 0; if (retVal != 0) { for (int i = 0; i < sessionCount; i++) { WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO)); currentSession += dataSize; WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes); WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes); WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSClientName, out ClientName, out bytes); WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSApplicationName, out ClientDisp, out bytes); resultList.Add("Domain and User: " + Marshal.PtrToStringAnsi(domainPtr) + "\\" + Marshal.PtrToStringAnsi(userPtr) + " Session ID: " + si.SessionID + " Tipo: " + si.pWinStationName + " Stato : " + si.State + " Client: " + Marshal.PtrToStringAnsi(ClientName) + " Client Disp: " + Marshal.PtrToStringAnsi(ClientDisp)); // cancello i puntatori WTSFreeMemory(userPtr); WTSFreeMemory(domainPtr); WTSFreeMemory(ClientName); WTSFreeMemory(ClientDisp); } WTSFreeMemory(SessionInfoPtr); } } finally { //Terminate_Session(); CloseServer(serverHandle); } return resultList; } // TERMINA LE CONNESSIONI PARTENDO DALL'HANDLE DEL SERVER E DALLA SESSIONID DEL UTENTE private static void Terminate_Session() { Boolean res = LogOffUser(3, serverHandle); Console.WriteLine(res.ToString()); if (!res) Console.WriteLine(Marshal.GetLastWin32Error()); Console.ReadKey(); } internal static bool LogOffUser(int sessionid, IntPtr server) { return WTSDisconnectSession(server, sessionid, true); } } } [/code]

Nessun commento:

Posta un commento