mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 20:36:35 +00:00
Kmode subsystem no more hardwired.
svn path=/trunk/; revision=13800
This commit is contained in:
parent
2078ec7054
commit
5bef1d9303
3 changed files with 254 additions and 30 deletions
|
@ -32,6 +32,10 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* SM handle for its own \SmApiPort */
|
||||||
|
HANDLE hSmApiPort = (HANDLE) 0;
|
||||||
|
|
||||||
|
|
||||||
/* TODO: this file should be totally rewritten
|
/* TODO: this file should be totally rewritten
|
||||||
*
|
*
|
||||||
* a) look if a special option is set for smss.exe in
|
* 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
|
* b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
|
||||||
* (programmatically)
|
* (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
|
* d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as described
|
||||||
* in the registry key Required="Debug Windows"
|
* in the registry key Required="Debug Windows"
|
||||||
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems
|
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems
|
||||||
|
@ -57,29 +58,40 @@ NTSTATUS
|
||||||
SmLoadSubsystems(VOID)
|
SmLoadSubsystems(VOID)
|
||||||
{
|
{
|
||||||
SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
|
SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
|
||||||
NTSTATUS Status;
|
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) */
|
/* Load Kmode subsystem (aka win32k.sys) */
|
||||||
RtlRosInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
|
Status = SmLookupSubsystem (L"Kmode",
|
||||||
L"\\SystemRoot\\system32\\win32k.sys");
|
Data,
|
||||||
|
& DataLength,
|
||||||
|
& DataType,
|
||||||
|
TRUE);
|
||||||
|
if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
|
||||||
|
{
|
||||||
|
WCHAR ImagePath [MAX_PATH + 1] = {0};
|
||||||
|
|
||||||
|
wcscpy (ImagePath, L"\\??\\");
|
||||||
|
wcscat (ImagePath, Data);
|
||||||
|
RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
|
||||||
|
RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
|
||||||
Status = NtSetSystemInformation(SystemLoadAndCallImage,
|
Status = NtSetSystemInformation(SystemLoadAndCallImage,
|
||||||
& ImageInfo,
|
& ImageInfo,
|
||||||
sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
|
sizeof ImageInfo);
|
||||||
|
|
||||||
DPRINT("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
|
|
||||||
#if 0
|
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n",
|
||||||
|
Status);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
/* TODO: load Required subsystems (Debug Windows) */
|
||||||
/* FIXME: load more subsystems (csrss!) */
|
return Status;
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -1,13 +1,29 @@
|
||||||
/* $Id: $
|
/* $Id$
|
||||||
*
|
*
|
||||||
* smapiexec.c - SM_API_EXECUTE_PROGRAM
|
* smapiexec.c - SM_API_EXECUTE_PROGRAM
|
||||||
*
|
*
|
||||||
* Reactos Session Manager
|
* 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 "smss.h"
|
||||||
#include <rosrtl/string.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -99,15 +115,205 @@ SmCreateUserProcess (LPWSTR ImagePath,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* 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
|
* SmExecPgm/1 API
|
||||||
*/
|
*/
|
||||||
SMAPI(SmExecPgm)
|
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__);
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -63,6 +63,12 @@ NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
|
||||||
PLARGE_INTEGER Timeout OPTIONAL,
|
PLARGE_INTEGER Timeout OPTIONAL,
|
||||||
BOOLEAN TerminateIt,
|
BOOLEAN TerminateIt,
|
||||||
PRTL_PROCESS_INFO ProcessInfo OPTIONAL);
|
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);
|
NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
|
||||||
|
|
||||||
/* smapicomp.c */
|
/* smapicomp.c */
|
||||||
|
|
Loading…
Reference in a new issue