updated an absolete comment
[reactos.git] / reactos / subsys / smss / initss.c
index e24035a..464cfe6 100644 (file)
 HANDLE hSmApiPort = (HANDLE) 0;\r
 \r
 \r
-/* TODO: this file should be totally rewritten\r
+/* TODO:\r
  *\r
  * a) look if a special option is set for smss.exe in\r
  *    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\r
+ */\r
+\r
+/**********************************************************************\r
+ *     SmpRegisterSmss/0\r
  *\r
- * b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
- *    (programmatically)\r
- *\r
- * d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as described\r
- *    in the registry key Required="Debug Windows"\r
- *    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\r
- *\r
- * e) make optional subsystems loadable (again: they must be described in the registry\r
- *    key Optional="Posix Os2" to be allowed to run)\r
+ * DESCRIPTION\r
+ *     Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
+ *     (programmatically). This also opens hSmApiPort to be used\r
+ *     in loading required subsystems.\r
  */\r
 \r
+static NTSTATUS\r
+SmpRegisterSmss(VOID)\r
+{\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+       UNICODE_STRING SbApiPortName = {0,0,NULL};\r
+\r
+       \r
+       DPRINT("SM: %s called\n",__FUNCTION__);\r
+\r
+       RtlInitUnicodeString (& SbApiPortName, L"");    \r
+       Status = SmConnectApiPort(& SbApiPortName,\r
+                                 (HANDLE) -1, /* SM has no SB port */\r
+                                 IMAGE_SUBSYSTEM_NATIVE,\r
+                                 & hSmApiPort);\r
+       if(!NT_SUCCESS(Status))\r
+       {\r
+               DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",\r
+                       __FUNCTION__,Status);\r
+               return Status;\r
+       }\r
+       DPRINT("SM self registered\n");\r
+       /*\r
+        * Note that you don't need to call complete session\r
+        * because connection handling code autocompletes\r
+        * the client structure for IMAGE_SUBSYSTEM_NATIVE.\r
+        */\r
+       return Status;\r
+}\r
+\r
+\r
 /**********************************************************************\r
+ *     SmpLoadKernelModeSubsystem/0\r
  */\r
-NTSTATUS\r
-SmLoadSubsystems(VOID)\r
+static NTSTATUS\r
+SmpLoadKernelModeSubsystem (VOID)\r
 {\r
-       SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
-       NTSTATUS                   Status = STATUS_SUCCESS;\r
-       WCHAR                      Data [MAX_PATH + 1];\r
-       ULONG                      DataLength = sizeof Data;\r
-       ULONG                      DataType = 0;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+       WCHAR     Data [MAX_PATH + 1];\r
+       ULONG     DataLength = sizeof Data;\r
+       ULONG     DataType = 0;\r
 \r
 \r
-       DPRINT("SM: loading subsystems\n");\r
\r
-       /* Load Kmode subsystem (aka win32k.sys) */\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
        Status = SmLookupSubsystem (L"Kmode",\r
                                    Data,\r
                                    & DataLength,\r
@@ -74,121 +102,101 @@ SmLoadSubsystems(VOID)
                                    TRUE);\r
        if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
        {\r
-               WCHAR ImagePath [MAX_PATH + 1] = {0};\r
+               WCHAR                      ImagePath [MAX_PATH + 1] = {0};\r
+               SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
 \r
                wcscpy (ImagePath, L"\\??\\");\r
                wcscat (ImagePath, Data);\r
                RtlZeroMemory (& ImageInfo, sizeof ImageInfo);\r
                RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);\r
                Status = NtSetSystemInformation(SystemLoadAndCallImage,\r
-                                         & ImageInfo,\r
-                                         sizeof ImageInfo);\r
+                                               & ImageInfo,\r
+                                               sizeof ImageInfo);\r
                if(!NT_SUCCESS(Status))\r
                {\r
-                       DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n",\r
-                               Status);\r
-                       return Status;\r
+                       DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",\r
+                               __FUNCTION__, Status);\r
                }\r
        }\r
-       /* TODO: load Required subsystems (Debug Windows) */\r
        return Status;\r
 }\r
 \r
-NTSTATUS\r
-SmRunCsrss(VOID)\r
+/**********************************************************************\r
+ *     SmpLoadRequiredSubsystems/0\r
+ */\r
+static NTSTATUS\r
+SmpLoadRequiredSubsystems (VOID)\r
 {\r
-  NTSTATUS Status;\r
-  UNICODE_STRING UnicodeString;\r
-  OBJECT_ATTRIBUTES ObjectAttributes;\r
-  RTL_PROCESS_INFO ProcessInfo;\r
-  HANDLE CsrssInitEvent;\r
-  WCHAR ImagePath [MAX_PATH];\r
-\r
-  DPRINT("SM: initializing csrss\n");\r
-\r
-  /* Run csrss.exe */\r
-  RtlRosInitUnicodeStringFromLiteral(&UnicodeString,\r
-                                 L"\\CsrssInitDone");\r
-  InitializeObjectAttributes(&ObjectAttributes,\r
-                            &UnicodeString,\r
-                            EVENT_ALL_ACCESS,\r
-                            0,\r
-                            NULL);\r
-  Status = NtCreateEvent(&CsrssInitEvent,\r
-                        EVENT_ALL_ACCESS,\r
-                        &ObjectAttributes,\r
-                        NotificationEvent,\r
-                        FALSE);\r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DbgPrint("Failed to create csrss notification event\n");\r
-    }\r
-\r
-  /*\r
-   * Start the Win32 subsystem (csrss.exe)\r
-   */\r
-\r
-  /* initialize executable path */\r
-  wcscpy(ImagePath, L"\\??\\");\r
-  wcscat(ImagePath, SharedUserData->NtSystemRoot);\r
-  wcscat(ImagePath, L"\\system32\\csrss.exe");\r
-\r
-  Status = SmCreateUserProcess(ImagePath,\r
-                               L"",\r
-                               FALSE, /* wait */\r
-                               NULL,\r
-                               FALSE, /* terminate */\r
-                               & ProcessInfo);\r
-  \r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);\r
-      return(Status);\r
-    }\r
-\r
-  Status = NtWaitForSingleObject(CsrssInitEvent,\r
-                       FALSE,\r
-                       NULL);\r
-\r
-  Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;\r
-\r
-  return Status;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+       WCHAR     Data [MAX_PATH + 1];\r
+       ULONG     DataLength = sizeof Data;\r
+       ULONG     DataType = 0;\r
+\r
+       \r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlZeroMemory (Data, DataLength);\r
+       Status = SmLookupSubsystem (L"Required",\r
+                                   Data,\r
+                                   & DataLength,\r
+                                   & DataType,\r
+                                   FALSE);\r
+       if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
+       {\r
+               PWCHAR Name = NULL;\r
+               ULONG Offset = 0;\r
+               \r
+               for (Name = Data; (Offset < DataLength); )\r
+               {\r
+                       if(L'\0' != *Name)\r
+                       {\r
+                               UNICODE_STRING Program;\r
+\r
+                               /* Run the current program */\r
+                               RtlInitUnicodeString (& Program, Name);\r
+                               Status = SmExecuteProgram (hSmApiPort, & Program);\r
+                               if(!NT_SUCCESS(Status))\r
+                               {\r
+                                       DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",\r
+                                               __FUNCTION__, Name, Status);\r
+                               }\r
+                               /* Look for the next program */\r
+                               while ((L'\0' != *Name) && (Offset < DataLength))\r
+                               {\r
+                                       ++ Name;\r
+                                       ++ Offset;\r
+                               }\r
+                       }\r
+                       ++ Name;\r
+                       ++ Offset;\r
+               }\r
+       }\r
+\r
+       return Status;\r
 }\r
 \r
+/**********************************************************************\r
+ *     SmLoadSubsystems/0\r
+ */\r
 NTSTATUS\r
-SmRunWinlogon(VOID)\r
+SmLoadSubsystems(VOID)\r
 {\r
-  NTSTATUS         Status = STATUS_SUCCESS;\r
-  RTL_PROCESS_INFO ProcessInfo;\r
-  WCHAR            ImagePath [MAX_PATH];\r
-\r
-  /*\r
-   * Start the logon process (winlogon.exe)\r
-   */\r
-\r
-  DPRINT("SM: starting winlogon\n");\r
-\r
-  /* initialize executable path */\r
-  wcscpy(ImagePath, L"\\??\\");\r
-  wcscat(ImagePath, SharedUserData->NtSystemRoot);\r
-  wcscat(ImagePath, L"\\system32\\winlogon.exe");\r
-\r
-  Status = SmCreateUserProcess(ImagePath,\r
-                               L"",\r
-                               FALSE, /* wait */\r
-                               NULL,\r
-                               FALSE, /* terminate */\r
-                               & ProcessInfo);\r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);\r
-      NtTerminateProcess(Children[CHILD_CSRSS], 0);\r
-      return(Status);\r
-    }\r
-\r
-  Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;\r
-\r
-  return Status;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+\r
+       \r
+       DPRINT("SM: loading subsystems\n");\r
+\r
+       /* SM self registers */\r
+       Status = SmpRegisterSmss();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* Load Kmode subsystem (aka win32k.sys) */\r
+       Status = SmpLoadKernelModeSubsystem();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* Load Required subsystems (Debug Windows) */\r
+       Status = SmpLoadRequiredSubsystems();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* done */\r
+       return Status;\r
 }\r
 \r
 /* EOF */\r