update for HEAD-2003021201
[reactos.git] / subsys / system / winlogon / winlogon.c
index ebeb403..2b3da97 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <wchar.h>
 
-#define NDEBUG
+#define DBG
 #include <debug.h>
 
 /* GLOBALS ******************************************************************/
@@ -30,7 +30,7 @@ HDESK ScreenSaverDesktop;           /* WinSta0\Screen-Saver */
 
 /* FUNCTIONS *****************************************************************/
 
-void PrintString (char* fmt,...)
+static void PrintString (char* fmt,...)
 {
    char buffer[512];
    va_list ap;
@@ -43,7 +43,7 @@ void PrintString (char* fmt,...)
 }
 
 
-BOOLEAN StartServices(VOID)
+static BOOLEAN StartServices(VOID)
 {
    HANDLE ServicesInitEvent;
    BOOLEAN Result;
@@ -64,44 +64,56 @@ BOOLEAN StartServices(VOID)
    StartupInfo.cbReserved2 = 0;
    StartupInfo.lpReserved2 = 0;
    
+   PrintString("WL: Creating new process - \"services.exe\".\n");
+
    Result = CreateProcess(CommandLine,
-                         NULL,
-                         NULL,
-                         NULL,
-                         FALSE,
-                         DETACHED_PROCESS,
-                         NULL,
-                         NULL,
-                         &StartupInfo,
-                         &ProcessInformation);
+                          NULL,
+                          NULL,
+                          NULL,
+                          FALSE,
+                          DETACHED_PROCESS,
+                          NULL,
+                          NULL,
+                          &StartupInfo,
+                          &ProcessInformation);
    if (!Result)
      {
-       PrintString("WL: Failed to execute services\n");
-       return FALSE;
+        PrintString("WL: Failed to execute services\n");
+        return FALSE;
      }
    
    /* wait for event creation (by SCM) for max. 20 seconds */
    for (Count = 0; Count < 20; Count++)
      {
-       Sleep(1000);
+        Sleep(1000);
    
-       ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
-                                     FALSE,
-                                     "SvcctrlStartEvent_A3725DX");
-       if (ServicesInitEvent != NULL)
-         {
-            break;
-         }
+        //DbgPrint("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
+        ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
+                                      FALSE,
+                                      "SvcctrlStartEvent_A3725DX");
+        if (ServicesInitEvent != NULL)
+          {
+             break;
+          }
      }
    
+   if (ServicesInitEvent == NULL)
+     {
+        DbgPrint("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
+        return FALSE;
+     }
+
    /* wait for event signalization */
+   //DbgPrint("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
    WaitForSingleObject(ServicesInitEvent, INFINITE);
+   //DbgPrint("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
    CloseHandle(ServicesInitEvent);
+   DbgPrint("WL: StartServices() Done.\n");
       
    return TRUE;
 }
 
-BOOLEAN StartLsass(VOID)
+static BOOLEAN StartLsass(VOID)
 {
    HANDLE LsassInitEvent;
    BOOLEAN Result;
@@ -110,14 +122,14 @@ BOOLEAN StartLsass(VOID)
    CHAR CommandLine[MAX_PATH];
    
    LsassInitEvent = CreateEvent(NULL,
-                               TRUE,
-                               FALSE,
-                               "\\LsassInitDone");
+                                TRUE,
+                                FALSE,
+                                "\\LsassInitDone");
    
    if (LsassInitEvent == NULL)
      {
-       DbgPrint("Failed to create lsass notification event\n");
-       return(FALSE);
+        DbgPrint("WL: Failed to create lsass notification event\n");
+        return(FALSE);
      }
    
    /* Start the local security authority subsystem (lsass.exe) */
@@ -134,19 +146,19 @@ BOOLEAN StartLsass(VOID)
    StartupInfo.lpReserved2 = 0;
    
    Result = CreateProcess(CommandLine,
-                         NULL,
-                         NULL,
-                         NULL,
-                         FALSE,
-                         DETACHED_PROCESS,
-                         NULL,
-                         NULL,
-                         &StartupInfo,
-                         &ProcessInformation);
+                          NULL,
+                          NULL,
+                          NULL,
+                          FALSE,
+                          DETACHED_PROCESS,
+                          NULL,
+                          NULL,
+                          &StartupInfo,
+                          &ProcessInformation);
    if (!Result)
      {
-       DbgPrint("WL: Failed to execute lsass\n");
-       return(FALSE);
+        DbgPrint("WL: Failed to execute lsass\n");
+        return(FALSE);
      }
    
    DPRINT("WL: Waiting for lsass\n");
@@ -156,16 +168,94 @@ BOOLEAN StartLsass(VOID)
    return(TRUE);
 }
 
-VOID DoLoginUser(PCHAR Name, PCHAR Password)
+static BOOLEAN OpenRegistryKey(HANDLE *WinLogonKey)
+{
+   return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                                        _T("SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon"),
+                                        0,
+                                        KEY_QUERY_VALUE,
+                                        WinLogonKey);
+}
+
+static BOOLEAN StartProcess(PCHAR ValueName)
+{
+   BOOL StartIt;
+   HANDLE 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;
+}
+
+static PCHAR GetShell(PCHAR CommandLine)
+{
+   HANDLE WinLogonKey;
+   BOOL GotCommandLine;
+   DWORD Type;
+   DWORD Size;
+   CHAR Shell[_MAX_PATH];
+
+   GotCommandLine = FALSE;
+   if (OpenRegistryKey(&WinLogonKey))
+     {
+       Size = MAX_PATH;
+       if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
+                                             _T("Shell"),
+                                            NULL,
+                                            &Type,
+                                            (LPBYTE) Shell,
+                                             &Size))
+          {
+          if (REG_EXPAND_SZ == Type)
+            {
+               ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
+               GotCommandLine = TRUE;
+            }
+          else if (REG_SZ == Type)
+            {
+               strcpy(CommandLine, Shell);
+               GotCommandLine = TRUE;
+            }
+          }
+       RegCloseKey(WinLogonKey);
+     }
+
+   if (! GotCommandLine)
+     {
+       GetSystemDirectory(CommandLine, MAX_PATH - 10);
+       strcat(CommandLine, "\\shell.exe");
+     }
+
+   return CommandLine;
+}
+
+static BOOL DoLoginUser(PCHAR Name, PCHAR Password)
 {
    PROCESS_INFORMATION ProcessInformation;
    STARTUPINFO StartupInfo;
    BOOLEAN Result;
    CHAR CommandLine[MAX_PATH];
    CHAR CurrentDirectory[MAX_PATH];
-   
-   GetSystemDirectory(CommandLine, MAX_PATH);
-   strcat(CommandLine, "\\shell.exe");
 
    GetWindowsDirectory(CurrentDirectory, MAX_PATH);
 
@@ -177,31 +267,33 @@ VOID DoLoginUser(PCHAR Name, PCHAR Password)
    StartupInfo.cbReserved2 = 0;
    StartupInfo.lpReserved2 = 0;
    
-   Result = CreateProcess(CommandLine,
-                         NULL,
-                         NULL,
-                         NULL,
-                         FALSE,
-                         DETACHED_PROCESS,
-                         NULL,
-                         CurrentDirectory,
-                         &StartupInfo,
-                         &ProcessInformation);
+   Result = CreateProcess(NULL,
+                          GetShell(CommandLine),
+                          NULL,
+                          NULL,
+                          FALSE,
+                          DETACHED_PROCESS,
+                          NULL,
+                          CurrentDirectory,
+                          &StartupInfo,
+                          &ProcessInformation);
    if (!Result)
      {
-       DbgPrint("WL: Failed to execute user shell\n");
-       return;
+        DbgPrint("WL: Failed to execute user shell %s\n", CommandLine);
+        return FALSE;
      }
    WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
    CloseHandle( ProcessInformation.hProcess );
    CloseHandle( ProcessInformation.hThread );
+
+   return TRUE;
 }
 
 int STDCALL
 WinMain(HINSTANCE hInstance,
-       HINSTANCE hPrevInstance,
-       LPSTR lpCmdLine,
-       int nShowCmd)
+        HINSTANCE hPrevInstance,
+        LPSTR lpCmdLine,
+        int nShowCmd)
 {
 #if 0
   LSA_STRING ProcessName;
@@ -230,7 +322,7 @@ WinMain(HINSTANCE hInstance,
      CreateWindowStationW(L"WinSta0", 0, GENERIC_ALL, NULL);
    if (InteractiveWindowStation == NULL)
      {
-       DbgPrint("Failed to create window station (0x%X)\n", GetLastError());
+       DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError());
        NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
        ExitProcess(1);
      }
@@ -245,40 +337,40 @@ WinMain(HINSTANCE hInstance,
     */
    ApplicationDesktop = 
      CreateDesktopW(L"Default",
-                   NULL,
-                   NULL,
-                   0,      /* FIXME: Set some flags */
-                   GENERIC_ALL,
-                   NULL); 
+                    NULL,
+                    NULL,
+                    0,      /* FIXME: Set some flags */
+                    GENERIC_ALL,
+                    NULL); 
 
    /*
     * Create the winlogon desktop
     */
    WinlogonDesktop = CreateDesktopW(L"Winlogon",
-                                   NULL,
-                                   NULL,
-                                   0,      /* FIXME: Set some flags */
-                                   GENERIC_ALL,
-                                   NULL);  
+                                    NULL,
+                                    NULL,
+                                    0,      /* FIXME: Set some flags */
+                                    GENERIC_ALL,
+                                    NULL);  
    
    /*
     * Create the screen saver desktop
     */
    ScreenSaverDesktop = CreateDesktopW(L"Screen-Saver",
-                                      NULL,
-                                      NULL,
-                                      0,      /* FIXME: Set some flags */
-                                      GENERIC_ALL,
-                                      NULL);  
+                                       NULL,
+                                       NULL,
+                                       0,      /* FIXME: Set some flags */
+                                       GENERIC_ALL,
+                                       NULL);  
    
    /*
     * Switch to winlogon desktop
     */
    /* FIXME: Do start up in the application desktop for now. */
    Status = NtSetInformationProcess(NtCurrentProcess(),
-                                   ProcessDesktop,
-                                   &ApplicationDesktop,
-                                   sizeof(ApplicationDesktop));
+                                    ProcessDesktop,
+                                    &ApplicationDesktop,
+                                    sizeof(ApplicationDesktop));
    if (!NT_SUCCESS(Status))
      {
        DbgPrint("WL: Cannot set default desktop for winlogon.\n");
@@ -287,15 +379,27 @@ WinMain(HINSTANCE hInstance,
    Success = SwitchDesktop(ApplicationDesktop);
    if (!Success)
      {
-       DbgPrint("Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
+       DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
      }
    
    AllocConsole();
    SetConsoleTitle( "Winlogon" );
    /* start system processes (services.exe & lsass.exe) */
-   StartServices();
+   if (StartProcess("StartServices"))
+     {
+       if (!StartServices())
+         {
+            DbgPrint("WL: Failed to Start Services (0x%X)\n", GetLastError());
+         }
+     }
 #if 0
-   StartLsass();
+   if (StartProcess("StartLsass"))
+     {
+       if (!StartLsass())
+         {
+            DbgPrint("WL: Failed to Start Security System (0x%X)\n", GetLastError());
+         }
+     }
 #endif
    
    /* FIXME: What name does the real WinLogon use? */
@@ -304,8 +408,8 @@ WinMain(HINSTANCE hInstance,
    Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
    if (!NT_SUCCESS(Status))
      {
-       DbgPrint("WL: Failed to connect to lsass\n");
-       return(1);
+        DbgPrint("WL: Failed to connect to lsass\n");
+        return(1);
      }
 #endif
    
@@ -321,41 +425,44 @@ WinMain(HINSTANCE hInstance,
 #if 0
        /* Display login prompt */
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
-                   LoginPrompt,
-                   strlen(LoginPrompt),  // wcslen(LoginPrompt),
-                   &Result,
-                   NULL);
+                    LoginPrompt,
+                    strlen(LoginPrompt),  // wcslen(LoginPrompt),
+                    &Result,
+                    NULL);
        i = 0;
        do
-        {
-          ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
-                      &LoginName[i],
-                      1,
-                      &Result,
-                      NULL);
-          i++;
-        } while (LoginName[i - 1] != '\n');
+         {
+           ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+                       &LoginName[i],
+                       1,
+                       &Result,
+                       NULL);
+           i++;
+         } while (LoginName[i - 1] != '\n');
        LoginName[i - 1] = 0;
        
-       /* Display password prompt */
+        /* Display password prompt */
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
-                   PasswordPrompt,
-                   strlen(PasswordPrompt),  // wcslen(PasswordPrompt),
-                   &Result,
-                   NULL);
+                    PasswordPrompt,
+                    strlen(PasswordPrompt),  // wcslen(PasswordPrompt),
+                    &Result,
+                    NULL);
        i = 0;
        do
-        {
-          ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
-                      &Password[i],
-                      1,
-                      &Result,
-                      NULL);
-          i++;
-        } while (Password[i - 1] != '\n');
+         {
+           ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+                       &Password[i],
+                       1,
+                       &Result,
+                       NULL);
+           i++;
+         } while (Password[i - 1] != '\n');
        Password[i - 1] =0;
 #endif
-       DoLoginUser(LoginName, Password);
+       if (! DoLoginUser(LoginName, Password))
+         {
+           break;
+         }
      }
    
    ExitProcess(0);