Remove HandleExitWindows, and move its code to HandleLogoff and HandleShutdown

Lots of cleanup

svn path=/trunk/; revision=23530
This commit is contained in:
Hervé Poussineau 2006-08-09 06:31:02 +00:00
parent 844073d973
commit 6007fa59ce
3 changed files with 335 additions and 330 deletions

View file

@ -81,32 +81,202 @@ HandleLogon(
/* FIXME: reverting to lower privileges after creating user shell? */ /* FIXME: reverting to lower privileges after creating user shell? */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old); RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
return Session->Gina.Functions.WlxActivateUserShell( //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS);
//DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
if (!Session->Gina.Functions.WlxActivateUserShell(
Session->Gina.Context, Session->Gina.Context,
L"Default",//NULL, /* FIXME */ L"Default",
NULL, /* FIXME */ NULL, /* FIXME */
lpEnvironment); lpEnvironment))
{
return FALSE;
}
/*if(!GinaInst->Functions->WlxActivateUserShell(GinaInst->Context,
L"WinSta0\\Default",
NULL,
NULL))
{
LoadString(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, 256 * sizeof(WCHAR));
MessageBox(0, StatusMsg, NULL, MB_ICONERROR);
SetEvent(hShutdownEvent);
}
WaitForSingleObject(hShutdownEvent, INFINITE);
CloseHandle(hShutdownEvent);
RemoveStatusMessage(Session);
*/
return TRUE;
}
#define EWX_ACTION_MASK 0xffffffeb
#define EWX_FLAGS_MASK 0x00000014
typedef struct tagLOGOFF_SHUTDOWN_DATA
{
UINT Flags;
PWLSESSION Session;
} LOGOFF_SHUTDOWN_DATA, *PLOGOFF_SHUTDOWN_DATA;
static DWORD WINAPI
LogoffShutdownThread(LPVOID Parameter)
{
PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA)Parameter;
if (!ImpersonateLoggedOnUser(LSData->Session->UserToken))
{
ERR("ImpersonateLoggedOnUser failed with error %lu\n", GetLastError());
return 0;
}
/* Close processes of the interactive user */
if (!ExitWindowsEx(
EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) |
(EWX_LOGOFF == (LSData->Flags & EWX_ACTION_MASK) ? EWX_INTERNAL_FLAG_LOGOFF : 0),
0))
{
ERR("Unable to kill user apps, error %lu\n", GetLastError());
RevertToSelf();
return 0;
}
/* FIXME: Call ExitWindowsEx() to terminate COM processes */
RevertToSelf();
return 1;
}
static NTSTATUS
HandleLogoff(
IN OUT PWLSESSION Session,
IN UINT Flags)
{
PLOGOFF_SHUTDOWN_DATA LSData;
HANDLE hThread;
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS);
/* Prepare data for logoff thread */
LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA));
if (!LSData)
{
ERR("Failed to allocate mem for thread data\n");
return STATUS_NO_MEMORY;
}
LSData->Flags = Flags;
LSData->Session = Session;
/* Run logoff thread */
hThread = CreateThread(NULL, 0, LogoffShutdownThread, (LPVOID)LSData, 0, NULL);
if (!hThread)
{
ERR("Unable to create shutdown thread, error %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, LSData);
return STATUS_UNSUCCESSFUL;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
HeapFree(GetProcessHeap(), 0, LSData);
Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
return STATUS_SUCCESS;
}
static INT_PTR CALLBACK
ShutdownComputerWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_BTNSHTDOWNCOMPUTER:
EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
return TRUE;
}
break;
}
case WM_INITDIALOG:
{
RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
return TRUE;
}
}
return FALSE;
} }
static VOID static VOID
HandleLogoff( UninitializeSAS(
IN OUT PWLSESSION Session) IN OUT PWLSESSION Session)
{ {
FIXME("FIXME: HandleLogoff() unimplemented\n"); if (Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
UnregisterClassW(WINLOGON_SAS_CLASS, hAppInstance);
} }
static BOOL BOOL
HandleShutdown( HandleShutdown(
IN OUT PWLSESSION Session, IN OUT PWLSESSION Session,
IN DWORD wlxAction) IN DWORD wlxAction)
{ {
FIXME("FIXME: HandleShutdown() unimplemented\n"); PLOGOFF_SHUTDOWN_DATA LSData;
HANDLE hThread;
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISSHUTTINGDOWN);
/* Prepare data for shutdown thread */
LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA));
if (!LSData)
{
ERR("Failed to allocate mem for thread data\n");
return STATUS_NO_MEMORY;
}
if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
LSData->Flags = EWX_POWEROFF;
else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
LSData->Flags = EWX_REBOOT;
else
LSData->Flags = EWX_SHUTDOWN;
LSData->Session = Session;
/* Run shutdown thread */
hThread = CreateThread(NULL, 0, LogoffShutdownThread, (LPVOID)LSData, 0, NULL);
if (!hThread)
{
ERR("Unable to create shutdown thread, error %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, LSData);
return STATUS_UNSUCCESSFUL;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
HeapFree(GetProcessHeap(), 0, LSData);
/* Destroy SAS window */
UninitializeSAS(Session);
FIXME("FIXME: Call SMSS API #1\n");
if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT) if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
NtShutdownSystem(ShutdownReboot); NtShutdownSystem(ShutdownReboot);
else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
NtShutdownSystem(ShutdownPowerOff);
else else
{
if (FALSE)
{
/* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerWindowProc);
}
NtShutdownSystem(ShutdownNoReboot); NtShutdownSystem(ShutdownNoReboot);
}
return TRUE; return TRUE;
} }
@ -144,15 +314,19 @@ DoGenericAction(
break; break;
SwitchDesktop(WLSession->WinlogonDesktop); SwitchDesktop(WLSession->WinlogonDesktop);
Session->Gina.Functions.WlxLogoff(Session->Gina.Context); Session->Gina.Functions.WlxLogoff(Session->Gina.Context);
HandleLogoff(Session); if (!NT_SUCCESS(HandleLogoff(Session, EWX_LOGOFF)))
Session->LogonStatus = WKSTA_IS_LOGGED_OFF; break;
Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
} }
if (WLX_SHUTTINGDOWN(wlxAction)) if (WLX_SHUTTINGDOWN(wlxAction))
{ {
Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction); Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction);
HandleShutdown(Session, wlxAction); HandleShutdown(Session, wlxAction);
} }
else
{
RemoveStatusMessage(Session);
Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
}
break; break;
case WLX_SAS_ACTION_TASKLIST: /* 0x07 */ case WLX_SAS_ACTION_TASKLIST: /* 0x07 */
SwitchDesktop(WLSession->ApplicationDesktop); SwitchDesktop(WLSession->ApplicationDesktop);
@ -247,47 +421,8 @@ UnregisterHotKeys(
return TRUE; return TRUE;
} }
#define EWX_ACTION_MASK 0xffffffeb
#define EWX_FLAGS_MASK 0x00000014
typedef struct tagLOGOFF_SHUTDOWN_DATA
{
UINT Flags;
PWLSESSION Session;
} LOGOFF_SHUTDOWN_DATA, *PLOGOFF_SHUTDOWN_DATA;
static DWORD WINAPI
LogoffShutdownThread(LPVOID Parameter)
{
PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA) Parameter;
if (!ImpersonateLoggedOnUser(LSData->Session->UserToken))
{
ERR("ImpersonateLoggedOnUser failed with error %lu\n", GetLastError());
return 0;
}
/* Close processes of the interactive user */
if (!ExitWindowsEx(
EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) |
(EWX_LOGOFF == (LSData->Flags & EWX_ACTION_MASK) ? EWX_INTERNAL_FLAG_LOGOFF : 0),
0))
{
ERR("Unable to kill user apps, error %lu\n", GetLastError());
RevertToSelf();
return 0;
}
/* FIXME: Call ExitWindowsEx() to terminate COM processes */
RevertToSelf();
return 1;
}
static NTSTATUS static NTSTATUS
CheckPrivilegeForRequestedAction( CheckForShutdownPrivilege(
IN UINT Action,
IN DWORD RequestingProcessId) IN DWORD RequestingProcessId)
{ {
HANDLE Process; HANDLE Process;
@ -295,18 +430,7 @@ CheckPrivilegeForRequestedAction(
BOOL CheckResult; BOOL CheckResult;
PPRIVILEGE_SET PrivSet; PPRIVILEGE_SET PrivSet;
TRACE("CheckPrivilegeForRequestedAction(%u)\n", Action); TRACE("CheckForShutdownPrivilege()\n");
if (Action == EWX_LOGOFF)
/* No privilege needed to log off */
return STATUS_SUCCESS;
/* Check for invalid arguments */
if (Action != EWX_SHUTDOWN && Action != EWX_REBOOT && Action != EWX_POWEROFF)
{
ERR("Invalid exit action %u\n", Action);
return STATUS_INVALID_PARAMETER;
}
Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, RequestingProcessId); Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, RequestingProcessId);
if (!Process) if (!Process)
@ -354,71 +478,6 @@ CheckPrivilegeForRequestedAction(
} }
} }
static LRESULT
HandleExitWindows(
IN OUT PWLSESSION Session,
IN DWORD RequestingProcessId,
IN UINT Flags)
{
UINT Action;
PLOGOFF_SHUTDOWN_DATA LSData;
HANDLE hThread;
NTSTATUS Status;
/* Check parameters */
Action = Flags & EWX_ACTION_MASK;
if (Action != EWX_LOGOFF &&
Action != EWX_SHUTDOWN &&
Action != EWX_REBOOT &&
Action != EWX_POWEROFF)
{
ERR("Invalid ExitWindows action 0x%x\n", Action);
return STATUS_INVALID_PARAMETER;
}
/* Check privilege */
Status = CheckPrivilegeForRequestedAction(Action, RequestingProcessId);
if (!NT_SUCCESS(Status))
return Status;
/* Prepare data for logoff/shutdown thread */
LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA));
if (!LSData)
{
ERR("Failed to allocate mem for thread data\n");
return STATUS_NO_MEMORY;
}
LSData->Flags = Flags;
LSData->Session = Session;
/* Run logoff/shutdown thread */
hThread = CreateThread(NULL, 0, LogoffShutdownThread, (LPVOID)LSData, 0, NULL);
if (!hThread)
{
ERR("Unable to create shutdown thread, error %lu\n", GetLastError());
HeapFree(GetProcessHeap(), 0, LSData);
return STATUS_UNSUCCESSFUL;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
HeapFree(GetProcessHeap(), 0, LSData);
Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
if (Action == EWX_LOGOFF)
{
DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT);
return 1;
}
/* Handle shutdown */
FIXME("FIXME: Call ExitWindowEx in SYSTEM process context\n");
FIXME("FIXME: Call SMSS API #1\n");
NtShutdownSystem(ShutdownNoReboot); /* FIXME: should go in smss */
return 1;
}
static LRESULT CALLBACK static LRESULT CALLBACK
SASWindowProc( SASWindowProc(
IN HWND hwndDlg, IN HWND hwndDlg,
@ -468,24 +527,38 @@ SASWindowProc(
} }
case PM_WINLOGON_EXITWINDOWS: case PM_WINLOGON_EXITWINDOWS:
{ {
return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam); UINT Flags = (UINT)lParam;
UINT Action = Flags & EWX_ACTION_MASK;
DWORD wlxAction;
/* Check parameters */
switch (Action)
{
case EWX_LOGOFF: wlxAction = WLX_SAS_ACTION_LOGOFF; break;
case EWX_SHUTDOWN: wlxAction = WLX_SAS_ACTION_SHUTDOWN; break;
case EWX_REBOOT: wlxAction = WLX_SAS_ACTION_SHUTDOWN_REBOOT; break;
case EWX_POWEROFF: wlxAction = WLX_SAS_ACTION_SHUTDOWN_POWER_OFF; break;
default:
{
ERR("Invalid ExitWindows action 0x%x\n", Action);
return STATUS_INVALID_PARAMETER;
}
}
if (WLX_SHUTTINGDOWN(wlxAction))
{
NTSTATUS Status = CheckForShutdownPrivilege((DWORD)wParam);
if (!NT_SUCCESS(Status))
return Status;
}
DoGenericAction(Session, wlxAction);
return 1;
} }
} }
return DefWindowProc(hwndDlg, uMsg, wParam, lParam); return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
} }
static VOID
UninitializeSAS(
IN OUT PWLSESSION Session)
{
if (Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
}
BOOL BOOL
InitializeSAS( InitializeSAS(
IN OUT PWLSESSION Session) IN OUT PWLSESSION Session)
@ -506,10 +579,13 @@ InitializeSAS(
swc.lpszMenuName = NULL; swc.lpszMenuName = NULL;
swc.lpszClassName = WINLOGON_SAS_CLASS; swc.lpszClassName = WINLOGON_SAS_CLASS;
swc.hIconSm = NULL; swc.hIconSm = NULL;
RegisterClassExW(&swc); /* FIXME: check return code */ if (RegisterClassExW(&swc) == 0)
{
ERR("WL: Failed to register SAS window class\n");
return FALSE;
}
/* create invisible SAS window */ /* create invisible SAS window */
DPRINT1("Session %p\n", Session);
Session->SASWindow = CreateWindowExW( Session->SASWindow = CreateWindowExW(
0, 0,
WINLOGON_SAS_CLASS, WINLOGON_SAS_CLASS,
@ -520,6 +596,7 @@ InitializeSAS(
if (!Session->SASWindow) if (!Session->SASWindow)
{ {
ERR("WL: Failed to create SAS window\n"); ERR("WL: Failed to create SAS window\n");
UninitializeSAS(Session);
return FALSE; return FALSE;
} }

View file

@ -21,104 +21,70 @@ PWLSESSION WLSession = NULL;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static INT_PTR CALLBACK
ShutdownComputerWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_BTNSHTDOWNCOMPUTER:
EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
return TRUE;
}
break;
}
case WM_INITDIALOG:
{
RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
return TRUE;
}
}
return FALSE;
}
static BOOL static BOOL
StartServicesManager(VOID) StartServicesManager(VOID)
{ {
HANDLE ServicesInitEvent; HANDLE ServicesInitEvent;
BOOLEAN Result; STARTUPINFOW StartupInfo;
STARTUPINFOW StartupInfo; PROCESS_INFORMATION ProcessInformation;
PROCESS_INFORMATION ProcessInformation; DWORD Count;
DWORD Count; LPCWSTR ServiceString = L"services.exe";
WCHAR ServiceString[] = L"services.exe"; BOOL res;
/* Start the service control manager (services.exe) */ /* Start the service control manager (services.exe) */
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
StartupInfo.cb = sizeof(StartupInfo); TRACE("WL: Creating new process - %S\n", ServiceString);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
#if 0 res = CreateProcessW(
DPRINT1(L"WL: Creating new process - \"services.exe\".\n"); ServiceString,
#endif NULL,
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if (!res)
{
ERR("WL: Failed to execute services (error %lu)\n", GetLastError());
return FALSE;
}
Result = CreateProcessW(NULL, /* Wait for event creation (by SCM) for max. 20 seconds */
ServiceString, for (Count = 0; Count < 20; Count++)
NULL, {
NULL, Sleep(1000);
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if (!Result)
{
DPRINT1("WL: Failed to execute services\n");
return FALSE;
}
/* wait for event creation (by SCM) for max. 20 seconds */ TRACE("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
for (Count = 0; Count < 20; Count++) ServicesInitEvent = OpenEventW(
{ EVENT_ALL_ACCESS, //SYNCHRONIZE,
Sleep(1000); FALSE,
L"SvcctrlStartEvent_A3725DX");
if (ServicesInitEvent)
break;
}
DPRINT("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n"); if (!ServicesInitEvent)
ServicesInitEvent = OpenEventW(EVENT_ALL_ACCESS, //SYNCHRONIZE, {
FALSE, ERR("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
L"SvcctrlStartEvent_A3725DX"); return FALSE;
if (ServicesInitEvent != NULL) }
{
break;
}
}
if (ServicesInitEvent == NULL) /* Wait for event signalization */
{ WaitForSingleObject(ServicesInitEvent, INFINITE);
DPRINT1("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n"); CloseHandle(ServicesInitEvent);
return FALSE; TRACE("WL: StartServicesManager() done.\n");
}
/* wait for event signalization */ return TRUE;
DPRINT("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
WaitForSingleObject(ServicesInitEvent, INFINITE);
DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
CloseHandle(ServicesInitEvent);
DPRINT("WL: StartServicesManager() Done.\n");
return TRUE;
} }
static BOOL static BOOL
@ -428,7 +394,7 @@ DoBrokenLogonUser(
} }
#endif #endif
static BOOL BOOL
DisplayStatusMessage( DisplayStatusMessage(
IN PWLSESSION Session, IN PWLSESSION Session,
IN HDESK hDesktop, IN HDESK hDesktop,
@ -436,6 +402,9 @@ DisplayStatusMessage(
{ {
WCHAR StatusMsg[MAX_PATH]; WCHAR StatusMsg[MAX_PATH];
if (Session->Gina.Version < WLX_VERSION_1_3)
return TRUE;
if (Session->SuppressStatus) if (Session->SuppressStatus)
return TRUE; return TRUE;
@ -445,66 +414,14 @@ DisplayStatusMessage(
return Session->Gina.Functions.WlxDisplayStatusMessage(Session->Gina.Context, hDesktop, 0, NULL, StatusMsg); return Session->Gina.Functions.WlxDisplayStatusMessage(Session->Gina.Context, hDesktop, 0, NULL, StatusMsg);
} }
static VOID BOOL
SessionLoop( RemoveStatusMessage(
IN OUT PWLSESSION Session) IN PWLSESSION Session)
{ {
//WCHAR StatusMsg[256]; if (Session->Gina.Version < WLX_VERSION_1_3)
//HANDLE hShutdownEvent; return TRUE;
MSG Msg;
Session->LogonStatus = WKSTA_IS_LOGGED_OFF; return Session->Gina.Functions.WlxRemoveStatusMessage(Session->Gina.Context);
RemoveStatusMessage(Session);
DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT);
/* Message loop for the SAS window */
while (GetMessage(&Msg, WLSession->SASWindow, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
/* Don't go there! */
/*
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
Sleep(150);
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
Sleep(150);
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS);
Sleep(150);
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
Sleep(150);
RemoveStatusMessage(Session);
if(!GinaInst->Functions->WlxActivateUserShell(GinaInst->Context,
L"WinSta0\\Default",
NULL,
NULL))
{
LoadString(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, 256 * sizeof(WCHAR));
MessageBox(0, StatusMsg, NULL, MB_ICONERROR);
SetEvent(hShutdownEvent);
}
WaitForSingleObject(hShutdownEvent, INFINITE);
CloseHandle(hShutdownEvent);
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS);
Sleep(150);
GinaInst->Functions->WlxShutdown(GinaInst->Context, WLX_SAS_ACTION_SHUTDOWN);
DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISSHUTTINGDOWN);
Sleep(250);
RemoveStatusMessage(Session);
*/
} }
static INT_PTR CALLBACK static INT_PTR CALLBACK
@ -565,20 +482,24 @@ WinMain(
ULONG AuthenticationPackage; ULONG AuthenticationPackage;
NTSTATUS Status; NTSTATUS Status;
#endif #endif
MSG Msg;
hAppInstance = hInstance; hAppInstance = hInstance;
if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
{ {
ERR("WL: Could not register logon process\n"); ERR("WL: Could not register logon process\n");
HandleShutdown(NULL, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
NtShutdownSystem(ShutdownNoReboot); NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0); ExitProcess(0);
return 0; return 0;
} }
WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION)); WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION));
ZeroMemory(WLSession, sizeof(WLSESSION));
if (!WLSession) if (!WLSession)
{ {
ERR("WL: Could not allocate memory for winlogon instance\n");
NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(1); ExitProcess(1);
return 1; return 1;
@ -587,6 +508,7 @@ WinMain(
if (!CreateWindowStationAndDesktops(WLSession)) if (!CreateWindowStationAndDesktops(WLSession))
{ {
ERR("WL: Could not create window station and desktops\n");
NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(1); ExitProcess(1);
return 1; return 1;
@ -596,9 +518,9 @@ WinMain(
if (!StartServicesManager()) if (!StartServicesManager())
{ {
ERR("WL: Could not start services.exe\n"); ERR("WL: Could not start services.exe\n");
NtShutdownSystem(ShutdownNoReboot); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(0); ExitProcess(1);
return 0; return 1;
} }
/* Check for pending setup */ /* Check for pending setup */
@ -610,7 +532,7 @@ WinMain(
SwitchDesktop(WLSession->ApplicationDesktop); SwitchDesktop(WLSession->ApplicationDesktop);
RunSetup(); RunSetup();
NtShutdownSystem(ShutdownReboot); HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
ExitProcess(0); ExitProcess(0);
return 0; return 0;
} }
@ -618,6 +540,8 @@ WinMain(
if (!StartLsass()) if (!StartLsass())
{ {
DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError()); DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(1);
return 1; return 1;
} }
@ -626,9 +550,9 @@ WinMain(
{ {
ERR("WL: Failed to initialize Gina\n"); ERR("WL: Failed to initialize Gina\n");
DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)L""); DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)L"");
NtShutdownSystem(ShutdownReboot); HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
ExitProcess(0); ExitProcess(1);
return 0; return 1;
} }
DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
@ -673,30 +597,22 @@ WinMain(
return 2; return 2;
} }
/* Main loop */ //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
SessionLoop(WLSession); //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
/* FIXME - Flush disks and registry, ... */ /* Display logged out screen */
WLSession->LogonStatus = WKSTA_IS_LOGGED_OFF;
RemoveStatusMessage(WLSession);
DispatchSAS(WLSession, WLX_SAS_TYPE_TIMEOUT);
if(WLSession->LogonStatus == 0) /* Message loop for the SAS window */
{ while (GetMessage(&Msg, WLSession->SASWindow, 0, 0))
/* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */ {
switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerWindowProc)) TranslateMessage(&Msg);
{ DispatchMessage(&Msg);
case IDC_BTNSHTDOWNCOMPUTER: }
NtShutdownSystem(ShutdownReboot);
break;
default:
NtShutdownSystem(ShutdownNoReboot);
break;
}
ExitProcess(0);
}
else
{
DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n");
ExitProcess(0);
}
return 0; /* We never go there */
return 0;
} }

View file

@ -71,7 +71,7 @@ typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID);
typedef struct _GINAFUNCTIONS typedef struct _GINAFUNCTIONS
{ {
/* Functions always available for a valid GINA */ /* Functions always available for a valid GINA */
PFWLXNEGOTIATE WlxNegotiate; PFWLXNEGOTIATE WlxNegotiate; /* optional */
PFWLXINITIALIZE WlxInitialize; PFWLXINITIALIZE WlxInitialize;
/* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */ /* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */
@ -87,15 +87,15 @@ typedef struct _GINAFUNCTIONS
PFWLXSHUTDOWN WlxShutdown; PFWLXSHUTDOWN WlxShutdown;
/* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */ /* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */
PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; /* optional, not called ATM */
PFWLXSTARTAPPLICATION WlxStartApplication; PFWLXSTARTAPPLICATION WlxStartApplication; /* optional, not called ATM */
/* Functions available if WlxVersion >= WLX_VERSION_1_2 (MS Windows NT 4.0) */ /* Functions available if WlxVersion >= WLX_VERSION_1_2 (MS Windows NT 4.0) */
/* Functions available if WlxVersion >= WLX_VERSION_1_3 (MS Windows 2000) */ /* Functions available if WlxVersion >= WLX_VERSION_1_3 (MS Windows 2000) */
PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad; PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad; /* not called ATM */
PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage; PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage;
PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; /* doesn't need to be called */
PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage; PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage;
/* Functions available if WlxVersion >= WLX_VERSION_1_4 (MS Windows XP) */ /* Functions available if WlxVersion >= WLX_VERSION_1_4 (MS Windows XP) */
@ -111,6 +111,7 @@ typedef struct _GINAINSTANCE
} GINAINSTANCE, *PGINAINSTANCE; } GINAINSTANCE, *PGINAINSTANCE;
/* FIXME: put in an enum */ /* FIXME: put in an enum */
/* See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthn/security/winlogon_states.asp */
#define WKSTA_IS_LOGGED_OFF 0 #define WKSTA_IS_LOGGED_OFF 0
#define WKSTA_IS_LOGGED_ON 1 #define WKSTA_IS_LOGGED_ON 1
#define WKSTA_IS_LOCKED 2 #define WKSTA_IS_LOCKED 2
@ -157,11 +158,6 @@ extern PWLSESSION WLSession;
((Status) == WLX_SAS_ACTION_SHUTDOWN_HIBERNATE) \ ((Status) == WLX_SAS_ACTION_SHUTDOWN_HIBERNATE) \
) )
#define RemoveStatusMessage(Session) \
Session->Gina.Functions.WlxRemoveStatusMessage(Session->Gina.Context);
#define DisplaySASNotice(Session) \
Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
/* user32 */ /* user32 */
BOOL WINAPI BOOL WINAPI
UpdatePerUserSystemParameters(DWORD dwUnknown, UpdatePerUserSystemParameters(DWORD dwUnknown,
@ -176,6 +172,17 @@ BOOL
InitializeSAS( InitializeSAS(
IN OUT PWLSESSION Session); IN OUT PWLSESSION Session);
/* winlogon.c */
BOOL
DisplayStatusMessage(
IN PWLSESSION Session,
IN HDESK hDesktop,
IN UINT ResourceId);
BOOL
RemoveStatusMessage(
IN PWLSESSION Session);
/* wlx.c */ /* wlx.c */
BOOL BOOL
GinaInit( GinaInit(
@ -184,6 +191,11 @@ BOOL
CreateWindowStationAndDesktops( CreateWindowStationAndDesktops(
IN OUT PWLSESSION Session); IN OUT PWLSESSION Session);
BOOL
HandleShutdown(
IN OUT PWLSESSION Session,
IN DWORD wlxAction);
VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx); VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx);
VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext); VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext);
VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType); VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType);