From 2a5d344d962c351bf4b4995bc7e895162c4f97e7 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 19 Feb 2012 11:39:07 +0000 Subject: [PATCH] [CSRSRV/KERNEL32]: Do the Windows thing and send a unified LPC message when a new process is created, which includes the thread information as well, instead of sending two LPC messages per process. Perf++. [CSRSRV/kERNEL32]: Switch to using the Windows CSRSS message structure for a new process, minus the bInheritHandles field which we still support for ReactOS compatibility. [CSRSRV]: Port CsrCreateProcess from CSRSRV2, rewrite CsrSrvCreateProcess to use this API, and add required ReactOS compatibility hacks. A lot of stuff is still not supported, but the minimum (ie: previous ReactOS functionality) has been maintained during the transition. Processes are now tracked correctly, but there are still refcount leaks (known, to be fixed later). Will let this breathe for a bit now to catch regressions. Work can now continue back on the kernel32 side while that happens. svn path=/trunk/; revision=55711 --- reactos/dll/win32/kernel32/client/proc.c | 77 ++----- reactos/include/reactos/subsys/csrss/csrss.h | 2 - .../win32/csrss/csrsrv/api/process.c | 174 ++++++++------ reactos/subsystems/win32/csrss/csrsrv/init.c | 2 +- .../subsystems/win32/csrss/csrsrv/procsup.c | 213 ++++++++++++++++++ reactos/subsystems/win32/csrss/include/api.h | 30 ++- 6 files changed, 367 insertions(+), 131 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/proc.c b/reactos/dll/win32/kernel32/client/proc.c index 9bc61f5bf63..d9e2b7a1bb2 100644 --- a/reactos/dll/win32/kernel32/client/proc.c +++ b/reactos/dll/win32/kernel32/client/proc.c @@ -485,42 +485,6 @@ BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress) ExitProcess(uExitCode); } -/* - * Tells CSR that a new process was created - */ -NTSTATUS -WINAPI -BasepNotifyCsrOfCreation(ULONG dwCreationFlags, - IN HANDLE ProcessId, - IN BOOL InheritHandles) -{ - ULONG Request = CREATE_PROCESS; - CSR_API_MESSAGE CsrRequest; - NTSTATUS Status; - - DPRINT("BasepNotifyCsrOfCreation: Process: %lx, Flags %lx\n", - ProcessId, dwCreationFlags); - - /* Fill out the request */ - CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessId; - CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags; - CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles; - - /* 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 process: %lx %lx\n", Status, CsrRequest.Status); - return CsrRequest.Status; - } - - /* Return Success */ - return STATUS_SUCCESS; -} - NTSTATUS WINAPI BasepNotifyCsrOfThread(IN HANDLE ThreadHandle, @@ -560,7 +524,9 @@ WINAPI BasepCreateFirstThread(HANDLE ProcessHandle, LPSECURITY_ATTRIBUTES lpThreadAttributes, PSECTION_IMAGE_INFORMATION SectionImageInfo, - PCLIENT_ID ClientId) + PCLIENT_ID ClientId, + BOOLEAN InheritHandles, + DWORD dwCreationFlags) { OBJECT_ATTRIBUTES LocalObjectAttributes; POBJECT_ATTRIBUTES ObjectAttributes; @@ -568,7 +534,8 @@ BasepCreateFirstThread(HANDLE ProcessHandle, INITIAL_TEB InitialTeb; NTSTATUS Status; HANDLE hThread; - + ULONG Request = CREATE_PROCESS; + CSR_API_MESSAGE CsrRequest; DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle); /* Create the Thread's Stack */ @@ -603,10 +570,22 @@ BasepCreateFirstThread(HANDLE ProcessHandle, return NULL; } - Status = BasepNotifyCsrOfThread(hThread, ClientId); - if (!NT_SUCCESS(Status)) + /* Fill out the request to notify CSRSS */ + CsrRequest.Data.CreateProcessRequest.ClientId = *ClientId; + CsrRequest.Data.CreateProcessRequest.ProcessHandle = ProcessHandle; + CsrRequest.Data.CreateProcessRequest.ThreadHandle = hThread; + CsrRequest.Data.CreateProcessRequest.CreationFlags = dwCreationFlags; + CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles; + + /* Call CSR */ + Status = CsrClientCallServer(&CsrRequest, + NULL, + MAKE_CSR_API(Request, CSR_NATIVE), + sizeof(CSR_API_MESSAGE)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status)) { - ASSERT(FALSE); + DPRINT1("Failed to tell csrss about new process: %lx %lx\n", Status, CsrRequest.Status); + return NULL; } /* Success */ @@ -3240,25 +3219,15 @@ GetAppName: &RemoteParameters->StandardError); } - /* Notify CSRSS */ - Status = BasepNotifyCsrOfCreation(dwCreationFlags, - (HANDLE)ProcessBasicInfo.UniqueProcessId, - bInheritHandles); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSR Notification Failed\n"); - BaseSetLastNTError(Status); - goto Cleanup; - } - /* Create the first thread */ DPRINT("Creating thread for process (EntryPoint = 0x%p)\n", SectionImageInfo.TransferAddress); hThread = BasepCreateFirstThread(hProcess, lpThreadAttributes, &SectionImageInfo, - &ClientId); + &ClientId, + bInheritHandles, + dwCreationFlags); if (hThread == NULL) { diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 360655f161e..f50e15f334a 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -69,8 +69,6 @@ typedef struct // // ReactOS Data // - HANDLE NewProcessId; - ULONG Flags; BOOL bInheritHandles; } CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS; diff --git a/reactos/subsystems/win32/csrss/csrsrv/api/process.c b/reactos/subsystems/win32/csrss/csrsrv/api/process.c index 3e9f8de5b6c..d2a44b3f921 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/api/process.c +++ b/reactos/subsystems/win32/csrss/csrsrv/api/process.c @@ -31,58 +31,6 @@ PCSR_PROCESS WINAPI CsrGetProcessData(HANDLE ProcessId) return CsrProcess; } -PCSR_PROCESS WINAPI CsrCreateProcessData(HANDLE ProcessId) -{ - PCSR_PROCESS pProcessData; - OBJECT_ATTRIBUTES ObjectAttributes; - CLIENT_ID ClientId; - NTSTATUS Status; - - LOCK; - - 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) { PCSR_PROCESS pProcessData; @@ -135,34 +83,114 @@ NTSTATUS WINAPI CsrFreeProcessData(HANDLE Pid) * CSRSS API *********************************************************************/ -CSR_API(CsrCreateProcess) +CSR_API(CsrSrvCreateProcess) { - PCSR_PROCESS NewProcessData; + NTSTATUS Status; + HANDLE ProcessHandle, ThreadHandle; + PCSR_THREAD CsrThread; + PCSR_PROCESS NewProcessData; + ULONG Flags, VdmPower = 0, DebugFlags = 0; - NewProcessData = CsrCreateProcessData(Request->Data.CreateProcessRequest.NewProcessId); - if (NewProcessData == NULL) + /* Get the current client thread */ + CsrThread = NtCurrentTeb()->CsrClientThread; + ASSERT(CsrThread != NULL); + + /* Extract the flags out of the process handle */ + Flags = (ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & 3; + Request->Data.CreateProcessRequest.ProcessHandle = (HANDLE)((ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & ~3); + + /* Duplicate the process handle */ + Status = NtDuplicateObject(CsrThread->Process->ProcessHandle, + Request->Data.CreateProcessRequest.ProcessHandle, + NtCurrentProcess(), + &ProcessHandle, + 0, + 0, + DUPLICATE_SAME_ACCESS); + if (!NT_SUCCESS(Status)) { - return(STATUS_NO_MEMORY); + DPRINT1("Failed to duplicate process handle\n"); + return Status; } - if (!(Request->Data.CreateProcessRequest.Flags & (CREATE_NEW_CONSOLE|DETACHED_PROCESS))) - { - NewProcessData->ParentConsole = ProcessData->Console; - NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles; - } - - CallProcessCreated(ProcessData, NewProcessData); + /* Duplicate the thread handle */ + Status = NtDuplicateObject(CsrThread->Process->ProcessHandle, + Request->Data.CreateProcessRequest.ThreadHandle, + NtCurrentProcess(), + &ThreadHandle, + 0, + 0, + DUPLICATE_SAME_ACCESS); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to duplicate process handle\n"); + NtClose(ProcessHandle); + return Status; + } - if (Request->Data.CreateProcessRequest.Flags & CREATE_NEW_PROCESS_GROUP) - { - NewProcessData->ProcessGroupId = (DWORD)(ULONG_PTR)NewProcessData->ClientId.UniqueProcess; - } - else - { - NewProcessData->ProcessGroupId = ProcessData->ProcessGroupId; - } + /* See if this is a VDM process */ + if (VdmPower) + { + /* Request VDM powers */ + Status = NtSetInformationProcess(ProcessHandle, + ProcessWx86Information, + &VdmPower, + sizeof(VdmPower)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get VDM powers\n"); + NtClose(ProcessHandle); + NtClose(ThreadHandle); + return Status; + } + } + + /* Convert some flags. FIXME: More need conversion */ + if (Request->Data.CreateProcessRequest.CreationFlags & CREATE_NEW_PROCESS_GROUP) + { + DebugFlags |= CsrProcessCreateNewGroup; + } - return(STATUS_SUCCESS); + /* FIXME: SxS Stuff */ + + /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */ + Status = CsrCreateProcess(ProcessHandle, + ThreadHandle, + &Request->Data.CreateProcessRequest.ClientId, + CsrThread->Process->NtSession, + DebugFlags, + NULL); + if (Status == STATUS_THREAD_IS_TERMINATING) + { + DPRINT1("Thread already dead\n"); + return Status; + } + + /* Check for other failures */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create process/thread structures: %lx\n", Status); + return Status; + } + + /* FIXME: Should notify user32 */ + + /* FIXME: VDM vodoo */ + + /* ReactOS Compatibility */ + Status = CsrLockProcessByClientId(Request->Data.CreateProcessRequest.ClientId.UniqueProcess, &NewProcessData); + ASSERT(Status == STATUS_SUCCESS); + if (!(Request->Data.CreateProcessRequest.CreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS))) + { + NewProcessData->ParentConsole = ProcessData->Console; + NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles; + } + RtlInitializeCriticalSection(&NewProcessData->HandleTableLock); + CallProcessCreated(ProcessData, NewProcessData); + CsrUnlockProcess(NewProcessData); + + /* Return the result of this operation */ + return Status; } CSR_API(CsrSrvCreateThread) diff --git a/reactos/subsystems/win32/csrss/csrsrv/init.c b/reactos/subsystems/win32/csrss/csrsrv/init.c index 4ec70eab6a1..f1bee12084b 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/init.c +++ b/reactos/subsystems/win32/csrss/csrsrv/init.c @@ -86,7 +86,7 @@ CallProcessCreated(IN PCSR_PROCESS SourceProcessData, CSRSS_API_DEFINITION NativeDefinitions[] = { - CSRSS_DEFINE_API(CREATE_PROCESS, CsrCreateProcess), + CSRSS_DEFINE_API(CREATE_PROCESS, CsrSrvCreateProcess), CSRSS_DEFINE_API(CREATE_THREAD, CsrSrvCreateThread), CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess), CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess), diff --git a/reactos/subsystems/win32/csrss/csrsrv/procsup.c b/reactos/subsystems/win32/csrss/csrsrv/procsup.c index f50dd928792..2a3b23ad0d1 100644 --- a/reactos/subsystems/win32/csrss/csrsrv/procsup.c +++ b/reactos/subsystems/win32/csrss/csrsrv/procsup.c @@ -497,6 +497,219 @@ CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess) } } +/*++ + * @name CsrCreateProcess + * @implemented NT4 + * + * Do nothing for 500ms. + * + * @param ArgumentCount + * Description of the parameter. Wrapped to more lines on ~70th + * column. + * + * @param Arguments + * Description of the parameter. Wrapped to more lines on ~70th + * column. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * othwerwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrCreateProcess(IN HANDLE hProcess, + IN HANDLE hThread, + IN PCLIENT_ID ClientId, + IN PCSR_NT_SESSION NtSession, + IN ULONG Flags, + IN PCLIENT_ID DebugCid) +{ + PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; + CLIENT_ID CurrentCid; + PCSR_PROCESS CurrentProcess; +// PVOID ProcessData; +// ULONG i; + PCSR_PROCESS CsrProcess; + NTSTATUS Status; + PCSR_THREAD CsrThread; + KERNEL_USER_TIMES KernelTimes; + + /* Get the current CID and lock Processes */ + CurrentCid = CurrentThread->ClientId; + CsrAcquireProcessLock(); + + /* Get the current CSR Thread */ + CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); + if (!CurrentThread) + { + /* We've failed to locate the thread */ + CsrReleaseProcessLock(); + return STATUS_THREAD_IS_TERMINATING; + } + + /* Allocate a new Process Object */ + CsrProcess = CsrAllocateProcess(); + if (!CsrProcess) + { + /* Couldn't allocate Process */ + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + +#if 0 + /* Inherit the Process Data */ + CurrentProcess = CurrentThread->Process; + ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX]; + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + { + /* Check if the DLL is Loaded and has Per Process Data */ + if ((CsrLoadedServerDll[i]) && (CsrLoadedServerDll[i]->SizeOfProcessData)) + { + /* Set the pointer */ + CsrProcess->ServerData[i] = ProcessData; + + /* Copy the Data */ + RtlMoveMemory(ProcessData, + CurrentProcess->ServerData[i], + CsrLoadedServerDll[i]->SizeOfProcessData); + + /* Update next data pointer */ + ProcessData = (PVOID)((ULONG_PTR)ProcessData + + CsrLoadedServerDll[i]->SizeOfProcessData); + } + else + { + /* No data for this Server */ + CsrProcess->ServerData[i] = NULL; + } + } +#endif + + /* Set the Exception port to us */ + Status = NtSetInformationProcess(hProcess, + ProcessExceptionPort, + &CsrApiPort, + sizeof(HANDLE)); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + CsrDeallocateProcess(CsrProcess); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */ + if (!(Flags & CsrProcessCreateNewGroup)) + { + /* Create new data */ + CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess); + CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber; + } + else + { + /* Copy it from the current process */ + CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId; + CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence; + } + + /* Check if this is a console process */ + if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp; + + /* Mask out non-debug flags */ + Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags); + + /* Check if every process will be debugged */ + if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren)) + { + /* Pass it on to the current process */ + CsrProcess->DebugFlags = CsrDebugProcessChildren; + CsrProcess->DebugCid = CurrentProcess->DebugCid; + } + + /* Check if Debugging was used on this process */ + if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid)) + { + /* Save the debug flag used */ + CsrProcess->DebugFlags = Flags; + + /* Save the CID */ + CsrProcess->DebugCid = *DebugCid; + } + + /* Check if we debugging is enabled */ + if (CsrProcess->DebugFlags) + { + /* Set the Debug Port to us */ + Status = NtSetInformationProcess(hProcess, + ProcessDebugPort, + &CsrApiPort, + sizeof(HANDLE)); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + CsrDeallocateProcess(CsrProcess); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + } + + /* Get the Thread Create Time */ + Status = NtQueryInformationThread(hThread, + ThreadTimes, + (PVOID)&KernelTimes, + sizeof(KernelTimes), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + CsrDeallocateProcess(CsrProcess); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* Allocate a CSR Thread Structure */ + CsrThread = CsrAllocateThread(CsrProcess); + if (!CsrThread) + { + /* Failed */ + CsrDeallocateProcess(CsrProcess); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* Save the data we have */ + CsrThread->CreateTime = KernelTimes.CreateTime; + CsrThread->ClientId = *ClientId; + CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); + CsrThread->Flags = 0; + + /* Insert the Thread into the Process */ + CsrInsertThread(CsrProcess, CsrThread); + + /* Reference the session */ + CsrReferenceNtSession(NtSession); + CsrProcess->NtSession = NtSession; + + /* Setup Process Data */ + CsrProcess->ClientId = *ClientId; + CsrProcess->ProcessHandle = hProcess; + CsrProcess->ShutdownLevel = 0x280; + + /* Set the Priority to Background */ + CsrSetBackgroundPriority(CsrProcess); + + /* Insert the Process */ + CsrInsertProcess(NULL, CurrentProcess, CsrProcess); + + /* Release lock and return */ + CsrReleaseProcessLock(); + return Status; +} + /*++ * @name CsrUnlockProcess * @implemented NT4 diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 7d1322201f2..f8beb873848 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -56,16 +56,31 @@ typedef enum _CSR_SHUTDOWN_FLAGS CsrShutdownOther = 8 } CSR_SHUTDOWN_FLAGS, *PCSR_SHUTDOWN_FLAGS; +typedef enum _CSR_DEBUG_FLAGS +{ + CsrDebugOnlyThisProcess = 1, + CsrDebugProcessChildren = 2 +} CSR_PROCESS_DEBUG_FLAGS, *PCSR_PROCESS_DEBUG_FLAGS; + typedef enum _CSR_PROCESS_FLAGS { CsrProcessTerminating = 0x1, CsrProcessSkipShutdown = 0x2, + CsrProcessNormalPriority = 0x10, + CsrProcessIdlePriority = 0x20, + CsrProcessHighPriority = 0x40, + CsrProcessRealtimePriority = 0x80, CsrProcessCreateNewGroup = 0x100, CsrProcessTerminated = 0x200, CsrProcessLastThreadTerminated = 0x400, CsrProcessIsConsoleApp = 0x800 } CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS; +#define CsrProcessPriorityFlags (CsrProcessNormalPriority | \ + CsrProcessIdlePriority | \ + CsrProcessHighPriority | \ + CsrProcessRealtimePriority) + typedef struct _CSRSS_CON_PROCESS_DATA { HANDLE ConsoleEvent; @@ -251,7 +266,7 @@ NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]); /* api/process.c */ CSR_API(CsrConnectProcess); -CSR_API(CsrCreateProcess); +CSR_API(CsrSrvCreateProcess); CSR_API(CsrTerminateProcess); CSR_API(CsrSrvCreateThread); CSR_API(CsrGetShutdownParameters); @@ -319,6 +334,15 @@ NTSTATUS NTAPI CsrApiPortInitialize(VOID); +NTSTATUS +NTAPI +CsrCreateProcess(IN HANDLE hProcess, + IN HANDLE hThread, + IN PCLIENT_ID ClientId, + IN PCSR_NT_SESSION NtSession, + IN ULONG Flags, + IN PCLIENT_ID DebugCid); + BOOLEAN NTAPI ProtectHandle(IN HANDLE ObjectHandle); @@ -391,6 +415,10 @@ CsrSrvSetPriorityClass( IN OUT PULONG Reply ); +VOID +NTAPI +CsrReferenceNtSession(IN PCSR_NT_SESSION Session); + LONG NTAPI CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo);