:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / system / winlogon / winlogon.c
1 /* $Id$
2  * 
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            services/winlogon/winlogon.c
6  * PURPOSE:         Logon 
7  * PROGRAMMER:      David Welch (welch@cwcom.net)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ntos.h>
15 #include <windows.h>
16 #include <stdio.h>
17 #include <lsass/ntsecapi.h>
18
19 #include <wchar.h>
20
21 #define NDEBUG
22 #include <debug.h>
23
24 /* GLOBALS ******************************************************************/
25
26 HWINSTA InteractiveWindowStation;   /* WinSta0 */
27 HDESK ApplicationDesktop;           /* WinSta0\Default */
28 HDESK WinlogonDesktop;              /* WinSta0\Winlogon */
29 HDESK ScreenSaverDesktop;           /* WinSta0\Screen-Saver */
30
31 /* FUNCTIONS *****************************************************************/
32
33 void PrintString (char* fmt,...)
34 {
35    char buffer[512];
36    va_list ap;
37
38    va_start(ap, fmt);
39    vsprintf(buffer, fmt, ap);
40    va_end(ap);
41
42    OutputDebugString(buffer);
43 }
44
45
46 BOOLEAN StartServices(VOID)
47 {
48    HANDLE ServicesInitEvent;
49    BOOLEAN Result;
50    STARTUPINFO StartupInfo;
51    PROCESS_INFORMATION ProcessInformation;
52    CHAR CommandLine[MAX_PATH];
53    DWORD Count;
54
55    /* Start the service control manager (services.exe) */   
56    GetSystemDirectory(CommandLine, MAX_PATH);
57    strcat(CommandLine, "\\services.exe");
58       
59    StartupInfo.cb = sizeof(StartupInfo);
60    StartupInfo.lpReserved = NULL;
61    StartupInfo.lpDesktop = NULL;
62    StartupInfo.lpTitle = NULL;
63    StartupInfo.dwFlags = 0;
64    StartupInfo.cbReserved2 = 0;
65    StartupInfo.lpReserved2 = 0;
66    
67    Result = CreateProcess(CommandLine,
68                           NULL,
69                           NULL,
70                           NULL,
71                           FALSE,
72                           DETACHED_PROCESS,
73                           NULL,
74                           NULL,
75                           &StartupInfo,
76                           &ProcessInformation);
77    if (!Result)
78      {
79         PrintString("WL: Failed to execute services\n");
80         return FALSE;
81      }
82    
83    /* wait for event creation (by SCM) for max. 20 seconds */
84    for (Count = 0; Count < 20; Count++)
85      {
86         Sleep(1000);
87    
88         ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
89                                       FALSE,
90                                       "SvcctrlStartEvent_A3725DX");
91         if (ServicesInitEvent != NULL)
92           {
93              break;
94           }
95      }
96    
97    /* wait for event signalization */
98    WaitForSingleObject(ServicesInitEvent, INFINITE);
99    CloseHandle(ServicesInitEvent);
100       
101    return TRUE;
102 }
103
104 BOOLEAN StartLsass(VOID)
105 {
106    HANDLE LsassInitEvent;
107    BOOLEAN Result;
108    STARTUPINFO StartupInfo;
109    PROCESS_INFORMATION ProcessInformation;
110    CHAR CommandLine[MAX_PATH];
111    
112    LsassInitEvent = CreateEvent(NULL,
113                                 TRUE,
114                                 FALSE,
115                                 "\\LsassInitDone");
116    
117    if (LsassInitEvent == NULL)
118      {
119         DbgPrint("Failed to create lsass notification event\n");
120         return(FALSE);
121      }
122    
123    /* Start the local security authority subsystem (lsass.exe) */
124    
125    GetSystemDirectory(CommandLine, MAX_PATH);
126    strcat(CommandLine, "\\lsass.exe");
127    
128    StartupInfo.cb = sizeof(StartupInfo);
129    StartupInfo.lpReserved = NULL;
130    StartupInfo.lpDesktop = NULL;
131    StartupInfo.lpTitle = NULL;
132    StartupInfo.dwFlags = 0;
133    StartupInfo.cbReserved2 = 0;
134    StartupInfo.lpReserved2 = 0;
135    
136    Result = CreateProcess(CommandLine,
137                           NULL,
138                           NULL,
139                           NULL,
140                           FALSE,
141                           DETACHED_PROCESS,
142                           NULL,
143                           NULL,
144                           &StartupInfo,
145                           &ProcessInformation);
146    if (!Result)
147      {
148         DbgPrint("WL: Failed to execute lsass\n");
149         return(FALSE);
150      }
151    
152    DPRINT("WL: Waiting for lsass\n");
153    WaitForSingleObject(LsassInitEvent, INFINITE);
154    CloseHandle(LsassInitEvent);
155    
156    return(TRUE);
157 }
158
159 VOID DoLoginUser(PCHAR Name, PCHAR Password)
160 {
161    PROCESS_INFORMATION ProcessInformation;
162    STARTUPINFO StartupInfo;
163    BOOLEAN Result;
164    CHAR CommandLine[MAX_PATH];
165    CHAR CurrentDirectory[MAX_PATH];
166    
167    GetSystemDirectory(CommandLine, MAX_PATH);
168    strcat(CommandLine, "\\shell.exe");
169
170    GetWindowsDirectory(CurrentDirectory, MAX_PATH);
171
172    StartupInfo.cb = sizeof(StartupInfo);
173    StartupInfo.lpReserved = NULL;
174    StartupInfo.lpDesktop = NULL;
175    StartupInfo.lpTitle = NULL;
176    StartupInfo.dwFlags = 0;
177    StartupInfo.cbReserved2 = 0;
178    StartupInfo.lpReserved2 = 0;
179    
180    Result = CreateProcess(CommandLine,
181                           NULL,
182                           NULL,
183                           NULL,
184                           FALSE,
185                           DETACHED_PROCESS,
186                           NULL,
187                           CurrentDirectory,
188                           &StartupInfo,
189                           &ProcessInformation);
190    if (!Result)
191      {
192         DbgPrint("WL: Failed to execute user shell\n");
193         return;
194      }
195    WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
196    CloseHandle( ProcessInformation.hProcess );
197    CloseHandle( ProcessInformation.hThread );
198 }
199
200 int STDCALL
201 WinMain(HINSTANCE hInstance,
202         HINSTANCE hPrevInstance,
203         LPSTR lpCmdLine,
204         int nShowCmd)
205 {
206 #if 0
207   LSA_STRING ProcessName;
208   NTSTATUS Status;
209   HANDLE LsaHandle;
210   LSA_OPERATIONAL_MODE Mode;
211 #endif
212   CHAR LoginPrompt[] = "login:";
213   CHAR PasswordPrompt[] = "password:";
214   DWORD Result;
215   CHAR LoginName[255];
216   CHAR Password[255];
217   BOOL Success;
218   ULONG i;
219   NTSTATUS Status;
220   
221   /*
222    * FIXME: Create a security descriptor with
223    *        one ACE containing the Winlogon SID
224    */
225   
226   /*
227    * Create the interactive window station
228    */
229    InteractiveWindowStation = 
230      CreateWindowStationW(L"WinSta0", 0, GENERIC_ALL, NULL);
231    if (InteractiveWindowStation == NULL)
232      {
233        DbgPrint("Failed to create window station (0x%X)\n", GetLastError());
234        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
235        ExitProcess(1);
236      }
237    
238    /*
239     * Set the process window station
240     */
241    SetProcessWindowStation(InteractiveWindowStation);
242
243    /*
244     * Create the application desktop
245     */
246    ApplicationDesktop = 
247      CreateDesktopW(L"Default",
248                     NULL,
249                     NULL,
250                     0,      /* FIXME: Set some flags */
251                     GENERIC_ALL,
252                     NULL); 
253
254    /*
255     * Create the winlogon desktop
256     */
257    WinlogonDesktop = CreateDesktopW(L"Winlogon",
258                                     NULL,
259                                     NULL,
260                                     0,      /* FIXME: Set some flags */
261                                     GENERIC_ALL,
262                                     NULL);  
263    
264    /*
265     * Create the screen saver desktop
266     */
267    ScreenSaverDesktop = CreateDesktopW(L"Screen-Saver",
268                                        NULL,
269                                        NULL,
270                                        0,      /* FIXME: Set some flags */
271                                        GENERIC_ALL,
272                                        NULL);  
273    
274    /*
275     * Switch to winlogon desktop
276     */
277    /* FIXME: Do start up in the application desktop for now. */
278    Status = NtSetInformationProcess(NtCurrentProcess(),
279                                     ProcessDesktop,
280                                     &ApplicationDesktop,
281                                     sizeof(ApplicationDesktop));
282    if (!NT_SUCCESS(Status))
283      {
284        DbgPrint("WL: Cannot set default desktop for winlogon.\n");
285      }
286    SetThreadDesktop(ApplicationDesktop);
287    Success = SwitchDesktop(ApplicationDesktop);
288    if (!Success)
289      {
290        DbgPrint("Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
291      }
292    
293    AllocConsole();
294    SetConsoleTitle( "Winlogon" );
295    /* start system processes (services.exe & lsass.exe) */
296    StartServices();
297 #if 0
298    StartLsass();
299 #endif
300    
301    /* FIXME: What name does the real WinLogon use? */
302 #if 0
303    RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"WinLogon");
304    Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
305    if (!NT_SUCCESS(Status))
306      {
307        DbgPrint("WL: Failed to connect to lsass\n");
308         return(1);
309      }
310 #endif
311    
312    /* FIXME: Create a window class and associate a Winlogon
313     *        window procedure with it.
314     *        Register SAS with the window.
315     *        Register for logoff notification
316     */
317    
318    /* Main loop */
319    for (;;)
320      {
321 #if 0
322        /* Display login prompt */
323        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
324                     LoginPrompt,
325                     strlen(LoginPrompt),  // wcslen(LoginPrompt),
326                     &Result,
327                     NULL);
328        i = 0;
329        do
330          {
331            ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
332                        &LoginName[i],
333                        1,
334                        &Result,
335                        NULL);
336            i++;
337          } while (LoginName[i - 1] != '\n');
338        LoginName[i - 1] = 0;
339        
340         /* Display password prompt */
341        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
342                     PasswordPrompt,
343                     strlen(PasswordPrompt),  // wcslen(PasswordPrompt),
344                     &Result,
345                     NULL);
346        i = 0;
347        do
348          {
349            ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
350                        &Password[i],
351                        1,
352                        &Result,
353                        NULL);
354            i++;
355          } while (Password[i - 1] != '\n');
356        Password[i - 1] =0;
357 #endif
358        DoLoginUser(LoginName, Password);
359      }
360    
361    ExitProcess(0);
362    
363    return 0;
364 }