mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-01 19:26:16 +00:00
[CSRSRV]: Port the alloc/dealloc/insert/remove CsrProcess management functions from CSRSRV2. There is no longer a hash table being used but instead a linked list just like in real CSRSRV(2 for us). This brings us closer to the CSRSRV2 model and makes some of the older ported code cleaner too.
svn path=/trunk/; revision=55624
This commit is contained in:
@@ -13,191 +13,428 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define CSR_SERVER_DLL_MAX 4
|
||||
#define LOCK RtlEnterCriticalSection(&ProcessDataLock)
|
||||
#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
|
||||
#define CsrAcquireProcessLock() LOCK
|
||||
#define CsrReleaseProcessLock() UNLOCK
|
||||
|
||||
#define ProcessStructureListLocked() \
|
||||
(ProcessDataLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
|
||||
|
||||
extern NTSTATUS CallProcessInherit(PCSR_PROCESS, PCSR_PROCESS);
|
||||
extern NTSTATUS CallProcessDeleted(PCSR_PROCESS);
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static ULONG NrProcess;
|
||||
PCSR_PROCESS ProcessData[256];
|
||||
RTL_CRITICAL_SECTION ProcessDataLock;
|
||||
RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock;
|
||||
extern PCSR_PROCESS CsrRootProcess;
|
||||
extern LIST_ENTRY CsrThreadHashTable[256];
|
||||
extern ULONG CsrTotalPerProcessDataLength;
|
||||
LONG CsrProcessSequenceCount = 5;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID WINAPI CsrInitProcessData(VOID)
|
||||
/*++
|
||||
* @name CsrAllocateProcess
|
||||
* @implemented NT4
|
||||
*
|
||||
* The CsrAllocateProcess routine allocates a new CSR Process object.
|
||||
*
|
||||
* @return Pointer to the newly allocated CSR Process.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
PCSR_PROCESS
|
||||
NTAPI
|
||||
CsrAllocateProcess(VOID)
|
||||
{
|
||||
PCSR_PROCESS CsrProcess;
|
||||
ULONG TotalSize;
|
||||
|
||||
/* Calculate the amount of memory this should take */
|
||||
TotalSize = sizeof(CSR_PROCESS) +
|
||||
(CSR_SERVER_DLL_MAX * sizeof(PVOID)) +
|
||||
CsrTotalPerProcessDataLength;
|
||||
|
||||
/* Allocate a Process */
|
||||
CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize);
|
||||
if (!CsrProcess) return NULL;
|
||||
|
||||
/* Handle the Sequence Number and protect against overflow */
|
||||
CsrProcess->SequenceNumber = CsrProcessSequenceCount++;
|
||||
if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
|
||||
|
||||
/* Increase the reference count */
|
||||
CsrProcess->ReferenceCount++;
|
||||
|
||||
/* Initialize the Thread List */
|
||||
InitializeListHead(&CsrProcess->ThreadList);
|
||||
|
||||
/* Return the Process */
|
||||
return CsrProcess;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrLockedReferenceProcess
|
||||
*
|
||||
* The CsrLockedReferenceProcess refences a CSR Process while the
|
||||
* Process Lock is already being held.
|
||||
*
|
||||
* @param CsrProcess
|
||||
* Pointer to the CSR Process to be referenced.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks This routine will return with the Process Lock held.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
|
||||
{
|
||||
/* Increment the reference count */
|
||||
++CsrProcess->ReferenceCount;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrServerInitialization
|
||||
* @implemented NT4
|
||||
*
|
||||
* The CsrInitializeProcessStructure routine sets up support for CSR Processes
|
||||
* and CSR Threads.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
||||
* othwerwise.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrInitializeProcessStructure(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
RtlZeroMemory (ProcessData, sizeof ProcessData);
|
||||
NrProcess = sizeof ProcessData / sizeof ProcessData[0];
|
||||
RtlInitializeCriticalSection( &ProcessDataLock );
|
||||
|
||||
CsrRootProcess = CsrCreateProcessData(NtCurrentTeb()->ClientId.UniqueProcess);
|
||||
|
||||
/* Initialize the Thread Hash List */
|
||||
for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
|
||||
|
||||
/* Initialize the Lock */
|
||||
Status = RtlInitializeCriticalSection(&ProcessDataLock);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Set up the Root Process */
|
||||
CsrRootProcess = CsrAllocateProcess();
|
||||
if (!CsrRootProcess) return STATUS_NO_MEMORY;
|
||||
|
||||
/* Set up the minimal information for it */
|
||||
InitializeListHead(&CsrRootProcess->ListLink);
|
||||
CsrRootProcess->ProcessHandle = (HANDLE)-1;
|
||||
CsrRootProcess->ClientId = NtCurrentTeb()->ClientId;
|
||||
|
||||
/* Initialize the Thread Hash List */
|
||||
for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
|
||||
|
||||
/* Initialize the Wait Lock */
|
||||
return RtlInitializeCriticalSection(&CsrWaitListsLock);
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrDeallocateProcess
|
||||
*
|
||||
* The CsrDeallocateProcess frees the memory associated with a CSR Process.
|
||||
*
|
||||
* @param CsrProcess
|
||||
* Pointer to the CSR Process to be freed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks Do not call this routine. It is reserved for the internal
|
||||
* thread management routines when a CSR Process has been cleanly
|
||||
* dereferenced and killed.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess)
|
||||
{
|
||||
/* Free the process object from the heap */
|
||||
RtlFreeHeap(CsrHeap, 0, CsrProcess);
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrRemoveProcess
|
||||
*
|
||||
* The CsrRemoveProcess function undoes a CsrInsertProcess operation and
|
||||
* removes the CSR Process from the Process List and notifies Server DLLs
|
||||
* of this removal.
|
||||
*
|
||||
* @param CsrProcess
|
||||
* Pointer to the CSR Process to remove.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
|
||||
{
|
||||
#if 0
|
||||
PCSR_SERVER_DLL ServerDll;
|
||||
ULONG i;
|
||||
#endif
|
||||
ASSERT(ProcessStructureListLocked());
|
||||
|
||||
/* Remove us from the Process List */
|
||||
RemoveEntryList(&CsrProcess->ListLink);
|
||||
|
||||
/* Release the lock */
|
||||
CsrReleaseProcessLock();
|
||||
#if 0
|
||||
/* Loop every Server DLL */
|
||||
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
|
||||
{
|
||||
/* Get the Server DLL */
|
||||
ServerDll = CsrLoadedServerDll[i];
|
||||
|
||||
/* Check if it's valid and if it has a Disconnect Callback */
|
||||
if (ServerDll && ServerDll->DisconnectCallback)
|
||||
{
|
||||
/* Call it */
|
||||
(ServerDll->DisconnectCallback)(CsrProcess);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrInsertProcess
|
||||
*
|
||||
* The CsrInsertProcess routine inserts a CSR Process into the Process List
|
||||
* and notifies Server DLLs of the creation of a new CSR Process.
|
||||
*
|
||||
* @param Parent
|
||||
* Optional pointer to the CSR Process creating this CSR Process.
|
||||
*
|
||||
* @param CurrentProcess
|
||||
* Optional pointer to the current CSR Process.
|
||||
*
|
||||
* @param CsrProcess
|
||||
* Pointer to the CSR Process which is to be inserted.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
|
||||
IN PCSR_PROCESS CurrentProcess OPTIONAL,
|
||||
IN PCSR_PROCESS CsrProcess)
|
||||
{
|
||||
#if 0
|
||||
PCSR_SERVER_DLL ServerDll;
|
||||
ULONG i;
|
||||
#endif
|
||||
ASSERT(ProcessStructureListLocked());
|
||||
|
||||
/* Set the parent */
|
||||
CsrProcess->Parent = Parent;
|
||||
|
||||
/* Insert it into the Root List */
|
||||
InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink);
|
||||
#if 0
|
||||
/* Notify the Server DLLs */
|
||||
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
|
||||
{
|
||||
/* Get the current Server DLL */
|
||||
ServerDll = CsrLoadedServerDll[i];
|
||||
|
||||
/* Make sure it's valid and that it has callback */
|
||||
if ((ServerDll) && (ServerDll->NewProcessCallback))
|
||||
{
|
||||
ServerDll->NewProcessCallback(CurrentProcess, CsrProcess);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name CsrLockProcessByClientId
|
||||
* @implemented NT4
|
||||
*
|
||||
* The CsrLockProcessByClientId routine locks the CSR Process corresponding
|
||||
* to the given Process ID and optionally returns it.
|
||||
*
|
||||
* @param Pid
|
||||
* Process ID corresponding to the CSR Process which will be locked.
|
||||
*
|
||||
* @param CsrProcess
|
||||
* Optional pointer to a CSR Process pointer which will hold the
|
||||
* CSR Process corresponding to the given Process ID.
|
||||
*
|
||||
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
|
||||
* othwerwise.
|
||||
*
|
||||
* @remarks Locking a CSR Process is defined as acquiring an extra
|
||||
* reference to it and returning with the Process Lock held.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrLockProcessByClientId(IN HANDLE Pid,
|
||||
OUT PCSR_PROCESS *CsrProcess)
|
||||
{
|
||||
PLIST_ENTRY NextEntry;
|
||||
PCSR_PROCESS CurrentProcess = NULL;
|
||||
|
||||
/* Acquire the lock */
|
||||
CsrAcquireProcessLock();
|
||||
|
||||
/* Assume failure */
|
||||
ASSERT(CsrProcess != NULL);
|
||||
*CsrProcess = NULL;
|
||||
|
||||
/* Setup the List Pointers */
|
||||
NextEntry = CsrRootProcess->ListLink.Flink;
|
||||
while (NextEntry != &CsrRootProcess->ListLink)
|
||||
{
|
||||
/* Get the Process */
|
||||
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
||||
|
||||
/* Check for PID Match */
|
||||
if (CurrentProcess->ClientId.UniqueProcess == Pid) break;
|
||||
|
||||
/* Next entry */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* Check if we didn't find it in the list */
|
||||
if (NextEntry == &CsrRootProcess->ListLink)
|
||||
{
|
||||
/* Nothing found, release the lock */
|
||||
CsrReleaseProcessLock();
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Lock the found process and return it */
|
||||
CsrLockedReferenceProcess(CurrentProcess);
|
||||
*CsrProcess = CurrentProcess;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
PCSR_PROCESS WINAPI CsrGetProcessData(HANDLE ProcessId)
|
||||
{
|
||||
ULONG hash;
|
||||
PCSR_PROCESS pProcessData;
|
||||
|
||||
hash = ((ULONG_PTR)ProcessId >> 2) % (sizeof(ProcessData) / sizeof(*ProcessData));
|
||||
|
||||
LOCK;
|
||||
|
||||
pProcessData = ProcessData[hash];
|
||||
|
||||
while (pProcessData && pProcessData->ClientId.UniqueProcess != ProcessId)
|
||||
{
|
||||
pProcessData = pProcessData->next;
|
||||
}
|
||||
UNLOCK;
|
||||
return pProcessData;
|
||||
PCSR_PROCESS CsrProcess;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = CsrLockProcessByClientId(ProcessId, &CsrProcess);
|
||||
if (!NT_SUCCESS(Status)) return NULL;
|
||||
|
||||
UNLOCK;
|
||||
return CsrProcess;
|
||||
}
|
||||
|
||||
PCSR_PROCESS WINAPI CsrCreateProcessData(HANDLE ProcessId)
|
||||
{
|
||||
ULONG hash;
|
||||
PCSR_PROCESS pProcessData;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
CLIENT_ID ClientId;
|
||||
NTSTATUS Status;
|
||||
PCSR_PROCESS pProcessData;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
CLIENT_ID ClientId;
|
||||
NTSTATUS Status;
|
||||
|
||||
hash = ((ULONG_PTR)ProcessId >> 2) % (sizeof(ProcessData) / sizeof(*ProcessData));
|
||||
|
||||
LOCK;
|
||||
|
||||
pProcessData = ProcessData[hash];
|
||||
|
||||
while (pProcessData && pProcessData->ClientId.UniqueProcess != ProcessId)
|
||||
{
|
||||
pProcessData = pProcessData->next;
|
||||
}
|
||||
if (pProcessData == NULL)
|
||||
{
|
||||
pProcessData = RtlAllocateHeap(CsrHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(CSR_PROCESS));
|
||||
if (pProcessData)
|
||||
{
|
||||
pProcessData->ClientId.UniqueProcess = ProcessId;
|
||||
pProcessData->next = ProcessData[hash];
|
||||
ProcessData[hash] = pProcessData;
|
||||
|
||||
ClientId.UniqueThread = NULL;
|
||||
ClientId.UniqueProcess = pProcessData->ClientId.UniqueProcess;
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
|
||||
Status = NtOpenProcess(&pProcessData->ProcessHandle,
|
||||
PROCESS_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&ClientId);
|
||||
DPRINT("CSR Process: %p Handle: %p\n", pProcessData, pProcessData->ProcessHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ProcessData[hash] = pProcessData->next;
|
||||
RtlFreeHeap(CsrHeap, 0, pProcessData);
|
||||
pProcessData = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitializeCriticalSection(&pProcessData->HandleTableLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Process data for pid %d already exist\n", ProcessId);
|
||||
}
|
||||
UNLOCK;
|
||||
if (pProcessData == NULL)
|
||||
{
|
||||
DPRINT1("CsrCreateProcessData() failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
pProcessData->Flags = ~CsrProcessTerminated;
|
||||
|
||||
/* Set default shutdown parameters */
|
||||
pProcessData->ShutdownLevel = 0x280;
|
||||
pProcessData->ShutdownFlags = 0;
|
||||
}
|
||||
LOCK;
|
||||
|
||||
pProcessData->ThreadCount = 0;
|
||||
InitializeListHead(&pProcessData->ThreadList);
|
||||
return pProcessData;
|
||||
pProcessData = CsrAllocateProcess();
|
||||
ASSERT(pProcessData != NULL);
|
||||
|
||||
pProcessData->ClientId.UniqueProcess = ProcessId;
|
||||
|
||||
ClientId.UniqueThread = NULL;
|
||||
ClientId.UniqueProcess = pProcessData->ClientId.UniqueProcess;
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
|
||||
Status = NtOpenProcess(&pProcessData->ProcessHandle,
|
||||
PROCESS_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&ClientId);
|
||||
DPRINT("CSR Process: %p Handle: %p\n", pProcessData, pProcessData->ProcessHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed\n");
|
||||
CsrDeallocateProcess(pProcessData);
|
||||
CsrReleaseProcessLock();
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitializeCriticalSection(&pProcessData->HandleTableLock);
|
||||
}
|
||||
|
||||
/* Set default shutdown parameters */
|
||||
pProcessData->ShutdownLevel = 0x280;
|
||||
pProcessData->ShutdownFlags = 0;
|
||||
|
||||
/* Insert the Process */
|
||||
CsrInsertProcess(NULL, NULL, pProcessData);
|
||||
|
||||
/* Release lock and return */
|
||||
CsrReleaseProcessLock();
|
||||
return pProcessData;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid)
|
||||
{
|
||||
ULONG hash;
|
||||
PCSR_PROCESS pProcessData, *pPrevLink;
|
||||
HANDLE Process;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PCSR_THREAD Thread;
|
||||
PCSR_PROCESS pProcessData;
|
||||
HANDLE Process;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PCSR_THREAD Thread;
|
||||
|
||||
hash = ((ULONG_PTR)Pid >> 2) % (sizeof(ProcessData) / sizeof(*ProcessData));
|
||||
pPrevLink = &ProcessData[hash];
|
||||
pProcessData = CsrGetProcessData(Pid);
|
||||
if (!pProcessData) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
LOCK;
|
||||
LOCK;
|
||||
|
||||
while ((pProcessData = *pPrevLink) && pProcessData->ClientId.UniqueProcess != Pid)
|
||||
Process = pProcessData->ProcessHandle;
|
||||
CallProcessDeleted(pProcessData);
|
||||
|
||||
/* Dereference all process threads */
|
||||
NextEntry = pProcessData->ThreadList.Flink;
|
||||
while (NextEntry != &pProcessData->ThreadList)
|
||||
{
|
||||
pPrevLink = &pProcessData->next;
|
||||
}
|
||||
|
||||
if (pProcessData)
|
||||
{
|
||||
DPRINT("CsrFreeProcessData pid: %d\n", Pid);
|
||||
Process = pProcessData->ProcessHandle;
|
||||
CallProcessDeleted(pProcessData);
|
||||
|
||||
/* Dereference all process threads */
|
||||
NextEntry = pProcessData->ThreadList.Flink;
|
||||
while (NextEntry != &pProcessData->ThreadList)
|
||||
{
|
||||
Thread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
CsrThreadRefcountZero(Thread);
|
||||
}
|
||||
}
|
||||
|
||||
if (pProcessData->ClientViewBase)
|
||||
{
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)pProcessData->ClientViewBase);
|
||||
}
|
||||
if (pProcessData->ClientViewBase)
|
||||
{
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)pProcessData->ClientViewBase);
|
||||
}
|
||||
|
||||
if (pProcessData->ClientPort)
|
||||
{
|
||||
NtClose(pProcessData->ClientPort);
|
||||
}
|
||||
if (pProcessData->ClientPort)
|
||||
{
|
||||
NtClose(pProcessData->ClientPort);
|
||||
}
|
||||
|
||||
*pPrevLink = pProcessData->next;
|
||||
CsrRemoveProcess(pProcessData);
|
||||
|
||||
RtlFreeHeap(CsrHeap, 0, pProcessData);
|
||||
UNLOCK;
|
||||
if (Process)
|
||||
{
|
||||
NtClose(Process);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
UNLOCK;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
CsrDeallocateProcess(pProcessData);
|
||||
|
||||
if (Process)
|
||||
{
|
||||
NtClose(Process);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
@@ -251,12 +488,7 @@ CSR_API(CsrSrvCreateThread)
|
||||
|
||||
CurrentThread = NtCurrentTeb()->CsrClientThread;
|
||||
CsrProcess = CurrentThread->Process;
|
||||
// DPRINT1("Current thread: %p %p\n", CurrentThread, CsrProcess);
|
||||
// DPRINT1("Request CID: %lx %lx %lx\n",
|
||||
// CsrProcess->ClientId.UniqueProcess,
|
||||
// NtCurrentTeb()->ClientId.UniqueProcess,
|
||||
// Request->Data.CreateThreadRequest.ClientId.UniqueProcess);
|
||||
|
||||
|
||||
if (CsrProcess->ClientId.UniqueProcess != Request->Data.CreateThreadRequest.ClientId.UniqueProcess)
|
||||
{
|
||||
if (Request->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
|
||||
@@ -266,15 +498,9 @@ CSR_API(CsrSrvCreateThread)
|
||||
|
||||
Status = CsrLockProcessByClientId(Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
|
||||
&CsrProcess);
|
||||
// DPRINT1("Found matching process: %p\n", CsrProcess);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
// DPRINT1("PIDs: %lx %lx\n", CurrentThread->Process->ClientId.UniqueProcess, CsrProcess->ClientId.UniqueProcess);
|
||||
// DPRINT1("Thread handle is: %lx Process Handle is: %lx %lx\n",
|
||||
// Request->Data.CreateThreadRequest.ThreadHandle,
|
||||
// CurrentThread->Process->ProcessHandle,
|
||||
// CsrProcess->Process);
|
||||
Status = NtDuplicateObject(CsrProcess->ProcessHandle,
|
||||
Request->Data.CreateThreadRequest.ThreadHandle,
|
||||
NtCurrentProcess(),
|
||||
@@ -282,7 +508,6 @@ CSR_API(CsrSrvCreateThread)
|
||||
0,
|
||||
0,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
//DPRINT1("Duplicate status: %lx\n", Status);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
|
||||
@@ -292,7 +517,6 @@ CSR_API(CsrSrvCreateThread)
|
||||
0,
|
||||
0,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
// DPRINT1("Duplicate status: %lx\n", Status);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS; // hack
|
||||
@@ -301,7 +525,6 @@ CSR_API(CsrSrvCreateThread)
|
||||
Status = CsrCreateThread(CsrProcess,
|
||||
ThreadHandle,
|
||||
&Request->Data.CreateThreadRequest.ClientId);
|
||||
// DPRINT1("Create status: %lx\n", Status);
|
||||
}
|
||||
|
||||
if (CsrProcess != CurrentThread->Process) CsrReleaseProcessLock();
|
||||
|
||||
@@ -1117,6 +1117,15 @@ CsrServerInitialization(IN ULONG ArgumentCount,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set up Process Support */
|
||||
Status = CsrInitializeProcessStructure();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
|
||||
__FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Parse the command line */
|
||||
Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
|
||||
if (!NT_SUCCESS(Status))
|
||||
@@ -1126,8 +1135,6 @@ CsrServerInitialization(IN ULONG ArgumentCount,
|
||||
return Status;
|
||||
}
|
||||
|
||||
CsrInitProcessData();
|
||||
|
||||
Status = CsrApiRegisterDefinitions(NativeDefinitions);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
extern RTL_CRITICAL_SECTION ProcessDataLock;
|
||||
extern PCSR_PROCESS ProcessData[256];
|
||||
PCSR_PROCESS CsrRootProcess;
|
||||
SECURITY_QUALITY_OF_SERVICE CsrSecurityQos =
|
||||
{
|
||||
@@ -225,63 +224,63 @@ PCSR_PROCESS
|
||||
NTAPI
|
||||
FindProcessForShutdown(IN PLUID CallerLuid)
|
||||
{
|
||||
ULONG Hash;
|
||||
PCSR_PROCESS CsrProcess, ReturnCsrProcess = NULL;
|
||||
NTSTATUS Status;
|
||||
ULONG Level = 0;
|
||||
LUID ProcessLuid;
|
||||
LUID SystemLuid = SYSTEM_LUID;
|
||||
BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
|
||||
PLIST_ENTRY NextEntry;
|
||||
|
||||
for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
|
||||
/* Set the List Pointers */
|
||||
NextEntry = CsrRootProcess->ListLink.Flink;
|
||||
while (NextEntry != &CsrRootProcess->ListLink)
|
||||
{
|
||||
/* 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 process */
|
||||
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
||||
|
||||
/* Move to the next entry */
|
||||
NextEntry = NextEntry->Flink;
|
||||
|
||||
/* Get the LUID of this Process */
|
||||
Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid);
|
||||
/* Skip this process if it's already been processed */
|
||||
if (CsrProcess->Flags & CsrProcessSkipShutdown) continue;
|
||||
|
||||
/* Get the LUID of this Process */
|
||||
Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &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;
|
||||
/* 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;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
/* Set the final process */
|
||||
ReturnCsrProcess = CsrProcess;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,28 +305,27 @@ CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc,
|
||||
PCSR_PROCESS CsrProcess = NULL;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
BOOLEAN FirstTry;
|
||||
PLIST_ENTRY NextEntry;
|
||||
ULONG Result = 0;
|
||||
ULONG Hash;
|
||||
|
||||
/* Acquire process lock */
|
||||
CsrAcquireProcessLock();
|
||||
|
||||
/* Start the loop */
|
||||
for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
|
||||
|
||||
/* Get the list pointers */
|
||||
NextEntry = CsrRootProcess->ListLink.Flink;
|
||||
while (NextEntry != &CsrRootProcess->ListLink)
|
||||
{
|
||||
/* Get the Process */
|
||||
CsrProcess = ProcessData[Hash];
|
||||
while (CsrProcess)
|
||||
{
|
||||
/* Remove the skip flag, set shutdown flags to 0*/
|
||||
CsrProcess->Flags &= ~CsrProcessSkipShutdown;
|
||||
CsrProcess->ShutdownFlags = 0;
|
||||
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
|
||||
|
||||
/* Move to the next */
|
||||
CsrProcess = CsrProcess->next;
|
||||
}
|
||||
/* Remove the skip flag, set shutdown flags to 0*/
|
||||
CsrProcess->Flags &= ~CsrProcessSkipShutdown;
|
||||
CsrProcess->ShutdownFlags = 0;
|
||||
|
||||
/* Move to the next */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
|
||||
/* Set shudown Priority */
|
||||
CsrSetToShutdownPriority();
|
||||
|
||||
@@ -388,48 +386,6 @@ Quickie:
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CsrLockProcessByClientId(IN HANDLE Pid,
|
||||
OUT PCSR_PROCESS *CsrProcess OPTIONAL)
|
||||
{
|
||||
ULONG Hash;
|
||||
PCSR_PROCESS 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->ClientId.UniqueProcess == 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 PCSR_PROCESS CsrProcess)
|
||||
|
||||
@@ -84,7 +84,6 @@ typedef struct _CSR_PROCESS
|
||||
ULONG ShutdownLevel;
|
||||
ULONG ShutdownFlags;
|
||||
// PVOID ServerData[ANYSIZE_ARRAY];
|
||||
struct _CSR_PROCESS* next;
|
||||
CSRSS_CON_PROCESS_DATA;
|
||||
} CSR_PROCESS, *PCSR_PROCESS;
|
||||
|
||||
@@ -154,7 +153,7 @@ extern HANDLE CsrSbApiPort;
|
||||
/* api/process.c */
|
||||
typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSR_PROCESS ProcessData,
|
||||
PVOID Context);
|
||||
VOID WINAPI CsrInitProcessData(VOID);
|
||||
NTSTATUS WINAPI CsrInitializeProcessStructure(VOID);
|
||||
PCSR_PROCESS WINAPI CsrGetProcessData(HANDLE ProcessId);
|
||||
PCSR_PROCESS WINAPI CsrCreateProcessData(HANDLE ProcessId);
|
||||
NTSTATUS WINAPI CsrFreeProcessData( HANDLE Pid );
|
||||
|
||||
Reference in New Issue
Block a user