From a90ec8327c6c83df214017942d276ec8a049d268 Mon Sep 17 00:00:00 2001 From: Emanuele Aliberti Date: Sun, 20 Mar 2005 22:55:05 +0000 Subject: [PATCH] SM: init system reading the registry CSR: register with SM for IMAGE_SUBSYSTEM_WINDOWS_CUI svn path=/trunk/; revision=14244 --- reactos/subsys/csrss/api/wapi.c | 124 +++++-- reactos/subsys/csrss/csrss.c | 56 +--- reactos/subsys/csrss/include/api.h | 9 +- reactos/subsys/csrss/init.c | 457 ++++++++++++++++++-------- reactos/subsys/csrss/win32csr/conio.c | 5 +- reactos/subsys/smss/client.c | 86 ++++- reactos/subsys/smss/init.c | 11 +- reactos/subsys/smss/initss.c | 204 +++++------- reactos/subsys/smss/makefile | 2 +- reactos/subsys/smss/smapi.c | 123 +++++-- reactos/subsys/smss/smapiexec.c | 16 +- reactos/subsys/smss/smapiquery.c | 46 +++ reactos/subsys/smss/smss.c | 3 + reactos/subsys/smss/smss.h | 10 +- 14 files changed, 739 insertions(+), 413 deletions(-) create mode 100644 reactos/subsys/smss/smapiquery.c diff --git a/reactos/subsys/csrss/api/wapi.c b/reactos/subsys/csrss/api/wapi.c index 0852c0af2e4..406f5ea90d4 100644 --- a/reactos/subsys/csrss/api/wapi.c +++ b/reactos/subsys/csrss/api/wapi.c @@ -10,16 +10,21 @@ /* INCLUDES ******************************************************************/ +#define NTOS_MODE_USER +#include #include #include -#include + + + +#define NDEBUG #include #include "api.h" /* GLOBALS *******************************************************************/ -HANDLE CsrssApiHeap; +HANDLE CsrssApiHeap = (HANDLE) 0; static unsigned ApiDefinitionsCount = 0; static PCSRSS_API_DEFINITION ApiDefinitions = NULL; @@ -33,6 +38,8 @@ CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions) PCSRSS_API_DEFINITION Scan; PCSRSS_API_DEFINITION New; + DPRINT("CSR: %s called", __FUNCTION__); + NewCount = 0; for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++) { @@ -107,6 +114,8 @@ ClientConnectionThread(HANDLE ServerPort) PCSRSS_PROCESS_DATA ProcessData; PCSRSS_API_REPLY Reply; + DPRINT("CSR: %s called", __FUNCTION__); + Reply = NULL; for (;;) @@ -153,34 +162,37 @@ ClientConnectionThread(HANDLE ServerPort) * Handle connection requests from clients to the port * "\Windows\ApiPort". */ -void STDCALL +DWORD STDCALL ServerApiPortThread (PVOID PortHandle) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; LPC_MAX_MESSAGE Request; - HANDLE ServerPort; - HANDLE ServerThread; - PCSRSS_PROCESS_DATA ProcessData; + HANDLE hApiListenPort = * (PHANDLE) PortHandle; + HANDLE ServerPort = (HANDLE) 0; + HANDLE ServerThread = (HANDLE) 0; + PCSRSS_PROCESS_DATA ProcessData = NULL; CsrInitProcessData(); + DPRINT("CSR: %s called", __FUNCTION__); + for (;;) { LPC_SECTION_READ LpcRead; ServerPort = NULL; - Status = NtListenPort(PortHandle, &Request.Header); + Status = NtListenPort (hApiListenPort, & Request.Header); if (!NT_SUCCESS(Status)) { DPRINT1("CSR: NtListenPort() failed\n"); break; } - Status = NtAcceptConnectPort(&ServerPort, - PortHandle, + Status = NtAcceptConnectPort(& ServerPort, + hApiListenPort, NULL, TRUE, 0, - &LpcRead); + & LpcRead); if (!NT_SUCCESS(Status)) { DPRINT1("CSR: NtAcceptConnectPort() failed\n"); @@ -215,7 +227,7 @@ ServerApiPortThread (PVOID PortHandle) NULL, (PTHREAD_START_ROUTINE)ClientConnectionThread, ServerPort, - &ServerThread, + & ServerThread, NULL); if (!NT_SUCCESS(Status)) { @@ -230,6 +242,7 @@ ServerApiPortThread (PVOID PortHandle) } NtClose(PortHandle); NtTerminateThread(NtCurrentThread(), Status); + return 0; } /********************************************************************** @@ -238,45 +251,88 @@ ServerApiPortThread (PVOID PortHandle) * * DESCRIPTION * 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) { - HANDLE hSbApiPortListen = (HANDLE) PortHandle; + HANDLE hSbApiPortListen = * (PHANDLE) PortHandle; HANDLE hConnectedPort = (HANDLE) 0; LPC_MAX_MESSAGE Request = {{0}}; + PVOID Context = NULL; 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); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSR: %s: NtListenPort(SB) failed\n", __FUNCTION__); - break; - } + DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n", + __FUNCTION__, Status); + } else { +DPRINT("-- 1\n"); Status = NtAcceptConnectPort (& hConnectedPort, hSbApiPortListen, - NULL, - TRUE, - NULL, + NULL, + TRUE, + NULL, NULL); if(!NT_SUCCESS(Status)) { - DPRINT1("CSR: %s: NtAcceptConnectPort() failed\n", __FUNCTION__); - break; + DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n", + __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); NtTerminateThread (NtCurrentThread(), Status); + return 0; } /* EOF */ diff --git a/reactos/subsys/csrss/csrss.c b/reactos/subsys/csrss/csrss.c index b2b885e6d12..9a2abea51df 100644 --- a/reactos/subsys/csrss/csrss.c +++ b/reactos/subsys/csrss/csrss.c @@ -35,6 +35,7 @@ #include #include #include +#include #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 */ VOID STDCALL NtProcessStartup(PPEB Peb) { PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL; COMMAND_LINE_ARGUMENT CmdLineArg = {0}; - HANDLE CsrssInitEvent = (HANDLE) 0; 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); /*================================================================== - * 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, RtlProcessParameters, & CmdLineArg); if(STATUS_SUCCESS != Status) { - DbgPrint("CSR: CsrpParseCommandLine failed (Status=0x%08lx)\n", - Status); + DPRINT1("CSR: %s: CsrpParseCommandLine failed (Status=0x%08lx)\n", + __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. *================================================================*/ 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); /* * Terminate the current thread only. diff --git a/reactos/subsys/csrss/include/api.h b/reactos/subsys/csrss/include/api.h index 0f8610ef0a6..eddf4d99198 100644 --- a/reactos/subsys/csrss/include/api.h +++ b/reactos/subsys/csrss/include/api.h @@ -82,6 +82,9 @@ PCSRSS_PROCESS_DATA ProcessData,\ PCSRSS_API_REQUEST Request,\ PCSRSS_API_REPLY Reply) +/* init.c */ +extern HANDLE hBootstrapOk; + /* api/process.c */ CSR_API(CsrConnectProcess); CSR_API(CsrCreateProcess); @@ -96,9 +99,9 @@ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_API_REQUEST Request, PCSRSS_API_REPLY Reply); -VOID STDCALL ServerApiPortThread (PVOID PortHandle); -VOID STDCALL ServerSbApiPortThread (PVOID PortHandle); -VOID Console_Api( DWORD Ignored ); +DWORD STDCALL ServerApiPortThread (PVOID PortHandle); +DWORD STDCALL ServerSbApiPortThread (PVOID PortHandle); +DWORD STDCALL Console_Api( PVOID unused ); extern HANDLE CsrssApiHeap; diff --git a/reactos/subsys/csrss/init.c b/reactos/subsys/csrss/init.c index 106ad692f46..a694ab7c40e 100644 --- a/reactos/subsys/csrss/init.c +++ b/reactos/subsys/csrss/init.c @@ -27,10 +27,9 @@ /* GLOBALS ******************************************************************/ -HANDLE CsrInitEvent = INVALID_HANDLE_VALUE; -HANDLE CsrHeap = INVALID_HANDLE_VALUE; +HANDLE CsrHeap = (HANDLE) 0; -HANDLE CsrObjectDirectory = INVALID_HANDLE_VALUE; +HANDLE CsrObjectDirectory = (HANDLE) 0; UNICODE_STRING CsrDirectoryName; @@ -39,11 +38,24 @@ extern HANDLE CsrssApiHeap; static unsigned InitCompleteProcCount; 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 -AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) +CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) { CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs; + DPRINT("CSR: %s called\n", __FUNCTION__); + NewProcs = RtlAllocateHeap(CsrssApiHeap, 0, (InitCompleteProcCount + 1) * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC)); @@ -64,12 +76,17 @@ AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc) return STATUS_SUCCESS; } +/********************************************************************** + * CallInitComplete/0 + */ static BOOL FASTCALL CallInitComplete(void) { BOOL Ok; unsigned i; + DPRINT("CSR: %s called\n", __FUNCTION__); + Ok = TRUE; if (0 != InitCompleteProcCount) { @@ -86,8 +103,11 @@ CallInitComplete(void) ULONG InitializeVideoAddressSpace(VOID); +/********************************************************************** + * CsrpParseCommandLine/2 + */ static NTSTATUS -CsrParseCommandLine ( +CsrpParseCommandLine ( ULONG ArgumentCount, PWSTR *ArgumentArray ) @@ -95,6 +115,8 @@ CsrParseCommandLine ( NTSTATUS Status; OBJECT_ATTRIBUTES Attributes; + DPRINT("CSR: %s called\n", __FUNCTION__); + /* DbgPrint ("Arguments: %ld\n", ArgumentCount); for (i = 0; i < ArgumentCount; i++) @@ -114,21 +136,28 @@ CsrParseCommandLine ( NULL); Status = NtCreateDirectoryObject(&CsrObjectDirectory, - 0xF000F, + 0xF000F, /* ea:??? */ &Attributes); return Status; } - -static VOID -CsrInitVideo(VOID) +/********************************************************************** + * CsrpInitVideo/0 + * + * TODO: we need a virtual device for sessions other than + * TODO: the console one + */ +static NTSTATUS +CsrpInitVideo (ULONG argc, PWSTR* argv) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING DeviceName; IO_STATUS_BLOCK Iosb; - HANDLE VideoHandle; - NTSTATUS Status; + HANDLE VideoHandle = (HANDLE) 0; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("CSR: %s called\n", __FUNCTION__); InitializeVideoAddressSpace(); @@ -148,10 +177,23 @@ CsrInitVideo(VOID) { 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; UNICODE_STRING DllName; @@ -163,6 +205,8 @@ InitWin32Csr() PCSRSS_OBJECT_DEFINITION ObjectDefinitions; CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc; + DPRINT("CSR: %s called\n", __FUNCTION__); + RtlInitUnicodeString(&DllName, L"win32csr.dll"); Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst); if (! NT_SUCCESS(Status)) @@ -196,7 +240,7 @@ InitWin32Csr() } if (NULL != InitCompleteProc) { - Status = AddInitCompleteProc(InitCompleteProc); + Status = CsrpAddInitCompleteProc(InitCompleteProc); } return Status; @@ -219,157 +263,292 @@ CSRSS_API_DEFINITION NativeDefinitions[] = { 0, 0, 0, NULL } }; -/********************************************************************** - * NAME - * CsrpRegisterSubsystem/0 - * - * 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) +static NTSTATUS STDCALL +CsrpCreateListenPort (IN LPWSTR Name, + IN OUT PHANDLE Port, + IN PTHREAD_START_ROUTINE ListenThread) { - NTSTATUS Status = STATUS_SUCCESS; - UNICODE_STRING SbApiPortName; + NTSTATUS Status = STATUS_SUCCESS; + OBJECT_ATTRIBUTES PortAttributes; + UNICODE_STRING PortName; - RtlInitUnicodeString (& SbApiPortName, L"\\Windows\\SbApiPort"); - Status = SmConnectApiPort (& SbApiPortName, - (HANDLE)-1, //unused - IMAGE_SUBSYSTEM_WINDOWS_CUI, - hSmApiPort); + DPRINT("CSR: %s called\n", __FUNCTION__); + + RtlInitUnicodeString (& PortName, Name); + InitializeObjectAttributes (& PortAttributes, + & 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)) { - 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; } - 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; } +/********************************************************************** + * 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 * CsrServerInitialization * * DESCRIPTION - * Create a directory object (\windows) and a named LPC port - * (\windows\ApiPort) + * Initialize the Win32 environment subsystem server. * * RETURN VALUE * TRUE: Initialization OK; otherwise FALSE. */ -BOOL -STDCALL +BOOL STDCALL CsrServerInitialization ( ULONG ArgumentCount, PWSTR *ArgumentArray ) { - NTSTATUS Status; - HANDLE hSmApiPort = (HANDLE) 0; - OBJECT_ATTRIBUTES ObAttributes; - UNICODE_STRING PortName; - HANDLE ApiPortHandle; -// HANDLE hSbApiPort = (HANDLE) 0; + INT i = 0; + NTSTATUS Status = STATUS_SUCCESS; -DisplayString(L"CSR: CsrServerInitialization\n"); + DPRINT("CSR: %s called\n", __FUNCTION__); - Status = CsrpRegisterSubsystem(& hSmApiPort); - if (! NT_SUCCESS(Status)) - { - DPRINT1("CSR: Unable to register subsystem (Status: %x)\n", Status); - return FALSE; - } - - Status = CsrParseCommandLine (ArgumentCount, ArgumentArray); - if (! NT_SUCCESS(Status)) - { - DPRINT1("CSR: Unable to parse the command line (Status: %x)\n", Status); - return FALSE; - } - - CsrInitVideo(); - - CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE, - NULL, - 65536, - 65536, - NULL, - 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; + for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++) + { + Status = InitRoutine[i].EntryPoint(ArgumentCount,ArgumentArray); + if(!NT_SUCCESS(Status)) + { + DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n", + __FUNCTION__, + InitRoutine[i].ErrorMessage, + Status); + if (InitRoutine[i].Required) + { + return FALSE; + } + } + } + if (CallInitComplete()) + { + Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort); + return TRUE; + } + return FALSE; } /* EOF */ diff --git a/reactos/subsys/csrss/win32csr/conio.c b/reactos/subsys/csrss/win32csr/conio.c index 4c82d872b59..a9d5f6b8bbf 100644 --- a/reactos/subsys/csrss/win32csr/conio.c +++ b/reactos/subsys/csrss/win32csr/conio.c @@ -1381,8 +1381,8 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode) } } -VOID -Console_Api(DWORD RefreshEvent) +DWORD STDCALL +Console_Api (PVOID unused) { /* keep reading events from the keyboard and stuffing them into the current console's input queue */ @@ -1409,6 +1409,7 @@ Console_Api(DWORD RefreshEvent) } PrivateCsrssAcquireOrReleaseInputOwnership(TRUE); + return 0; } CSR_API(CsrGetScreenBufferInfo) diff --git a/reactos/subsys/smss/client.c b/reactos/subsys/smss/client.c index 533ceea087d..33dc6bf5477 100644 --- a/reactos/subsys/smss/client.c +++ b/reactos/subsys/smss/client.c @@ -99,6 +99,37 @@ SmCompleteClientInitialization (HANDLE hProcess) * SIDE EFFECTS * 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 SmpLookupClient (USHORT SubsystemId) { @@ -107,18 +138,10 @@ SmpLookupClient (USHORT SubsystemId) DPRINT("SM: %s called\n", __FUNCTION__); RtlEnterCriticalSection (& SmpClientDirectory.Lock); - if (SmpClientDirectory.Count > 0) + Client = SmpLookupClientUnsafe (SubsystemId, NULL); + if(NULL != Client) { - Client = SmpClientDirectory.Client; - while (NULL != Client) - { - if (SubsystemId == Client->SubsystemId) - { - RtlLeaveCriticalSection (& SmpClientDirectory.Lock); - return Client; - } - Client = Client->Next; - } + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); } /* * Note that we do *not* release SmpClientDirectory.Lock here @@ -135,7 +158,7 @@ NTSTATUS STDCALL SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData) { 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); DPRINT("SM: %s called\n", __FUNCTION__); @@ -206,16 +229,51 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData) /********************************************************************** * SmpDestroyClient/1 + * + * 1. close any handle + * 2. kill client process + * 3. release resources */ NTSTATUS STDCALL SmDestroyClient (ULONG SubsystemId) { + NTSTATUS Status = STATUS_SUCCESS; + PSM_CLIENT_DATA Parent = NULL; + PSM_CLIENT_DATA Client = NULL; + DPRINT("SM: %s called\n", __FUNCTION__); 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); - return STATUS_SUCCESS; + return Status; } /* EOF */ diff --git a/reactos/subsys/smss/init.c b/reactos/subsys/smss/init.c index f3a1126c98e..a8880e253ec 100644 --- a/reactos/subsys/smss/init.c +++ b/reactos/subsys/smss/init.c @@ -39,7 +39,7 @@ SmpSignalInitEvent(VOID) NTSTATUS Status = STATUS_SUCCESS; OBJECT_ATTRIBUTES ObjectAttributes = {0}; UNICODE_STRING EventName ={0}; - HANDLE ReactOSInitEvent = NULL; + HANDLE ReactOSInitEvent = (HANDLE) 0; RtlInitUnicodeString (& EventName, L"\\ReactOSInitDone"); InitializeObjectAttributes(&ObjectAttributes, @@ -92,16 +92,13 @@ struct { {TRUE, SmInitializeClientManagement, "initialize client management"}, {TRUE, SmLoadSubsystems, "load subsystems"}, {FALSE, SmpSignalInitEvent, "open ReactOS init notification event"}, - {TRUE, SmRunCsrss, "run csrss"}, - {TRUE, SmRunWinlogon, "run winlogon"}, - {TRUE, SmInitializeDbgSs, "initialize DbgSs"} }; NTSTATUS InitSessionManager(VOID) { - int i; - NTSTATUS Status; + INT i = 0; + NTSTATUS Status = STATUS_SUCCESS; for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++) { @@ -118,8 +115,6 @@ InitSessionManager(VOID) } } } - - return(STATUS_SUCCESS); } diff --git a/reactos/subsys/smss/initss.c b/reactos/subsys/smss/initss.c index 392595bc2bd..2c79c3a8037 100644 --- a/reactos/subsys/smss/initss.c +++ b/reactos/subsys/smss/initss.c @@ -41,15 +41,9 @@ HANDLE hSmApiPort = (HANDLE) 0; * a) look if a special option is set for smss.exe in * 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 * in the registry key Required="Debug Windows" * 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; UNICODE_STRING SbApiPortName = {0,0,NULL}; + DPRINT("SM: %s called\n",__FUNCTION__); RtlInitUnicodeString (& SbApiPortName, L""); Status = SmConnectApiPort(& SbApiPortName, - (HANDLE) 0, + (HANDLE) -1, /* SM has no SB port */ IMAGE_SUBSYSTEM_NATIVE, & hSmApiPort); 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); return Status; } @@ -91,27 +86,19 @@ SmpRegisterSmss(VOID) /********************************************************************** + * SmpLoadKernelModeSubsystem/0 */ -NTSTATUS -SmLoadSubsystems(VOID) +static NTSTATUS +SmpLoadKernelModeSubsystem (VOID) { - SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo; - NTSTATUS Status = STATUS_SUCCESS; - WCHAR Data [MAX_PATH + 1]; - ULONG DataLength = sizeof Data; - ULONG DataType = 0; + NTSTATUS Status = STATUS_SUCCESS; + WCHAR Data [MAX_PATH + 1]; + ULONG DataLength = sizeof Data; + 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", Data, & DataLength, @@ -119,128 +106,101 @@ SmLoadSubsystems(VOID) TRUE); 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"\\??\\"); wcscat (ImagePath, Data); RtlZeroMemory (& ImageInfo, sizeof ImageInfo); RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath); Status = NtSetSystemInformation(SystemLoadAndCallImage, - & ImageInfo, - sizeof ImageInfo); + & ImageInfo, + sizeof ImageInfo); if(!NT_SUCCESS(Status)) { - DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n", - Status); - return Status; + DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n", + __FUNCTION__, 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; } -NTSTATUS -SmRunCsrss(VOID) +/********************************************************************** + * SmpLoadRequiredSubsystems/0 + */ +static NTSTATUS +SmpLoadRequiredSubsystems (VOID) { - NTSTATUS Status; - UNICODE_STRING UnicodeString; - OBJECT_ATTRIBUTES ObjectAttributes; - RTL_PROCESS_INFO ProcessInfo; - HANDLE CsrssInitEvent; - WCHAR ImagePath [MAX_PATH]; + NTSTATUS Status = STATUS_SUCCESS; + WCHAR Data [MAX_PATH + 1]; + ULONG DataLength = sizeof Data; + ULONG DataType = 0; - DPRINT("SM: initializing csrss\n"); + + DPRINT("SM: %s called\n", __FUNCTION__); - /* Run csrss.exe */ - RtlRosInitUnicodeStringFromLiteral(&UnicodeString, - L"\\CsrssInitDone"); - InitializeObjectAttributes(&ObjectAttributes, - &UnicodeString, - EVENT_ALL_ACCESS, - 0, - NULL); - Status = NtCreateEvent(&CsrssInitEvent, - EVENT_ALL_ACCESS, - &ObjectAttributes, - NotificationEvent, - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to create csrss notification event\n"); - } + RtlZeroMemory (Data, DataLength); + Status = SmLookupSubsystem (L"Required", + Data, + & DataLength, + & DataType, + FALSE); + if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0])) + { + PWCHAR Name = NULL; + ULONG Offset = 0; + + for (Name = Data; (Offset < DataLength); ) + { + if(L'\0' != *Name) + { + UNICODE_STRING Program; - /* - * Start the Win32 subsystem (csrss.exe) - */ + /* Run the current program */ + 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 */ - 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; + return Status; } +/********************************************************************** + * SmLoadSubsystems/0 + */ NTSTATUS -SmRunWinlogon(VOID) +SmLoadSubsystems(VOID) { - NTSTATUS Status = STATUS_SUCCESS; - RTL_PROCESS_INFO ProcessInfo; - WCHAR ImagePath [MAX_PATH]; + NTSTATUS Status = STATUS_SUCCESS; - /* - * Start the logon process (winlogon.exe) - */ + + DPRINT("SM: loading subsystems\n"); - DPRINT("SM: starting winlogon\n"); - - /* initialize executable path */ - wcscpy(ImagePath, L"\\??\\"); - wcscat(ImagePath, SharedUserData->NtSystemRoot); - wcscat(ImagePath, L"\\system32\\winlogon.exe"); - - Status = SmCreateUserProcess(ImagePath, - L"", - FALSE, /* wait */ - NULL, - 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; + /* SM self registers */ + Status = SmpRegisterSmss(); + if(!NT_SUCCESS(Status)) return Status; + /* Load Kmode subsystem (aka win32k.sys) */ + Status = SmpLoadKernelModeSubsystem(); + if(!NT_SUCCESS(Status)) return Status; + /* Load Required subsystems (Debug Windows) */ + Status = SmpLoadRequiredSubsystems(); + if(!NT_SUCCESS(Status)) return Status; + /* done */ + return Status; } /* EOF */ diff --git a/reactos/subsys/smss/makefile b/reactos/subsys/smss/makefile index ebfc47e575d..3845a347e7a 100644 --- a/reactos/subsys/smss/makefile +++ b/reactos/subsys/smss/makefile @@ -21,7 +21,7 @@ TARGET_OBJECTS = $(TARGET_NAME).o \ init.o initheap.o initenv.o initobdir.o initdosdev.o \ initrun.o initmv.o initwkdll.o initpage.o initss.o \ initreg.o \ - smapi.o smapicomp.o smapiexec.o \ + smapi.o smapicomp.o smapiexec.o smapiquery.o \ client.o debug.o print.o include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/subsys/smss/smapi.c b/reactos/subsys/smss/smapi.c index 62a72f26bd0..a1578507f7e 100644 --- a/reactos/subsys/smss/smapi.c +++ b/reactos/subsys/smss/smapi.c @@ -34,14 +34,63 @@ SM_PORT_API SmApi [] = SmCompSes, /* smapicomp.c */ SmInvalid, /* obsolete */ 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__) NTSTATUS STDCALL SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request); #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 @@ -59,8 +108,7 @@ SmpApiConnectedThread(PVOID pConnectedPort) SM_PORT_MESSAGE Request = {{0}}; HANDLE ConnectedPort = * (PHANDLE) pConnectedPort; - DPRINT("SM: %s(%08lx) running\n", __FUNCTION__, pConnectedPort); - DPRINT("SM: %s(%08lx): ConnectedPort = %08lx\n", __FUNCTION__, pConnectedPort, ConnectedPort); + DPRINT("SM: %s called\n", __FUNCTION__); while (TRUE) { @@ -122,7 +170,7 @@ SmpApiConnectedThread(PVOID pConnectedPort) NTSTATUS STDCALL 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; BOOL Accept = FALSE; PSM_CLIENT_DATA ClientData = NULL; @@ -132,46 +180,69 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request) PHANDLE ClientDataApiPortThread = & hClientDataApiPortThread; 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(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->Subsystem) { /* - * This is not a call from an environment server - * willing to register, but from any other process + * This is not a call to register an image set, + * but a simple connection request from a process * 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; ClientDataApiPortThread = & hClientDataApiPortThread; Accept = TRUE; } 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*. - * 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). + * Reject GUIs classes: only odd subsystem IDs are + * allowed to register here (tty mode images). */ - Status = SmCreateClient (Request, & ClientData); - if(STATUS_SUCCESS == Status) + if(1 == (ConnectData->Subsystem % 2)) { - /* OK: the client is an environment subsystem - * willing to manage a free image type. - */ - ClientDataApiPort = & ClientData->ApiPort; - ClientDataApiPortThread = & ClientData->ApiPortThread; + DPRINT("SM: %s: id = %d\n", __FUNCTION__, ConnectData->Subsystem); /* - * Reject GUIs: only odd subsystem IDs are - * allowed to register here. + * 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) */ - 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__) Status = NtAcceptConnectPort (ClientDataApiPort, Context, @@ -187,8 +258,6 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request) NULL, NULL); #endif - DPRINT("SM: %s: ClientDataPort=0x%08lx\n", __FUNCTION__, ClientDataApiPort); - DPRINT("SM: %s: *ClientDataPort=0x%08lx\n", __FUNCTION__, *ClientDataApiPort); if(Accept) { if(!NT_SUCCESS(Status)) @@ -247,6 +316,8 @@ SmpApiThread (HANDLE ListeningPort) { NTSTATUS Status = STATUS_SUCCESS; LPC_MAX_MESSAGE Request = {{0}}; + + DPRINT("SM: %s called\n", __FUNCTION__); while (TRUE) { diff --git a/reactos/subsys/smss/smapiexec.c b/reactos/subsys/smss/smapiexec.c index 744a094549f..ad83e512667 100644 --- a/reactos/subsys/smss/smapiexec.c +++ b/reactos/subsys/smss/smapiexec.c @@ -83,16 +83,8 @@ SmCreateUserProcess (LPWSTR ImagePath, 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); + DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n", + __FUNCTION__, ImagePathString.Buffer, Status); return Status; } @@ -145,7 +137,7 @@ SmLookupSubsystem (IN PWSTR Name, OBJECT_ATTRIBUTES Oa = {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 * related object attributes. @@ -268,7 +260,7 @@ SMAPI(SmExecPgm) RtlCopyMemory (Name, ExecPgm->Name, (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 * (Is this correct? Debug is in the registry too) diff --git a/reactos/subsys/smss/smapiquery.c b/reactos/subsys/smss/smapiquery.c new file mode 100644 index 00000000000..e93e593405a --- /dev/null +++ b/reactos/subsys/smss/smapiquery.c @@ -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 + + +/********************************************************************** + * SmQryInfo/1 API + */ +SMAPI(SmQryInfo) +{ + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("SM: %s called\n", __FUNCTION__); + + Request->Status = STATUS_NOT_IMPLEMENTED; + return Status; +} + + +/* EOF */ diff --git a/reactos/subsys/smss/smss.c b/reactos/subsys/smss/smss.c index a6a983fe09a..b03197c0a70 100644 --- a/reactos/subsys/smss/smss.c +++ b/reactos/subsys/smss/smss.c @@ -56,6 +56,7 @@ NtProcessStartup(PPEB Peb) } /* Initialize the system */ Status = InitSessionManager(); +#if 0 if (!NT_SUCCESS(Status)) { int i; @@ -90,6 +91,8 @@ ByeBye: 0,0,0,0,0); // NtTerminateProcess(NtCurrentProcess(), 0); +#endif + NtTerminateThread(NtCurrentThread(), Status); } /* EOF */ diff --git a/reactos/subsys/smss/smss.h b/reactos/subsys/smss/smss.h index 03ad2e34e58..eae61437e30 100644 --- a/reactos/subsys/smss/smss.h +++ b/reactos/subsys/smss/smss.h @@ -49,12 +49,14 @@ NTSTATUS SmInitializeRegistry(VOID); /* initss.c */ NTSTATUS SmLoadSubsystems(VOID); -NTSTATUS SmRunCsrss(VOID); -NTSTATUS SmRunWinlogon(VOID); /* smapi.c */ #define SMAPI(n) \ NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request) +PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE); +NTSTATUS SmCreateApiPort(VOID); +VOID STDCALL SmpApiThread(PVOID); + /* smapiexec.c */ NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath, @@ -74,8 +76,8 @@ NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE); /* smapicomp.c */ NTSTATUS FASTCALL SmCompSes(PSM_PORT_MESSAGE); -NTSTATUS SmCreateApiPort(VOID); -VOID STDCALL SmpApiThread(PVOID); +/* smapiquery.c */ +NTSTATUS FASTCALL SmQryInfo(PSM_PORT_MESSAGE); /* client.c */ typedef struct _SM_CLIENT_DATA