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
= NULL
;
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(
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
);
105 if (!StartServiceW(hService
, 0, NULL
))
112 CloseServiceHandle(hService
);
114 CloseServiceHandle(hSCManager
);
121 HANDLE LsassInitEvent
;
123 LsassInitEvent
= CreateEventW(
127 L
"Global\\SECURITY_SERVICES_STARTED");
130 ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError());
134 /* Start the local security authority subsystem (Netlogon service) */
135 if (!StartCustomService(L
"Netlogon"))
137 ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError());
141 WaitForSingleObject(LsassInitEvent
, INFINITE
);
142 CloseHandle(LsassInitEvent
);
150 OUT HKEY
*WinLogonKey
)
152 return ERROR_SUCCESS
== RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
153 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
172 if (OpenRegistryKey(&WinLogonKey
))
174 Size
= sizeof(DWORD
);
175 if (ERROR_SUCCESS
== RegQueryValueEx(WinLogonKey
,
179 (LPBYTE
) &StartValue
,
182 if (REG_DWORD
== Type
)
184 StartIt
= (0 != StartValue
);
187 RegCloseKey(WinLogonKey
);
195 static BOOL RestartShell(
196 IN OUT PWLSESSION Session)
199 DWORD Type, Size, Value;
201 if(OpenRegistryKey(&WinLogonKey))
203 Size = sizeof(DWORD);
204 if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
211 if(Type == REG_DWORD)
213 RegCloseKey(WinLogonKey);
217 RegCloseKey(WinLogonKey);
226 OUT WCHAR
*CommandLine
,
227 IN DWORD BufferLength
)
233 WCHAR Shell
[_MAX_PATH
];
235 GotCommandLine
= FALSE
;
236 if (OpenRegistryKey(&WinLogonKey
))
239 if (ERROR_SUCCESS
== RegQueryValueEx(WinLogonKey
,
246 if (REG_EXPAND_SZ
== Type
)
248 ExpandEnvironmentStrings(Shell
, CommandLine
, _MAX_PATH
);
249 GotCommandLine
= TRUE
;
251 else if (REG_SZ
== Type
)
253 wcscpy(CommandLine
, Shell
);
254 GotCommandLine
= TRUE
;
257 RegCloseKey(WinLogonKey
);
260 if (! GotCommandLine
)
262 GetSystemDirectory(CommandLine
, MAX_PATH
- 15);
263 wcscat(CommandLine
, L
"\\userinit.exe");
272 DisplayStatusMessage(
273 IN PWLSESSION Session
,
277 WCHAR StatusMsg
[MAX_PATH
];
279 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
282 if (Session
->SuppressStatus
)
285 if (LoadStringW(hAppInstance
, ResourceId
, StatusMsg
, MAX_PATH
) == 0)
288 return Session
->Gina
.Functions
.WlxDisplayStatusMessage(Session
->Gina
.Context
, hDesktop
, 0, NULL
, StatusMsg
);
293 IN PWLSESSION Session
)
295 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
298 return Session
->Gina
.Functions
.WlxRemoveStatusMessage(Session
->Gina
.Context
);
302 GinaLoadFailedWindowProc(
312 switch (LOWORD(wParam
))
315 EndDialog(hwndDlg
, IDOK
);
323 WCHAR templateText
[MAX_PATH
], text
[MAX_PATH
];
325 len
= GetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, templateText
, MAX_PATH
);
328 wsprintfW(text
, templateText
, (LPWSTR
)lParam
);
329 SetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, text
);
331 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
336 EndDialog(hwndDlg
, IDCANCEL
);
346 IN HINSTANCE hInstance
,
347 IN HINSTANCE hPrevInstance
,
352 LSA_STRING ProcessName
, PackageName
;
354 LSA_OPERATIONAL_MODE Mode
;
356 ULONG AuthenticationPackage
;
359 ULONG HardErrorResponse
;
362 UNREFERENCED_PARAMETER(hPrevInstance
);
363 UNREFERENCED_PARAMETER(lpCmdLine
);
364 UNREFERENCED_PARAMETER(nShowCmd
);
366 hAppInstance
= hInstance
;
368 if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE
))
370 ERR("WL: Could not register logon process\n");
371 HandleShutdown(NULL
, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
);
372 NtShutdownSystem(ShutdownNoReboot
);
376 WLSession
= (PWLSESSION
)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION
));
379 ERR("WL: Could not allocate memory for winlogon instance\n");
380 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
383 ZeroMemory(WLSession
, sizeof(WLSESSION
));
384 WLSession
->DialogTimeout
= 120; /* 2 minutes */
386 if (!CreateWindowStationAndDesktops(WLSession
))
388 ERR("WL: Could not create window station and desktops\n");
389 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
392 LockWorkstation(WLSession
);
394 if (!StartServicesManager())
396 ERR("WL: Could not start services.exe\n");
397 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
401 /* Check for pending setup */
402 if (GetSetupType() != 0)
404 TRACE("WL: Setup mode detected\n");
407 SetDefaultLanguage(FALSE
);
409 /* Run setup and reboot when done */
410 SwitchDesktop(WLSession
->ApplicationDesktop
);
413 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
419 DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
420 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, OptionOk
, &HardErrorResponse
);
424 /* Load and initialize gina */
425 if (!GinaInit(WLSession
))
427 ERR("WL: Failed to initialize Gina\n");
428 DialogBoxParam(hAppInstance
, MAKEINTRESOURCE(IDD_GINALOADFAILED
), GetDesktopWindow(), GinaLoadFailedWindowProc
, (LPARAM
)L
"");
429 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
433 DisplayStatusMessage(WLSession
, WLSession
->WinlogonDesktop
, IDS_REACTOSISSTARTINGUP
);
436 /* Connect to NetLogon service (lsass.exe) */
437 /* Real winlogon uses "Winlogon" */
438 RtlInitUnicodeString((PUNICODE_STRING
)&ProcessName
, L
"Winlogon");
439 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
440 if (Status
== STATUS_PORT_CONNECTION_REFUSED
)
442 /* Add the 'SeTcbPrivilege' privilege and try again */
443 Status
= RtlAdjustPrivilege(SE_TCB_PRIVILEGE
, TRUE
, TRUE
, &Old
);
444 if (!NT_SUCCESS(Status
))
446 ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status
));
449 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
451 if (!NT_SUCCESS(Status
))
453 ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status
));
457 RtlInitUnicodeString((PUNICODE_STRING
)&PackageName
, MICROSOFT_KERBEROS_NAME_W
);
458 Status
= LsaLookupAuthenticationPackage(LsaHandle
, &PackageName
, &AuthenticationPackage
);
459 if (!NT_SUCCESS(Status
))
461 ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status
));
462 LsaDeregisterLogonProcess(LsaHandle
);
467 /* Create a hidden window to get SAS notifications */
468 if (!InitializeSAS(WLSession
))
470 ERR("WL: Failed to initialize SAS\n");
474 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
475 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
477 /* Display logged out screen */
478 WLSession
->LogonStatus
= WKSTA_IS_LOGGED_OFF
;
479 RemoveStatusMessage(WLSession
);
480 PostMessageW(WLSession
->SASWindow
, WLX_WM_SAS
, WLX_SAS_TYPE_TIMEOUT
, 0);
482 /* Message loop for the SAS window */
483 while (GetMessageW(&Msg
, WLSession
->SASWindow
, 0, 0))
485 TranslateMessage(&Msg
);
486 DispatchMessageW(&Msg
);
489 /* We never go there */