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;
69 PrintString("WL: Creating new process - \"services.exe\".\n");
72 Result = CreateProcess(CommandLine,
84 PrintString("WL: Failed to execute services\n");
88 /* wait for event creation (by SCM) for max. 20 seconds */
89 for (Count = 0; Count < 20; Count++)
93 //DbgPrint("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
94 ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
96 "SvcctrlStartEvent_A3725DX");
97 if (ServicesInitEvent != NULL)
103 if (ServicesInitEvent == NULL)
105 DbgPrint("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
109 /* wait for event signalization */
110 //DbgPrint("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
111 WaitForSingleObject(ServicesInitEvent, INFINITE);
112 //DbgPrint("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
113 CloseHandle(ServicesInitEvent);
114 //DbgPrint("WL: StartServices() Done.\n");
119 static BOOLEAN StartLsass(VOID)
121 HANDLE LsassInitEvent;
123 STARTUPINFO StartupInfo;
124 PROCESS_INFORMATION ProcessInformation;
125 CHAR CommandLine[MAX_PATH];
127 LsassInitEvent = CreateEvent(NULL,
132 if (LsassInitEvent == NULL)
134 DbgPrint("WL: Failed to create lsass notification event\n");
138 /* Start the local security authority subsystem (lsass.exe) */
140 GetSystemDirectory(CommandLine, MAX_PATH);
141 strcat(CommandLine, "\\lsass.exe");
143 StartupInfo.cb = sizeof(StartupInfo);
144 StartupInfo.lpReserved = NULL;
145 StartupInfo.lpDesktop = NULL;
146 StartupInfo.lpTitle = NULL;
147 StartupInfo.dwFlags = 0;
148 StartupInfo.cbReserved2 = 0;
149 StartupInfo.lpReserved2 = 0;
151 Result = CreateProcess(CommandLine,
160 &ProcessInformation);
163 DbgPrint("WL: Failed to execute lsass\n");
167 DPRINT("WL: Waiting for lsass\n");
168 WaitForSingleObject(LsassInitEvent, INFINITE);
169 CloseHandle(LsassInitEvent);
174 static BOOLEAN OpenRegistryKey(HANDLE *WinLogonKey)
176 return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
177 _T("SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon"),
183 static BOOLEAN StartProcess(PCHAR ValueName)
192 if (OpenRegistryKey(&WinLogonKey))
194 Size = sizeof(DWORD);
195 if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
199 (LPBYTE) &StartValue,
202 if (REG_DWORD == Type)
204 StartIt = (0 != StartValue);
207 RegCloseKey(WinLogonKey);
213 static PCHAR GetShell(PCHAR CommandLine)
219 CHAR Shell[_MAX_PATH];
221 GotCommandLine = FALSE;
222 if (OpenRegistryKey(&WinLogonKey))
225 if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
232 if (REG_EXPAND_SZ == Type)
234 ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
235 GotCommandLine = TRUE;
237 else if (REG_SZ == Type)
239 strcpy(CommandLine, Shell);
240 GotCommandLine = TRUE;
243 RegCloseKey(WinLogonKey);
246 if (! GotCommandLine)
248 GetSystemDirectory(CommandLine, MAX_PATH - 10);
249 strcat(CommandLine, "\\cmd.exe");
255 static BOOL DoLoginUser(PCHAR Name, PCHAR Password)
257 PROCESS_INFORMATION ProcessInformation;
258 STARTUPINFO StartupInfo;
260 CHAR CommandLine[MAX_PATH];
261 CHAR CurrentDirectory[MAX_PATH];
263 GetWindowsDirectory(CurrentDirectory, MAX_PATH);
265 StartupInfo.cb = sizeof(StartupInfo);
266 StartupInfo.lpReserved = NULL;
267 StartupInfo.lpDesktop = NULL;
268 StartupInfo.lpTitle = NULL;
269 StartupInfo.dwFlags = 0;
270 StartupInfo.cbReserved2 = 0;
271 StartupInfo.lpReserved2 = 0;
273 Result = CreateProcess(NULL,
274 GetShell(CommandLine),
282 &ProcessInformation);
285 DbgPrint("WL: Failed to execute user shell %s\n", CommandLine);
288 WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
289 CloseHandle( ProcessInformation.hProcess );
290 CloseHandle( ProcessInformation.hThread );
296 WinMain(HINSTANCE hInstance,
297 HINSTANCE hPrevInstance,
302 LSA_STRING ProcessName;
305 LSA_OPERATIONAL_MODE Mode;
307 CHAR LoginPrompt[] = "login:";
308 CHAR PasswordPrompt[] = "password:";
317 * FIXME: Create a security descriptor with
318 * one ACE containing the Winlogon SID
322 * Create the interactive window station
324 InteractiveWindowStation =
325 CreateWindowStationW(L"WinSta0", 0, GENERIC_ALL, NULL);
326 if (InteractiveWindowStation == NULL)
328 DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError());
329 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
334 * Set the process window station
336 SetProcessWindowStation(InteractiveWindowStation);
339 * Create the application desktop
342 CreateDesktopW(L"Default",
345 0, /* FIXME: Set some flags */
350 * Create the winlogon desktop
352 WinlogonDesktop = CreateDesktopW(L"Winlogon",
355 0, /* FIXME: Set some flags */
360 * Create the screen saver desktop
362 ScreenSaverDesktop = CreateDesktopW(L"Screen-Saver",
365 0, /* FIXME: Set some flags */
370 * Switch to winlogon desktop
372 /* FIXME: Do start up in the application desktop for now. */
373 Status = NtSetInformationProcess(NtCurrentProcess(),
376 sizeof(ApplicationDesktop));
377 if (!NT_SUCCESS(Status))
379 DbgPrint("WL: Cannot set default desktop for winlogon.\n");
381 SetThreadDesktop(ApplicationDesktop);
382 Success = SwitchDesktop(ApplicationDesktop);
385 DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
389 SetConsoleTitle( "Winlogon" );
391 /* Check for pending setup */
392 if (GetSetupType () != 0)
394 DPRINT ("Winlogon: CheckForSetup() in setup mode\n");
396 /* Run setup and reboot when done */
399 // NtShutdownSystem (ShutdownReboot);
400 NtShutdownSystem (ShutdownNoReboot);
405 /* start system processes (services.exe & lsass.exe) */
406 if (StartProcess("StartServices"))
408 if (!StartServices())
410 DbgPrint("WL: Failed to start Services (0x%X)\n", GetLastError());
414 if (StartProcess("StartLsass"))
418 DbgPrint("WL: Failed to start LSASS (0x%X)\n", GetLastError());
423 /* FIXME: What name does the real WinLogon use? */
425 RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"WinLogon");
426 Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
427 if (!NT_SUCCESS(Status))
429 DbgPrint("WL: Failed to connect to LSASS\n");
434 /* FIXME: Create a window class and associate a Winlogon
435 * window procedure with it.
436 * Register SAS with the window.
437 * Register for logoff notification
442 /* Display login prompt */
443 WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
445 strlen(LoginPrompt), // wcslen(LoginPrompt),
451 ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
457 } while (LoginName[i - 1] != '\n');
458 LoginName[i - 1] = 0;
460 /* Display password prompt */
461 WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
463 strlen(PasswordPrompt), // wcslen(PasswordPrompt),
469 ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
475 } while (Password[i - 1] != '\n');
479 if (! DoLoginUser(LoginName, Password))
483 NtShutdownSystem(ShutdownNoReboot);