DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
TerminalSession.cpp
Go to the documentation of this file.
1#include "pch.h"
5#include <vector>
6
7#if defined(_WIN32)
8#include <winsock2.h>
9#include <windows.h>
10#include <wtsapi32.h>
11#pragma comment(lib, "wtsapi32.lib")
12#endif
13
14namespace DotNetDupe {
15 namespace System {
16 namespace Diagnostics {
17
20
21#if defined(_WIN32)
22 RdpSessionState TerminalSession::ConvertWtsState(int iState) {
24 switch (iState) {
25 case WTSActive: return RdpSessionState::Active;
26 case WTSConnected: return RdpSessionState::Connected;
27 case WTSConnectQuery: return RdpSessionState::ConnectQuery;
28 case WTSShadow: return RdpSessionState::Shadow;
29 case WTSDisconnected: return RdpSessionState::Disconnected;
30 case WTSIdle: return RdpSessionState::Idle;
31 case WTSListen: return RdpSessionState::Listen;
32 case WTSReset: return RdpSessionState::Reset;
33 case WTSDown: return RdpSessionState::Down;
34 case WTSInit: return RdpSessionState::Init;
35 default: return RdpSessionState::Unknown;
36 }
37 }
38
39 String TerminalSession::QueryWtsString(unsigned long uSessionId, unsigned int eInfoClass) {
41 LPWSTR pBuffer = NULL;
42 DWORD dwBytesReturned = 0;
43 String sResult;
44
45 if (::WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, uSessionId, static_cast<WTS_INFO_CLASS>(eInfoClass), &pBuffer, &dwBytesReturned)) {
46 if (pBuffer != NULL && dwBytesReturned > 0) {
47 sResult = String(pBuffer);
48 }
49 ::WTSFreeMemory(pBuffer);
50 } else if (::GetLastError() == ERROR_ACCESS_DENIED) {
51 throw UnauthorizedAccessException("Access denied querying terminal session information.");
52 }
53
54 return sResult;
55 }
56
57 void TerminalSession::QuerySessionDetails(unsigned long uSessionId, const String& sSessionName, RdpSessionState eState, RdpSessionInfo& info) {
59 info.uSessionId = uSessionId;
60 info.sSessionName = sSessionName;
61 info.eState = eState;
62 info.sUserName = QueryWtsString(uSessionId, WTSUserName);
63 info.sDomainName = QueryWtsString(uSessionId, WTSDomainName);
64 info.sClientName = QueryWtsString(uSessionId, WTSClientName);
65 info.sClientIpAddress = QueryWtsString(uSessionId, WTSClientAddress);
66 info.bIsRdpSession = !info.sClientName.IsEmpty() || info.sSessionName.Contains("RDP");
67 }
68
72 WTS_SESSION_INFOW* pSessionInfo = NULL;
73 DWORD dwCount = 0;
74 if (::WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount)) {
75 for (DWORD i = 0; i < dwCount; ++i) {
76 RdpSessionInfo info;
77 String sName = (pSessionInfo[i].pWinStationName != NULL) ? String(pSessionInfo[i].pWinStationName) : String("");
78 RdpSessionState eState = ConvertWtsState(pSessionInfo[i].State);
79 QuerySessionDetails(pSessionInfo[i].SessionId, sName, eState, info);
80 lstResult.Add(info);
81 }
82 ::WTSFreeMemory(pSessionInfo);
83 } else if (::GetLastError() == ERROR_ACCESS_DENIED) {
84 throw UnauthorizedAccessException("Access denied enumerating terminal sessions. Administrator privileges required.");
85 }
86 return lstResult;
87 }
88#else
91 }
92#endif
93
96 auto lstAll = GetSessions();
98 for (int i = 0; i < lstAll.GetCount(); ++i) {
99 if (lstAll[i].eState == RdpSessionState::Active) lstActive.Add(lstAll[i]);
100 }
101 return lstActive;
102 }
103
106 auto lstAll = GetSessions();
108 for (int i = 0; i < lstAll.GetCount(); ++i) {
109 if (lstAll[i].eState == RdpSessionState::Disconnected) lstDisconnected.Add(lstAll[i]);
110 }
111 return lstDisconnected;
112 }
113
114 }
115 }
116}
Utility routines for high-performance UTF-8, UTF-16, and wide-character string conversions.
The exception that is thrown when the operating system denies access because of an I/O error or a spe...
Represents a strongly typed list of objects accessible by index.
Definition List.h:29
void Add(const T &item)
Adds an object to the end of the List.
Definition List.h:138
static Collections::Generic::List< RdpSessionInfo > GetSessions()
Enumerates all terminal sessions on the local system.
static Collections::Generic::List< RdpSessionInfo > GetDisconnectedSessions()
Enumerates disconnected terminal sessions available for reconnection.
static Collections::Generic::List< RdpSessionInfo > GetActiveSessions()
Enumerates only actively connected terminal sessions.
TerminalSession()
Initializes a new instance of TerminalSession.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
Definition String.h:74
String()
Initializes a new instance of the String class to an empty string.
Definition String.cpp:64
UnauthorizedAccessException()
Initializes a new instance of the UnauthorizedAccessException class with a default message.
Definition Exception.cpp:52
RdpSessionState
Represents the operational connection state of a Remote Desktop or Terminal session.
@ Down
Session is down or non-operational.
@ Connected
Client is connected to terminal session but logon not yet completed.
@ Shadow
Session is being shadowed by another session.
@ Active
User is logged on and actively interacting with the session.
@ Listen
Session is listening for incoming client connections.
@ Idle
Session is waiting for connection.
@ Disconnected
Session is disconnected but state preserved for reconnection.
@ ConnectQuery
Session is in process of connecting to client.
Contains extended telemetry for a Remote Desktop Protocol (RDP) session.