Kmode subsystem no more hardwired.
Modified: trunk/reactos/subsys/smss/initss.c
Modified: trunk/reactos/subsys/smss/smapiexec.c
Modified: trunk/reactos/subsys/smss/smss.h
_____
Modified: trunk/reactos/subsys/smss/initss.c
--- trunk/reactos/subsys/smss/initss.c 2005-03-02 21:54:58 UTC (rev
13799)
+++ trunk/reactos/subsys/smss/initss.c 2005-03-02 22:09:53 UTC (rev
13800)
@@ -32,6 +32,10 @@
#define NDEBUG
#include <debug.h>
+/* SM handle for its own \SmApiPort */
+HANDLE hSmApiPort = (HANDLE) 0;
+
+
/* TODO: this file should be totally rewritten
*
* a) look if a special option is set for smss.exe in
@@ -40,9 +44,6 @@
* b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
* (programmatically)
*
- * c) make smss load win32k.sys as set in Kmode key
- * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\SubSystems
- *
* d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as
described
* in the registry key Required="Debug Windows"
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\SubSystems
@@ -56,30 +57,41 @@
NTSTATUS
SmLoadSubsystems(VOID)
{
- SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
- NTSTATUS Status;
+ SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
+ NTSTATUS Status = STATUS_SUCCESS;
+ WCHAR Data [MAX_PATH + 1];
+ ULONG DataLength = sizeof Data;
+ ULONG DataType = 0;
- DPRINT("SM: loading subsystems\n");
+
+ DPRINT("SM: loading subsystems\n");
- /* Load kernel mode subsystem (aka win32k.sys) */
- RtlRosInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
- L"\\SystemRoot\\system32\\win32k.sys");
+ /* Load Kmode subsystem (aka win32k.sys) */
+ Status = SmLookupSubsystem (L"Kmode",
+ Data,
+ & DataLength,
+ & DataType,
+ TRUE);
+ if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
+ {
+ WCHAR ImagePath [MAX_PATH + 1] = {0};
- Status = NtSetSystemInformation(SystemLoadAndCallImage,
- &ImageInfo,
- sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
-
- DPRINT("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
-#if 0
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-#endif
-
- /* FIXME: load more subsystems (csrss!) */
-
- return(Status);
+ wcscpy (ImagePath, L"\\??\\");
+ wcscat (ImagePath, Data);
+ RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
+ RtlInitUnicodeString (& ImageInfo.ModuleName,
ImagePath);
+ Status = NtSetSystemInformation(SystemLoadAndCallImage,
+ & ImageInfo,
+ sizeof ImageInfo);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("SM: loading Kmode failed
(Status=0x%08lx)\n",
+ Status);
+ return Status;
+ }
+ }
+ /* TODO: load Required subsystems (Debug Windows) */
+ return Status;
}
NTSTATUS
_____
Modified: trunk/reactos/subsys/smss/smapiexec.c
--- trunk/reactos/subsys/smss/smapiexec.c 2005-03-02 21:54:58 UTC
(rev 13799)
+++ trunk/reactos/subsys/smss/smapiexec.c 2005-03-02 22:09:53 UTC
(rev 13800)
@@ -1,13 +1,29 @@
-/* $Id: $
+/* $Id$
*
* smapiexec.c - SM_API_EXECUTE_PROGRAM
*
* Reactos Session Manager
*
+ * --------------------------------------------------------------------
+ *
+ * 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"
-#include <rosrtl/string.h>
#define NDEBUG
#include <debug.h>
@@ -100,14 +116,204 @@
}
/**********************************************************************
+ * NAME
+ * SmLookupSubsystem/5
+ *
+ * DESCRIPTION
+ * Read from the registry key
+ * \Registry\SYSTEM\CurrentControlSet\Control\Session
Manager\Subsystems
+ * the value which name is Name.
+ *
+ * ARGUMENTS
+ * Name: name of the program to run, that is a value's name in
+ * the SM registry key Subsystems;
+ * Data: what the registry gived back for Name;
+ * DataLength: how much Data the registry retruns;
+ * DataType: what is Data?
+ * Expand: set it TRUE if you want this function to use the env
+ * to possibly expand Data before giving it back.
+ */
+NTSTATUS STDCALL
+SmLookupSubsystem (IN PWSTR Name,
+ IN OUT PWSTR Data,
+ IN OUT PULONG DataLength,
+ IN OUT PULONG DataType,
+ IN BOOLEAN Expand)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING usKeyName = {0};
+ OBJECT_ATTRIBUTES Oa = {0};
+ HANDLE hKey = (HANDLE) 0;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+ /*
+ * Prepare the key name to scan and
+ * related object attributes.
+ */
+ RtlInitUnicodeString (& usKeyName,
+
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session
Manager\\SubSystems");
+
+ InitializeObjectAttributes (& Oa,
+ & usKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ /*
+ * Open the key. This MUST NOT fail, if the
+ * request is for a legitimate subsystem.
+ */
+ Status = NtOpenKey (& hKey,
+ MAXIMUM_ALLOWED,
+ & Oa);
+ if(NT_SUCCESS(Status))
+ {
+ UNICODE_STRING usValueName = {0};
+ WCHAR KeyValueInformation [1024] = {L'\0'};
+ ULONG ResultLength = 0L;
+ PKEY_VALUE_PARTIAL_INFORMATION
+ kvpi = (PKEY_VALUE_PARTIAL_INFORMATION)
KeyValueInformation;
+
+
+ RtlInitUnicodeString (& usValueName, Name);
+ Status = NtQueryValueKey (hKey,
+ & usValueName,
+ KeyValuePartialInformation,
+ KeyValueInformation,
+ sizeof KeyValueInformation,
+ & ResultLength);
+ if(NT_SUCCESS(Status))
+ {
+ DPRINT("nkvpi.TitleIndex = %ld\n",
kvpi->TitleIndex);
+ DPRINT("kvpi.Type = %ld\n", kvpi->Type);
+ DPRINT("kvpi.DataLength = %ld\n",
kvpi->DataLength);
+
+ if((NULL != Data) && (NULL != DataLength) &&
(NULL != DataType))
+ {
+ *DataType = kvpi->Type;
+ if((Expand) && (REG_EXPAND_SZ ==
*DataType))
+ {
+ UNICODE_STRING Source;
+ WCHAR DestinationBuffer
[2048] = {0};
+ UNICODE_STRING Destination;
+ ULONG Length = 0;
+
+ DPRINT("SM: %s: value will be
expanded\n", __FUNCTION__);
+
+ Source.Length =
kvpi->DataLength;
+ Source.MaximumLength =
kvpi->DataLength;
+ Source.Buffer = (PWCHAR)
& kvpi->Data;
+
+ Destination.Length = 0;
+ Destination.MaximumLength =
sizeof DestinationBuffer;
+ Destination.Buffer =
DestinationBuffer;
+
+ Status =
RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
+
& Source,
+
& Destination,
+
& Length);
+ if(NT_SUCCESS(Status))
+ {
+ *DataLength =
min(*DataLength, Destination.Length);
+ RtlCopyMemory (Data,
Destination.Buffer, *DataLength);
+ }
+
+ }else{
+ DPRINT("SM: %s: value won't be
expanded\n", __FUNCTION__);
+ *DataLength = min(*DataLength,
kvpi->DataLength);
+ RtlCopyMemory (Data, &
kvpi->Data, *DataLength);
+ }
+ *DataType = kvpi->Type;
+ }else{
+ DPRINT1("SM: %s: Data or DataLength or
DataType is NULL!\n", __FUNCTION__);
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }else{
+ DPRINT1("%s: NtQueryValueKey failed
(Status=0x%08lx)\n", __FUNCTION__, Status);
+ }
+ NtClose (hKey);
+ }else{
+ DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
+ }
+ return Status;
+}
+
+
+/**********************************************************************
* SmExecPgm/1 API
*/
SMAPI(SmExecPgm)
{
+ PSM_PORT_MESSAGE_EXECPGM ExecPgm = NULL;
+ WCHAR Name [SM_EXEXPGM_MAX_LENGTH + 1];
+ NTSTATUS Status = STATUS_SUCCESS;
+
DPRINT("SM: %s called\n",__FUNCTION__);
- Request->Status = STATUS_NOT_IMPLEMENTED;
- return STATUS_SUCCESS;
+
+ if(NULL == Request)
+ {
+ DPRINT1("SM: %s: Request == NULL!\n", __FUNCTION__);
+ return STATUS_INVALID_PARAMETER;
+ }
+ DPRINT("SM: %s called from CID(%lx|%lx)\n",
+ __FUNCTION__, Request->Header.ClientId.UniqueProcess,
+ Request->Header.ClientId.UniqueThread);
+ ExecPgm = & Request->ExecPgm;
+ /* Check if the name lenght is valid */
+ if((ExecPgm->NameLength > 0) &&
+ (ExecPgm->NameLength <= SM_EXEXPGM_MAX_LENGTH) &&
+ TRUE /* TODO: check LPC payload size */)
+ {
+
+ RtlZeroMemory (Name, sizeof Name);
+ RtlCopyMemory (Name,
+ ExecPgm->Name,
+ (sizeof ExecPgm->Name[0] *
ExecPgm->NameLength));
+ DPRINT("SM: %s: Name=[%wZ]\n", __FUNCTION__, Name);
+ /*
+ * Check if program name is internal
+ * (Is this correct? Debug is in the registry too)
+ */
+ if(0 == _wcsicmp(L"DEBUG", Name))
+ {
+ /*
+ * Initialize DBGSS.
+ * NOTE: probably in early prototypes it was an
+ * independent process; now it is embedded in
the
+ * SM for performance or security.
+ */
+ Request->Status = SmInitializeDbgSs();
+ }
+ else
+ {
+ WCHAR ImagePath [1024] = {0};
+ ULONG ImagePathLength = sizeof ImagePath;
+ ULONG ImagePathType = REG_EXPAND_SZ;
+
+ /* Lookup Name in the registry */
+ Status = SmLookupSubsystem (Name,
+ ImagePath,
+ & ImagePathLength,
+ & ImagePathType,
+ TRUE); /* expand */
+ if(NT_SUCCESS(Status))
+ {
+ /* Create native process */
+ Request->Status =
SmCreateUserProcess(ImagePath,
+
L"", /* FIXME */
+
FALSE, /* wait */
+
NULL,
+
FALSE, /* terminate */
+
NULL);
+ }else{
+ Request->Status = Status;
+ }
+ }
+ }
+ else
+ {
+ Request->Status = Status = STATUS_INVALID_PARAMETER;
+ }
+ return Status;
}
-
/* EOF */
_____
Modified: trunk/reactos/subsys/smss/smss.h
--- trunk/reactos/subsys/smss/smss.h 2005-03-02 21:54:58 UTC (rev
13799)
+++ trunk/reactos/subsys/smss/smss.h 2005-03-02 22:09:53 UTC (rev
13800)
@@ -63,6 +63,12 @@
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 */