SM: init system reading the registry

CSR: register with SM for IMAGE_SUBSYSTEM_WINDOWS_CUI

svn path=/trunk/; revision=14244
This commit is contained in:
Emanuele Aliberti 2005-03-20 22:55:05 +00:00
parent 8b0ad6b22f
commit a90ec8327c
14 changed files with 739 additions and 413 deletions

View file

@ -10,16 +10,21 @@
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#define NTOS_MODE_USER
#include <ntos.h>
#include <csrss/csrss.h> #include <csrss/csrss.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <ntdll/rtl.h>
#define NDEBUG
#include <debug.h> #include <debug.h>
#include "api.h" #include "api.h"
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
HANDLE CsrssApiHeap; HANDLE CsrssApiHeap = (HANDLE) 0;
static unsigned ApiDefinitionsCount = 0; static unsigned ApiDefinitionsCount = 0;
static PCSRSS_API_DEFINITION ApiDefinitions = NULL; static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
@ -33,6 +38,8 @@ CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
PCSRSS_API_DEFINITION Scan; PCSRSS_API_DEFINITION Scan;
PCSRSS_API_DEFINITION New; PCSRSS_API_DEFINITION New;
DPRINT("CSR: %s called", __FUNCTION__);
NewCount = 0; NewCount = 0;
for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++) for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
{ {
@ -107,6 +114,8 @@ ClientConnectionThread(HANDLE ServerPort)
PCSRSS_PROCESS_DATA ProcessData; PCSRSS_PROCESS_DATA ProcessData;
PCSRSS_API_REPLY Reply; PCSRSS_API_REPLY Reply;
DPRINT("CSR: %s called", __FUNCTION__);
Reply = NULL; Reply = NULL;
for (;;) for (;;)
@ -153,34 +162,37 @@ ClientConnectionThread(HANDLE ServerPort)
* Handle connection requests from clients to the port * Handle connection requests from clients to the port
* "\Windows\ApiPort". * "\Windows\ApiPort".
*/ */
void STDCALL DWORD STDCALL
ServerApiPortThread (PVOID PortHandle) ServerApiPortThread (PVOID PortHandle)
{ {
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
LPC_MAX_MESSAGE Request; LPC_MAX_MESSAGE Request;
HANDLE ServerPort; HANDLE hApiListenPort = * (PHANDLE) PortHandle;
HANDLE ServerThread; HANDLE ServerPort = (HANDLE) 0;
PCSRSS_PROCESS_DATA ProcessData; HANDLE ServerThread = (HANDLE) 0;
PCSRSS_PROCESS_DATA ProcessData = NULL;
CsrInitProcessData(); CsrInitProcessData();
DPRINT("CSR: %s called", __FUNCTION__);
for (;;) for (;;)
{ {
LPC_SECTION_READ LpcRead; LPC_SECTION_READ LpcRead;
ServerPort = NULL; ServerPort = NULL;
Status = NtListenPort(PortHandle, &Request.Header); Status = NtListenPort (hApiListenPort, & Request.Header);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSR: NtListenPort() failed\n"); DPRINT1("CSR: NtListenPort() failed\n");
break; break;
} }
Status = NtAcceptConnectPort(&ServerPort, Status = NtAcceptConnectPort(& ServerPort,
PortHandle, hApiListenPort,
NULL, NULL,
TRUE, TRUE,
0, 0,
&LpcRead); & LpcRead);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CSR: NtAcceptConnectPort() failed\n"); DPRINT1("CSR: NtAcceptConnectPort() failed\n");
@ -215,7 +227,7 @@ ServerApiPortThread (PVOID PortHandle)
NULL, NULL,
(PTHREAD_START_ROUTINE)ClientConnectionThread, (PTHREAD_START_ROUTINE)ClientConnectionThread,
ServerPort, ServerPort,
&ServerThread, & ServerThread,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -230,6 +242,7 @@ ServerApiPortThread (PVOID PortHandle)
} }
NtClose(PortHandle); NtClose(PortHandle);
NtTerminateThread(NtCurrentThread(), Status); NtTerminateThread(NtCurrentThread(), Status);
return 0;
} }
/********************************************************************** /**********************************************************************
@ -238,45 +251,88 @@ ServerApiPortThread (PVOID PortHandle)
* *
* DESCRIPTION * DESCRIPTION
* Handle connection requests from SM to the port * Handle connection requests from SM to the port
* "\Windows\SbApiPort". * "\Windows\SbApiPort". We will accept only one
* connection request (from the SM).
*/ */
VOID STDCALL DWORD STDCALL
ServerSbApiPortThread (PVOID PortHandle) ServerSbApiPortThread (PVOID PortHandle)
{ {
HANDLE hSbApiPortListen = (HANDLE) PortHandle; HANDLE hSbApiPortListen = * (PHANDLE) PortHandle;
HANDLE hConnectedPort = (HANDLE) 0; HANDLE hConnectedPort = (HANDLE) 0;
LPC_MAX_MESSAGE Request = {{0}}; LPC_MAX_MESSAGE Request = {{0}};
PVOID Context = NULL;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
while (TRUE) DPRINT("CSR: %s called\n", __FUNCTION__);
Status = NtListenPort (hSbApiPortListen, & Request.Header);
if (!NT_SUCCESS(Status))
{ {
Status = NtListenPort (hSbApiPortListen, & Request.Header); DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
if (!NT_SUCCESS(Status)) __FUNCTION__, Status);
{ } else {
DPRINT1("CSR: %s: NtListenPort(SB) failed\n", __FUNCTION__); DPRINT("-- 1\n");
break;
}
Status = NtAcceptConnectPort (& hConnectedPort, Status = NtAcceptConnectPort (& hConnectedPort,
hSbApiPortListen, hSbApiPortListen,
NULL, NULL,
TRUE, TRUE,
NULL, NULL,
NULL); NULL);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
DPRINT1("CSR: %s: NtAcceptConnectPort() failed\n", __FUNCTION__); DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
break; __FUNCTION__, Status);
} else {
DPRINT("-- 2\n");
Status = NtCompleteConnectPort (hConnectedPort);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
} else {
DPRINT("-- 3\n");
PLPC_MESSAGE Reply = NULL;
/*
* Tell the init thread the SM gave the
* green light for boostrapping.
*/
Status = NtSetEvent (hBootstrapOk, NULL);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
}
/* Wait for messages from the SM */
DPRINT("-- 4\n");
while (TRUE)
{
Status = NtReplyWaitReceivePort(hConnectedPort,
Context,
Reply,
& Request.Header);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
break;
}
switch (Request.Header.MessageType)//fix .h PORT_MESSAGE_TYPE(Request))
{
/* TODO */
default:
DPRINT1("CSR: %s received message (type=%d)\n",
__FUNCTION__, Request.Header.MessageType);
}
DPRINT("-- 5\n");
}
}
} }
Status = NtCompleteConnectPort (hConnectedPort);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: NtCompleteConnectPort() failed\n", __FUNCTION__);
break;
}
/* TODO: create thread for the connected port */
} }
DPRINT1("CSR: %s: terminating!\n", __FUNCTION__);
if(hConnectedPort) NtClose (hConnectedPort);
NtClose (hSbApiPortListen); NtClose (hSbApiPortListen);
NtTerminateThread (NtCurrentThread(), Status); NtTerminateThread (NtCurrentThread(), Status);
return 0;
} }
/* EOF */ /* EOF */

View file

@ -35,6 +35,7 @@
#include <ntdll/rtl.h> #include <ntdll/rtl.h>
#include <csrss/csrss.h> #include <csrss/csrss.h>
#include <rosrtl/string.h> #include <rosrtl/string.h>
#include <reactos/buildno.h>
#include "api.h" #include "api.h"
@ -145,78 +146,37 @@ CsrpFreeCommandLine (HANDLE ProcessHeap,
} }
/**********************************************************************
* NAME PRIVATE
* CsrpOpenSmInitDoneEvent/0
*/
static NTSTATUS STDCALL
CsrpOpenSmInitDoneEvent (PHANDLE CsrssInitEvent)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING EventName;
DPRINT("CSR: %s called\n", __FUNCTION__);
RtlInitUnicodeString(& EventName,
L"\\CsrssInitDone");
InitializeObjectAttributes (& ObjectAttributes,
& EventName,
EVENT_ALL_ACCESS,
0,
NULL);
return NtOpenEvent (CsrssInitEvent,
EVENT_ALL_ACCESS,
& ObjectAttributes);
}
/* Native process' entry point */ /* Native process' entry point */
VOID STDCALL NtProcessStartup(PPEB Peb) VOID STDCALL NtProcessStartup(PPEB Peb)
{ {
PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL; PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL;
COMMAND_LINE_ARGUMENT CmdLineArg = {0}; COMMAND_LINE_ARGUMENT CmdLineArg = {0};
HANDLE CsrssInitEvent = (HANDLE) 0;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSR: %s\n", __FUNCTION__); PrintString("ReactOS Client/Server Run-Time %s (Build %s)\n",
KERNEL_RELEASE_STR,
KERNEL_VERSION_BUILD_STR);
RtlProcessParameters = RtlNormalizeProcessParams (Peb->ProcessParameters); RtlProcessParameters = RtlNormalizeProcessParams (Peb->ProcessParameters);
/*================================================================== /*==================================================================
* Parse the command line. * Parse the command line: TODO actually parse the cl, because
* it is required to load hosted server DLLs.
*================================================================*/ *================================================================*/
Status = CsrpParseCommandLine (Peb->ProcessHeap, Status = CsrpParseCommandLine (Peb->ProcessHeap,
RtlProcessParameters, RtlProcessParameters,
& CmdLineArg); & CmdLineArg);
if(STATUS_SUCCESS != Status) if(STATUS_SUCCESS != Status)
{ {
DbgPrint("CSR: CsrpParseCommandLine failed (Status=0x%08lx)\n", DPRINT1("CSR: %s: CsrpParseCommandLine failed (Status=0x%08lx)\n",
Status); __FUNCTION__, Status);
} }
/*
* Open the SM notification event to notify we are OK after
* subsystem server initialization.
*/
Status = CsrpOpenSmInitDoneEvent(& CsrssInitEvent);
if (!NT_SUCCESS(Status))
{
DbgPrint("CSR: CsrpOpenSmInitDoneEvent failed (Status=0x%08lx)\n",
Status);
}
/*================================================================== /*==================================================================
* Initialize the Win32 environment subsystem server. * Initialize the Win32 environment subsystem server.
*================================================================*/ *================================================================*/
if (CsrServerInitialization (CmdLineArg.Count, CmdLineArg.Vector) == TRUE) if (CsrServerInitialization (CmdLineArg.Count, CmdLineArg.Vector) == TRUE)
{ {
/*=============================================================
* Tell SM we are up and safe. If we fail to notify SM, it will
* die and the kernel will bugcheck with
* SESSION5_INITIALIZATION_FAILED.
* TODO: this won't be necessary, because CSR will call SM
* API SM_SESSION_COMPLETE.
*===========================================================*/
NtSetEvent (CsrssInitEvent, NULL);
CsrpFreeCommandLine (Peb->ProcessHeap, & CmdLineArg); CsrpFreeCommandLine (Peb->ProcessHeap, & CmdLineArg);
/* /*
* Terminate the current thread only. * Terminate the current thread only.

View file

@ -82,6 +82,9 @@ PCSRSS_PROCESS_DATA ProcessData,\
PCSRSS_API_REQUEST Request,\ PCSRSS_API_REQUEST Request,\
PCSRSS_API_REPLY Reply) PCSRSS_API_REPLY Reply)
/* init.c */
extern HANDLE hBootstrapOk;
/* api/process.c */ /* api/process.c */
CSR_API(CsrConnectProcess); CSR_API(CsrConnectProcess);
CSR_API(CsrCreateProcess); CSR_API(CsrCreateProcess);
@ -96,9 +99,9 @@ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions
VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData, VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
PCSRSS_API_REQUEST Request, PCSRSS_API_REQUEST Request,
PCSRSS_API_REPLY Reply); PCSRSS_API_REPLY Reply);
VOID STDCALL ServerApiPortThread (PVOID PortHandle); DWORD STDCALL ServerApiPortThread (PVOID PortHandle);
VOID STDCALL ServerSbApiPortThread (PVOID PortHandle); DWORD STDCALL ServerSbApiPortThread (PVOID PortHandle);
VOID Console_Api( DWORD Ignored ); DWORD STDCALL Console_Api( PVOID unused );
extern HANDLE CsrssApiHeap; extern HANDLE CsrssApiHeap;

View file

@ -27,10 +27,9 @@
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
HANDLE CsrInitEvent = INVALID_HANDLE_VALUE; HANDLE CsrHeap = (HANDLE) 0;
HANDLE CsrHeap = INVALID_HANDLE_VALUE;
HANDLE CsrObjectDirectory = INVALID_HANDLE_VALUE; HANDLE CsrObjectDirectory = (HANDLE) 0;
UNICODE_STRING CsrDirectoryName; UNICODE_STRING CsrDirectoryName;
@ -39,11 +38,24 @@ extern HANDLE CsrssApiHeap;
static unsigned InitCompleteProcCount; static unsigned InitCompleteProcCount;
static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL; static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
HANDLE hSbApiPort = (HANDLE) 0;
HANDLE hBootstrapOk = (HANDLE) 0;
HANDLE hSmApiPort = (HANDLE) 0;
HANDLE hApiPort = (HANDLE) 0;
/**********************************************************************
* CsrpAddInitCompleteProc/1
*/
static NTSTATUS FASTCALL static NTSTATUS FASTCALL
AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
{ {
CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs; CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs;
DPRINT("CSR: %s called\n", __FUNCTION__);
NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
(InitCompleteProcCount + 1) (InitCompleteProcCount + 1)
* sizeof(CSRPLUGIN_INIT_COMPLETE_PROC)); * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
@ -64,12 +76,17 @@ AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/**********************************************************************
* CallInitComplete/0
*/
static BOOL FASTCALL static BOOL FASTCALL
CallInitComplete(void) CallInitComplete(void)
{ {
BOOL Ok; BOOL Ok;
unsigned i; unsigned i;
DPRINT("CSR: %s called\n", __FUNCTION__);
Ok = TRUE; Ok = TRUE;
if (0 != InitCompleteProcCount) if (0 != InitCompleteProcCount)
{ {
@ -86,8 +103,11 @@ CallInitComplete(void)
ULONG ULONG
InitializeVideoAddressSpace(VOID); InitializeVideoAddressSpace(VOID);
/**********************************************************************
* CsrpParseCommandLine/2
*/
static NTSTATUS static NTSTATUS
CsrParseCommandLine ( CsrpParseCommandLine (
ULONG ArgumentCount, ULONG ArgumentCount,
PWSTR *ArgumentArray PWSTR *ArgumentArray
) )
@ -95,6 +115,8 @@ CsrParseCommandLine (
NTSTATUS Status; NTSTATUS Status;
OBJECT_ATTRIBUTES Attributes; OBJECT_ATTRIBUTES Attributes;
DPRINT("CSR: %s called\n", __FUNCTION__);
/* DbgPrint ("Arguments: %ld\n", ArgumentCount); /* DbgPrint ("Arguments: %ld\n", ArgumentCount);
for (i = 0; i < ArgumentCount; i++) for (i = 0; i < ArgumentCount; i++)
@ -114,21 +136,28 @@ CsrParseCommandLine (
NULL); NULL);
Status = NtCreateDirectoryObject(&CsrObjectDirectory, Status = NtCreateDirectoryObject(&CsrObjectDirectory,
0xF000F, 0xF000F, /* ea:??? */
&Attributes); &Attributes);
return Status; return Status;
} }
/**********************************************************************
static VOID * CsrpInitVideo/0
CsrInitVideo(VOID) *
* TODO: we need a virtual device for sessions other than
* TODO: the console one
*/
static NTSTATUS
CsrpInitVideo (ULONG argc, PWSTR* argv)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DeviceName; UNICODE_STRING DeviceName;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
HANDLE VideoHandle; HANDLE VideoHandle = (HANDLE) 0;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSR: %s called\n", __FUNCTION__);
InitializeVideoAddressSpace(); InitializeVideoAddressSpace();
@ -148,10 +177,23 @@ CsrInitVideo(VOID)
{ {
NtClose(VideoHandle); NtClose(VideoHandle);
} }
return Status;
} }
static NTSTATUS FASTCALL /**********************************************************************
InitWin32Csr() * CsrpInitWin32Csr/0
*
* TODO: this function should be turned more general to load an
* TODO: hosted server DLL as received from the command line;
* TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
* TODO: ^method ^dll ^api ^sid
* TODO:
* TODO: CsrpHostServerDll (LPWSTR DllName,
* TODO: LPWSTR ApiName,
* TODO: DWORD ServerId)
*/
static NTSTATUS
CsrpInitWin32Csr (ULONG argc, PWSTR* argv)
{ {
NTSTATUS Status; NTSTATUS Status;
UNICODE_STRING DllName; UNICODE_STRING DllName;
@ -163,6 +205,8 @@ InitWin32Csr()
PCSRSS_OBJECT_DEFINITION ObjectDefinitions; PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc; CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
DPRINT("CSR: %s called\n", __FUNCTION__);
RtlInitUnicodeString(&DllName, L"win32csr.dll"); RtlInitUnicodeString(&DllName, L"win32csr.dll");
Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst); Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
@ -196,7 +240,7 @@ InitWin32Csr()
} }
if (NULL != InitCompleteProc) if (NULL != InitCompleteProc)
{ {
Status = AddInitCompleteProc(InitCompleteProc); Status = CsrpAddInitCompleteProc(InitCompleteProc);
} }
return Status; return Status;
@ -219,157 +263,292 @@ CSRSS_API_DEFINITION NativeDefinitions[] =
{ 0, 0, 0, NULL } { 0, 0, 0, NULL }
}; };
/********************************************************************** static NTSTATUS STDCALL
* NAME CsrpCreateListenPort (IN LPWSTR Name,
* CsrpRegisterSubsystem/0 IN OUT PHANDLE Port,
* IN PTHREAD_START_ROUTINE ListenThread)
* DESCRIPTION
* Register CSRSS in the SM to manage IMAGE_SUBSYSTEM_WINDOWS_CUI
* processes (environment subsystem server).
*
* RETURN VALUE
* STATUS_SUCCESS on success.
*/
static NTSTATUS FASTCALL
CsrpRegisterSubsystem(PHANDLE hSmApiPort)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING SbApiPortName; OBJECT_ATTRIBUTES PortAttributes;
UNICODE_STRING PortName;
RtlInitUnicodeString (& SbApiPortName, L"\\Windows\\SbApiPort"); DPRINT("CSR: %s called\n", __FUNCTION__);
Status = SmConnectApiPort (& SbApiPortName,
(HANDLE)-1, //unused RtlInitUnicodeString (& PortName, Name);
IMAGE_SUBSYSTEM_WINDOWS_CUI, InitializeObjectAttributes (& PortAttributes,
hSmApiPort); & PortName,
0,
NULL,
NULL);
Status = NtCreatePort ( Port,
& PortAttributes,
260, /* TODO: make caller set it*/
328, /* TODO: make caller set it*/
0); /* TODO: make caller set it*/
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
DPRINT("CSR: unable to connect to the SM (Status=0x%lx)\n", Status); DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status; return Status;
} }
DisplayString(L"CSR: registered with SM\n"); Status = RtlCreateUserThread(NtCurrentProcess(),
NULL,
FALSE,
0,
NULL,
NULL,
(PTHREAD_START_ROUTINE) ListenThread,
Port,
NULL,
NULL);
return Status;
}
/* === INIT ROUTINES === */
/**********************************************************************
* CsrpCreateCallbackPort/0
*/
static NTSTATUS
CsrpCreateHeap (ULONG argc, PWSTR* argv)
{
DPRINT("CSR: %s called\n", __FUNCTION__);
CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
NULL,
65536,
65536,
NULL,
NULL);
if (CsrssApiHeap == NULL)
{
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
/**********************************************************************
* CsrpCreateCallbackPort/0
*/
static NTSTATUS
CsrpCreateCallbackPort (ULONG argc, PWSTR* argv)
{
DPRINT("CSR: %s called\n", __FUNCTION__);
return CsrpCreateListenPort (L"\\Windows\\SbApiPort",
& hSbApiPort,
ServerSbApiPortThread);
}
/**********************************************************************
* CsrpRegisterSubsystem/2
*/
static NTSTATUS
CsrpRegisterSubsystem (ULONG argc, PWSTR* argv)
{
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES BootstrapOkAttributes;
UNICODE_STRING Name;
DPRINT("CSR: %s called\n", __FUNCTION__);
/*
* Create the event object the callback port
* thread will signal *if* the SM will
* authorize us to bootstrap.
*/
RtlInitUnicodeString (& Name, L"\\CsrssBooting");
InitializeObjectAttributes(& BootstrapOkAttributes,
& Name,
0, NULL, NULL);
Status = NtCreateEvent (& hBootstrapOk,
EVENT_ALL_ACCESS,
& BootstrapOkAttributes,
SynchronizationEvent,
FALSE);
if(!NT_SUCCESS(Status))
{
DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/*
* Let's tell the SM a new environment
* subsystem server is in the system.
*/
RtlInitUnicodeString (& Name, L"\\Windows\\SbApiPort");
DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__);
Status = SmConnectApiPort (& Name,
hSbApiPort,
IMAGE_SUBSYSTEM_WINDOWS_CUI,
& hSmApiPort);
if(!NT_SUCCESS(Status))
{
DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
__FUNCTION__, Status);
NtClose (hBootstrapOk);
return Status;
}
/*
* Wait for SM to reply OK... If the SM
* won't answer, we hang here forever!
*/
DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__);
Status = NtWaitForSingleObject (hBootstrapOk,
FALSE,
NULL);
NtClose (hBootstrapOk);
return Status; return Status;
} }
/**********************************************************************
* CsrpCreateApiPort/0
*/
static NTSTATUS
CsrpCreateApiPort (ULONG argc, PWSTR* argv)
{
DPRINT("CSR: %s called\n", __FUNCTION__);
return CsrpCreateListenPort (L"\\Windows\\ApiPort",
& hApiPort,
ServerApiPortThread);
}
/**********************************************************************
* CsrpApiRegisterDef/0
*/
static NTSTATUS
CsrpApiRegisterDef (ULONG argc, PWSTR* argv)
{
return CsrApiRegisterDefinitions(NativeDefinitions);
}
/**********************************************************************
* CsrpCCTS/2
*/
static NTSTATUS
CsrpCCTS (ULONG argc, PWSTR* argv)
{
return CsrClientConnectToServer();
}
/**********************************************************************
* CsrpRunWinlogon/0
*
* Start the logon process (winlogon.exe).
*
* TODO: this should be moved in CsrpCreateSession/x (one per session)
* TODO: in its own desktop (one logon desktop per winstation).
*/
static NTSTATUS
CsrpRunWinlogon (ULONG argc, PWSTR* argv)
{
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ImagePath;
UNICODE_STRING CommandLine;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
RTL_PROCESS_INFO ProcessInfo;
DPRINT("CSR: %s called\n", __FUNCTION__);
/* initialize the process parameters */
RtlInitUnicodeString (& ImagePath, L"\\SystemRoot\\system32\\winlogon.exe");
RtlInitUnicodeString (& CommandLine, L"");
RtlCreateProcessParameters(& ProcessParameters,
& ImagePath,
NULL,
NULL,
& CommandLine,
NULL,
NULL,
NULL,
NULL,
NULL);
/* Create the winlogon process */
Status = RtlCreateUserProcess (& ImagePath,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL,
NULL,
NULL,
FALSE,
NULL,
NULL,
& ProcessInfo);
/* Cleanup */
RtlDestroyProcessParameters (ProcessParameters);
if (!NT_SUCCESS(Status))
{
DPRINT("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
__FUNCTION__, Status);
}
return Status;
}
typedef NTSTATUS (* CSR_INIT_ROUTINE)(ULONG, PWSTR*);
struct {
BOOL Required;
CSR_INIT_ROUTINE EntryPoint;
PCHAR ErrorMessage;
} InitRoutine [] = {
{TRUE, CsrpCreateCallbackPort, "create the callback port \\Windows\\SbApiPort"},
{TRUE, CsrpRegisterSubsystem, "register with SM"},
{TRUE, CsrpCreateHeap, "create the CSR heap"},
{TRUE, CsrpCreateApiPort, "create the api port \\Windows\\ApiPort"},
{TRUE, CsrpParseCommandLine, "parse the command line"},
{TRUE, CsrpInitVideo, "initialize video"},
{TRUE, CsrpApiRegisterDef, "initialize api definitions"},
{TRUE, CsrpCCTS, "connect client to server"},
{TRUE, CsrpInitWin32Csr, "load usermode dll"},
{TRUE, CsrpRunWinlogon, "run WinLogon"},
};
/********************************************************************** /**********************************************************************
* NAME * NAME
* CsrServerInitialization * CsrServerInitialization
* *
* DESCRIPTION * DESCRIPTION
* Create a directory object (\windows) and a named LPC port * Initialize the Win32 environment subsystem server.
* (\windows\ApiPort)
* *
* RETURN VALUE * RETURN VALUE
* TRUE: Initialization OK; otherwise FALSE. * TRUE: Initialization OK; otherwise FALSE.
*/ */
BOOL BOOL STDCALL
STDCALL
CsrServerInitialization ( CsrServerInitialization (
ULONG ArgumentCount, ULONG ArgumentCount,
PWSTR *ArgumentArray PWSTR *ArgumentArray
) )
{ {
NTSTATUS Status; INT i = 0;
HANDLE hSmApiPort = (HANDLE) 0; NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObAttributes;
UNICODE_STRING PortName;
HANDLE ApiPortHandle;
// HANDLE hSbApiPort = (HANDLE) 0;
DisplayString(L"CSR: CsrServerInitialization\n"); DPRINT("CSR: %s called\n", __FUNCTION__);
Status = CsrpRegisterSubsystem(& hSmApiPort); for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
if (! NT_SUCCESS(Status)) {
{ Status = InitRoutine[i].EntryPoint(ArgumentCount,ArgumentArray);
DPRINT1("CSR: Unable to register subsystem (Status: %x)\n", Status); if(!NT_SUCCESS(Status))
return FALSE; {
} DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
__FUNCTION__,
Status = CsrParseCommandLine (ArgumentCount, ArgumentArray); InitRoutine[i].ErrorMessage,
if (! NT_SUCCESS(Status)) Status);
{ if (InitRoutine[i].Required)
DPRINT1("CSR: Unable to parse the command line (Status: %x)\n", Status); {
return FALSE; return FALSE;
} }
}
CsrInitVideo(); }
if (CallInitComplete())
CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE, {
NULL, Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort);
65536, return TRUE;
65536, }
NULL, return FALSE;
NULL);
if (CsrssApiHeap == NULL)
{
DPRINT1("CSR: Failed to create private heap, aborting\n");
return FALSE;
}
Status = CsrApiRegisterDefinitions(NativeDefinitions);
if (! NT_SUCCESS(Status))
{
return Status;
}
/* NEW NAMED PORT: \Windows\ApiPort */
RtlRosInitUnicodeStringFromLiteral(&PortName, L"\\Windows\\ApiPort");
InitializeObjectAttributes(&ObAttributes,
&PortName,
0,
NULL,
NULL);
Status = NtCreatePort(&ApiPortHandle,
&ObAttributes,
260,
328,
0);
if (! NT_SUCCESS(Status))
{
DPRINT1("CSR: Unable to create \\Windows\\ApiPort (Status %x)\n", Status);
return FALSE;
}
Status = RtlCreateUserThread(NtCurrentProcess(),
NULL,
FALSE,
0,
NULL,
NULL,
(PTHREAD_START_ROUTINE)ServerApiPortThread,
ApiPortHandle,
NULL,
NULL);
if (! NT_SUCCESS(Status))
{
DPRINT1("CSR: Unable to create server thread\n");
NtClose(ApiPortHandle);
return FALSE;
}
/* TODO: create \Windows\SbApiPort */
Status = CsrClientConnectToServer();
if (!NT_SUCCESS(Status))
{
DPRINT1("CsrClientConnectToServer() failed (Status %x)\n", Status);
return FALSE;
}
Status = InitWin32Csr();
if (! NT_SUCCESS(Status))
{
DPRINT1("CSR: Unable to load usermode dll (Status %x)\n", Status);
return FALSE;
}
if (CallInitComplete())
{
#if 0
Status = SmCompleteSession (hSmApiPort,hSbApiPort,ApiPortHandle);
#endif
NtClose (hSmApiPort);
return TRUE;
}
return FALSE;
} }
/* EOF */ /* EOF */

View file

@ -1381,8 +1381,8 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
} }
} }
VOID DWORD STDCALL
Console_Api(DWORD RefreshEvent) Console_Api (PVOID unused)
{ {
/* keep reading events from the keyboard and stuffing them into the current /* keep reading events from the keyboard and stuffing them into the current
console's input queue */ console's input queue */
@ -1409,6 +1409,7 @@ Console_Api(DWORD RefreshEvent)
} }
PrivateCsrssAcquireOrReleaseInputOwnership(TRUE); PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
return 0;
} }
CSR_API(CsrGetScreenBufferInfo) CSR_API(CsrGetScreenBufferInfo)

View file

@ -99,6 +99,37 @@ SmCompleteClientInitialization (HANDLE hProcess)
* SIDE EFFECTS * SIDE EFFECTS
* SmpClientDirectory.Lock is released only on success. * SmpClientDirectory.Lock is released only on success.
*/ */
static PSM_CLIENT_DATA FASTCALL
SmpLookupClientUnsafe (USHORT SubsystemId,
PSM_CLIENT_DATA * Parent)
{
PSM_CLIENT_DATA Client = NULL;
DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId);
if(NULL != Parent)
{
*Parent = NULL;
}
if (SmpClientDirectory.Count > 0)
{
Client = SmpClientDirectory.Client;
while (NULL != Client)
{
if (SubsystemId == Client->SubsystemId)
{
break;
}
if(NULL != Parent)
{
*Parent = Client;
}
Client = Client->Next;
}
}
return Client;
}
static PSM_CLIENT_DATA STDCALL static PSM_CLIENT_DATA STDCALL
SmpLookupClient (USHORT SubsystemId) SmpLookupClient (USHORT SubsystemId)
{ {
@ -107,18 +138,10 @@ SmpLookupClient (USHORT SubsystemId)
DPRINT("SM: %s called\n", __FUNCTION__); DPRINT("SM: %s called\n", __FUNCTION__);
RtlEnterCriticalSection (& SmpClientDirectory.Lock); RtlEnterCriticalSection (& SmpClientDirectory.Lock);
if (SmpClientDirectory.Count > 0) Client = SmpLookupClientUnsafe (SubsystemId, NULL);
if(NULL != Client)
{ {
Client = SmpClientDirectory.Client; RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
while (NULL != Client)
{
if (SubsystemId == Client->SubsystemId)
{
RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
return Client;
}
Client = Client->Next;
}
} }
/* /*
* Note that we do *not* release SmpClientDirectory.Lock here * Note that we do *not* release SmpClientDirectory.Lock here
@ -135,7 +158,7 @@ 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 = SmpGetConnectData (Request);
ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request); ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);
DPRINT("SM: %s called\n", __FUNCTION__); DPRINT("SM: %s called\n", __FUNCTION__);
@ -206,16 +229,51 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
/********************************************************************** /**********************************************************************
* SmpDestroyClient/1 * SmpDestroyClient/1
*
* 1. close any handle
* 2. kill client process
* 3. release resources
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
SmDestroyClient (ULONG SubsystemId) SmDestroyClient (ULONG SubsystemId)
{ {
NTSTATUS Status = STATUS_SUCCESS;
PSM_CLIENT_DATA Parent = NULL;
PSM_CLIENT_DATA Client = NULL;
DPRINT("SM: %s called\n", __FUNCTION__); DPRINT("SM: %s called\n", __FUNCTION__);
RtlEnterCriticalSection (& SmpClientDirectory.Lock); RtlEnterCriticalSection (& SmpClientDirectory.Lock);
/* TODO */ Client = SmpLookupClientUnsafe (SubsystemId, & Parent);
if(NULL == Client)
{
DPRINT1("SM: %s: del req for non existent subsystem (id=%d)\n",
__FUNCTION__, SubsystemId);
Status = STATUS_NOT_FOUND;
}
else
{
/* 1st in the list? */
if(NULL == Parent)
{
SmpClientDirectory.Client = Client->Next;
}
else
{
if(NULL != Parent)
{
Parent->Next = Client->Next;
} else {
DPRINT1("SM: %s: n-th has no parent!\n", __FUNCTION__);
Status = STATUS_UNSUCCESSFUL; /* FIXME */
}
}
/* TODO: send shutdown or kill */
RtlFreeHeap (SmpHeap, 0, Client);
-- SmpClientDirectory.Count;
}
RtlLeaveCriticalSection (& SmpClientDirectory.Lock); RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
return STATUS_SUCCESS; return Status;
} }
/* EOF */ /* EOF */

View file

@ -39,7 +39,7 @@ SmpSignalInitEvent(VOID)
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObjectAttributes = {0}; OBJECT_ATTRIBUTES ObjectAttributes = {0};
UNICODE_STRING EventName ={0}; UNICODE_STRING EventName ={0};
HANDLE ReactOSInitEvent = NULL; HANDLE ReactOSInitEvent = (HANDLE) 0;
RtlInitUnicodeString (& EventName, L"\\ReactOSInitDone"); RtlInitUnicodeString (& EventName, L"\\ReactOSInitDone");
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
@ -92,16 +92,13 @@ struct {
{TRUE, SmInitializeClientManagement, "initialize client management"}, {TRUE, SmInitializeClientManagement, "initialize client management"},
{TRUE, SmLoadSubsystems, "load subsystems"}, {TRUE, SmLoadSubsystems, "load subsystems"},
{FALSE, SmpSignalInitEvent, "open ReactOS init notification event"}, {FALSE, SmpSignalInitEvent, "open ReactOS init notification event"},
{TRUE, SmRunCsrss, "run csrss"},
{TRUE, SmRunWinlogon, "run winlogon"},
{TRUE, SmInitializeDbgSs, "initialize DbgSs"}
}; };
NTSTATUS NTSTATUS
InitSessionManager(VOID) InitSessionManager(VOID)
{ {
int i; INT i = 0;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++) for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
{ {
@ -118,8 +115,6 @@ InitSessionManager(VOID)
} }
} }
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }

View file

@ -41,15 +41,9 @@ HANDLE hSmApiPort = (HANDLE) 0;
* a) look if a special option is set for smss.exe in * a) look if a special option is set for smss.exe in
* HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
* *
* b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
* (programmatically)
*
* 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
*
* e) make optional subsystems loadable (again: they must be described in the registry
* key Optional="Posix Os2" to be allowed to run)
*/ */
/********************************************************************** /**********************************************************************
@ -67,16 +61,17 @@ SmpRegisterSmss(VOID)
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING SbApiPortName = {0,0,NULL}; UNICODE_STRING SbApiPortName = {0,0,NULL};
DPRINT("SM: %s called\n",__FUNCTION__); DPRINT("SM: %s called\n",__FUNCTION__);
RtlInitUnicodeString (& SbApiPortName, L""); RtlInitUnicodeString (& SbApiPortName, L"");
Status = SmConnectApiPort(& SbApiPortName, Status = SmConnectApiPort(& SbApiPortName,
(HANDLE) 0, (HANDLE) -1, /* SM has no SB port */
IMAGE_SUBSYSTEM_NATIVE, IMAGE_SUBSYSTEM_NATIVE,
& hSmApiPort); & hSmApiPort);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n", DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",
__FUNCTION__,Status); __FUNCTION__,Status);
return Status; return Status;
} }
@ -91,27 +86,19 @@ SmpRegisterSmss(VOID)
/********************************************************************** /**********************************************************************
* SmpLoadKernelModeSubsystem/0
*/ */
NTSTATUS static NTSTATUS
SmLoadSubsystems(VOID) SmpLoadKernelModeSubsystem (VOID)
{ {
SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo; NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS Status = STATUS_SUCCESS; WCHAR Data [MAX_PATH + 1];
WCHAR Data [MAX_PATH + 1]; ULONG DataLength = sizeof Data;
ULONG DataLength = sizeof Data; ULONG DataType = 0;
ULONG DataType = 0;
DPRINT("SM: loading subsystems\n"); DPRINT("SM: %s called\n", __FUNCTION__);
/* SM self registers */
Status = SmpRegisterSmss();
if(!NT_SUCCESS(Status))
{
DPRINT1("SM: SM failed to self register: system is not secure!\n");
}
/* Load Kmode subsystem (aka win32k.sys) */
Status = SmLookupSubsystem (L"Kmode", Status = SmLookupSubsystem (L"Kmode",
Data, Data,
& DataLength, & DataLength,
@ -119,128 +106,101 @@ SmLoadSubsystems(VOID)
TRUE); TRUE);
if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0])) if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
{ {
WCHAR ImagePath [MAX_PATH + 1] = {0}; WCHAR ImagePath [MAX_PATH + 1] = {0};
SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
wcscpy (ImagePath, L"\\??\\"); wcscpy (ImagePath, L"\\??\\");
wcscat (ImagePath, Data); wcscat (ImagePath, Data);
RtlZeroMemory (& ImageInfo, sizeof ImageInfo); RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath); RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
Status = NtSetSystemInformation(SystemLoadAndCallImage, Status = NtSetSystemInformation(SystemLoadAndCallImage,
& ImageInfo, & ImageInfo,
sizeof ImageInfo); sizeof ImageInfo);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n", DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",
Status); __FUNCTION__, Status);
return Status;
} }
} }
/* TODO: load Required subsystems (Debug Windows) */
#if 0
Status = SmExecuteProgram (hSmApiPort, L"DEBUG");
if(!NT_SUCCESS(Status))
{
DPRINT1("SM: DBSS failed to initialize!\n");
}
#endif
return Status; return Status;
} }
NTSTATUS /**********************************************************************
SmRunCsrss(VOID) * SmpLoadRequiredSubsystems/0
*/
static NTSTATUS
SmpLoadRequiredSubsystems (VOID)
{ {
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING UnicodeString; WCHAR Data [MAX_PATH + 1];
OBJECT_ATTRIBUTES ObjectAttributes; ULONG DataLength = sizeof Data;
RTL_PROCESS_INFO ProcessInfo; ULONG DataType = 0;
HANDLE CsrssInitEvent;
WCHAR ImagePath [MAX_PATH];
DPRINT("SM: initializing csrss\n");
DPRINT("SM: %s called\n", __FUNCTION__);
/* Run csrss.exe */ RtlZeroMemory (Data, DataLength);
RtlRosInitUnicodeStringFromLiteral(&UnicodeString, Status = SmLookupSubsystem (L"Required",
L"\\CsrssInitDone"); Data,
InitializeObjectAttributes(&ObjectAttributes, & DataLength,
&UnicodeString, & DataType,
EVENT_ALL_ACCESS, FALSE);
0, if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
NULL); {
Status = NtCreateEvent(&CsrssInitEvent, PWCHAR Name = NULL;
EVENT_ALL_ACCESS, ULONG Offset = 0;
&ObjectAttributes,
NotificationEvent, for (Name = Data; (Offset < DataLength); )
FALSE); {
if (!NT_SUCCESS(Status)) if(L'\0' != *Name)
{ {
DbgPrint("Failed to create csrss notification event\n"); UNICODE_STRING Program;
}
/* /* Run the current program */
* Start the Win32 subsystem (csrss.exe) RtlInitUnicodeString (& Program, Name);
*/ Status = SmExecuteProgram (hSmApiPort, & Program);
if(!NT_SUCCESS(Status))
{
DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",
__FUNCTION__, Name, Status);
}
/* Look for the next program */
while ((L'\0' != *Name) && (Offset < DataLength))
{
++ Name;
++ Offset;
}
}
++ Name;
++ Offset;
}
}
/* initialize executable path */ return Status;
wcscpy(ImagePath, L"\\??\\");
wcscat(ImagePath, SharedUserData->NtSystemRoot);
wcscat(ImagePath, L"\\system32\\csrss.exe");
Status = SmCreateUserProcess(ImagePath,
L"",
FALSE, /* wait */
NULL,
FALSE, /* terminate */
& ProcessInfo);
if (!NT_SUCCESS(Status))
{
DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);
return(Status);
}
Status = NtWaitForSingleObject(CsrssInitEvent,
FALSE,
NULL);
Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
return Status;
} }
/**********************************************************************
* SmLoadSubsystems/0
*/
NTSTATUS NTSTATUS
SmRunWinlogon(VOID) SmLoadSubsystems(VOID)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
RTL_PROCESS_INFO ProcessInfo;
WCHAR ImagePath [MAX_PATH];
/*
* Start the logon process (winlogon.exe) DPRINT("SM: loading subsystems\n");
*/
DPRINT("SM: starting winlogon\n"); /* SM self registers */
Status = SmpRegisterSmss();
/* initialize executable path */ if(!NT_SUCCESS(Status)) return Status;
wcscpy(ImagePath, L"\\??\\"); /* Load Kmode subsystem (aka win32k.sys) */
wcscat(ImagePath, SharedUserData->NtSystemRoot); Status = SmpLoadKernelModeSubsystem();
wcscat(ImagePath, L"\\system32\\winlogon.exe"); if(!NT_SUCCESS(Status)) return Status;
/* Load Required subsystems (Debug Windows) */
Status = SmCreateUserProcess(ImagePath, Status = SmpLoadRequiredSubsystems();
L"", if(!NT_SUCCESS(Status)) return Status;
FALSE, /* wait */ /* done */
NULL, return Status;
FALSE, /* terminate */
& ProcessInfo);
if (!NT_SUCCESS(Status))
{
DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);
NtTerminateProcess(Children[CHILD_CSRSS], 0);
return(Status);
}
Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
return Status;
} }
/* EOF */ /* EOF */

View file

@ -21,7 +21,7 @@ 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 smapicomp.o smapiexec.o \ smapi.o smapicomp.o smapiexec.o smapiquery.o \
client.o debug.o print.o client.o debug.o print.o
include $(PATH_TO_TOP)/rules.mak include $(PATH_TO_TOP)/rules.mak

View file

@ -34,14 +34,63 @@ SM_PORT_API SmApi [] =
SmCompSes, /* smapicomp.c */ SmCompSes, /* smapicomp.c */
SmInvalid, /* obsolete */ SmInvalid, /* obsolete */
SmInvalid, /* unknown */ SmInvalid, /* unknown */
SmExecPgm /* smapiexec.c */ SmExecPgm, /* smapiexec.c */
SmQryInfo /* smapyqry.c */
}; };
/* TODO: optimize this address computation (it should be done
* with a macro) */
PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE Request)
{
PLPC_MAX_MESSAGE LpcMaxMessage = (PLPC_MAX_MESSAGE) Request;
return (PSM_CONNECT_DATA) & LpcMaxMessage->Data[0];
}
#if !defined(__USE_NT_LPC__) #if !defined(__USE_NT_LPC__)
NTSTATUS STDCALL NTSTATUS STDCALL
SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request); SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
#endif #endif
/**********************************************************************
* SmpCallback/2
*
* The SM calls back a previously connected subsystem process to
* authorizes it to bootstrap (initialize). The SM connects to a
* named LPC port which name was sent in the connection data by the
* candidate subsystem server process.
*/
static NTSTATUS
SmpCallbackServer (PSM_PORT_MESSAGE Request,
PSM_CLIENT_DATA ClientData)
{
NTSTATUS Status = STATUS_SUCCESS;
PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
UNICODE_STRING CallbackPortName;
ULONG CallbackPortNameLength = SM_SB_NAME_MAX_LENGTH; /* TODO: compute length */
DPRINT("SM: %s called\n", __FUNCTION__);
if(IMAGE_SUBSYSTEM_NATIVE == ConnectData->Subsystem)
{
DPRINT("SM: %s: we do not need calling back SM!\n",
__FUNCTION__);
return STATUS_SUCCESS;
}
RtlCopyMemory (ClientData->SbApiPortName,
ConnectData->SbName,
CallbackPortNameLength);
RtlInitUnicodeString (& CallbackPortName,
ClientData->SbApiPortName);
Status = NtConnectPort (& ClientData->SbApiPort,
& CallbackPortName,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
return Status;
}
/********************************************************************** /**********************************************************************
* NAME * NAME
@ -59,8 +108,7 @@ SmpApiConnectedThread(PVOID pConnectedPort)
SM_PORT_MESSAGE Request = {{0}}; SM_PORT_MESSAGE Request = {{0}};
HANDLE ConnectedPort = * (PHANDLE) pConnectedPort; HANDLE ConnectedPort = * (PHANDLE) pConnectedPort;
DPRINT("SM: %s(%08lx) running\n", __FUNCTION__, pConnectedPort); DPRINT("SM: %s called\n", __FUNCTION__);
DPRINT("SM: %s(%08lx): ConnectedPort = %08lx\n", __FUNCTION__, pConnectedPort, ConnectedPort);
while (TRUE) while (TRUE)
{ {
@ -122,7 +170,7 @@ SmpApiConnectedThread(PVOID pConnectedPort)
NTSTATUS STDCALL NTSTATUS STDCALL
SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request) SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
{ {
PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST); PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
BOOL Accept = FALSE; BOOL Accept = FALSE;
PSM_CLIENT_DATA ClientData = NULL; PSM_CLIENT_DATA ClientData = NULL;
@ -132,46 +180,69 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
PHANDLE ClientDataApiPortThread = & hClientDataApiPortThread; PHANDLE ClientDataApiPortThread = & hClientDataApiPortThread;
PVOID Context = NULL; PVOID Context = NULL;
DPRINT("SM: %s called\n", __FUNCTION__); DPRINT("SM: %s called:\n SubSystemID=%d\n SbName=\"%S\"\n",
__FUNCTION__, ConnectData->Subsystem, ConnectData->SbName);
if(sizeof (SM_CONNECT_DATA) == Request->Header.DataSize) if(sizeof (SM_CONNECT_DATA) == Request->Header.DataSize)
{ {
if(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->Subsystem) if(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->Subsystem)
{ {
/* /*
* This is not a call from an environment server * This is not a call to register an image set,
* willing to register, but from any other process * but a simple connection request from a process
* that will use the SM API. * that will use the SM API.
*/ */
DPRINT("SM: %s: req from NON subsys server process\n", __FUNCTION__); DPRINT("SM: %s: simple request\n", __FUNCTION__);
ClientDataApiPort = & hClientDataApiPort; ClientDataApiPort = & hClientDataApiPort;
ClientDataApiPortThread = & hClientDataApiPortThread; ClientDataApiPortThread = & hClientDataApiPortThread;
Accept = TRUE; Accept = TRUE;
} else { } else {
DPRINT("SM: %s: req from subsys server process\n", __FUNCTION__); DPRINT("SM: %s: request to register an image set\n", __FUNCTION__);
/* /*
* SmCreateClient/2 is called here explicitly to *fail*. * Reject GUIs classes: only odd subsystem IDs are
* If it succeeds, there is something wrong in the * allowed to register here (tty mode images).
* 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(1 == (ConnectData->Subsystem % 2))
if(STATUS_SUCCESS == Status)
{ {
/* OK: the client is an environment subsystem DPRINT("SM: %s: id = %d\n", __FUNCTION__, ConnectData->Subsystem);
* willing to manage a free image type.
*/
ClientDataApiPort = & ClientData->ApiPort;
ClientDataApiPortThread = & ClientData->ApiPortThread;
/* /*
* Reject GUIs: only odd subsystem IDs are * SmCreateClient/2 is called here explicitly to *fail*.
* allowed to register here. * If it succeeds, there is something wrong in the
* connection request. An environment subsystem *never*
* registers twice. (security issue)
*/ */
Accept = (1 == (ConnectData->Subsystem % 2)); Status = SmCreateClient (Request, & ClientData);
if(STATUS_SUCCESS == Status)
{
DPRINT("SM: %s: ClientData = 0x%08lx\n",
__FUNCTION__, ClientData);
/*
* OK: the client is an environment subsystem
* willing to manage a free image type.
*/
ClientDataApiPort = & ClientData->ApiPort;
ClientDataApiPortThread = & ClientData->ApiPortThread;
/*
* Call back the candidate environment subsystem
* server (use the port name sent in in the
* connection request message).
*/
Status = SmpCallbackServer (Request, ClientData);
if(NT_SUCCESS(Status))
{
DPRINT("SM: %s: SmpCallbackServer OK\n",
__FUNCTION__);
Accept = TRUE;
} else {
DPRINT("SM: %s: SmpCallbackServer failed (Status=%08lx)\n",
__FUNCTION__, Status);
Status = SmDestroyClient (ConnectData->Subsystem);
}
}
} }
} }
} }
DPRINT("SM: %s: before NtAcceptConnectPort\n", __FUNCTION__);
#if defined(__USE_NT_LPC__) #if defined(__USE_NT_LPC__)
Status = NtAcceptConnectPort (ClientDataApiPort, Status = NtAcceptConnectPort (ClientDataApiPort,
Context, Context,
@ -187,8 +258,6 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
NULL, NULL,
NULL); NULL);
#endif #endif
DPRINT("SM: %s: ClientDataPort=0x%08lx\n", __FUNCTION__, ClientDataApiPort);
DPRINT("SM: %s: *ClientDataPort=0x%08lx\n", __FUNCTION__, *ClientDataApiPort);
if(Accept) if(Accept)
{ {
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
@ -247,6 +316,8 @@ SmpApiThread (HANDLE ListeningPort)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
LPC_MAX_MESSAGE Request = {{0}}; LPC_MAX_MESSAGE Request = {{0}};
DPRINT("SM: %s called\n", __FUNCTION__);
while (TRUE) while (TRUE)
{ {

View file

@ -83,16 +83,8 @@ SmCreateUserProcess (LPWSTR ImagePath,
pProcessInfo); pProcessInfo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
CHAR AnsiBuffer [MAX_PATH]; DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n",
INT i = 0; __FUNCTION__, ImagePathString.Buffer, Status);
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; return Status;
} }
@ -145,7 +137,7 @@ SmLookupSubsystem (IN PWSTR Name,
OBJECT_ATTRIBUTES Oa = {0}; OBJECT_ATTRIBUTES Oa = {0};
HANDLE hKey = (HANDLE) 0; HANDLE hKey = (HANDLE) 0;
DPRINT("SM: %s called\n", __FUNCTION__); DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);
/* /*
* Prepare the key name to scan and * Prepare the key name to scan and
* related object attributes. * related object attributes.
@ -268,7 +260,7 @@ SMAPI(SmExecPgm)
RtlCopyMemory (Name, RtlCopyMemory (Name,
ExecPgm->Name, ExecPgm->Name,
(sizeof ExecPgm->Name[0] * ExecPgm->NameLength)); (sizeof ExecPgm->Name[0] * ExecPgm->NameLength));
DPRINT("SM: %s: Name=[%wZ]\n", __FUNCTION__, Name); DPRINT("SM: %s: Name='%S'\n", __FUNCTION__, Name);
/* /*
* Check if program name is internal * Check if program name is internal
* (Is this correct? Debug is in the registry too) * (Is this correct? Debug is in the registry too)

View file

@ -0,0 +1,46 @@
/* $Id: $
*
* smapiquery.c - SM_API_QUERY_INFORMATION
*
* 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"
#define NDEBUG
#include <debug.h>
/**********************************************************************
* SmQryInfo/1 API
*/
SMAPI(SmQryInfo)
{
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("SM: %s called\n", __FUNCTION__);
Request->Status = STATUS_NOT_IMPLEMENTED;
return Status;
}
/* EOF */

View file

@ -56,6 +56,7 @@ NtProcessStartup(PPEB Peb)
} }
/* Initialize the system */ /* Initialize the system */
Status = InitSessionManager(); Status = InitSessionManager();
#if 0
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
int i; int i;
@ -90,6 +91,8 @@ ByeBye:
0,0,0,0,0); 0,0,0,0,0);
// NtTerminateProcess(NtCurrentProcess(), 0); // NtTerminateProcess(NtCurrentProcess(), 0);
#endif
NtTerminateThread(NtCurrentThread(), Status);
} }
/* EOF */ /* EOF */

View file

@ -49,12 +49,14 @@ NTSTATUS SmInitializeRegistry(VOID);
/* initss.c */ /* initss.c */
NTSTATUS SmLoadSubsystems(VOID); NTSTATUS SmLoadSubsystems(VOID);
NTSTATUS SmRunCsrss(VOID);
NTSTATUS SmRunWinlogon(VOID);
/* smapi.c */ /* smapi.c */
#define SMAPI(n) \ #define SMAPI(n) \
NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request) NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request)
PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE);
NTSTATUS SmCreateApiPort(VOID);
VOID STDCALL SmpApiThread(PVOID);
/* smapiexec.c */ /* smapiexec.c */
NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath, NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
@ -74,8 +76,8 @@ NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
/* smapicomp.c */ /* smapicomp.c */
NTSTATUS FASTCALL SmCompSes(PSM_PORT_MESSAGE); NTSTATUS FASTCALL SmCompSes(PSM_PORT_MESSAGE);
NTSTATUS SmCreateApiPort(VOID); /* smapiquery.c */
VOID STDCALL SmpApiThread(PVOID); NTSTATUS FASTCALL SmQryInfo(PSM_PORT_MESSAGE);
/* client.c */ /* client.c */
typedef struct _SM_CLIENT_DATA typedef struct _SM_CLIENT_DATA