-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initss.c - Load the subsystems\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-\r
-#include "smss.h"\r
-#include <rosrtl/string.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* TODO: this file should be totally rewritten\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
- * b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
- * (programmatically)\r
- *\r
- * c) make smss load win32k.sys as set in Kmode key\r
- * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\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
- */\r
-NTSTATUS\r
-SmLoadSubsystems(VOID)\r
-{\r
- SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
- NTSTATUS Status;\r
-\r
- DPRINT("SM: loading subsystems\n");\r
-\r
- /* Load kernel mode subsystem (aka win32k.sys) */\r
- RtlRosInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,\r
- L"\\SystemRoot\\system32\\win32k.sys");\r
-\r
- Status = NtSetSystemInformation(SystemLoadAndCallImage,\r
- &ImageInfo,\r
- sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));\r
-\r
- DPRINT("SMSS: Loaded win32k.sys (Status %lx)\n", Status);\r
-#if 0\r
- if (!NT_SUCCESS(Status))\r
- {\r
- return(Status);\r
- }\r
-#endif\r
-\r
- /* FIXME: load more subsystems (csrss!) */\r
-\r
- return(Status);\r
-}\r
-\r
-NTSTATUS\r
-SmRunCsrss(VOID)\r
-{\r
- NTSTATUS Status;\r
- UNICODE_STRING UnicodeString;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- PRTL_USER_PROCESS_PARAMETERS ProcessParameters;\r
- RTL_PROCESS_INFO ProcessInfo;\r
- HANDLE CsrssInitEvent;\r
- WCHAR UnicodeBuffer[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(UnicodeBuffer, L"\\??\\");\r
- wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);\r
- wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");\r
- RtlInitUnicodeString(&UnicodeString,\r
- UnicodeBuffer);\r
-\r
- RtlCreateProcessParameters(&ProcessParameters,\r
- &UnicodeString,\r
- NULL,\r
- NULL,\r
- NULL,\r
- SmSystemEnvironment,\r
- NULL,\r
- NULL,\r
- NULL,\r
- NULL);\r
-\r
- Status = RtlCreateUserProcess(&UnicodeString,\r
- OBJ_CASE_INSENSITIVE,\r
- ProcessParameters,\r
- NULL,\r
- NULL,\r
- NULL,\r
- FALSE,\r
- NULL,\r
- NULL,\r
- &ProcessInfo);\r
-\r
- RtlDestroyProcessParameters (ProcessParameters);\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
-}\r
-\r
-NTSTATUS\r
-SmRunWinlogon(VOID)\r
-{\r
- NTSTATUS Status;\r
- UNICODE_STRING UnicodeString;\r
- PRTL_USER_PROCESS_PARAMETERS ProcessParameters;\r
- RTL_PROCESS_INFO ProcessInfo;\r
- WCHAR UnicodeBuffer[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(UnicodeBuffer, L"\\??\\");\r
- wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);\r
- wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");\r
- RtlInitUnicodeString(&UnicodeString,\r
- UnicodeBuffer);\r
-\r
- RtlCreateProcessParameters(&ProcessParameters,\r
- &UnicodeString,\r
- NULL,\r
- NULL,\r
- NULL,\r
- SmSystemEnvironment,\r
- NULL,\r
- NULL,\r
- NULL,\r
- NULL);\r
-\r
- Status = RtlCreateUserProcess(&UnicodeString,\r
- OBJ_CASE_INSENSITIVE,\r
- ProcessParameters,\r
- NULL,\r
- NULL,\r
- NULL,\r
- FALSE,\r
- NULL,\r
- NULL,\r
- &ProcessInfo);\r
-\r
- RtlDestroyProcessParameters(ProcessParameters);\r
-\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);\r
- NtTerminateProcess(Children[CHILD_CSRSS],\r
- 0);\r
- return(Status);\r
- }\r
- Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;\r
-\r
- return Status;\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initss.c - Load the subsystems
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* SM handle for its own \SmApiPort */
+HANDLE hSmApiPort = (HANDLE) 0;
+
+
+/* TODO:
+ *
+ * a) look if a special option is set for smss.exe in
+ * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
+ */
+
+/**********************************************************************
+ * SmRegisterInternalSubsystem/3
+ *
+ * DESCRIPTION
+ * Register with itself for ImageSubsystemId
+ * (programmatically).
+ */
+NTSTATUS STDCALL SmRegisterInternalSubsystem (LPWSTR PgmName,
+ USHORT ImageSubsystemId,
+ PHANDLE ApiPort)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ RTL_USER_PROCESS_INFORMATION ProcessInfo;
+
+
+ DPRINT("SM: %s(%S,%d) called\n",__FUNCTION__, PgmName, ImageSubsystemId);
+
+ RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo);
+ ProcessInfo.Size = sizeof ProcessInfo;
+ ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId;
+ ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId;
+ DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n",
+ __FUNCTION__,ProcessInfo.ProcessHandle);
+ Status = SmCreateClient (& ProcessInfo, PgmName);
+ if (NT_SUCCESS(Status))
+ {
+ UNICODE_STRING SbApiPortName = {0,0,NULL};
+
+ RtlInitUnicodeString (& SbApiPortName, L"");
+ Status = SmConnectApiPort(& SbApiPortName,
+ (HANDLE) -1, /* internal SS have no SB port */
+ ImageSubsystemId,
+ ApiPort);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",
+ __FUNCTION__,Status);
+ return Status;
+ }
+ DPRINT("SM:%s: %S self registered\n", __FUNCTION__, PgmName);
+ }
+ else
+ {
+ DPRINT1("SM: %s: SmCreateClient(%S) failed (Status=0x%08lx)\n",
+ __FUNCTION__, PgmName, Status);
+ }
+ /*
+ * Note that you don't need to call complete session
+ * here because connection handling code autocompletes
+ * the client structure for IMAGE_SUBSYSTEM_NATIVE and
+ * -1.
+ */
+ return Status;
+}
+/**********************************************************************
+ * SmpLoadRequiredSubsystems/0
+ */
+static NTSTATUS
+SmpLoadRequiredSubsystems (VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ WCHAR Data [MAX_PATH + 1];
+ ULONG DataLength = sizeof Data;
+ ULONG DataType = 0;
+
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlZeroMemory (Data, DataLength);
+ Status = SmLookupSubsystem (L"Required",
+ Data,
+ & DataLength,
+ & DataType,
+ NULL);
+ if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
+ {
+ PWCHAR Name = NULL;
+ ULONG Offset = 0;
+
+ for (Name = Data; (Offset < DataLength); )
+ {
+ if(L'\0' != *Name)
+ {
+ UNICODE_STRING Program;
+
+ /* Run the current program */
+ RtlInitUnicodeString (& Program, Name);
+ Status = SmExecuteProgram (hSmApiPort, & Program);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",
+ __FUNCTION__, Name, Status);
+ }
+ /* Look for the next program */
+ while ((L'\0' != *Name) && (Offset < DataLength))
+ {
+ ++ Name;
+ ++ Offset;
+ }
+ }
+ ++ Name;
+ ++ Offset;
+ }
+ }
+
+ return Status;
+}
+
+/**********************************************************************
+ * SmLoadSubsystems/0
+ */
+NTSTATUS
+SmLoadSubsystems(VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+
+ DPRINT("SM: loading subsystems...\n");
+
+ /*
+ * SM self registers: this also opens hSmApiPort to be used
+ * in loading required subsystems.
+ */
+ Status = SmRegisterInternalSubsystem (L"Session Manager", IMAGE_SUBSYSTEM_NATIVE, & hSmApiPort);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: SmRegisterInternalSubsystem failed Status=%08lx\n", __FUNCTION__, Status);
+ return Status;
+ }
+ /* Load Required subsystems (Debug Windows) */
+ Status = SmpLoadRequiredSubsystems();
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: SmpLoadRequiredSubsystems failed Status=%08lx\n", __FUNCTION__, Status);
+ return Status;
+ }
+ /* done */
+ DPRINT("SM: done loading subsystems\n");
+ return Status;
+}
+
+/* EOF */