-/* $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
-\r
-#include <rosrtl/string.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* SM handle for its own \SmApiPort */\r
-HANDLE hSmApiPort = (HANDLE) 0;\r
-\r
-\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
- * 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
- RTL_PROCESS_INFO ProcessInfo;\r
-\r
- \r
- DPRINT("SM: %s called\n",__FUNCTION__);\r
- \r
- RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo);\r
- ProcessInfo.Size = sizeof ProcessInfo;\r
- ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId;\r
- ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId;\r
- DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n",\r
- __FUNCTION__,ProcessInfo.ProcessHandle);\r
- Status = SmCreateClient (& ProcessInfo, L"Session Manager");\r
- if (NT_SUCCESS(Status))\r
- {\r
- UNICODE_STRING SbApiPortName = {0,0,NULL};\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
- else\r
- {\r
- DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\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
-static NTSTATUS\r
-SmpLoadKernelModeSubsystem (VOID)\r
-{\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
- Status = SmLookupSubsystem (L"Kmode",\r
- Data,\r
- & DataLength,\r
- & DataType,\r
- TRUE);\r
- if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
- {\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
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- }\r
- return Status;\r
-}\r
-\r
-/**********************************************************************\r
- * SmpLoadRequiredSubsystems/0\r
- */\r
-static NTSTATUS\r
-SmpLoadRequiredSubsystems (VOID)\r
-{\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
-SmLoadSubsystems(VOID)\r
-{\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
+/* $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 */