diff --git a/reactos/subsys/system/winlogon/makefile b/reactos/subsys/system/winlogon/makefile index 23cde0a4994..54cc7098998 100644 --- a/reactos/subsys/system/winlogon/makefile +++ b/reactos/subsys/system/winlogon/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.9 2004/03/20 15:58:16 ekohl Exp $ +# $Id: makefile,v 1.10 2004/03/28 12:21:41 weiden Exp $ PATH_TO_TOP = ../../.. @@ -12,9 +12,9 @@ TARGET_INSTALLDIR = system32 TARGET_SDKLIBS = ntdll.a kernel32.a user32.a advapi32.a userenv.a secur32.a -TARGET_OBJECTS = setup.o winlogon.o wlx.o +TARGET_OBJECTS = setup.o winlogon.o wlx.o sas.o -TARGET_CFLAGS = -Wall -Werror -DUNICODE -I./ -I../../../include +TARGET_CFLAGS = -Wall -Werror -DUNICODE -D_UNICODE -I./ -I../../../include include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/subsys/system/winlogon/sas.c b/reactos/subsys/system/winlogon/sas.c new file mode 100644 index 00000000000..739baaf39b1 --- /dev/null +++ b/reactos/subsys/system/winlogon/sas.c @@ -0,0 +1,167 @@ +/* $Id: sas.c,v 1.1 2004/03/28 12:21:41 weiden Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/winlogon/sas.c + * PURPOSE: Secure Attention Sequence + * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) + * UPDATE HISTORY: + * Created 28/03/2004 + */ + +#define NTOS_MODE_USER +#include +#include +#include +#include +#include +#include + +#include "setup.h" +#include "winlogon.h" +#include "resource.h" + +#define SAS_CLASS L"SAS window class" +#define HK_CTRL_ALT_DEL 0 +#define HK_CTRL_SHIFT_ESC 1 + +void +DispatchSAS(PWLSESSION Session, DWORD dwSasType) +{ + Session->SASAction = dwSasType; + +} + +void +UninitSAS(PWLSESSION Session) +{ + if(Session->SASWindow) + { + DestroyWindow(Session->SASWindow); + Session->SASWindow = NULL; + } +} + +BOOL +SetupSAS(PWLSESSION Session, HWND hwndSAS) +{ + /* Register Ctrl+Alt+Del Hotkey */ + if(!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE)) + { + DbgPrint("WL-SAS: Unable to register Ctrl+Alt+Del hotkey!\n"); + return FALSE; + } + + /* Register Ctrl+Shift+Esc */ + Session->TaskManHotkey = RegisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC, MOD_CONTROL | MOD_SHIFT, VK_ESCAPE); + if(!Session->TaskManHotkey) + { + DbgPrint("WL-SAS: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n"); + } + return TRUE; +} + +BOOL +DestroySAS(PWLSESSION Session, HWND hwndSAS) +{ + /* Unregister hotkeys */ + + UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL); + + if(Session->TaskManHotkey) + { + UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC); + } + + return TRUE; +} + +LRESULT CALLBACK +SASProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PWLSESSION Session = (PWLSESSION)GetWindowLong(hwnd, GWL_USERDATA); + if(!Session) + { + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + switch(uMsg) + { + case WM_HOTKEY: + { + switch(wParam) + { + case HK_CTRL_ALT_DEL: + DbgPrint("SAS: CTR+ALT+DEL\n"); + break; + case HK_CTRL_SHIFT_ESC: + DbgPrint("SAS: CTR+SHIFT+ESC\n"); + break; + } + return 0; + } + case WM_CREATE: + { + if(!SetupSAS(Session, hwnd)) + { + /* Fail! */ + return 1; + } + return 0; + } + case WM_DESTROY: + { + DestroySAS(Session, hwnd); + return 0; + } + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +BOOL +InitializeSAS(PWLSESSION Session) +{ + WNDCLASSEX swc; + + /* register SAS window class. + WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */ + swc.cbSize = sizeof(WNDCLASSEXW); + swc.style = CS_SAVEBITS; + swc.lpfnWndProc = SASProc; + swc.cbClsExtra = 0; + swc.cbWndExtra = 0; + swc.hInstance = hAppInstance; + swc.hIcon = NULL; + swc.hCursor = NULL; + swc.hbrBackground = NULL; + swc.lpszMenuName = NULL; + swc.lpszClassName = SAS_CLASS; + swc.hIconSm = NULL; + RegisterClassEx(&swc); + + /* create invisible SAS window */ + Session->SASWindow = CreateWindowEx(0, SAS_CLASS, L"SAS", WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, 0, 0, hAppInstance, NULL); + if(!Session->SASWindow) + { + DbgPrint("WL: Failed to create SAS window\n"); + return FALSE; + } + + /* Save the Session pointer so the window proc can access it */ + SetWindowLong(Session->SASWindow, GWL_USERDATA, (LONG)Session); + + #if 0 + /* Register SAS window to receive SAS notifications + FIXME - SetLogonNotifyWindow() takes only one parameter, + definition in funcs.h is wrong! */ + if(!SetLogonNotifyWindow(Session->SASWindow)) + { + UninitSAS(Session); + DbgPrint("WL: Failed to register SAS window\n"); + return FALSE; + } + #endif + + return TRUE; +} + diff --git a/reactos/subsys/system/winlogon/winlogon.c b/reactos/subsys/system/winlogon/winlogon.c index 338f25bab75..7365f34609e 100644 --- a/reactos/subsys/system/winlogon/winlogon.c +++ b/reactos/subsys/system/winlogon/winlogon.c @@ -1,4 +1,4 @@ -/* $Id: winlogon.c,v 1.28 2004/03/20 15:58:16 ekohl Exp $ +/* $Id: winlogon.c,v 1.29 2004/03/28 12:21:41 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -33,16 +33,17 @@ BOOL LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion); +PWLSESSION +MsGinaInit(void); +void +SessionLoop(PWLSESSION Session); BOOL -MsGinaInit(DWORD Version); +InitServices(void); +BOOL +WlxCreateWindowStationAndDesktops(PWLSESSION Session); HINSTANCE hAppInstance; -HWINSTA InteractiveWindowStation; /* WinSta0 */ -HDESK ApplicationDesktop; /* WinSta0\Default */ -HDESK WinlogonDesktop; /* WinSta0\Winlogon */ -HDESK ScreenSaverDesktop; /* WinSta0\Screen-Saver */ - -MSGINAFUNCTIONS MsGinaFunctions; +PWLSESSION WLSession = NULL; #if SUPPORT_CONSOLESTART BOOL StartConsole = TRUE; @@ -475,151 +476,10 @@ WinMain(HINSTANCE hInstance, LSA_OPERATIONAL_MODE Mode; ULONG AuthenticationPackage; #endif - DWORD GinaDllVersion; - HANDLE hShutdownEvent; - WCHAR StatusMsg[256]; - BOOL Success; NTSTATUS Status; hAppInstance = hInstance; - /* - * FIXME: Create a security descriptor with - * one ACE containing the Winlogon SID - */ - - /* - * Create the interactive window station - */ - InteractiveWindowStation = - CreateWindowStation(L"WinSta0", 0, GENERIC_ALL, NULL); - if (InteractiveWindowStation == NULL) - { - DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError()); - NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); - ExitProcess(1); - } - - /* - * Set the process window station - */ - SetProcessWindowStation(InteractiveWindowStation); - - /* - * Create the application desktop - */ - ApplicationDesktop = - CreateDesktop(L"Default", - NULL, - NULL, - 0, /* FIXME: Set some flags */ - GENERIC_ALL, - NULL); - - /* - * Create the winlogon desktop - */ - WinlogonDesktop = CreateDesktop(L"Winlogon", - NULL, - NULL, - 0, /* FIXME: Set some flags */ - GENERIC_ALL, - NULL); - - /* - * Create the screen saver desktop - */ - ScreenSaverDesktop = CreateDesktop(L"Screen-Saver", - NULL, - NULL, - 0, /* FIXME: Set some flags */ - GENERIC_ALL, - NULL); - - /* - * Switch to winlogon desktop - */ - /* FIXME: Do start up in the application desktop for now. */ - Status = NtSetInformationProcess(NtCurrentProcess(), - ProcessDesktop, - &ApplicationDesktop, - sizeof(ApplicationDesktop)); - if (!NT_SUCCESS(Status)) - { - DbgPrint("WL: Cannot set default desktop for winlogon.\n"); - } - SetThreadDesktop(ApplicationDesktop); - Success = SwitchDesktop(ApplicationDesktop); - if (!Success) - { - DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError()); - } - - /* Check for pending setup */ - if (GetSetupType () != 0) - { - DPRINT ("Winlogon: CheckForSetup() in setup mode\n"); - - /* Run setup and reboot when done */ - RunSetup (); - - NtShutdownSystem (ShutdownReboot); - ExitProcess (0); - return 0; - } - -#if SUPPORT_CONSOLESTART - StartConsole = !StartIntoGUI(); - if(!StartConsole) - { -#endif - if(!LoadGina(&MsGinaFunctions, &GinaDllVersion)) - { - NtShutdownSystem(ShutdownReboot); - ExitProcess(0); - return(0); - } - - /* FIXME - better solution needed */ - hShutdownEvent = CreateEvent(NULL, - TRUE, - FALSE, - L"WinLogonShutdown"); - - if(!hShutdownEvent) - { - DbgPrint("WL: Failed to create WinLogonShutdown event!\n"); - NtShutdownSystem(ShutdownNoReboot); - ExitProcess(0); - return(0); - } - - if(!MsGinaInit(GinaDllVersion) || !MsGinaInst) - { - DbgPrint("WL: Failed to initialize winlogon!\n"); - NtShutdownSystem(ShutdownNoReboot); - ExitProcess(0); - return(0); - } - - LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR)); - MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, - ApplicationDesktop, - 0, - NULL, - StatusMsg); -#if SUPPORT_CONSOLESTART - } -#endif - - /* start system processes (services.exe & lsass.exe) */ - if (StartProcess(L"StartServices")) - { - if (!StartServices()) - { - DbgPrint("WL: Failed to start Services (0x%X)\n", GetLastError()); - } - } #if START_LSASS if (StartProcess(L"StartLsass")) { @@ -629,6 +489,80 @@ WinMain(HINSTANCE hInstance, } } #endif + + if(!(WLSession = MsGinaInit())) + { + DbgPrint("WL: Failed to initialize msgina.dll\n"); + NtShutdownSystem(ShutdownNoReboot); + ExitProcess(0); + return 0; + } + + WLSession->LogonStatus = LOGON_INITIALIZING; +#if START_LSASS + if(!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) + { + DbgPrint("WL: Could not register logon process\n"); + NtShutdownSystem(ShutdownNoReboot); + ExitProcess(0); + return 0; + } +#endif + + if(!WlxCreateWindowStationAndDesktops(WLSession)) + { + NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); + ExitProcess(1); + return 1; + } + + /* + * Switch to winlogon desktop + */ + /* FIXME: Do start up in the application desktop for now. */ + Status = NtSetInformationProcess(NtCurrentProcess(), + ProcessDesktop, + &WLSession->ApplicationDesktop, + sizeof(HDESK)); + if(!NT_SUCCESS(Status)) + { + DbgPrint("WL: Cannot set default desktop for winlogon.\n"); + } + SetThreadDesktop(WLSession->ApplicationDesktop); + if(!SwitchDesktop(WLSession->ApplicationDesktop)) + { + DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError()); + } + + /* Check for pending setup */ + if (GetSetupType () != 0) + { + DPRINT ("Winlogon: CheckForSetup() in setup mode\n"); + + /* Run setup and reboot when done */ + RunSetup(); + + NtShutdownSystem(ShutdownReboot); + ExitProcess(0); + return 0; + } + +#if SUPPORT_CONSOLESTART + StartConsole = !StartIntoGUI(); + if(!StartConsole) + { +#endif + if(!InitializeSAS(WLSession)) + { + DbgPrint("WL: Failed to initialize SAS\n"); + ExitProcess(2); + return 2; + } +#if SUPPORT_CONSOLESTART + } +#endif + + InitServices(); #if 0 /* real winlogon uses "Winlogon" */ @@ -722,7 +656,188 @@ WinMain(HINSTANCE hInstance, else { #endif + + SessionLoop(WLSession); + + /* FIXME - Flush disks and registry, ... */ + + if(WLSession->LogonStatus == LOGON_SHUTDOWN) + { + /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */ + switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerProc)) + { + case IDC_BTNSHTDOWNCOMPUTER: + NtShutdownSystem(ShutdownReboot); + break; + default: + NtShutdownSystem(ShutdownNoReboot); + break; + } + ExitProcess(0); + } + else + { + DbgPrint("WL: LogonStatus != LOGON_SHUTDOWN!!!\n"); + ExitProcess(0); + } +#if SUPPORT_CONSOLESTART + } +#endif + + return 0; +} +BOOL +DisplayStatusMessage(PWLSESSION Session, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage) +{ + if(Session->SuppressStatus) + { + return TRUE; + } + + #if SUPPORT_CONSOLESTART + if(StartConsole) + { + if(pMessage) + { + DbgPrint("WL-Status: %ws\n", pMessage); + } + return TRUE; + } + #endif + + return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, dwOptions, pTitle, pMessage); +} + +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(!StartServices()) + { + DbgPrint("WL: Failed to start Services (0x%X)\n", GetLastError()); + } + } + + return TRUE; +} + +DWORD +DoLogin(PWLSESSION Session) +{ + DWORD WlxAction, Options; + WLX_MPR_NOTIFY_INFO MprNotifyInfo; + PWLX_PROFILE_V2_0 Profile; + PSID LogonSid; + 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); + + return WlxAction; +} + +void +SessionLoop(PWLSESSION Session) +{ + //WCHAR StatusMsg[256]; + // HANDLE hShutdownEvent; + DWORD WlxAction; + MSG Msg; + + WlxAction = WLX_SAS_ACTION_NONE; + Session->LogonStatus = LOGON_NONE; + while(WlxAction == WLX_SAS_ACTION_NONE) + { + RemoveStatusMessage(Session); + if(Session->LogonStatus == LOGON_NONE) + { + Session->LogonStatus = LOGON_SHOWINGLOGON; + /* we're ready to display a logon window, + don't timeout dialogboxes here */ + WlxSetTimeout(Session->MsGina.Context, 0); + Session->SuppressStatus = TRUE; + /* tell msgina to show a window telling the user one can logon */ + #if SUPPORT_CONSOLESTART + if(!StartConsole) + #endif + DisplaySASNotice(Session); + Session->SuppressStatus = FALSE; + + if(Session->SASAction == WLX_SAS_ACTION_LOGOFF) + { + /* the system wants to log off here */ + Session->LogonStatus = LOGON_SHUTDOWN; + break; + } + } + + WlxAction = DoLogin(Session); + if(WlxAction == WLX_SAS_ACTION_LOGOFF) + { + /* the user doesn't want to login, instead pressed cancel + we should display the window again so one can logon again */ + /* FIXME - disconnect any connections in case we did a remote logon */ + DbgPrint("WL: DoLogin failed\n"); + WlxAction = WLX_SAS_ACTION_NONE; + } + if(WlxAction == WLX_SAS_ACTION_NONE) + { + if(Session->SASAction == WLX_SAS_ACTION_LOGOFF) + { + /* system is about to shut down, leave the main loop */ + Session->LogonStatus = LOGON_SHUTDOWN; + break; + } + Session->LogonStatus = LOGON_NONE; + continue; + } + + /* 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; + } + + /* Message loop for the SAS window */ + while(GetMessage(&Msg, 0, 0, 0)) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + /* LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR)); MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, ApplicationDesktop, @@ -730,7 +845,7 @@ WinMain(HINSTANCE hInstance, NULL, StatusMsg); - /* FIXME */ + Sleep(150); LoadString(hAppInstance, IDS_APPLYINGCOMPUTERSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); @@ -740,14 +855,14 @@ WinMain(HINSTANCE hInstance, NULL, StatusMsg); - /* FIXME */ + Sleep(150); MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - /* FIXME - call WlxLoggedOutSAS() to display the login dialog */ + Sleep(250); LoadString(hAppInstance, IDS_LOADINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); @@ -756,8 +871,7 @@ WinMain(HINSTANCE hInstance, 0, NULL, StatusMsg); - - /* FIXME */ + Sleep(150); LoadString(hAppInstance, IDS_APPLYINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR)); @@ -767,7 +881,7 @@ WinMain(HINSTANCE hInstance, NULL, StatusMsg); - /* FIXME */ + Sleep(150); MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); @@ -794,7 +908,7 @@ WinMain(HINSTANCE hInstance, NULL, StatusMsg); - /* FIXME */ + Sleep(150); MsGinaInst->Functions->WlxShutdown(MsGinaInst->Context, WLX_SAS_ACTION_SHUTDOWN); @@ -806,28 +920,11 @@ WinMain(HINSTANCE hInstance, NULL, StatusMsg); - /* FIXME */ + Sleep(250); MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context); - - /* FIXME - Flush disks and registry, ... */ - - /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */ - switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerProc)) - { - case IDC_BTNSHTDOWNCOMPUTER: - NtShutdownSystem(ShutdownReboot); - break; - default: - NtShutdownSystem(ShutdownNoReboot); - break; - } - ExitProcess(0); -#if SUPPORT_CONSOLESTART - } -#endif - - return 0; + */ } + diff --git a/reactos/subsys/system/winlogon/winlogon.h b/reactos/subsys/system/winlogon/winlogon.h index 3df60f3b411..be205c49a5c 100644 --- a/reactos/subsys/system/winlogon/winlogon.h +++ b/reactos/subsys/system/winlogon/winlogon.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: winlogon.h,v 1.2 2003/12/07 00:04:20 weiden Exp $ +/* $Id: winlogon.h,v 1.3 2004/03/28 12:21:41 weiden Exp $ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS winlogon * FILE: subsys/system/winlogon/winlogon.h @@ -29,6 +29,34 @@ #include +VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx); +VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext); +VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType); +BOOL WINAPI WlxSetTimeout(HANDLE hWlx, DWORD Timeout); +int WINAPI WlxAssignShellProtection(HANDLE hWlx, HANDLE hToken, HANDLE hProcess, HANDLE hThread); +int WINAPI WlxMessageBox(HANDLE hWlx, HWND hwndOwner, LPWSTR lpszText, LPWSTR lpszTitle, UINT fuStyle); +int WINAPI WlxDialogBox(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc); +int WINAPI WlxDialogBoxParam(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam); +int WINAPI WlxDialogBoxIndirect(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc); +int WINAPI WlxDialogBoxIndirectParam(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam); +int WINAPI WlxSwitchDesktopToUser(HANDLE hWlx); +int WINAPI WlxSwitchDesktopToWinlogon(HANDLE hWlx); +int WINAPI WlxChangePasswordNotify(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo); +BOOL WINAPI WlxGetSourceDesktop(HANDLE hWlx, PWLX_DESKTOP* ppDesktop); +BOOL WINAPI WlxSetReturnDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop); +BOOL WINAPI WlxCreateUserDesktop(HANDLE hWlx, HANDLE hToken, DWORD Flags, PWSTR pszDesktopName, PWLX_DESKTOP* ppDesktop); +int WINAPI WlxChangePasswordNotifyEx(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo, PWSTR ProviderName, PVOID Reserved); +BOOL WINAPI WlxCloseUserDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop, HANDLE hToken); +BOOL WINAPI WlxSetOption(HANDLE hWlx, DWORD Option, ULONG_PTR Value, ULONG_PTR* OldValue); +BOOL WINAPI WlxGetOption(HANDLE hWlx, DWORD Option, ULONG_PTR* Value); +VOID WINAPI WlxWin31Migrate(HANDLE hWlx); +BOOL WINAPI WlxQueryClientCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred); +BOOL WINAPI WlxQueryInetConnectorCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred); +DWORD WINAPI WlxQueryConsoleSwitchCredentials(PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred); +BOOL WINAPI WlxQueryTsLogonCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred); +BOOL WINAPI WlxDisconnect(void); +DWORD WINAPI WlxQueryTerminalServicesData(HANDLE hWlx, PWLX_TERMINAL_SERVICES_DATA pTSData, WCHAR* UserName, WCHAR* Domain); + typedef BOOL (WINAPI * PFWLXNEGOTIATE) (DWORD, DWORD *); typedef BOOL (WINAPI * PFWLXINITIALIZE) (LPWSTR, HANDLE, PVOID, PVOID, PVOID *); typedef VOID (WINAPI * PFWLXDISPLAYSASNOTICE) (PVOID); @@ -83,20 +111,56 @@ typedef struct _MSGINAFUNCTIONS typedef struct _MSGINAINSTANCE { HANDLE hDllInstance; - PMSGINAFUNCTIONS Functions; + MSGINAFUNCTIONS Functions; PVOID Context; DWORD Version; } MSGINAINSTANCE, *PMSGINAINSTANCE; +typedef struct _WLSESSION +{ + MSGINAINSTANCE MsGina; + DWORD SASAction; + DWORD LogonStatus; + BOOL SuppressStatus; + BOOL TaskManHotkey; + HWND SASWindow; + HWINSTA InteractiveWindowStation; + HDESK ApplicationDesktop; + HDESK WinlogonDesktop; + HDESK ScreenSaverDesktop; + LUID LogonId; +} WLSESSION, *PWLSESSION; + extern HINSTANCE hAppInstance; -extern PMSGINAINSTANCE MsGinaInst; -extern HWINSTA InteractiveWindowStation; /* WinSta0 */ -extern HDESK ApplicationDesktop; /* WinSta0\Default */ -extern HDESK WinlogonDesktop; /* WinSta0\Winlogon */ -extern HDESK ScreenSaverDesktop; /* WinSta0\Screen-Saver */ +extern PWLSESSION WLSession; -extern MSGINAFUNCTIONS MsGinaFunctions; +BOOL +InitializeSAS(PWLSESSION Session); +void +DispatchSAS(PWLSESSION Session, DWORD dwSasType); +#define LOGON_INITIALIZING 1 +#define LOGON_NONE 2 +#define LOGON_SHOWINGLOGON 3 + +#define LOGON_SHUTDOWN 9 + +#define WLX_SHUTTINGDOWN(Status) \ + (((Status) == WLX_SAS_ACTION_SHUTDOWN) || \ + ((Status) == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF) || \ + ((Status) == WLX_SAS_ACTION_SHUTDOWN_REBOOT) \ + ) + +#define WLX_SUSPENDING(Status) \ + (((Status) == WLX_SAS_ACTION_SHUTDOWN_SLEEP) || \ + ((Status) == WLX_SAS_ACTION_SHUTDOWN_SLEEP2) || \ + ((Status) == WLX_SAS_ACTION_SHUTDOWN_HIBERNATE) \ + ) + +#define RemoveStatusMessage(Session) \ + Session->MsGina.Functions.WlxRemoveStatusMessage(Session->MsGina.Context); +#define DisplaySASNotice(Session) \ + Session->MsGina.Functions.WlxDisplaySASNotice(Session->MsGina.Context); #endif /* __WINLOGON_MAIN_H__ */ diff --git a/reactos/subsys/system/winlogon/wlx.c b/reactos/subsys/system/winlogon/wlx.c index 47d4b099d5b..494bb7916d9 100644 --- a/reactos/subsys/system/winlogon/wlx.c +++ b/reactos/subsys/system/winlogon/wlx.c @@ -1,4 +1,4 @@ -/* $Id: wlx.c,v 1.3 2004/01/06 16:11:57 ekohl Exp $ +/* $Id: wlx.c,v 1.4 2004/03/28 12:21:41 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,21 +26,19 @@ #define Unimplemented DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__) -PMSGINAINSTANCE MsGinaInst; - /* - * @unimplemented + * @implemented */ VOID WINAPI WlxUseCtrlAltDel( HANDLE hWlx ) { - Unimplemented; + WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, NULL); } /* - * @unimplemented + * @implemented */ VOID WINAPI WlxSetContextPointer( @@ -48,11 +46,11 @@ WlxSetContextPointer( PVOID pWlxContext ) { - Unimplemented; + WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, NULL); } /* - * @unimplemented + * @implemented */ VOID WINAPI WlxSasNotify( @@ -60,7 +58,7 @@ WlxSasNotify( DWORD dwSasType ) { - Unimplemented; + DispatchSAS((PWLSESSION)hWlx, dwSasType); } /* @@ -72,7 +70,7 @@ WlxSetTimeout( DWORD Timeout ) { - Unimplemented; + /* Unimplemented; */ return FALSE; } @@ -294,9 +292,9 @@ WlxSetOption( ULONG_PTR* OldValue ) { - PMSGINAINSTANCE Instance = (PMSGINAINSTANCE)hWlx; - Unimplemented; - if(Instance || !Value) + PWLSESSION Session = (PWLSESSION)hWlx; + + if(Session || !Value) { switch(Option) { @@ -304,8 +302,8 @@ WlxSetOption( return TRUE; case WLX_OPTION_CONTEXT_POINTER: { - *OldValue = (ULONG_PTR)Instance->Context; - Instance->Context = (PVOID)Value; + *OldValue = (ULONG_PTR)Session->MsGina.Context; + Session->MsGina.Context = (PVOID)Value; return TRUE; } case WLX_OPTION_USE_SMART_CARD: @@ -571,21 +569,19 @@ GinaLoadFailedProc( } BOOL -LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion) +LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion, HMODULE *GinaInstance) { HMODULE hGina; WCHAR GinaDll[MAX_PATH + 1]; - MsGinaInst = NULL; - GetMsGinaPath(GinaDll); - hGina = LoadLibrary(GinaDll); - if(!hGina) + if(!(hGina = LoadLibrary(GinaDll))) { DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedProc, (LPARAM)&GinaDll); return FALSE; } + *GinaInstance = hGina; Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize"); @@ -634,32 +630,99 @@ LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion) return (Functions->WlxNegotiate != NULL) && (Functions->WlxInitialize != NULL); } -BOOL -MsGinaInit(DWORD Version) +PWLSESSION +MsGinaInit(void) { - PMSGINAINSTANCE Instance; + PWLSESSION WLSession; + DWORD GinaDllVersion; - Instance = (PMSGINAINSTANCE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSGINAINSTANCE)); - if(!Instance) + WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION)); + if(!WLSession) { - return 0; + return NULL; } - Instance->Functions = &MsGinaFunctions; - Instance->hDllInstance = NULL; /* FIXME */ - Instance->Context = NULL; - Instance->Version = Version; - - MsGinaInst = Instance; - - if(!Instance->Functions->WlxInitialize(InteractiveWindowStation, - (HANDLE)Instance, - NULL, - (PVOID)&FunctionTable, - &Instance->Context)) + if(!LoadGina(&WLSession->MsGina.Functions, &GinaDllVersion, &WLSession->MsGina.hDllInstance)) { - return 0; + HeapFree(GetProcessHeap(), 0, WLSession); + return NULL; } + + WLSession->MsGina.Context = NULL; + WLSession->MsGina.Version = GinaDllVersion; + WLSession->SuppressStatus = FALSE; + + if(!WLSession->MsGina.Functions.WlxInitialize(WLSession->InteractiveWindowStation, + (HANDLE)WLSession, + NULL, + (PVOID)&FunctionTable, + &WLSession->MsGina.Context)) + { + HeapFree(GetProcessHeap(), 0, WLSession); + return NULL; + } + return WLSession; +} + +BOOL +WlxCreateWindowStationAndDesktops(PWLSESSION Session) +{ + /* + * Create the interactive window station + */ + Session->InteractiveWindowStation = CreateWindowStation(L"WinSta0", 0, GENERIC_ALL, NULL); + if(!Session->InteractiveWindowStation) + { + DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError()); + return FALSE; + } + SetProcessWindowStation(Session->InteractiveWindowStation); + + /* + * Create the application desktop + */ + Session->ApplicationDesktop = CreateDesktop(L"Default", + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); + if(!Session->ApplicationDesktop) + { + DbgPrint("WL: Failed to create Default desktop (0x%X)\n", GetLastError()); + return FALSE; + } + + /* + * Create the winlogon desktop + */ + Session->WinlogonDesktop = CreateDesktop(L"Winlogon", + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); + if(!Session->WinlogonDesktop) + { + DbgPrint("WL: Failed to create Winlogon desktop (0x%X)\n", GetLastError()); + return FALSE; + } + + /* + * Create the screen saver desktop + */ + Session->ScreenSaverDesktop = CreateDesktop(L"Screen-Saver", + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); + if(!Session->ScreenSaverDesktop) + { + DbgPrint("WL: Failed to create Screen-Saver desktop (0x%X)\n", GetLastError()); + return FALSE; + } + return TRUE; }