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_A3752DX\"\n");
68 ServicesInitEvent
= OpenEventW(
71 L
"SvcctrlStartEvent_A3752DX");
72 if (ServicesInitEvent
)
76 if (!ServicesInitEvent
)
78 ERR("WL: Failed to open event \"SvcctrlStartEvent_A3752DX\"\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);
101 ERR("WL: Failed to OpenSCManager\n");
105 hService
= OpenServiceW(hSCManager
, ServiceName
, SERVICE_START
);
108 ERR("WL: Failed to open the service\n");
111 if (!StartServiceW(hService
, 0, NULL
))
113 ERR("WL: Failed to start the service\n");
121 CloseServiceHandle(hService
);
123 CloseServiceHandle(hSCManager
);
130 HANDLE LsassInitEvent
;
132 LsassInitEvent
= CreateEventW(
136 L
"Global\\SECURITY_SERVICES_STARTED");
139 ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError());
143 /* Start the local security authority subsystem (Netlogon service) */
144 if (!StartCustomService(L
"Netlogon"))
146 ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError());
150 WaitForSingleObject(LsassInitEvent
, INFINITE
);
151 CloseHandle(LsassInitEvent
);
159 OUT HKEY
*WinLogonKey
)
161 return ERROR_SUCCESS
== RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
162 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
181 if (OpenRegistryKey(&WinLogonKey
))
183 Size
= sizeof(DWORD
);
184 if (ERROR_SUCCESS
== RegQueryValueEx(WinLogonKey
,
188 (LPBYTE
) &StartValue
,
191 if (REG_DWORD
== Type
)
193 StartIt
= (0 != StartValue
);
196 RegCloseKey(WinLogonKey
);
204 static BOOL RestartShell(
205 IN OUT PWLSESSION Session)
208 DWORD Type, Size, Value;
210 if(OpenRegistryKey(&WinLogonKey))
212 Size = sizeof(DWORD);
213 if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
220 if(Type == REG_DWORD)
222 RegCloseKey(WinLogonKey);
226 RegCloseKey(WinLogonKey);
235 OUT WCHAR
*CommandLine
,
236 IN DWORD BufferLength
)
242 WCHAR Shell
[_MAX_PATH
];
244 GotCommandLine
= FALSE
;
245 if (OpenRegistryKey(&WinLogonKey
))
248 if (ERROR_SUCCESS
== RegQueryValueEx(WinLogonKey
,
255 if (REG_EXPAND_SZ
== Type
)
257 ExpandEnvironmentStrings(Shell
, CommandLine
, _MAX_PATH
);
258 GotCommandLine
= TRUE
;
260 else if (REG_SZ
== Type
)
262 wcscpy(CommandLine
, Shell
);
263 GotCommandLine
= TRUE
;
266 RegCloseKey(WinLogonKey
);
269 if (! GotCommandLine
)
271 GetSystemDirectory(CommandLine
, MAX_PATH
- 15);
272 wcscat(CommandLine
, L
"\\userinit.exe");
281 DisplayStatusMessage(
282 IN PWLSESSION Session
,
286 WCHAR StatusMsg
[MAX_PATH
];
288 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
291 if (Session
->SuppressStatus
)
294 if (LoadStringW(hAppInstance
, ResourceId
, StatusMsg
, MAX_PATH
) == 0)
297 return Session
->Gina
.Functions
.WlxDisplayStatusMessage(Session
->Gina
.Context
, hDesktop
, 0, NULL
, StatusMsg
);
302 IN PWLSESSION Session
)
304 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
307 return Session
->Gina
.Functions
.WlxRemoveStatusMessage(Session
->Gina
.Context
);
311 GinaLoadFailedWindowProc(
321 switch (LOWORD(wParam
))
324 EndDialog(hwndDlg
, IDOK
);
332 WCHAR templateText
[MAX_PATH
], text
[MAX_PATH
];
334 len
= GetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, templateText
, MAX_PATH
);
337 wsprintfW(text
, templateText
, (LPWSTR
)lParam
);
338 SetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, text
);
340 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
345 EndDialog(hwndDlg
, IDCANCEL
);
355 IN HINSTANCE hInstance
,
356 IN HINSTANCE hPrevInstance
,
361 LSA_STRING ProcessName
, PackageName
;
363 LSA_OPERATIONAL_MODE Mode
;
365 ULONG AuthenticationPackage
;
368 ULONG HardErrorResponse
;
371 UNREFERENCED_PARAMETER(hPrevInstance
);
372 UNREFERENCED_PARAMETER(lpCmdLine
);
373 UNREFERENCED_PARAMETER(nShowCmd
);
375 hAppInstance
= hInstance
;
377 if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE
))
379 ERR("WL: Could not register logon process\n");
380 HandleShutdown(NULL
, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
);
381 NtShutdownSystem(ShutdownNoReboot
);
385 WLSession
= (PWLSESSION
)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION
));
388 ERR("WL: Could not allocate memory for winlogon instance\n");
389 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
392 ZeroMemory(WLSession
, sizeof(WLSESSION
));
393 WLSession
->DialogTimeout
= 120; /* 2 minutes */
395 if (!CreateWindowStationAndDesktops(WLSession
))
397 ERR("WL: Could not create window station and desktops\n");
398 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
401 LockWorkstation(WLSession
);
403 if (!StartServicesManager())
405 ERR("WL: Could not start services.exe\n");
406 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
410 /* Check for pending setup */
411 if (GetSetupType() != 0)
413 TRACE("WL: Setup mode detected\n");
416 SetDefaultLanguage(FALSE
);
418 /* Run setup and reboot when done */
419 SwitchDesktop(WLSession
->ApplicationDesktop
);
422 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
428 DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
429 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, OptionOk
, &HardErrorResponse
);
433 /* Load and initialize gina */
434 if (!GinaInit(WLSession
))
436 ERR("WL: Failed to initialize Gina\n");
437 DialogBoxParam(hAppInstance
, MAKEINTRESOURCE(IDD_GINALOADFAILED
), GetDesktopWindow(), GinaLoadFailedWindowProc
, (LPARAM
)L
"");
438 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
442 DisplayStatusMessage(WLSession
, WLSession
->WinlogonDesktop
, IDS_REACTOSISSTARTINGUP
);
445 /* Connect to NetLogon service (lsass.exe) */
446 /* Real winlogon uses "Winlogon" */
447 RtlInitUnicodeString((PUNICODE_STRING
)&ProcessName
, L
"Winlogon");
448 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
449 if (Status
== STATUS_PORT_CONNECTION_REFUSED
)
451 /* Add the 'SeTcbPrivilege' privilege and try again */
452 Status
= RtlAdjustPrivilege(SE_TCB_PRIVILEGE
, TRUE
, TRUE
, &Old
);
453 if (!NT_SUCCESS(Status
))
455 ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status
));
458 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
460 if (!NT_SUCCESS(Status
))
462 ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status
));
466 RtlInitUnicodeString((PUNICODE_STRING
)&PackageName
, MICROSOFT_KERBEROS_NAME_W
);
467 Status
= LsaLookupAuthenticationPackage(LsaHandle
, &PackageName
, &AuthenticationPackage
);
468 if (!NT_SUCCESS(Status
))
470 ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status
));
471 LsaDeregisterLogonProcess(LsaHandle
);
476 /* Create a hidden window to get SAS notifications */
477 if (!InitializeSAS(WLSession
))
479 ERR("WL: Failed to initialize SAS\n");
483 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
484 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
486 /* Display logged out screen */
487 WLSession
->LogonStatus
= WKSTA_IS_LOGGED_OFF
;
488 RemoveStatusMessage(WLSession
);
489 PostMessageW(WLSession
->SASWindow
, WLX_WM_SAS
, WLX_SAS_TYPE_TIMEOUT
, 0);
491 /* Message loop for the SAS window */
492 while (GetMessageW(&Msg
, WLSession
->SASWindow
, 0, 0))
494 TranslateMessage(&Msg
);
495 DispatchMessageW(&Msg
);
498 /* We never go there */