Kmode subsystem no more hardwired.
authorEmanuele Aliberti <ea@iol.it>
Wed, 2 Mar 2005 22:09:53 +0000 (22:09 +0000)
committerEmanuele Aliberti <ea@iol.it>
Wed, 2 Mar 2005 22:09:53 +0000 (22:09 +0000)
svn path=/trunk/; revision=13800

reactos/subsys/smss/initss.c
reactos/subsys/smss/smapiexec.c
reactos/subsys/smss/smss.h

index 1208592..e24035a 100644 (file)
 #define NDEBUG\r
 #include <debug.h>\r
 \r
+/* SM handle for its own \SmApiPort */\r
+HANDLE hSmApiPort = (HANDLE) 0;\r
+\r
+\r
 /* TODO: this file should be totally rewritten\r
  *\r
  * a) look if a special option is set for smss.exe in\r
@@ -40,9 +44,6 @@
  * 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
 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
+       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
 \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
+       DPRINT("SM: loading subsystems\n");\r
\r
+       /* Load Kmode subsystem (aka win32k.sys) */\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
+\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: loading Kmode failed (Status=0x%08lx)\n",\r
+                               Status);\r
+                       return Status;\r
+               }\r
+       }\r
+       /* TODO: load Required subsystems (Debug Windows) */\r
+       return Status;\r
 }\r
 \r
 NTSTATUS\r
index d2faac8..7bbf642 100644 (file)
@@ -1,13 +1,29 @@
-/* $Id$\r
+/* $Id$\r
  *\r
  * smapiexec.c - SM_API_EXECUTE_PROGRAM\r
  *\r
  * Reactos Session Manager\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
 #include "smss.h"\r
-#include <rosrtl/string.h>\r
 \r
 #define NDEBUG\r
 #include <debug.h>\r
@@ -99,15 +115,205 @@ SmCreateUserProcess (LPWSTR ImagePath,
        return STATUS_SUCCESS;\r
 }\r
 \r
+/**********************************************************************\r
+ * NAME\r
+ *     SmLookupSubsystem/5\r
+ *\r
+ * DESCRIPTION\r
+ *     Read from the registry key\r
+ *     \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems\r
+ *     the value which name is Name.\r
+ *\r
+ * ARGUMENTS\r
+ *     Name: name of the program to run, that is a value's name in\r
+ *           the SM registry key Subsystems;\r
+ *     Data: what the registry gived back for Name;\r
+ *     DataLength: how much Data the registry retruns;\r
+ *     DataType: what is Data?\r
+ *     Expand: set it TRUE if you want this function to use the env\r
+ *           to possibly expand Data before giving it back.\r
+ */\r
+NTSTATUS STDCALL\r
+SmLookupSubsystem (IN     PWSTR   Name,\r
+                  IN OUT PWSTR   Data,\r
+                  IN OUT PULONG  DataLength,\r
+                  IN OUT PULONG  DataType,\r
+                  IN     BOOLEAN Expand)\r
+{\r
+       NTSTATUS           Status = STATUS_SUCCESS;\r
+       UNICODE_STRING     usKeyName = {0};\r
+       OBJECT_ATTRIBUTES  Oa = {0};\r
+       HANDLE             hKey = (HANDLE) 0;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+       /*\r
+        * Prepare the key name to scan and\r
+        * related object attributes.\r
+        */\r
+       RtlInitUnicodeString (& usKeyName,\r
+               L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");\r
+\r
+       InitializeObjectAttributes (& Oa,\r
+                                   & usKeyName,\r
+                                   OBJ_CASE_INSENSITIVE,\r
+                                   NULL,\r
+                                   NULL);\r
+       /*\r
+        * Open the key. This MUST NOT fail, if the\r
+        * request is for a legitimate subsystem.\r
+        */\r
+       Status = NtOpenKey (& hKey,\r
+                             MAXIMUM_ALLOWED,\r
+                             & Oa);\r
+       if(NT_SUCCESS(Status))\r
+       {\r
+               UNICODE_STRING usValueName = {0};\r
+               WCHAR          KeyValueInformation [1024] = {L'\0'};\r
+               ULONG          ResultLength = 0L;\r
+               PKEY_VALUE_PARTIAL_INFORMATION\r
+                              kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;\r
+\r
+               \r
+               RtlInitUnicodeString (& usValueName, Name);\r
+               Status = NtQueryValueKey (hKey,\r
+                                         & usValueName,\r
+                                         KeyValuePartialInformation,\r
+                                         KeyValueInformation,\r
+                                         sizeof KeyValueInformation,\r
+                                         & ResultLength);\r
+               if(NT_SUCCESS(Status))\r
+               {\r
+                       DPRINT("nkvpi.TitleIndex = %ld\n", kvpi->TitleIndex);\r
+                       DPRINT("kvpi.Type        = %ld\n", kvpi->Type);\r
+                       DPRINT("kvpi.DataLength  = %ld\n", kvpi->DataLength);\r
+\r
+                       if((NULL != Data) && (NULL != DataLength) && (NULL != DataType))\r
+                       {\r
+                               *DataType = kvpi->Type;\r
+                               if((Expand) && (REG_EXPAND_SZ == *DataType))\r
+                               {\r
+                                       UNICODE_STRING Source;\r
+                                       WCHAR          DestinationBuffer [2048] = {0};\r
+                                       UNICODE_STRING Destination;\r
+                                       ULONG          Length = 0;\r
+\r
+                                       DPRINT("SM: %s: value will be expanded\n", __FUNCTION__);\r
+\r
+                                       Source.Length        = kvpi->DataLength;\r
+                                       Source.MaximumLength = kvpi->DataLength;\r
+                                       Source.Buffer        = (PWCHAR) & kvpi->Data;\r
+\r
+                                       Destination.Length        = 0;\r
+                                       Destination.MaximumLength = sizeof DestinationBuffer;\r
+                                       Destination.Buffer        = DestinationBuffer;\r
+\r
+                                       Status = RtlExpandEnvironmentStrings_U (SmSystemEnvironment,\r
+                                                                               & Source,\r
+                                                                               & Destination,\r
+                                                                               & Length);\r
+                                       if(NT_SUCCESS(Status))\r
+                                       {\r
+                                               *DataLength = min(*DataLength, Destination.Length);\r
+                                               RtlCopyMemory (Data, Destination.Buffer, *DataLength);                          \r
+                                       }\r
+                                                       \r
+                               }else{\r
+                                       DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__);\r
+                                       *DataLength = min(*DataLength, kvpi->DataLength);\r
+                                       RtlCopyMemory (Data, & kvpi->Data, *DataLength);\r
+                               }\r
+                               *DataType = kvpi->Type;\r
+                       }else{\r
+                               DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__);\r
+                               Status = STATUS_INVALID_PARAMETER;\r
+                       }\r
+               }else{\r
+                       DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+               }\r
+               NtClose (hKey);\r
+       }else{\r
+               DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+       }\r
+       return Status;\r
+}\r
+\r
+\r
 /**********************************************************************\r
  * SmExecPgm/1                                                 API\r
  */\r
 SMAPI(SmExecPgm)\r
 {\r
+       PSM_PORT_MESSAGE_EXECPGM ExecPgm = NULL;\r
+       WCHAR                    Name [SM_EXEXPGM_MAX_LENGTH + 1];\r
+       NTSTATUS                 Status = STATUS_SUCCESS;\r
+\r
        DPRINT("SM: %s called\n",__FUNCTION__);\r
-       Request->Status = STATUS_NOT_IMPLEMENTED;\r
-       return STATUS_SUCCESS;\r
-}\r
 \r
+       if(NULL == Request)\r
+       {\r
+               DPRINT1("SM: %s: Request == NULL!\n", __FUNCTION__);\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+       DPRINT("SM: %s called from CID(%lx|%lx)\n",\r
+               __FUNCTION__, Request->Header.ClientId.UniqueProcess,\r
+               Request->Header.ClientId.UniqueThread);\r
+       ExecPgm = & Request->ExecPgm;\r
+       /* Check if the name lenght is valid */\r
+       if((ExecPgm->NameLength > 0) &&\r
+          (ExecPgm->NameLength <= SM_EXEXPGM_MAX_LENGTH) &&\r
+          TRUE /* TODO: check LPC payload size */)\r
+       {\r
+               \r
+               RtlZeroMemory (Name, sizeof Name);\r
+               RtlCopyMemory (Name,\r
+                              ExecPgm->Name,\r
+                              (sizeof ExecPgm->Name[0] * ExecPgm->NameLength));\r
+               DPRINT("SM: %s: Name=[%wZ]\n", __FUNCTION__, Name);\r
+               /*\r
+                * Check if program name is internal\r
+                * (Is this correct? Debug is in the registry too)\r
+                */\r
+               if(0 == _wcsicmp(L"DEBUG", Name))\r
+               {\r
+                       /*\r
+                        * Initialize DBGSS.\r
+                        * NOTE: probably in early prototypes it was an\r
+                        * independent process; now it is embedded in the\r
+                        * SM for performance or security.\r
+                        */\r
+                       Request->Status = SmInitializeDbgSs();\r
+               }\r
+               else\r
+               {\r
+                       WCHAR ImagePath [1024] = {0};\r
+                       ULONG ImagePathLength = sizeof ImagePath;\r
+                       ULONG ImagePathType = REG_EXPAND_SZ;\r
+\r
+                       /* Lookup Name in the registry */\r
+                       Status = SmLookupSubsystem (Name,\r
+                                                   ImagePath,\r
+                                                   & ImagePathLength,\r
+                                                   & ImagePathType,\r
+                                                   TRUE); /* expand */\r
+                       if(NT_SUCCESS(Status))\r
+                       {\r
+                               /* Create native process */\r
+                               Request->Status = SmCreateUserProcess(ImagePath,\r
+                                                                     L"", /* FIXME */\r
+                                                                     FALSE, /* wait */\r
+                                                                     NULL,\r
+                                                                     FALSE, /* terminate */\r
+                                                                     NULL);\r
+                       }else{\r
+                               Request->Status = Status;\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               Request->Status = Status = STATUS_INVALID_PARAMETER;\r
+       }\r
+       return Status;\r
+}\r
 \r
 /* EOF */\r
index ea78a89..2bd3480 100644 (file)
@@ -63,6 +63,12 @@ NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
                                     PLARGE_INTEGER Timeout OPTIONAL,
                                     BOOLEAN TerminateIt,
                                     PRTL_PROCESS_INFO ProcessInfo OPTIONAL);
+NTSTATUS STDCALL
+SmLookupSubsystem (IN     PWSTR   Name,
+                  IN OUT PWSTR   Data,
+                  IN OUT PULONG  DataLength,
+                  IN OUT PULONG  DataType,
+                  IN     BOOLEAN Expand);
 NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
 
 /* smapicomp.c */