Winlogon:
[reactos.git] / reactos / base / system / winlogon / winlogon.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: services/winlogon/winlogon.c
5 * PURPOSE: Logon
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Filip Navara
8 * Hervé Poussineau (hpoussin@reactos.org)
9 */
10
11 /* INCLUDES *****************************************************************/
12 #include "winlogon.h"
13
14 #define YDEBUG
15 #include <wine/debug.h>
16
17 /* GLOBALS ******************************************************************/
18
19 HINSTANCE hAppInstance;
20 PWLSESSION WLSession = NULL;
21
22 /* FUNCTIONS *****************************************************************/
23
24 static INT_PTR CALLBACK
25 ShutdownComputerWindowProc(
26 IN HWND hwndDlg,
27 IN UINT uMsg,
28 IN WPARAM wParam,
29 IN LPARAM lParam)
30 {
31 switch (uMsg)
32 {
33 case WM_COMMAND:
34 {
35 switch (LOWORD(wParam))
36 {
37 case IDC_BTNSHTDOWNCOMPUTER:
38 EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
39 break;
40 }
41 break;
42 }
43 case WM_INITDIALOG:
44 {
45 RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
46 SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
47 break;
48 }
49 }
50 return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
51 }
52
53 static BOOL
54 StartServicesManager(void)
55 {
56 HANDLE ServicesInitEvent;
57 BOOLEAN Result;
58 STARTUPINFO StartupInfo;
59 PROCESS_INFORMATION ProcessInformation;
60 DWORD Count;
61 WCHAR ServiceString[] = L"services.exe";
62
63 /* Start the service control manager (services.exe) */
64
65 StartupInfo.cb = sizeof(StartupInfo);
66 StartupInfo.lpReserved = NULL;
67 StartupInfo.lpDesktop = NULL;
68 StartupInfo.lpTitle = NULL;
69 StartupInfo.dwFlags = 0;
70 StartupInfo.cbReserved2 = 0;
71 StartupInfo.lpReserved2 = 0;
72
73 #if 0
74 DPRINT1(L"WL: Creating new process - \"services.exe\".\n");
75 #endif
76
77 Result = CreateProcess(NULL,
78 ServiceString,
79 NULL,
80 NULL,
81 FALSE,
82 DETACHED_PROCESS,
83 NULL,
84 NULL,
85 &StartupInfo,
86 &ProcessInformation);
87 if (!Result)
88 {
89 DPRINT1("WL: Failed to execute services\n");
90 return FALSE;
91 }
92
93 /* wait for event creation (by SCM) for max. 20 seconds */
94 for (Count = 0; Count < 20; Count++)
95 {
96 Sleep(1000);
97
98 DPRINT("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
99 ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
100 FALSE,
101 L"SvcctrlStartEvent_A3725DX");
102 if (ServicesInitEvent != NULL)
103 {
104 break;
105 }
106 }
107
108 if (ServicesInitEvent == NULL)
109 {
110 DPRINT1("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
111 return FALSE;
112 }
113
114 /* wait for event signalization */
115 DPRINT("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
116 WaitForSingleObject(ServicesInitEvent, INFINITE);
117 DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
118 CloseHandle(ServicesInitEvent);
119 DPRINT("WL: StartServicesManager() Done.\n");
120
121 return TRUE;
122 }
123
124 static BOOL
125 StartCustomService(
126 IN LPCWSTR ServiceName)
127 {
128 SC_HANDLE hSCManager = NULL;
129 SC_HANDLE hService = NULL;
130 BOOL ret = FALSE;
131
132 hSCManager = OpenSCManager(NULL, NULL, 0);
133 if (!hSCManager)
134 goto cleanup;
135
136 hService = OpenService(hSCManager, ServiceName, SERVICE_START);
137 if (!hService)
138 goto cleanup;
139 #if 0
140 if (!StartService(hService, 0, NULL))
141 goto cleanup;
142 #endif
143
144 ret = TRUE;
145
146 cleanup:
147 if (hService)
148 CloseServiceHandle(hService);
149 if (hSCManager)
150 CloseServiceHandle(hSCManager);
151 return ret;
152 }
153
154 static BOOL
155 StartLsass(VOID)
156 {
157 HANDLE LsassInitEvent;
158
159 LsassInitEvent = CreateEvent(
160 NULL,
161 TRUE,
162 FALSE,
163 L"Global\\SECURITY_SERVICES_STARTED");
164 if (!LsassInitEvent)
165 {
166 ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError());
167 return FALSE;
168 }
169
170 /* Start the local security authority subsystem (Netlogon service) */
171 if (!StartCustomService(L"Netlogon"))
172 {
173 ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError());
174 return FALSE;
175 }
176
177 #if 0
178 WaitForSingleObject(LsassInitEvent, INFINITE);
179 #endif
180 CloseHandle(LsassInitEvent);
181
182 return TRUE;
183 }
184
185 static BOOL
186 OpenRegistryKey(
187 OUT HKEY *WinLogonKey)
188 {
189 return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
190 L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
191 0,
192 KEY_QUERY_VALUE,
193 WinLogonKey);
194 }
195
196 #if 0
197 static BOOL
198 StartProcess(
199 IN PWCHAR ValueName)
200 {
201 BOOL StartIt;
202 HKEY WinLogonKey;
203 DWORD Type;
204 DWORD Size;
205 DWORD StartValue;
206
207 StartIt = TRUE;
208 if (OpenRegistryKey(&WinLogonKey))
209 {
210 Size = sizeof(DWORD);
211 if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
212 ValueName,
213 NULL,
214 &Type,
215 (LPBYTE) &StartValue,
216 &Size))
217 {
218 if (REG_DWORD == Type)
219 {
220 StartIt = (0 != StartValue);
221 }
222 }
223 RegCloseKey(WinLogonKey);
224 }
225
226 return StartIt;
227 }
228 #endif
229
230 /*
231 static BOOL RestartShell(void)
232 {
233 HKEY WinLogonKey;
234 DWORD Type, Size, Value;
235
236 if(OpenRegistryKey(&WinLogonKey))
237 {
238 Size = sizeof(DWORD);
239 if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
240 L"AutoRestartShell",
241 NULL,
242 &Type,
243 (LPBYTE)&Value,
244 &Size))
245 {
246 if(Type == REG_DWORD)
247 {
248 RegCloseKey(WinLogonKey);
249 return (Value != 0);
250 }
251 }
252 RegCloseKey(WinLogonKey);
253 }
254 return FALSE;
255 }
256 */
257
258 static PWCHAR
259 GetUserInit(
260 OUT WCHAR *CommandLine,
261 IN DWORD BufferLength)
262 {
263 HKEY WinLogonKey;
264 BOOL GotCommandLine;
265 DWORD Type;
266 DWORD Size;
267 WCHAR Shell[_MAX_PATH];
268
269 GotCommandLine = FALSE;
270 if (OpenRegistryKey(&WinLogonKey))
271 {
272 Size = MAX_PATH;
273 if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
274 L"UserInit",
275 NULL,
276 &Type,
277 (LPBYTE) Shell,
278 &Size))
279 {
280 if (REG_EXPAND_SZ == Type)
281 {
282 ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
283 GotCommandLine = TRUE;
284 }
285 else if (REG_SZ == Type)
286 {
287 wcscpy(CommandLine, Shell);
288 GotCommandLine = TRUE;
289 }
290 }
291 RegCloseKey(WinLogonKey);
292 }
293
294 if (! GotCommandLine)
295 {
296 GetSystemDirectory(CommandLine, MAX_PATH - 15);
297 wcscat(CommandLine, L"\\userinit.exe");
298 }
299
300 return CommandLine;
301 }
302
303
304 BOOL
305 DoBrokenLogonUser(
306 IN PWLSESSION WLSession,
307 IN PWLX_MPR_NOTIFY_INFO pMprNotifyInfo)
308 {
309 PROCESS_INFORMATION ProcessInformation;
310 STARTUPINFO StartupInfo;
311 WCHAR CommandLine[MAX_PATH];
312 WCHAR CurrentDirectory[MAX_PATH];
313 PROFILEINFOW ProfileInfo;
314 BOOL Result;
315 LPVOID lpEnvironment = NULL;
316 MSG Msg;
317 BOOLEAN Old;
318
319 SwitchDesktop(WLSession->ApplicationDesktop);
320
321 /* Load the user profile */
322 ProfileInfo.dwSize = sizeof(PROFILEINFOW);
323 ProfileInfo.dwFlags = 0;
324 ProfileInfo.lpUserName = pMprNotifyInfo->pszUserName;
325 ProfileInfo.lpProfilePath = NULL;
326 ProfileInfo.lpDefaultPath = NULL;
327 ProfileInfo.lpServerName = NULL;
328 ProfileInfo.lpPolicyPath = NULL;
329 ProfileInfo.hProfile = NULL;
330
331 if (!LoadUserProfileW (WLSession->UserToken,
332 &ProfileInfo))
333 {
334 DPRINT1 ("WL: LoadUserProfileW() failed\n");
335 CloseHandle (WLSession->UserToken);
336 RtlDestroyEnvironment (lpEnvironment);
337 return FALSE;
338 }
339
340 if (!CreateEnvironmentBlock (&lpEnvironment,
341 WLSession->UserToken,
342 TRUE))
343 {
344 DPRINT1("WL: CreateEnvironmentBlock() failed\n");
345 return FALSE;
346 }
347
348 if (ImpersonateLoggedOnUser(WLSession->UserToken))
349 {
350 UpdatePerUserSystemParameters(0, TRUE);
351 RevertToSelf();
352 }
353
354 GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
355
356 StartupInfo.cb = sizeof(StartupInfo);
357 StartupInfo.lpReserved = NULL;
358 StartupInfo.lpDesktop = NULL;
359 StartupInfo.lpTitle = NULL;
360 StartupInfo.dwFlags = 0;
361 StartupInfo.cbReserved2 = 0;
362 StartupInfo.lpReserved2 = 0;
363
364 /* Get privilege */
365 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
366
367 Result = CreateProcessAsUserW(
368 WLSession->UserToken,
369 NULL,
370 GetUserInit (CommandLine, MAX_PATH),
371 NULL,
372 NULL,
373 FALSE,
374 CREATE_UNICODE_ENVIRONMENT,
375 lpEnvironment,
376 CurrentDirectory,
377 &StartupInfo,
378 &ProcessInformation);
379 if (!Result)
380 {
381 DPRINT1("WL: Failed to execute user shell %ws\n", CommandLine);
382 if (ImpersonateLoggedOnUser(WLSession->UserToken))
383 {
384 UpdatePerUserSystemParameters(0, FALSE);
385 RevertToSelf();
386 }
387 UnloadUserProfile (WLSession->UserToken,
388 ProfileInfo.hProfile);
389 CloseHandle (WLSession->UserToken);
390 DestroyEnvironmentBlock (lpEnvironment);
391 return FALSE;
392 }
393 /*WLSession->MsGina.Functions.WlxActivateUserShell(WLSession->MsGina.Context,
394 L"WinSta0\\Default",
395 NULL,
396 NULL);*/
397
398 while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0)
399 {
400 if (PeekMessage(&Msg, WLSession->SASWindow, 0, 0, PM_REMOVE))
401 {
402 TranslateMessage(&Msg);
403 DispatchMessage(&Msg);
404 }
405 }
406
407 CloseHandle (ProcessInformation.hProcess);
408 CloseHandle (ProcessInformation.hThread);
409
410 if (ImpersonateLoggedOnUser(WLSession->UserToken))
411 {
412 UpdatePerUserSystemParameters(0, FALSE);
413 RevertToSelf();
414 }
415
416 /* Unload user profile */
417 UnloadUserProfile (WLSession->UserToken,
418 ProfileInfo.hProfile);
419
420 CloseHandle (WLSession->UserToken);
421
422 RtlDestroyEnvironment (lpEnvironment);
423
424 return TRUE;
425 }
426
427 static BOOL
428 DisplayStatusMessage(
429 IN PWLSESSION Session,
430 IN HDESK hDesktop,
431 IN UINT ResourceId)
432 {
433 WCHAR StatusMsg[MAX_PATH];
434
435 if (Session->SuppressStatus)
436 return TRUE;
437
438 if (LoadString(hAppInstance, ResourceId, StatusMsg, MAX_PATH) == 0)
439 return FALSE;
440
441 return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, 0, NULL, StatusMsg);
442 }
443
444 #if 0
445 static BOOL
446 InitServices(VOID)
447 {
448 /*WCHAR StatusMsg[256];
449
450 LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR));
451 DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);*/
452
453 /* start system processes (services.exe & lsass.exe) */
454 if(StartProcess(L"StartServices"))
455 {
456 if(!StartServicesManager())
457 {
458 DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError());
459 }
460 }
461 else
462 {
463 DPRINT1("WL: StartProcess() failed!\n");
464 }
465
466 return TRUE;
467 }
468 #endif
469
470 #if 0
471 static DWORD
472 DoLogin(
473 IN OUT PWLSESSION Session)
474 {
475 DWORD WlxAction, Options;
476 WLX_MPR_NOTIFY_INFO MprNotifyInfo;
477 PWLX_PROFILE_V2_0 Profile;
478 PSID LogonSid = NULL;
479 HANDLE Token;
480
481 /* FIXME - Create a Logon Sid
482 if(!(LogonSid = CreateUserLogonSid(NULL)))
483 {
484 return WLX_SAS_ACTION_NONE;
485 }
486 */
487
488 Options = 0;
489 WlxAction = Session->MsGina.Functions.WlxLoggedOutSAS(Session->MsGina.Context,
490 Session->SASAction,
491 &Session->LogonId,
492 LogonSid,
493 &Options,
494 &Token,
495 &MprNotifyInfo,
496 (PVOID*)&Profile);
497
498 if (WlxAction == WLX_SAS_ACTION_LOGON)
499 {
500 Session->UserToken = Token;
501 if (!DoBrokenLogonUser(Session, &MprNotifyInfo))
502 WlxAction = WLX_SAS_ACTION_NONE;
503 }
504 return WlxAction;
505 }
506 #endif
507
508 static VOID
509 SessionLoop(
510 IN OUT PWLSESSION Session)
511 {
512 //WCHAR StatusMsg[256];
513 //HANDLE hShutdownEvent;
514 MSG Msg;
515
516 Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
517 RemoveStatusMessage(Session);
518 DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT);
519
520 /* Message loop for the SAS window */
521 while (GetMessage(&Msg, WLSession->SASWindow, 0, 0))
522 {
523 TranslateMessage(&Msg);
524 DispatchMessage(&Msg);
525 }
526
527 /* Don't go there! */
528
529 #if 0
530 /* FIXME - don't leave the loop when suspending the computer */
531 if(WLX_SUSPENDING(WlxAction))
532 {
533 Session->LogonStatus = LOGON_NONE;
534 WlxAction = WLX_SAS_ACTION_NONE;
535 /* don't leave the loop */
536 continue;
537 }
538
539 if(WLX_SHUTTINGDOWN(WlxAction))
540 {
541 Session->LogonStatus = LOGON_SHUTDOWN;
542 /* leave the loop here */
543 break;
544 }
545
546 #endif
547 /*
548 LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR));
549 MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
550 ApplicationDesktop,
551 0,
552 NULL,
553 StatusMsg);
554
555
556 Sleep(150);
557
558 LoadString(hAppInstance, IDS_APPLYINGCOMPUTERSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
559 MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
560 ApplicationDesktop,
561 0,
562 NULL,
563 StatusMsg);
564
565
566 Sleep(150);
567
568 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
569 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
570 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
571
572
573 Sleep(250);
574
575 LoadString(hAppInstance, IDS_LOADINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
576 MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
577 ApplicationDesktop,
578 0,
579 NULL,
580 StatusMsg);
581
582 Sleep(150);
583
584 LoadString(hAppInstance, IDS_APPLYINGYOURPERSONALSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
585 MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
586 ApplicationDesktop,
587 0,
588 NULL,
589 StatusMsg);
590
591
592 Sleep(150);
593
594 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
595 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
596
597 if(!MsGinaInst->Functions->WlxActivateUserShell(MsGinaInst->Context,
598 L"WinSta0\\Default",
599 NULL,
600 NULL))
601 {
602 LoadString(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, 256 * sizeof(WCHAR));
603 MessageBox(0, StatusMsg, NULL, MB_ICONERROR);
604 SetEvent(hShutdownEvent);
605 }
606
607
608 WaitForSingleObject(hShutdownEvent, INFINITE);
609 CloseHandle(hShutdownEvent);
610
611 LoadString(hAppInstance, IDS_SAVEYOURSETTINGS, StatusMsg, 256 * sizeof(WCHAR));
612 MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
613 ApplicationDesktop,
614 0,
615 NULL,
616 StatusMsg);
617
618
619 Sleep(150);
620
621 MsGinaInst->Functions->WlxShutdown(MsGinaInst->Context, WLX_SAS_ACTION_SHUTDOWN);
622
623 LoadString(hAppInstance, IDS_REACTOSISSHUTTINGDOWN, StatusMsg, 256 * sizeof(WCHAR));
624 MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
625 ApplicationDesktop,
626 0,
627 NULL,
628 StatusMsg);
629
630
631 Sleep(250);
632
633 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
634 MsGinaInst->Functions->WlxRemoveStatusMessage(MsGinaInst->Context);
635 */
636 }
637
638 int WINAPI
639 WinMain(
640 IN HINSTANCE hInstance,
641 IN HINSTANCE hPrevInstance,
642 IN LPSTR lpCmdLine,
643 IN int nShowCmd)
644 {
645 #if 0
646 LSA_STRING ProcessName, PackageName;
647 HANDLE LsaHandle;
648 LSA_OPERATIONAL_MODE Mode;
649 BOOLEAN Old;
650 ULONG AuthenticationPackage;
651 NTSTATUS Status;
652 #endif
653
654 hAppInstance = hInstance;
655
656 if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
657 {
658 ERR("WL: Could not register logon process\n");
659 NtShutdownSystem(ShutdownNoReboot);
660 ExitProcess(0);
661 return 0;
662 }
663
664 WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION));
665 if (!WLSession)
666 {
667 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
668 ExitProcess(1);
669 return 1;
670 }
671
672 if (!CreateWindowStationAndDesktops(WLSession))
673 {
674 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
675 ExitProcess(1);
676 return 1;
677 }
678
679 /* Check for pending setup */
680 if (GetSetupType() != 0)
681 {
682 DPRINT("Winlogon: CheckForSetup() in setup mode\n");
683
684 /* Run setup and reboot when done */
685 SwitchDesktop(WLSession->ApplicationDesktop);
686 RunSetup();
687
688 NtShutdownSystem(ShutdownReboot);
689 ExitProcess(0);
690 return 0;
691 }
692
693 /* Load and initialize gina */
694 if (!GinaInit(WLSession))
695 {
696 ERR("WL: Failed to initialize Gina\n");
697 NtShutdownSystem(ShutdownNoReboot);
698 ExitProcess(0);
699 return 0;
700 }
701
702 DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
703
704 if (!StartServicesManager())
705 {
706 ERR("WL: Could not start services.exe\n");
707 NtShutdownSystem(ShutdownNoReboot);
708 ExitProcess(0);
709 return 0;
710 }
711
712 if (!StartLsass())
713 {
714 DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
715 return 1;
716 }
717
718 #if 0
719 /* Connect to NetLogon service (lsass.exe) */
720 /* Real winlogon uses "Winlogon" */
721 RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon");
722 Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
723 if (Status == STATUS_PORT_CONNECTION_REFUSED)
724 {
725 /* Add the 'SeTcbPrivilege' privilege and try again */
726 RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old);
727 Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
728 }
729 if (!NT_SUCCESS(Status))
730 {
731 ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status));
732 return 1;
733 }
734
735 RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W);
736 Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage);
737 if (!NT_SUCCESS(Status))
738 {
739 ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status));
740 LsaDeregisterLogonProcess(LsaHandle);
741 return 1;
742 }
743 #endif
744
745 /* Create a hidden window to get SAS notifications */
746 if (!InitializeSAS(WLSession))
747 {
748 ERR("WL: Failed to initialize SAS\n");
749 ExitProcess(2);
750 return 2;
751 }
752
753 /* Main loop */
754 SessionLoop(WLSession);
755
756 /* FIXME - Flush disks and registry, ... */
757
758 if(WLSession->LogonStatus == 0)
759 {
760 /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
761 switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerWindowProc))
762 {
763 case IDC_BTNSHTDOWNCOMPUTER:
764 NtShutdownSystem(ShutdownReboot);
765 break;
766 default:
767 NtShutdownSystem(ShutdownNoReboot);
768 break;
769 }
770 ExitProcess(0);
771 }
772 else
773 {
774 DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n");
775 ExitProcess(0);
776 }
777
778 return 0;
779 }