2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: services/winlogon/winlogon.c
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
8 * Hervé Poussineau (hpoussin@reactos.org)
11 /* INCLUDES *****************************************************************/
15 #include <wine/debug.h>
17 /* GLOBALS ******************************************************************/
19 HINSTANCE hAppInstance
;
20 PWLSESSION WLSession
= NULL
;
22 /* FUNCTIONS *****************************************************************/
25 StartServicesManager(VOID
)
27 HANDLE ServicesInitEvent
;
28 STARTUPINFOW StartupInfo
;
29 PROCESS_INFORMATION ProcessInformation
;
31 LPCWSTR ServiceString
= L
"services.exe";
34 /* Start the service control manager (services.exe) */
35 StartupInfo
.cb
= sizeof(StartupInfo
);
36 StartupInfo
.lpReserved
= NULL
;
37 StartupInfo
.lpDesktop
= NULL
;
38 StartupInfo
.lpTitle
= NULL
;
39 StartupInfo
.dwFlags
= 0;
40 StartupInfo
.cbReserved2
= 0;
41 StartupInfo
.lpReserved2
= 0;
43 TRACE("WL: Creating new process - %S\n", ServiceString
);
58 ERR("WL: Failed to execute services (error %lu)\n", GetLastError());
62 /* Wait for event creation (by SCM) for max. 20 seconds */
63 for (Count
= 0; Count
< 20; Count
++)
67 TRACE("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
68 ServicesInitEvent
= OpenEventW(
69 EVENT_ALL_ACCESS
, //SYNCHRONIZE,
71 L
"SvcctrlStartEvent_A3725DX");
72 if (ServicesInitEvent
)
76 if (!ServicesInitEvent
)
78 ERR("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
82 /* Wait for event signalization */
83 WaitForSingleObject(ServicesInitEvent
, INFINITE
);
84 CloseHandle(ServicesInitEvent
);
85 TRACE("WL: StartServicesManager() done.\n");
92 IN LPCWSTR ServiceName
)
94 SC_HANDLE hSCManager
= NULL
;
95 SC_HANDLE hService
= NULL
;
98 hSCManager
= OpenSCManager(NULL
, NULL
, 0);
102 hService
= OpenServiceW(hSCManager
, ServiceName
, SERVICE_START
);
106 if (!StartServiceW(hService
, 0, NULL
))
114 CloseServiceHandle(hService
);
116 CloseServiceHandle(hSCManager
);
123 HANDLE LsassInitEvent
;
125 LsassInitEvent
= CreateEventW(
129 L
"Global\\SECURITY_SERVICES_STARTED");
132 ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError());
136 /* Start the local security authority subsystem (Netlogon service) */
137 if (!StartCustomService(L
"Netlogon"))
139 ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError());
144 WaitForSingleObject(LsassInitEvent
, INFINITE
);
146 CloseHandle(LsassInitEvent
);
154 OUT HKEY
*WinLogonKey
)
156 return ERROR_SUCCESS
== RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
157 L
"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
176 if (OpenRegistryKey(&WinLogonKey
))
178 Size
= sizeof(DWORD
);
179 if (ERROR_SUCCESS
== RegQueryValueEx(WinLogonKey
,
183 (LPBYTE
) &StartValue
,
186 if (REG_DWORD
== Type
)
188 StartIt
= (0 != StartValue
);
191 RegCloseKey(WinLogonKey
);
199 static BOOL RestartShell(
200 IN OUT PWLSESSION Session)
203 DWORD Type, Size, Value;
205 if(OpenRegistryKey(&WinLogonKey))
207 Size = sizeof(DWORD);
208 if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
215 if(Type == REG_DWORD)
217 RegCloseKey(WinLogonKey);
221 RegCloseKey(WinLogonKey);
230 OUT WCHAR
*CommandLine
,
231 IN DWORD BufferLength
)
237 WCHAR Shell
[_MAX_PATH
];
239 GotCommandLine
= FALSE
;
240 if (OpenRegistryKey(&WinLogonKey
))
243 if (ERROR_SUCCESS
== RegQueryValueEx(WinLogonKey
,
250 if (REG_EXPAND_SZ
== Type
)
252 ExpandEnvironmentStrings(Shell
, CommandLine
, _MAX_PATH
);
253 GotCommandLine
= TRUE
;
255 else if (REG_SZ
== Type
)
257 wcscpy(CommandLine
, Shell
);
258 GotCommandLine
= TRUE
;
261 RegCloseKey(WinLogonKey
);
264 if (! GotCommandLine
)
266 GetSystemDirectory(CommandLine
, MAX_PATH
- 15);
267 wcscat(CommandLine
, L
"\\userinit.exe");
276 DisplayStatusMessage(
277 IN PWLSESSION Session
,
281 WCHAR StatusMsg
[MAX_PATH
];
283 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
286 if (Session
->SuppressStatus
)
289 if (LoadStringW(hAppInstance
, ResourceId
, StatusMsg
, MAX_PATH
) == 0)
292 return Session
->Gina
.Functions
.WlxDisplayStatusMessage(Session
->Gina
.Context
, hDesktop
, 0, NULL
, StatusMsg
);
297 IN PWLSESSION Session
)
299 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
302 return Session
->Gina
.Functions
.WlxRemoveStatusMessage(Session
->Gina
.Context
);
305 static INT_PTR CALLBACK
306 GinaLoadFailedWindowProc(
316 switch (LOWORD(wParam
))
319 EndDialog(hwndDlg
, IDOK
);
327 WCHAR templateText
[MAX_PATH
], text
[MAX_PATH
];
329 len
= GetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, templateText
, MAX_PATH
);
332 wsprintfW(text
, templateText
, (LPWSTR
)lParam
);
333 SetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, text
);
335 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
340 EndDialog(hwndDlg
, IDCANCEL
);
350 IN HINSTANCE hInstance
,
351 IN HINSTANCE hPrevInstance
,
356 LSA_STRING ProcessName
, PackageName
;
358 LSA_OPERATIONAL_MODE Mode
;
360 ULONG AuthenticationPackage
;
365 hAppInstance
= hInstance
;
367 if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE
))
369 ERR("WL: Could not register logon process\n");
370 HandleShutdown(NULL
, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
);
371 NtShutdownSystem(ShutdownNoReboot
);
376 WLSession
= (PWLSESSION
)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION
));
377 ZeroMemory(WLSession
, sizeof(WLSESSION
));
380 ERR("WL: Could not allocate memory for winlogon instance\n");
381 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, 0, 0);
385 WLSession
->DialogTimeout
= 120; /* 2 minutes */
387 if (!CreateWindowStationAndDesktops(WLSession
))
389 ERR("WL: Could not create window station and desktops\n");
390 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, 0, 0);
394 LockWorkstation(WLSession
);
396 if (!StartServicesManager())
398 ERR("WL: Could not start services.exe\n");
399 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, 0, 0);
404 /* Check for pending setup */
405 if (GetSetupType() != 0)
407 TRACE("WL: Setup mode detected\n");
409 /* Run setup and reboot when done */
410 SwitchDesktop(WLSession
->ApplicationDesktop
);
413 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
420 DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
421 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, 0, 0);
426 /* Load and initialize gina */
427 if (!GinaInit(WLSession
))
429 ERR("WL: Failed to initialize Gina\n");
430 DialogBoxParam(hAppInstance
, MAKEINTRESOURCE(IDD_GINALOADFAILED
), 0, GinaLoadFailedWindowProc
, (LPARAM
)L
"");
431 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
436 DisplayStatusMessage(WLSession
, WLSession
->WinlogonDesktop
, IDS_REACTOSISSTARTINGUP
);
439 /* Connect to NetLogon service (lsass.exe) */
440 /* Real winlogon uses "Winlogon" */
441 RtlInitUnicodeString((PUNICODE_STRING
)&ProcessName
, L
"Winlogon");
442 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
443 if (Status
== STATUS_PORT_CONNECTION_REFUSED
)
445 /* Add the 'SeTcbPrivilege' privilege and try again */
446 Status
= RtlAdjustPrivilege(SE_TCB_PRIVILEGE
, TRUE
, TRUE
, &Old
);
447 if (!NT_SUCCESS(Status
))
449 ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status
));
452 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
454 if (!NT_SUCCESS(Status
))
456 ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status
));
460 RtlInitUnicodeString((PUNICODE_STRING
)&PackageName
, MICROSOFT_KERBEROS_NAME_W
);
461 Status
= LsaLookupAuthenticationPackage(LsaHandle
, &PackageName
, &AuthenticationPackage
);
462 if (!NT_SUCCESS(Status
))
464 ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status
));
465 LsaDeregisterLogonProcess(LsaHandle
);
470 /* Create a hidden window to get SAS notifications */
471 if (!InitializeSAS(WLSession
))
473 ERR("WL: Failed to initialize SAS\n");
478 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
479 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
481 /* Display logged out screen */
482 WLSession
->LogonStatus
= WKSTA_IS_LOGGED_OFF
;
483 RemoveStatusMessage(WLSession
);
484 DispatchSAS(WLSession
, WLX_SAS_TYPE_TIMEOUT
);
486 /* Message loop for the SAS window */
487 while (GetMessage(&Msg
, WLSession
->SASWindow
, 0, 0))
489 TranslateMessage(&Msg
);
490 DispatchMessage(&Msg
);
493 /* We never go there */