11#pragma comment(lib, "wtsapi32.lib")
39 String TerminalSession::QueryWtsString(
unsigned long uSessionId,
unsigned int eInfoClass) {
41 LPWSTR pBuffer = NULL;
42 DWORD dwBytesReturned = 0;
45 if (::WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, uSessionId,
static_cast<WTS_INFO_CLASS
>(eInfoClass), &pBuffer, &dwBytesReturned)) {
46 if (pBuffer != NULL && dwBytesReturned > 0) {
49 ::WTSFreeMemory(pBuffer);
50 }
else if (::GetLastError() == ERROR_ACCESS_DENIED) {
57 void TerminalSession::QuerySessionDetails(
unsigned long uSessionId,
const String& sSessionName,
RdpSessionState eState,
RdpSessionInfo& info) {
59 info.uSessionId = uSessionId;
60 info.sSessionName = sSessionName;
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");
72 WTS_SESSION_INFOW* pSessionInfo = NULL;
74 if (::WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount)) {
75 for (DWORD i = 0; i < dwCount; ++i) {
77 String sName = (pSessionInfo[i].pWinStationName != NULL) ?
String(pSessionInfo[i].pWinStationName) :
String(
"");
79 QuerySessionDetails(pSessionInfo[i].SessionId, sName, eState, info);
82 ::WTSFreeMemory(pSessionInfo);
83 }
else if (::GetLastError() == ERROR_ACCESS_DENIED) {
98 for (
int i = 0; i < lstAll.GetCount(); ++i) {
108 for (
int i = 0; i < lstAll.GetCount(); ++i) {
111 return lstDisconnected;
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.
void Add(const T &item)
Adds an object to the end of the List.
static Collections::Generic::List< RdpSessionInfo > GetSessions()
Enumerates all terminal sessions on the local system.
virtual ~TerminalSession()
Virtual destructor.
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.
String()
Initializes a new instance of the String class to an empty string.
UnauthorizedAccessException()
Initializes a new instance of the UnauthorizedAccessException class with a default message.
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.
@ Reset
Session is being reset.
@ Unknown
State could not be determined.
@ Init
Session is initializing.
@ 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.