Check if logoff succeeded before continuing

Check if shutdown succeeded before calling kernel

svn path=/trunk/; revision=23534
This commit is contained in:
Hervé Poussineau 2006-08-09 14:29:12 +00:00
parent 4419e2ce2a
commit 3be6aa3601
3 changed files with 46 additions and 131 deletions

View file

@ -75,6 +75,7 @@ HandleLogon(
return FALSE;
}
/* FIXME: use Session->Profile.pszEnvironment */
/* FIXME: UpdatePerUserSystemParameters(0, TRUE); */
/* Get privilege */
/* FIXME: who should do it? winlogon or gina? */
@ -124,7 +125,7 @@ LogoffShutdownThread(LPVOID Parameter)
{
PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA)Parameter;
if (!ImpersonateLoggedOnUser(LSData->Session->UserToken))
if (LSData->Session->UserToken && !ImpersonateLoggedOnUser(LSData->Session->UserToken))
{
ERR("ImpersonateLoggedOnUser failed with error %lu\n", GetLastError());
return 0;
@ -143,7 +144,8 @@ LogoffShutdownThread(LPVOID Parameter)
/* FIXME: Call ExitWindowsEx() to terminate COM processes */
RevertToSelf();
if (LSData->Session->UserToken)
RevertToSelf();
return 1;
}
@ -155,6 +157,7 @@ HandleLogoff(
{
PLOGOFF_SHUTDOWN_DATA LSData;
HANDLE hThread;
DWORD exitCode;
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS);
@ -172,15 +175,30 @@ HandleLogoff(
hThread = CreateThread(NULL, 0, LogoffShutdownThread, (LPVOID)LSData, 0, NULL);
if (!hThread)
{
ERR("Unable to create shutdown thread, error %lu\n", GetLastError());
ERR("Unable to create logoff thread, error %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, LSData);
return STATUS_UNSUCCESSFUL;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
HeapFree(GetProcessHeap(), 0, LSData);
if (!GetExitCodeThread(hThread, &exitCode))
{
ERR("Unable to get exit code of logoff thread (error %lu)\n", GetLastError());
CloseHandle(hThread);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(hThread);
if (exitCode == 0)
{
ERR("Logoff thread returned failure\n");
return STATUS_UNSUCCESSFUL;
}
//UnloadUserProfile(Session->UserToken, ProfileInfo.hProfile);
//CloseHandle(Session->UserToken);
//UpdatePerUserSystemParameters(0, FALSE);
Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
Session->UserToken = NULL;
return STATUS_SUCCESS;
}
@ -232,6 +250,7 @@ HandleShutdown(
{
PLOGOFF_SHUTDOWN_DATA LSData;
HANDLE hThread;
DWORD exitCode;
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISSHUTTINGDOWN);
@ -259,8 +278,19 @@ HandleShutdown(
return STATUS_UNSUCCESSFUL;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
HeapFree(GetProcessHeap(), 0, LSData);
if (!GetExitCodeThread(hThread, &exitCode))
{
ERR("Unable to get exit code of shutdown thread (error %lu)\n", GetLastError());
CloseHandle(hThread);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(hThread);
if (exitCode == 0)
{
ERR("Shutdown thread returned failure\n");
return STATUS_UNSUCCESSFUL;
}
/* Destroy SAS window */
UninitializeSAS(Session);
@ -315,12 +345,19 @@ DoGenericAction(
SwitchDesktop(WLSession->WinlogonDesktop);
Session->Gina.Functions.WlxLogoff(Session->Gina.Context);
if (!NT_SUCCESS(HandleLogoff(Session, EWX_LOGOFF)))
{
RemoveStatusMessage(Session);
break;
}
}
if (WLX_SHUTTINGDOWN(wlxAction))
{
Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction);
HandleShutdown(Session, wlxAction);
if (!NT_SUCCESS(HandleShutdown(Session, wlxAction)))
{
RemoveStatusMessage(Session);
Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
}
}
else
{

View file

@ -11,7 +11,7 @@
/* INCLUDES *****************************************************************/
#include "winlogon.h"
#define YDEBUG
//#define YDEBUG
#include <wine/debug.h>
/* GLOBALS ******************************************************************/
@ -270,128 +270,6 @@ GetUserInit(
return CommandLine;
}
static BOOL
DoBrokenLogonUser(
IN PWLSESSION WLSession,
IN PWLX_MPR_NOTIFY_INFO pMprNotifyInfo)
{
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo;
WCHAR CommandLine[MAX_PATH];
WCHAR CurrentDirectory[MAX_PATH];
PROFILEINFOW ProfileInfo;
BOOL Result;
LPVOID lpEnvironment = NULL;
MSG Msg;
BOOLEAN Old;
SwitchDesktop(WLSession->ApplicationDesktop);
/* Load the user profile */
ProfileInfo.dwSize = sizeof(PROFILEINFOW);
ProfileInfo.dwFlags = 0;
ProfileInfo.lpUserName = pMprNotifyInfo->pszUserName;
ProfileInfo.lpProfilePath = NULL;
ProfileInfo.lpDefaultPath = NULL;
ProfileInfo.lpServerName = NULL;
ProfileInfo.lpPolicyPath = NULL;
ProfileInfo.hProfile = NULL;
if (!LoadUserProfileW (WLSession->UserToken,
&ProfileInfo))
{
DPRINT1 ("WL: LoadUserProfileW() failed\n");
CloseHandle (WLSession->UserToken);
RtlDestroyEnvironment (lpEnvironment);
return FALSE;
}
if (!CreateEnvironmentBlock (&lpEnvironment,
WLSession->UserToken,
TRUE))
{
DPRINT1("WL: CreateEnvironmentBlock() failed\n");
return FALSE;
}
if (ImpersonateLoggedOnUser(WLSession->UserToken))
{
UpdatePerUserSystemParameters(0, TRUE);
RevertToSelf();
}
GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
/* Get privilege */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
Result = CreateProcessAsUserW(
WLSession->UserToken,
NULL,
GetUserInit (CommandLine, MAX_PATH),
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
lpEnvironment,
CurrentDirectory,
&StartupInfo,
&ProcessInformation);
if (!Result)
{
DPRINT1("WL: Failed to execute user shell %ws\n", CommandLine);
if (ImpersonateLoggedOnUser(WLSession->UserToken))
{
UpdatePerUserSystemParameters(0, FALSE);
RevertToSelf();
}
UnloadUserProfile (WLSession->UserToken,
ProfileInfo.hProfile);
CloseHandle (WLSession->UserToken);
DestroyEnvironmentBlock (lpEnvironment);
return FALSE;
}
/*WLSession->Gina.Functions.WlxActivateUserShell(WLSession->Gina.Context,
L"WinSta0\\Default",
NULL,
NULL);*/
while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0)
{
if (PeekMessage(&Msg, WLSession->SASWindow, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
CloseHandle (ProcessInformation.hProcess);
CloseHandle (ProcessInformation.hThread);
if (ImpersonateLoggedOnUser(WLSession->UserToken))
{
UpdatePerUserSystemParameters(0, FALSE);
RevertToSelf();
}
/* Unload user profile */
UnloadUserProfile (WLSession->UserToken,
ProfileInfo.hProfile);
CloseHandle (WLSession->UserToken);
RtlDestroyEnvironment (lpEnvironment);
return TRUE;
}
#endif
BOOL

View file

@ -12,7 +12,7 @@
#include "winlogon.h"
#define YDEBUG
//#define YDEBUG
#include <wine/debug.h>
static DLGPROC PreviousWindowProc;
@ -323,7 +323,7 @@ WlxCloseUserDesktop(
}
/*
* @unimplemented
* @implemented
*/
BOOL WINAPI
WlxSetOption(