Fixed creation of environment variable SystemDrive.
[reactos.git] / reactos / subsys / smss / init.c
index dde0591..929b9aa 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.19 2000/10/09 00:18:00 ekohl Exp $
+/* $Id: init.c,v 1.32 2002/03/18 22:44:42 hbirr Exp $
  *
  * init.c - Session Manager initialization
  * 
 
 #define NDEBUG
 
+/* TYPES ********************************************************************/
+
+/*
+ * NOTE: This is only used until the dos device links are
+ *       read from the registry!!
+ */
+typedef struct
+{
+   PWSTR DeviceName;
+   PWSTR LinkName;
+} LINKDATA, *PLINKDATA;
+
 /* GLOBAL VARIABLES *********************************************************/
 
 HANDLE SmApiPort = INVALID_HANDLE_VALUE;
 HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
 HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
 
-PVOID SmSystemEnvironment = NULL;
+PWSTR SmSystemEnvironment = NULL;
 
 
 /* FUNCTIONS ****************************************************************/
 
-#if 0
 static VOID
 SmCreatePagingFiles (VOID)
 {
-       UNICODE_STRING FileName;
-       ULONG ulCurrentSize;
-
-       /* FIXME: Read file names from registry */
+  UNICODE_STRING FileName;
+  LARGE_INTEGER InitialSize;
+  LARGE_INTEGER MaximumSize;
+  NTSTATUS Status;
+
+  /* FIXME: Read file names from registry */
+  
+  RtlInitUnicodeString (&FileName,
+                       L"\\SystemRoot\\pagefile.sys");
+
+  InitialSize.QuadPart = 50 * 4096;
+  MaximumSize.QuadPart = 80 * 4096;
+
+  Status = NtCreatePagingFile(&FileName,
+                             &InitialSize,
+                             &MaximumSize,
+                             0);
+  if (!NT_SUCCESS(Status))
+    {
+      PrintString("SM: Failed to create paging file (Status was 0x%.8X)\n", Status);
+    }
+}
 
-       RtlInitUnicodeString (&FileName,
-                             L"\\SystemRoot\\pagefile.sys");
 
-       NtCreatePagingFile (&FileName,
-                           50,
-                           80,
-                           &ulCurrentSize);
-}
+static VOID
+SmInitDosDevices(VOID)
+{
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING DeviceName;
+   UNICODE_STRING LinkName;
+   HANDLE LinkHandle;
+#if 0
+   HANDLE DeviceHandle;
+   IO_STATUS_BLOCK StatusBlock;
 #endif
+   NTSTATUS Status;
+   WCHAR LinkBuffer[80];
+   
+   PLINKDATA LinkPtr;
+   LINKDATA LinkData[] =
+       {{L"\\Device\\NamedPipe", L"PIPE"},
+        {L"\\Device\\Null", L"NUL"},
+        {L"\\Device\\Mup", L"UNC"},
+        {L"\\Device\\MailSlot", L"MAILSLOT"},
+        {L"\\DosDevices\\COM1", L"AUX"},
+        {L"\\DosDevices\\LPT1", L"PRN"},
+        {NULL, NULL}};
+   
+   /* FIXME: Read the list of symbolic links from the registry!! */
+   
+   LinkPtr = &LinkData[0];
+   while (LinkPtr->DeviceName != NULL)
+     {
+       swprintf(LinkBuffer, L"\\??\\%s",
+                LinkPtr->LinkName);
+       RtlInitUnicodeString(&LinkName,
+                            LinkBuffer);
+       RtlInitUnicodeString(&DeviceName,
+                            LinkPtr->DeviceName);
+   
+#if 0
+       /* check if target device exists (can be opened) */
+       InitializeObjectAttributes(&ObjectAttributes,
+                                  &DeviceName,
+                                  0,
+                                  NULL,
+                                  NULL);
+   
+       Status = NtOpenFile(&DeviceHandle,
+                           0x10001,
+                           &ObjectAttributes,
+                           &StatusBlock,
+                           1,
+                           FILE_SYNCHRONOUS_IO_NONALERT);
+       if (NT_SUCCESS(Status))
+         {
+            NtClose(DeviceHandle);
+#endif
+            /* create symbolic link */
+            InitializeObjectAttributes(&ObjectAttributes,
+                                       &LinkName,
+                                       OBJ_PERMANENT,
+                                       NULL,
+                                       NULL);
+   
+            Status = NtCreateSymbolicLinkObject(&LinkHandle,
+                                                SYMBOLIC_LINK_ALL_ACCESS,
+                                                &ObjectAttributes,
+                                                &DeviceName);
+            if (!NT_SUCCESS(Status))
+              {
+                 PrintString("SM: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
+                             &LinkName,
+                             &DeviceName);
+              }
+            NtClose(LinkHandle);
+#if 0
+         }
+#endif
+       LinkPtr++;
+     }
+}
 
 
 static VOID
@@ -110,6 +209,8 @@ SmSetEnvironmentVariables (VOID)
        /* Set "SystemDrive = C:" */
        RtlInitUnicodeString (&EnvVariable,
                              L"SystemDrive");
+       RtlInitUnicodeString (&EnvValue,
+                             ValueBuffer);
        RtlSetEnvironmentVariable (&SmSystemEnvironment,
                                   &EnvVariable,
                                   &EnvValue);
@@ -163,50 +264,79 @@ SmSetEnvironmentVariables (VOID)
 
 BOOL InitSessionManager (HANDLE        Children[])
 {
-   NTSTATUS Status;
-   UNICODE_STRING UnicodeString;
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   UNICODE_STRING CmdLineW;
-   UNICODE_STRING CurrentDirectoryW;
-   PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
-   RTL_USER_PROCESS_INFO ProcessInfo;
-   HANDLE CsrssInitEvent;
-   
-   /* Create the "\SmApiPort" object (LPC) */
-   RtlInitUnicodeString (&UnicodeString,
-                        L"\\SmApiPort");
-   InitializeObjectAttributes (&ObjectAttributes,
-                              &UnicodeString,
-                              0xff,
-                              NULL,
-                              NULL);
-   
-   Status = NtCreatePort (&SmApiPort,
-                         &ObjectAttributes,
-                         0,
-                         0,
-                         0);
+  NTSTATUS Status;
+  UNICODE_STRING UnicodeString;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING CmdLineW;
+  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+  RTL_PROCESS_INFO ProcessInfo;
+  HANDLE CsrssInitEvent;
+  HANDLE WindowsDirectory;
+  WCHAR UnicodeBuffer[MAX_PATH];
+  PKUSER_SHARED_DATA SharedUserData = 
+    (PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
+
+  /*
+   * FIXME: The '\Windows' directory is created by csrss.exe but
+   *        win32k.sys needs it at intialization and it is loaded
+   *        before csrss.exe
+   */
+
+  /*
+   * Create the '\Windows' directory
+   */
+  RtlInitUnicodeString(&UnicodeString,
+                      L"\\Windows");
+
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &UnicodeString,
+                            0,
+                            NULL,
+                            NULL);
+
+  Status = ZwCreateDirectoryObject(&WindowsDirectory,
+                                  0,
+                                  &ObjectAttributes);
+  if (!NT_SUCCESS(Status))
+    {
+      DisplayString(L"SM: Could not create \\Windows directory!\n");
+      return FALSE;
+    }
+
+  /* Create the "\SmApiPort" object (LPC) */
+  RtlInitUnicodeString(&UnicodeString,
+                      L"\\SmApiPort");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &UnicodeString,
+                            PORT_ALL_ACCESS,
+                            NULL,
+                            NULL);
+
+  Status = NtCreatePort(&SmApiPort,
+                       &ObjectAttributes,
+                       0,
+                       0,
+                       0);
+  if (!NT_SUCCESS(Status))
+    {
+      return FALSE;
+    }
 
-   if (!NT_SUCCESS(Status))
-     {
-       return FALSE;
-     }
-   
 #ifndef NDEBUG
-   DisplayString (L"SM: \\SmApiPort created...\n");
+  DisplayString (L"SM: \\SmApiPort created...\n");
 #endif
-   
-   /* Create two threads for "\SmApiPort" */
-   RtlCreateUserThread (NtCurrentProcess (),
-                       NULL,
-                       FALSE,
-                       0,
-                       NULL,
-                       NULL,
-                       (PTHREAD_START_ROUTINE)SmApiThread,
-                       (PVOID)SmApiPort,
-                       NULL,
-                       NULL);
+
+  /* Create two threads for "\SmApiPort" */
+  RtlCreateUserThread(NtCurrentProcess(),
+                     NULL,
+                     FALSE,
+                     0,
+                     NULL,
+                     NULL,
+                     (PTHREAD_START_ROUTINE)SmApiThread,
+                     (PVOID)SmApiPort,
+                     NULL,
+                     NULL);
 
    RtlCreateUserThread (NtCurrentProcess (),
                        NULL,
@@ -218,210 +348,205 @@ BOOL InitSessionManager (HANDLE Children[])
                        (PVOID)SmApiPort,
                        NULL,
                        NULL);
-   
-   /* Create the system environment */
-   Status = RtlCreateEnvironment (TRUE,
-                                 &SmSystemEnvironment);
-   if (!NT_SUCCESS(Status))
-     return FALSE;
+
+  /* Create the system environment */
+  Status = RtlCreateEnvironment(FALSE,
+                               &SmSystemEnvironment);
+  if (!NT_SUCCESS(Status))
+    {
+      return FALSE;
+    }
 #ifndef NDEBUG
-   DisplayString (L"SM: System Environment created\n");
+  DisplayString (L"SM: System Environment created\n");
 #endif
 
-   /* FIXME: Define symbolic links to kernel devices (MS-DOS names) */
-   
-   /* FIXME: Run all programs in the boot execution list */
-   
-   /* FIXME: Process the file rename list */
-   
-   /* FIXME: Load the well known DLLs */
-   
-#if 0
-   /* Create paging files */
-   SmCreatePagingFiles ();
-#endif
-   
-   /* Load remaining registry hives */
-   NtInitializeRegistry (FALSE);
-   
-   /* Set environment variables from registry */
-   SmSetEnvironmentVariables ();
+  /* Define symbolic links to kernel devices (MS-DOS names) */
+  SmInitDosDevices();
 
-   /* Load the kernel mode driver win32k.sys */
-   RtlInitUnicodeString (&CmdLineW,
-                        L"\\SystemRoot\\system32\\drivers\\win32k.sys");
-   Status = NtLoadDriver (&CmdLineW);
-   
-   if (!NT_SUCCESS(Status))
-     {
-       return FALSE;
-     }
-   
-   /* Run csrss.exe */
-   RtlInitUnicodeString(&UnicodeString,
-                       L"\\CsrssInitDone");
-   InitializeObjectAttributes(&ObjectAttributes,
-                             &UnicodeString,
-                             EVENT_ALL_ACCESS,
-                             0,
-                             NULL);
-   Status = NtCreateEvent(&CsrssInitEvent,
-                         EVENT_ALL_ACCESS,
-                         &ObjectAttributes,
-                         TRUE,
-                         FALSE);
-   if (!NT_SUCCESS(Status))
-     {
-       DbgPrint("Failed to create csrss notification event\n");
-     }
-   
-   /* Start the Win32 subsystem (csrss.exe) */
-   DisplayString (L"SM: Executing csrss.exe\n");
-   
-   RtlInitUnicodeString (&UnicodeString,
-                        L"\\??\\C:\\reactos\\system32\\csrss.exe");
-   
-   /* initialize current directory */
-   RtlInitUnicodeString (&CurrentDirectoryW,
-                        L"C:\\reactos\\system32\\");
-   
-   RtlCreateProcessParameters (&ProcessParameters,
-                              &UnicodeString,
-                              NULL,
-                              &CurrentDirectoryW,
-                              NULL,
-                              SmSystemEnvironment,
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL);
-
-   Status = RtlCreateUserProcess (&UnicodeString,
-                                 0,
-                                 ProcessParameters,
-                                 NULL,
-                                 NULL,
-                                 FALSE,
-                                 0,
-                                 0,
-                                 0,
-                                 &ProcessInfo);
-   
-   RtlDestroyProcessParameters (ProcessParameters);
-   
-   if (!NT_SUCCESS(Status))
-     {
-       DisplayString (L"SM: Loading csrss.exe failed!\n");
-       return FALSE;
-     }
-   
-   DbgPrint("SM: Waiting for csrss\n");
-   NtWaitForSingleObject(CsrssInitEvent,
-                        FALSE,
-                        NULL);
-   DbgPrint("SM: Finished waiting for csrss\n");
-   
-   Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
+  /* FIXME: Run all programs in the boot execution list */
+//  SmRunBootApps();
 
+  /* FIXME: Process the file rename list */
+//  SmProcessFileRenameList();
 
-       /* Start the simple shell (shell.exe) */
-       DisplayString (L"SM: Executing shell\n");
-       RtlInitUnicodeString (&UnicodeString,
-                             L"\\??\\C:\\reactos\\system32\\shell.exe");
-#if 0
-       /* Start the logon process (winlogon.exe) */
-       DisplayString (L"SM: Running winlogon\n");
-       RtlInitUnicodeString (&UnicodeString,
-                             L"\\??\\C:\\reactos\\system32\\winlogon.exe");
-#endif
+  /* FIXME: Load the well known DLLs */
+//  SmPreloadDlls();
+
+  /* Create paging files */
+  SmCreatePagingFiles();
 
-       /* initialize current directory (trailing backslash!!)*/
-       RtlInitUnicodeString (&CurrentDirectoryW,
-                             L"C:\\reactos\\");
-
-       RtlCreateProcessParameters (&ProcessParameters,
-                                   &UnicodeString,
-                                   NULL,
-                                   &CurrentDirectoryW,
-                                   NULL,
-                                   SmSystemEnvironment,
-                                   NULL,
-                                   NULL,
-                                   NULL,
-                                   NULL);
-
-
-       Status = RtlCreateUserProcess (&UnicodeString,
-                                      0,
-                                      ProcessParameters,
-                                      NULL,
-                                      NULL,
-                                      FALSE,
-                                      0,
-                                      0,
-                                      0,
-                                      &ProcessInfo);
-
-       RtlDestroyProcessParameters (ProcessParameters);
-
-       if (!NT_SUCCESS(Status))
-       {
-               DisplayString (L"SM: Loading shell.exe failed!\n");
+  /* Load remaining registry hives */
+  NtInitializeRegistry(FALSE);
+
+  /* Set environment variables from registry */
+  SmSetEnvironmentVariables();
+
+  /* Load the kernel mode driver win32k.sys */
+  RtlInitUnicodeString(&CmdLineW,
+                      L"\\SystemRoot\\system32\\drivers\\win32k.sys");
+  Status = NtLoadDriver(&CmdLineW);
 #if 0
-               NtTerminateProcess (Children[CHILD_CSRSS],
-                                   0);
+  if (!NT_SUCCESS(Status))
+    {
+      return FALSE;
+    }
 #endif
-               return FALSE;
-       }
-       Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
-
-       /* Create the \DbgSsApiPort object (LPC) */
-       RtlInitUnicodeString (&UnicodeString,
-                             L"\\DbgSsApiPort");
-       InitializeObjectAttributes (&ObjectAttributes,
-                                   &UnicodeString,
-                                   0xff,
-                                   NULL,
-                                   NULL);
-
-       Status = NtCreatePort (&DbgSsApiPort,
-                              &ObjectAttributes,
-                              0,
-                              0,
-                              0);
-
-       if (!NT_SUCCESS(Status))
-       {
-               return FALSE;
-       }
+
+  /* Run csrss.exe */
+  RtlInitUnicodeString(&UnicodeString,
+                      L"\\CsrssInitDone");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &UnicodeString,
+                            EVENT_ALL_ACCESS,
+                            0,
+                            NULL);
+  Status = NtCreateEvent(&CsrssInitEvent,
+                        EVENT_ALL_ACCESS,
+                        &ObjectAttributes,
+                        TRUE,
+                        FALSE);
+  if (!NT_SUCCESS(Status))
+    {
+      DbgPrint("Failed to create csrss notification event\n");
+    }
+
+  /*
+   * Start the Win32 subsystem (csrss.exe)
+   */
+
+  /* initialize executable path */
+  wcscpy(UnicodeBuffer, L"\\??\\");
+  wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
+  wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
+  RtlInitUnicodeString(&UnicodeString,
+                      UnicodeBuffer);
+
+  RtlCreateProcessParameters(&ProcessParameters,
+                            &UnicodeString,
+                            NULL,
+                            NULL,
+                            NULL,
+                            SmSystemEnvironment,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+
+  Status = RtlCreateUserProcess(&UnicodeString,
+                               OBJ_CASE_INSENSITIVE,
+                               ProcessParameters,
+                               NULL,
+                               NULL,
+                               NULL,
+                               FALSE,
+                               NULL,
+                               NULL,
+                               &ProcessInfo);
+
+  RtlDestroyProcessParameters (ProcessParameters);
+
+  if (!NT_SUCCESS(Status))
+    {
+      DisplayString(L"SM: Loading csrss.exe failed!\n");
+      return FALSE;
+    }
+
+  NtWaitForSingleObject(CsrssInitEvent,
+                       FALSE,
+                       NULL);
+
+  Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
+
+  /*
+   * Start the logon process (winlogon.exe)
+   */
+
+  /* initialize executable path */
+  wcscpy(UnicodeBuffer, L"\\??\\");
+  wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
+  wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
+  RtlInitUnicodeString(&UnicodeString,
+                      UnicodeBuffer);
+
+  RtlCreateProcessParameters(&ProcessParameters,
+                            &UnicodeString,
+                            NULL,
+                            NULL,
+                            NULL,
+                            SmSystemEnvironment,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+
+  Status = RtlCreateUserProcess(&UnicodeString,
+                               OBJ_CASE_INSENSITIVE,
+                               ProcessParameters,
+                               NULL,
+                               NULL,
+                               NULL,
+                               FALSE,
+                               NULL,
+                               NULL,
+                               &ProcessInfo);
+
+  RtlDestroyProcessParameters(ProcessParameters);
+
+  if (!NT_SUCCESS(Status))
+    {
+      DisplayString(L"SM: Loading winlogon.exe failed!\n");
+      NtTerminateProcess(Children[CHILD_CSRSS],
+                        0);
+      return FALSE;
+    }
+  Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
+
+  /* Create the \DbgSsApiPort object (LPC) */
+  RtlInitUnicodeString(&UnicodeString,
+                      L"\\DbgSsApiPort");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &UnicodeString,
+                            PORT_ALL_ACCESS,
+                            NULL,
+                            NULL);
+
+  Status = NtCreatePort(&DbgSsApiPort,
+                       &ObjectAttributes,
+                       0,
+                       0,
+                       0);
+
+  if (!NT_SUCCESS(Status))
+    {
+      return FALSE;
+    }
 #ifndef NDEBUG
-       DisplayString (L"SM: DbgSsApiPort created...\n");
+  DisplayString(L"SM: DbgSsApiPort created...\n");
 #endif
 
-       /* Create the \DbgUiApiPort object (LPC) */
-       RtlInitUnicodeString (&UnicodeString,
-                             L"\\DbgUiApiPort");
-       InitializeObjectAttributes (&ObjectAttributes,
-                                   &UnicodeString,
-                                   0xff,
-                                   NULL,
-                                   NULL);
-
-       Status = NtCreatePort (&DbgUiApiPort,
-                              &ObjectAttributes,
-                              0,
-                              0,
-                              0);
-
-       if (!NT_SUCCESS(Status))
-       {
-               return FALSE;
-       }
+  /* Create the \DbgUiApiPort object (LPC) */
+  RtlInitUnicodeString(&UnicodeString,
+                      L"\\DbgUiApiPort");
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &UnicodeString,
+                            PORT_ALL_ACCESS,
+                            NULL,
+                            NULL);
+
+  Status = NtCreatePort(&DbgUiApiPort,
+                       &ObjectAttributes,
+                       0,
+                       0,
+                       0);
+  if (!NT_SUCCESS(Status))
+    {
+      return FALSE;
+    }
 #ifndef NDEBUG
-       DisplayString (L"SM: DbgUiApiPort created...\n");
+  DisplayString (L"SM: DbgUiApiPort created...\n");
 #endif
 
-       return TRUE;
+  return TRUE;
 }
 
 /* EOF */