So far the hang-up happens only in Vista. (I haven't tried it under Windows 7 yet.) I tried it a dozen times in XP and it worked fine. So that middle flag isn't even used under Vista.
I did more tests and what seems to help is if I introduce a slight delay between those two APIs:
Well, it's quite obvious you have to give the system some time to log off, like close session related processes and unload user profile. And even more I say, you have to find some more reliable way to understand that logoff is completed (maybe wait on WTS handle or something) than just waiting for a few seconds.
But why not obeying this would deadlock system hibernation, that's the question.
Well, it's quite obvious you have to give the system some time to log off
Yes, I agree.
OK then, in reference to the WTSLogoffSession API, and it's 3rd parameter:
Originally Posted by MSDN
bWait [in]
Indicates whether the operation is synchronous.
If bWait is TRUE, the function returns when the session is logged off.
And as you can see I set it to TRUE.
OK, if we keep reading, there's this:
If bWait is FALSE, the function returns immediately. To verify that the session has been logged off, specify the session identifier in a call to the WTSQuerySessionInformation function. WTSQuerySessionInformation returns zero if the session is logged off.
So I adjust my code like so:
Code:
WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, dwUserSessionID, TRUE);
//Wait for maximum 30 seconds
for(int i = 0; i < 30000; i += 100)
{
LPTSTR pBuff = NULL;
DWORD dwszBuff = 0;
BOOL bGotSessionData = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwUserSessionID, WTSUserName, &pBuff, &dwszBuff);
if(pBuff)
{
WTSFreeMemory(pBuff);
pBuff = NULL;
}
if(!bGotSessionData)
break;
Sleep(100);
}
SetSuspendState(FALSE, TRUE, FALSE);
So what happens above is that the waiting part quits the for() loop almost immediately. (Unfortunately I cannot run a debugger at this point, I can tell this by placing couple logging functions before and after it.)
But on top of that the code above, of polling user sessions (like it is suggested by MSDN) is far from being my favorite. Here's why. Each session has a simplest possible ID. For instance, the one that you're logged in now is probably 1 So if you log off and the system automatically logs in one of its own sessions, guess what ID that session may be assigned ... yes, 1 as well. And what I observed happens under Windows Vista is that right after a user session is logged off almost immediately a new session is created. That session has no name but its status is set as WTSDisconnected or WTSIdle. I don't know what it's used for, that stuff is clearly not documented ...
So at this point I don't know how else to poll user sessions or the system for the "ready" state after the log-off, do you?
And one more thing. I ran the code above (without the waiting part) under Windows 7 and although the sleep function succeeded, when the system woke up and I tried to log in I've presented with a screen I've never seen before, have you? (Screenshot attached.)
The Local Session Manager service failed the logon.
The group or resource is not in the correct state to perform the requested operation.
Last edited by ahmd; January 28th, 2012 at 06:59 PM.
Well, everything you said about session logoff has sounded convincing. Now we have an only undocumented thing with system creating idle session. And I'm inclined to think now that exactly this session may cause the effect you observed. Sorry, I'm not that experienced in WTS stuff, so I hardly could give a hint more informative than this.
Seems like you'd live with 3 second delay so far, until you find an explanation for all this.
That session has no name but its status is set as WTSDisconnected or WTSIdle. I don't know what it's used for,
I would say it might be some performance improving stuff. Rather than start a new session after successful logon, it seems more user friendly to have a session in idle state to inhabit immediately.
So at this point I don't know how else to poll user sessions or the system for the "ready" state after the log-off, do you?
As I already said, I think the session just logged off hardly could affect the hibernation. But automatically started one could do alright.
And one more thing. I ran the code above (without the waiting part) under Windows 7 and although the sleep function succeeded, when the system woke up and I tried to log in I've presented with a screen I've never seen before, have you? (Screenshot attached.)
Thanks for your help, Igor. And, you're right, it seems like I'll have to live with a 3-second delay. That seems to have worked in almost 100% of my trials.
PS. If someone searches out this thread and finds a better solution, please post it here ... I'd be glad to hear your take on this.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.