diff --git a/reactos/base/system/winlogon/sas.c b/reactos/base/system/winlogon/sas.c index b8d17d15564..9b7483aa534 100644 --- a/reactos/base/system/winlogon/sas.c +++ b/reactos/base/system/winlogon/sas.c @@ -81,32 +81,202 @@ HandleLogon( /* FIXME: reverting to lower privileges after creating user shell? */ 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, - L"Default",//NULL, /* FIXME */ + L"Default", 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 -HandleLogoff( +UninitializeSAS( 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( IN OUT PWLSESSION Session, 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) NtShutdownSystem(ShutdownReboot); - else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF) - NtShutdownSystem(ShutdownPowerOff); 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); + } return TRUE; } @@ -144,15 +314,19 @@ DoGenericAction( break; SwitchDesktop(WLSession->WinlogonDesktop); Session->Gina.Functions.WlxLogoff(Session->Gina.Context); - HandleLogoff(Session); - Session->LogonStatus = WKSTA_IS_LOGGED_OFF; - Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context); + if (!NT_SUCCESS(HandleLogoff(Session, EWX_LOGOFF))) + break; } if (WLX_SHUTTINGDOWN(wlxAction)) { Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction); HandleShutdown(Session, wlxAction); } + else + { + RemoveStatusMessage(Session); + Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context); + } break; case WLX_SAS_ACTION_TASKLIST: /* 0x07 */ SwitchDesktop(WLSession->ApplicationDesktop); @@ -247,47 +421,8 @@ UnregisterHotKeys( 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 -CheckPrivilegeForRequestedAction( - IN UINT Action, +CheckForShutdownPrivilege( IN DWORD RequestingProcessId) { HANDLE Process; @@ -295,18 +430,7 @@ CheckPrivilegeForRequestedAction( BOOL CheckResult; PPRIVILEGE_SET PrivSet; - TRACE("CheckPrivilegeForRequestedAction(%u)\n", Action); - - 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; - } + TRACE("CheckForShutdownPrivilege()\n"); Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, RequestingProcessId); 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 SASWindowProc( IN HWND hwndDlg, @@ -468,24 +527,38 @@ SASWindowProc( } 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); } -static VOID -UninitializeSAS( - IN OUT PWLSESSION Session) -{ - if (Session->SASWindow) - { - DestroyWindow(Session->SASWindow); - Session->SASWindow = NULL; - } -} - BOOL InitializeSAS( IN OUT PWLSESSION Session) @@ -506,10 +579,13 @@ InitializeSAS( swc.lpszMenuName = NULL; swc.lpszClassName = WINLOGON_SAS_CLASS; 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 */ - DPRINT1("Session %p\n", Session); Session->SASWindow = CreateWindowExW( 0, WINLOGON_SAS_CLASS, @@ -520,6 +596,7 @@ InitializeSAS( if (!Session->SASWindow) { ERR("WL: Failed to create SAS window\n"); + UninitializeSAS(Session); return FALSE; } diff --git a/reactos/base/system/winlogon/winlogon.c b/reactos/base/system/winlogon/winlogon.c index d3814fef72c..ed1381c6e6d 100644 --- a/reactos/base/system/winlogon/winlogon.c +++ b/reactos/base/system/winlogon/winlogon.c @@ -21,104 +21,70 @@ PWLSESSION WLSession = NULL; /* 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 StartServicesManager(VOID) { - HANDLE ServicesInitEvent; - BOOLEAN Result; - STARTUPINFOW StartupInfo; - PROCESS_INFORMATION ProcessInformation; - DWORD Count; - WCHAR ServiceString[] = L"services.exe"; + HANDLE ServicesInitEvent; + STARTUPINFOW StartupInfo; + PROCESS_INFORMATION ProcessInformation; + DWORD Count; + LPCWSTR 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); - StartupInfo.lpReserved = NULL; - StartupInfo.lpDesktop = NULL; - StartupInfo.lpTitle = NULL; - StartupInfo.dwFlags = 0; - StartupInfo.cbReserved2 = 0; - StartupInfo.lpReserved2 = 0; + TRACE("WL: Creating new process - %S\n", ServiceString); -#if 0 - DPRINT1(L"WL: Creating new process - \"services.exe\".\n"); -#endif + res = CreateProcessW( + ServiceString, + 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, - ServiceString, - NULL, - NULL, - 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 */ + for (Count = 0; Count < 20; Count++) + { + Sleep(1000); - /* wait for event creation (by SCM) for max. 20 seconds */ - for (Count = 0; Count < 20; Count++) - { - Sleep(1000); + TRACE("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n"); + ServicesInitEvent = OpenEventW( + EVENT_ALL_ACCESS, //SYNCHRONIZE, + FALSE, + L"SvcctrlStartEvent_A3725DX"); + if (ServicesInitEvent) + break; + } - DPRINT("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n"); - ServicesInitEvent = OpenEventW(EVENT_ALL_ACCESS, //SYNCHRONIZE, - FALSE, - L"SvcctrlStartEvent_A3725DX"); - if (ServicesInitEvent != NULL) - { - break; - } - } + if (!ServicesInitEvent) + { + ERR("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n"); + return FALSE; + } - if (ServicesInitEvent == NULL) - { - DPRINT1("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n"); - return FALSE; - } + /* Wait for event signalization */ + WaitForSingleObject(ServicesInitEvent, INFINITE); + CloseHandle(ServicesInitEvent); + TRACE("WL: StartServicesManager() done.\n"); - /* wait for event signalization */ - 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; + return TRUE; } static BOOL @@ -428,7 +394,7 @@ DoBrokenLogonUser( } #endif -static BOOL +BOOL DisplayStatusMessage( IN PWLSESSION Session, IN HDESK hDesktop, @@ -436,6 +402,9 @@ DisplayStatusMessage( { WCHAR StatusMsg[MAX_PATH]; + if (Session->Gina.Version < WLX_VERSION_1_3) + return TRUE; + if (Session->SuppressStatus) return TRUE; @@ -445,66 +414,14 @@ DisplayStatusMessage( return Session->Gina.Functions.WlxDisplayStatusMessage(Session->Gina.Context, hDesktop, 0, NULL, StatusMsg); } -static VOID -SessionLoop( - IN OUT PWLSESSION Session) +BOOL +RemoveStatusMessage( + IN PWLSESSION Session) { - //WCHAR StatusMsg[256]; - //HANDLE hShutdownEvent; - MSG Msg; + if (Session->Gina.Version < WLX_VERSION_1_3) + return TRUE; - Session->LogonStatus = WKSTA_IS_LOGGED_OFF; - 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); - */ + return Session->Gina.Functions.WlxRemoveStatusMessage(Session->Gina.Context); } static INT_PTR CALLBACK @@ -565,20 +482,24 @@ WinMain( ULONG AuthenticationPackage; NTSTATUS Status; #endif + MSG Msg; hAppInstance = hInstance; if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) { ERR("WL: Could not register logon process\n"); + HandleShutdown(NULL, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF); NtShutdownSystem(ShutdownNoReboot); ExitProcess(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) { + ERR("WL: Could not allocate memory for winlogon instance\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); return 1; @@ -587,6 +508,7 @@ WinMain( if (!CreateWindowStationAndDesktops(WLSession)) { + ERR("WL: Could not create window station and desktops\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); ExitProcess(1); return 1; @@ -596,9 +518,9 @@ WinMain( if (!StartServicesManager()) { ERR("WL: Could not start services.exe\n"); - NtShutdownSystem(ShutdownNoReboot); - ExitProcess(0); - return 0; + NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); + ExitProcess(1); + return 1; } /* Check for pending setup */ @@ -610,7 +532,7 @@ WinMain( SwitchDesktop(WLSession->ApplicationDesktop); RunSetup(); - NtShutdownSystem(ShutdownReboot); + HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); ExitProcess(0); return 0; } @@ -618,6 +540,8 @@ WinMain( if (!StartLsass()) { 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; } @@ -626,9 +550,9 @@ WinMain( { ERR("WL: Failed to initialize Gina\n"); DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)L""); - NtShutdownSystem(ShutdownReboot); - ExitProcess(0); - return 0; + HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); + ExitProcess(1); + return 1; } DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); @@ -673,30 +597,22 @@ WinMain( return 2; } - /* Main loop */ - SessionLoop(WLSession); + //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS); + //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) - { - /* 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)) - { - case IDC_BTNSHTDOWNCOMPUTER: - NtShutdownSystem(ShutdownReboot); - break; - default: - NtShutdownSystem(ShutdownNoReboot); - break; - } - ExitProcess(0); - } - else - { - DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n"); - ExitProcess(0); - } + /* Message loop for the SAS window */ + while (GetMessage(&Msg, WLSession->SASWindow, 0, 0)) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } - return 0; + /* We never go there */ + + return 0; } diff --git a/reactos/base/system/winlogon/winlogon.h b/reactos/base/system/winlogon/winlogon.h index 1d5814f479b..15a1d2d714b 100644 --- a/reactos/base/system/winlogon/winlogon.h +++ b/reactos/base/system/winlogon/winlogon.h @@ -71,7 +71,7 @@ typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID); typedef struct _GINAFUNCTIONS { /* Functions always available for a valid GINA */ - PFWLXNEGOTIATE WlxNegotiate; + PFWLXNEGOTIATE WlxNegotiate; /* optional */ PFWLXINITIALIZE WlxInitialize; /* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */ @@ -87,15 +87,15 @@ typedef struct _GINAFUNCTIONS PFWLXSHUTDOWN WlxShutdown; /* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */ - PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; - PFWLXSTARTAPPLICATION WlxStartApplication; + PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; /* optional, not called ATM */ + 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_3 (MS Windows 2000) */ - PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad; + PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad; /* not called ATM */ PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage; - PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; + PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; /* doesn't need to be called */ PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage; /* Functions available if WlxVersion >= WLX_VERSION_1_4 (MS Windows XP) */ @@ -111,6 +111,7 @@ typedef struct _GINAINSTANCE } GINAINSTANCE, *PGINAINSTANCE; /* 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_ON 1 #define WKSTA_IS_LOCKED 2 @@ -157,11 +158,6 @@ extern PWLSESSION WLSession; ((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 */ BOOL WINAPI UpdatePerUserSystemParameters(DWORD dwUnknown, @@ -176,6 +172,17 @@ BOOL InitializeSAS( IN OUT PWLSESSION Session); +/* winlogon.c */ +BOOL +DisplayStatusMessage( + IN PWLSESSION Session, + IN HDESK hDesktop, + IN UINT ResourceId); + +BOOL +RemoveStatusMessage( + IN PWLSESSION Session); + /* wlx.c */ BOOL GinaInit( @@ -184,6 +191,11 @@ BOOL CreateWindowStationAndDesktops( IN OUT PWLSESSION Session); +BOOL +HandleShutdown( + IN OUT PWLSESSION Session, + IN DWORD wlxAction); + VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx); VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext); VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType);