SM: simplify and fix client (subsystem servers) management.
authorEmanuele Aliberti <ea@iol.it>
Sat, 27 Aug 2005 09:55:27 +0000 (09:55 +0000)
committerEmanuele Aliberti <ea@iol.it>
Sat, 27 Aug 2005 09:55:27 +0000 (09:55 +0000)
svn path=/trunk/; revision=17567

reactos/subsys/smss/client.c
reactos/subsys/smss/debug.c
reactos/subsys/smss/initss.c
reactos/subsys/smss/smapi.c
reactos/subsys/smss/smapiexec.c
reactos/subsys/smss/smss.h

index e516fe5..21dc329 100644 (file)
 
 /* 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);
index 62619f3..56bbac4 100644 (file)
@@ -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,
index bc180df..656b139 100644 (file)
@@ -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;
 }
 
index 9f5c004..0e04888 100644 (file)
@@ -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",
index f7422ed..ebb825c 100644 (file)
@@ -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 {
index 797c0d2..7d2a26b 100644 (file)
@@ -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);