diff --git a/reactos/base/system/winlogon/sas.c b/reactos/base/system/winlogon/sas.c index be2eaa97499..5f5b6e000ea 100644 --- a/reactos/base/system/winlogon/sas.c +++ b/reactos/base/system/winlogon/sas.c @@ -3,75 +3,256 @@ * PROJECT: ReactOS kernel * FILE: services/winlogon/sas.c * PURPOSE: Secure Attention Sequence - * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) + * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) + * Hervé Poussineau (hpoussin@reactos.org) * UPDATE HISTORY: * Created 28/03/2004 */ #include "winlogon.h" -#define NDEBUG -#include +#define YDEBUG +#include -#define WINLOGON_SAS_CLASS L"SAS window class" -#define WINLOGON_SAS_TITLE L"SAS" +#define WINLOGON_SAS_CLASS L"SAS Window class" +#define WINLOGON_SAS_TITLE L"SAS window" -#define HK_CTRL_ALT_DEL 0 -#define HK_CTRL_SHIFT_ESC 1 +#define HK_CTRL_ALT_DEL 0 +#define HK_CTRL_SHIFT_ESC 1 #ifdef __USE_W32API extern BOOL STDCALL SetLogonNotifyWindow(HWND Wnd, HWINSTA WinSta); #endif -void -DispatchSAS(PWLSESSION Session, DWORD dwSasType) +static BOOL +StartTaskManager( + IN OUT PWLSESSION Session) { - Session->SASAction = dwSasType; + 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", + NULL, + NULL, + NULL, + FALSE, + CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, + NULL, + NULL, + &StartupInfo, + &ProcessInformation); + + CloseHandle (ProcessInformation.hProcess); + CloseHandle (ProcessInformation.hThread); + return TRUE; } -void -UninitSAS(PWLSESSION Session) +static BOOL +HandleLogon( + IN OUT PWLSESSION Session) { - if(Session->SASWindow) - { - DestroyWindow(Session->SASWindow); - Session->SASWindow = NULL; - } + PROFILEINFOW ProfileInfo; + LPVOID lpEnvironment = NULL; + BOOLEAN Old; + + if (!(Session->Options & WLX_LOGON_OPT_NO_PROFILE)) + { + /* Load the user profile */ + ProfileInfo.dwSize = sizeof(PROFILEINFOW); + ProfileInfo.dwFlags = 0; + ProfileInfo.lpUserName = Session->MprNotifyInfo.pszUserName; + ProfileInfo.lpProfilePath = Session->Profile.pszProfile; + ProfileInfo.lpDefaultPath = Session->Profile.pszNetworkDefaultUserProfile; + ProfileInfo.lpServerName = Session->Profile.pszServerName; + ProfileInfo.lpPolicyPath = Session->Profile.pszPolicy; + ProfileInfo.hProfile = NULL; + + if (!LoadUserProfileW(Session->UserToken, &ProfileInfo)) + { + ERR("WL: LoadUserProfileW() failed\n"); + CloseHandle(Session->UserToken); + return FALSE; + } + } + + /* Create environment block for the user */ + if (!CreateEnvironmentBlock( + &lpEnvironment, + Session->UserToken, + TRUE)) + { + ERR("WL: CreateEnvironmentBlock() failed\n"); + UnloadUserProfile(WLSession->UserToken, ProfileInfo.hProfile); + CloseHandle(Session->UserToken); + return FALSE; + } + /* FIXME: use Session->Profile.pszEnvironment */ + + /* Get privilege */ + /* FIXME: who should do it? winlogon or gina? */ + /* FIXME: reverting to lower privileges after creating user shell? */ + RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old); + + return Session->MsGina.Functions.WlxActivateUserShell( + Session->MsGina.Context, + L"WinSta0\\Default",//NULL, /* FIXME */ + NULL, /* FIXME */ + lpEnvironment); } -BOOL -SetupSAS(PWLSESSION Session, HWND hwndSAS) +static BOOL +HandleLogoff( + IN OUT PWLSESSION Session) { - /* Register Ctrl+Alt+Del Hotkey */ - if(!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE)) - { - DPRINT1("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) - { - DPRINT1("WL-SAS: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n"); - } - return TRUE; + FIXME("FIXME: HandleLogoff() unimplemented\n"); + return FALSE; } -BOOL -DestroySAS(PWLSESSION Session, HWND hwndSAS) +static BOOL +HandleShutdown( + IN OUT PWLSESSION Session) { - /* Unregister hotkeys */ + FIXME("FIXME: HandleShutdown() unimplemented\n"); + return FALSE; +} - UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL); +static VOID +DoGenericAction( + IN OUT PWLSESSION Session, + IN DWORD wlxAction) +{ + switch (wlxAction) + { + case WLX_SAS_ACTION_LOGON: /* 0x01 */ + if (HandleLogon(Session)) + { + Session->LogonStatus = WKSTA_IS_LOGGED_ON; + SwitchDesktop(WLSession->ApplicationDesktop); + } + break; + case WLX_SAS_ACTION_NONE: /* 0x02 */ + break; + case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */ + if (Session->MsGina.Functions.WlxIsLockOk(Session->MsGina.Context)) + { + SwitchDesktop(WLSession->WinlogonDesktop); + Session->LogonStatus = WKSTA_IS_LOCKED; + Session->MsGina.Functions.WlxDisplayLockedNotice(Session->MsGina.Context); + } + break; + case WLX_SAS_ACTION_LOGOFF: /* 0x04 */ + case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */ + if (Session->LogonStatus != WKSTA_IS_LOGGED_OFF) + { + if (!Session->MsGina.Functions.WlxIsLogoffOk(Session->MsGina.Context)) + break; + SwitchDesktop(WLSession->WinlogonDesktop); + Session->MsGina.Functions.WlxLogoff(Session->MsGina.Context); + HandleLogoff(Session); + Session->LogonStatus = WKSTA_IS_LOGGED_OFF; + Session->MsGina.Functions.WlxDisplaySASNotice(Session->MsGina.Context); + } + if (WLX_SHUTTINGDOWN(wlxAction)) + HandleShutdown(Session); + break; + case WLX_SAS_ACTION_TASKLIST: /* 0x07 */ + StartTaskManager(Session); + break; + default: + WARN("Unknown SAS action 0x%lx\n", wlxAction); + } +} - if(Session->TaskManHotkey) - { - UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC); - } +VOID +DispatchSAS( + IN OUT PWLSESSION Session, + IN DWORD dwSasType) +{ + DWORD wlxAction = WLX_SAS_ACTION_NONE; - return TRUE; + if (Session->LogonStatus == WKSTA_IS_LOGGED_ON) + wlxAction = Session->MsGina.Functions.WlxLoggedOnSAS(Session->MsGina.Context, dwSasType, NULL); + else if (Session->LogonStatus == WKSTA_IS_LOCKED) + wlxAction = Session->MsGina.Functions.WlxWkstaLockedSAS(Session->MsGina.Context, dwSasType); + else + { + /* Display a new dialog (if necessary) */ + switch (dwSasType) + { + case WLX_SAS_TYPE_TIMEOUT: /* 0x00 */ + { + Session->MsGina.Functions.WlxDisplaySASNotice(Session->MsGina.Context); + break; + } + case WLX_SAS_TYPE_CTRL_ALT_DEL: /* 0x01 */ + { + PSID LogonSid = NULL; /* FIXME */ + + ZeroMemory(&Session->Profile, sizeof(Session->Profile)); + Session->Options = 0; + + wlxAction = Session->MsGina.Functions.WlxLoggedOutSAS( + Session->MsGina.Context, + Session->SASAction, + &Session->LogonId, + LogonSid, + &Session->Options, + &Session->UserToken, + &Session->MprNotifyInfo, + (PVOID*)&Session->Profile); + break; + } + default: + WARN("Unknown SAS type 0x%lx\n", dwSasType); + } + } + + DoGenericAction(Session, wlxAction); +} + +static BOOL +RegisterHotKeys( + IN PWLSESSION Session, + IN HWND hwndSAS) +{ + /* Register Ctrl+Alt+Del Hotkey */ + if (!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE)) + { + ERR("WL: Unable to register Ctrl+Alt+Del hotkey!\n"); + return FALSE; + } + + /* Register Ctrl+Shift+Esc (optional) */ + Session->TaskManHotkey = RegisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC, MOD_CONTROL | MOD_SHIFT, VK_ESCAPE); + if (!Session->TaskManHotkey) + WARN("WL: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n"); + return TRUE; +} + +static BOOL +UnregisterHotKeys( + IN PWLSESSION Session, + IN HWND hwndSAS) +{ + /* Unregister hotkeys */ + UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL); + + if (Session->TaskManHotkey) + UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC); + + return TRUE; } #define EWX_ACTION_MASK 0xffffffeb @@ -196,95 +377,115 @@ HandleExitWindows(PWLSESSION Session, DWORD RequestingProcessId, UINT Flags) return 1; } -LRESULT CALLBACK -SASProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK +SASWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwnd, GWLP_USERDATA); - if(!Session) - { - return DefWindowProc(hwnd, uMsg, wParam, lParam); - } - switch(uMsg) - { - case WM_HOTKEY: - { - switch(wParam) - { - case HK_CTRL_ALT_DEL: - DPRINT1("SAS: CTR+ALT+DEL\n"); - break; - case HK_CTRL_SHIFT_ESC: - DPRINT1("SAS: CTR+SHIFT+ESC\n"); - break; - } - return 0; - } - case WM_CREATE: - { - /* Get the session pointer from the create data */ - Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams; + PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - /* Save the Session pointer */ - SetWindowLongPtr(Session->SASWindow, GWLP_USERDATA, (DWORD_PTR)Session); + switch (uMsg) + { + case WM_HOTKEY: + { + switch (lParam) + { + case MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE): + { + TRACE("SAS: CONTROL+ALT+DELETE\n"); + DispatchSAS(Session, WLX_SAS_TYPE_CTRL_ALT_DEL); + return TRUE; + } + case MAKELONG(MOD_CONTROL | MOD_SHIFT, VK_ESCAPE): + { + TRACE("SAS: CONTROL+SHIFT+ESCAPE\n"); + DoGenericAction(Session, WLX_SAS_ACTION_TASKLIST); + return TRUE; + } + } + break; + } + case WM_CREATE: + { + /* Get the session pointer from the create data */ + Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams; - if(!SetupSAS(Session, hwnd)) - { - /* Fail! */ - return 1; - } - return 0; - } - case PM_WINLOGON_EXITWINDOWS: - { - return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam); - } - case WM_DESTROY: - { - DestroySAS(Session, hwnd); - return 0; - } - } - return DefWindowProc(hwnd, uMsg, wParam, lParam); + /* Save the Session pointer */ + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)Session); + + return RegisterHotKeys(Session, hwndDlg); + } + case WM_DESTROY: + { + UnregisterHotKeys(Session, hwndDlg); + return TRUE; + } + case PM_WINLOGON_EXITWINDOWS: + { + return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam); + } + } + + return DefWindowProc(hwndDlg, uMsg, wParam, lParam); +} + +static VOID +UninitializeSAS( + IN OUT PWLSESSION Session) +{ + if (Session->SASWindow) + { + DestroyWindow(Session->SASWindow); + Session->SASWindow = NULL; + } } BOOL -InitializeSAS(PWLSESSION Session) +InitializeSAS( + IN OUT PWLSESSION Session) { - WNDCLASSEX swc; + 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 = WINLOGON_SAS_CLASS; - swc.hIconSm = NULL; - RegisterClassEx(&swc); + /* register SAS window class. + * WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */ + swc.cbSize = sizeof(WNDCLASSEXW); + swc.style = CS_SAVEBITS; + swc.lpfnWndProc = SASWindowProc; + swc.cbClsExtra = 0; + swc.cbWndExtra = 0; + swc.hInstance = hAppInstance; + swc.hIcon = NULL; + swc.hCursor = NULL; + swc.hbrBackground = NULL; + swc.lpszMenuName = NULL; + swc.lpszClassName = WINLOGON_SAS_CLASS; + swc.hIconSm = NULL; + RegisterClassEx(&swc); /* FIXME: check return code */ - /* create invisible SAS window */ - Session->SASWindow = CreateWindowEx(0, WINLOGON_SAS_CLASS, WINLOGON_SAS_TITLE, WS_POPUP, - 0, 0, 0, 0, 0, 0, hAppInstance, Session); - if(!Session->SASWindow) - { - DPRINT1("WL: Failed to create SAS window\n"); - return FALSE; - } + /* create invisible SAS window */ + DPRINT1("Session %p\n", Session); + Session->SASWindow = CreateWindowEx( + 0, + WINLOGON_SAS_CLASS, + WINLOGON_SAS_TITLE, + WS_POPUP, + 0, 0, 0, 0, 0, 0, + hAppInstance, Session); + if (!Session->SASWindow) + { + ERR("WL: Failed to create SAS window\n"); + return FALSE; + } - /* Register SAS window to receive SAS notifications */ - if(!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation)) - { - UninitSAS(Session); - DPRINT1("WL: Failed to register SAS window\n"); - return FALSE; - } + /* Register SAS window to receive SAS notifications */ + if (!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation)) + { + UninitializeSAS(Session); + ERR("WL: Failed to register SAS window\n"); + return FALSE; + } - return TRUE; + return TRUE; } - diff --git a/reactos/base/system/winlogon/winlogon.c b/reactos/base/system/winlogon/winlogon.c index 83a52530e02..10631bf359e 100644 --- a/reactos/base/system/winlogon/winlogon.c +++ b/reactos/base/system/winlogon/winlogon.c @@ -3,80 +3,55 @@ * PROJECT: ReactOS Winlogon * FILE: services/winlogon/winlogon.c * PURPOSE: Logon - * PROGRAMMER: David Welch (welch@cwcom.net) - * UPDATE HISTORY: - * Created 22/05/98 + * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) + * Filip Navara + * Hervé Poussineau (hpoussin@reactos.org) */ /* INCLUDES *****************************************************************/ #include "winlogon.h" -#define NDEBUG -#include +#define YDEBUG +#include /* GLOBALS ******************************************************************/ -BOOL -LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion); -PWLSESSION -MsGinaInit(void); -void -SessionLoop(PWLSESSION Session); -BOOL -InitServices(void); -BOOL -WlxCreateWindowStationAndDesktops(PWLSESSION Session); - HINSTANCE hAppInstance; PWLSESSION WLSession = NULL; -HWND hwndSASWindow = NULL; /* FUNCTIONS *****************************************************************/ -static void -PrintString (WCHAR* fmt,...) +static INT_PTR CALLBACK +ShutdownComputerWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - WCHAR buffer[512]; - va_list ap; - - va_start(ap, fmt); - wsprintf(buffer, fmt, ap); - va_end(ap); - - OutputDebugString(buffer); + switch (uMsg) + { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_BTNSHTDOWNCOMPUTER: + EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER); + break; + } + break; + } + case WM_INITDIALOG: + { + RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND); + SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER)); + break; + } + } + return DefWindowProc(hwndDlg, uMsg, wParam, lParam); } - -INT_PTR CALLBACK -ShutdownComputerProc (HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - switch(uMsg) - { - case WM_COMMAND: - { - switch(LOWORD(wParam)) - { - case IDC_BTNSHTDOWNCOMPUTER: - EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER); - break; - } - break; - } - case WM_INITDIALOG: - { - RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND); - SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER)); - break; - } - } - return FALSE; -} - -static BOOLEAN -StartServices (VOID) +static BOOL +StartServicesManager(void) { HANDLE ServicesInitEvent; BOOLEAN Result; @@ -96,7 +71,7 @@ StartServices (VOID) StartupInfo.lpReserved2 = 0; #if 0 - PrintString(L"WL: Creating new process - \"services.exe\".\n"); + DPRINT1(L"WL: Creating new process - \"services.exe\".\n"); #endif Result = CreateProcess(NULL, @@ -111,7 +86,7 @@ StartServices (VOID) &ProcessInformation); if (!Result) { - PrintString(L"WL: Failed to execute services\n"); + DPRINT1("WL: Failed to execute services\n"); return FALSE; } @@ -141,66 +116,75 @@ StartServices (VOID) WaitForSingleObject(ServicesInitEvent, INFINITE); DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n"); CloseHandle(ServicesInitEvent); - DPRINT("WL: StartServices() Done.\n"); + DPRINT("WL: StartServicesManager() Done.\n"); return TRUE; } -static BOOLEAN -StartLsass (VOID) +static BOOL +StartCustomService( + IN LPCWSTR ServiceName) { - HANDLE LsassInitEvent; - BOOLEAN Result; - STARTUPINFO StartupInfo; - PROCESS_INFORMATION ProcessInformation; - WCHAR ServiceString[] = L"lsass.exe"; + SC_HANDLE hSCManager = NULL; + SC_HANDLE hService = NULL; + BOOL ret = FALSE; - LsassInitEvent = CreateEvent(NULL, - TRUE, - FALSE, - L"\\SECURITY_SERVICES_STARTED"); + hSCManager = OpenSCManager(NULL, NULL, 0); + if (!hSCManager) + goto cleanup; - if (LsassInitEvent == NULL) - { - DPRINT1("WL: Failed to create lsass notification event\n"); - return(FALSE); - } + hService = OpenService(hSCManager, ServiceName, SERVICE_START); + if (!hService) + goto cleanup; +#if 0 + if (!StartService(hService, 0, NULL)) + goto cleanup; +#endif - /* Start the local security authority subsystem (lsass.exe) */ + ret = TRUE; - StartupInfo.cb = sizeof(StartupInfo); - StartupInfo.lpReserved = NULL; - StartupInfo.lpDesktop = NULL; - StartupInfo.lpTitle = NULL; - StartupInfo.dwFlags = 0; - StartupInfo.cbReserved2 = 0; - StartupInfo.lpReserved2 = 0; - - Result = CreateProcess(NULL, - ServiceString, - NULL, - NULL, - FALSE, - DETACHED_PROCESS, - NULL, - NULL, - &StartupInfo, - &ProcessInformation); - if (!Result) - { - DPRINT1("WL: Failed to execute lsass\n"); - return(FALSE); - } - - WaitForSingleObject(LsassInitEvent, INFINITE); - CloseHandle(LsassInitEvent); - - return(TRUE); +cleanup: + if (hService) + CloseServiceHandle(hService); + if (hSCManager) + CloseServiceHandle(hSCManager); + return ret; } +static BOOL +StartLsass(VOID) +{ + HANDLE LsassInitEvent; -static BOOLEAN -OpenRegistryKey (HKEY *WinLogonKey) + LsassInitEvent = CreateEvent( + NULL, + TRUE, + FALSE, + L"Global\\SECURITY_SERVICES_STARTED"); + if (!LsassInitEvent) + { + ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError()); + return FALSE; + } + + /* Start the local security authority subsystem (Netlogon service) */ + if (!StartCustomService(L"Netlogon")) + { + ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError()); + return FALSE; + } + +#if 0 + WaitForSingleObject(LsassInitEvent, INFINITE); +#endif + CloseHandle(LsassInitEvent); + + return TRUE; +} + +static BOOL +OpenRegistryKey( + OUT HKEY *WinLogonKey) { return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon", @@ -209,8 +193,10 @@ OpenRegistryKey (HKEY *WinLogonKey) WinLogonKey); } - -static BOOLEAN StartProcess(PWCHAR ValueName) +#if 0 +static BOOL +StartProcess( + IN PWCHAR ValueName) { BOOL StartIt; HKEY WinLogonKey; @@ -239,6 +225,7 @@ static BOOLEAN StartProcess(PWCHAR ValueName) return StartIt; } +#endif /* static BOOL RestartShell(void) @@ -268,56 +255,10 @@ static BOOL RestartShell(void) } */ -VOID STDCALL -RegisterHotKeys(VOID) -{ - RegisterHotKey(hwndSASWindow, 0, MOD_ALT | MOD_CONTROL, VK_DELETE); -} - -VOID STDCALL -UnregisterHotKeys(VOID) -{ - UnregisterHotKey(NULL, 0); -} - -VOID STDCALL -HandleHotKey(MSG *Msg) -{ - DPRINT1("HOTKEY: Got hot key (%d)\n", Msg->wParam); - - /* CTRL-ALT-DEL */ - if (Msg->wParam == 0) - { - STARTUPINFO StartupInfo; - PROCESS_INFORMATION ProcessInformation; - - 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", - NULL, - NULL, - NULL, - FALSE, - CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, - NULL, - NULL, - &StartupInfo, - &ProcessInformation); - - CloseHandle (ProcessInformation.hProcess); - CloseHandle (ProcessInformation.hThread); - } -} - static PWCHAR -GetUserInit (WCHAR *CommandLine) +GetUserInit( + OUT WCHAR *CommandLine, + IN DWORD BufferLength) { HKEY WinLogonKey; BOOL GotCommandLine; @@ -360,9 +301,10 @@ GetUserInit (WCHAR *CommandLine) } -static BOOL -DoLogonUser (PWCHAR Name, - PWCHAR Password) +BOOL +DoBrokenLogonUser( + IN PWLSESSION WLSession, + IN PWLX_MPR_NOTIFY_INFO pMprNotifyInfo) { PROCESS_INFORMATION ProcessInformation; STARTUPINFO StartupInfo; @@ -372,24 +314,14 @@ DoLogonUser (PWCHAR Name, BOOL Result; LPVOID lpEnvironment = NULL; MSG Msg; + BOOLEAN Old; - Result = LogonUserW (Name, - NULL, - Password, - LOGON32_LOGON_INTERACTIVE, - LOGON32_PROVIDER_DEFAULT, - &WLSession->UserToken); - if (!Result) - { - DPRINT1 ("WL: LogonUserW() failed\n"); - RtlDestroyEnvironment (lpEnvironment); - return FALSE; - } + SwitchDesktop(WLSession->ApplicationDesktop); /* Load the user profile */ ProfileInfo.dwSize = sizeof(PROFILEINFOW); ProfileInfo.dwFlags = 0; - ProfileInfo.lpUserName = Name; + ProfileInfo.lpUserName = pMprNotifyInfo->pszUserName; ProfileInfo.lpProfilePath = NULL; ProfileInfo.lpDefaultPath = NULL; ProfileInfo.lpServerName = NULL; @@ -428,10 +360,14 @@ DoLogonUser (PWCHAR Name, StartupInfo.dwFlags = 0; StartupInfo.cbReserved2 = 0; StartupInfo.lpReserved2 = 0; + + /* Get privilege */ + RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old); - Result = CreateProcessAsUserW (WLSession->UserToken, + Result = CreateProcessAsUserW( + WLSession->UserToken, NULL, - GetUserInit (CommandLine), + GetUserInit (CommandLine, MAX_PATH), NULL, NULL, FALSE, @@ -442,7 +378,7 @@ DoLogonUser (PWCHAR Name, &ProcessInformation); if (!Result) { - DPRINT1("WL: Failed to execute user shell %s\n", CommandLine); + DPRINT1("WL: Failed to execute user shell %ws\n", CommandLine); if (ImpersonateLoggedOnUser(WLSession->UserToken)) { UpdatePerUserSystemParameters(0, FALSE); @@ -454,20 +390,20 @@ DoLogonUser (PWCHAR Name, DestroyEnvironmentBlock (lpEnvironment); return FALSE; } - - RegisterHotKeys(); + /*WLSession->MsGina.Functions.WlxActivateUserShell(WLSession->MsGina.Context, + L"WinSta0\\Default", + NULL, + NULL);*/ while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0) { - if (PeekMessage(&Msg, hwndSASWindow, 0, 0, PM_REMOVE)) + if (PeekMessage(&Msg, WLSession->SASWindow, 0, 0, PM_REMOVE)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } } - UnregisterHotKeys(); - CloseHandle (ProcessInformation.hProcess); CloseHandle (ProcessInformation.hThread); @@ -488,264 +424,36 @@ DoLogonUser (PWCHAR Name, return TRUE; } -static LRESULT CALLBACK -SASWindowProc( - IN HWND hwndDlg, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam) +static BOOL +DisplayStatusMessage( + IN PWLSESSION Session, + IN HDESK hDesktop, + IN UINT ResourceId) { - DbgBreakPoint(); - switch (uMsg) - { - case WM_HOTKEY: - { - switch (lParam) - { - case MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE): - { - DispatchSAS(WLSession, WLX_SAS_TYPE_CTRL_ALT_DEL); - return TRUE; - } - } - } - } + WCHAR StatusMsg[MAX_PATH]; - return DefWindowProc(hwndDlg, uMsg, wParam, lParam); + if (Session->SuppressStatus) + return TRUE; + + if (LoadString(hAppInstance, ResourceId, StatusMsg, MAX_PATH) == 0) + return FALSE; + + return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, 0, NULL, StatusMsg); } -int STDCALL -WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nShowCmd) -{ - BOOLEAN Old; - WNDCLASS wndClass; #if 0 - LSA_STRING ProcessName, PackageName; - HANDLE LsaHandle; - LSA_OPERATIONAL_MODE Mode; - ULONG AuthenticationPackage; -#endif - - hAppInstance = hInstance; - - if(!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) - { - DPRINT1("WL: Could not register logon process\n"); - NtShutdownSystem(ShutdownNoReboot); - ExitProcess(0); - return 0; - } - - /* Get privilege */ - RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old); - - if (StartProcess(L"StartLsass")) - { - if (!StartLsass()) - { - DPRINT1("WL: Failed to start LSASS (0x%X)\n", GetLastError()); - } - } - else - { - DPRINT1("WL: StartProcess() failed!\n"); - } - - if(!(WLSession = MsGinaInit())) - { - DPRINT1("WL: Failed to initialize msgina.dll\n"); - NtShutdownSystem(ShutdownNoReboot); - ExitProcess(0); - return 0; - } - - WLSession->LogonStatus = LOGON_INITIALIZING; - - 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. */ - SetThreadDesktop(WLSession->ApplicationDesktop); - if(!SwitchDesktop(WLSession->ApplicationDesktop)) - { - DPRINT1("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError()); - } - - InitServices(); - - /* 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(!InitializeSAS(WLSession)) - { - DPRINT1("WL: Failed to initialize SAS\n"); - ExitProcess(2); - return 2; - } - -#if 0 - /* real winlogon uses "Winlogon" */ - RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon"); - Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); - if (!NT_SUCCESS(Status)) - { - switch(Status) - { - case STATUS_PORT_CONNECTION_REFUSED: - /* FIXME - we don't have the 'SeTcbPrivilege' pivilege, so set it or call - LsaAddAccountRights() and try again */ - DPRINT1("WL: LsaRegisterLogonProcess() returned STATUS_PORT_CONNECTION_REFUSED\n"); - break; - case STATUS_NAME_TOO_LONG: - DPRINT1("WL: LsaRegisterLogonProcess() returned STATUS_NAME_TOO_LONG\n"); - break; - default: - DPRINT1("WL: Failed to connect to LSASS\n"); - break; - } - return(1); - } - - RtlInitUnicodeString((PUNICODE_STRING)&PackageName, L"Kerberos"); - Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); - if (!NT_SUCCESS(Status)) - { - LsaDeregisterLogonProcess(LsaHandle); - DPRINT1("WL: Failed to lookup authentication package\n"); - return(1); - } -#endif - - /* FIXME: Create a window class and associate a Winlogon - * window procedure with it. - * Register SAS with the window. - * Register for logoff notification - */ - /* Create a window class */ - ZeroMemory(&wndClass, sizeof(WNDCLASS)); - wndClass.style = CS_GLOBALCLASS; - wndClass.lpfnWndProc = SASWindowProc; - wndClass.hInstance = hInstance; - wndClass.lpszClassName = L"SAS Window class"; - RegisterClass(&wndClass); - hwndSASWindow = CreateWindow( - L"SAS Window class", L"SAS window", 0, - 0, 0, 0, 0, - NULL, NULL, hInstance, NULL); - - /* Main loop */ -#if 0 - /* Display login prompt */ - WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - LoginPrompt, - strlen(LoginPrompt), // wcslen(LoginPrompt), - &Result, - NULL); - i = 0; - do - { - ReadConsole(GetStdHandle(STD_INPUT_HANDLE), - &LoginName[i], - 1, - &Result, - NULL); - i++; - } while (LoginName[i - 1] != '\n'); - LoginName[i - 1] = 0; - - /* Display password prompt */ - WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - PasswordPrompt, - strlen(PasswordPrompt), // wcslen(PasswordPrompt), - &Result, - NULL); - i = 0; - do - { - ReadConsole(GetStdHandle(STD_INPUT_HANDLE), - &Password[i], - 1, - &Result, - NULL); - i++; - } while (Password[i - 1] != '\n'); - Password[i - 1] =0; -#endif - - RegisterHotKeys(); - - SessionLoop(WLSession); - - UnregisterHotKeys(); - - /* 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 - { - DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n"); - ExitProcess(0); - } - - return 0; -} - -BOOL -DisplayStatusMessage(PWLSESSION Session, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage) +static BOOL +InitServices(VOID) { - if(Session->SuppressStatus) - { - return TRUE; - } - - return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, dwOptions, pTitle, pMessage); -} - -BOOL -InitServices(void) -{ - WCHAR StatusMsg[256]; + /*WCHAR StatusMsg[256]; LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR)); - DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg); + DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);*/ /* start system processes (services.exe & lsass.exe) */ if(StartProcess(L"StartServices")) { - if(!StartServices()) + if(!StartServicesManager()) { DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError()); } @@ -757,9 +465,12 @@ InitServices(void) return TRUE; } +#endif -DWORD -DoLogin(PWLSESSION Session) +#if 0 +static DWORD +DoLogin( + IN OUT PWLSESSION Session) { DWORD WlxAction, Options; WLX_MPR_NOTIFY_INFO MprNotifyInfo; @@ -784,66 +495,38 @@ DoLogin(PWLSESSION Session) &MprNotifyInfo, (PVOID*)&Profile); + if (WlxAction == WLX_SAS_ACTION_LOGON) + { + Session->UserToken = Token; + if (!DoBrokenLogonUser(Session, &MprNotifyInfo)) + WlxAction = WLX_SAS_ACTION_NONE; + } return WlxAction; } +#endif -void -SessionLoop(PWLSESSION Session) +static VOID +SessionLoop( + IN OUT PWLSESSION Session) { - //WCHAR StatusMsg[256]; - // HANDLE hShutdownEvent; - DWORD WlxAction; - MSG Msg; + //WCHAR StatusMsg[256]; + //HANDLE hShutdownEvent; + 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 */ - DisplaySASNotice(Session); - Session->SuppressStatus = FALSE; + Session->LogonStatus = WKSTA_IS_LOGGED_OFF; + RemoveStatusMessage(Session); + DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT); - if(Session->SASAction == WLX_SAS_ACTION_LOGOFF) - { - /* the system wants to log off here */ - Session->LogonStatus = LOGON_SHUTDOWN; - break; - } - } + /* Message loop for the SAS window */ + while (GetMessage(&Msg, WLSession->SASWindow, 0, 0)) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } - WlxAction = DoLogin(Session); - if (WlxAction == WLX_SAS_ACTION_LOGON) - { - DoLogonUser(L"Administrator", L"Secret"); - } - else 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 */ - DPRINT1("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; - } + /* Don't go there! */ +#if 0 /* FIXME - don't leave the loop when suspending the computer */ if(WLX_SUSPENDING(WlxAction)) { @@ -860,13 +543,7 @@ SessionLoop(PWLSESSION Session) break; } - /* Message loop for the SAS window */ - while(GetMessage(&Msg, hwndSASWindow, 0, 0)) - { - TranslateMessage(&Msg); - DispatchMessage(&Msg); - } - } +#endif /* LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR)); MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, @@ -958,3 +635,145 @@ SessionLoop(PWLSESSION Session) */ } +int WINAPI +WinMain( + IN HINSTANCE hInstance, + IN HINSTANCE hPrevInstance, + IN LPSTR lpCmdLine, + IN int nShowCmd) +{ +#if 0 + LSA_STRING ProcessName, PackageName; + HANDLE LsaHandle; + LSA_OPERATIONAL_MODE Mode; + BOOLEAN Old; + ULONG AuthenticationPackage; + NTSTATUS Status; +#endif + + hAppInstance = hInstance; + + if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) + { + ERR("WL: Could not register logon process\n"); + NtShutdownSystem(ShutdownNoReboot); + ExitProcess(0); + return 0; + } + + WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION)); + if (!WLSession) + { + NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); + ExitProcess(1); + return 1; + } + + if (!CreateWindowStationAndDesktops(WLSession)) + { + NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); + ExitProcess(1); + return 1; + } + + /* Check for pending setup */ + if (GetSetupType() != 0) + { + DPRINT("Winlogon: CheckForSetup() in setup mode\n"); + + /* Run setup and reboot when done */ + SwitchDesktop(WLSession->ApplicationDesktop); + RunSetup(); + + NtShutdownSystem(ShutdownReboot); + ExitProcess(0); + return 0; + } + + /* Load and initialize gina */ + if (!GinaInit(WLSession)) + { + ERR("WL: Failed to initialize Gina\n"); + NtShutdownSystem(ShutdownNoReboot); + ExitProcess(0); + return 0; + } + + DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); + + if (!StartServicesManager()) + { + ERR("WL: Could not start services.exe\n"); + NtShutdownSystem(ShutdownNoReboot); + ExitProcess(0); + return 0; + } + + if (!StartLsass()) + { + DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError()); + return 1; + } + +#if 0 + /* Connect to NetLogon service (lsass.exe) */ + /* Real winlogon uses "Winlogon" */ + RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon"); + Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); + if (Status == STATUS_PORT_CONNECTION_REFUSED) + { + /* Add the 'SeTcbPrivilege' privilege and try again */ + RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old); + Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); + } + if (!NT_SUCCESS(Status)) + { + ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status)); + return 1; + } + + RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W); + Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); + if (!NT_SUCCESS(Status)) + { + ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status)); + LsaDeregisterLogonProcess(LsaHandle); + return 1; + } +#endif + + /* Create a hidden window to get SAS notifications */ + if (!InitializeSAS(WLSession)) + { + ERR("WL: Failed to initialize SAS\n"); + ExitProcess(2); + return 2; + } + + /* Main loop */ + SessionLoop(WLSession); + + /* FIXME - Flush disks and registry, ... */ + + 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); + } + + return 0; +} diff --git a/reactos/base/system/winlogon/winlogon.h b/reactos/base/system/winlogon/winlogon.h index 7b9521beb85..f24d5b4eb7a 100644 --- a/reactos/base/system/winlogon/winlogon.h +++ b/reactos/base/system/winlogon/winlogon.h @@ -34,40 +34,13 @@ #include #include #include +#include #include #include "setup.h" #include "resource.h" -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); @@ -97,36 +70,50 @@ typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID); typedef struct _MSGINAFUNCTIONS { - PFWLXNEGOTIATE WlxNegotiate; - PFWLXINITIALIZE WlxInitialize; - PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice; - PFWLXLOGGEDOUTSAS WlxLoggedOutSAS; - PFWLXACTIVATEUSERSHELL WlxActivateUserShell; - PFWLXLOGGEDONSAS WlxLoggedOnSAS; - PFWLXDISPLAYLOCKEDNOTICE WlxDisplayLockedNotice; - PFWLXWKSTALOCKEDSAS WlxWkstaLockedSAS; - PFWLXISLOCKOK WlxIsLockOk; - PFWLXISLOGOFFOK WlxIsLogoffOk; - PFWLXLOGOFF WlxLogoff; - PFWLXSHUTDOWN WlxShutdown; + /* Functions always available for a valid GINA */ + PFWLXNEGOTIATE WlxNegotiate; + PFWLXINITIALIZE WlxInitialize; - PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; - PFWLXSTARTAPPLICATION WlxStartApplication; + /* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */ + PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice; + PFWLXLOGGEDOUTSAS WlxLoggedOutSAS; + PFWLXACTIVATEUSERSHELL WlxActivateUserShell; + PFWLXLOGGEDONSAS WlxLoggedOnSAS; + PFWLXDISPLAYLOCKEDNOTICE WlxDisplayLockedNotice; + PFWLXWKSTALOCKEDSAS WlxWkstaLockedSAS; + PFWLXISLOCKOK WlxIsLockOk; + PFWLXISLOGOFFOK WlxIsLogoffOk; + PFWLXLOGOFF WlxLogoff; + PFWLXSHUTDOWN WlxShutdown; - PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad; - PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage; - PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; - PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage; + /* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */ + PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; + PFWLXSTARTAPPLICATION WlxStartApplication; + + /* 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; + PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage; + PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; + PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage; + + /* Functions available if WlxVersion >= WLX_VERSION_1_4 (MS Windows XP) */ } MSGINAFUNCTIONS, *PMSGINAFUNCTIONS; typedef struct _MSGINAINSTANCE { - HMODULE hDllInstance; - MSGINAFUNCTIONS Functions; - PVOID Context; - DWORD Version; + HMODULE hDllInstance; + MSGINAFUNCTIONS Functions; + PVOID Context; + DWORD Version; } MSGINAINSTANCE, *PMSGINAINSTANCE; +/* FIXME: put in an enum */ +#define WKSTA_IS_LOGGED_OFF 0 +#define WKSTA_IS_LOGGED_ON 1 +#define WKSTA_IS_LOCKED 2 + typedef struct _WLSESSION { MSGINAINSTANCE MsGina; @@ -142,22 +129,16 @@ typedef struct _WLSESSION HDESK ScreenSaverDesktop; LUID LogonId; HANDLE UserToken; + + /* Logon informations */ + DWORD Options; + WLX_MPR_NOTIFY_INFO MprNotifyInfo; + WLX_PROFILE_V2_0 Profile; } WLSESSION, *PWLSESSION; extern HINSTANCE hAppInstance; extern PWLSESSION WLSession; -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) || \ @@ -180,6 +161,51 @@ BOOL WINAPI UpdatePerUserSystemParameters(DWORD dwUnknown, DWORD dwReserved); +/* sas.c */ +VOID +DispatchSAS( + IN OUT PWLSESSION Session, + IN DWORD dwSasType); +BOOL +InitializeSAS( + IN OUT PWLSESSION Session); + +/* wlx.c */ +BOOL +GinaInit( + IN OUT PWLSESSION Session); +BOOL +CreateWindowStationAndDesktops( + IN OUT PWLSESSION Session); + +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); + #endif /* __WINLOGON_MAIN_H__ */ /* EOF */ diff --git a/reactos/base/system/winlogon/wlx.c b/reactos/base/system/winlogon/wlx.c index ef2601dad81..d53258e87b0 100644 --- a/reactos/base/system/winlogon/wlx.c +++ b/reactos/base/system/winlogon/wlx.c @@ -1,22 +1,21 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Winlogon * FILE: services/winlogon/wlx.c * PURPOSE: Logon - * PROGRAMMER: David Welch (welch@cwcom.net) - * UPDATE HISTORY: - * Created 22/05/98 + * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) + * Ge van Geldorp (gvg@reactos.com) + * Hervé Poussineau (hpoussin@reactos.org) */ /* INCLUDES *****************************************************************/ #include "winlogon.h" -#define NDEBUG -#include +#define YDEBUG +#include -#define Unimplemented DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__) +//#define UNIMPLEMENTED DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__) #define WINLOGON_DESKTOP L"Winlogon" @@ -25,10 +24,9 @@ */ VOID WINAPI WlxUseCtrlAltDel( - HANDLE hWlx -) + HANDLE hWlx) { - WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, NULL); + WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, NULL); } /* @@ -36,11 +34,10 @@ WlxUseCtrlAltDel( */ VOID WINAPI WlxSetContextPointer( - HANDLE hWlx, - PVOID pWlxContext -) + HANDLE hWlx, + PVOID pWlxContext) { - WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, NULL); + WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, NULL); } /* @@ -48,11 +45,10 @@ WlxSetContextPointer( */ VOID WINAPI WlxSasNotify( - HANDLE hWlx, - DWORD dwSasType -) + HANDLE hWlx, + DWORD dwSasType) { - DispatchSAS((PWLSESSION)hWlx, dwSasType); + DispatchSAS((PWLSESSION)hWlx, dwSasType); } /* @@ -60,12 +56,11 @@ WlxSasNotify( */ BOOL WINAPI WlxSetTimeout( - HANDLE hWlx, - DWORD Timeout -) + HANDLE hWlx, + DWORD Timeout) { - /* Unimplemented; */ - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -73,14 +68,13 @@ WlxSetTimeout( */ int WINAPI WlxAssignShellProtection( - HANDLE hWlx, - HANDLE hToken, - HANDLE hProcess, - HANDLE hThread -) + HANDLE hWlx, + HANDLE hToken, + HANDLE hProcess, + HANDLE hThread) { - Unimplemented; - return 0; + UNIMPLEMENTED; + return 0; } /* @@ -88,14 +82,13 @@ WlxAssignShellProtection( */ int WINAPI WlxMessageBox( - HANDLE hWlx, - HWND hwndOwner, - LPWSTR lpszText, - LPWSTR lpszTitle, - UINT fuStyle -) + HANDLE hWlx, + HWND hwndOwner, + LPWSTR lpszText, + LPWSTR lpszTitle, + UINT fuStyle) { - return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); + return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); } /* @@ -103,14 +96,13 @@ WlxMessageBox( */ int WINAPI WlxDialogBox( - HANDLE hWlx, - HANDLE hInst, - LPWSTR lpszTemplate, - HWND hwndOwner, - DLGPROC dlgprc -) + HANDLE hWlx, + HANDLE hInst, + LPWSTR lpszTemplate, + HWND hwndOwner, + DLGPROC dlgprc) { - return (int)DialogBox(hInst, lpszTemplate, hwndOwner, dlgprc); + return (int)DialogBox(hInst, lpszTemplate, hwndOwner, dlgprc); } /* @@ -118,30 +110,28 @@ WlxDialogBox( */ int WINAPI WlxDialogBoxParam( - HANDLE hWlx, - HANDLE hInst, - LPWSTR lpszTemplate, - HWND hwndOwner, - DLGPROC dlgprc, - LPARAM dwInitParam -) + HANDLE hWlx, + HANDLE hInst, + LPWSTR lpszTemplate, + HWND hwndOwner, + DLGPROC dlgprc, + LPARAM dwInitParam) { - return (int)DialogBoxParam(hInst, lpszTemplate, hwndOwner, dlgprc, dwInitParam); + return (int)DialogBoxParam(hInst, lpszTemplate, hwndOwner, dlgprc, dwInitParam); } /* - * @unimplemented + * @implemented */ int WINAPI WlxDialogBoxIndirect( - HANDLE hWlx, - HANDLE hInst, - LPCDLGTEMPLATE hDialogTemplate, - HWND hwndOwner, - DLGPROC dlgprc -) + HANDLE hWlx, + HANDLE hInst, + LPCDLGTEMPLATE hDialogTemplate, + HWND hwndOwner, + DLGPROC dlgprc) { - return (int)DialogBoxIndirect(hInst, hDialogTemplate, hwndOwner, dlgprc); + return (int)DialogBoxIndirect(hInst, hDialogTemplate, hwndOwner, dlgprc); } /* @@ -149,39 +139,36 @@ WlxDialogBoxIndirect( */ int WINAPI WlxDialogBoxIndirectParam( - HANDLE hWlx, - HANDLE hInst, - LPCDLGTEMPLATE hDialogTemplate, - HWND hwndOwner, - DLGPROC dlgprc, - LPARAM dwInitParam -) + HANDLE hWlx, + HANDLE hInst, + LPCDLGTEMPLATE hDialogTemplate, + HWND hwndOwner, + DLGPROC dlgprc, + LPARAM dwInitParam) { - return (int)DialogBoxIndirectParam(hInst, hDialogTemplate, hwndOwner, dlgprc, dwInitParam); + return (int)DialogBoxIndirectParam(hInst, hDialogTemplate, hwndOwner, dlgprc, dwInitParam); } /* - * @unimplemented + * @implemented */ int WINAPI WlxSwitchDesktopToUser( - HANDLE hWlx -) + HANDLE hWlx) { - Unimplemented; - return 0; + PWLSESSION Session = (PWLSESSION)hWlx; + return (int)SwitchDesktop(Session->ApplicationDesktop); } /* - * @unimplemented + * @implemented */ int WINAPI WlxSwitchDesktopToWinlogon( - HANDLE hWlx -) + HANDLE hWlx) { - Unimplemented; - return 0; + PWLSESSION Session = (PWLSESSION)hWlx; + return (int)SwitchDesktop(Session->WinlogonDesktop); } /* @@ -189,13 +176,12 @@ WlxSwitchDesktopToWinlogon( */ int WINAPI WlxChangePasswordNotify( - HANDLE hWlx, - PWLX_MPR_NOTIFY_INFO pMprInfo, - DWORD dwChangeInfo -) + HANDLE hWlx, + PWLX_MPR_NOTIFY_INFO pMprInfo, + DWORD dwChangeInfo) { - Unimplemented; - return 0; + UNIMPLEMENTED; + return 0; } /* @@ -203,12 +189,11 @@ WlxChangePasswordNotify( */ BOOL WINAPI WlxGetSourceDesktop( - HANDLE hWlx, - PWLX_DESKTOP* ppDesktop -) + HANDLE hWlx, + PWLX_DESKTOP* ppDesktop) { - Unimplemented; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -216,12 +201,11 @@ WlxGetSourceDesktop( */ BOOL WINAPI WlxSetReturnDesktop( - HANDLE hWlx, - PWLX_DESKTOP pDesktop -) + HANDLE hWlx, + PWLX_DESKTOP pDesktop) { - Unimplemented; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -229,15 +213,14 @@ WlxSetReturnDesktop( */ BOOL WINAPI WlxCreateUserDesktop( - HANDLE hWlx, - HANDLE hToken, - DWORD Flags, - PWSTR pszDesktopName, - PWLX_DESKTOP* ppDesktop -) + HANDLE hWlx, + HANDLE hToken, + DWORD Flags, + PWSTR pszDesktopName, + PWLX_DESKTOP* ppDesktop) { - Unimplemented; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -245,15 +228,14 @@ WlxCreateUserDesktop( */ int WINAPI WlxChangePasswordNotifyEx( - HANDLE hWlx, - PWLX_MPR_NOTIFY_INFO pMprInfo, - DWORD dwChangeInfo, - PWSTR ProviderName, - PVOID Reserved -) + HANDLE hWlx, + PWLX_MPR_NOTIFY_INFO pMprInfo, + DWORD dwChangeInfo, + PWSTR ProviderName, + PVOID Reserved) { - Unimplemented; - return 0; + UNIMPLEMENTED; + return 0; } /* @@ -261,13 +243,12 @@ WlxChangePasswordNotifyEx( */ BOOL WINAPI WlxCloseUserDesktop( - HANDLE hWlx, - PWLX_DESKTOP pDesktop, - HANDLE hToken -) + HANDLE hWlx, + PWLX_DESKTOP pDesktop, + HANDLE hToken) { - Unimplemented; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -275,32 +256,32 @@ WlxCloseUserDesktop( */ BOOL WINAPI WlxSetOption( - HANDLE hWlx, - DWORD Option, - ULONG_PTR Value, - ULONG_PTR* OldValue -) + HANDLE hWlx, + DWORD Option, + ULONG_PTR Value, + ULONG_PTR* OldValue) { - PWLSESSION Session = (PWLSESSION)hWlx; + PWLSESSION Session = (PWLSESSION)hWlx; + UNIMPLEMENTED; - if(Session || !Value) - { - switch(Option) - { - case WLX_OPTION_USE_CTRL_ALT_DEL: - return TRUE; - case WLX_OPTION_CONTEXT_POINTER: - { - *OldValue = (ULONG_PTR)Session->MsGina.Context; - Session->MsGina.Context = (PVOID)Value; - return TRUE; - } - case WLX_OPTION_USE_SMART_CARD: - return FALSE; - } - } + if (Session || !Value) + { + switch (Option) + { + case WLX_OPTION_USE_CTRL_ALT_DEL: + return TRUE; + case WLX_OPTION_CONTEXT_POINTER: + { + *OldValue = (ULONG_PTR)Session->MsGina.Context; + Session->MsGina.Context = (PVOID)Value; + return TRUE; + } + case WLX_OPTION_USE_SMART_CARD: + return FALSE; + } + } - return FALSE; + return FALSE; } /* @@ -308,57 +289,57 @@ WlxSetOption( */ BOOL WINAPI WlxGetOption( - HANDLE hWlx, - DWORD Option, - ULONG_PTR* Value -) + HANDLE hWlx, + DWORD Option, + ULONG_PTR* Value) { - PMSGINAINSTANCE Instance = (PMSGINAINSTANCE)hWlx; - Unimplemented; - if(Instance || !Value) - { - switch(Option) - { - case WLX_OPTION_USE_CTRL_ALT_DEL: - return TRUE; - case WLX_OPTION_CONTEXT_POINTER: - { - *Value = (ULONG_PTR)Instance->Context; - return TRUE; - } - case WLX_OPTION_USE_SMART_CARD: - case WLX_OPTION_SMART_CARD_PRESENT: - case WLX_OPTION_SMART_CARD_INFO: - *Value = 0; - return FALSE; - case WLX_OPTION_DISPATCH_TABLE_SIZE: - { - switch(Instance->Version) - { - case WLX_VERSION_1_0: - *Value = sizeof(WLX_DISPATCH_VERSION_1_0); - break; - case WLX_VERSION_1_1: - *Value = sizeof(WLX_DISPATCH_VERSION_1_1); - break; - case WLX_VERSION_1_2: - *Value = sizeof(WLX_DISPATCH_VERSION_1_2); - break; - case WLX_VERSION_1_3: - *Value = sizeof(WLX_DISPATCH_VERSION_1_3); - break; - case WLX_VERSION_1_4: - *Value = sizeof(WLX_DISPATCH_VERSION_1_4); - break; - default: - return 0; - } - return TRUE; - } - } - } + PMSGINAINSTANCE Instance = (PMSGINAINSTANCE)hWlx; + UNIMPLEMENTED; - return FALSE; + if (Instance || !Value) + { + switch (Option) + { + case WLX_OPTION_USE_CTRL_ALT_DEL: + return TRUE; + case WLX_OPTION_CONTEXT_POINTER: + { + *Value = (ULONG_PTR)Instance->Context; + return TRUE; + } + case WLX_OPTION_USE_SMART_CARD: + case WLX_OPTION_SMART_CARD_PRESENT: + case WLX_OPTION_SMART_CARD_INFO: + *Value = 0; + return FALSE; + case WLX_OPTION_DISPATCH_TABLE_SIZE: + { + switch (Instance->Version) + { + case WLX_VERSION_1_0: + *Value = sizeof(WLX_DISPATCH_VERSION_1_0); + break; + case WLX_VERSION_1_1: + *Value = sizeof(WLX_DISPATCH_VERSION_1_1); + break; + case WLX_VERSION_1_2: + *Value = sizeof(WLX_DISPATCH_VERSION_1_2); + break; + case WLX_VERSION_1_3: + *Value = sizeof(WLX_DISPATCH_VERSION_1_3); + break; + case WLX_VERSION_1_4: + *Value = sizeof(WLX_DISPATCH_VERSION_1_4); + break; + default: + return FALSE; + } + return TRUE; + } + } + } + + return FALSE; } /* @@ -366,10 +347,9 @@ WlxGetOption( */ VOID WINAPI WlxWin31Migrate( - HANDLE hWlx -) + HANDLE hWlx) { - Unimplemented; + UNIMPLEMENTED; } /* @@ -377,11 +357,10 @@ WlxWin31Migrate( */ BOOL WINAPI WlxQueryClientCredentials( - PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred -) + PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) { - Unimplemented; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -389,45 +368,20 @@ WlxQueryClientCredentials( */ BOOL WINAPI WlxQueryInetConnectorCredentials( - PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred -) + PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) { - Unimplemented; - return FALSE; -} - -/* - * @unimplemented - */ -DWORD WINAPI -WlxQueryConsoleSwitchCredentials( - PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred -) -{ - Unimplemented; - return 0; + UNIMPLEMENTED; + return FALSE; } /* * @unimplemented */ BOOL WINAPI -WlxQueryTsLogonCredentials( - PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred -) +WlxDisconnect(VOID) { - Unimplemented; - return FALSE; -} - -/* - * @unimplemented - */ -BOOL WINAPI -WlxDisconnect(void) -{ - Unimplemented; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -435,284 +389,332 @@ WlxDisconnect(void) */ DWORD WINAPI WlxQueryTerminalServicesData( - HANDLE hWlx, - PWLX_TERMINAL_SERVICES_DATA pTSData, - WCHAR* UserName, - WCHAR* Domain -) + HANDLE hWlx, + PWLX_TERMINAL_SERVICES_DATA pTSData, + WCHAR* UserName, + WCHAR* Domain) { - Unimplemented; - return 0; + UNIMPLEMENTED; + return 0; } -const +/* + * @unimplemented + */ +DWORD WINAPI +WlxQueryConsoleSwitchCredentials( + PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred) +{ + UNIMPLEMENTED; + return 0; +} + +/* + * @unimplemented + */ +BOOL WINAPI +WlxQueryTsLogonCredentials( + PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred) +{ + UNIMPLEMENTED; + return FALSE; +} + +static const WLX_DISPATCH_VERSION_1_4 FunctionTable = { - WlxUseCtrlAltDel, - WlxSetContextPointer, - WlxSasNotify, - WlxSetTimeout, - WlxAssignShellProtection, - WlxMessageBox, - WlxDialogBox, - WlxDialogBoxParam, - WlxDialogBoxIndirect, - WlxDialogBoxIndirectParam, - WlxSwitchDesktopToUser, - WlxSwitchDesktopToWinlogon, - WlxChangePasswordNotify, - WlxGetSourceDesktop, - WlxSetReturnDesktop, - WlxCreateUserDesktop, - WlxChangePasswordNotifyEx, - WlxCloseUserDesktop, - WlxSetOption, - WlxGetOption, - WlxWin31Migrate, - WlxQueryClientCredentials, - WlxQueryInetConnectorCredentials, - WlxDisconnect, - WlxQueryTerminalServicesData, - WlxQueryConsoleSwitchCredentials, - WlxQueryTsLogonCredentials + WlxUseCtrlAltDel, + WlxSetContextPointer, + WlxSasNotify, + WlxSetTimeout, + WlxAssignShellProtection, + WlxMessageBox, + WlxDialogBox, + WlxDialogBoxParam, + WlxDialogBoxIndirect, + WlxDialogBoxIndirectParam, + WlxSwitchDesktopToUser, + WlxSwitchDesktopToWinlogon, + WlxChangePasswordNotify, + WlxGetSourceDesktop, + WlxSetReturnDesktop, + WlxCreateUserDesktop, + WlxChangePasswordNotifyEx, + WlxCloseUserDesktop, + WlxSetOption, + WlxGetOption, + WlxWin31Migrate, + WlxQueryClientCredentials, + WlxQueryInetConnectorCredentials, + WlxDisconnect, + WlxQueryTerminalServicesData, + WlxQueryConsoleSwitchCredentials, + WlxQueryTsLogonCredentials }; /******************************************************************************/ -static void -GetMsGinaPath(WCHAR *path) +static BOOL +GetGinaPath( + OUT LPWSTR Path, + IN DWORD Len) { - DWORD Status, Type, Size; - HKEY hKey; + LONG Status; + DWORD Type, Size; + HKEY hKey; - Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", - 0, - KEY_QUERY_VALUE, - &hKey); - if(Status != ERROR_SUCCESS) - { - wcscpy(path, L"msgina.dll"); - return; - } + Status = RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", + 0, + KEY_QUERY_VALUE, + &hKey); + if (Status != ERROR_SUCCESS) + { + /* Default value */ + wcsncpy(Path, L"msgina.dll", Len); + return TRUE; + } - Size = MAX_PATH * sizeof(WCHAR); - Status = RegQueryValueEx(hKey, - L"GinaDLL", - NULL, - &Type, - (LPBYTE)path, - &Size); - if((Status != ERROR_SUCCESS) || (Size != REG_SZ) || (Size == 0)) - { - wcscpy(path, L"msgina.dll"); - } - RegCloseKey(hKey); + Size = Len * sizeof(WCHAR); + Status = RegQueryValueEx( + hKey, + L"GinaDLL", + NULL, + &Type, + (LPBYTE)Path, + &Size); + if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0) + wcsncpy(Path, L"msgina.dll", Len); + RegCloseKey(hKey); + return TRUE; } -INT_PTR CALLBACK -GinaLoadFailedProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) +static INT_PTR CALLBACK +GinaLoadFailedWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - switch(uMsg) - { - case WM_COMMAND: - { - switch(LOWORD(wParam)) - { - case IDOK: - EndDialog(hwndDlg, IDOK); - break; - } - break; - } - case WM_INITDIALOG: - { - int len; - WCHAR str[MAX_PATH], str2[MAX_PATH]; + switch (uMsg) + { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hwndDlg, IDOK); + break; + } + break; + } + case WM_INITDIALOG: + { + int len; + WCHAR templateText[MAX_PATH], text[MAX_PATH]; - if(lParam) - { - len = GetDlgItemText(hwndDlg, IDC_GINALOADFAILED, str, MAX_PATH); + len = GetDlgItemText(hwndDlg, IDC_GINALOADFAILED, templateText, MAX_PATH); + if (len) + { + wsprintf(text, templateText, (LPWSTR)lParam); + SetDlgItemText(hwndDlg, IDC_GINALOADFAILED, text); + } + SetFocus(GetDlgItem(hwndDlg, IDOK)); + break; + } + case WM_CLOSE: + { + EndDialog(hwndDlg, IDCANCEL); + return TRUE; + } + } - if(len) - { - wsprintf(str2, str, (LPWSTR)lParam); - SetDlgItemText(hwndDlg, IDC_GINALOADFAILED, str2); - } - } - SetFocus(GetDlgItem(hwndDlg, IDOK)); - break; - } - case WM_CLOSE: - { - EndDialog(hwndDlg, IDCANCEL); - return TRUE; - } - } - return FALSE; + return DefWindowProc(hwndDlg, uMsg, wParam, lParam); +} + +#define FAIL_AND_RETURN() return DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)GinaDll) && FALSE +static BOOL +LoadGina( + IN OUT PMSGINAFUNCTIONS Functions, + OUT DWORD *DllVersion, + OUT HMODULE *GinaInstance) +{ + HMODULE hGina; + WCHAR GinaDll[MAX_PATH + 1]; + + GinaDll[0] = '\0'; + if (!GetGinaPath(GinaDll, MAX_PATH)) + FAIL_AND_RETURN(); + /* Terminate string */ + GinaDll[MAX_PATH] = '\0'; + + if (!(hGina = LoadLibrary(GinaDll))) + FAIL_AND_RETURN(); + *GinaInstance = hGina; + + Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); + Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize"); + + if (!Functions->WlxInitialize) + FAIL_AND_RETURN(); + + if (!Functions->WlxNegotiate) + { + /* Assume current version */ + *DllVersion = WLX_CURRENT_VERSION; + } + else if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion)) + FAIL_AND_RETURN(); + + if (*DllVersion >= WLX_VERSION_1_0) + { + Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell"); + if (!Functions->WlxActivateUserShell) FAIL_AND_RETURN(); + Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice"); + if (!Functions->WlxDisplayLockedNotice) FAIL_AND_RETURN(); + Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice"); + if (!Functions->WlxDisplaySASNotice) FAIL_AND_RETURN(); + Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk"); + if (!Functions->WlxIsLockOk) FAIL_AND_RETURN(); + Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk"); + if (!Functions->WlxIsLogoffOk) FAIL_AND_RETURN(); + Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS"); + if (!Functions->WlxLoggedOnSAS) FAIL_AND_RETURN(); + Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS"); + if (!Functions->WlxLoggedOutSAS) FAIL_AND_RETURN(); + Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff"); + if (!Functions->WlxLogoff) FAIL_AND_RETURN(); + Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown"); + if (!Functions->WlxShutdown) FAIL_AND_RETURN(); + Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS"); + if (!Functions->WlxWkstaLockedSAS) FAIL_AND_RETURN(); + } + + if (*DllVersion >= WLX_VERSION_1_1) + { + Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify"); + if (!Functions->WlxScreenSaverNotify) FAIL_AND_RETURN(); + Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication"); + if (!Functions->WlxStartApplication) FAIL_AND_RETURN(); + } + + if (*DllVersion >= WLX_VERSION_1_3) + { + Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage"); + if (!Functions->WlxDisplayStatusMessage) FAIL_AND_RETURN(); + Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage"); + if (!Functions->WlxGetStatusMessage) FAIL_AND_RETURN(); + Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad"); + if (!Functions->WlxNetworkProviderLoad) FAIL_AND_RETURN(); + Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage"); + if (!Functions->WlxRemoveStatusMessage) FAIL_AND_RETURN(); + } + + return TRUE; +} +#undef FAIL_AND_RETURN + +BOOL +GinaInit( + IN OUT PWLSESSION Session) +{ + DWORD GinaDllVersion; + + if (!LoadGina(&Session->MsGina.Functions, &GinaDllVersion, &Session->MsGina.hDllInstance)) + return FALSE; + + Session->MsGina.Context = NULL; + Session->MsGina.Version = GinaDllVersion; + Session->SuppressStatus = FALSE; + + return Session->MsGina.Functions.WlxInitialize( + Session->InteractiveWindowStationName, + (HANDLE)Session, + NULL, + (PVOID)&FunctionTable, + &Session->MsGina.Context); } BOOL -LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion, HMODULE *GinaInstance) +CreateWindowStationAndDesktops( + IN OUT PWLSESSION Session) { - HMODULE hGina; - WCHAR GinaDll[MAX_PATH + 1]; + /* + * Create the interactive window station + */ + Session->InteractiveWindowStationName = L"WinSta0"; + Session->InteractiveWindowStation = CreateWindowStation( + Session->InteractiveWindowStationName, + 0, + WINSTA_CREATEDESKTOP, + NULL); + if (!Session->InteractiveWindowStation) + { + ERR("WL: Failed to create window station (%lu)\n", GetLastError()); + return FALSE; + } + SetProcessWindowStation(Session->InteractiveWindowStation); - GetMsGinaPath(GinaDll); + /* + * Create the application desktop + */ + Session->ApplicationDesktop = CreateDesktop( + L"Default", + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); + if (!Session->ApplicationDesktop) + { + ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError()); + return FALSE; + } - if(!(hGina = LoadLibrary(GinaDll))) - { - DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedProc, (LPARAM)&GinaDll); - return FALSE; - } - *GinaInstance = hGina; + /* + * Create the winlogon desktop + */ + Session->WinlogonDesktop = CreateDesktop( + WINLOGON_DESKTOP, + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); + if (!Session->WinlogonDesktop) + { + ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError()); + return FALSE; + } - Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); - Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize"); + /* + * Create the screen saver desktop + */ + Session->ScreenSaverDesktop = CreateDesktop( + L"Screen-Saver", + NULL, + NULL, + 0, /* FIXME: Set some flags */ + GENERIC_ALL, + NULL); + if(!Session->ScreenSaverDesktop) + { + ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError()); + return FALSE; + } - if(Functions->WlxNegotiate) - { - if(!Functions->WlxNegotiate(WLX_VERSION_1_3, DllVersion)) - { - return FALSE; - } + /* FIXME: big HACK */ + Session->WinlogonDesktop = Session->ApplicationDesktop; - if(*DllVersion >= WLX_VERSION_1_0) - { - Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell"); - Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice"); - Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice"); - Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk"); - Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk"); - Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS"); - Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS"); - Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff"); - Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown"); - Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS"); - } + /* + * Switch to winlogon desktop + */ + if (!SetThreadDesktop(Session->WinlogonDesktop) || + !SwitchDesktop(Session->WinlogonDesktop)) + { + ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError()); + return FALSE; + } - if(*DllVersion >= WLX_VERSION_1_1) - { - Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify"); - Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication"); - } - - if(*DllVersion >= WLX_VERSION_1_3) - { - Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage"); - Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage"); - Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad"); - Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage"); - } - - if(*DllVersion >= WLX_VERSION_1_4) - { - - } - } - - return (Functions->WlxNegotiate != NULL) && (Functions->WlxInitialize != NULL); + return TRUE; } - -PWLSESSION -MsGinaInit(void) -{ - PWLSESSION WLSession; - DWORD GinaDllVersion; - - WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION)); - if(!WLSession) - { - return NULL; - } - - if(!LoadGina(&WLSession->MsGina.Functions, &GinaDllVersion, &WLSession->MsGina.hDllInstance)) - { - HeapFree(GetProcessHeap(), 0, WLSession); - return NULL; - } - - WLSession->MsGina.Context = NULL; - WLSession->MsGina.Version = GinaDllVersion; - WLSession->SuppressStatus = FALSE; - - if(!WLSession->MsGina.Functions.WlxInitialize(WLSession->InteractiveWindowStationName, - (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->InteractiveWindowStationName = L"WinSta0"; - Session->InteractiveWindowStation = CreateWindowStation(Session->InteractiveWindowStationName, - 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(WINLOGON_DESKTOP, - 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; -} - diff --git a/reactos/dll/win32/msgina/gui.c b/reactos/dll/win32/msgina/gui.c new file mode 100644 index 00000000000..488122dcbc5 --- /dev/null +++ b/reactos/dll/win32/msgina/gui.c @@ -0,0 +1,380 @@ +/* + * PROJECT: ReactOS msgina.dll + * FILE: dll/win32/msgina/gui.c + * PURPOSE: ReactOS Logon GINA DLL + * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org) + */ + +#include "msgina.h" + +#include +#define TRACE DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint +#define FIXME DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint +#define WARN DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint +#undef DPRINT +#undef DPRINT1 + +typedef struct _DISPLAYSTATUSMSG +{ + PGINA_CONTEXT Context; + HDESK hDesktop; + DWORD dwOptions; + PWSTR pTitle; + PWSTR pMessage; + HANDLE StartupEvent; +} DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG; + +static BOOL +GUIInitialize( + IN OUT PGINA_CONTEXT pgContext) +{ + TRACE("GUIInitialize(%p)\n", pgContext); + return TRUE; +} + +static BOOL CALLBACK +StatusMessageWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam; + if (!msg) + return FALSE; + + msg->Context->hStatusWindow = hwndDlg; + + if (msg->pTitle) + SetWindowText(hwndDlg, msg->pTitle); + SetDlgItemText(hwndDlg, IDC_STATUSLABEL, msg->pMessage); + if (!msg->Context->SignaledStatusWindowCreated) + { + msg->Context->SignaledStatusWindowCreated = TRUE; + SetEvent(msg->StartupEvent); + } + break; + } + } + return DefWindowProc(hwndDlg, uMsg, wParam, lParam); +} + +static DWORD WINAPI +StartupWindowThread(LPVOID lpParam) +{ + HDESK OldDesk; + PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam; + + OldDesk = GetThreadDesktop(GetCurrentThreadId()); + + if(!SetThreadDesktop(msg->hDesktop)) + { + HeapFree(GetProcessHeap(), 0, lpParam); + return FALSE; + } + DialogBoxParam( + hDllInstance, + MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG), + 0, + StatusMessageWindowProc, + (LPARAM)lpParam); + SetThreadDesktop(OldDesk); + + msg->Context->hStatusWindow = 0; + msg->Context->SignaledStatusWindowCreated = FALSE; + + HeapFree(GetProcessHeap(), 0, lpParam); + return TRUE; +} + +static BOOL +GUIDisplayStatusMessage( + IN PGINA_CONTEXT pgContext, + IN HDESK hDesktop, + IN DWORD dwOptions, + IN PWSTR pTitle, + IN PWSTR pMessage) +{ + PDISPLAYSTATUSMSG msg; + HANDLE Thread; + DWORD ThreadId; + + TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage); + + if (!pgContext->hStatusWindow) + { + msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG)); + if(!msg) + return FALSE; + + msg->Context = pgContext; + msg->dwOptions = dwOptions; + msg->pTitle = pTitle; + msg->pMessage = pMessage; + msg->hDesktop = hDesktop; + + msg->StartupEvent = CreateEvent( + NULL, + TRUE, + FALSE, + NULL); + + if (!msg->StartupEvent) + return FALSE; + + Thread = CreateThread( + NULL, + 0, + StartupWindowThread, + (PVOID)msg, + 0, + &ThreadId); + if (Thread) + { + CloseHandle(Thread); + WaitForSingleObject(msg->StartupEvent, INFINITE); + CloseHandle(msg->StartupEvent); + return TRUE; + } + + return FALSE; + } + + if(pTitle) + SetWindowText(pgContext->hStatusWindow, pTitle); + + SetDlgItemText(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage); + + return TRUE; +} + +static VOID +GUIDisplaySASNotice( + IN OUT PGINA_CONTEXT pgContext) +{ + int result; + + TRACE("GUIDisplaySASNotice()\n"); + + /* Display the notice window */ + result = pgContext->pWlxFuncs->WlxDialogBoxParam( + pgContext->hWlx, + pgContext->hDllInstance, + MAKEINTRESOURCE(IDD_NOTICE_DLG), + NULL, + (DLGPROC)DefWindowProc, + (LPARAM)NULL); + if (result == -1) + { + /* Failed to display the window. Do as if the user + * already has pressed CTRL+ALT+DELETE */ + pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + } +} + +/* Get the text contained in a textbox. Allocates memory in pText + * to contain the text. Returns TRUE in case of success */ +static BOOL +GetTextboxText( + IN HWND hwndDlg, + IN INT TextboxId, + OUT LPWSTR *pText) +{ + LPWSTR Text; + int Count; + + Count = GetWindowTextLength(GetDlgItem(hwndDlg, TextboxId)); + Text = HeapAlloc(GetProcessHeap(), 0, (Count + 1) * sizeof(WCHAR)); + if (!Text) + return FALSE; + if (Count != GetWindowText(GetDlgItem(hwndDlg, TextboxId), Text, Count + 1)) + { + HeapFree(GetProcessHeap(), 0, Text); + return FALSE; + } + *pText = Text; + return TRUE; +} + +static INT_PTR CALLBACK +LoggedOutWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + /* FIXME: take care of DontDisplayLastUserName, NoDomainUI, ShutdownWithoutLogon */ + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)lParam); + SetFocus(GetDlgItem(hwndDlg, IDC_USERNAME)); + break; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + PGINA_CONTEXT pgContext; + LPWSTR UserName = NULL, Password = NULL; + INT result = WLX_SAS_ACTION_NONE; + pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA); + + if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0') + break; + if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) && + DoLoginTasks(pgContext, UserName, NULL, Password)) + { + result = WLX_SAS_ACTION_LOGON; + } + HeapFree(GetProcessHeap(), 0, UserName); + HeapFree(GetProcessHeap(), 0, Password); + EndDialog(hwndDlg, result); + return TRUE; + } + case IDCANCEL: + { + EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); + return TRUE; + } + case IDC_SHUTDOWN: + { + EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN); + return TRUE; + } + } + break; + } + } + + return DefWindowProc(hwndDlg, uMsg, wParam, lParam); +} + +static INT_PTR CALLBACK +LoggedOnWindowProc( + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + switch (uMsg) + { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDYES: + case IDNO: + { + EndDialog(hwndDlg, LOWORD(wParam)); + break; + } + } + return TRUE; + } + case WM_INITDIALOG: + { + SetFocus(GetDlgItem(hwndDlg, IDNO)); + break; + } + case WM_CLOSE: + { + EndDialog(hwndDlg, IDNO); + return TRUE; + } + } + + return DefWindowProc(hwndDlg, uMsg, wParam, lParam); +} + +static INT +GUILoggedOnSAS( + IN OUT PGINA_CONTEXT pgContext, + IN DWORD dwSasType) +{ + INT SasAction = WLX_SAS_ACTION_NONE; + + TRACE("GUILoggedOnSAS()\n"); + + switch (dwSasType) + { + case WLX_SAS_TYPE_CTRL_ALT_DEL: + { + INT result; + /* Display "Are you sure you want to log off?" dialog */ + result = pgContext->pWlxFuncs->WlxDialogBoxParam( + pgContext->hWlx, + pgContext->hDllInstance, + MAKEINTRESOURCE(IDD_LOGGEDON_DLG), + NULL, + LoggedOnWindowProc, + (LPARAM)pgContext); + if (result == IDOK) + SasAction = WLX_SAS_ACTION_LOCK_WKSTA; + break; + } + case WLX_SAS_TYPE_SC_INSERT: + { + FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n"); + break; + } + case WLX_SAS_TYPE_SC_REMOVE: + { + FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n"); + break; + } + case WLX_SAS_TYPE_TIMEOUT: + { + FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n"); + break; + } + default: + { + WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType); + break; + } + } + + return SasAction; +} + +static INT +GUILoggedOutSAS( + IN OUT PGINA_CONTEXT pgContext) +{ + int result; + + TRACE("GUILoggedOutSAS()\n"); + + result = pgContext->pWlxFuncs->WlxDialogBoxParam( + pgContext->hWlx, + pgContext->hDllInstance, + MAKEINTRESOURCE(IDD_LOGGEDOUT_DLG), + NULL, + LoggedOutWindowProc, + (LPARAM)pgContext); + if (result >= WLX_SAS_ACTION_LOGON && + result <= WLX_SAS_ACTION_SWITCH_CONSOLE) + { + WARN("WlxLoggedOutSAS() returns 0x%x\n", result); + return result; + } + + WARN("WlxDialogBoxParam() failed (0x%x)\n", result); + return WLX_SAS_ACTION_NONE; +} + +GINA_UI GinaGraphicalUI = { + GUIInitialize, + GUIDisplayStatusMessage, + GUIDisplaySASNotice, + GUILoggedOnSAS, + GUILoggedOutSAS, +}; diff --git a/reactos/dll/win32/msgina/msgina.c b/reactos/dll/win32/msgina/msgina.c index 3659e529a1a..2af0bfb2e7b 100644 --- a/reactos/dll/win32/msgina/msgina.c +++ b/reactos/dll/win32/msgina/msgina.c @@ -1,6 +1,6 @@ /* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * ReactOS GINA + * Copyright (C) 2003-2004, 2006 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,88 +16,78 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * +/* * PROJECT: ReactOS msgina.dll - * FILE: lib/msgina/msgina.c + * FILE: dll/win32/msgina/msgina.c * PURPOSE: ReactOS Logon GINA DLL * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) - * UPDATE HISTORY: - * 24-11-2003 Created + * Hervé Poussineau (hpoussin@reactos.org) */ -#include -#include + #include "msgina.h" -#include "resource.h" #include extern HINSTANCE hDllInstance; -typedef struct _DISPLAYSTATUSMSG -{ - PGINA_CONTEXT Context; - HDESK hDesktop; - DWORD dwOptions; - PWSTR pTitle; - PWSTR pMessage; - HANDLE StartupEvent; -} DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG; - -INT_PTR CALLBACK -LoggedOnDlgProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) -{ - switch(uMsg) - { - case WM_COMMAND: - { - switch(LOWORD(wParam)) - { - case IDYES: - case IDNO: - { - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - } - return FALSE; - } - case WM_INITDIALOG: - { - SetFocus(GetDlgItem(hwndDlg, IDNO)); - break; - } - case WM_CLOSE: - { - EndDialog(hwndDlg, IDNO); - return TRUE; - } - } - return FALSE; -} - +extern GINA_UI GinaGraphicalUI; +extern GINA_UI GinaTextUI; +static PGINA_UI pGinaUI = &GinaGraphicalUI; /* Default value */ /* * @implemented */ BOOL WINAPI WlxNegotiate( - DWORD dwWinlogonVersion, - PDWORD pdwDllVersion) + IN DWORD dwWinlogonVersion, + OUT PDWORD pdwDllVersion) { - if(!pdwDllVersion || (dwWinlogonVersion < GINA_VERSION)) - return FALSE; - - *pdwDllVersion = GINA_VERSION; - - return TRUE; + DPRINT1("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion, pdwDllVersion); + + if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3)) + return FALSE; + + *pdwDllVersion = WLX_VERSION_1_3; + + return TRUE; } +static BOOL +ChooseGinaUI(VOID) +{ + HKEY WinLogonKey = NULL; + DWORD Type, Size, Value; + LONG rc; + + rc = RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon", + 0, + KEY_QUERY_VALUE, + &WinLogonKey); + if (rc != ERROR_SUCCESS) + goto cleanup; + + Size = sizeof(DWORD); + rc = RegQueryValueEx( + WinLogonKey, + L"StartGUI", + NULL, + &Type, + (LPBYTE)&Value, + &Size); + if (rc != ERROR_SUCCESS || Type != REG_DWORD || Size != sizeof(DWORD)) + goto cleanup; + + if (Value != 0) + pGinaUI = &GinaGraphicalUI; + else + pGinaUI = &GinaTextUI; + +cleanup: + if (WinLogonKey != NULL) + RegCloseKey(WinLogonKey); +} /* * @implemented @@ -122,7 +112,7 @@ WlxInitialize( pgContext->hDllInstance = hDllInstance; /* save pointer to dispatch table */ - pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION)pWinlogonFunctions; + pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions; /* save the winlogon handle used to call the dispatch functions */ pgContext->hWlx = hWlx; @@ -136,7 +126,13 @@ WlxInitialize( /* notify winlogon that we will use the default SAS */ pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx); - return TRUE; + /* Locates the authentification package */ + //LsaRegisterLogonProcess(...); + + pgContext->DoAutoLogonOnce = FALSE; + + ChooseGinaUI(); + return pGinaUI->Initialize(pgContext); } @@ -193,13 +189,14 @@ WlxActivateUserShell( PVOID pEnvironment) { PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - STARTUPINFO si; - PROCESS_INFORMATION pi; + STARTUPINFO StartupInfo; + PROCESS_INFORMATION ProcessInformation; HKEY hKey; DWORD BufSize, ValueType; WCHAR pszUserInitApp[MAX_PATH]; WCHAR pszExpUserInitApp[MAX_PATH]; BOOL Ret; + WCHAR CurrentDirectory[MAX_PATH]; /* get the path of userinit */ if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, @@ -222,31 +219,34 @@ WlxActivateUserShell( /* start userinit */ /* FIXME - allow to start more applications that are comma-separated */ - si.cb = sizeof(STARTUPINFO); - si.lpReserved = NULL; - si.lpTitle = L"userinit"; - si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0; - si.dwFlags = 0; - si.wShowWindow = SW_SHOW; - si.lpReserved2 = NULL; - si.cbReserved2 = 0; - si.lpDesktop = pszDesktopName; + StartupInfo.cb = sizeof(STARTUPINFO); + StartupInfo.lpReserved = NULL; + StartupInfo.lpDesktop = pszDesktopName; + StartupInfo.lpTitle = NULL; + StartupInfo.dwFlags = 0; + StartupInfo.lpReserved2 = NULL; + StartupInfo.cbReserved2 = 0; + StartupInfo.dwX = StartupInfo.dwY = StartupInfo.dwXSize = StartupInfo.dwYSize = 0; + StartupInfo.wShowWindow = SW_SHOW; ExpandEnvironmentStrings(pszUserInitApp, pszExpUserInitApp, MAX_PATH); + GetWindowsDirectoryW (CurrentDirectory, MAX_PATH); Ret = CreateProcessAsUser(pgContext->UserToken, - pszExpUserInitApp, NULL, + pszExpUserInitApp, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, pEnvironment, - NULL, - &si, - &pi); - if(!Ret) ERR("GINA: Failed: 3\n"); + CurrentDirectory, + &StartupInfo, + &ProcessInformation); + if(!Ret) ERR("GINA: Failed: 3, error %lu\n", GetLastError()); VirtualFree(pEnvironment, 0, MEM_RELEASE); + Ret = pgContext->pWlxFuncs->WlxSwitchDesktopToUser(pgContext->hWlx); + if(!Ret) ERR("GINA: Failed: 4, error %lu\n", GetLastError()); return Ret; } @@ -260,303 +260,295 @@ WlxLoggedOnSAS( DWORD dwSasType, PVOID pReserved) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - int SasAction = WLX_SAS_ACTION_NONE; - - switch(dwSasType) - { - case WLX_SAS_TYPE_CTRL_ALT_DEL: - { - int Result; - /* display "Are you sure you want to log off?" dialog */ - Result = pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx, - pgContext->hDllInstance, - (LPTSTR)IDD_LOGOFF_DLG, - NULL, - LoggedOnDlgProc, - (LPARAM)pgContext); - if(Result == IDOK) - { - SasAction = WLX_SAS_ACTION_LOCK_WKSTA; - } - break; - } - case WLX_SAS_TYPE_SC_INSERT: - { - FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n"); - break; - } - case WLX_SAS_TYPE_SC_REMOVE: - { - FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n"); - break; - } - case WLX_SAS_TYPE_TIMEOUT: - { - FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n"); - break; - } - default: - { - WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType); - break; - } - } - - return SasAction; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + + DPRINT1("WlxLoggedOnSAS(0x%lx)\n", dwSasType); + + return pGinaUI->LoggedOnSAS(pgContext, dwSasType); } - -BOOL -CALLBACK -StatusMessageWindowProc( - HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam -) -{ - switch(uMsg) - { - case WM_INITDIALOG: - { - PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam; - if(!msg) - return FALSE; - - msg->Context->hStatusWindow = hwndDlg; - - if(msg->pTitle) - SetWindowText(hwndDlg, msg->pTitle); - SetDlgItemText(hwndDlg, IDC_STATUSLABEL, msg->pMessage); - if(!msg->Context->SignaledStatusWindowCreated) - { - msg->Context->SignaledStatusWindowCreated = TRUE; - SetEvent(msg->StartupEvent); - } - break; - } - } - return FALSE; -} - - -DWORD WINAPI -StartupWindowThread(LPVOID lpParam) -{ - HDESK OldDesk; - PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam; - - OldDesk = GetThreadDesktop(GetCurrentThreadId()); - - if(!SetThreadDesktop(msg->hDesktop)) - { - HeapFree(GetProcessHeap(), 0, lpParam); - return FALSE; - } - DialogBoxParam(hDllInstance, - MAKEINTRESOURCE(IDD_STATUSWINDOW), - 0, - StatusMessageWindowProc, - (LPARAM)lpParam); - SetThreadDesktop(OldDesk); - - msg->Context->hStatusWindow = 0; - msg->Context->SignaledStatusWindowCreated = FALSE; - - HeapFree(GetProcessHeap(), 0, lpParam); - return TRUE; -} - - /* * @implemented */ BOOL WINAPI WlxDisplayStatusMessage( - PVOID pWlxContext, - HDESK hDesktop, - DWORD dwOptions, - PWSTR pTitle, - PWSTR pMessage) + IN PVOID pWlxContext, + IN HDESK hDesktop, + IN DWORD dwOptions, + IN PWSTR pTitle, + IN PWSTR pMessage) { - PDISPLAYSTATUSMSG msg; - HANDLE Thread; - DWORD ThreadId; - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - - if(!pgContext->hStatusWindow) - { - msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG)); - if(!msg) - return FALSE; - - msg->Context = pgContext; - msg->dwOptions = dwOptions; - msg->pTitle = pTitle; - msg->pMessage = pMessage; - msg->hDesktop = hDesktop; - - msg->StartupEvent = CreateEvent(NULL, - TRUE, - FALSE, - NULL); - - if(!msg->StartupEvent) - return FALSE; - - Thread = CreateThread(NULL, - 0, - StartupWindowThread, - (PVOID)msg, - 0, - &ThreadId); - if(Thread) - { - CloseHandle(Thread); - WaitForSingleObject(msg->StartupEvent, INFINITE); - CloseHandle(msg->StartupEvent); - return TRUE; - } - - return FALSE; - } - - if(pTitle) - SetWindowText(pgContext->hStatusWindow, pTitle); - - SetDlgItemText(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage); - - return TRUE; -} + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + DPRINT1("WlxDisplayStatusMessage(\"%S\")\n", pMessage); + + return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage); +} /* * @implemented */ BOOL WINAPI WlxRemoveStatusMessage( - PVOID pWlxContext) + IN PVOID pWlxContext) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - if(pgContext->hStatusWindow) - { - EndDialog(pgContext->hStatusWindow, 0); - pgContext->hStatusWindow = 0; - } - - return TRUE; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + if (pgContext->hStatusWindow) + { + EndDialog(pgContext->hStatusWindow, 0); + pgContext->hStatusWindow = 0; + } + + return TRUE; } +static LONG +ReadRegSzKey( + IN HKEY hKey, + IN LPCWSTR pszKey, + OUT LPWSTR* pValue) +{ + LONG rc; + DWORD dwType; + DWORD cbData = 0; + LPWSTR Value; + + rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); + if (rc != ERROR_SUCCESS) + return rc; + if (dwType != REG_SZ) + return ERROR_FILE_NOT_FOUND; + Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); + if (!Value) + return ERROR_NOT_ENOUGH_MEMORY; + rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); + if (rc != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, Value); + return rc; + } + /* NULL-terminate the string */ + Value[cbData / sizeof(WCHAR)] = '\0'; + + *pValue = Value; + return ERROR_SUCCESS; +} + +static PWSTR +DuplicationString(PWSTR Str) +{ + DWORD cb; + PWSTR NewStr; + + if (Str == NULL) return NULL; + + cb = (wcslen(Str) + 1) * sizeof(WCHAR); + if ((NewStr = LocalAlloc(LMEM_FIXED, cb))) + memcpy(NewStr, Str, cb); + return NewStr; +} + +BOOL +DoLoginTasks( + IN OUT PGINA_CONTEXT pgContext, + IN PWSTR UserName, + IN PWSTR Domain, + IN PWSTR Password) +{ + TOKEN_STATISTICS Stats; + DWORD cbStats; + + if(!LogonUserW(UserName, Domain, Password, + LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */ + LOGON32_PROVIDER_DEFAULT, + pgContext->phToken)) + { + WARN("GINA: Logonuser() failed\n"); + return FALSE; + } + + if(!(*pgContext->phToken)) + { + WARN("GINA: *phToken == NULL!\n"); + return FALSE; + } + + pgContext->UserToken =*pgContext->phToken; + + *pgContext->pdwOptions = 0; + *pgContext->pProfile =NULL; + + if(!GetTokenInformation(*pgContext->phToken, + TokenStatistics, + (PVOID)&Stats, + sizeof(TOKEN_STATISTICS), + &cbStats)) + { + WARN("GINA: Couldn't get Authentication id from user token!\n"); + return FALSE; + } + *pgContext->pAuthenticationId = Stats.AuthenticationId; + pgContext->pNprNotifyInfo->pszUserName = DuplicationString(UserName); + pgContext->pNprNotifyInfo->pszDomain = DuplicationString(Domain); + pgContext->pNprNotifyInfo->pszPassword = DuplicationString(Password); + pgContext->pNprNotifyInfo->pszOldPassword = NULL; + return TRUE; +} + +static BOOL +DoAutoLogon( + IN PGINA_CONTEXT pgContext, + IN BOOL CheckOnly) +{ + HKEY WinLogonKey = NULL; + LPWSTR AutoLogon = NULL; + LPWSTR AutoCount = NULL; + LPWSTR IgnoreShiftOverride = NULL; + LPWSTR UserName = NULL; + LPWSTR DomainName = NULL; + LPWSTR Password = NULL; + BOOL result = FALSE; + LONG rc; + + rc = RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon", + 0, + KEY_QUERY_VALUE, + &WinLogonKey); + if (rc != ERROR_SUCCESS) + goto cleanup; + + rc = ReadRegSzKey(WinLogonKey, L"AutoAdminLogon", &AutoLogon); + if (rc != ERROR_SUCCESS) + goto cleanup; + if (wcscmp(AutoLogon, L"1") != 0) + goto cleanup; + + rc = ReadRegSzKey(WinLogonKey, L"AutoLogonCount", &AutoCount); + if (rc == ERROR_SUCCESS && wcscmp(AutoCount, L"0") == 0) + goto cleanup; + else if (rc != ERROR_FILE_NOT_FOUND) + goto cleanup; + + rc = ReadRegSzKey(WinLogonKey, L"IgnoreShiftOverride", &UserName); + if (rc == ERROR_SUCCESS) + { + if (wcscmp(AutoLogon, L"1") != 0 && GetKeyState(VK_SHIFT) < 0) + goto cleanup; + } + else if (GetKeyState(VK_SHIFT) < 0) + { + /* User pressed SHIFT */ + goto cleanup; + } + + if (CheckOnly) + { + result = TRUE; + goto cleanup; + } + + rc = ReadRegSzKey(WinLogonKey, L"DefaultUserName", &UserName); + if (rc != ERROR_SUCCESS) + goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"DefaultDomainName", &DomainName); + if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) + goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"DefaultPassword", &Password); + if (rc != ERROR_SUCCESS) + goto cleanup; + + result = DoLoginTasks(pgContext, UserName, DomainName, Password); + +cleanup: + if (WinLogonKey != NULL) + RegCloseKey(WinLogonKey); + HeapFree(GetProcessHeap(), 0, AutoLogon); + HeapFree(GetProcessHeap(), 0, AutoCount); + HeapFree(GetProcessHeap(), 0, IgnoreShiftOverride); + HeapFree(GetProcessHeap(), 0, UserName); + HeapFree(GetProcessHeap(), 0, DomainName); + HeapFree(GetProcessHeap(), 0, Password); + return result; +} /* * @implemented */ VOID WINAPI WlxDisplaySASNotice( - PVOID pWlxContext) + IN PVOID pWlxContext) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + + DPRINT1("WlxDisplaySASNotice(%p)\n", pWlxContext); + + if (GetSystemMetrics(SM_REMOTESESSION)) + { + /* User is remotely logged on. Don't display a notice */ + pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + return; + } + + if (DoAutoLogon(NULL, TRUE)) + { + /* Don't display the window, we want to do an automatic logon */ + pgContext->DoAutoLogonOnce = TRUE; + pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + return; + } + + pGinaUI->DisplaySASNotice(pgContext); + + DPRINT1("WlxDisplaySASNotice() done\n"); } - -static PWSTR -DuplicationString(PWSTR Str) -{ - DWORD cb; - PWSTR NewStr; - - cb = (wcslen(Str) + 1) * sizeof(WCHAR); - if((NewStr = LocalAlloc(LMEM_FIXED, cb))) - { - memcpy(NewStr, Str, cb); - } - return NewStr; -} - - /* - * @unimplemented + * @implemented */ -int WINAPI +INT WINAPI WlxLoggedOutSAS( - PVOID pWlxContext, - DWORD dwSasType, - PLUID pAuthenticationId, - PSID pLogonSid, - PDWORD pdwOptions, - PHANDLE phToken, - PWLX_MPR_NOTIFY_INFO pNprNotifyInfo, - PVOID *pProfile) + IN PVOID pWlxContext, + IN DWORD dwSasType, + OUT PLUID pAuthenticationId, + IN OUT PSID pLogonSid, + OUT PDWORD pdwOptions, + OUT PHANDLE phToken, + OUT PWLX_MPR_NOTIFY_INFO pNprNotifyInfo, + OUT PVOID *pProfile) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - TOKEN_STATISTICS Stats; - DWORD cbStats; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - if(!phToken) - { - WARN("msgina: phToken == NULL!\n"); - return WLX_SAS_ACTION_NONE; - } + DPRINT1("WlxLoggedOutSAS()\n"); - if(!LogonUser(L"Administrator", NULL, L"Secrect", - LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */ - LOGON32_PROVIDER_DEFAULT, - phToken)) - { - WARN("msgina: Logonuser() failed\n"); - return WLX_SAS_ACTION_NONE; - } - - if(!(*phToken)) - { - WARN("msgina: *phToken == NULL!\n"); - return WLX_SAS_ACTION_NONE; - } + pgContext->pAuthenticationId = pAuthenticationId; + pgContext->pdwOptions = pdwOptions; + pgContext->phToken = phToken; + pgContext->pNprNotifyInfo = pNprNotifyInfo; + pgContext->pProfile = pProfile; - pgContext->UserToken =*phToken; - - *pdwOptions = 0; - *pProfile =NULL; - - if(!GetTokenInformation(*phToken, - TokenStatistics, - (PVOID)&Stats, - sizeof(TOKEN_STATISTICS), - &cbStats)) - { - WARN("msgina: Couldn't get Autentication id from user token!\n"); - return WLX_SAS_ACTION_NONE; - } - *pAuthenticationId = Stats.AuthenticationId; - pNprNotifyInfo->pszUserName = DuplicationString(L"Administrator"); - pNprNotifyInfo->pszDomain = NULL; - pNprNotifyInfo->pszPassword = DuplicationString(L"Secret"); - pNprNotifyInfo->pszOldPassword = NULL; + if (!GetSystemMetrics(SM_REMOTESESSION) && + pgContext->DoAutoLogonOnce && + DoAutoLogon(pgContext, FALSE)) + { + /* User is local and registry contains information + * to log on him automatically */ + pgContext->DoAutoLogonOnce = FALSE; + return WLX_SAS_ACTION_LOGON; + } - return WLX_SAS_ACTION_LOGON; + return pGinaUI->LoggedOutSAS(pgContext); } - -BOOL STDCALL +BOOL WINAPI DllMain( - HINSTANCE hinstDLL, - DWORD dwReason, - LPVOID lpvReserved) + IN HINSTANCE hinstDLL, + IN DWORD dwReason, + IN LPVOID lpvReserved) { - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - /* fall through */ - case DLL_THREAD_ATTACH: - hDllInstance = hinstDLL; - break; - case DLL_THREAD_DETACH: - break; - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} + if (dwReason == DLL_PROCESS_ATTACH) + hDllInstance = hinstDLL; + return TRUE; +} diff --git a/reactos/dll/win32/msgina/msgina.h b/reactos/dll/win32/msgina/msgina.h index 71046d8b1ef..0b4b6575a72 100644 --- a/reactos/dll/win32/msgina/msgina.h +++ b/reactos/dll/win32/msgina/msgina.h @@ -1,22 +1,53 @@ #ifndef __MSGINA_H #define __MSGINA_H -#define GINA_VERSION (WLX_VERSION_1_3) - -#define PWLX_DISPATCH_VERSION PWLX_DISPATCH_VERSION_1_3 +#include +#include +#include "resource.h" typedef struct { - HANDLE hWlx; - LPWSTR station; - PWLX_DISPATCH_VERSION pWlxFuncs; - HANDLE hDllInstance; - HANDLE UserToken; - HWND hStatusWindow; - BOOL SignaledStatusWindowCreated; + HANDLE hWlx; + LPWSTR station; + PWLX_DISPATCH_VERSION_1_3 pWlxFuncs; + HANDLE hDllInstance; + HANDLE UserToken; + HWND hStatusWindow; + BOOL SignaledStatusWindowCreated; + BOOL DoAutoLogonOnce; + + /* Informations to be filled during logon */ + PLUID pAuthenticationId; + PDWORD pdwOptions; + PHANDLE phToken; + PWLX_MPR_NOTIFY_INFO pNprNotifyInfo; + PVOID *pProfile; } GINA_CONTEXT, *PGINA_CONTEXT; HINSTANCE hDllInstance; +typedef BOOL (*PFGINA_INITIALIZE)(PGINA_CONTEXT); +typedef BOOL (*PFGINA_DISPLAYSTATUSMESSAGE)(PGINA_CONTEXT, HDESK, DWORD, PWSTR, PWSTR); +typedef VOID (*PFGINA_DISPLAYSASNOTICE)(PGINA_CONTEXT); +typedef INT (*PFGINA_LOGGEDONSAS)(PGINA_CONTEXT, DWORD); +typedef INT (*PFGINA_LOGGEDOUTSAS)(PGINA_CONTEXT); +typedef struct _GINA_UI +{ + PFGINA_INITIALIZE Initialize; + PFGINA_DISPLAYSTATUSMESSAGE DisplayStatusMessage; + PFGINA_DISPLAYSASNOTICE DisplaySASNotice; + PFGINA_LOGGEDONSAS LoggedOnSAS; + PFGINA_LOGGEDOUTSAS LoggedOutSAS; +} GINA_UI, *PGINA_UI; + +/* msgina.c */ + +BOOL +DoLoginTasks( + IN OUT PGINA_CONTEXT pgContext, + IN PWSTR UserName, + IN PWSTR Domain, + IN PWSTR Password); + #endif /* __MSGINA_H */ /* EOF */ diff --git a/reactos/dll/win32/msgina/msgina.rbuild b/reactos/dll/win32/msgina/msgina.rbuild index 25eddd2315f..cc68c806dee 100644 --- a/reactos/dll/win32/msgina/msgina.rbuild +++ b/reactos/dll/win32/msgina/msgina.rbuild @@ -10,7 +10,9 @@ kernel32 advapi32 user32 + gui.c msgina.c stubs.c + tui.c msgina.rc diff --git a/reactos/dll/win32/msgina/msgina.rc b/reactos/dll/win32/msgina/msgina.rc index 82dc894b147..b00b1811e58 100644 --- a/reactos/dll/win32/msgina/msgina.rc +++ b/reactos/dll/win32/msgina/msgina.rc @@ -9,26 +9,51 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDI_LOGOFFICON ICON "resources/ico_logoff.ico" - -IDD_LOGOFF_DLG DIALOG 0, 0, 188, 60 -STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Log Off ReactOS" -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -FONT 8, "MS Shell Dlg" -{ - ICON IDI_LOGOFFICON, IDC_LOGOFFICON, 7, 7, 21, 21, SS_ICON | WS_CHILD | WS_VISIBLE - LTEXT "Are you sure you want to log off?", -1, 35, 16, 146, 8, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP - PUSHBUTTON "&Log Off", 1, 41, 39, 50, 14, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP - PUSHBUTTON "&No", 2, 95, 39, 50, 14, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP -} - -IDD_STATUSWINDOW DIALOG 0, 0, 274, 26 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Please wait..." -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -FONT 8, "MS Shell Dlg" -{ - LTEXT "", IDC_STATUSLABEL, 7, 8, 234, 12, SS_ENDELLIPSIS -} +FONT 8,"MS Shell Dlg 2",400,0,1 +BEGIN + LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS +END + +IDD_NOTICE_DLG DIALOGEX 0,0,186,59 +STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP +CAPTION "Welcome to ReactOS" +FONT 8,"MS Shell Dlg 2",400,0,1 +BEGIN + LTEXT "Press Control-Alt-Delete key combination",IDC_STATIC,16,18,144,14 +END + +IDD_LOGGEDOUT_DLG DIALOGEX 0,0,245,77 +STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP +CAPTION "Logon" +FONT 8,"MS Shell Dlg 2",400,0,1 +BEGIN + PUSHBUTTON "OK",IDOK,31,52,50,14,BS_DEFPUSHBUTTON + PUSHBUTTON "Cancel",IDCANCEL,95,52,50,14 + PUSHBUTTON "Shutdown",IDC_SHUTDOWN,159,52,50,14 + LTEXT "User name:",IDC_STATIC,16,15,40,8 + LTEXT "Password:",IDC_STATIC,16,33,42,8 + EDITTEXT IDC_USERNAME,64,12,169,14,ES_AUTOHSCROLL + EDITTEXT IDC_PASSWORD,64,31,169,14,ES_AUTOHSCROLL | ES_PASSWORD +END + +IDD_LOGGEDON_DLG DIALOGEX 0,0,186,52 +STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU +CAPTION "Security" +FONT 8,"MS Shell Dlg 2",400,0,1 +BEGIN + PUSHBUTTON "Cancel",IDCANCEL,125,31,50,14 + PUSHBUTTON "Log off",IDC_LOGOFF,11,31,50,14 + PUSHBUTTON "Shutdown",IDC_SHUTDOWN,69,31,50,14 + LTEXT "What do you want to do?",IDC_STATIC,50,18,87,8 +END + +STRINGTABLE +BEGIN + IDS_PRESSCTRLALTDELETE "Press CONTROL+ALT+DELETE key combination\n" + IDS_ASKFORUSER "User name: " + IDS_ASKFORPASSWORD "Password: " +END diff --git a/reactos/dll/win32/msgina/resource.h b/reactos/dll/win32/msgina/resource.h index 7c7f0b0db8a..558e29116e3 100644 --- a/reactos/dll/win32/msgina/resource.h +++ b/reactos/dll/win32/msgina/resource.h @@ -1,13 +1,19 @@ #ifndef __MSGINA_RESOURCE_H #define __MSGINA_RESOURCE_H -#define IDD_LOGOFF_DLG 2250 -#define IDD_STATUSWINDOW 2450 - -#define IDC_LOGOFFICON 21 -#define IDC_STATUSLABEL 2451 - -#define IDI_LOGOFFICON 2251 +#define IDC_STATIC -1 +#define IDD_STATUSWINDOW_DLG 100 +#define IDD_NOTICE_DLG 101 +#define IDD_LOGGEDON_DLG 102 +#define IDD_LOGGEDOUT_DLG 103 +#define IDC_LOGOFF 1001 +#define IDC_USERNAME 1002 +#define IDC_PASSWORD 1003 +#define IDC_SHUTDOWN 1004 +#define IDC_STATUSLABEL 1005 +#define IDS_ASKFORUSER 40000 +#define IDS_PRESSCTRLALTDELETE 40001 +#define IDS_ASKFORPASSWORD 40002 #endif /* __MSGINA_RESOURCE_H */ diff --git a/reactos/dll/win32/msgina/tui.c b/reactos/dll/win32/msgina/tui.c new file mode 100644 index 00000000000..d2cb15c2362 --- /dev/null +++ b/reactos/dll/win32/msgina/tui.c @@ -0,0 +1,148 @@ +/* + * PROJECT: ReactOS msgina.dll + * FILE: dll/win32/msgina/tui.c + * PURPOSE: ReactOS Logon GINA DLL + * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org) + */ + +#include "msgina.h" + +#include +#define TRACE DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint +#define FIXME DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint +#define WARN DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint +#undef DPRINT +#undef DPRINT1 + +static BOOL +TUIInitialize( + IN OUT PGINA_CONTEXT pgContext) +{ + TRACE("TUIInitialize(%p)\n", pgContext); + + return AllocConsole(); +} + +static BOOL +TUIDisplayStatusMessage( + IN PGINA_CONTEXT pgContext, + IN HDESK hDesktop, + IN DWORD dwOptions, + IN PWSTR pTitle, + IN PWSTR pMessage) +{ + static LPCWSTR newLine = L"\n"; + DWORD result; + + TRACE("TUIDisplayStatusMessage(%ws)\n", pMessage); + + return + WriteConsole( + GetStdHandle(STD_OUTPUT_HANDLE), + pMessage, + wcslen(pMessage), + &result, + NULL) && + WriteConsole( + GetStdHandle(STD_OUTPUT_HANDLE), + newLine, + wcslen(newLine), + &result, + NULL); +} + +static VOID +TUIDisplaySASNotice( + IN OUT PGINA_CONTEXT pgContext) +{ + WCHAR CtrlAltDelPrompt[256]; + DWORD count; + + TRACE("TUIDisplaySASNotice()\n"); + + if (LoadString(hDllInstance, IDS_PRESSCTRLALTDELETE, CtrlAltDelPrompt, 256)) + { + WriteConsole( + GetStdHandle(STD_OUTPUT_HANDLE), + CtrlAltDelPrompt, + wcslen(CtrlAltDelPrompt), + &count, + NULL); + } +} + +static INT +TUILoggedOnSAS( + IN OUT PGINA_CONTEXT pgContext, + IN DWORD dwSasType) +{ + TRACE("TUILoggedOnSAS()\n"); + for (;;) FIXME("FIXME!\n"); + return 0; +} + +static BOOL +ReadString( + IN PGINA_CONTEXT pgContext, + IN UINT uIdResourcePrompt, + IN OUT PWSTR Buffer, + IN DWORD BufferLength, + IN BOOL ShowString) +{ + WCHAR Prompt[256]; + DWORD count, i; + + if (!SetConsoleMode( + GetStdHandle(STD_INPUT_HANDLE), + ShowString ? ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT: ENABLE_LINE_INPUT)) + { + return FALSE; + } + + if (!LoadString(hDllInstance, uIdResourcePrompt, Prompt, 256)) + return FALSE; + + if (!WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), Prompt, wcslen(Prompt), &count, NULL)) + return FALSE; + + i = 0; + do + { + if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &Buffer[i], 1, &count, NULL)) + return FALSE; + i++; + /* FIXME: buffer overflow if the user writes too many chars! */ + /* FIXME: handle backspace */ + } while (Buffer[i - 1] != '\n'); + Buffer[i - 1] = 0; + return TRUE; +} + +static INT +TUILoggedOutSAS( + IN OUT PGINA_CONTEXT pgContext) +{ + WCHAR User[256]; + WCHAR Password[256]; + + TRACE("TUILoggedOutSAS()\n"); + + /* Ask the user for credentials */ + if (!ReadString(pgContext, IDS_ASKFORUSER, User, 256, TRUE)) + return WLX_SAS_ACTION_NONE; + if (!ReadString(pgContext, IDS_ASKFORPASSWORD, Password, 256, FALSE)) + return WLX_SAS_ACTION_NONE; + + if (DoLoginTasks(pgContext, User, NULL, Password)) + return WLX_SAS_ACTION_LOGON; + else + return WLX_SAS_ACTION_NONE; +} + +GINA_UI GinaTextUI = { + TUIInitialize, + TUIDisplayStatusMessage, + TUIDisplaySASNotice, + TUILoggedOnSAS, + TUILoggedOutSAS, +};