Per the documentation for WTSIsRemoteSession
:
WTSIsRemoteSession
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
.
Windows Server 2008 and Windows Vista: This value is not supported.
This implies that the return value of WTSQuerySessionInformation()
holds the value you are looking for, and whatever memory the function may allocate, if any, is secondary and should be ignored when querying WTSIsRemoteSession
, eg:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
bool isRDP = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen);
if ((!isRDP) && (GetLastError() != 0))
{
// Do some error handling...
return;
}
if (pSessionInfo)
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}
However, if you find that isRDP
is always true in this case, then the documentation is misleading and you should check the contents of the pSessionInfo
buffer instead. You are setting your isRDP
variable based on whether WTSQuerySessionInformation()
allocates any memory at all, you are not looking at what is actually inside the data.
For instance, assuming dataLen
is being set to sizeof(BOOL)
on output then cast your pSessionInfo
pointer to a BOOL*
pointer and dereference it, eg:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen))
{
// Do some error handling...
return;
}
bool isRDP = * (BOOL*) pSessionInfo;
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}
Alternatively:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
BOOL *isRDP = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, (LPWSTR*)&isRDP, &dataLen))
{
// Do some error handling...
return;
}
// use *isRDP as needed...
WTSFreeMemory(isRDP);
...
}
UPDATE:
On the other hand, if dataLen
is instead being set to sizeof(UCHAR)
on output then cast your pSessionInfo
pointer to a UCHAR*
pointer and dereference it, eg:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
LPWSTR *pSessionInfo = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, &pSessionInfo, &dataLen))
{
// Do some error handling...
return;
}
bool isRDP = * (UCHAR*) pSessionInfo;
WTSFreeMemory(pSessionInfo);
// use isRDP as needed...
...
}
Alternatively:
VOID SessionChangeHandler(DWORD reason, DWORD sessionId)
{
UCHAR *isRDP = nullptr;
DWORD dataLen = 0;
if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSIsRemoteSession, (LPWSTR*)&isRDP, &dataLen))
{
// Do some error handling...
return;
}
// use *isRDP as needed...
WTSFreeMemory(isRDP);
...
}