SM: subsystem registration (partial)

- merged duplicate code in process creation
- experimental implementation of env subsystem registration

svn path=/trunk/; revision=13654
This commit is contained in:
Emanuele Aliberti 2005-02-19 22:58:18 +00:00
parent 1c2c6c8582
commit 5ea38c2861
12 changed files with 520 additions and 226 deletions

View file

@ -26,6 +26,7 @@
#define NTOS_MODE_USER #define NTOS_MODE_USER
#include <ntos.h> #include <ntos.h>
#include "smss.h" #include "smss.h"
#include <sm/helper.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -41,6 +42,39 @@ struct _SM_CLIENT_DIRECTORY
} SmpClientDirectory; } SmpClientDirectory;
#if 0
/**********************************************************************
* SmpRegisterSmss/0
*/
static NTSTATUS
SmpRegisterSmss(VOID)
{
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING SbApiPortName = {0,0,NULL};
HANDLE hSmApiPort = (HANDLE) 0;
DPRINT("SM: %s called\n",__FUNCTION__);
Status = SmConnectApiPort(& SbApiPortName,
(HANDLE) -1,
IMAGE_SUBSYSTEM_NATIVE,
& hSmApiPort);
if(!NT_SUCCESS(Status))
{
DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",__FUNCTION__,Status);
return Status;
}
Status = SmCompleteSession (hSmApiPort, (HANDLE)0, hSmApiPort);
if(!NT_SUCCESS(Status))
{
DPRINT("SM: %s: SMDLL!SmCompleteSession failed (Status=0x%08lx)\n",__FUNCTION__,Status);
return Status;
}
NtClose(hSmApiPort);
return Status;
}
#endif
/********************************************************************** /**********************************************************************
* SmInitializeClientManagement/0 * SmInitializeClientManagement/0
*/ */
@ -51,11 +85,22 @@ SmInitializeClientManagement (VOID)
RtlInitializeCriticalSection(& SmpClientDirectory.Lock); RtlInitializeCriticalSection(& SmpClientDirectory.Lock);
SmpClientDirectory.Count = 0; SmpClientDirectory.Count = 0;
SmpClientDirectory.Client = NULL; SmpClientDirectory.Client = NULL;
#if 0
/* Register IMAGE_SUBSYSTE_NATIVE to be managed by SM */
return SmpRegisterSmss();
#endif
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/********************************************************************** /**********************************************************************
* SmpLookupClient/1 * SmpLookupClient/1
*
* DESCRIPTION
* Lookup the subsystem server descriptor given its image ID.
*
* SIDE EFFECTS
* SmpClientDirectory.Lock is released only on success.
*/ */
static PSM_CLIENT_DATA STDCALL static PSM_CLIENT_DATA STDCALL
SmpLookupClient (USHORT SubsystemId) SmpLookupClient (USHORT SubsystemId)
@ -70,22 +115,31 @@ SmpLookupClient (USHORT SubsystemId)
Client = SmpClientDirectory.Client; Client = SmpClientDirectory.Client;
while (NULL != Client) while (NULL != Client)
{ {
if (SubsystemId == Client->SubsystemId) break; if (SubsystemId == Client->SubsystemId)
{
RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
return Client;
}
Client = Client->Next; Client = Client->Next;
} }
} }
RtlLeaveCriticalSection (& SmpClientDirectory.Lock); /*
* Note that we do *not* release SmpClientDirectory.Lock here
* because SmpLookupClient is called to FAIL when SubsystemId
* is not registered yet.
*/
return Client; return Client;
} }
/********************************************************************** /**********************************************************************
* SmpCreateClient/1 * SmpCreateClient/2
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData) SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
{ {
PSM_CLIENT_DATA pClient = NULL; PSM_CLIENT_DATA pClient = NULL;
PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST); PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);
ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);
DPRINT("SM: %s called\n", __FUNCTION__); DPRINT("SM: %s called\n", __FUNCTION__);
@ -94,9 +148,12 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
*/ */
if (SmpLookupClient(ConnectData->Subsystem)) if (SmpLookupClient(ConnectData->Subsystem))
{ {
DbgPrint("SMSS: %s: attempt to register again subsystem %d.\n",__FUNCTION__,0); DPRINT("SMSS: %s: attempt to register again subsystem %d.\n",
__FUNCTION__,
ConnectData->Subsystem);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
DPRINT("SM: %s: registering subsystem %d \n", __FUNCTION__, ConnectData->Subsystem);
/* /*
* Allocate the storage for client data * Allocate the storage for client data
*/ */
@ -112,13 +169,17 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
* Initialize the client data * Initialize the client data
*/ */
pClient->SubsystemId = ConnectData->Subsystem; pClient->SubsystemId = ConnectData->Subsystem;
pClient->Initialized = FALSE; pClient->Initialized = (IMAGE_SUBSYSTEM_NATIVE == pClient->SubsystemId);
// TODO if (SbApiPortNameSize > 0)
{
RtlCopyMemory (pClient->SbApiPortName,
ConnectData->SbName,
SbApiPortNameSize);
}
/* /*
* Insert the new descriptor in the * Insert the new descriptor in the
* client directory. * client directory.
*/ */
RtlEnterCriticalSection (& SmpClientDirectory.Lock);
if (NULL == SmpClientDirectory.Client) if (NULL == SmpClientDirectory.Client)
{ {
SmpClientDirectory.Client = pClient; SmpClientDirectory.Client = pClient;
@ -132,8 +193,15 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
} }
pClient->Next = NULL; pClient->Next = NULL;
++ SmpClientDirectory.Count; ++ SmpClientDirectory.Count;
/*
* Note we unlock the client directory here, because
* it was locked by SmpLookupClient on failure.
*/
RtlLeaveCriticalSection (& SmpClientDirectory.Lock); RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
if (ClientData) *ClientData = pClient; if (ClientData)
{
*ClientData = pClient;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -1,6 +1,6 @@
/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $ /* $Id: init.c 13449 2005-02-06 21:55:07Z ea $
* *
* initdosdev.c - Define symbolic links to kernel devices (MS-DOS names) * initdosdev.c - Define symbolic links to kernel devices (MS-DOS names).
* *
* ReactOS Operating System * ReactOS Operating System
* *

View file

@ -1,6 +1,6 @@
/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $ /* $Id: init.c 13449 2005-02-06 21:55:07Z ea $
* *
* initenv.c - Environment initialization * initenv.c - Hive loading
* *
* ReactOS Operating System * ReactOS Operating System
* *

View file

@ -32,6 +32,9 @@
HANDLE Children[2] = {0, 0}; /* csrss, winlogon */ HANDLE Children[2] = {0, 0}; /* csrss, winlogon */
/**********************************************************************
* SmpRunBootAppsQueryRoutine/6
*/
static NTSTATUS STDCALL static NTSTATUS STDCALL
SmpRunBootAppsQueryRoutine(PWSTR ValueName, SmpRunBootAppsQueryRoutine(PWSTR ValueName,
ULONG ValueType, ULONG ValueType,
@ -40,14 +43,10 @@ SmpRunBootAppsQueryRoutine(PWSTR ValueName,
PVOID Context, PVOID Context,
PVOID EntryContext) PVOID EntryContext)
{ {
PRTL_USER_PROCESS_PARAMETERS ProcessParameters; WCHAR Description [MAX_PATH];
RTL_PROCESS_INFO ProcessInfo; WCHAR ImageName [MAX_PATH];
UNICODE_STRING ImagePathString; WCHAR ImagePath [MAX_PATH];
UNICODE_STRING CommandLineString; WCHAR CommandLine [MAX_PATH];
WCHAR Description[256];
WCHAR ImageName[256];
WCHAR ImagePath[256];
WCHAR CommandLine[256];
PWSTR p1, p2; PWSTR p1, p2;
ULONG len; ULONG len;
NTSTATUS Status; NTSTATUS Status;
@ -96,54 +95,23 @@ SmpRunBootAppsQueryRoutine(PWSTR ValueName,
wcscat(ImagePath, ImageName); wcscat(ImagePath, ImageName);
wcscat(ImagePath, L".exe"); wcscat(ImagePath, L".exe");
RtlInitUnicodeString(&ImagePathString, /* Create NT process */
ImagePath); Status = SmCreateUserProcess (ImagePath,
CommandLine,
RtlInitUnicodeString(&CommandLineString, TRUE, /* wait */
CommandLine);
RtlCreateProcessParameters(&ProcessParameters,
&ImagePathString,
NULL,
NULL,
&CommandLineString,
NULL,
NULL,
NULL,
NULL,
NULL);
Status = RtlCreateUserProcess(&ImagePathString,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL, NULL,
NULL, TRUE, /* terminate */
NULL, NULL);
FALSE,
NULL,
NULL,
&ProcessInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("Running %s failed (Status %lx)\n", Description, Status);
return(STATUS_SUCCESS);
}
RtlDestroyProcessParameters(ProcessParameters);
/* Wait for process termination */
NtWaitForSingleObject(ProcessInfo.ProcessHandle,
FALSE,
NULL);
NtClose(ProcessInfo.ThreadHandle);
NtClose(ProcessInfo.ProcessHandle);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
/* /**********************************************************************
* SmRunBootApplications/0
*
* DESCRIPTION
*
* Run native applications listed in the registry. * Run native applications listed in the registry.
* *
* Key: * Key:

View file

@ -26,6 +26,7 @@
#include "smss.h" #include "smss.h"
#include <rosrtl/string.h> #include <rosrtl/string.h>
#define NDEBUG #define NDEBUG
@ -49,6 +50,9 @@
* e) make optional subsystems loadable (again: they must be described in the registry * e) make optional subsystems loadable (again: they must be described in the registry
* key Optional="Posix Os2" to be allowed to run) * key Optional="Posix Os2" to be allowed to run)
*/ */
/**********************************************************************
*/
NTSTATUS NTSTATUS
SmLoadSubsystems(VOID) SmLoadSubsystems(VOID)
{ {
@ -56,7 +60,7 @@ SmLoadSubsystems(VOID)
NTSTATUS Status; NTSTATUS Status;
DPRINT("SM: loading subsystems\n"); DPRINT("SM: loading subsystems\n");
/* Load kernel mode subsystem (aka win32k.sys) */ /* Load kernel mode subsystem (aka win32k.sys) */
RtlRosInitUnicodeStringFromLiteral(&ImageInfo.ModuleName, RtlRosInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
L"\\SystemRoot\\system32\\win32k.sys"); L"\\SystemRoot\\system32\\win32k.sys");
@ -84,10 +88,9 @@ SmRunCsrss(VOID)
NTSTATUS Status; NTSTATUS Status;
UNICODE_STRING UnicodeString; UNICODE_STRING UnicodeString;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
RTL_PROCESS_INFO ProcessInfo; RTL_PROCESS_INFO ProcessInfo;
HANDLE CsrssInitEvent; HANDLE CsrssInitEvent;
WCHAR UnicodeBuffer[MAX_PATH]; WCHAR ImagePath [MAX_PATH];
DPRINT("SM: initializing csrss\n"); DPRINT("SM: initializing csrss\n");
@ -114,36 +117,17 @@ SmRunCsrss(VOID)
*/ */
/* initialize executable path */ /* initialize executable path */
wcscpy(UnicodeBuffer, L"\\??\\"); wcscpy(ImagePath, L"\\??\\");
wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot); wcscat(ImagePath, SharedUserData->NtSystemRoot);
wcscat(UnicodeBuffer, L"\\system32\\csrss.exe"); wcscat(ImagePath, L"\\system32\\csrss.exe");
RtlInitUnicodeString(&UnicodeString,
UnicodeBuffer);
RtlCreateProcessParameters(&ProcessParameters, Status = SmCreateUserProcess(ImagePath,
&UnicodeString, L"",
NULL, FALSE, /* wait */
NULL,
NULL,
SmSystemEnvironment,
NULL,
NULL,
NULL,
NULL);
Status = RtlCreateUserProcess(&UnicodeString,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL, NULL,
NULL, FALSE, /* terminate */
NULL, & ProcessInfo);
FALSE,
NULL,
NULL,
&ProcessInfo);
RtlDestroyProcessParameters (ProcessParameters);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__); DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);
@ -162,11 +146,9 @@ SmRunCsrss(VOID)
NTSTATUS NTSTATUS
SmRunWinlogon(VOID) SmRunWinlogon(VOID)
{ {
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING UnicodeString;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
RTL_PROCESS_INFO ProcessInfo; RTL_PROCESS_INFO ProcessInfo;
WCHAR UnicodeBuffer[MAX_PATH]; WCHAR ImagePath [MAX_PATH];
/* /*
* Start the logon process (winlogon.exe) * Start the logon process (winlogon.exe)
@ -175,43 +157,23 @@ SmRunWinlogon(VOID)
DPRINT("SM: starting winlogon\n"); DPRINT("SM: starting winlogon\n");
/* initialize executable path */ /* initialize executable path */
wcscpy(UnicodeBuffer, L"\\??\\"); wcscpy(ImagePath, L"\\??\\");
wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot); wcscat(ImagePath, SharedUserData->NtSystemRoot);
wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe"); wcscat(ImagePath, L"\\system32\\winlogon.exe");
RtlInitUnicodeString(&UnicodeString,
UnicodeBuffer);
RtlCreateProcessParameters(&ProcessParameters, Status = SmCreateUserProcess(ImagePath,
&UnicodeString, L"",
NULL, FALSE, /* wait */
NULL,
NULL,
SmSystemEnvironment,
NULL,
NULL,
NULL,
NULL);
Status = RtlCreateUserProcess(&UnicodeString,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL, NULL,
NULL, FALSE, /* terminate */
NULL, & ProcessInfo);
FALSE,
NULL,
NULL,
&ProcessInfo);
RtlDestroyProcessParameters(ProcessParameters);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__); DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);
NtTerminateProcess(Children[CHILD_CSRSS], NtTerminateProcess(Children[CHILD_CSRSS], 0);
0);
return(Status); return(Status);
} }
Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle; Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
return Status; return Status;

View file

@ -6,6 +6,8 @@ TARGET_TYPE = program
TARGET_APPTYPE = native TARGET_APPTYPE = native
TARGET_SDKLIBS = ntdll.a smdll.a
TARGET_NAME = smss TARGET_NAME = smss
TARGET_INSTALLDIR = system32 TARGET_INSTALLDIR = system32
@ -19,8 +21,8 @@ TARGET_OBJECTS = $(TARGET_NAME).o \
init.o initheap.o initenv.o initobdir.o initdosdev.o \ init.o initheap.o initenv.o initobdir.o initdosdev.o \
initrun.o initmv.o initwkdll.o initpage.o initss.o \ initrun.o initmv.o initwkdll.o initpage.o initss.o \
initreg.o \ initreg.o \
smapi.o \ smapi.o smapicomp.o smapiexec.o \
client.o debug.o client.o debug.o print.o
include $(PATH_TO_TOP)/rules.mak include $(PATH_TO_TOP)/rules.mak

View file

@ -0,0 +1,56 @@
/* $Id: print.c 12852 2005-01-06 13:58:04Z mf $
*
* print.c - Print on the blue screen
*
* ReactOS Operating System
*
* --------------------------------------------------------------------
*
* 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.
*
* --------------------------------------------------------------------
*/
#define NTOS_MODE_USER
#include <ntos.h>
VOID STDCALL DisplayString(LPCWSTR lpwString)
{
UNICODE_STRING us;
RtlInitUnicodeString (&us, lpwString);
ZwDisplayString (&us);
}
VOID STDCALL PrintString (char* fmt, ...)
{
char buffer[512];
va_list ap;
UNICODE_STRING UnicodeString;
ANSI_STRING AnsiString;
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
va_end(ap);
RtlInitAnsiString (&AnsiString, buffer);
RtlAnsiStringToUnicodeString (&UnicodeString,
&AnsiString,
TRUE);
NtDisplayString(&UnicodeString);
RtlFreeUnicodeString (&UnicodeString);
}
/* EOF */

View file

@ -9,7 +9,7 @@
#include "smss.h" #include "smss.h"
#include <rosrtl/string.h> #include <rosrtl/string.h>
#define NDEBUG //#define NDEBUG
#include <debug.h> #include <debug.h>
/* GLOBAL VARIABLES *********************************************************/ /* GLOBAL VARIABLES *********************************************************/
@ -18,9 +18,6 @@ static HANDLE SmApiPort = INVALID_HANDLE_VALUE;
/* SM API *******************************************************************/ /* SM API *******************************************************************/
#define SMAPI(n) \
NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request)
SMAPI(SmInvalid) SMAPI(SmInvalid)
{ {
DPRINT("SM: %s called\n",__FUNCTION__); DPRINT("SM: %s called\n",__FUNCTION__);
@ -28,101 +25,33 @@ SMAPI(SmInvalid)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
SMAPI(SmCompSes)
{
DPRINT("SM: %s called\n",__FUNCTION__);
Request->Status = STATUS_NOT_IMPLEMENTED;
return STATUS_SUCCESS;
}
SMAPI(SmExecPgm)
{
DPRINT("SM: %s called\n",__FUNCTION__);
Request->Status = STATUS_NOT_IMPLEMENTED;
return STATUS_SUCCESS;
}
/* SM API Table */ /* SM API Table */
typedef NTSTATUS (FASTCALL * SM_PORT_API)(PSM_PORT_MESSAGE); typedef NTSTATUS (FASTCALL * SM_PORT_API)(PSM_PORT_MESSAGE);
SM_PORT_API SmApi [] = SM_PORT_API SmApi [] =
{ {
SmInvalid, /* unused */ SmInvalid, /* unused */
SmCompSes, SmCompSes, /* smapicomp.c */
SmInvalid, /* obsolete */ SmInvalid, /* obsolete */
SmInvalid, /* unknown */ SmInvalid, /* unknown */
SmExecPgm SmExecPgm /* smapiexec.c */
}; };
#if !defined(__USE_NT_LPC__)
/**********************************************************************
* NAME
* SmpHandleConnectionRequest/2
*
* REMARKS
* Quoted in http://support.microsoft.com/kb/258060/EN-US/
*/
NTSTATUS STDCALL NTSTATUS STDCALL
SmpHandleConnectionRequest (HANDLE Port, PSM_PORT_MESSAGE Request) SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
{ #endif
NTSTATUS Status = STATUS_SUCCESS;
PSM_CLIENT_DATA ClientData = NULL;
PVOID Context = NULL;
DPRINT("SM: %s called\n",__FUNCTION__);
Status = SmCreateClient (Request, & ClientData);
if(STATUS_SUCCESS == Status)
{
#ifdef __USE_NT_LPC__
Status = NtAcceptConnectPort (& ClientData->ApiPort,
Context,
SmApiPort,
TRUE, //accept
NULL,
NULL);
#else
Status = NtAcceptConnectPort (& ClientData->ApiPort,
Context,
(PLPC_MESSAGE) Request,
TRUE, //accept
NULL,
NULL);
#endif
if(NT_SUCCESS(Status))
{
Status = NtCompleteConnectPort(ClientData->ApiPort);
}
return STATUS_SUCCESS;
} else {
/* Reject the subsystem */
#ifdef __USE_NT_LPC__
Status = NtAcceptConnectPort (& ClientData->ApiPort,
Context,
SmApiPort,
FALSE, //reject
NULL,
NULL);
#else
Status = NtAcceptConnectPort (& ClientData->ApiPort,
Context,
(PLPC_MESSAGE) Request,
FALSE, //reject
NULL,
NULL);
#endif
}
return Status;
}
/********************************************************************** /**********************************************************************
* NAME * NAME
* SmpApiThread/1 * SmpApiConnectedThread/1
* *
* DESCRIPTION * DESCRIPTION
* Entry point for the listener thread of LPC port "\SmApiPort". * Entry point for the listener thread of LPC port "\SmApiPort".
*/ */
VOID STDCALL VOID STDCALL
SmpApiThread(HANDLE Port) SmpApiConnectedThread(PVOID dummy)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PVOID Unknown = NULL; PVOID Unknown = NULL;
@ -135,7 +64,7 @@ SmpApiThread(HANDLE Port)
{ {
DPRINT("SM: %s: waiting for message\n",__FUNCTION__); DPRINT("SM: %s: waiting for message\n",__FUNCTION__);
Status = NtReplyWaitReceivePort(Port, Status = NtReplyWaitReceivePort(SmApiPort,
(PULONG) & Unknown, (PULONG) & Unknown,
Reply, Reply,
(PLPC_MESSAGE) & Request); (PLPC_MESSAGE) & Request);
@ -148,7 +77,7 @@ SmpApiThread(HANDLE Port)
switch (Request.Header.MessageType) switch (Request.Header.MessageType)
{ {
case LPC_CONNECTION_REQUEST: case LPC_CONNECTION_REQUEST:
SmpHandleConnectionRequest (Port, &Request); SmpHandleConnectionRequest (&Request);
Reply = NULL; Reply = NULL;
break; break;
case LPC_DEBUG_EVENT: case LPC_DEBUG_EVENT:
@ -173,6 +102,158 @@ SmpApiThread(HANDLE Port)
} }
} }
/**********************************************************************
* NAME
* SmpHandleConnectionRequest/1
*
* ARGUMENTS
* Request: LPC connection request message
*
* REMARKS
* Quoted in http://support.microsoft.com/kb/258060/EN-US/
*/
NTSTATUS STDCALL
SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
{
#if defined(__USE_NT_LPC__)
NTSTATUS Status = STATUS_SUCCESS;
PSM_CLIENT_DATA ClientData = NULL;
PVOID Context = NULL;
DPRINT("SM: %s called\n",__FUNCTION__);
/*
* SmCreateClient/2 is called here explicitly to *fail*.
* If it succeeds, there is something wrong in the
* connection request. An environment subsystem *never*
* registers twice. (Security issue: maybe we will
* write this event into the security log).
*/
Status = SmCreateClient (Request, & ClientData);
if(STATUS_SUCCESS == Status)
{
/* OK: the client is an environment subsystem
* willing to manage a free image type.
* Accept it.
*/
Status = NtAcceptConnectPort (& ClientData->ApiPort,
Context,
(PLPC_MESSAGE) Request,
TRUE, //accept
NULL,
NULL);
if(NT_SUCCESS(Status))
{
Status = NtCompleteConnectPort(ClientData->ApiPort);
}
return STATUS_SUCCESS;
} else {
/* Reject the subsystem */
Status = NtAcceptConnectPort (& ClientData->ApiPort,
Context,
(PLPC_MESSAGE) Request,
FALSE, //reject
NULL,
NULL);
}
#else /* ReactOS LPC */
NTSTATUS Status = STATUS_SUCCESS;
PSM_CLIENT_DATA ClientData = NULL;
DPRINT("SM: %s called\n",__FUNCTION__);
Status = SmCreateClient (Request, & ClientData);
if(STATUS_SUCCESS == Status)
{
Status = NtAcceptConnectPort (& ClientData->ApiPort,
SmApiPort,
NULL,
TRUE, //accept
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
return Status;
} else {
Status = NtCompleteConnectPort(ClientData->ApiPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
return Status;
}
Status = RtlCreateUserThread(NtCurrentProcess(),
NULL,
FALSE,
0,
NULL,
NULL,
(PTHREAD_START_ROUTINE) SmpApiConnectedThread,
ClientData->ApiPort,
& ClientData->ApiPortThread,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: Unable to create server thread (Status=0x%08lx)\n",
__FUNCTION__, Status);
return Status;
}
}
return STATUS_SUCCESS;
} else {
/* Reject the subsystem */
Status = NtAcceptConnectPort (& ClientData->ApiPort,
SmApiPort,
NULL,
FALSE, //reject
NULL,
NULL);
}
#endif /* defined __USE_NT_LPC__ */
return Status;
}
/**********************************************************************
* NAME
* SmpApiThread/1
*
* DECRIPTION
* Due to differences in LPC implementation between NT and ROS,
* we need a thread to listen for connection request that
* creates a new thread for each connected port. This is not
* necessary in NT LPC, because server side connected ports are
* never used to receive requests.
*/
VOID STDCALL
SmpApiThread (HANDLE ListeningPort)
{
NTSTATUS Status = STATUS_SUCCESS;
LPC_MAX_MESSAGE Request = {{0}};
while (TRUE)
{
Status = NtListenPort (ListeningPort, & Request.Header);
if (!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);
break;
}
Status = SmpHandleConnectionRequest ((PSM_PORT_MESSAGE) & Request);
if(!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: SmpHandleConnectionRequest failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
break;
}
}
/* Cleanup */
NtClose(ListeningPort);
/* DIE */
NtTerminateThread(NtCurrentThread(), Status);
}
/* LPC PORT INITIALIZATION **************************************************/ /* LPC PORT INITIALIZATION **************************************************/
@ -186,9 +267,9 @@ SmpApiThread(HANDLE Port)
NTSTATUS NTSTATUS
SmCreateApiPort(VOID) SmCreateApiPort(VOID)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes = {0};
UNICODE_STRING UnicodeString; UNICODE_STRING UnicodeString = {0};
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
RtlRosInitUnicodeStringFromLiteral(&UnicodeString, RtlRosInitUnicodeStringFromLiteral(&UnicodeString,
L"\\SmApiPort"); L"\\SmApiPort");
@ -207,19 +288,10 @@ SmCreateApiPort(VOID)
{ {
return(Status); return(Status);
} }
/*
/* Create two threads for "\SmApiPort" */ * Create one thread for the named LPC
RtlCreateUserThread(NtCurrentProcess(), * port \SmApiPort
NULL, */
FALSE,
0,
NULL,
NULL,
(PTHREAD_START_ROUTINE)SmpApiThread,
(PVOID)SmApiPort,
NULL,
NULL);
RtlCreateUserThread(NtCurrentProcess(), RtlCreateUserThread(NtCurrentProcess(),
NULL, NULL,
FALSE, FALSE,

View file

@ -0,0 +1,27 @@
/* $Id: $
*
* smapicomp.c - SM_API_COMPLETE_SESSION
*
* Reactos Session Manager
*
*/
#include "smss.h"
#include <rosrtl/string.h>
#define NDEBUG
#include <debug.h>
/**********************************************************************
* SmCompSes/1 API
*/
SMAPI(SmCompSes)
{
DPRINT("SM: %s called\n",__FUNCTION__);
Request->Status = STATUS_NOT_IMPLEMENTED;
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -0,0 +1,113 @@
/* $Id: $
*
* smapiexec.c - SM_API_EXECUTE_PROGRAM
*
* Reactos Session Manager
*
*/
#include "smss.h"
#include <rosrtl/string.h>
#define NDEBUG
#include <debug.h>
/**********************************************************************
* SmCreateUserProcess/5
*
*/
NTSTATUS STDCALL
SmCreateUserProcess (LPWSTR ImagePath,
LPWSTR CommandLine,
BOOLEAN WaitForIt,
PLARGE_INTEGER Timeout OPTIONAL,
BOOLEAN TerminateIt,
PRTL_PROCESS_INFO UserProcessInfo OPTIONAL
)
{
UNICODE_STRING ImagePathString = {0};
UNICODE_STRING CommandLineString = {0};
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
RTL_PROCESS_INFO ProcessInfo = {0};
PRTL_PROCESS_INFO pProcessInfo = & ProcessInfo;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("SM: %s called\n",__FUNCTION__);
RtlInitUnicodeString (& ImagePathString, ImagePath);
RtlInitUnicodeString (& CommandLineString, CommandLine);
RtlCreateProcessParameters(& ProcessParameters,
& ImagePathString,
NULL,
NULL,
& CommandLineString,
SmSystemEnvironment,
NULL,
NULL,
NULL,
NULL);
if(NULL != UserProcessInfo)
{
/* Use caller provided storage */
pProcessInfo = UserProcessInfo;
}
Status = RtlCreateUserProcess (& ImagePathString,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL,
NULL,
NULL,
FALSE,
NULL,
NULL,
pProcessInfo);
if (!NT_SUCCESS(Status))
{
CHAR AnsiBuffer [MAX_PATH];
INT i = 0;
for(i=0;ImagePathString.Buffer[i];i++)
{
/* raw U -> A */
AnsiBuffer [i] = (CHAR) (ImagePathString.Buffer[i] & 0xff);
}
DPRINT1("SM: %s: Running \"%s\" failed (Status=0x%08lx)\n",
AnsiBuffer, __FUNCTION__, Status);
return Status;
}
RtlDestroyProcessParameters (ProcessParameters);
/* Wait for process termination */
if(WaitForIt)
{
NtWaitForSingleObject (pProcessInfo->ProcessHandle,
FALSE,
Timeout);
}
/* Terminate process */
if(TerminateIt)
{
NtClose(pProcessInfo->ThreadHandle);
NtClose(pProcessInfo->ProcessHandle);
}
return STATUS_SUCCESS;
}
/**********************************************************************
* SmExecPgm/1 API
*/
SMAPI(SmExecPgm)
{
DPRINT("SM: %s called\n",__FUNCTION__);
Request->Status = STATUS_NOT_IMPLEMENTED;
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -25,6 +25,7 @@
*/ */
#include "smss.h" #include "smss.h"
#include <rosrtl/string.h> #include <rosrtl/string.h>
#include <reactos/buildno.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -36,6 +37,11 @@ NtProcessStartup(PPEB Peb)
{ {
NTSTATUS Status; NTSTATUS Status;
DisplayString(L"SMSS\n");
PrintString("ReactOS Session Manager %s (Build %s)\n",
KERNEL_RELEASE_STR,
KERNEL_VERSION_BUILD_STR);
Status = InitSessionManager(); Status = InitSessionManager();
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -4,7 +4,6 @@
#define NTOS_MODE_USER #define NTOS_MODE_USER
#include <ntos.h> #include <ntos.h>
#include <sm/api.h> #include <sm/api.h>
#include <sm/helper.h>
#define CHILD_CSRSS 0 #define CHILD_CSRSS 0
#define CHILD_WINLOGON 1 #define CHILD_WINLOGON 1
@ -50,8 +49,23 @@ NTSTATUS SmRunCsrss(VOID);
NTSTATUS SmRunWinlogon(VOID); NTSTATUS SmRunWinlogon(VOID);
/* smapi.c */ /* smapi.c */
#define SMAPI(n) \
NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request)
/* smapiexec.c */
NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
LPWSTR CommandLine,
BOOLEAN WaitForIt,
PLARGE_INTEGER Timeout OPTIONAL,
BOOLEAN TerminateIt,
PRTL_PROCESS_INFO ProcessInfo OPTIONAL);
NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
/* smapicomp.c */
NTSTATUS FASTCALL SmCompSes(PSM_PORT_MESSAGE);
NTSTATUS SmCreateApiPort(VOID); NTSTATUS SmCreateApiPort(VOID);
VOID STDCALL SmpApiThread(HANDLE Port); VOID STDCALL SmpApiThread(PVOID);
/* client.c */ /* client.c */
typedef struct _SM_CLIENT_DATA typedef struct _SM_CLIENT_DATA
@ -60,12 +74,14 @@ typedef struct _SM_CLIENT_DATA
BOOL Initialized; BOOL Initialized;
HANDLE ServerProcess; HANDLE ServerProcess;
HANDLE ApiPort; HANDLE ApiPort;
HANDLE ApiPortThread;
HANDLE SbApiPort; HANDLE SbApiPort;
WCHAR SbApiPortName [SM_SB_NAME_MAX_LENGTH]; WCHAR SbApiPortName [SM_SB_NAME_MAX_LENGTH];
struct _SM_CLIENT_DATA * Next; struct _SM_CLIENT_DATA * Next;
} SM_CLIENT_DATA, *PSM_CLIENT_DATA; } SM_CLIENT_DATA, *PSM_CLIENT_DATA;
NTSTATUS SmInitializeClientManagement(VOID); NTSTATUS SmInitializeClientManagement(VOID);
NTSTATUS SmpRegisterSmss(VOID);
NTSTATUS STDCALL SmCreateClient(PSM_PORT_MESSAGE,PSM_CLIENT_DATA*); NTSTATUS STDCALL SmCreateClient(PSM_PORT_MESSAGE,PSM_CLIENT_DATA*);
NTSTATUS STDCALL SmDestroyClient(ULONG); NTSTATUS STDCALL SmDestroyClient(ULONG);
@ -74,6 +90,10 @@ extern HANDLE DbgSsApiPort;
extern HANDLE DbgUiApiPort; extern HANDLE DbgUiApiPort;
NTSTATUS SmInitializeDbgSs(VOID); NTSTATUS SmInitializeDbgSs(VOID);
/* print.c */
VOID STDCALL DisplayString(LPCWSTR lpwString);
VOID STDCALL PrintString (char* fmt, ...);
#endif /* _SMSS_H_INCLUDED_ */ #endif /* _SMSS_H_INCLUDED_ */
/* EOF */ /* EOF */