/* FUNCTIONS *****************************************************************/
-DWORD
-WINAPI
-PlayLogonSoundThread(
- IN LPVOID lpParameter)
-{
- HKEY hKey;
- WCHAR szBuffer[MAX_PATH] = {0};
- WCHAR szDest[MAX_PATH];
- DWORD dwSize = sizeof(szBuffer);
- HMODULE hLibrary;
- SERVICE_STATUS_PROCESS Info;
- typedef BOOL (WINAPI *PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
- PLAYSOUNDW Play;
- ULONG Index = 0;
-
- if (RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
- {
- ExitThread(0);
- }
-
- if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szBuffer, &dwSize) != ERROR_SUCCESS)
- {
- RegCloseKey(hKey);
- ExitThread(0);
- }
-
-
- RegCloseKey(hKey);
-
- if (!szBuffer[0])
- ExitThread(0);
-
-
- szBuffer[MAX_PATH-1] = L'\0';
- if (ExpandEnvironmentStringsW(szBuffer, szDest, MAX_PATH))
- {
- SC_HANDLE hSCManager, hService;
-
- hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- if (!hSCManager)
- ExitThread(0);;
-
- hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
- if (!hService)
- {
- CloseServiceHandle(hSCManager);
- TRACE("WL: failed to open sysaudio Status %x\n", GetLastError());
- ExitThread(0);
- }
-
- do
- {
- if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
- {
- TRACE("WL: QueryServiceStatusEx failed %x\n", GetLastError());
- break;
- }
-
- if (Info.dwCurrentState == SERVICE_RUNNING)
- break;
-
- Sleep(1000);
-
- }while(Index++ < 20);
-
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCManager);
-
- if (Info.dwCurrentState != SERVICE_RUNNING)
- ExitThread(0);
-
-
- hLibrary = LoadLibraryW(L"winmm.dll");
- if (hLibrary)
- {
- Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
- if (Play)
- {
- Play(szDest, NULL, SND_FILENAME);
- }
- FreeLibrary(hLibrary);
- }
- }
- ExitThread(0);
-}
-
-
-
static BOOL
StartServicesManager(VOID)
{
LPCWSTR ServiceString = L"lsass.exe";
BOOL res;
- /* Start the service control manager (services.exe) */
+ /* Start the local security authority subsystem (lsass.exe) */
ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
return res;
}
+
+static VOID
+WaitForLsass(VOID)
+{
+ HANDLE hEvent;
+ DWORD dwError;
+
+ hEvent = CreateEventW(NULL,
+ TRUE,
+ FALSE,
+ L"LSA_RPC_SERVER_ACTIVE");
+ if (hEvent == NULL)
+ {
+ dwError = GetLastError();
+ TRACE("WL: Failed to create the notication event (Error %lu)\n", dwError);
+
+ if (dwError == ERROR_ALREADY_EXISTS)
+ {
+ hEvent = OpenEventW(SYNCHRONIZE,
+ FALSE,
+ L"LSA_RPC_SERVER_ACTIVE");
+ if (hEvent == NULL)
+ {
+ ERR("WL: Could not open the notification event (Error %lu)\n", GetLastError());
+ return;
+ }
+ }
+ }
+
+ TRACE("WL: Wait for the LSA server!\n");
+ WaitForSingleObject(hEvent, INFINITE);
+ TRACE("WL: LSA server running!\n");
+
+ CloseHandle(hEvent);
+}
+
+
+static BOOL
+InitKeyboardLayouts()
+{
+ WCHAR wszKeyName[12], wszKLID[10];
+ DWORD dwSize = sizeof(wszKLID), dwType, i = 1;
+ HKEY hKey;
+ UINT Flags;
+ BOOL bRet = FALSE;
+
+ /* Open registry key with preloaded layouts */
+ if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ while(TRUE)
+ {
+ /* Read values with integer names only */
+ swprintf(wszKeyName, L"%d", i++);
+ if (RegQueryValueExW(hKey, wszKeyName, NULL, &dwType, (LPBYTE)wszKLID, &dwSize) != ERROR_SUCCESS)
+ {
+ /* There is no more entries */
+ break;
+ }
+
+ /* Only REG_SZ values are valid */
+ if (dwType != REG_SZ)
+ {
+ ERR("Wrong type: %ws!\n", wszKLID);
+ continue;
+ }
+
+ /* Load keyboard layout with given locale id */
+ Flags = KLF_SUBSTITUTE_OK;
+ if (i > 1)
+ Flags |= KLF_NOTELLSHELL|KLF_REPLACELANG;
+ else // First layout
+ Flags |= KLF_ACTIVATE; // |0x40000000
+ if (!LoadKeyboardLayoutW(wszKLID, Flags))
+ {
+ ERR("LoadKeyboardLayoutW(%ws) failed!\n", wszKLID);
+ continue;
+ }
+ else
+ {
+ /* We loaded at least one layout - success */
+ bRet = TRUE;
+ }
+ }
+
+ /* Close the key now */
+ RegCloseKey(hKey);
+ }
+ else
+ WARN("RegOpenKeyExW(Keyboard Layout\\Preload) failed!\n");
+
+ if (!bRet)
+ {
+ /* If we failed, load US keyboard layout */
+ if (LoadKeyboardLayoutW(L"00000409", 0x04090409))
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+
BOOL
DisplayStatusMessage(
IN PWLSESSION Session,
#endif
ULONG HardErrorResponse;
MSG Msg;
- HANDLE hThread;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
{
ERR("WL: Could not register logon process\n");
- HandleShutdown(NULL, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0);
}
}
LockWorkstation(WLSession);
+ /* Load default keyboard layouts */
+ if (!InitKeyboardLayouts())
+ {
+ ERR("WL: Could not preload keyboard layouts\n");
+ NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
+ ExitProcess(1);
+ }
+
if (!StartServicesManager())
{
ERR("WL: Could not start services.exe\n");
DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
+
+ /* Wait for the LSA server */
+ WaitForLsass();
+
#if 0
/* Connect to NetLogon service (lsass.exe) */
/* Real winlogon uses "Winlogon" */
else
PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_TIMEOUT, 0);
- /* Play logon sound */
- hThread = CreateThread(NULL, 0, PlayLogonSoundThread, NULL, 0, NULL);
- if (hThread)
- {
- CloseHandle(hThread);
- }
-
/* Tell kernel that CurrentControlSet is good (needed
* to support Last good known configuration boot) */
- NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED);
+ NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1);
/* Message loop for the SAS window */
while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0))