[WINLOGON]
[reactos.git] / reactos / base / system / winlogon / winlogon.c
index 245720c..3329848 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Winlogon
- * FILE:            services/winlogon/winlogon.c
+ * FILE:            base/system/winlogon/winlogon.c
  * PURPOSE:         Logon
  * PROGRAMMERS:     Thomas Weidenmueller (w3seek@users.sourceforge.net)
  *                  Filip Navara
@@ -9,11 +9,13 @@
  */
 
 /* INCLUDES *****************************************************************/
+
 #include "winlogon.h"
 
-//#define YDEBUG
 #include <wine/debug.h>
 
+WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
+
 /* GLOBALS ******************************************************************/
 
 HINSTANCE hAppInstance;
@@ -21,17 +23,104 @@ PWLSESSION WLSession = NULL;
 
 /* 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)
 {
-       HANDLE ServicesInitEvent;
        STARTUPINFOW StartupInfo;
        PROCESS_INFORMATION ProcessInformation;
-       DWORD Count;
        LPCWSTR ServiceString = L"services.exe";
        BOOL res;
 
        /* Start the service control manager (services.exe) */
+       ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
        StartupInfo.cb = sizeof(StartupInfo);
        StartupInfo.lpReserved = NULL;
        StartupInfo.lpDesktop = NULL;
@@ -59,219 +148,57 @@ StartServicesManager(VOID)
                return FALSE;
        }
 
-       /* Wait for event creation (by SCM) for max. 20 seconds */
-       for (Count = 0; Count < 20; Count++)
-       {
-               Sleep(1000);
-
-               TRACE("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
-               ServicesInitEvent = OpenEventW(
-                       SYNCHRONIZE,
-                       FALSE,
-                       L"SvcctrlStartEvent_A3725DX");
-               if (ServicesInitEvent)
-                       break;
-       }
+       TRACE("WL: Created new process - %S\n", ServiceString);
 
-       if (!ServicesInitEvent)
-       {
-               ERR("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
-               return FALSE;
-       }
+       CloseHandle(ProcessInformation.hThread);
+       CloseHandle(ProcessInformation.hProcess);
 
-       /* Wait for event signalization */
-       WaitForSingleObject(ServicesInitEvent, INFINITE);
-       CloseHandle(ServicesInitEvent);
        TRACE("WL: StartServicesManager() done.\n");
 
        return TRUE;
 }
 
-static BOOL
-StartCustomService(
-       IN LPCWSTR ServiceName)
-{
-       SC_HANDLE hSCManager = NULL;
-       SC_HANDLE hService = NULL;
-       BOOL ret = FALSE;
-
-       hSCManager = OpenSCManager(NULL, NULL, 0);
-       if (!hSCManager)
-               goto cleanup;
-
-       hService = OpenServiceW(hSCManager, ServiceName, SERVICE_START);
-       if (!hService)
-               goto cleanup;
-#if 0
-       if (!StartServiceW(hService, 0, NULL))
-               goto cleanup;
-#endif
-
-       ret = TRUE;
-
-cleanup:
-       if (hService)
-               CloseServiceHandle(hService);
-       if (hSCManager)
-               CloseServiceHandle(hSCManager);
-       return ret;
-}
 
 static BOOL
 StartLsass(VOID)
 {
-       HANDLE LsassInitEvent;
-
-       LsassInitEvent = CreateEventW(
-               NULL,
-               TRUE,
-               FALSE,
-               L"Global\\SECURITY_SERVICES_STARTED");
-       if (!LsassInitEvent)
-       {
-               ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError());
-               return FALSE;
-       }
-
-       /* Start the local security authority subsystem (Netlogon service) */
-       if (!StartCustomService(L"Netlogon"))
-       {
-               ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError());
-               return FALSE;
-       }
+       STARTUPINFOW StartupInfo;
+       PROCESS_INFORMATION ProcessInformation;
+       LPCWSTR ServiceString = L"lsass.exe";
+       BOOL res;
 
-#if 0
-       WaitForSingleObject(LsassInitEvent, INFINITE);
-#endif
-       CloseHandle(LsassInitEvent);
+       /* Start the service control manager (services.exe) */
+       ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
+       StartupInfo.cb = sizeof(StartupInfo);
+       StartupInfo.lpReserved = NULL;
+       StartupInfo.lpDesktop = NULL;
+       StartupInfo.lpTitle = NULL;
+       StartupInfo.dwFlags = 0;
+       StartupInfo.cbReserved2 = 0;
+       StartupInfo.lpReserved2 = 0;
 
-       return TRUE;
-}
+       TRACE("WL: Creating new process - %S\n", ServiceString);
 
-#if 0
-static BOOL
-OpenRegistryKey(
-       OUT HKEY *WinLogonKey)
-{
-   return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                                        L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
-                                        0,
-                                        KEY_QUERY_VALUE,
-                                        WinLogonKey);
-}
-#endif
+       res = CreateProcessW(
+               ServiceString,
+               NULL,
+               NULL,
+               NULL,
+               FALSE,
+               DETACHED_PROCESS,
+               NULL,
+               NULL,
+               &StartupInfo,
+               &ProcessInformation);
 
-#if 0
-static BOOL
-StartProcess(
-       IN PWCHAR ValueName)
-{
-   BOOL StartIt;
-   HKEY WinLogonKey;
-   DWORD Type;
-   DWORD Size;
-   DWORD StartValue;
-
-   StartIt = TRUE;
-   if (OpenRegistryKey(&WinLogonKey))
-     {
-       Size = sizeof(DWORD);
-       if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
-                                             ValueName,
-                                            NULL,
-                                            &Type,
-                                            (LPBYTE) &StartValue,
-                                             &Size))
-          {
-          if (REG_DWORD == Type)
-            {
-               StartIt = (0 != StartValue);
-            }
-          }
-       RegCloseKey(WinLogonKey);
-     }
-
-   return StartIt;
-}
-#endif
+       TRACE("WL: Created new process - %S\n", ServiceString);
 
-/*
-static BOOL RestartShell(
-       IN OUT PWLSESSION Session)
-{
-  HKEY WinLogonKey;
-  DWORD Type, Size, Value;
-
-  if(OpenRegistryKey(&WinLogonKey))
-  {
-    Size = sizeof(DWORD);
-    if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
-                                        L"AutoRestartShell",
-                                        NULL,
-                                        &Type,
-                                        (LPBYTE)&Value,
-                                        &Size))
-    {
-      if(Type == REG_DWORD)
-      {
-        RegCloseKey(WinLogonKey);
-        return (Value != 0);
-      }
-    }
-    RegCloseKey(WinLogonKey);
-  }
-  return FALSE;
-}
-*/
+       CloseHandle(ProcessInformation.hThread);
+       CloseHandle(ProcessInformation.hProcess);
 
-#if 0
-static PWCHAR
-GetUserInit(
-       OUT WCHAR *CommandLine,
-       IN DWORD BufferLength)
-{
-   HKEY WinLogonKey;
-   BOOL GotCommandLine;
-   DWORD Type;
-   DWORD Size;
-   WCHAR Shell[_MAX_PATH];
-
-   GotCommandLine = FALSE;
-   if (OpenRegistryKey(&WinLogonKey))
-     {
-       Size = MAX_PATH;
-       if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
-                                         L"UserInit",
-                                            NULL,
-                                            &Type,
-                                            (LPBYTE) Shell,
-                                         &Size))
-          {
-          if (REG_EXPAND_SZ == Type)
-            {
-               ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
-               GotCommandLine = TRUE;
-            }
-          else if (REG_SZ == Type)
-            {
-               wcscpy(CommandLine, Shell);
-               GotCommandLine = TRUE;
-            }
-          }
-       RegCloseKey(WinLogonKey);
-     }
-
-   if (! GotCommandLine)
-     {
-       GetSystemDirectory(CommandLine, MAX_PATH - 15);
-       wcscat(CommandLine, L"\\userinit.exe");
-     }
-
-   return CommandLine;
+       return res;
 }
 
-#endif
-
 BOOL
 DisplayStatusMessage(
        IN PWLSESSION Session,
@@ -360,7 +287,13 @@ WinMain(
        ULONG AuthenticationPackage;
        NTSTATUS Status;
 #endif
+       ULONG HardErrorResponse;
        MSG Msg;
+       HANDLE hThread;
+
+       UNREFERENCED_PARAMETER(hPrevInstance);
+       UNREFERENCED_PARAMETER(lpCmdLine);
+       UNREFERENCED_PARAMETER(nShowCmd);
 
        hAppInstance = hInstance;
 
@@ -370,70 +303,47 @@ WinMain(
                HandleShutdown(NULL, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
                NtShutdownSystem(ShutdownNoReboot);
                ExitProcess(0);
-               return 0;
        }
 
        WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION));
-       ZeroMemory(WLSession, sizeof(WLSESSION));
        if (!WLSession)
        {
                ERR("WL: Could not allocate memory for winlogon instance\n");
-               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
+               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
                ExitProcess(1);
-               return 1;
        }
+       ZeroMemory(WLSession, sizeof(WLSESSION));
        WLSession->DialogTimeout = 120; /* 2 minutes */
 
        if (!CreateWindowStationAndDesktops(WLSession))
        {
                ERR("WL: Could not create window station and desktops\n");
-               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
+               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
                ExitProcess(1);
-               return 1;
        }
        LockWorkstation(WLSession);
 
        if (!StartServicesManager())
        {
                ERR("WL: Could not start services.exe\n");
-               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
+               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse);
                ExitProcess(1);
-               return 1;
-       }
-
-       /* Check for pending setup */
-       if (GetSetupType() != 0)
-       {
-               TRACE("WL: Setup mode detected\n");
-
-               /* Set locale */
-               SetDefaultLanguage(FALSE);
-
-               /* Run setup and reboot when done */
-               SwitchDesktop(WLSession->ApplicationDesktop);
-               RunSetup();
-
-               HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
-               ExitProcess(0);
-               return 0;
        }
 
        if (!StartLsass())
        {
-               DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
-               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
+               ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
+               NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, OptionOk, &HardErrorResponse);
                ExitProcess(1);
-               return 1;
        }
 
        /* Load and initialize gina */
        if (!GinaInit(WLSession))
        {
                ERR("WL: Failed to initialize Gina\n");
-               DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)L"");
+               DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), GetDesktopWindow(), GinaLoadFailedWindowProc, (LPARAM)L"");
                HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
                ExitProcess(1);
-               return 1;
        }
 
        DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
@@ -475,7 +385,6 @@ WinMain(
        {
                ERR("WL: Failed to initialize SAS\n");
                ExitProcess(2);
-               return 2;
        }
 
        //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS);
@@ -484,7 +393,29 @@ WinMain(
        /* Display logged out screen */
        WLSession->LogonStatus = WKSTA_IS_LOGGED_OFF;
        RemoveStatusMessage(WLSession);
-       PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_TIMEOUT, 0);
+
+       /* Check for pending setup */
+       if (GetSetupType() != 0)
+       {
+               TRACE("WL: Setup mode detected\n");
+
+               /* Run setup and reboot when done */
+               SwitchDesktop(WLSession->ApplicationDesktop);
+               RunSetup();
+       }
+       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 | 1);
 
        /* Message loop for the SAS window */
        while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0))