From: Sir Richard Date: Wed, 10 Mar 2010 06:49:53 +0000 (+0000) Subject: [CSRSRV]: Move the new process/thread management functions into new, dedicated files... X-Git-Tag: backups/header-work@57446~158^2~47 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=34fa6fb97b3f5892d0c8b9681b95e4cf06ece3aa [CSRSRV]: Move the new process/thread management functions into new, dedicated files. Export some of the functions, so that win32csr can use them by linking to csrsrv. Last change needed for barebones user-mode shutdown support. svn path=/trunk/; revision=46052 --- diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c index 423424b86e3..5fcac045c70 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -15,298 +15,19 @@ #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); diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild index 5cd35e28f40..3f002106bfe 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.rbuild @@ -15,6 +15,8 @@ user.c wapi.c + procsup.c + thredsup.c init.c srv.h diff --git a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec index c394d83df49..d3e7b64f40f 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec +++ b/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec @@ -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) @@ -13,23 +13,23 @@ ;@ 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) diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index 59b69c54e37..c6fa69b42de 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -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 index 00000000000..d139d9701d6 --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/procsup.c @@ -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 + +#define NDEBUG +#include + +#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 index 00000000000..e893888773b --- /dev/null +++ b/reactos/subsystems/win32/csrss/csrsrv/thredsup.c @@ -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 + +#define NDEBUG +#include + +#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 */ diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 463ee50c002..7fbf6db9e58 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -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);