From: Emanuele Aliberti Date: Sat, 27 Aug 2005 09:55:27 +0000 (+0000) Subject: SM: simplify and fix client (subsystem servers) management. X-Git-Tag: ReactOS-0.2.8~839 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=3c693f90bcde62658714927fb3eb480ee7825b5a SM: simplify and fix client (subsystem servers) management. svn path=/trunk/; revision=17567 --- diff --git a/reactos/subsys/smss/client.c b/reactos/subsys/smss/client.c index e516fe501f6..21dc32932bd 100644 --- a/reactos/subsys/smss/client.c +++ b/reactos/subsys/smss/client.c @@ -31,12 +31,14 @@ /* Private ADT */ +#define SM_MAX_CLIENT_COUNT 16 +#define SM_INVALID_CLIENT_INDEX -1 struct _SM_CLIENT_DIRECTORY { RTL_CRITICAL_SECTION Lock; ULONG Count; - PSM_CLIENT_DATA Client; + PSM_CLIENT_DATA Client [SM_MAX_CLIENT_COUNT]; PSM_CLIENT_DATA CandidateClient; } SmpClientDirectory; @@ -51,7 +53,7 @@ SmInitializeClientManagement (VOID) DPRINT("SM: %s called\n", __FUNCTION__); RtlInitializeCriticalSection(& SmpClientDirectory.Lock); SmpClientDirectory.Count = 0; - SmpClientDirectory.Client = NULL; + RtlZeroMemory (SmpClientDirectory.Client, sizeof SmpClientDirectory.Client); SmpClientDirectory.CandidateClient = NULL; return STATUS_SUCCESS; @@ -66,56 +68,85 @@ SmpSetClientInitialized (PSM_CLIENT_DATA Client) Client->Flags |= SM_CLIENT_FLAG_INITIALIZED; } /********************************************************************** - * SmpLookupClient/2 PRIVATE + * SmpGetFirstFreeClientEntry/0 PRIVATE + * + * NOTE: call it holding SmpClientDirectory.Lock only + */ +static INT STDCALL SmpGetFirstFreeClientEntry (VOID) +{ + INT ClientIndex = 0; + + DPRINT("SM: %s called\n", __FUNCTION__); + + if (SmpClientDirectory.Count < SM_MAX_CLIENT_COUNT) + { + for (ClientIndex = 0; + (ClientIndex < SM_MAX_CLIENT_COUNT); + ClientIndex ++) + { + if (NULL == SmpClientDirectory.Client[ClientIndex]) + { + DPRINT("SM: %s => %d\n", __FUNCTION__, ClientIndex); + return ClientIndex; // found + } + } + } + return SM_INVALID_CLIENT_INDEX; // full! +} +/********************************************************************** + * SmpLookupClient/1 PRIVATE * * DESCRIPTION - * Lookup the subsystem server descriptor given its image ID. + * Lookup the subsystem server descriptor (client data) given its + * base image ID. * * ARGUMENTS * SubsystemId: IMAGE_SUBSYSTEM_xxx - * Parent: optional: caller provided storage for the - * the pointer to the SM_CLIENT_DATA which - * Next field contains the value returned by - * the function (on success). * * RETURN VALUES - * NULL on error; otherwise a pointer to the SM_CLIENT_DATA - * looked up object. + * SM_INVALID_CLIENT_INDEX on error; + * otherwise an index in the range (0..SM_MAX_CLIENT_COUNT). * * WARNING * SmpClientDirectory.Lock must be held by the caller. */ -static PSM_CLIENT_DATA FASTCALL -SmpLookupClient (USHORT SubsystemId, - PSM_CLIENT_DATA * Parent) +static INT FASTCALL +SmpLookupClient (USHORT SubsystemId) { - PSM_CLIENT_DATA Client = NULL; + INT ClientIndex = 0; DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId); - - if(NULL != Parent) - { - *Parent = NULL; - } - if (SmpClientDirectory.Count > 0) + + if (0 != SmpClientDirectory.Count) { - Client = SmpClientDirectory.Client; - while (NULL != Client) + for (ClientIndex = 0; (ClientIndex < SM_MAX_CLIENT_COUNT); ClientIndex ++) { - DPRINT("SM: %s: Client==%08lx\n", __FUNCTION__, Client); - if (SubsystemId == Client->SubsystemId) - { - DPRINT("SM: %s: FOUND Client==%08lx\n", __FUNCTION__, Client); - break; - } - if(NULL != Parent) + if (NULL != SmpClientDirectory.Client[ClientIndex]) { - *Parent = Client; + if (SubsystemId == SmpClientDirectory.Client[ClientIndex]->SubsystemId) + { + return ClientIndex; + } } - Client = Client->Next; } - } - return Client; + } + return SM_INVALID_CLIENT_INDEX; +} +/********************************************************************** + * SmpDestroyClientObject/2 PRIVATE + * + * WARNING + * SmpClientDirectory.Lock must be held by the caller. + */ +static NTSTATUS STDCALL +SmpDestroyClientObject (PSM_CLIENT_DATA Client, NTSTATUS DestroyReason) +{ + DPRINT("SM:%s(%08lx,%08lx) called\n", __FUNCTION__, DestroyReason); + /* TODO: send shutdown to the SB port */ + NtTerminateProcess (Client->ServerProcess, DestroyReason); + RtlFreeHeap (SmpHeap, 0, Client); + -- SmpClientDirectory.Count; + return STATUS_SUCCESS; } /********************************************************************** * SmBeginClientInitialization/1 @@ -135,18 +166,20 @@ NTSTATUS STDCALL SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, OUT PSM_CLIENT_DATA * ClientData) { - NTSTATUS Status = STATUS_SUCCESS; - PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request); - ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request); + NTSTATUS Status = STATUS_SUCCESS; + PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request); + ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request); + INT ClientIndex = SM_INVALID_CLIENT_INDEX; - DPRINT("SM: %s called\n", __FUNCTION__); + DPRINT("SM: %s(%08lx,%08lx) called\n", __FUNCTION__, + Request, ClientData); RtlEnterCriticalSection (& SmpClientDirectory.Lock); /* * Is there a subsystem bootstrap in progress? */ - if (SmpClientDirectory.CandidateClient) + if (NULL != SmpClientDirectory.CandidateClient) { PROCESS_BASIC_INFORMATION pbi; @@ -164,7 +197,6 @@ SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, } else { - RtlFreeHeap (SmpHeap, 0, SmpClientDirectory.CandidateClient); DPRINT1("SM: %s: subsys booting with no descriptor!\n", __FUNCTION__); Status = STATUS_NOT_FOUND; RtlLeaveCriticalSection (& SmpClientDirectory.Lock); @@ -173,14 +205,28 @@ SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, /* * Check if a client for the ID already exist. */ - if (SmpLookupClient(ConnectData->SubSystemId, NULL)) + if (SM_INVALID_CLIENT_INDEX != SmpLookupClient(ConnectData->SubSystemId)) { DPRINT("SM: %s: attempt to register again subsystem %d.\n", __FUNCTION__, ConnectData->SubSystemId); + // TODO something else to do here? RtlLeaveCriticalSection (& SmpClientDirectory.Lock); return STATUS_UNSUCCESSFUL; } + /* + * Check if a free entry exists in SmpClientDirectory.Client[]. + */ + ClientIndex = SmpGetFirstFreeClientEntry(); + if (SM_INVALID_CLIENT_INDEX == ClientIndex) + { + DPRINT("SM: %s: SM_INVALID_CLIENT_INDEX == ClientIndex ", __FUNCTION__); + SmpDestroyClientObject (SmpClientDirectory.CandidateClient, STATUS_NO_MEMORY); + SmpClientDirectory.CandidateClient = NULL; + return STATUS_NO_MEMORY; + } + + /* OK! */ DPRINT("SM: %s: registering subsystem ID=%d \n", __FUNCTION__, ConnectData->SubSystemId); @@ -191,12 +237,13 @@ SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, /* SM && DBG auto-initializes; other subsystems are required to call * SM_API_COMPLETE_SESSION via SMDLL. */ if ((IMAGE_SUBSYSTEM_NATIVE == SmpClientDirectory.CandidateClient->SubsystemId) || - (IMAGE_SUBSYSTEM_UNKNOWN == SmpClientDirectory.CandidateClient->SubsystemId)) + ((USHORT)-1 == SmpClientDirectory.CandidateClient->SubsystemId)) { SmpSetClientInitialized (SmpClientDirectory.CandidateClient); } if (SbApiPortNameSize > 0) { + /* Only external servers have an SB port */ RtlCopyMemory (SmpClientDirectory.CandidateClient->SbApiPortName, ConnectData->SbName, SbApiPortNameSize); @@ -205,18 +252,7 @@ SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, * Insert the new descriptor in the * client directory. */ - if (NULL == SmpClientDirectory.Client) - { - SmpClientDirectory.Client = SmpClientDirectory.CandidateClient; - } else { - PSM_CLIENT_DATA pCD = NULL; - - for (pCD=SmpClientDirectory.Client; - (NULL != pCD->Next); - pCD = pCD->Next); - pCD->Next = SmpClientDirectory.CandidateClient; - } - SmpClientDirectory.CandidateClient->Next = NULL; + SmpClientDirectory.Client [ClientIndex] = SmpClientDirectory.CandidateClient; /* * Increment the number of active subsystems. */ @@ -233,6 +269,7 @@ SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, */ SmpClientDirectory.CandidateClient = NULL; + /* Done */ RtlLeaveCriticalSection (& SmpClientDirectory.Lock); return STATUS_SUCCESS; @@ -247,30 +284,101 @@ SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, NTSTATUS STDCALL SmCompleteClientInitialization (ULONG ProcessId) { - NTSTATUS Status = STATUS_NOT_FOUND; - PSM_CLIENT_DATA Client = NULL; + NTSTATUS Status = STATUS_NOT_FOUND; + INT ClientIndex = SM_INVALID_CLIENT_INDEX; DPRINT("SM: %s(%lu) called\n", __FUNCTION__, ProcessId); RtlEnterCriticalSection (& SmpClientDirectory.Lock); if (SmpClientDirectory.Count > 0) { - Client = SmpClientDirectory.Client; - while (NULL != Client) - { - if (ProcessId == Client->ServerProcessId) + for (ClientIndex = 0; ClientIndex < SM_MAX_CLIENT_COUNT; ClientIndex ++) + { + if ((NULL != SmpClientDirectory.Client [ClientIndex]) && + (ProcessId == SmpClientDirectory.Client [ClientIndex]->ServerProcessId)) { - SmpSetClientInitialized (Client); + SmpSetClientInitialized (SmpClientDirectory.Client [ClientIndex]); Status = STATUS_SUCCESS; break; } - Client = Client->Next; } } RtlLeaveCriticalSection (& SmpClientDirectory.Lock); return Status; } +/********************************************************************** + * SmpDestroyClientByClientIndex/1 PRIVATE + */ +static NTSTATUS STDCALL +SmpDestroyClientByClientIndex (INT ClientIndex) +{ + NTSTATUS Status = STATUS_SUCCESS; + PSM_CLIENT_DATA Client = NULL; + + DPRINT("SM: %s(%d) called\n", __FUNCTION__, ClientIndex); + + if (SM_INVALID_CLIENT_INDEX == ClientIndex) + { + DPRINT1("SM: %s: SM_INVALID_CLIENT_INDEX == ClientIndex!\n", + __FUNCTION__); + Status = STATUS_NOT_FOUND; + } + else + { + Client = SmpClientDirectory.Client [ClientIndex]; + SmpClientDirectory.Client [ClientIndex] = NULL; + if (NULL != Client) + { + Status = SmpDestroyClientObject (Client, STATUS_SUCCESS); + } else { + DPRINT("SM:%s: NULL == Client[%d]!\n", __FUNCTION__, + ClientIndex); + Status = STATUS_UNSUCCESSFUL; + } + } + return Status; +} +/********************************************************************** + * SmpTimeoutCandidateClient/1 + * + * DESCRIPTION + * Give the candidate client time to bootstrap and complete + * session initialization. If the client fails in any way, + * drop the pending client and kill the process. + * + * ARGUMENTS + * x: HANDLE for the candidate process. + * + * RETURN VALUE + * NONE. + */ +static VOID STDCALL SmpTimeoutCandidateClient (PVOID x) +{ + NTSTATUS Status = STATUS_SUCCESS; + HANDLE CandidateClientProcessHandle = (HANDLE) x; + LARGE_INTEGER TimeOut; + DPRINT("SM: %s(%lx) called\n", __FUNCTION__, x); + + TimeOut.QuadPart = (LONGLONG) -300000000L; // 30s + Status = NtWaitForSingleObject (CandidateClientProcessHandle, + FALSE, + & TimeOut); + if (STATUS_TIMEOUT == Status) + { + RtlEnterCriticalSection (& SmpClientDirectory.Lock); + if (NULL != SmpClientDirectory.CandidateClient) + { + DPRINT("SM:%s: destroy candidate %08lx\n", __FUNCTION__, + SmpClientDirectory.CandidateClient); + Status = SmpDestroyClientObject (SmpClientDirectory.CandidateClient, + STATUS_TIMEOUT); + SmpClientDirectory.CandidateClient = NULL; + } + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + } + NtTerminateThread (NtCurrentThread(), Status); +} /********************************************************************** * SmpCreateClient/1 * @@ -294,9 +402,8 @@ NTSTATUS STDCALL SmCreateClient (PRTL_USER_PROCESS_INFORMATION ProcessInfo, PWSTR ProgramName) { NTSTATUS Status = STATUS_SUCCESS; - - DPRINT("SM: %s(%lx) called\n", __FUNCTION__, ProcessInfo->ProcessHandle); + DPRINT("SM: %s(%lx, %S) called\n", __FUNCTION__, ProcessInfo->ProcessHandle, ProgramName); RtlEnterCriticalSection (& SmpClientDirectory.Lock); /* @@ -304,6 +411,16 @@ SmCreateClient (PRTL_USER_PROCESS_INFORMATION ProcessInfo, PWSTR ProgramName) */ if (NULL == SmpClientDirectory.CandidateClient) { + /* + * Check if there exist a free entry in the + * SmpClientDirectory.Client array. + */ + if (SM_INVALID_CLIENT_INDEX == SmpGetFirstFreeClientEntry()) + { + DPRINT("SM: %s(%lx): out of memory!\n", + __FUNCTION__, ProcessInfo->ProcessHandle); + Status = STATUS_NO_MEMORY; + } /* * Allocate the storage for client data */ @@ -319,6 +436,8 @@ SmCreateClient (PRTL_USER_PROCESS_INFORMATION ProcessInfo, PWSTR ProgramName) } else { + DPRINT("SM:%s(%08lx,%S): candidate is %08lx\n", __FUNCTION__, + ProcessInfo, ProgramName, SmpClientDirectory.CandidateClient); /* Initialize the candidate client. */ RtlInitializeCriticalSection(& SmpClientDirectory.CandidateClient->Lock); SmpClientDirectory.CandidateClient->ServerProcess = @@ -333,16 +452,35 @@ SmCreateClient (PRTL_USER_PROCESS_INFORMATION ProcessInfo, PWSTR ProgramName) SM_SB_NAME_MAX_LENGTH); } } else { - DPRINT1("SM: %s: CandidateClient pending!\n", __FUNCTION__); - RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + DPRINT1("SM: %s: CandidateClient %08lx pending!\n", __FUNCTION__, + SmpClientDirectory.CandidateClient); Status = STATUS_DEVICE_BUSY; } RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + /* Create the timeout thread for external subsystems */ + if (_wcsicmp (ProgramName, L"Session Manager") && _wcsicmp (ProgramName, L"Debug")) + { + Status = RtlCreateUserThread (NtCurrentProcess(), + NULL, + FALSE, + 0, + 0, + 0, + (PTHREAD_START_ROUTINE) SmpTimeoutCandidateClient, + SmpClientDirectory.CandidateClient->ServerProcess, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM:%s: RtlCreateUserThread() failed (Status=%08lx)\n", + __FUNCTION__, Status); + } + } + return Status; } - /********************************************************************** * SmpDestroyClient/1 * @@ -353,42 +491,20 @@ SmCreateClient (PRTL_USER_PROCESS_INFORMATION ProcessInfo, PWSTR ProgramName) NTSTATUS STDCALL SmDestroyClient (ULONG SubsystemId) { - NTSTATUS Status = STATUS_SUCCESS; - PSM_CLIENT_DATA Parent = NULL; - PSM_CLIENT_DATA Client = NULL; + NTSTATUS Status = STATUS_SUCCESS; + INT ClientIndex = SM_INVALID_CLIENT_INDEX; - DPRINT("SM: %s called\n", __FUNCTION__); + DPRINT("SM: %s(%lu) called\n", __FUNCTION__, SubsystemId); RtlEnterCriticalSection (& SmpClientDirectory.Lock); - Client = SmpLookupClient (SubsystemId, & Parent); - if(NULL == Client) + ClientIndex = SmpLookupClient (SubsystemId); + if (SM_INVALID_CLIENT_INDEX == ClientIndex) { 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 */ - NtTerminateProcess (Client->ServerProcess, 0); //FIXME - RtlFreeHeap (SmpHeap, 0, Client); - -- SmpClientDirectory.Count; + return STATUS_NOT_FOUND; } + Status = SmpDestroyClientByClientIndex (ClientIndex); RtlLeaveCriticalSection (& SmpClientDirectory.Lock); return Status; } @@ -401,10 +517,10 @@ SmDestroyClient (ULONG SubsystemId) NTSTATUS FASTCALL SmGetClientBasicInformation (PSM_BASIC_INFORMATION i) { - INT Index = 0; - PSM_CLIENT_DATA ClientData = NULL; + INT ClientIndex = 0; + INT Index = 0; - DPRINT("SM: %s called\n", __FUNCTION__); + DPRINT("SM: %s(%08lx) called\n", __FUNCTION__, i); RtlEnterCriticalSection (& SmpClientDirectory.Lock); @@ -413,13 +529,16 @@ SmGetClientBasicInformation (PSM_BASIC_INFORMATION i) if (SmpClientDirectory.Count > 0) { - ClientData = SmpClientDirectory.Client; - while ((NULL != ClientData) && (Index < SM_QRYINFO_MAX_SS_COUNT)) + for (ClientIndex = 0; (ClientIndex < SM_MAX_CLIENT_COUNT); ClientIndex ++) { - i->SubSystem[Index].Id = ClientData->SubsystemId; - i->SubSystem[Index].Flags = ClientData->Flags; - i->SubSystem[Index].ProcessId = ClientData->ServerProcessId; - ClientData = ClientData->Next; + if ((NULL != SmpClientDirectory.Client [ClientIndex]) && + (Index < SM_QRYINFO_MAX_SS_COUNT)) + { + i->SubSystem[Index].Id = SmpClientDirectory.Client [ClientIndex]->SubsystemId; + i->SubSystem[Index].Flags = SmpClientDirectory.Client [ClientIndex]->Flags; + i->SubSystem[Index].ProcessId = SmpClientDirectory.Client [ClientIndex]->ServerProcessId; + ++ Index; + } } } @@ -433,23 +552,23 @@ SmGetClientBasicInformation (PSM_BASIC_INFORMATION i) NTSTATUS FASTCALL SmGetSubSystemInformation (PSM_SUBSYSTEM_INFORMATION i) { - NTSTATUS Status = STATUS_SUCCESS; - PSM_CLIENT_DATA ClientData = NULL; + NTSTATUS Status = STATUS_SUCCESS; + INT ClientIndex = SM_INVALID_CLIENT_INDEX; - DPRINT("SM: %s called\n", __FUNCTION__); + DPRINT("SM: %s(%08lx) called\n", __FUNCTION__, i); RtlEnterCriticalSection (& SmpClientDirectory.Lock); - ClientData = SmpLookupClient (i->SubSystemId, NULL); - if (NULL == ClientData) + ClientIndex = SmpLookupClient (i->SubSystemId); + if (SM_INVALID_CLIENT_INDEX == ClientIndex) { Status = STATUS_NOT_FOUND; } else { - i->Flags = ClientData->Flags; - i->ProcessId = ClientData->ServerProcessId; + i->Flags = SmpClientDirectory.Client [ClientIndex]->Flags; + i->ProcessId = SmpClientDirectory.Client [ClientIndex]->ServerProcessId; RtlCopyMemory (i->NameSpaceRootNode, - ClientData->SbApiPortName, + SmpClientDirectory.Client [ClientIndex]->SbApiPortName, (SM_QRYINFO_MAX_ROOT_NODE * sizeof(i->NameSpaceRootNode[0]))); } RtlLeaveCriticalSection (& SmpClientDirectory.Lock); diff --git a/reactos/subsys/smss/debug.c b/reactos/subsys/smss/debug.c index 62619f3d730..56bbac4f209 100644 --- a/reactos/subsys/smss/debug.c +++ b/reactos/subsys/smss/debug.c @@ -33,6 +33,7 @@ HANDLE DbgSsApiPort = (HANDLE) 0; HANDLE DbgUiApiPort = (HANDLE) 0; +HANDLE hSmDbgApiPort = (HANDLE) 0; /* FUNCTIONS *********************************************************/ @@ -135,8 +136,21 @@ SmInitializeDbgSs (VOID) NTSTATUS Status = STATUS_SUCCESS; HANDLE hDbgSsApiPortThread = (HANDLE) 0; + DPRINT("SM: %s called\n", __FUNCTION__); + /* Self register */ +#if 0 + Status = SmRegisterInternalSubsystem (L"Debug", + (USHORT)-1, + & hSmDbgApiPort); + if (!NT_SUCCESS(Status)) + { + DPRINT1("DBG:%s: SmRegisterInternalSubsystem failed with Status=%08lx\n", + __FUNCTION__, Status); + return Status; + } +#endif /* Create the \DbgSsApiPort object (LPC) */ Status = SmpCreatePT(& DbgSsApiPort, SM_DBGSS_PORT_NAME, diff --git a/reactos/subsys/smss/initss.c b/reactos/subsys/smss/initss.c index bc180dfc07a..656b1396be3 100644 --- a/reactos/subsys/smss/initss.c +++ b/reactos/subsys/smss/initss.c @@ -39,61 +39,59 @@ HANDLE hSmApiPort = (HANDLE) 0; */ /********************************************************************** - * SmpRegisterSmss/0 - * + * SmRegisterInternalSubsystem/3 + * * DESCRIPTION - * Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE - * (programmatically). This also opens hSmApiPort to be used - * in loading required subsystems. + * Register with itself for ImageSubsystemId + * (programmatically). */ - -static NTSTATUS -SmpRegisterSmss(VOID) +NTSTATUS STDCALL SmRegisterInternalSubsystem (LPWSTR PgmName, + USHORT ImageSubsystemId, + PHANDLE ApiPort) { - NTSTATUS Status = STATUS_SUCCESS; - RTL_USER_PROCESS_INFORMATION ProcessInfo; + NTSTATUS Status = STATUS_SUCCESS; + RTL_USER_PROCESS_INFORMATION ProcessInfo; - DPRINT("SM: %s called\n",__FUNCTION__); - + DPRINT("SM: %s(%S,%d) called\n",__FUNCTION__, PgmName, ImageSubsystemId); + RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo); ProcessInfo.Size = sizeof ProcessInfo; ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId; ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId; DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n", __FUNCTION__,ProcessInfo.ProcessHandle); - Status = SmCreateClient (& ProcessInfo, L"Session Manager"); + Status = SmCreateClient (& ProcessInfo, PgmName); if (NT_SUCCESS(Status)) { UNICODE_STRING SbApiPortName = {0,0,NULL}; RtlInitUnicodeString (& SbApiPortName, L""); Status = SmConnectApiPort(& SbApiPortName, - (HANDLE) -1, /* SM has no SB port */ - IMAGE_SUBSYSTEM_NATIVE, - & hSmApiPort); + (HANDLE) -1, /* internal SS have no SB port */ + ImageSubsystemId, + ApiPort); if(!NT_SUCCESS(Status)) { DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n", __FUNCTION__,Status); return Status; } - DPRINT("SM self registered\n"); + DPRINT("SM:%s: %S self registered\n", __FUNCTION__, PgmName); } else { - DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n", - __FUNCTION__, Status); + DPRINT1("SM: %s: SmCreateClient(%S) failed (Status=0x%08lx)\n", + __FUNCTION__, PgmName, Status); } /* * Note that you don't need to call complete session - * because connection handling code autocompletes - * the client structure for IMAGE_SUBSYSTEM_NATIVE. + * here because connection handling code autocompletes + * the client structure for IMAGE_SUBSYSTEM_NATIVE and + * -1. */ return Status; } - - /********************************************************************** * SmpLoadRequiredSubsystems/0 */ @@ -157,15 +155,27 @@ SmLoadSubsystems(VOID) NTSTATUS Status = STATUS_SUCCESS; - DPRINT("SM: loading subsystems\n"); + DPRINT("SM: loading subsystems...\n"); - /* SM self registers */ - Status = SmpRegisterSmss(); - if(!NT_SUCCESS(Status)) return Status; + /* + * SM self registers: this also opens hSmApiPort to be used + * in loading required subsystems. + */ + Status = SmRegisterInternalSubsystem (L"Session Manager", IMAGE_SUBSYSTEM_NATIVE, & hSmApiPort); + if(!NT_SUCCESS(Status)) + { + DPRINT1("SM: SmRegisterInternalSubsystem failed Status=%08lx\n", __FUNCTION__, Status); + return Status; + } /* Load Required subsystems (Debug Windows) */ Status = SmpLoadRequiredSubsystems(); - if(!NT_SUCCESS(Status)) return Status; + if(!NT_SUCCESS(Status)) + { + DPRINT1("SM: SmpLoadRequiredSubsystems failed Status=%08lx\n", __FUNCTION__, Status); + return Status; + } /* done */ + DPRINT("SM: done loading subsystems\n"); return Status; } diff --git a/reactos/subsys/smss/smapi.c b/reactos/subsys/smss/smapi.c index 9f5c0042664..0e04888bb04 100644 --- a/reactos/subsys/smss/smapi.c +++ b/reactos/subsys/smss/smapi.c @@ -71,7 +71,7 @@ SmpCallbackServer (PSM_PORT_MESSAGE Request, DPRINT("SM: %s called\n", __FUNCTION__); - if ( (IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->SubSystemId) || + if ( ((USHORT)-1 == ConnectData->SubSystemId) || (IMAGE_SUBSYSTEM_NATIVE == ConnectData->SubSystemId)) { DPRINT("SM: %s: we do not need calling back SM!\n", diff --git a/reactos/subsys/smss/smapiexec.c b/reactos/subsys/smss/smapiexec.c index f7422ed189c..ebb825c7a5e 100644 --- a/reactos/subsys/smss/smapiexec.c +++ b/reactos/subsys/smss/smapiexec.c @@ -34,7 +34,7 @@ * DESCRIPTION * * ARGUMENTS - * ImagePath: bsolute path of the image to run; + * ImagePath: absolute path of the image to run; * CommandLine: arguments and options for ImagePath; * WaitForIt: TRUE for boot time processes and FALSE for * subsystems bootstrapping; @@ -215,6 +215,8 @@ SMAPI(SmExecPgm) Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL); if (!NT_SUCCESS(Status)) { + DPRINT1("SM: %s: NtResumeThread failed (Status=0x%08lx)\n", + __FUNCTION__, Status); //Status = SmDestroyClient TODO } } else { diff --git a/reactos/subsys/smss/smss.h b/reactos/subsys/smss/smss.h index 797c0d2e6df..7d2a26bf7db 100644 --- a/reactos/subsys/smss/smss.h +++ b/reactos/subsys/smss/smss.h @@ -48,6 +48,7 @@ NTSTATUS SmCreatePagingFiles(VOID); NTSTATUS SmInitializeRegistry(VOID); /* initss.c */ +NTSTATUS STDCALL SmRegisterInternalSubsystem(LPWSTR,USHORT,PHANDLE); NTSTATUS SmLoadSubsystems(VOID); /* smapi.c */ @@ -89,7 +90,6 @@ typedef struct _SM_CLIENT_DATA HANDLE ApiPortThread; HANDLE SbApiPort; WCHAR SbApiPortName [SM_SB_NAME_MAX_LENGTH]; - struct _SM_CLIENT_DATA * Next; } SM_CLIENT_DATA, *PSM_CLIENT_DATA; NTSTATUS SmInitializeClientManagement (VOID);