I have a program that switches desktop and start a new process on it. When the process exits, the parent process restores the original desktop.
For testing purposes, I put a button in a plain win32 app that triggers the switch. It works, and closing the launched process (notepad), I go back to the original desktop.
In that same program, I have called WTSRegisterSessionNotification to receive a notification when a session is unlocked (WTS_SESSION_UNLOCK). I receive it.
But when I try to switch desktops in WTS_SESSION_UNLOCK message handler, SwitchDesktop fails and GetLastError is 0. The documentation says that last error is usually not set by SwitchDesktop.
Funny enough, if I put my call to switch desktop in a for loop, it works on the 5th iteration.
In short, this does not work :
case WM_WTSSESSION_CHANGE:
if(wParam == WTS_SESSION_UNLOCK)
{
SwitchDesktop(a_valid_desktop_handle);
}
break;
But this ugly hack works :
case WM_WTSSESSION_CHANGE:
if(wParam == WTS_SESSION_UNLOCK)
{
for(int i=0; i<10; ++i)
{
if(SwitchDesktop(a_valid_desktop_handle))
{
//This will work when i == 5, maybe 6.
break;
}
}
}
break;
Setting a timer (to exit the message loop) also works, but it is just a more convoluted form of loop with regards to this problem. SwitchDesktop will work on after a handfull of WM_TIMER messages. It looks like constant time, although I did not measure it.
MSDN documentation for SwitchDesktop mentions that this will fail with a custom Userinit process, which I use. But getting the name of the current desktop just before the switch :
wchar_t name[512];
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, name, sizeof(name)/sizeof(*name), 0);
OutputDebugString(name);
Gives me default
all the time. And since GetLastError
is 0, not 5 (access denied) I am pretty sure the secure desktop is gone before I receive the WTS_SESSION_UNLOCK notification.
I known I can't switch desktop while the screen is locked, but is there a "grace period" after the desktop is unlocked in which I can't call SwitchDesktop ?
I can't test it right now but I would put the call to
SwitchDesktop
not onWTS_SESSION_UNLOCK
but onWTS_CONSOLE_CONNECT
. From what I gatherWTS_SESSION_UNLOCK
occurs first and then your getWTS_CONSOLE_CONNECT
which would correspond to what you see with the "constand time"...