2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/winlogon.c
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
8 * Hervé Poussineau (hpoussin@reactos.org)
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS ******************************************************************/
17 HINSTANCE hAppInstance
;
18 PWLSESSION WLSession
= NULL
;
20 /* FUNCTIONS *****************************************************************/
24 StartServicesManager(VOID
)
26 STARTUPINFOW StartupInfo
;
27 PROCESS_INFORMATION ProcessInformation
;
28 LPCWSTR ServiceString
= L
"services.exe";
31 /* Start the service control manager (services.exe) */
32 ZeroMemory(&StartupInfo
, sizeof(STARTUPINFOW
));
33 StartupInfo
.cb
= sizeof(StartupInfo
);
34 StartupInfo
.lpReserved
= NULL
;
35 StartupInfo
.lpDesktop
= NULL
;
36 StartupInfo
.lpTitle
= NULL
;
37 StartupInfo
.dwFlags
= 0;
38 StartupInfo
.cbReserved2
= 0;
39 StartupInfo
.lpReserved2
= 0;
41 TRACE("WL: Creating new process - %S\n", ServiceString
);
43 res
= CreateProcessW(ServiceString
,
55 ERR("WL: Failed to execute services (error %lu)\n", GetLastError());
59 TRACE("WL: Created new process - %S\n", ServiceString
);
61 CloseHandle(ProcessInformation
.hThread
);
62 CloseHandle(ProcessInformation
.hProcess
);
64 TRACE("WL: StartServicesManager() done.\n");
74 STARTUPINFOW StartupInfo
;
75 PROCESS_INFORMATION ProcessInformation
;
76 LPCWSTR ServiceString
= L
"lsass.exe";
79 /* Start the local security authority subsystem (lsass.exe) */
80 ZeroMemory(&StartupInfo
, sizeof(STARTUPINFOW
));
81 StartupInfo
.cb
= sizeof(StartupInfo
);
82 StartupInfo
.lpReserved
= NULL
;
83 StartupInfo
.lpDesktop
= NULL
;
84 StartupInfo
.lpTitle
= NULL
;
85 StartupInfo
.dwFlags
= 0;
86 StartupInfo
.cbReserved2
= 0;
87 StartupInfo
.lpReserved2
= 0;
89 TRACE("WL: Creating new process - %S\n", ServiceString
);
91 res
= CreateProcessW(ServiceString
,
100 &ProcessInformation
);
102 TRACE("WL: Created new process - %S\n", ServiceString
);
104 CloseHandle(ProcessInformation
.hThread
);
105 CloseHandle(ProcessInformation
.hProcess
);
118 hEvent
= CreateEventW(NULL
,
121 L
"LSA_RPC_SERVER_ACTIVE");
124 dwError
= GetLastError();
125 TRACE("WL: Failed to create the notication event (Error %lu)\n", dwError
);
127 if (dwError
== ERROR_ALREADY_EXISTS
)
129 hEvent
= OpenEventW(SYNCHRONIZE
,
131 L
"LSA_RPC_SERVER_ACTIVE");
134 ERR("WL: Could not open the notification event (Error %lu)\n", GetLastError());
140 TRACE("WL: Wait for the LSA server!\n");
141 WaitForSingleObject(hEvent
, INFINITE
);
142 TRACE("WL: LSA server running!\n");
150 InitKeyboardLayouts(VOID
)
152 WCHAR wszKeyName
[12], wszKLID
[10];
153 DWORD dwSize
= sizeof(wszKLID
), dwType
, i
= 1;
158 /* Open registry key with preloaded layouts */
159 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Preload", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
163 /* Read values with integer names only */
164 swprintf(wszKeyName
, L
"%d", i
++);
165 if (RegQueryValueExW(hKey
, wszKeyName
, NULL
, &dwType
, (LPBYTE
)wszKLID
, &dwSize
) != ERROR_SUCCESS
)
167 /* There is no more entries */
171 /* Only REG_SZ values are valid */
172 if (dwType
!= REG_SZ
)
174 ERR("Wrong type: %ws!\n", wszKLID
);
178 /* Load keyboard layout with given locale id */
179 Flags
= KLF_SUBSTITUTE_OK
;
181 Flags
|= KLF_NOTELLSHELL
|KLF_REPLACELANG
;
183 Flags
|= KLF_ACTIVATE
; // |0x40000000
184 if (!LoadKeyboardLayoutW(wszKLID
, Flags
))
186 ERR("LoadKeyboardLayoutW(%ws) failed!\n", wszKLID
);
191 /* We loaded at least one layout - success */
196 /* Close the key now */
200 WARN("RegOpenKeyExW(Keyboard Layout\\Preload) failed!\n");
204 /* If we failed, load US keyboard layout */
205 if (LoadKeyboardLayoutW(L
"00000409", 0x04090409))
214 DisplayStatusMessage(
215 IN PWLSESSION Session
,
219 WCHAR StatusMsg
[MAX_PATH
];
221 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
224 if (Session
->SuppressStatus
)
227 if (LoadStringW(hAppInstance
, ResourceId
, StatusMsg
, MAX_PATH
) == 0)
230 return Session
->Gina
.Functions
.WlxDisplayStatusMessage(Session
->Gina
.Context
, hDesktop
, 0, NULL
, StatusMsg
);
236 IN PWLSESSION Session
)
238 if (Session
->Gina
.Version
< WLX_VERSION_1_3
)
241 return Session
->Gina
.Functions
.WlxRemoveStatusMessage(Session
->Gina
.Context
);
248 GinaLoadFailedWindowProc(
258 switch (LOWORD(wParam
))
261 EndDialog(hwndDlg
, IDOK
);
270 WCHAR templateText
[MAX_PATH
], text
[MAX_PATH
];
272 len
= GetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, templateText
, MAX_PATH
);
275 wsprintfW(text
, templateText
, (LPWSTR
)lParam
);
276 SetDlgItemTextW(hwndDlg
, IDC_GINALOADFAILED
, text
);
279 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
285 EndDialog(hwndDlg
, IDCANCEL
);
297 IN HINSTANCE hInstance
,
298 IN HINSTANCE hPrevInstance
,
303 LSA_STRING ProcessName
, PackageName
;
305 LSA_OPERATIONAL_MODE Mode
;
307 ULONG AuthenticationPackage
;
310 ULONG HardErrorResponse
;
313 UNREFERENCED_PARAMETER(hPrevInstance
);
314 UNREFERENCED_PARAMETER(lpCmdLine
);
315 UNREFERENCED_PARAMETER(nShowCmd
);
317 hAppInstance
= hInstance
;
319 if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE
))
321 ERR("WL: Could not register logon process\n");
322 NtShutdownSystem(ShutdownNoReboot
);
326 WLSession
= (PWLSESSION
)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION
));
329 ERR("WL: Could not allocate memory for winlogon instance\n");
330 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
334 ZeroMemory(WLSession
, sizeof(WLSESSION
));
335 WLSession
->DialogTimeout
= 120; /* 2 minutes */
337 /* Initialize the dialog tracking list */
338 InitDialogListHead();
340 if (!CreateWindowStationAndDesktops(WLSession
))
342 ERR("WL: Could not create window station and desktops\n");
343 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
347 LockWorkstation(WLSession
);
349 /* Load default keyboard layouts */
350 if (!InitKeyboardLayouts())
352 ERR("WL: Could not preload keyboard layouts\n");
353 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
357 if (!StartServicesManager())
359 ERR("WL: Could not start services.exe\n");
360 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, NULL
, OptionOk
, &HardErrorResponse
);
366 ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
367 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
, 0, 0, 0, OptionOk
, &HardErrorResponse
);
371 /* Wait for the LSA server */
374 /* Load and initialize gina */
375 if (!GinaInit(WLSession
))
377 ERR("WL: Failed to initialize Gina\n");
378 DialogBoxParam(hAppInstance
, MAKEINTRESOURCE(IDD_GINALOADFAILED
), GetDesktopWindow(), GinaLoadFailedWindowProc
, (LPARAM
)L
"");
379 HandleShutdown(WLSession
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
383 DisplayStatusMessage(WLSession
, WLSession
->WinlogonDesktop
, IDS_REACTOSISSTARTINGUP
);
386 /* Connect to NetLogon service (lsass.exe) */
387 /* Real winlogon uses "Winlogon" */
388 RtlInitUnicodeString((PUNICODE_STRING
)&ProcessName
, L
"Winlogon");
389 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
390 if (Status
== STATUS_PORT_CONNECTION_REFUSED
)
392 /* Add the 'SeTcbPrivilege' privilege and try again */
393 Status
= RtlAdjustPrivilege(SE_TCB_PRIVILEGE
, TRUE
, TRUE
, &Old
);
394 if (!NT_SUCCESS(Status
))
396 ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status
));
400 Status
= LsaRegisterLogonProcess(&ProcessName
, &LsaHandle
, &Mode
);
403 if (!NT_SUCCESS(Status
))
405 ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status
));
409 RtlInitUnicodeString((PUNICODE_STRING
)&PackageName
, MICROSOFT_KERBEROS_NAME_W
);
410 Status
= LsaLookupAuthenticationPackage(LsaHandle
, &PackageName
, &AuthenticationPackage
);
411 if (!NT_SUCCESS(Status
))
413 ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status
));
414 LsaDeregisterLogonProcess(LsaHandle
);
419 /* Create a hidden window to get SAS notifications */
420 if (!InitializeSAS(WLSession
))
422 ERR("WL: Failed to initialize SAS\n");
426 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
427 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS);
429 /* Display logged out screen */
430 WLSession
->LogonState
= STATE_LOGGED_OFF
;
431 RemoveStatusMessage(WLSession
);
433 /* Check for pending setup */
434 if (GetSetupType() != 0)
436 TRACE("WL: Setup mode detected\n");
438 /* Run setup and reboot when done */
439 SwitchDesktop(WLSession
->ApplicationDesktop
);
443 PostMessageW(WLSession
->SASWindow
, WLX_WM_SAS
, WLX_SAS_TYPE_TIMEOUT
, 0);
445 /* Tell kernel that CurrentControlSet is good (needed
446 * to support Last good known configuration boot) */
447 NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED
| 1);
449 /* Message loop for the SAS window */
450 while (GetMessageW(&Msg
, WLSession
->SASWindow
, 0, 0))
452 TranslateMessage(&Msg
);
453 DispatchMessageW(&Msg
);
456 /* We never go there */