\r
\r
#include "smss.h"\r
+\r
#include <rosrtl/string.h>\r
\r
-//#define NDEBUG\r
+#define NDEBUG\r
#include <debug.h>\r
\r
-/* TODO: this file should be totally rewritten\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
- * 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
+ * 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
- 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
+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
- /* FIXME: load more subsystems (csrss!) */\r
\r
- return(Status);\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
-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
- 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
+ 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;\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
+ 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