I want my application to hook remote connect and disconnect events for all sessions on the specified computer.
According to the documentation, I should call WTSRegisterSessionNotification
function first:
WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_ALL_SESSIONS);
Then in the messages processor callback I should do the required stuff on WM_WTSSESSION_CHANGE
message type:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_WTSSESSION_CHANGE:
{
// do stuff
break;
}
}
}
It works very strange however. Every time I connect or disconnect to/from the computer where my application running, WTS_REMOTE_CONNECT
or WTS_REMOTE_DISCONNECT
called twice -- in one of these calls I can get user name and in another I can't (it's just an empty string).
case WM_WTSSESSION_CHANGE:
{
const int reason = (int)wParam;
const DWORD sessionId = (DWORD)lParam;
switch (reason)
{
case WTS_REMOTE_CONNECT:
{
DWORD bytesReturned = 0;
LPSTR pData = NULL;
if (WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, &pData, &bytesReturned) == 0)
{
// Handle error
break;
}
const std::string username = pData;
WTSFreeMemory(pData);
// do other stuff
I found this question but it has very strange accepted answer:
Hmm, the answer appears to be that it's fairly normal for these fields to be empty on a terminal services/RDP session
I don't understand why it actually works this way.