mirror of
https://github.com/reactos/reactos.git
synced 2025-05-23 02:56:09 +00:00
[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
This commit is contained in:
parent
1cd9cb22ef
commit
34fa6fb97b
7 changed files with 778 additions and 699 deletions
|
@ -15,298 +15,19 @@
|
||||||
|
|
||||||
#define LOCK RtlEnterCriticalSection(&ProcessDataLock)
|
#define LOCK RtlEnterCriticalSection(&ProcessDataLock)
|
||||||
#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
|
#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
|
||||||
|
#define CsrAcquireProcessLock() LOCK
|
||||||
|
#define CsrReleaseProcessLock() UNLOCK
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
static ULONG NrProcess;
|
static ULONG NrProcess;
|
||||||
static PCSRSS_PROCESS_DATA ProcessData[256];
|
PCSRSS_PROCESS_DATA ProcessData[256];
|
||||||
RTL_CRITICAL_SECTION ProcessDataLock;
|
RTL_CRITICAL_SECTION ProcessDataLock;
|
||||||
|
extern PCSRSS_PROCESS_DATA CsrRootProcess;
|
||||||
|
extern LIST_ENTRY CsrThreadHashTable[256];
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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)
|
VOID WINAPI CsrInitProcessData(VOID)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -477,409 +198,6 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid)
|
||||||
return STATUS_INVALID_PARAMETER;
|
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
|
* CSRSS API
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
@ -920,7 +238,7 @@ CSR_API(CsrCreateProcess)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSR_API(CsrCreateThread)
|
CSR_API(CsrSrvCreateThread)
|
||||||
{
|
{
|
||||||
PCSR_THREAD CurrentThread;
|
PCSR_THREAD CurrentThread;
|
||||||
HANDLE ThreadHandle;
|
HANDLE ThreadHandle;
|
||||||
|
@ -979,7 +297,7 @@ CSR_API(CsrCreateThread)
|
||||||
Status = STATUS_SUCCESS; // hack
|
Status = STATUS_SUCCESS; // hack
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = CsrCreateThreadData(CsrProcess,
|
Status = CsrCreateThread(CsrProcess,
|
||||||
ThreadHandle,
|
ThreadHandle,
|
||||||
&Request->Data.CreateThreadRequest.ClientId);
|
&Request->Data.CreateThreadRequest.ClientId);
|
||||||
// DPRINT1("Create status: %lx\n", Status);
|
// DPRINT1("Create status: %lx\n", Status);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
<file>user.c</file>
|
<file>user.c</file>
|
||||||
<file>wapi.c</file>
|
<file>wapi.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
|
<file>procsup.c</file>
|
||||||
|
<file>thredsup.c</file>
|
||||||
<file>init.c</file>
|
<file>init.c</file>
|
||||||
<pch>srv.h</pch>
|
<pch>srv.h</pch>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
;@ stdcall CsrAddStaticServerThread(ptr ptr long)
|
@ stdcall CsrAddStaticServerThread(ptr ptr long)
|
||||||
;@ stdcall CsrCallServerFromServer(ptr ptr)
|
;@ stdcall CsrCallServerFromServer(ptr ptr)
|
||||||
;@ stdcall CsrConnectToUser()
|
;@ stdcall CsrConnectToUser()
|
||||||
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
|
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
|
||||||
;@ stdcall CsrCreateRemoteThread(ptr ptr)
|
;@ stdcall CsrCreateRemoteThread(ptr ptr)
|
||||||
;@ stdcall CsrCreateThread(ptr ptr ptr)
|
@ stdcall CsrCreateThread(ptr ptr ptr)
|
||||||
;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
|
;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
|
||||||
;@ stdcall CsrDebugProcess(ptr)
|
;@ stdcall CsrDebugProcess(ptr)
|
||||||
;@ stdcall CsrDebugProcessStop(ptr)
|
;@ stdcall CsrDebugProcessStop(ptr)
|
||||||
|
@ -13,23 +13,23 @@
|
||||||
;@ stdcall CsrDestroyProcess(ptr long)
|
;@ stdcall CsrDestroyProcess(ptr long)
|
||||||
;@ stdcall CsrDestroyThread(ptr)
|
;@ stdcall CsrDestroyThread(ptr)
|
||||||
;@ stdcall CsrExecServerThread(ptr long)
|
;@ stdcall CsrExecServerThread(ptr long)
|
||||||
;@ stdcall CsrGetProcessLuid(ptr ptr)
|
@ stdcall CsrGetProcessLuid(ptr ptr)
|
||||||
;@ stdcall CsrImpersonateClient(ptr)
|
@ stdcall CsrImpersonateClient(ptr)
|
||||||
;@ stdcall CsrLockProcessByClientId(ptr ptr)
|
@ stdcall CsrLockProcessByClientId(ptr ptr)
|
||||||
;@ stdcall CsrLockThreadByClientId(ptr ptr)
|
;@ stdcall CsrLockThreadByClientId(ptr ptr)
|
||||||
;@ stdcall CsrMoveSatisfiedWait(ptr ptr)
|
;@ stdcall CsrMoveSatisfiedWait(ptr ptr)
|
||||||
;@ stdcall CsrNotifyWait(ptr long ptr ptr)
|
;@ stdcall CsrNotifyWait(ptr long ptr ptr)
|
||||||
;@ stdcall CsrPopulateDosDevices()
|
;@ stdcall CsrPopulateDosDevices()
|
||||||
;@ stdcall CsrQueryApiPort()
|
;@ stdcall CsrQueryApiPort()
|
||||||
;@ stdcall CsrReferenceThread(ptr)
|
;@ stdcall CsrReferenceThread(ptr)
|
||||||
;@ stdcall CsrRevertToSelf()
|
@ stdcall CsrRevertToSelf()
|
||||||
@ stdcall CsrServerInitialization(long ptr)
|
@ stdcall CsrServerInitialization(long ptr)
|
||||||
;@ stdcall CsrSetBackgroundPriority(ptr)
|
;@ stdcall CsrSetBackgroundPriority(ptr)
|
||||||
;@ stdcall CsrSetCallingSpooler(long)
|
;@ stdcall CsrSetCallingSpooler(long)
|
||||||
;@ stdcall CsrSetForegroundPriority(ptr)
|
;@ stdcall CsrSetForegroundPriority(ptr)
|
||||||
;@ stdcall CsrShutdownProcesses(ptr long)
|
;@ stdcall CsrShutdownProcesses(ptr long)
|
||||||
;@ stdcall CsrUnhandledExceptionFilter(ptr)
|
;@ stdcall CsrUnhandledExceptionFilter(ptr)
|
||||||
;@ stdcall CsrUnlockProcess(ptr)
|
@ stdcall CsrUnlockProcess(ptr)
|
||||||
;@ stdcall CsrUnlockThread(ptr)
|
;@ stdcall CsrUnlockThread(ptr)
|
||||||
;@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
|
;@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
|
||||||
;@ stdcall CsrValidateMessageString(ptr ptr)
|
;@ stdcall CsrValidateMessageString(ptr ptr)
|
||||||
|
|
|
@ -364,7 +364,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp)
|
||||||
CSRSS_API_DEFINITION NativeDefinitions[] =
|
CSRSS_API_DEFINITION NativeDefinitions[] =
|
||||||
{
|
{
|
||||||
CSRSS_DEFINE_API(CREATE_PROCESS, CsrCreateProcess),
|
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(TERMINATE_PROCESS, CsrTerminateProcess),
|
||||||
CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess),
|
CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess),
|
||||||
CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess),
|
CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess),
|
||||||
|
|
447
reactos/subsystems/win32/csrss/csrsrv/procsup.c
Normal file
447
reactos/subsystems/win32/csrss/csrsrv/procsup.c
Normal file
|
@ -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 */
|
306
reactos/subsystems/win32/csrss/csrsrv/thredsup.c
Normal file
306
reactos/subsystems/win32/csrss/csrsrv/thredsup.c
Normal file
|
@ -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 */
|
|
@ -148,7 +148,7 @@ extern HANDLE hBootstrapOk;
|
||||||
CSR_API(CsrConnectProcess);
|
CSR_API(CsrConnectProcess);
|
||||||
CSR_API(CsrCreateProcess);
|
CSR_API(CsrCreateProcess);
|
||||||
CSR_API(CsrTerminateProcess);
|
CSR_API(CsrTerminateProcess);
|
||||||
CSR_API(CsrCreateThread);
|
CSR_API(CsrSrvCreateThread);
|
||||||
|
|
||||||
/* print.c */
|
/* print.c */
|
||||||
VOID WINAPI DisplayString(LPCWSTR lpwString);
|
VOID WINAPI DisplayString(LPCWSTR lpwString);
|
||||||
|
@ -181,6 +181,9 @@ 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 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 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);
|
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 */
|
/* api/handle.c */
|
||||||
NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
|
NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
|
||||||
|
@ -192,6 +195,9 @@ NTSTATUS WINAPI CsrReleaseObjectByPointer(Object_t *Object);
|
||||||
NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
|
NTSTATUS WINAPI CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
|
||||||
NTSTATUS WINAPI CsrVerifyObject( 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(CsrGetInputHandle);
|
||||||
CSR_API(CsrGetOutputHandle);
|
CSR_API(CsrGetOutputHandle);
|
||||||
CSR_API(CsrCloseHandle);
|
CSR_API(CsrCloseHandle);
|
||||||
|
|
Loading…
Reference in a new issue