From e202c810acd411503f76e2ce2640d4b21187d295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 3 Aug 2006 13:50:40 +0000 Subject: [PATCH] Implement shutdown and unlocking Remove some useless code Implement Timeout for dialogs svn path=/trunk/; revision=23433 --- reactos/base/system/winlogon/sas.c | 59 ++++----- reactos/base/system/winlogon/winlogon.c | 163 +++--------------------- reactos/base/system/winlogon/winlogon.h | 5 + reactos/base/system/winlogon/wlx.c | 75 +++++++++-- 4 files changed, 113 insertions(+), 189 deletions(-) diff --git a/reactos/base/system/winlogon/sas.c b/reactos/base/system/winlogon/sas.c index 5f5b6e000ea..9c10dc26db3 100644 --- a/reactos/base/system/winlogon/sas.c +++ b/reactos/base/system/winlogon/sas.c @@ -28,35 +28,11 @@ static BOOL StartTaskManager( IN OUT PWLSESSION Session) { - STARTUPINFO StartupInfo; - PROCESS_INFORMATION ProcessInformation; - - if (Session->LogonStatus == WKSTA_IS_LOGGED_OFF) - return FALSE; - - StartupInfo.cb = sizeof(StartupInfo); - StartupInfo.lpReserved = NULL; - StartupInfo.lpDesktop = NULL; - StartupInfo.lpTitle = NULL; - StartupInfo.dwFlags = 0; - StartupInfo.cbReserved2 = 0; - StartupInfo.lpReserved2 = 0; - - CreateProcessW( - L"taskmgr.exe", + return Session->MsGina.Functions.WlxStartApplication( + Session->MsGina.Context, + L"Default", NULL, - NULL, - NULL, - FALSE, - CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, - NULL, - NULL, - &StartupInfo, - &ProcessInformation); - - CloseHandle (ProcessInformation.hProcess); - CloseHandle (ProcessInformation.hThread); - return TRUE; + L"taskmgr.exe"); } static BOOL @@ -107,25 +83,31 @@ HandleLogon( return Session->MsGina.Functions.WlxActivateUserShell( Session->MsGina.Context, - L"WinSta0\\Default",//NULL, /* FIXME */ + L"Default",//NULL, /* FIXME */ NULL, /* FIXME */ lpEnvironment); } -static BOOL +static VOID HandleLogoff( IN OUT PWLSESSION Session) { FIXME("FIXME: HandleLogoff() unimplemented\n"); - return FALSE; } static BOOL HandleShutdown( - IN OUT PWLSESSION Session) + IN OUT PWLSESSION Session, + IN DWORD wlxAction) { FIXME("FIXME: HandleShutdown() unimplemented\n"); - return FALSE; + if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT) + NtShutdownSystem(ShutdownReboot); + else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF) + NtShutdownSystem(ShutdownPowerOff); + else + NtShutdownSystem(ShutdownNoReboot); + return TRUE; } static VOID @@ -138,8 +120,8 @@ DoGenericAction( case WLX_SAS_ACTION_LOGON: /* 0x01 */ if (HandleLogon(Session)) { + SwitchDesktop(Session->ApplicationDesktop); Session->LogonStatus = WKSTA_IS_LOGGED_ON; - SwitchDesktop(WLSession->ApplicationDesktop); } break; case WLX_SAS_ACTION_NONE: /* 0x02 */ @@ -154,6 +136,8 @@ DoGenericAction( break; case WLX_SAS_ACTION_LOGOFF: /* 0x04 */ case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */ + case WLX_SAS_ACTION_SHUTDOWN_POWER_OFF: /* 0x0a */ + case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */ if (Session->LogonStatus != WKSTA_IS_LOGGED_OFF) { if (!Session->MsGina.Functions.WlxIsLogoffOk(Session->MsGina.Context)) @@ -165,11 +149,16 @@ DoGenericAction( Session->MsGina.Functions.WlxDisplaySASNotice(Session->MsGina.Context); } if (WLX_SHUTTINGDOWN(wlxAction)) - HandleShutdown(Session); + HandleShutdown(Session, wlxAction); break; case WLX_SAS_ACTION_TASKLIST: /* 0x07 */ + SwitchDesktop(WLSession->ApplicationDesktop); StartTaskManager(Session); break; + case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */ + SwitchDesktop(WLSession->ApplicationDesktop); + Session->LogonStatus = WKSTA_IS_LOGGED_ON; + break; default: WARN("Unknown SAS action 0x%lx\n", wlxAction); } diff --git a/reactos/base/system/winlogon/winlogon.c b/reactos/base/system/winlogon/winlogon.c index 10631bf359e..30975291f7f 100644 --- a/reactos/base/system/winlogon/winlogon.c +++ b/reactos/base/system/winlogon/winlogon.c @@ -51,7 +51,7 @@ ShutdownComputerWindowProc( } static BOOL -StartServicesManager(void) +StartServicesManager(VOID) { HANDLE ServicesInitEvent; BOOLEAN Result; @@ -182,6 +182,7 @@ StartLsass(VOID) return TRUE; } +#if 0 static BOOL OpenRegistryKey( OUT HKEY *WinLogonKey) @@ -192,6 +193,7 @@ OpenRegistryKey( KEY_QUERY_VALUE, WinLogonKey); } +#endif #if 0 static BOOL @@ -228,7 +230,8 @@ StartProcess( #endif /* -static BOOL RestartShell(void) +static BOOL RestartShell( + IN OUT PWLSESSION Session) { HKEY WinLogonKey; DWORD Type, Size, Value; @@ -255,6 +258,7 @@ static BOOL RestartShell(void) } */ +#if 0 static PWCHAR GetUserInit( OUT WCHAR *CommandLine, @@ -300,8 +304,7 @@ GetUserInit( return CommandLine; } - -BOOL +static BOOL DoBrokenLogonUser( IN PWLSESSION WLSession, IN PWLX_MPR_NOTIFY_INFO pMprNotifyInfo) @@ -423,6 +426,7 @@ DoBrokenLogonUser( return TRUE; } +#endif static BOOL DisplayStatusMessage( @@ -441,70 +445,6 @@ DisplayStatusMessage( return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, 0, NULL, StatusMsg); } -#if 0 -static BOOL -InitServices(VOID) -{ - /*WCHAR StatusMsg[256]; - - LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR)); - DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);*/ - - /* start system processes (services.exe & lsass.exe) */ - if(StartProcess(L"StartServices")) - { - if(!StartServicesManager()) - { - DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError()); - } - } - else - { - DPRINT1("WL: StartProcess() failed!\n"); - } - - return TRUE; -} -#endif - -#if 0 -static DWORD -DoLogin( - IN OUT PWLSESSION Session) -{ - DWORD WlxAction, Options; - WLX_MPR_NOTIFY_INFO MprNotifyInfo; - PWLX_PROFILE_V2_0 Profile; - PSID LogonSid = NULL; - HANDLE Token; - - /* FIXME - Create a Logon Sid - if(!(LogonSid = CreateUserLogonSid(NULL))) - { - return WLX_SAS_ACTION_NONE; - } - */ - - Options = 0; - WlxAction = Session->MsGina.Functions.WlxLoggedOutSAS(Session->MsGina.Context, - Session->SASAction, - &Session->LogonId, - LogonSid, - &Options, - &Token, - &MprNotifyInfo, - (PVOID*)&Profile); - - if (WlxAction == WLX_SAS_ACTION_LOGON) - { - Session->UserToken = Token; - if (!DoBrokenLogonUser(Session, &MprNotifyInfo)) - WlxAction = WLX_SAS_ACTION_NONE; - } - return WlxAction; -} -#endif - static VOID SessionLoop( IN OUT PWLSESSION Session) @@ -526,73 +466,20 @@ SessionLoop( /* Don't go there! */ -#if 0 - /* FIXME - don't leave the loop when suspending the computer */ - if(WLX_SUSPENDING(WlxAction)) - { - Session->LogonStatus = LOGON_NONE; - WlxAction = WLX_SAS_ACTION_NONE; - /* don't leave the loop */ - continue; - } - - if(WLX_SHUTTINGDOWN(WlxAction)) - { - Session->LogonStatus = LOGON_SHUTDOWN; - /* leave the loop here */ - break; - } - -#endif /* - LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); - - + DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS); Sleep(150); - LoadString(hAppInstance, IDS_APPLYINGCOMPUTERSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); - - + DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS); Sleep(150); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - - - Sleep(250); - - LoadString(hAppInstance, IDS_LOADINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); - + DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS); Sleep(150); - LoadString(hAppInstance, IDS_APPLYINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); - - + DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS); Sleep(150); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); + RemoveStatusMessage(Session); if(!MsGinaInst->Functions->WlxActivateUserShell(MsGinaInst->Context, L"WinSta0\\Default", @@ -604,34 +491,19 @@ SessionLoop( SetEvent(hShutdownEvent); } - WaitForSingleObject(hShutdownEvent, INFINITE); CloseHandle(hShutdownEvent); - LoadString(hAppInstance, IDS_SAVEYOURSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); - + DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS); Sleep(150); MsGinaInst->Functions->WlxShutdown(MsGinaInst->Context, WLX_SAS_ACTION_SHUTDOWN); - - LoadString(hAppInstance, IDS_REACTOSISSHUTTINGDOWN, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); - + DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISSHUTTINGDOWN); Sleep(250); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); + RemoveStatusMessage(Session); */ } @@ -668,6 +540,7 @@ WinMain( ExitProcess(1); return 1; } + WLSession->DialogTimeout = 120; /* 2 minutes */ if (!CreateWindowStationAndDesktops(WLSession)) { @@ -675,6 +548,7 @@ WinMain( ExitProcess(1); return 1; } + LockWorkstation(WLSession); /* Check for pending setup */ if (GetSetupType() != 0) @@ -682,6 +556,7 @@ WinMain( DPRINT("Winlogon: CheckForSetup() in setup mode\n"); /* Run setup and reboot when done */ + RemoveStatusMessage(WLSession); SwitchDesktop(WLSession->ApplicationDesktop); RunSetup(); diff --git a/reactos/base/system/winlogon/winlogon.h b/reactos/base/system/winlogon/winlogon.h index f24d5b4eb7a..298346ac785 100644 --- a/reactos/base/system/winlogon/winlogon.h +++ b/reactos/base/system/winlogon/winlogon.h @@ -114,6 +114,9 @@ typedef struct _MSGINAINSTANCE #define WKSTA_IS_LOGGED_ON 1 #define WKSTA_IS_LOCKED 2 +#define LockWorkstation(Session) +#define UnlockWorkstation(Session) + typedef struct _WLSESSION { MSGINAINSTANCE MsGina; @@ -130,6 +133,8 @@ typedef struct _WLSESSION LUID LogonId; HANDLE UserToken; + DWORD DialogTimeout; /* Timeout for dialog boxes, in seconds */ + /* Logon informations */ DWORD Options; WLX_MPR_NOTIFY_INFO MprNotifyInfo; diff --git a/reactos/base/system/winlogon/wlx.c b/reactos/base/system/winlogon/wlx.c index d53258e87b0..85ce7eb72d5 100644 --- a/reactos/base/system/winlogon/wlx.c +++ b/reactos/base/system/winlogon/wlx.c @@ -15,9 +15,49 @@ #define YDEBUG #include -//#define UNIMPLEMENTED DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__) +static DLGPROC PreviousWindowProc; +static UINT_PTR IdTimer; -#define WINLOGON_DESKTOP L"Winlogon" +static INT_PTR CALLBACK +DefaultWlxWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer) + { + CHECKPOINT1; + EndDialog(hwndDlg, -1); + KillTimer(hwndDlg, IdTimer); + CHECKPOINT1; + return TRUE; + } + else if (uMsg == WM_INITDIALOG) + { + CHECKPOINT1; + PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); + IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL); + CHECKPOINT1; + if (IdTimer == 0) + return FALSE; + return TRUE; + } + else if (uMsg == WM_NCDESTROY) + { + CHECKPOINT1; + PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); + CHECKPOINT1; + PreviousWindowProc = NULL; + return TRUE; + } + else + { + INT_PTR ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); + ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); + return ret; + } +} /* * @implemented @@ -52,15 +92,16 @@ WlxSasNotify( } /* - * @unimplemented + * @implemented */ BOOL WINAPI WlxSetTimeout( HANDLE hWlx, DWORD Timeout) { - UNIMPLEMENTED; - return FALSE; + PWLSESSION Session = (PWLSESSION)hWlx; + Session->DialogTimeout = Timeout; + return TRUE; } /* @@ -88,6 +129,7 @@ WlxMessageBox( LPWSTR lpszTitle, UINT fuStyle) { + /* FIXME: Provide a custom window proc to be able to handle timeout */ return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); } @@ -102,7 +144,10 @@ WlxDialogBox( HWND hwndOwner, DLGPROC dlgprc) { - return (int)DialogBox(hInst, lpszTemplate, hwndOwner, dlgprc); + if (PreviousWindowProc != NULL) + return -1; + PreviousWindowProc = dlgprc; + return (int)DialogBox(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc); } /* @@ -117,7 +162,10 @@ WlxDialogBoxParam( DLGPROC dlgprc, LPARAM dwInitParam) { - return (int)DialogBoxParam(hInst, lpszTemplate, hwndOwner, dlgprc, dwInitParam); + if (PreviousWindowProc != NULL) + return -1; + PreviousWindowProc = dlgprc; + return (int)DialogBoxParam(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc, dwInitParam); } /* @@ -131,7 +179,10 @@ WlxDialogBoxIndirect( HWND hwndOwner, DLGPROC dlgprc) { - return (int)DialogBoxIndirect(hInst, hDialogTemplate, hwndOwner, dlgprc); + if (PreviousWindowProc != NULL) + return -1; + PreviousWindowProc = dlgprc; + return (int)DialogBoxIndirect(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc); } /* @@ -146,7 +197,10 @@ WlxDialogBoxIndirectParam( DLGPROC dlgprc, LPARAM dwInitParam) { - return (int)DialogBoxIndirectParam(hInst, hDialogTemplate, hwndOwner, dlgprc, dwInitParam); + if (PreviousWindowProc != NULL) + return -1; + PreviousWindowProc = dlgprc; + return (int)DialogBoxIndirectParam(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc, dwInitParam); } /* @@ -626,6 +680,7 @@ GinaInit( Session->MsGina.Context = NULL; Session->MsGina.Version = GinaDllVersion; Session->SuppressStatus = FALSE; + PreviousWindowProc = NULL; return Session->MsGina.Functions.WlxInitialize( Session->InteractiveWindowStationName, @@ -675,7 +730,7 @@ CreateWindowStationAndDesktops( * Create the winlogon desktop */ Session->WinlogonDesktop = CreateDesktop( - WINLOGON_DESKTOP, + L"Winlogon", NULL, NULL, 0, /* FIXME: Set some flags */