3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/winlogon/winlogon.c
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
17 #include <lsass/ntsecapi.h>
25 /* GLOBALS ******************************************************************/
27 HWINSTA InteractiveWindowStation; /* WinSta0 */
28 HDESK ApplicationDesktop; /* WinSta0\Default */
29 HDESK WinlogonDesktop; /* WinSta0\Winlogon */
30 HDESK ScreenSaverDesktop; /* WinSta0\Screen-Saver */
32 /* FUNCTIONS *****************************************************************/
34 static void PrintString (char* fmt,...)
40 vsprintf(buffer, fmt, ap);
43 OutputDebugString(buffer);
47 static BOOLEAN StartServices(VOID)
49 HANDLE ServicesInitEvent;
51 STARTUPINFO StartupInfo;
52 PROCESS_INFORMATION ProcessInformation;
53 CHAR CommandLine[MAX_PATH];
56 /* Start the service control manager (services.exe) */
57 GetSystemDirectory(CommandLine, MAX_PATH);
58 strcat(CommandLine, "\\services.exe");
60 StartupInfo.cb = sizeof(StartupInfo);
61 StartupInfo.lpReserved = NULL;
62 StartupInfo.lpDesktop = NULL;
63 StartupInfo.lpTitle = NULL;
64 StartupInfo.dwFlags = 0;
65 StartupInfo.cbReserved2 = 0;
66 StartupInfo.lpReserved2 = 0;
68 PrintString("WL: Creating new process - \"services.exe\".\n");
70 Result = CreateProcess(CommandLine,
82 PrintString("WL: Failed to execute services\n");
86 /* wait for event creation (by SCM) for max. 20 seconds */
87 for (Count = 0; Count < 20; Count++)
91 //DbgPrint("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
92 ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
94 "SvcctrlStartEvent_A3725DX");
95 if (ServicesInitEvent != NULL)
101 if (ServicesInitEvent == NULL)
103 DbgPrint("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
107 /* wait for event signalization */
108 //DbgPrint("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
109 WaitForSingleObject(ServicesInitEvent, INFINITE);
110 //DbgPrint("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
111 CloseHandle(ServicesInitEvent);
112 DbgPrint("WL: StartServices() Done.\n");
117 static BOOLEAN StartLsass(VOID)
119 HANDLE LsassInitEvent;
121 STARTUPINFO StartupInfo;
122 PROCESS_INFORMATION ProcessInformation;
123 CHAR CommandLine[MAX_PATH];
125 LsassInitEvent = CreateEvent(NULL,
130 if (LsassInitEvent == NULL)
132 DbgPrint("WL: Failed to create lsass notification event\n");
136 /* Start the local security authority subsystem (lsass.exe) */
138 GetSystemDirectory(CommandLine, MAX_PATH);
139 strcat(CommandLine, "\\lsass.exe");
141 StartupInfo.cb = sizeof(StartupInfo);
142 StartupInfo.lpReserved = NULL;
143 StartupInfo.lpDesktop = NULL;
144 StartupInfo.lpTitle = NULL;
145 StartupInfo.dwFlags = 0;
146 StartupInfo.cbReserved2 = 0;
147 StartupInfo.lpReserved2 = 0;
149 Result = CreateProcess(CommandLine,
158 &ProcessInformation);
161 DbgPrint("WL: Failed to execute lsass\n");
165 DPRINT("WL: Waiting for lsass\n");
166 WaitForSingleObject(LsassInitEvent, INFINITE);
167 CloseHandle(LsassInitEvent);
172 static BOOLEAN OpenRegistryKey(HANDLE *WinLogonKey)
174 return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
175 _T("SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon"),
181 static BOOLEAN StartProcess(PCHAR ValueName)
190 if (OpenRegistryKey(&WinLogonKey))
192 Size = sizeof(DWORD);
193 if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
197 (LPBYTE) &StartValue,
200 if (REG_DWORD == Type)
202 StartIt = (0 != StartValue);
205 RegCloseKey(WinLogonKey);
211 static PCHAR GetShell(PCHAR CommandLine)
217 CHAR Shell[_MAX_PATH];
219 GotCommandLine = FALSE;
220 if (OpenRegistryKey(&WinLogonKey))
223 if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
230 if (REG_EXPAND_SZ == Type)
232 ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
233 GotCommandLine = TRUE;
235 else if (REG_SZ == Type)
237 strcpy(CommandLine, Shell);
238 GotCommandLine = TRUE;
241 RegCloseKey(WinLogonKey);
244 if (! GotCommandLine)
246 GetSystemDirectory(CommandLine, MAX_PATH - 10);
247 strcat(CommandLine, "\\cmd.exe");
253 static BOOL DoLoginUser(PCHAR Name, PCHAR Password)
255 PROCESS_INFORMATION ProcessInformation;
256 STARTUPINFO StartupInfo;
258 CHAR CommandLine[MAX_PATH];
259 CHAR CurrentDirectory[MAX_PATH];
261 GetWindowsDirectory(CurrentDirectory, MAX_PATH);
263 StartupInfo.cb = sizeof(StartupInfo);
264 StartupInfo.lpReserved = NULL;
265 StartupInfo.lpDesktop = NULL;
266 StartupInfo.lpTitle = NULL;
267 StartupInfo.dwFlags = 0;
268 StartupInfo.cbReserved2 = 0;
269 StartupInfo.lpReserved2 = 0;
271 Result = CreateProcess(NULL,
272 GetShell(CommandLine),
280 &ProcessInformation);
283 DbgPrint("WL: Failed to execute user shell %s\n", CommandLine);
286 WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
287 CloseHandle( ProcessInformation.hProcess );
288 CloseHandle( ProcessInformation.hThread );
294 WinMain(HINSTANCE hInstance,
295 HINSTANCE hPrevInstance,
300 LSA_STRING ProcessName;
303 LSA_OPERATIONAL_MODE Mode;
305 CHAR LoginPrompt[] = "login:";
306 CHAR PasswordPrompt[] = "password:";
315 * FIXME: Create a security descriptor with
316 * one ACE containing the Winlogon SID
320 * Create the interactive window station
322 InteractiveWindowStation =
323 CreateWindowStationW(L"WinSta0", 0, GENERIC_ALL, NULL);
324 if (InteractiveWindowStation == NULL)
326 DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError());
327 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
332 * Set the process window station
334 SetProcessWindowStation(InteractiveWindowStation);
337 * Create the application desktop
340 CreateDesktopW(L"Default",
343 0, /* FIXME: Set some flags */
348 * Create the winlogon desktop
350 WinlogonDesktop = CreateDesktopW(L"Winlogon",
353 0, /* FIXME: Set some flags */
358 * Create the screen saver desktop
360 ScreenSaverDesktop = CreateDesktopW(L"Screen-Saver",
363 0, /* FIXME: Set some flags */
368 * Switch to winlogon desktop
370 /* FIXME: Do start up in the application desktop for now. */
371 Status = NtSetInformationProcess(NtCurrentProcess(),
374 sizeof(ApplicationDesktop));
375 if (!NT_SUCCESS(Status))
377 DbgPrint("WL: Cannot set default desktop for winlogon.\n");
379 SetThreadDesktop(ApplicationDesktop);
380 Success = SwitchDesktop(ApplicationDesktop);
383 DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
387 SetConsoleTitle( "Winlogon" );
389 /* Check for pending setup */
390 if (GetSetupType () != 0)
392 DPRINT ("Winlogon: CheckForSetup() in setup mode\n");
394 /* Run setup and reboot when done */
397 // NtShutdownSystem (ShutdownReboot);
398 NtShutdownSystem (ShutdownNoReboot);
403 /* start system processes (services.exe & lsass.exe) */
404 if (StartProcess("StartServices"))
406 if (!StartServices())
408 DbgPrint("WL: Failed to start Services (0x%X)\n", GetLastError());
412 if (StartProcess("StartLsass"))
416 DbgPrint("WL: Failed to start LSASS (0x%X)\n", GetLastError());
421 /* FIXME: What name does the real WinLogon use? */
423 RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"WinLogon");
424 Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
425 if (!NT_SUCCESS(Status))
427 DbgPrint("WL: Failed to connect to LSASS\n");
432 /* FIXME: Create a window class and associate a Winlogon
433 * window procedure with it.
434 * Register SAS with the window.
435 * Register for logoff notification
440 /* Display login prompt */
441 WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
443 strlen(LoginPrompt), // wcslen(LoginPrompt),
449 ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
455 } while (LoginName[i - 1] != '\n');
456 LoginName[i - 1] = 0;
458 /* Display password prompt */
459 WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
461 strlen(PasswordPrompt), // wcslen(PasswordPrompt),
467 ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
473 } while (Password[i - 1] != '\n');
477 if (! DoLoginUser(LoginName, Password))
481 NtShutdownSystem(ShutdownNoReboot);