diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c index 4e329e9427b..d8c7256651c 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -106,7 +106,9 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) Thread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); NextEntry = NextEntry->Flink; + ASSERT(ProcessStructureListLocked()); CsrThreadRefcountZero(Thread); + LOCK; } if (pProcessData->ClientViewBase) @@ -233,17 +235,21 @@ CSR_API(CsrTerminateProcess) Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + LOCK; + NextEntry = ProcessData->ThreadList.Flink; while (NextEntry != &ProcessData->ThreadList) { Thread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); NextEntry = NextEntry->Flink; + ASSERT(ProcessStructureListLocked()); CsrThreadRefcountZero(Thread); + LOCK; } - + UNLOCK; ProcessData->Flags |= CsrProcessTerminated; return STATUS_SUCCESS; } diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index 0305854446d..7f7cd9f2898 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -783,9 +783,6 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, return Status; } - /* Hackito ergo sum */ - BasepFakeStaticServerData(); - /* Load us */ Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER); } @@ -825,6 +822,10 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, /* Load it */ if (CsrDebug & 1) DPRINT1("CSRSS: Should be loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); + + /* Hackito ergo sum */ + BasepFakeStaticServerData(); + Status = STATUS_SUCCESS; if (!NT_SUCCESS(Status)) { @@ -1061,7 +1062,7 @@ CsrServerInitialization(IN ULONG ArgumentCount, __FUNCTION__, Status); return Status; } - + /* Set up Session Support */ Status = CsrInitializeNtSessionList(); if (!NT_SUCCESS(Status)) diff --git a/reactos/subsystems/win32/csrss/csrsrv/procsup.c b/reactos/subsystems/win32/csrss/csrsrv/procsup.c index 66efec33beb..f2e33ba31fa 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/procsup.c +++ b/reactos/subsystems/win32/csrss/csrsrv/procsup.c @@ -382,12 +382,141 @@ Quickie: return Status; } +/*++ + * @name CsrProcessRefcountZero + * + * The CsrProcessRefcountZero routine is executed when a CSR Process has lost + * all its active references. It removes and de-allocates the CSR Process. + * + * @param CsrProcess + * Pointer to the CSR Process that is to be deleted. + * + * @return None. + * + * @remarks Do not call this routine. It is reserved for the internal + * thread management routines when a CSR Process has lost all + * its references. + * + * This routine is called with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) +{ + ASSERT(ProcessStructureListLocked()); + + /* Remove the Process from the list */ + CsrRemoveProcess(CsrProcess); + + /* Check if there's a session */ + if (CsrProcess->NtSession) + { + /* Dereference the Session */ + //CsrDereferenceNtSession(CsrProcess->NtSession, 0); + } + + /* Close the Client Port if there is one */ + if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort); + + /* Close the process handle */ + NtClose(CsrProcess->ProcessHandle); + + /* Free the Proces Object */ + CsrDeallocateProcess(CsrProcess); +} + +/*++ + * @name CsrLockedDereferenceProcess + * + * The CsrLockedDereferenceProcess dereferences a CSR Process while the + * Process Lock is already being held. + * + * @param CsrProcess + * Pointer to the CSR Process to be dereferenced. + * + * @return None. + * + * @remarks This routine will return with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess) +{ + LONG LockCount; + + /* Decrease reference count */ + LockCount = --CsrProcess->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) + { + /* Call the generic cleanup code */ + DPRINT1("Should kill process: %p\n", CsrProcess); + //CsrProcessRefcountZero(CsrProcess); + CsrAcquireProcessLock(); + } +} + +/*++ + * @name CsrDereferenceProcess + * @implemented NT4 + * + * The CsrDereferenceProcess routine removes a reference from a CSR Process. + * + * @param CsrThread + * Pointer to the CSR Process to dereference. + * + * @return None. + * + * @remarks If the reference count has reached zero (ie: the CSR Process has + * no more active references), it will be deleted. + * + *--*/ +VOID +NTAPI +CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess) +{ + LONG LockCount; + + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Decrease reference count */ + LockCount = --CsrProcess->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) + { + /* Call the generic cleanup code */ + CsrProcessRefcountZero(CsrProcess); + } + else + { + /* Just release the lock */ + CsrReleaseProcessLock(); + } +} + +/*++ + * @name CsrUnlockProcess + * @implemented NT4 + * + * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation. + * + * @param CsrProcess + * Pointer to a previously locked CSR Process. + * + * @return STATUS_SUCCESS. + * + * @remarks This routine must be called with the Process Lock held. + * + *--*/ NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess) { /* Dereference the process */ - //CsrLockedDereferenceProcess(CsrProcess); + CsrLockedDereferenceProcess(CsrProcess); /* Release the lock and return */ CsrReleaseProcessLock(); diff --git a/reactos/subsystems/win32/csrss/csrsrv/thredsup.c b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c index 471c8a98e60..6cc6f060e01 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/thredsup.c +++ b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c @@ -113,7 +113,7 @@ CsrAllocateThread(IN PCSR_PROCESS CsrProcess) /* Reference the Thread and Process */ CsrThread->ReferenceCount++; - // CsrProcess->ReferenceCount++; + CsrProcess->ReferenceCount++; /* Set the Parent Process */ CsrThread->Process = CsrProcess; @@ -230,6 +230,8 @@ VOID NTAPI CsrRemoveThread(IN PCSR_THREAD CsrThread) { + ASSERT(ProcessStructureListLocked()); + /* Remove it from the List */ RemoveEntryList(&CsrThread->Link); @@ -246,10 +248,10 @@ CsrRemoveThread(IN PCSR_THREAD CsrThread) if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated)) { /* Let everyone know this process is about to lose the thread */ - //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated; + CsrThread->Process->Flags |= CsrProcessLastThreadTerminated; /* Reference the Process */ - //CsrLockedDereferenceProcess(CsrThread->Process); + CsrLockedDereferenceProcess(CsrThread->Process); } } @@ -261,13 +263,15 @@ VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) { + PCSR_PROCESS CsrProcess = CsrThread->Process; NTSTATUS Status; + ASSERT(ProcessStructureListLocked()); /* Remove this thread */ CsrRemoveThread(CsrThread); /* Release the Process Lock */ - //CsrReleaseProcessLock(); + CsrReleaseProcessLock(); /* Close the NT Thread Handle */ if (CsrThread->ThreadHandle) @@ -281,7 +285,7 @@ CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) CsrDeallocateThread(CsrThread); /* Remove a reference from the process */ - //CsrDereferenceProcess(CsrProcess); + CsrDereferenceProcess(CsrProcess); } NTSTATUS diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 0dc8be9b0da..488084e74b8 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -385,12 +385,20 @@ CsrSrvSetPriorityClass( IN OUT PULONG Reply ); +VOID +NTAPI +CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess); + +VOID +NTAPI +CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess); + NTSTATUS NTAPI CsrLoadServerDll(IN PCHAR DllString, IN PCHAR EntryPoint OPTIONAL, IN ULONG ServerId); - + /* api/user.c */ CSR_API(CsrRegisterServicesProcess);