[CSRSRV]: Move the new process/thread management functions into new, dedicated files...
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 10 Mar 2010 06:49:53 +0000 (06:49 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 10 Mar 2010 06:49:53 +0000 (06:49 +0000)
svn path=/trunk/; revision=46052

reactos/subsystems/win32/csrss/csrsrv/api/process.c
reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild
reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec
reactos/subsystems/win32/csrss/csrsrv/init.c
reactos/subsystems/win32/csrss/csrsrv/procsup.c [new file with mode: 0644]
reactos/subsystems/win32/csrss/csrsrv/thredsup.c [new file with mode: 0644]
reactos/subsystems/win32/csrss/include/api.h

index 423424b..5fcac04 100644 (file)
 
 #define LOCK   RtlEnterCriticalSection(&ProcessDataLock)
 #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
+#define CsrAcquireProcessLock() LOCK
+#define CsrReleaseProcessLock() UNLOCK
 
 /* GLOBALS *******************************************************************/
 
 static ULONG NrProcess;
-static PCSRSS_PROCESS_DATA ProcessData[256];
+PCSRSS_PROCESS_DATA ProcessData[256];
 RTL_CRITICAL_SECTION ProcessDataLock;
+extern PCSRSS_PROCESS_DATA CsrRootProcess;
+extern LIST_ENTRY CsrThreadHashTable[256];
 
 /* FUNCTIONS *****************************************************************/
 
-#define CsrHeap RtlGetProcessHeap()
-
-#define CsrHashThread(t) \
-    (HandleToUlong(t)&(256 - 1))
-    
-LIST_ENTRY CsrThreadHashTable[256];
-PCSRSS_PROCESS_DATA CsrRootProcess;
-
-PCSR_THREAD
-NTAPI
-CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess)
-{
-    PCSR_THREAD CsrThread;
-
-    /* Allocate the structure */
-    CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
-    if (!CsrThread) return(NULL);
-
-    /* Reference the Thread and Process */
-    CsrThread->ReferenceCount++;
-   // CsrProcess->ReferenceCount++;
-
-    /* Set the Parent Process */
-    CsrThread->Process = CsrProcess;
-
-    /* Return Thread */
-    return CsrThread;
-}
-
-PCSR_THREAD
-NTAPI
-CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL,
-                          IN PCLIENT_ID ClientId)
-{
-    ULONG i;
-    PLIST_ENTRY ListHead, NextEntry;
-    PCSR_THREAD FoundThread;
-
-    /* Hash the Thread */
-    i = CsrHashThread(ClientId->UniqueThread);
-    
-    /* Set the list pointers */
-    ListHead = &CsrThreadHashTable[i];
-    NextEntry = ListHead->Flink;
-
-    /* Star the loop */
-    while (NextEntry != ListHead)
-    {
-        /* Get the thread */
-        FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
-
-        /* Compare the CID */
-        if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
-        {
-            /* Match found, return the process */
-            *Process = FoundThread->Process;
-
-            /* Return thread too */
-//            DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
-            return FoundThread;
-        }
-
-        /* Next */
-        NextEntry = NextEntry->Flink;
-    }
-
-    /* Nothing found */
-    return NULL;
-}
-
-PCSR_THREAD
-NTAPI
-CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL,
-                         IN PCLIENT_ID Cid)
-{
-    PLIST_ENTRY ListHead, NextEntry;
-    PCSR_THREAD FoundThread = NULL;
-
-    /* Use the Root Process if none was specified */
-    if (!CsrProcess) CsrProcess = CsrRootProcess;
-
-    /* Save the List pointers */
-//    DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
-    ListHead = &CsrProcess->ThreadList;
-    NextEntry = ListHead->Flink;
-
-    /* Start the Loop */
-    while (NextEntry != ListHead)
-    {
-        /* Get Thread Entry */
-        FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
-        /* Check for TID Match */
-        if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
-
-        /* Next entry */
-        NextEntry = NextEntry->Flink;
-    }
-
-    /* Return what we found */
-//    DPRINT1("Found: %p\n", FoundThread);
-    return FoundThread;
-}
-
-VOID
-NTAPI
-CsrInsertThread(IN PCSRSS_PROCESS_DATA Process,
-                IN PCSR_THREAD Thread)
-{
-    ULONG i;
-
-    /* Insert it into the Regular List */
-    InsertTailList(&Process->ThreadList, &Thread->Link);
-
-    /* Increase Thread Count */
-    Process->ThreadCount++;
-
-    /* Hash the Thread */
-    i = CsrHashThread(Thread->ClientId.UniqueThread);
-//    DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
-
-    /* Insert it there too */
-    InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks);
-}
-
-
-#define CsrAcquireProcessLock() LOCK
-#define CsrReleaseProcessLock() UNLOCK
-
-VOID
-NTAPI
-CsrDeallocateThread(IN PCSR_THREAD CsrThread)
-{
-    /* Free the process object from the heap */
-    RtlFreeHeap(CsrHeap, 0, CsrThread);
-}
-
-VOID
-NTAPI
-CsrRemoveThread(IN PCSR_THREAD CsrThread)
-{
-    /* Remove it from the List */
-    RemoveEntryList(&CsrThread->Link);
-
-    /* Decreate the thread count of the process */
-    CsrThread->Process->ThreadCount--;
-
-    /* Remove it from the Hash List as well */
-    if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
-
-    /* Check if this is the last Thread */
-    if (!CsrThread->Process->ThreadCount)
-    {
-        /* Check if it's not already been marked for deletion */
-        if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated))
-        {
-            /* Let everyone know this process is about to lose the thread */
-            //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated;
-
-            /* Reference the Process */
-            //CsrLockedDereferenceProcess(CsrThread->Process);
-        }
-    }
-
-    /* Mark the thread for deletion */
-    CsrThread->Flags |= CsrThreadInTermination;
-}
-
-VOID
-NTAPI
-CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
-{
-    /* Remove this thread */
-    CsrRemoveThread(CsrThread);
-
-    /* Release the Process Lock */
-    //CsrReleaseProcessLock();
-
-    /* Close the NT Thread Handle */
-    if (CsrThread->ThreadHandle) NtClose(CsrThread->ThreadHandle);
-    
-    /* De-allocate the CSR Thread Object */
-    CsrDeallocateThread(CsrThread);
-
-    /* Remove a reference from the process */
-    //CsrDereferenceProcess(CsrProcess);
-}
-
-NTSTATUS
-NTAPI
-CsrCreateThreadData(IN PCSRSS_PROCESS_DATA CsrProcess,
-                    IN HANDLE hThread,
-                    IN PCLIENT_ID ClientId)
-{
-    NTSTATUS Status;
-    PCSR_THREAD CsrThread;
-    //PCSRSS_PROCESS_DATA CurrentProcess;
-    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
-    CLIENT_ID CurrentCid;
-    KERNEL_USER_TIMES KernelTimes;
-
-//    DPRINT1("CSRSRV: %s called\n", __FUNCTION__);
-
-    /* Get the current thread and CID */
-    CurrentCid = CurrentThread->ClientId;
-//    DPRINT1("CALLER PID/TID: %lx/%lx\n", CurrentCid.UniqueProcess, CurrentCid.UniqueThread);
-
-    /* Acquire the Process Lock */
-    CsrAcquireProcessLock();
-#if 0
-    /* Get the current Process and make sure the Thread is valid with this CID */
-    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
-                                              &CurrentCid);
-
-    /* Something is wrong if we get an empty thread back */
-    if (!CurrentThread)
-    {
-        DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
-        CsrReleaseProcessLock();
-        return STATUS_THREAD_IS_TERMINATING;
-    }
-#endif
-    /* Get the Thread Create Time */
-    Status = NtQueryInformationThread(hThread,
-                                      ThreadTimes,
-                                      (PVOID)&KernelTimes,
-                                      sizeof(KernelTimes),
-                                      NULL);
-
-    /* Allocate a CSR Thread Structure */
-    if (!(CsrThread = CsrAllocateThread(CsrProcess)))
-    {
-        DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
-        CsrReleaseProcessLock();
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Save the data we have */
-    CsrThread->CreateTime = KernelTimes.CreateTime;
-    CsrThread->ClientId = *ClientId;
-    CsrThread->ThreadHandle = hThread;
-    CsrThread->Flags = 0;
-
-    /* Insert the Thread into the Process */
-    CsrInsertThread(CsrProcess, CsrThread);
-
-    /* Release the lock and return */
-    CsrReleaseProcessLock();
-    return STATUS_SUCCESS;
-}
-
-PCSR_THREAD
-NTAPI
-CsrAddStaticServerThread(IN HANDLE hThread,
-                         IN PCLIENT_ID ClientId,
-                         IN ULONG ThreadFlags)
-{
-    PCSR_THREAD CsrThread;
-
-    /* Get the Lock */
-    CsrAcquireProcessLock();
-
-    /* Allocate the Server Thread */
-    if ((CsrThread = CsrAllocateThread(CsrRootProcess)))
-    {
-        /* Setup the Object */
-//        DPRINT1("New CSR thread created: %lx PID/TID: %lx/%lx\n", CsrThread, ClientId->UniqueProcess, ClientId->UniqueThread);
-        CsrThread->ThreadHandle = hThread;
-        CsrThread->ClientId = *ClientId;
-        CsrThread->Flags = ThreadFlags;
-
-        /* Insert it into the Thread List */
-        InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
-
-        /* Increment the thread count */
-        CsrRootProcess->ThreadCount++;
-    }
-
-    /* Release the Process Lock and return */
-    CsrReleaseProcessLock();
-    return CsrThread;
-}
-
 VOID WINAPI CsrInitProcessData(VOID)
 {
     ULONG i;
@@ -477,409 +198,6 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid)
    return STATUS_INVALID_PARAMETER;
 }
 
-VOID
-NTAPI
-CsrSetToNormalPriority(VOID)
-{
-    KPRIORITY BasePriority = (8 + 1) + 4;
-
-    /* Set the Priority */
-    NtSetInformationProcess(NtCurrentProcess(),
-                            ProcessBasePriority,
-                            &BasePriority,
-                            sizeof(KPRIORITY));
-}
-
-VOID
-NTAPI
-CsrSetToShutdownPriority(VOID)
-{
-    KPRIORITY SetBasePriority = (8 + 1) + 6;
-    BOOLEAN Old;
-
-    /* Get the shutdown privilege */
-    if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
-                                      TRUE,
-                                      FALSE,
-                                      &Old)))
-    {
-        /* Set the Priority */
-        NtSetInformationProcess(NtCurrentProcess(),
-                                ProcessBasePriority,
-                                &SetBasePriority,
-                                sizeof(KPRIORITY));
-    }
-}
-
-NTSTATUS
-NTAPI
-CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
-                  PLUID Luid)
-{
-    HANDLE hToken = NULL;
-    NTSTATUS Status;
-    ULONG Length;
-    PTOKEN_STATISTICS TokenStats;
-
-    /* Check if we have a handle to a CSR Process */
-    if (!hProcess)
-    {
-        /* We don't, so try opening the Thread's Token */
-        Status = NtOpenThreadToken(NtCurrentThread(),
-                                   TOKEN_QUERY,
-                                   FALSE,
-                                   &hToken);
-
-        /* Check for success */
-        if (!NT_SUCCESS(Status))
-        {
-            /* If we got some other failure, then return and quit */
-            if (Status != STATUS_NO_TOKEN) return Status;
-
-            /* We don't have a Thread Token, use a Process Token */
-            hProcess = NtCurrentProcess();
-            hToken = NULL;
-        }
-    }
-
-    /* Check if we have a token by now */
-    if (!hToken)
-    {
-        /* No token yet, so open the Process Token */
-        Status = NtOpenProcessToken(hProcess,
-                                    TOKEN_QUERY,
-                                    &hToken);
-        if (!NT_SUCCESS(Status))
-        {
-            /* Still no token, return the error */
-            return Status;
-        }
-    }
-
-    /* Now get the size we'll need for the Token Information */
-    Status = NtQueryInformationToken(hToken,
-                                     TokenStatistics,
-                                     NULL,
-                                     0,
-                                     &Length);
-
-    /* Allocate memory for the Token Info */
-    if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
-    {
-        /* Fail and close the token */
-        NtClose(hToken);
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Now query the information */
-    Status = NtQueryInformationToken(hToken,
-                                     TokenStatistics,
-                                     TokenStats,
-                                     Length,
-                                     &Length);
-
-    /* Close the handle */
-    NtClose(hToken);
-
-    /* Check for success */
-    if (NT_SUCCESS(Status))
-    {
-        /* Return the LUID */
-        *Luid = TokenStats->AuthenticationId;
-    }
-
-    /* Free the query information */
-    RtlFreeHeap(CsrHeap, 0, TokenStats);
-
-    /* Return the Status */
-    return Status;
-}
-
-SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
-{
-    sizeof(SECURITY_QUALITY_OF_SERVICE),
-    SecurityImpersonation,
-    SECURITY_STATIC_TRACKING,
-    FALSE
-};
-
-BOOLEAN
-NTAPI
-CsrImpersonateClient(IN PCSR_THREAD CsrThread)
-{
-    NTSTATUS Status;
-    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
-
-    /* Use the current thread if none given */
-    if (!CsrThread) CsrThread = CurrentThread;
-
-    /* Still no thread, something is wrong */
-    if (!CsrThread)
-    {
-        /* Failure */
-        return FALSE;
-    }
-
-    /* Make the call */
-    Status = NtImpersonateThread(NtCurrentThread(),
-                                 CsrThread->ThreadHandle,
-                                 &CsrSecurityQos);
-
-    if (!NT_SUCCESS(Status))
-    {
-        /* Failure */
-        return FALSE;
-    }
-
-    /* Increase the impersonation count for the current thread */
-    if (CurrentThread) ++CurrentThread->ImpersonationCount;
-
-    /* Return Success */
-    return TRUE;
-}
-
-BOOLEAN
-NTAPI
-CsrRevertToSelf(VOID)
-{
-    NTSTATUS Status;
-    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
-    HANDLE ImpersonationToken = NULL;
-
-    /* Check if we have a Current Thread */
-    if (CurrentThread)
-    {
-        /* Make sure impersonation is on */
-        if (!CurrentThread->ImpersonationCount)
-        {
-            return FALSE;
-        }
-        else if (--CurrentThread->ImpersonationCount > 0)
-        {
-            /* Success; impersonation count decreased but still not zero */
-            return TRUE;
-        }
-    }
-
-    /* Impersonation has been totally removed, revert to ourselves */
-    Status = NtSetInformationThread(NtCurrentThread(),
-                                    ThreadImpersonationToken,
-                                    &ImpersonationToken,
-                                    sizeof(HANDLE));
-
-    /* Return TRUE or FALSE */
-    return NT_SUCCESS(Status);
-}
-
-PCSRSS_PROCESS_DATA
-NTAPI
-FindProcessForShutdown(IN PLUID CallerLuid)
-{
-    ULONG Hash;
-    PCSRSS_PROCESS_DATA CsrProcess, ReturnCsrProcess = NULL;
-    NTSTATUS Status;
-    ULONG Level = 0;
-    LUID ProcessLuid;
-    LUID SystemLuid = SYSTEM_LUID;
-    BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
-    
-    for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
-    {
-        /* Get this process hash bucket */
-        CsrProcess = ProcessData[Hash];
-        while (CsrProcess)
-        {
-            /* Skip this process if it's already been processed*/
-            if (CsrProcess->Flags & CsrProcessSkipShutdown) goto Next;
-        
-            /* Get the LUID of this Process */
-            Status = CsrGetProcessLuid(CsrProcess->Process, &ProcessLuid);
-
-            /* Check if we didn't get access to the LUID */
-            if (Status == STATUS_ACCESS_DENIED)
-            {
-                /* FIXME:Check if we have any threads */
-            }
-            
-            if (!NT_SUCCESS(Status))
-            {
-                /* We didn't have access, so skip it */
-                CsrProcess->Flags |= CsrProcessSkipShutdown;
-                goto Next;
-            }
-            
-            /* Check if this is the System LUID */
-            if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid)))
-            {
-                /* Mark this process */
-                CsrProcess->ShutdownFlags |= CsrShutdownSystem;
-            }
-            else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid)))
-            {
-                /* Our LUID doesn't match with the caller's */
-                CsrProcess->ShutdownFlags |= CsrShutdownOther;
-            }
-            
-            /* Check if we're past the previous level */
-            if (CsrProcess->ShutdownLevel > Level)
-            {
-                /* Update the level */
-                Level = CsrProcess->ShutdownLevel;
-
-                /* Set the final process */
-                ReturnCsrProcess = CsrProcess;
-            }
-Next:
-            /* Next process */
-            CsrProcess = CsrProcess->next;
-        }
-    }
-    
-    /* Check if we found a process */
-    if (ReturnCsrProcess)
-    {
-        /* Skip this one next time */
-        ReturnCsrProcess->Flags |= CsrProcessSkipShutdown;
-    }
-    
-    return ReturnCsrProcess;
-}
-
-/* This is really "CsrShutdownProcess", mostly */
-NTSTATUS
-WINAPI
-CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc,
-                 IN PVOID Context)
-{
-    PVOID* RealContext = (PVOID*)Context;
-    PLUID CallerLuid = RealContext[0];
-    PCSRSS_PROCESS_DATA CsrProcess = NULL;
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
-    BOOLEAN FirstTry;
-    ULONG Result = 0;
-    ULONG Hash;
-
-    /* Acquire process lock */
-    CsrAcquireProcessLock();
-
-    /* Start the loop */
-    for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
-    {
-        /* Get the Process */
-        CsrProcess = ProcessData[Hash];
-        while (CsrProcess)
-        {
-           /* Remove the skip flag, set shutdown flags to 0*/
-            CsrProcess->Flags &= ~CsrProcessSkipShutdown;
-            CsrProcess->ShutdownFlags = 0;
-
-            /* Move to the next */
-            CsrProcess = CsrProcess->next;
-        }
-    }
-
-    /* Set shudown Priority */
-    CsrSetToShutdownPriority();
-
-    /* Loop all processes */
-    DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart);
-    
-    /* Start looping */
-    while (TRUE)
-    {
-        /* Find the next process to shutdown */
-        FirstTry = TRUE;
-        if (!(CsrProcess = FindProcessForShutdown(CallerLuid)))
-        {
-            /* Done, quit */
-            CsrReleaseProcessLock();
-            Status = STATUS_SUCCESS;
-            goto Quickie;
-        }
-
-LoopAgain:
-        /* Release the lock, make the callback, and acquire it back */
-        DPRINT1("Found process: %lx\n", CsrProcess->ProcessId);
-        CsrReleaseProcessLock();
-        Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry));
-        CsrAcquireProcessLock();
-
-        /* Check the result */
-        DPRINT1("Result: %d\n", Result);
-        if (Result == CsrShutdownCsrProcess)
-        {
-            /* The callback unlocked the process */
-            break;
-        }
-        else if (Result == CsrShutdownNonCsrProcess)
-        {
-            /* A non-CSR process, the callback didn't touch it */
-            //continue;
-        }
-        else if (Result == CsrShutdownCancelled)
-        {
-            /* Shutdown was cancelled, unlock and exit */
-            CsrReleaseProcessLock();
-            Status = STATUS_CANCELLED;
-            goto Quickie;
-        }
-
-        /* No matches during the first try, so loop again */
-        if (FirstTry && Result == CsrShutdownNonCsrProcess)
-        {
-            FirstTry = FALSE;
-            goto LoopAgain;
-        }
-    }
-
-Quickie:
-    /* Return to normal priority */
-    CsrSetToNormalPriority();
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-CsrLockProcessByClientId(IN HANDLE Pid,
-                         OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL)
-{
-    ULONG Hash;
-    PCSRSS_PROCESS_DATA CurrentProcess = NULL;
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
-
-    /* Acquire the lock */
-    CsrAcquireProcessLock();
-
-    /* Start the loop */
-    for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
-    {
-        /* Get the Process */
-        CurrentProcess = ProcessData[Hash];
-        while (CurrentProcess)
-        {
-            /* Check for PID match */
-            if (CurrentProcess->ProcessId == Pid)
-            {
-                /* Get out of here with success */
-//                DPRINT1("Found %p for PID %lx\n", CurrentProcess, Pid);
-                Status = STATUS_SUCCESS;
-                goto Found;
-            }
-            
-            /* Move to the next */
-            CurrentProcess = CurrentProcess->next;
-        }
-    }
-    
-    /* Nothing found, release the lock */
-Found:
-    if (!CurrentProcess) CsrReleaseProcessLock();
-
-    /* Return the status and process */
-    if (CsrProcess) *CsrProcess = CurrentProcess;
-    return Status;
-}
-
 /**********************************************************************
  *     CSRSS API
  *********************************************************************/
@@ -920,7 +238,7 @@ CSR_API(CsrCreateProcess)
    return(STATUS_SUCCESS);
 }
 
-CSR_API(CsrCreateThread)
+CSR_API(CsrSrvCreateThread)
 {
     PCSR_THREAD CurrentThread;
     HANDLE ThreadHandle;
@@ -979,7 +297,7 @@ CSR_API(CsrCreateThread)
     Status = STATUS_SUCCESS; // hack
     if (NT_SUCCESS(Status))
     {
-        Status = CsrCreateThreadData(CsrProcess,
+        Status = CsrCreateThread(CsrProcess,
                                      ThreadHandle,
                                      &Request->Data.CreateThreadRequest.ClientId);
        // DPRINT1("Create status: %lx\n", Status);
index 5cd35e2..3f00210 100644 (file)
@@ -15,6 +15,8 @@
                <file>user.c</file>
                <file>wapi.c</file>
        </directory>
+       <file>procsup.c</file>
+       <file>thredsup.c</file>
        <file>init.c</file>
        <pch>srv.h</pch>
 </module>
index c394d83..d3e7b64 100644 (file)
@@ -1,9 +1,9 @@
-;@ stdcall CsrAddStaticServerThread(ptr ptr long)
+@ stdcall CsrAddStaticServerThread(ptr ptr long)
 ;@ stdcall CsrCallServerFromServer(ptr ptr)
 ;@ stdcall CsrConnectToUser()
 ;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
 ;@ stdcall CsrCreateRemoteThread(ptr ptr)
-;@ stdcall CsrCreateThread(ptr ptr ptr)
+@ stdcall CsrCreateThread(ptr ptr ptr)
 ;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
 ;@ stdcall CsrDebugProcess(ptr)
 ;@ stdcall CsrDebugProcessStop(ptr)
 ;@ stdcall CsrDestroyProcess(ptr long)
 ;@ stdcall CsrDestroyThread(ptr)
 ;@ stdcall CsrExecServerThread(ptr long)
-;@ stdcall CsrGetProcessLuid(ptr ptr)
-;@ stdcall CsrImpersonateClient(ptr)
-;@ stdcall CsrLockProcessByClientId(ptr ptr)
+@ stdcall CsrGetProcessLuid(ptr ptr)
+@ stdcall CsrImpersonateClient(ptr)
+@ stdcall CsrLockProcessByClientId(ptr ptr)
 ;@ stdcall CsrLockThreadByClientId(ptr ptr)
 ;@ stdcall CsrMoveSatisfiedWait(ptr ptr)
 ;@ stdcall CsrNotifyWait(ptr long ptr ptr)
 ;@ stdcall CsrPopulateDosDevices()
 ;@ stdcall CsrQueryApiPort()
 ;@ stdcall CsrReferenceThread(ptr)
-;@ stdcall CsrRevertToSelf()
+@ stdcall CsrRevertToSelf()
 @ stdcall CsrServerInitialization(long ptr)
 ;@ stdcall CsrSetBackgroundPriority(ptr)
 ;@ stdcall CsrSetCallingSpooler(long)
 ;@ stdcall CsrSetForegroundPriority(ptr)
 ;@ stdcall CsrShutdownProcesses(ptr long)
 ;@ stdcall CsrUnhandledExceptionFilter(ptr)
-;@ stdcall CsrUnlockProcess(ptr)
+@ stdcall CsrUnlockProcess(ptr)
 ;@ stdcall CsrUnlockThread(ptr)
 ;@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
 ;@ stdcall CsrValidateMessageString(ptr ptr)
index 59b69c5..c6fa69b 100644 (file)
@@ -364,7 +364,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp)
 CSRSS_API_DEFINITION NativeDefinitions[] =
   {
     CSRSS_DEFINE_API(CREATE_PROCESS,               CsrCreateProcess),
-    CSRSS_DEFINE_API(CREATE_THREAD,                CsrCreateThread),
+    CSRSS_DEFINE_API(CREATE_THREAD,                CsrSrvCreateThread),
     CSRSS_DEFINE_API(TERMINATE_PROCESS,            CsrTerminateProcess),
     CSRSS_DEFINE_API(CONNECT_PROCESS,              CsrConnectProcess),
     CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS,    CsrRegisterServicesProcess),
diff --git a/reactos/subsystems/win32/csrss/csrsrv/procsup.c b/reactos/subsystems/win32/csrss/csrsrv/procsup.c
new file mode 100644 (file)
index 0000000..d139d97
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS CSR Sub System
+ * FILE:            subsys/csr/csrsrv/procsup.c
+ * PURPOSE:         CSR Process Management
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ *                  Alex Ionescu
+ */
+/* INCLUDES *******************************************************************/
+
+#include <srv.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#define LOCK   RtlEnterCriticalSection(&ProcessDataLock)
+#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
+#define CsrHeap RtlGetProcessHeap()
+
+#define CsrAcquireProcessLock() LOCK
+#define CsrReleaseProcessLock() UNLOCK
+
+/* GLOBALS ********************************************************************/
+
+extern RTL_CRITICAL_SECTION ProcessDataLock;
+extern PCSRSS_PROCESS_DATA ProcessData[256];
+PCSRSS_PROCESS_DATA CsrRootProcess;
+LIST_ENTRY CsrThreadHashTable[256];
+SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
+{
+    sizeof(SECURITY_QUALITY_OF_SERVICE),
+    SecurityImpersonation,
+    SECURITY_STATIC_TRACKING,
+    FALSE
+};
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+CsrSetToNormalPriority(VOID)
+{
+    KPRIORITY BasePriority = (8 + 1) + 4;
+
+    /* Set the Priority */
+    NtSetInformationProcess(NtCurrentProcess(),
+                            ProcessBasePriority,
+                            &BasePriority,
+                            sizeof(KPRIORITY));
+}
+
+VOID
+NTAPI
+CsrSetToShutdownPriority(VOID)
+{
+    KPRIORITY SetBasePriority = (8 + 1) + 6;
+    BOOLEAN Old;
+
+    /* Get the shutdown privilege */
+    if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
+                                      TRUE,
+                                      FALSE,
+                                      &Old)))
+    {
+        /* Set the Priority */
+        NtSetInformationProcess(NtCurrentProcess(),
+                                ProcessBasePriority,
+                                &SetBasePriority,
+                                sizeof(KPRIORITY));
+    }
+}
+
+NTSTATUS
+NTAPI
+CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
+                  PLUID Luid)
+{
+    HANDLE hToken = NULL;
+    NTSTATUS Status;
+    ULONG Length;
+    PTOKEN_STATISTICS TokenStats;
+
+    /* Check if we have a handle to a CSR Process */
+    if (!hProcess)
+    {
+        /* We don't, so try opening the Thread's Token */
+        Status = NtOpenThreadToken(NtCurrentThread(),
+                                   TOKEN_QUERY,
+                                   FALSE,
+                                   &hToken);
+
+        /* Check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* If we got some other failure, then return and quit */
+            if (Status != STATUS_NO_TOKEN) return Status;
+
+            /* We don't have a Thread Token, use a Process Token */
+            hProcess = NtCurrentProcess();
+            hToken = NULL;
+        }
+    }
+
+    /* Check if we have a token by now */
+    if (!hToken)
+    {
+        /* No token yet, so open the Process Token */
+        Status = NtOpenProcessToken(hProcess,
+                                    TOKEN_QUERY,
+                                    &hToken);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Still no token, return the error */
+            return Status;
+        }
+    }
+
+    /* Now get the size we'll need for the Token Information */
+    Status = NtQueryInformationToken(hToken,
+                                     TokenStatistics,
+                                     NULL,
+                                     0,
+                                     &Length);
+
+    /* Allocate memory for the Token Info */
+    if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
+    {
+        /* Fail and close the token */
+        NtClose(hToken);
+        return STATUS_NO_MEMORY;
+    }
+
+    /* Now query the information */
+    Status = NtQueryInformationToken(hToken,
+                                     TokenStatistics,
+                                     TokenStats,
+                                     Length,
+                                     &Length);
+
+    /* Close the handle */
+    NtClose(hToken);
+
+    /* Check for success */
+    if (NT_SUCCESS(Status))
+    {
+        /* Return the LUID */
+        *Luid = TokenStats->AuthenticationId;
+    }
+
+    /* Free the query information */
+    RtlFreeHeap(CsrHeap, 0, TokenStats);
+
+    /* Return the Status */
+    return Status;
+}
+
+BOOLEAN
+NTAPI
+CsrImpersonateClient(IN PCSR_THREAD CsrThread)
+{
+    NTSTATUS Status;
+    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
+
+    /* Use the current thread if none given */
+    if (!CsrThread) CsrThread = CurrentThread;
+
+    /* Still no thread, something is wrong */
+    if (!CsrThread)
+    {
+        /* Failure */
+        return FALSE;
+    }
+
+    /* Make the call */
+    Status = NtImpersonateThread(NtCurrentThread(),
+                                 CsrThread->ThreadHandle,
+                                 &CsrSecurityQos);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failure */
+        return FALSE;
+    }
+
+    /* Increase the impersonation count for the current thread */
+    if (CurrentThread) ++CurrentThread->ImpersonationCount;
+
+    /* Return Success */
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+CsrRevertToSelf(VOID)
+{
+    NTSTATUS Status;
+    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
+    HANDLE ImpersonationToken = NULL;
+
+    /* Check if we have a Current Thread */
+    if (CurrentThread)
+    {
+        /* Make sure impersonation is on */
+        if (!CurrentThread->ImpersonationCount)
+        {
+            return FALSE;
+        }
+        else if (--CurrentThread->ImpersonationCount > 0)
+        {
+            /* Success; impersonation count decreased but still not zero */
+            return TRUE;
+        }
+    }
+
+    /* Impersonation has been totally removed, revert to ourselves */
+    Status = NtSetInformationThread(NtCurrentThread(),
+                                    ThreadImpersonationToken,
+                                    &ImpersonationToken,
+                                    sizeof(HANDLE));
+
+    /* Return TRUE or FALSE */
+    return NT_SUCCESS(Status);
+}
+
+PCSRSS_PROCESS_DATA
+NTAPI
+FindProcessForShutdown(IN PLUID CallerLuid)
+{
+    ULONG Hash;
+    PCSRSS_PROCESS_DATA CsrProcess, ReturnCsrProcess = NULL;
+    NTSTATUS Status;
+    ULONG Level = 0;
+    LUID ProcessLuid;
+    LUID SystemLuid = SYSTEM_LUID;
+    BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
+    
+    for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
+    {
+        /* Get this process hash bucket */
+        CsrProcess = ProcessData[Hash];
+        while (CsrProcess)
+        {
+            /* Skip this process if it's already been processed*/
+            if (CsrProcess->Flags & CsrProcessSkipShutdown) goto Next;
+        
+            /* Get the LUID of this Process */
+            Status = CsrGetProcessLuid(CsrProcess->Process, &ProcessLuid);
+
+            /* Check if we didn't get access to the LUID */
+            if (Status == STATUS_ACCESS_DENIED)
+            {
+                /* FIXME:Check if we have any threads */
+            }
+            
+            if (!NT_SUCCESS(Status))
+            {
+                /* We didn't have access, so skip it */
+                CsrProcess->Flags |= CsrProcessSkipShutdown;
+                goto Next;
+            }
+            
+            /* Check if this is the System LUID */
+            if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid)))
+            {
+                /* Mark this process */
+                CsrProcess->ShutdownFlags |= CsrShutdownSystem;
+            }
+            else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid)))
+            {
+                /* Our LUID doesn't match with the caller's */
+                CsrProcess->ShutdownFlags |= CsrShutdownOther;
+            }
+            
+            /* Check if we're past the previous level */
+            if (CsrProcess->ShutdownLevel > Level)
+            {
+                /* Update the level */
+                Level = CsrProcess->ShutdownLevel;
+
+                /* Set the final process */
+                ReturnCsrProcess = CsrProcess;
+            }
+Next:
+            /* Next process */
+            CsrProcess = CsrProcess->next;
+        }
+    }
+    
+    /* Check if we found a process */
+    if (ReturnCsrProcess)
+    {
+        /* Skip this one next time */
+        ReturnCsrProcess->Flags |= CsrProcessSkipShutdown;
+    }
+    
+    return ReturnCsrProcess;
+}
+
+/* This is really "CsrShutdownProcess", mostly */
+NTSTATUS
+WINAPI
+CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc,
+                 IN PVOID Context)
+{
+    PVOID* RealContext = (PVOID*)Context;
+    PLUID CallerLuid = RealContext[0];
+    PCSRSS_PROCESS_DATA CsrProcess = NULL;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    BOOLEAN FirstTry;
+    ULONG Result = 0;
+    ULONG Hash;
+
+    /* Acquire process lock */
+    CsrAcquireProcessLock();
+
+    /* Start the loop */
+    for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
+    {
+        /* Get the Process */
+        CsrProcess = ProcessData[Hash];
+        while (CsrProcess)
+        {
+           /* Remove the skip flag, set shutdown flags to 0*/
+            CsrProcess->Flags &= ~CsrProcessSkipShutdown;
+            CsrProcess->ShutdownFlags = 0;
+
+            /* Move to the next */
+            CsrProcess = CsrProcess->next;
+        }
+    }
+
+    /* Set shudown Priority */
+    CsrSetToShutdownPriority();
+
+    /* Loop all processes */
+    //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart);
+    
+    /* Start looping */
+    while (TRUE)
+    {
+        /* Find the next process to shutdown */
+        FirstTry = TRUE;
+        if (!(CsrProcess = FindProcessForShutdown(CallerLuid)))
+        {
+            /* Done, quit */
+            CsrReleaseProcessLock();
+            Status = STATUS_SUCCESS;
+            goto Quickie;
+        }
+
+LoopAgain:
+        /* Release the lock, make the callback, and acquire it back */
+        //DPRINT1("Found process: %lx\n", CsrProcess->ProcessId);
+        CsrReleaseProcessLock();
+        Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry));
+        CsrAcquireProcessLock();
+
+        /* Check the result */
+        //DPRINT1("Result: %d\n", Result);
+        if (Result == CsrShutdownCsrProcess)
+        {
+            /* The callback unlocked the process */
+            break;
+        }
+        else if (Result == CsrShutdownNonCsrProcess)
+        {
+            /* A non-CSR process, the callback didn't touch it */
+            //continue;
+        }
+        else if (Result == CsrShutdownCancelled)
+        {
+            /* Shutdown was cancelled, unlock and exit */
+            CsrReleaseProcessLock();
+            Status = STATUS_CANCELLED;
+            goto Quickie;
+        }
+
+        /* No matches during the first try, so loop again */
+        if (FirstTry && Result == CsrShutdownNonCsrProcess)
+        {
+            FirstTry = FALSE;
+            goto LoopAgain;
+        }
+    }
+
+Quickie:
+    /* Return to normal priority */
+    CsrSetToNormalPriority();
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CsrLockProcessByClientId(IN HANDLE Pid,
+                         OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL)
+{
+    ULONG Hash;
+    PCSRSS_PROCESS_DATA CurrentProcess = NULL;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+    /* Acquire the lock */
+    CsrAcquireProcessLock();
+
+    /* Start the loop */
+    for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
+    {
+        /* Get the Process */
+        CurrentProcess = ProcessData[Hash];
+        while (CurrentProcess)
+        {
+            /* Check for PID match */
+            if (CurrentProcess->ProcessId == Pid)
+            {
+                /* Get out of here with success */
+//                DPRINT1("Found %p for PID %lx\n", CurrentProcess, Pid);
+                Status = STATUS_SUCCESS;
+                goto Found;
+            }
+            
+            /* Move to the next */
+            CurrentProcess = CurrentProcess->next;
+        }
+    }
+    
+    /* Nothing found, release the lock */
+Found:
+    if (!CurrentProcess) CsrReleaseProcessLock();
+
+    /* Return the status and process */
+    if (CsrProcess) *CsrProcess = CurrentProcess;
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+CsrUnlockProcess(IN PCSRSS_PROCESS_DATA CsrProcess)
+{
+    /* Dereference the process */
+    //CsrLockedDereferenceProcess(CsrProcess);
+
+    /* Release the lock and return */
+    CsrReleaseProcessLock();
+    return STATUS_SUCCESS;
+}
+
+/* EOF */
diff --git a/reactos/subsystems/win32/csrss/csrsrv/thredsup.c b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c
new file mode 100644 (file)
index 0000000..e893888
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS CSR Sub System
+ * FILE:            subsys/csr/csrsrv/procsup.c
+ * PURPOSE:         CSR Process Management
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ *                  Alex Ionescu
+ */
+/* INCLUDES *******************************************************************/
+
+#include <srv.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#define LOCK   RtlEnterCriticalSection(&ProcessDataLock)
+#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
+#define CsrHeap RtlGetProcessHeap()
+#define CsrHashThread(t) \
+    (HandleToUlong(t)&(256 - 1))
+
+#define CsrAcquireProcessLock() LOCK
+#define CsrReleaseProcessLock() UNLOCK
+
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY CsrThreadHashTable[256];
+extern PCSRSS_PROCESS_DATA CsrRootProcess;
+extern RTL_CRITICAL_SECTION ProcessDataLock;
+extern PCSRSS_PROCESS_DATA ProcessData[256];
+
+/* FUNCTIONS ******************************************************************/
+
+PCSR_THREAD
+NTAPI
+CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess)
+{
+    PCSR_THREAD CsrThread;
+
+    /* Allocate the structure */
+    CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
+    if (!CsrThread) return(NULL);
+
+    /* Reference the Thread and Process */
+    CsrThread->ReferenceCount++;
+   // CsrProcess->ReferenceCount++;
+
+    /* Set the Parent Process */
+    CsrThread->Process = CsrProcess;
+
+    /* Return Thread */
+    return CsrThread;
+}
+
+PCSR_THREAD
+NTAPI
+CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL,
+                          IN PCLIENT_ID ClientId)
+{
+    ULONG i;
+    PLIST_ENTRY ListHead, NextEntry;
+    PCSR_THREAD FoundThread;
+
+    /* Hash the Thread */
+    i = CsrHashThread(ClientId->UniqueThread);
+    
+    /* Set the list pointers */
+    ListHead = &CsrThreadHashTable[i];
+    NextEntry = ListHead->Flink;
+
+    /* Star the loop */
+    while (NextEntry != ListHead)
+    {
+        /* Get the thread */
+        FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
+
+        /* Compare the CID */
+        if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
+        {
+            /* Match found, return the process */
+            *Process = FoundThread->Process;
+
+            /* Return thread too */
+//            DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
+            return FoundThread;
+        }
+
+        /* Next */
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Nothing found */
+    return NULL;
+}
+
+PCSR_THREAD
+NTAPI
+CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL,
+                         IN PCLIENT_ID Cid)
+{
+    PLIST_ENTRY ListHead, NextEntry;
+    PCSR_THREAD FoundThread = NULL;
+
+    /* Use the Root Process if none was specified */
+    if (!CsrProcess) CsrProcess = CsrRootProcess;
+
+    /* Save the List pointers */
+//    DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
+    ListHead = &CsrProcess->ThreadList;
+    NextEntry = ListHead->Flink;
+
+    /* Start the Loop */
+    while (NextEntry != ListHead)
+    {
+        /* Get Thread Entry */
+        FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
+
+        /* Check for TID Match */
+        if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
+
+        /* Next entry */
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Return what we found */
+//    DPRINT1("Found: %p\n", FoundThread);
+    return FoundThread;
+}
+
+VOID
+NTAPI
+CsrInsertThread(IN PCSRSS_PROCESS_DATA Process,
+                IN PCSR_THREAD Thread)
+{
+    ULONG i;
+
+    /* Insert it into the Regular List */
+    InsertTailList(&Process->ThreadList, &Thread->Link);
+
+    /* Increase Thread Count */
+    Process->ThreadCount++;
+
+    /* Hash the Thread */
+    i = CsrHashThread(Thread->ClientId.UniqueThread);
+//    DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
+
+    /* Insert it there too */
+    InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks);
+}
+
+VOID
+NTAPI
+CsrDeallocateThread(IN PCSR_THREAD CsrThread)
+{
+    /* Free the process object from the heap */
+    RtlFreeHeap(CsrHeap, 0, CsrThread);
+}
+
+VOID
+NTAPI
+CsrRemoveThread(IN PCSR_THREAD CsrThread)
+{
+    /* Remove it from the List */
+    RemoveEntryList(&CsrThread->Link);
+
+    /* Decreate the thread count of the process */
+    CsrThread->Process->ThreadCount--;
+
+    /* Remove it from the Hash List as well */
+    if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
+
+    /* Check if this is the last Thread */
+    if (!CsrThread->Process->ThreadCount)
+    {
+        /* Check if it's not already been marked for deletion */
+        if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated))
+        {
+            /* Let everyone know this process is about to lose the thread */
+            //CsrThread->Process->Flags |= CsrProcessLastThreadTerminated;
+
+            /* Reference the Process */
+            //CsrLockedDereferenceProcess(CsrThread->Process);
+        }
+    }
+
+    /* Mark the thread for deletion */
+    CsrThread->Flags |= CsrThreadInTermination;
+}
+
+VOID
+NTAPI
+CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
+{
+    /* Remove this thread */
+    CsrRemoveThread(CsrThread);
+
+    /* Release the Process Lock */
+    //CsrReleaseProcessLock();
+
+    /* Close the NT Thread Handle */
+    if (CsrThread->ThreadHandle) NtClose(CsrThread->ThreadHandle);
+    
+    /* De-allocate the CSR Thread Object */
+    CsrDeallocateThread(CsrThread);
+
+    /* Remove a reference from the process */
+    //CsrDereferenceProcess(CsrProcess);
+}
+
+NTSTATUS
+NTAPI
+CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess,
+                IN HANDLE hThread,
+                IN PCLIENT_ID ClientId)
+{
+    NTSTATUS Status;
+    PCSR_THREAD CsrThread;
+    //PCSRSS_PROCESS_DATA CurrentProcess;
+    PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
+    CLIENT_ID CurrentCid;
+    KERNEL_USER_TIMES KernelTimes;
+
+//    DPRINT1("CSRSRV: %s called\n", __FUNCTION__);
+
+    /* Get the current thread and CID */
+    CurrentCid = CurrentThread->ClientId;
+//    DPRINT1("CALLER PID/TID: %lx/%lx\n", CurrentCid.UniqueProcess, CurrentCid.UniqueThread);
+
+    /* Acquire the Process Lock */
+    CsrAcquireProcessLock();
+#if 0
+    /* Get the current Process and make sure the Thread is valid with this CID */
+    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
+                                              &CurrentCid);
+
+    /* Something is wrong if we get an empty thread back */
+    if (!CurrentThread)
+    {
+        DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
+        CsrReleaseProcessLock();
+        return STATUS_THREAD_IS_TERMINATING;
+    }
+#endif
+    /* Get the Thread Create Time */
+    Status = NtQueryInformationThread(hThread,
+                                      ThreadTimes,
+                                      (PVOID)&KernelTimes,
+                                      sizeof(KernelTimes),
+                                      NULL);
+
+    /* Allocate a CSR Thread Structure */
+    if (!(CsrThread = CsrAllocateThread(CsrProcess)))
+    {
+        DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
+        CsrReleaseProcessLock();
+        return STATUS_NO_MEMORY;
+    }
+
+    /* Save the data we have */
+    CsrThread->CreateTime = KernelTimes.CreateTime;
+    CsrThread->ClientId = *ClientId;
+    CsrThread->ThreadHandle = hThread;
+    CsrThread->Flags = 0;
+
+    /* Insert the Thread into the Process */
+    CsrInsertThread(CsrProcess, CsrThread);
+
+    /* Release the lock and return */
+    CsrReleaseProcessLock();
+    return STATUS_SUCCESS;
+}
+
+PCSR_THREAD
+NTAPI
+CsrAddStaticServerThread(IN HANDLE hThread,
+                         IN PCLIENT_ID ClientId,
+                         IN ULONG ThreadFlags)
+{
+    PCSR_THREAD CsrThread;
+
+    /* Get the Lock */
+    CsrAcquireProcessLock();
+
+    /* Allocate the Server Thread */
+    if ((CsrThread = CsrAllocateThread(CsrRootProcess)))
+    {
+        /* Setup the Object */
+//        DPRINT1("New CSR thread created: %lx PID/TID: %lx/%lx\n", CsrThread, ClientId->UniqueProcess, ClientId->UniqueThread);
+        CsrThread->ThreadHandle = hThread;
+        CsrThread->ClientId = *ClientId;
+        CsrThread->Flags = ThreadFlags;
+
+        /* Insert it into the Thread List */
+        InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
+
+        /* Increment the thread count */
+        CsrRootProcess->ThreadCount++;
+    }
+
+    /* Release the Process Lock and return */
+    CsrReleaseProcessLock();
+    return CsrThread;
+}
+
+/* EOF */
index 463ee50..7fbf6db 100644 (file)
@@ -148,7 +148,7 @@ extern HANDLE hBootstrapOk;
 CSR_API(CsrConnectProcess);
 CSR_API(CsrCreateProcess);
 CSR_API(CsrTerminateProcess);
-CSR_API(CsrCreateThread);
+CSR_API(CsrSrvCreateThread);
 
 /* print.c */
 VOID WINAPI DisplayString(LPCWSTR lpwString);
@@ -181,7 +181,10 @@ NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context
 PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN  ULONG ThreadFlags);
 PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSRSS_PROCESS_DATA CsrProcess OPTIONAL, IN PCLIENT_ID Cid);
 PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSRSS_PROCESS_DATA *Process OPTIONAL, IN PCLIENT_ID ClientId);
-                             
+NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSRSS_PROCESS_DATA *CsrProcess OPTIONAL);
+NTSTATUS NTAPI CsrCreateThread(IN PCSRSS_PROCESS_DATA CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId);
+NTSTATUS NTAPI CsrUnlockProcess(IN PCSRSS_PROCESS_DATA CsrProcess);
+
 /* api/handle.c */
 NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
 NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable );
@@ -192,6 +195,9 @@ NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object);
 NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
 NTSTATUS WINAPI CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
 
+//hack
+VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
+
 CSR_API(CsrGetInputHandle);
 CSR_API(CsrGetOutputHandle);
 CSR_API(CsrCloseHandle);