Kmode subsystem no more hardwired.

svn path=/trunk/; revision=13800
This commit is contained in:
Emanuele Aliberti 2005-03-02 22:09:53 +00:00
parent 2078ec7054
commit 5bef1d9303
3 changed files with 254 additions and 30 deletions

View file

@ -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

View file

@ -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>
@ -99,15 +115,205 @@ SmCreateUserProcess (LPWSTR ImagePath,
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
*/
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 */

View 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 */