-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: services/winlogon/winlogon.c
+ * PROJECT: ReactOS Winlogon
+ * FILE: base/system/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 <debug.h>
+#include <wine/debug.h>
-#define SUPPORT_CONSOLESTART 1
-#define START_LSASS 1
+WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
/* 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;
-#if SUPPORT_CONSOLESTART
-BOOL StartConsole = TRUE;
-#endif
-
/* FUNCTIONS *****************************************************************/
-static void
-PrintString (WCHAR* fmt,...)
-{
- WCHAR buffer[512];
- va_list ap;
-
- va_start(ap, fmt);
- wsprintf(buffer, fmt, ap);
- va_end(ap);
-
- OutputDebugString(buffer);
-}
-
-
-INT_PTR CALLBACK
-ShutdownComputerProc (HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
+DWORD
+WINAPI
+PlayLogonSoundThread(
+ IN LPVOID lpParameter)
{
- 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;
+ HKEY hKey;
+ WCHAR szBuffer[MAX_PATH] = {0};
+ WCHAR szDest[MAX_PATH];
+ DWORD dwSize = sizeof(szBuffer);
+ HMODULE hLibrary;
+ SERVICE_STATUS_PROCESS Info;
+ typedef BOOL (WINAPI *PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
+ PLAYSOUNDW Play;
+ ULONG Index = 0;
+
+ if (RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+ {
+ ExitThread(0);
+ }
+
+ if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szBuffer, &dwSize) != ERROR_SUCCESS)
+ {
+ RegCloseKey(hKey);
+ ExitThread(0);
+ }
+
+
+ RegCloseKey(hKey);
+
+ if (!szBuffer[0])
+ ExitThread(0);
+
+
+ szBuffer[MAX_PATH-1] = L'\0';
+ if (ExpandEnvironmentStringsW(szBuffer, szDest, MAX_PATH))
+ {
+ SC_HANDLE hSCManager, hService;
+
+ hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+ if (!hSCManager)
+ ExitThread(0);;
+
+ hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
+ if (!hService)
+ {
+ CloseServiceHandle(hSCManager);
+ TRACE("WL: failed to open sysaudio Status %x\n", GetLastError());
+ ExitThread(0);
+ }
+
+ do
+ {
+ if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
+ {
+ TRACE("WL: QueryServiceStatusEx failed %x\n", GetLastError());
+ break;
+ }
+
+ if (Info.dwCurrentState == SERVICE_RUNNING)
+ break;
+
+ Sleep(1000);
+
+ }while(Index++ < 20);
+
+ CloseServiceHandle(hService);
+ CloseServiceHandle(hSCManager);
+
+ if (Info.dwCurrentState != SERVICE_RUNNING)
+ ExitThread(0);
+
+
+ hLibrary = LoadLibraryW(L"winmm.dll");
+ if (hLibrary)
+ {
+ Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
+ if (Play)
+ {
+ Play(szDest, NULL, SND_FILENAME);
+ }
+ FreeLibrary(hLibrary);
+ }
+ }
+ ExitThread(0);
}
-static BOOLEAN
-StartServices (VOID)
-{
- HANDLE ServicesInitEvent;
- BOOLEAN Result;
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
- DWORD Count;
- WCHAR ServiceString[] = L"services.exe";
-
- /* Start the service control manager (services.exe) */
-
- StartupInfo.cb = sizeof(StartupInfo);
- StartupInfo.lpReserved = NULL;
- StartupInfo.lpDesktop = NULL;
- StartupInfo.lpTitle = NULL;
- StartupInfo.dwFlags = 0;
- StartupInfo.cbReserved2 = 0;
- StartupInfo.lpReserved2 = 0;
-#if 0
- PrintString(L"WL: Creating new process - \"services.exe\".\n");
-#endif
-
- Result = CreateProcess(NULL,
- ServiceString,
- NULL,
- NULL,
- FALSE,
- DETACHED_PROCESS,
- NULL,
- NULL,
- &StartupInfo,
- &ProcessInformation);
- if (!Result)
- {
- PrintString(L"WL: Failed to execute services\n");
- return FALSE;
- }
-
- /* wait for event creation (by SCM) for max. 20 seconds */
- for (Count = 0; Count < 20; Count++)
- {
- Sleep(1000);
-
- //DbgPrint("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
- ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
- FALSE,
- L"SvcctrlStartEvent_A3725DX");
- if (ServicesInitEvent != NULL)
- {
- break;
- }
- }
-
- if (ServicesInitEvent == NULL)
- {
- DbgPrint("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
- return FALSE;
- }
-
- /* wait for event signalization */
- //DbgPrint("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
- WaitForSingleObject(ServicesInitEvent, INFINITE);
- //DbgPrint("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
- CloseHandle(ServicesInitEvent);
- //DbgPrint("WL: StartServices() Done.\n");
-
- return TRUE;
-}
-#if START_LSASS
-static BOOLEAN
-StartLsass (VOID)
+static BOOL
+StartServicesManager(VOID)
{
- HANDLE LsassInitEvent;
- BOOLEAN Result;
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
- WCHAR ServiceString[] = L"lsass.exe";
-
- LsassInitEvent = CreateEvent(NULL,
- TRUE,
- FALSE,
- L"\\SECURITY_SERVICES_STARTED");
-
- if (LsassInitEvent == NULL)
- {
- DbgPrint("WL: Failed to create lsass notification event\n");
- return(FALSE);
- }
-
- /* Start the local security authority subsystem (lsass.exe) */
-
- 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)
- {
- DbgPrint("WL: Failed to execute lsass\n");
- return(FALSE);
- }
-
- WaitForSingleObject(LsassInitEvent, INFINITE);
- CloseHandle(LsassInitEvent);
-
- return(TRUE);
+ STARTUPINFOW StartupInfo;
+ PROCESS_INFORMATION ProcessInformation;
+ LPCWSTR ServiceString = L"services.exe";
+ BOOL res;
+
+ /* Start the service control manager (services.exe) */
+ ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
+ StartupInfo.cb = sizeof(StartupInfo);
+ StartupInfo.lpReserved = NULL;
+ StartupInfo.lpDesktop = NULL;
+ StartupInfo.lpTitle = NULL;
+ StartupInfo.dwFlags = 0;
+ StartupInfo.cbReserved2 = 0;
+ StartupInfo.lpReserved2 = 0;
+
+ TRACE("WL: Creating new process - %S\n", ServiceString);
+
+ res = CreateProcessW(
+ ServiceString,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ DETACHED_PROCESS,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation);
+ if (!res)
+ {
+ ERR("WL: Failed to execute services (error %lu)\n", GetLastError());
+ return FALSE;
+ }
+
+ TRACE("WL: Created new process - %S\n", ServiceString);
+
+ CloseHandle(ProcessInformation.hThread);
+ CloseHandle(ProcessInformation.hProcess);
+
+ TRACE("WL: StartServicesManager() done.\n");
+
+ return TRUE;
}
-#endif
-static BOOLEAN
-OpenRegistryKey (HKEY *WinLogonKey)
+static BOOL
+StartLsass(VOID)
{
- return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
- 0,
- KEY_QUERY_VALUE,
- WinLogonKey);
+ STARTUPINFOW StartupInfo;
+ PROCESS_INFORMATION ProcessInformation;
+ LPCWSTR ServiceString = L"lsass.exe";
+ BOOL res;
+
+ /* Start the service control manager (services.exe) */
+ ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
+ StartupInfo.cb = sizeof(StartupInfo);
+ StartupInfo.lpReserved = NULL;
+ StartupInfo.lpDesktop = NULL;
+ StartupInfo.lpTitle = NULL;
+ StartupInfo.dwFlags = 0;
+ StartupInfo.cbReserved2 = 0;
+ StartupInfo.lpReserved2 = 0;
+
+ TRACE("WL: Creating new process - %S\n", ServiceString);
+
+ res = CreateProcessW(
+ ServiceString,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ DETACHED_PROCESS,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation);
+
+ TRACE("WL: Created new process - %S\n", ServiceString);
+
+ CloseHandle(ProcessInformation.hThread);
+ CloseHandle(ProcessInformation.hProcess);
+
+ return res;
}
-
-static BOOLEAN StartProcess(PWCHAR ValueName)
+BOOL
+DisplayStatusMessage(
+ IN PWLSESSION Session,
+ IN HDESK hDesktop,
+ IN UINT ResourceId)
{
- BOOL StartIt;
- HKEY WinLogonKey;
- DWORD Type;
- DWORD Size;
- DWORD StartValue;
-
- StartIt = TRUE;
- if (OpenRegistryKey(&WinLogonKey))
- {
- Size = sizeof(DWORD);
- if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
- ValueName,
- NULL,
- &Type,
- (LPBYTE) &StartValue,
- &Size))
- {
- if (REG_DWORD == Type)
- {
- StartIt = (0 != StartValue);
- }
- }
- RegCloseKey(WinLogonKey);
- }
-
- return StartIt;
-}
+ WCHAR StatusMsg[MAX_PATH];
-/*
-static BOOL RestartShell(void)
-{
- HKEY WinLogonKey;
- DWORD Type, Size, Value;
-
- if(OpenRegistryKey(&WinLogonKey))
- {
- Size = sizeof(DWORD);
- if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
- L"AutoRestartShell",
- NULL,
- &Type,
- (LPBYTE)&Value,
- &Size))
- {
- if(Type == REG_DWORD)
- {
- RegCloseKey(WinLogonKey);
- return (Value != 0);
- }
- }
- RegCloseKey(WinLogonKey);
- }
- return FALSE;
-}
-*/
+ if (Session->Gina.Version < WLX_VERSION_1_3)
+ return TRUE;
-VOID STDCALL
-RegisterHotKeys(VOID)
-{
- RegisterHotKey(NULL, 0, MOD_ALT | MOD_CONTROL, VK_DELETE);
-}
+ if (Session->SuppressStatus)
+ return TRUE;
-VOID STDCALL
-UnregisterHotKeys(VOID)
-{
- UnregisterHotKey(NULL, 0);
-}
+ if (LoadStringW(hAppInstance, ResourceId, StatusMsg, MAX_PATH) == 0)
+ return FALSE;
-VOID STDCALL
-HandleHotKey(MSG *Msg)
-{
- DbgPrint("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);
- }
+ return Session->Gina.Functions.WlxDisplayStatusMessage(Session->Gina.Context, hDesktop, 0, NULL, StatusMsg);
}
-#if SUPPORT_CONSOLESTART
-static BOOL StartIntoGUI(VOID)
+BOOL
+RemoveStatusMessage(
+ IN PWLSESSION Session)
{
- HKEY WinLogonKey;
- DWORD Type, Size, Value;
-
- if(OpenRegistryKey(&WinLogonKey))
- {
- Size = sizeof(DWORD);
- if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
- L"StartGUI",
- NULL,
- &Type,
- (LPBYTE)&Value,
- &Size))
- {
- if(Type == REG_DWORD)
- {
- RegCloseKey(WinLogonKey);
- return (Value != 0);
- }
- }
- RegCloseKey(WinLogonKey);
- }
- return FALSE;
-}
-
+ if (Session->Gina.Version < WLX_VERSION_1_3)
+ return TRUE;
-static PWCHAR
-GetUserInit (WCHAR *CommandLine)
-{
- HKEY WinLogonKey;
- BOOL GotCommandLine;
- DWORD Type;
- DWORD Size;
- WCHAR Shell[_MAX_PATH];
-
- GotCommandLine = FALSE;
- if (OpenRegistryKey(&WinLogonKey))
- {
- Size = MAX_PATH;
- if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
- L"UserInit",
- NULL,
- &Type,
- (LPBYTE) Shell,
- &Size))
- {
- if (REG_EXPAND_SZ == Type)
- {
- ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
- GotCommandLine = TRUE;
- }
- else if (REG_SZ == Type)
- {
- wcscpy(CommandLine, Shell);
- GotCommandLine = TRUE;
- }
- }
- RegCloseKey(WinLogonKey);
- }
-
- if (! GotCommandLine)
- {
- GetSystemDirectory(CommandLine, MAX_PATH - 15);
- wcscat(CommandLine, L"\\userinit.exe");
- }
-
- return CommandLine;
+ return Session->Gina.Functions.WlxRemoveStatusMessage(Session->Gina.Context);
}
-
-static BOOL
-DoLogonUser (PWCHAR Name,
- PWCHAR Password)
+static INT_PTR CALLBACK
+GinaLoadFailedWindowProc(
+ IN HWND hwndDlg,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
{
- PROCESS_INFORMATION ProcessInformation;
- STARTUPINFO StartupInfo;
- WCHAR CommandLine[MAX_PATH];
- WCHAR CurrentDirectory[MAX_PATH];
- PROFILEINFOW ProfileInfo;
- BOOL Result;
- LPVOID lpEnvironment = NULL;
- MSG Msg;
-
- Result = LogonUserW (Name,
- NULL,
- Password,
- LOGON32_LOGON_INTERACTIVE,
- LOGON32_PROVIDER_DEFAULT,
- &WLSession->UserToken);
- if (!Result)
- {
- DbgPrint ("WL: LogonUserW() failed\n");
- RtlDestroyEnvironment (lpEnvironment);
- return FALSE;
- }
-
- /* Load the user profile */
- ProfileInfo.dwSize = sizeof(PROFILEINFOW);
- ProfileInfo.dwFlags = 0;
- ProfileInfo.lpUserName = Name;
- ProfileInfo.lpProfilePath = NULL;
- ProfileInfo.lpDefaultPath = NULL;
- ProfileInfo.lpServerName = NULL;
- ProfileInfo.lpPolicyPath = NULL;
- ProfileInfo.hProfile = NULL;
-
- if (!LoadUserProfileW (WLSession->UserToken,
- &ProfileInfo))
- {
- DbgPrint ("WL: LoadUserProfileW() failed\n");
- CloseHandle (WLSession->UserToken);
- RtlDestroyEnvironment (lpEnvironment);
- return FALSE;
- }
-
- if (!CreateEnvironmentBlock (&lpEnvironment,
- WLSession->UserToken,
- TRUE))
- {
- DbgPrint ("WL: CreateEnvironmentBlock() failed\n");
- return FALSE;
- }
-
- if (ImpersonateLoggedOnUser(WLSession->UserToken))
- {
- UpdatePerUserSystemParameters(0, TRUE);
- RevertToSelf();
- }
-
- GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
-
- StartupInfo.cb = sizeof(StartupInfo);
- StartupInfo.lpReserved = NULL;
- StartupInfo.lpDesktop = NULL;
- StartupInfo.lpTitle = NULL;
- StartupInfo.dwFlags = 0;
- StartupInfo.cbReserved2 = 0;
- StartupInfo.lpReserved2 = 0;
-
- Result = CreateProcessAsUserW (WLSession->UserToken,
- NULL,
- GetUserInit (CommandLine),
- NULL,
- NULL,
- FALSE,
- CREATE_UNICODE_ENVIRONMENT,
- lpEnvironment,
- CurrentDirectory,
- &StartupInfo,
- &ProcessInformation);
- if (!Result)
- {
- DbgPrint ("WL: Failed to execute user shell %s\n", CommandLine);
- if (ImpersonateLoggedOnUser(WLSession->UserToken))
- {
- UpdatePerUserSystemParameters(0, FALSE);
- RevertToSelf();
- }
- UnloadUserProfile (WLSession->UserToken,
- ProfileInfo.hProfile);
- CloseHandle (WLSession->UserToken);
- DestroyEnvironmentBlock (lpEnvironment);
- return FALSE;
- }
-
- RegisterHotKeys();
-
- while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0)
- {
- if (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE))
- {
- if (Msg.message == WM_HOTKEY)
- HandleHotKey(&Msg);
- TranslateMessage(&Msg);
- DispatchMessage(&Msg);
- }
- }
-
- UnregisterHotKeys();
-
- CloseHandle (ProcessInformation.hProcess);
- CloseHandle (ProcessInformation.hThread);
-
- if (ImpersonateLoggedOnUser(WLSession->UserToken))
- {
- UpdatePerUserSystemParameters(0, FALSE);
- RevertToSelf();
- }
-
- /* Unload user profile */
- UnloadUserProfile (WLSession->UserToken,
- ProfileInfo.hProfile);
-
- CloseHandle (WLSession->UserToken);
-
- RtlDestroyEnvironment (lpEnvironment);
-
- return TRUE;
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ return TRUE;
+ }
+ break;
+ }
+ case WM_INITDIALOG:
+ {
+ int len;
+ WCHAR templateText[MAX_PATH], text[MAX_PATH];
+
+ len = GetDlgItemTextW(hwndDlg, IDC_GINALOADFAILED, templateText, MAX_PATH);
+ if (len)
+ {
+ wsprintfW(text, templateText, (LPWSTR)lParam);
+ SetDlgItemTextW(hwndDlg, IDC_GINALOADFAILED, text);
+ }
+ SetFocus(GetDlgItem(hwndDlg, IDOK));
+ return TRUE;
+ }
+ case WM_CLOSE:
+ {
+ EndDialog(hwndDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
-#endif
-int STDCALL
-WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nShowCmd)
+int WINAPI
+WinMain(
+ IN HINSTANCE hInstance,
+ IN HINSTANCE hPrevInstance,
+ IN LPSTR lpCmdLine,
+ IN int nShowCmd)
{
-#if SUPPORT_CONSOLESTART
-// WCHAR LoginName[255];
-// WCHAR Password[255];
-#endif
#if 0
- LSA_STRING ProcessName, PackageName;
- HANDLE LsaHandle;
- LSA_OPERATIONAL_MODE Mode;
- ULONG AuthenticationPackage;
+ LSA_STRING ProcessName, PackageName;
+ HANDLE LsaHandle;
+ LSA_OPERATIONAL_MODE Mode;
+ BOOLEAN Old;
+ ULONG AuthenticationPackage;
+ NTSTATUS Status;
#endif
+ ULONG HardErrorResponse;
+ MSG Msg;
+ HANDLE hThread;
+
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+ UNREFERENCED_PARAMETER(nShowCmd);
+
+ hAppInstance = hInstance;
+
+ if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
+ {
+ ERR("WL: Could not register logon process\n");
+ HandleShutdown(NULL, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
+ NtShutdownSystem(ShutdownNoReboot);
+ ExitProcess(0);
+ }
+
+ WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION));
+ if (!WLSession)
+ {
+ ERR("WL: Could not allocate memory for winlogon instance\n");
+ NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
+ ExitProcess(1);
+ }
+ ZeroMemory(WLSession, sizeof(WLSESSION));
+ WLSession->DialogTimeout = 120; /* 2 minutes */
+
+ if (!CreateWindowStationAndDesktops(WLSession))
+ {
+ ERR("WL: Could not create window station and desktops\n");
+ NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
+ ExitProcess(1);
+ }
+ LockWorkstation(WLSession);
+
+ if (!StartServicesManager())
+ {
+ ERR("WL: Could not start services.exe\n");
+ NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
+ ExitProcess(1);
+ }
- hAppInstance = hInstance;
-
- if(!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
- {
- DbgPrint("WL: Could not register logon process\n");
- NtShutdownSystem(ShutdownNoReboot);
- ExitProcess(0);
- return 0;
- }
-
-#if START_LSASS
- if (StartProcess(L"StartLsass"))
- {
if (!StartLsass())
- {
- DbgPrint("WL: Failed to start LSASS (0x%X)\n", GetLastError());
- }
- }
-#endif
-
- if(!(WLSession = MsGinaInit()))
- {
- DbgPrint("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))
- {
- DbgPrint("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 SUPPORT_CONSOLESTART
- StartConsole = !StartIntoGUI();
-#endif
- if(!InitializeSAS(WLSession))
- {
- DbgPrint("WL: Failed to initialize SAS\n");
- ExitProcess(2);
- return 2;
- }
+ {
+ ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
+ NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, OptionOk, &HardErrorResponse);
+ ExitProcess(1);
+ }
+
+ /* Load and initialize gina */
+ if (!GinaInit(WLSession))
+ {
+ ERR("WL: Failed to initialize Gina\n");
+ DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), GetDesktopWindow(), GinaLoadFailedWindowProc, (LPARAM)L"");
+ HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
+ ExitProcess(1);
+ }
+
+ DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
#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 */
- DbgPrint("WL: LsaRegisterLogonProcess() returned STATUS_PORT_CONNECTION_REFUSED\n");
- break;
- case STATUS_NAME_TOO_LONG:
- DbgPrint("WL: LsaRegisterLogonProcess() returned STATUS_NAME_TOO_LONG\n");
- break;
- default:
- DbgPrint("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);
- DbgPrint("WL: Failed to lookup authentication package\n");
- return(1);
- }
+ /* 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 */
+ Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status));
+ return 1;
+ }
+ 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
- /* FIXME: Create a window class and associate a Winlogon
- * window procedure with it.
- * Register SAS with the window.
- * Register for logoff notification
- */
-
- /* 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
-
-#if SUPPORT_CONSOLESTART
- if(StartConsole)
- {
-// if (! DoLogonUser(LoginName, Password))
- if (! DoLogonUser(L"Administrator", L"Secret"))
- {
- }
-
- NtShutdownSystem(ShutdownNoReboot);
- ExitProcess(0);
- }
- else
- {
-#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
- {
- DbgPrint("WL: LogonStatus != LOGON_SHUTDOWN!!!\n");
- ExitProcess(0);
- }
-#if SUPPORT_CONSOLESTART
- }
-#endif
-
- return 0;
-}
-
-BOOL
-DisplayStatusMessage(PWLSESSION Session, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage)
-{
- if(Session->SuppressStatus)
- {
- return TRUE;
- }
-
- #if SUPPORT_CONSOLESTART
- if(StartConsole)
- {
- if(pMessage)
- {
- DbgPrint("WL-Status: %ws\n", pMessage);
- }
- return TRUE;
- }
- #endif
-
- return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, dwOptions, pTitle, pMessage);
-}
-
-BOOL
-InitServices(void)
-{
- WCHAR StatusMsg[256];
-
- LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR));
- DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);
-
- /* start system processes (services.exe & lsass.exe) */
- if(StartProcess(L"StartServices"))
- {
- if(!StartServices())
- {
- DbgPrint("WL: Failed to start Services (0x%X)\n", GetLastError());
- }
- }
-
- return TRUE;
+ /* Create a hidden window to get SAS notifications */
+ if (!InitializeSAS(WLSession))
+ {
+ ERR("WL: Failed to initialize SAS\n");
+ ExitProcess(2);
+ }
+
+ //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
+ //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
+
+ /* Display logged out screen */
+ WLSession->LogonStatus = WKSTA_IS_LOGGED_OFF;
+ RemoveStatusMessage(WLSession);
+
+ /* Check for pending setup */
+ if (GetSetupType() != 0)
+ {
+ TRACE("WL: Setup mode detected\n");
+
+ /* Run setup and reboot when done */
+ SwitchDesktop(WLSession->ApplicationDesktop);
+ RunSetup();
+ }
+ else
+ PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_TIMEOUT, 0);
+
+ /* Play logon sound */
+ hThread = CreateThread(NULL, 0, PlayLogonSoundThread, NULL, 0, NULL);
+ if (hThread)
+ {
+ CloseHandle(hThread);
+ }
+
+ /* Tell kernel that CurrentControlSet is good (needed
+ * to support Last good known configuration boot) */
+ NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1);
+
+ /* Message loop for the SAS window */
+ while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0))
+ {
+ TranslateMessage(&Msg);
+ DispatchMessageW(&Msg);
+ }
+
+ /* We never go there */
+
+ return 0;
}
-
-DWORD
-DoLogin(PWLSESSION Session)
-{
- DWORD WlxAction, Options;
- WLX_MPR_NOTIFY_INFO MprNotifyInfo;
- PWLX_PROFILE_V2_0 Profile;
- PSID LogonSid = NULL;
- HANDLE Token;
-
- /* FIXME - Create a Logon Sid
- if(!(LogonSid = CreateUserLogonSid(NULL)))
- {
- return WLX_SAS_ACTION_NONE;
- }
- */
-
- Options = 0;
- WlxAction = Session->MsGina.Functions.WlxLoggedOutSAS(Session->MsGina.Context,
- Session->SASAction,
- &Session->LogonId,
- LogonSid,
- &Options,
- &Token,
- &MprNotifyInfo,
- (PVOID*)&Profile);
-
- return WlxAction;
-}
-
-void
-SessionLoop(PWLSESSION Session)
-{
- //WCHAR StatusMsg[256];
- // HANDLE hShutdownEvent;
- DWORD WlxAction;
- MSG Msg;
-
- WlxAction = WLX_SAS_ACTION_NONE;
- Session->LogonStatus = LOGON_NONE;
- while(WlxAction == WLX_SAS_ACTION_NONE)
- {
- RemoveStatusMessage(Session);
- if(Session->LogonStatus == LOGON_NONE)
- {
- Session->LogonStatus = LOGON_SHOWINGLOGON;
- /* we're ready to display a logon window,
- don't timeout dialogboxes here */
- WlxSetTimeout(Session->MsGina.Context, 0);
- Session->SuppressStatus = TRUE;
- /* tell msgina to show a window telling the user one can logon */
- #if SUPPORT_CONSOLESTART
- if(!StartConsole)
- #endif
- DisplaySASNotice(Session);
- Session->SuppressStatus = FALSE;
-
- if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
- {
- /* the system wants to log off here */
- Session->LogonStatus = LOGON_SHUTDOWN;
- break;
- }
- }
-
- WlxAction = DoLogin(Session);
- if(WlxAction == WLX_SAS_ACTION_LOGOFF)
- {
- /* the user doesn't want to login, instead pressed cancel
- we should display the window again so one can logon again */
- /* FIXME - disconnect any connections in case we did a remote logon */
- DbgPrint("WL: DoLogin failed\n");
- WlxAction = WLX_SAS_ACTION_NONE;
- }
- if(WlxAction == WLX_SAS_ACTION_NONE)
- {
- if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
- {
- /* system is about to shut down, leave the main loop */
- Session->LogonStatus = LOGON_SHUTDOWN;
- break;
- }
- Session->LogonStatus = LOGON_NONE;
- continue;
- }
-
- /* FIXME - don't leave the loop when suspending the computer */
- if(WLX_SUSPENDING(WlxAction))
- {
- Session->LogonStatus = LOGON_NONE;
- WlxAction = WLX_SAS_ACTION_NONE;
- /* don't leave the loop */
- continue;
- }
-
- if(WLX_SHUTTINGDOWN(WlxAction))
- {
- Session->LogonStatus = LOGON_SHUTDOWN;
- /* leave the loop here */
- break;
- }
-
- /* Message loop for the SAS window */
- while(GetMessage(&Msg, 0, 0, 0))
- {
- if (Msg.message == WM_HOTKEY)
- HandleHotKey(&Msg);
- TranslateMessage(&Msg);
- DispatchMessage(&Msg);
- }
- }
- /*
- LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR));
- MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
- ApplicationDesktop,
- 0,
- NULL,
- StatusMsg);
-
-
- Sleep(150);
-
- LoadString(hAppInstance, IDS_APPLYINGCOMPUTERSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
- MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
- ApplicationDesktop,
- 0,
- NULL,
- StatusMsg);
-
-
- Sleep(150);
-
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
-
-
- Sleep(250);
-
- LoadString(hAppInstance, IDS_LOADINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
- MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
- ApplicationDesktop,
- 0,
- NULL,
- StatusMsg);
-
- Sleep(150);
-
- LoadString(hAppInstance, IDS_APPLYINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
- MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
- ApplicationDesktop,
- 0,
- NULL,
- StatusMsg);
-
-
- Sleep(150);
-
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
-
- if(!MsGinaInst->Functions->WlxActivateUserShell(MsGinaInst->Context,
- L"WinSta0\\Default",
- NULL,
- NULL))
- {
- LoadString(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, 256 * sizeof(WCHAR));
- MessageBox(0, StatusMsg, NULL, MB_ICONERROR);
- SetEvent(hShutdownEvent);
- }
-
-
- WaitForSingleObject(hShutdownEvent, INFINITE);
- CloseHandle(hShutdownEvent);
-
- LoadString(hAppInstance, IDS_SAVEYOURSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
- MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
- ApplicationDesktop,
- 0,
- NULL,
- StatusMsg);
-
-
- Sleep(150);
-
- MsGinaInst->Functions->WlxShutdown(MsGinaInst->Context, WLX_SAS_ACTION_SHUTDOWN);
-
- LoadString(hAppInstance, IDS_REACTOSISSHUTTINGDOWN, StatusMsg, 256 * sizeof(WCHAR));
- MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
- ApplicationDesktop,
- 0,
- NULL,
- StatusMsg);
-
-
- Sleep(250);
-
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
- MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
- */
-}
-