mirror of
https://github.com/reactos/reactos.git
synced 2024-08-01 09:01:13 +00:00
[KERNEL32/CSRSS]: Register new Win32 threads with CSRSS. Add a bunch of lookup, creation, allocation, hashing and CSR thread management routines from the unused CSRSRV in trunk.
[CSRSS]: Bang in the new thread support in a bunch of places, including creating static server threads. It's very hacked and handle duplication doesn't work 100% reliably, but it gets the job done. [CSRSS]: Add CsrGetProcessLuid, CsrImpersonateClient, CsrRevertToSelf, CsrShutdownProcesses, CsrFindProcessForShutdown required for user-mode shutdown. Right now we are able to reliably enumerate user apps (in the user LUID) and then service/system apps (in the LOCAL SYSTEM LUID). svn path=/trunk/; revision=46042
This commit is contained in:
parent
e2d31e88e4
commit
4f05a88e82
|
@ -110,7 +110,38 @@ BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
|
||||||
return CsrRequest.Status;
|
return CsrRequest.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* REturn Success */
|
/* Return Success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WINAPI
|
||||||
|
BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
|
||||||
|
IN PCLIENT_ID ClientId)
|
||||||
|
{
|
||||||
|
ULONG Request = CREATE_THREAD;
|
||||||
|
CSR_API_MESSAGE CsrRequest;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("BasepNotifyCsrOfThread: Thread: %lx, Handle %lx\n",
|
||||||
|
ClientId->UniqueThread, ThreadHandle);
|
||||||
|
|
||||||
|
/* Fill out the request */
|
||||||
|
CsrRequest.Data.CreateThreadRequest.ClientId = *ClientId;
|
||||||
|
CsrRequest.Data.CreateThreadRequest.ThreadHandle = ThreadHandle;
|
||||||
|
|
||||||
|
/* Call CSR */
|
||||||
|
Status = CsrClientCallServer(&CsrRequest,
|
||||||
|
NULL,
|
||||||
|
MAKE_CSR_API(Request, CSR_NATIVE),
|
||||||
|
sizeof(CSR_API_MESSAGE));
|
||||||
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to tell csrss about new thread\n");
|
||||||
|
return CsrRequest.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return Success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +195,13 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = BasepNotifyCsrOfThread(hThread, ClientId);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Success */
|
/* Success */
|
||||||
return hThread;
|
return hThread;
|
||||||
}
|
}
|
||||||
|
@ -1375,6 +1412,18 @@ GetAppName:
|
||||||
&RemoteParameters->StandardError);
|
&RemoteParameters->StandardError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notify CSRSS */
|
||||||
|
Status = BasepNotifyCsrOfCreation(dwCreationFlags,
|
||||||
|
(HANDLE)ProcessBasicInfo.UniqueProcessId,
|
||||||
|
bInheritHandles);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CSR Notification Failed");
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the first thread */
|
/* Create the first thread */
|
||||||
DPRINT("Creating thread for process (EntryPoint = 0x%p)\n",
|
DPRINT("Creating thread for process (EntryPoint = 0x%p)\n",
|
||||||
SectionImageInfo.TransferAddress);
|
SectionImageInfo.TransferAddress);
|
||||||
|
@ -1390,18 +1439,6 @@ GetAppName:
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify CSRSS */
|
|
||||||
Status = BasepNotifyCsrOfCreation(dwCreationFlags,
|
|
||||||
(HANDLE)ProcessBasicInfo.UniqueProcessId,
|
|
||||||
bInheritHandles);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("CSR Notification Failed");
|
|
||||||
SetLastErrorByStatus(Status);
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(dwCreationFlags & CREATE_SUSPENDED))
|
if (!(dwCreationFlags & CREATE_SUSPENDED))
|
||||||
{
|
{
|
||||||
NtResumeThread(hThread, &Dummy);
|
NtResumeThread(hThread, &Dummy);
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
#define HIGH_PRIORITY 31
|
#define HIGH_PRIORITY 31
|
||||||
#define SXS_SUPPORT_FIXME
|
#define SXS_SUPPORT_FIXME
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WINAPI
|
||||||
|
BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
|
||||||
|
IN PCLIENT_ID ClientId);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
static
|
static
|
||||||
LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)
|
LONG BaseThreadExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)
|
||||||
|
@ -219,8 +224,13 @@ CreateRemoteThread(HANDLE hProcess,
|
||||||
DPRINT1("RtlAllocateActivationContextStack failed %x\n", Status);
|
DPRINT1("RtlAllocateActivationContextStack failed %x\n", Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Notify CSR */
|
/* Notify CSR */
|
||||||
|
Status = BasepNotifyCsrOfThread(hThread, &ClientId);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Success */
|
/* Success */
|
||||||
if(lpThreadId) *lpThreadId = (DWORD)ClientId.UniqueThread;
|
if(lpThreadId) *lpThreadId = (DWORD)ClientId.UniqueThread;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,12 @@ typedef struct
|
||||||
BOOL bInheritHandles;
|
BOOL bInheritHandles;
|
||||||
} CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS;
|
} CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
} CSRSS_CREATE_THREAD, *PCSRSS_CREATE_THREAD;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Dummy;
|
ULONG Dummy;
|
||||||
|
@ -544,6 +550,7 @@ typedef struct
|
||||||
#define GET_CONSOLE_ALIASES_EXES (0x3C)
|
#define GET_CONSOLE_ALIASES_EXES (0x3C)
|
||||||
#define GET_CONSOLE_ALIASES_EXES_LENGTH (0x3D)
|
#define GET_CONSOLE_ALIASES_EXES_LENGTH (0x3D)
|
||||||
#define GENERATE_CTRL_EVENT (0x3E)
|
#define GENERATE_CTRL_EVENT (0x3E)
|
||||||
|
#define CREATE_THREAD (0x3F)
|
||||||
|
|
||||||
/* Keep in sync with definition below. */
|
/* Keep in sync with definition below. */
|
||||||
#define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS))
|
#define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS))
|
||||||
|
@ -557,6 +564,7 @@ typedef struct _CSR_API_MESSAGE
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
CSRSS_CREATE_PROCESS CreateProcessRequest;
|
CSRSS_CREATE_PROCESS CreateProcessRequest;
|
||||||
|
CSRSS_CREATE_THREAD CreateThreadRequest;
|
||||||
CSRSS_CONNECT_PROCESS ConnectRequest;
|
CSRSS_CONNECT_PROCESS ConnectRequest;
|
||||||
CSRSS_WRITE_CONSOLE WriteConsoleRequest;
|
CSRSS_WRITE_CONSOLE WriteConsoleRequest;
|
||||||
CSRSS_READ_CONSOLE ReadConsoleRequest;
|
CSRSS_READ_CONSOLE ReadConsoleRequest;
|
||||||
|
|
|
@ -24,11 +24,241 @@ RTL_CRITICAL_SECTION ProcessDataLock;
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
||||||
|
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;
|
||||||
RtlZeroMemory (ProcessData, sizeof ProcessData);
|
RtlZeroMemory (ProcessData, sizeof ProcessData);
|
||||||
NrProcess = sizeof ProcessData / sizeof ProcessData[0];
|
NrProcess = sizeof ProcessData / sizeof ProcessData[0];
|
||||||
RtlInitializeCriticalSection( &ProcessDataLock );
|
RtlInitializeCriticalSection( &ProcessDataLock );
|
||||||
|
|
||||||
|
CsrRootProcess = CsrCreateProcessData(NtCurrentTeb()->ClientId.UniqueProcess);
|
||||||
|
|
||||||
|
/* Initialize the Thread Hash List */
|
||||||
|
for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCSRSS_PROCESS_DATA WINAPI CsrGetProcessData(HANDLE ProcessId)
|
PCSRSS_PROCESS_DATA WINAPI CsrGetProcessData(HANDLE ProcessId)
|
||||||
|
@ -89,8 +319,7 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId)
|
||||||
|
|
||||||
/* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
|
/* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
|
||||||
Status = NtOpenProcess(&pProcessData->Process,
|
Status = NtOpenProcess(&pProcessData->Process,
|
||||||
PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION |
|
PROCESS_ALL_ACCESS,
|
||||||
PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | SYNCHRONIZE,
|
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&ClientId);
|
&ClientId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -122,6 +351,9 @@ PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId)
|
||||||
pProcessData->ShutdownLevel = 0x280;
|
pProcessData->ShutdownLevel = 0x280;
|
||||||
pProcessData->ShutdownFlags = 0;
|
pProcessData->ShutdownFlags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pProcessData->ThreadCount = 0;
|
||||||
|
InitializeListHead(&pProcessData->ThreadList);
|
||||||
return pProcessData;
|
return pProcessData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,33 +418,406 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS WINAPI
|
VOID
|
||||||
CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context)
|
NTAPI
|
||||||
|
CsrSetToNormalPriority(VOID)
|
||||||
{
|
{
|
||||||
UINT Hash;
|
KPRIORITY BasePriority = (8 + 1) + 4;
|
||||||
PCSRSS_PROCESS_DATA pProcessData;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
LOCK;
|
/* Set the Priority */
|
||||||
|
NtSetInformationProcess(NtCurrentProcess(),
|
||||||
|
ProcessBasePriority,
|
||||||
|
&BasePriority,
|
||||||
|
sizeof(KPRIORITY));
|
||||||
|
}
|
||||||
|
|
||||||
for (Hash = 0; Hash < (sizeof(ProcessData) / sizeof(*ProcessData)); Hash++)
|
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)))
|
||||||
{
|
{
|
||||||
pProcessData = ProcessData[Hash];
|
/* Set the Priority */
|
||||||
while (NULL != pProcessData)
|
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))
|
||||||
{
|
{
|
||||||
Status = EnumProc(pProcessData, Context);
|
/* If we got some other failure, then return and quit */
|
||||||
if (STATUS_SUCCESS != Status)
|
if (Status != STATUS_NO_TOKEN) return Status;
|
||||||
{
|
|
||||||
UNLOCK;
|
/* We don't have a Thread Token, use a Process Token */
|
||||||
return Status;
|
hProcess = NtCurrentProcess();
|
||||||
}
|
hToken = NULL;
|
||||||
pProcessData = pProcessData->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK;
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 = TRUE;
|
||||||
|
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 */
|
||||||
|
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, Context);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
@ -255,6 +860,76 @@ CSR_API(CsrCreateProcess)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSR_API(CsrCreateThread)
|
||||||
|
{
|
||||||
|
PCSR_THREAD CurrentThread;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCSRSS_PROCESS_DATA CsrProcess;
|
||||||
|
|
||||||
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
||||||
|
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
|
||||||
|
|
||||||
|
CurrentThread = NtCurrentTeb()->CsrClientThread;
|
||||||
|
CsrProcess = CurrentThread->Process;
|
||||||
|
// DPRINT1("Current thread: %p %p\n", CurrentThread, CsrProcess);
|
||||||
|
// DPRINT1("Request CID: %lx %lx %lx\n",
|
||||||
|
// CsrProcess->ProcessId,
|
||||||
|
// NtCurrentTeb()->ClientId.UniqueProcess,
|
||||||
|
// Request->Data.CreateThreadRequest.ClientId.UniqueProcess);
|
||||||
|
|
||||||
|
if (CsrProcess->ProcessId != Request->Data.CreateThreadRequest.ClientId.UniqueProcess)
|
||||||
|
{
|
||||||
|
if (Request->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
|
||||||
|
{
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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->ProcessId, CsrProcess->ProcessId);
|
||||||
|
// DPRINT1("Thread handle is: %lx Process Handle is: %lx %lx\n",
|
||||||
|
// Request->Data.CreateThreadRequest.ThreadHandle,
|
||||||
|
// CurrentThread->Process->Process,
|
||||||
|
// CsrProcess->Process);
|
||||||
|
Status = NtDuplicateObject(CsrProcess->Process,
|
||||||
|
Request->Data.CreateThreadRequest.ThreadHandle,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&ThreadHandle,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
//DPRINT1("Duplicate status: %lx\n", Status);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = NtDuplicateObject(CurrentThread->Process->Process,
|
||||||
|
Request->Data.CreateThreadRequest.ThreadHandle,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&ThreadHandle,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
// DPRINT1("Duplicate status: %lx\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS; // hack
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = CsrCreateThreadData(CsrProcess,
|
||||||
|
ThreadHandle,
|
||||||
|
&Request->Data.CreateThreadRequest.ClientId);
|
||||||
|
// DPRINT1("Create status: %lx\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CsrProcess != CurrentThread->Process) CsrReleaseProcessLock();
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
CSR_API(CsrTerminateProcess)
|
CSR_API(CsrTerminateProcess)
|
||||||
{
|
{
|
||||||
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
|
||||||
|
|
|
@ -126,6 +126,7 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
|
||||||
HANDLE ServerPort = NULL, ServerThread = NULL;
|
HANDLE ServerPort = NULL, ServerThread = NULL;
|
||||||
PCSRSS_PROCESS_DATA ProcessData = NULL;
|
PCSRSS_PROCESS_DATA ProcessData = NULL;
|
||||||
REMOTE_PORT_VIEW LpcRead;
|
REMOTE_PORT_VIEW LpcRead;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
LpcRead.Length = sizeof(LpcRead);
|
LpcRead.Length = sizeof(LpcRead);
|
||||||
ServerPort = NULL;
|
ServerPort = NULL;
|
||||||
|
|
||||||
|
@ -169,19 +170,23 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
|
||||||
|
|
||||||
Status = RtlCreateUserThread(NtCurrentProcess(),
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
||||||
NULL,
|
NULL,
|
||||||
FALSE,
|
TRUE,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PTHREAD_START_ROUTINE)ClientConnectionThread,
|
(PTHREAD_START_ROUTINE)ClientConnectionThread,
|
||||||
ServerPort,
|
ServerPort,
|
||||||
& ServerThread,
|
& ServerThread,
|
||||||
NULL);
|
&ClientId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("CSR: Unable to create server thread\n");
|
DPRINT1("CSR: Unable to create server thread\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CsrAddStaticServerThread(ServerThread, &ClientId, 0);
|
||||||
|
|
||||||
|
NtResumeThread(ServerThread, NULL);
|
||||||
|
|
||||||
NtClose(ServerThread);
|
NtClose(ServerThread);
|
||||||
|
|
||||||
|
@ -190,6 +195,53 @@ CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCSR_THREAD
|
||||||
|
NTAPI
|
||||||
|
CsrConnectToUser(VOID)
|
||||||
|
{
|
||||||
|
PTEB Teb = NtCurrentTeb();
|
||||||
|
PCSR_THREAD CsrThread;
|
||||||
|
#if 0
|
||||||
|
NTSTATUS Status;
|
||||||
|
ANSI_STRING DllName;
|
||||||
|
UNICODE_STRING TempName;
|
||||||
|
HANDLE hUser32;
|
||||||
|
STRING StartupName;
|
||||||
|
|
||||||
|
/* Check if we didn't already find it */
|
||||||
|
if (!CsrClientThreadSetup)
|
||||||
|
{
|
||||||
|
/* Get the DLL Handle for user32.dll */
|
||||||
|
RtlInitAnsiString(&DllName, "user32");
|
||||||
|
RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
|
||||||
|
Status = LdrGetDllHandle(NULL,
|
||||||
|
NULL,
|
||||||
|
&TempName,
|
||||||
|
&hUser32);
|
||||||
|
RtlFreeUnicodeString(&TempName);
|
||||||
|
|
||||||
|
/* If we got teh handle, get the Client Thread Startup Entrypoint */
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlInitAnsiString(&StartupName,"ClientThreadSetup");
|
||||||
|
Status = LdrGetProcedureAddress(hUser32,
|
||||||
|
&StartupName,
|
||||||
|
0,
|
||||||
|
(PVOID)&CsrClientThreadSetup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to user32 */
|
||||||
|
CsrClientThreadSetup();
|
||||||
|
#endif
|
||||||
|
/* Save pointer to this thread in TEB */
|
||||||
|
CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
|
||||||
|
if (CsrThread) Teb->CsrClientThread = CsrThread;
|
||||||
|
|
||||||
|
/* Return it */
|
||||||
|
return CsrThread;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
WINAPI
|
WINAPI
|
||||||
ClientConnectionThread(HANDLE ServerPort)
|
ClientConnectionThread(HANDLE ServerPort)
|
||||||
|
@ -199,10 +251,20 @@ ClientConnectionThread(HANDLE ServerPort)
|
||||||
PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
|
PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
|
||||||
PCSR_API_MESSAGE Reply;
|
PCSR_API_MESSAGE Reply;
|
||||||
PCSRSS_PROCESS_DATA ProcessData;
|
PCSRSS_PROCESS_DATA ProcessData;
|
||||||
|
PCSR_THREAD ServerThread;
|
||||||
|
|
||||||
DPRINT("CSR: %s called\n", __FUNCTION__);
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
/* Connect to user32 */
|
||||||
|
while (!CsrConnectToUser())
|
||||||
|
{
|
||||||
|
/* Keep trying until we get a response */
|
||||||
|
NtCurrentTeb()->Win32ClientInfo[0] = 0;
|
||||||
|
//NtDelayExecution(FALSE, &TimeOut);
|
||||||
|
}
|
||||||
|
|
||||||
/* Reply must be NULL at the first call to NtReplyWaitReceivePort */
|
/* Reply must be NULL at the first call to NtReplyWaitReceivePort */
|
||||||
|
ServerThread = NtCurrentTeb()->CsrClientThread;
|
||||||
Reply = NULL;
|
Reply = NULL;
|
||||||
|
|
||||||
/* Loop and reply/wait for a new message */
|
/* Loop and reply/wait for a new message */
|
||||||
|
@ -271,7 +333,7 @@ ClientConnectionThread(HANDLE ServerPort)
|
||||||
}
|
}
|
||||||
if (ProcessData->Terminated)
|
if (ProcessData->Terminated)
|
||||||
{
|
{
|
||||||
DPRINT1("Message %d: process %p already terminated\n",
|
DPRINT1("Message %d: process %d already terminated\n",
|
||||||
Request->Type, Request->Header.ClientId.UniqueProcess);
|
Request->Type, Request->Header.ClientId.UniqueProcess);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -284,8 +346,17 @@ ClientConnectionThread(HANDLE ServerPort)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
PCSR_THREAD Thread;
|
||||||
|
PCSRSS_PROCESS_DATA Process = NULL;
|
||||||
|
|
||||||
|
//DPRINT1("locate thread %lx/%lx\n", Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread);
|
||||||
|
Thread = CsrLocateThreadByClientId(&Process, &Request->Header.ClientId);
|
||||||
|
//DPRINT1("Thread found: %p %p\n", Thread, Process);
|
||||||
|
|
||||||
/* Call the Handler */
|
/* Call the Handler */
|
||||||
|
if (Thread) NtCurrentTeb()->CsrClientThread = Thread;
|
||||||
CsrApiCallHandler(ProcessData, Request);
|
CsrApiCallHandler(ProcessData, Request);
|
||||||
|
if (Thread) NtCurrentTeb()->CsrClientThread = ServerThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send back the reply */
|
/* Send back the reply */
|
||||||
|
|
|
@ -13,6 +13,29 @@
|
||||||
|
|
||||||
#include <csrss/csrss.h>
|
#include <csrss/csrss.h>
|
||||||
|
|
||||||
|
typedef enum _SHUTDOWN_RESULT
|
||||||
|
{
|
||||||
|
CsrShutdownCsrProcess = 1,
|
||||||
|
CsrShutdownNonCsrProcess,
|
||||||
|
CsrShutdownCancelled
|
||||||
|
} SHUTDOWN_RESULT, *PSHUTDOWN_RESULT;
|
||||||
|
|
||||||
|
typedef enum _CSR_SHUTDOWN_FLAGS
|
||||||
|
{
|
||||||
|
CsrShutdownSystem = 4,
|
||||||
|
CsrShutdownOther = 8
|
||||||
|
} CSR_SHUTDOWN_FLAGS, *PCSR_SHUTDOWN_FLAGS;
|
||||||
|
|
||||||
|
typedef enum _CSR_PROCESS_FLAGS
|
||||||
|
{
|
||||||
|
CsrProcessTerminating = 0x1,
|
||||||
|
CsrProcessSkipShutdown = 0x2,
|
||||||
|
CsrProcessCreateNewGroup = 0x100,
|
||||||
|
CsrProcessTerminated = 0x200,
|
||||||
|
CsrProcessLastThreadTerminated = 0x400,
|
||||||
|
CsrProcessIsConsoleApp = 0x800
|
||||||
|
} CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS;
|
||||||
|
|
||||||
typedef struct Object_tt
|
typedef struct Object_tt
|
||||||
{
|
{
|
||||||
LONG Type;
|
LONG Type;
|
||||||
|
@ -59,8 +82,25 @@ typedef struct _CSRSS_PROCESS_DATA
|
||||||
LIST_ENTRY ProcessEntry;
|
LIST_ENTRY ProcessEntry;
|
||||||
PCONTROLDISPATCHER CtrlDispatcher;
|
PCONTROLDISPATCHER CtrlDispatcher;
|
||||||
BOOL Terminated;
|
BOOL Terminated;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG ThreadCount;
|
||||||
|
LIST_ENTRY ThreadList;
|
||||||
} CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA;
|
} CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA;
|
||||||
|
|
||||||
|
typedef struct _CSR_THREAD
|
||||||
|
{
|
||||||
|
LARGE_INTEGER CreateTime;
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
LIST_ENTRY HashLinks;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
PCSRSS_PROCESS_DATA Process;
|
||||||
|
//struct _CSR_WAIT_BLOCK *WaitBlock;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
ULONG ImpersonationCount;
|
||||||
|
} CSR_THREAD, *PCSR_THREAD;
|
||||||
|
|
||||||
typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object);
|
typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object);
|
||||||
|
|
||||||
typedef struct tagCSRSS_OBJECT_DEFINITION
|
typedef struct tagCSRSS_OBJECT_DEFINITION
|
||||||
|
@ -100,6 +140,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);
|
||||||
|
|
||||||
/* print.c */
|
/* print.c */
|
||||||
VOID WINAPI DisplayString(LPCWSTR lpwString);
|
VOID WINAPI DisplayString(LPCWSTR lpwString);
|
||||||
|
@ -129,7 +170,10 @@ PCSRSS_PROCESS_DATA WINAPI CsrGetProcessData(HANDLE ProcessId);
|
||||||
PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId);
|
PCSRSS_PROCESS_DATA WINAPI CsrCreateProcessData(HANDLE ProcessId);
|
||||||
NTSTATUS WINAPI CsrFreeProcessData( HANDLE Pid );
|
NTSTATUS WINAPI CsrFreeProcessData( HANDLE Pid );
|
||||||
NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context);
|
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);
|
||||||
|
|
||||||
/* api/handle.c */
|
/* api/handle.c */
|
||||||
NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
|
NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
|
||||||
NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable );
|
NTSTATUS WINAPI CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable );
|
||||||
|
|
|
@ -283,6 +283,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(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),
|
||||||
|
@ -305,6 +306,8 @@ CsrpCreateListenPort (IN LPWSTR Name,
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
OBJECT_ATTRIBUTES PortAttributes;
|
OBJECT_ATTRIBUTES PortAttributes;
|
||||||
UNICODE_STRING PortName;
|
UNICODE_STRING PortName;
|
||||||
|
HANDLE ServerThread;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
|
||||||
DPRINT("CSR: %s called\n", __FUNCTION__);
|
DPRINT("CSR: %s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
@ -327,14 +330,22 @@ CsrpCreateListenPort (IN LPWSTR Name,
|
||||||
}
|
}
|
||||||
Status = RtlCreateUserThread(NtCurrentProcess(),
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
||||||
NULL,
|
NULL,
|
||||||
FALSE,
|
TRUE,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PTHREAD_START_ROUTINE) ListenThread,
|
(PTHREAD_START_ROUTINE) ListenThread,
|
||||||
*Port,
|
*Port,
|
||||||
NULL,
|
&ServerThread,
|
||||||
NULL);
|
&ClientId);
|
||||||
|
|
||||||
|
if (ListenThread == (PVOID)ClientConnectionThread)
|
||||||
|
{
|
||||||
|
CsrAddStaticServerThread(ServerThread, &ClientId, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtResumeThread(ServerThread, NULL);
|
||||||
|
NtClose(ServerThread);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue