[CSRSRV/KERNEL32]: Close the last big architectural known issue: we were not notifying CSRSRV of server threads within server-to-server situations. Port and fix CsrCreateRemoteThread from CSRSRV2, and call it from Kernel32 now when running inside the server itself. Also fix BaseProcessStart not to exit the whole process during an exception.

At this point, other issues are unknown regressions.

svn path=/trunk/; revision=55720
This commit is contained in:
Alex Ionescu 2012-02-19 20:09:49 +00:00
parent 339ee42bae
commit 0e457a22c3
4 changed files with 139 additions and 10 deletions

View file

@ -459,8 +459,6 @@ VOID
WINAPI
BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
{
UINT uExitCode = 0;
DPRINT("BaseProcessStartup(..) - setting up exception frame.\n");
_SEH2_TRY
@ -472,17 +470,23 @@ BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
sizeof(PPROCESS_START_ROUTINE));
/* Call the Start Routine */
uExitCode = (lpStartAddress)();
ExitThread(lpStartAddress());
}
_SEH2_EXCEPT(BaseExceptionFilter(_SEH2_GetExceptionInformation()))
{
/* Get the SEH Error */
uExitCode = _SEH2_GetExceptionCode();
/* Get the Exit code from the SEH Handler */
if (!BaseRunningInServerProcess)
{
/* Kill the whole process, usually */
ExitProcess(_SEH2_GetExceptionCode());
}
else
{
/* If running inside CSRSS, kill just this thread */
ExitThread(_SEH2_GetExceptionCode());
}
}
_SEH2_END;
/* Exit the Process with our error */
ExitProcess(uExitCode);
}
NTSTATUS

View file

@ -19,6 +19,8 @@
#define HIGH_PRIORITY 31
#define SXS_SUPPORT_FIXME
typedef NTSTATUS (NTAPI *PCSR_CREATE_REMOTE_THREAD)(IN HANDLE ThreadHandle, IN PCLIENT_ID ClientId);
NTSTATUS
WINAPI
BasepNotifyCsrOfThread(IN HANDLE ThreadHandle,
@ -239,7 +241,29 @@ CreateRemoteThread(HANDLE hProcess,
}
/* Notify CSR */
Status = BasepNotifyCsrOfThread(hThread, &ClientId);
if (!BaseRunningInServerProcess)
{
Status = BasepNotifyCsrOfThread(hThread, &ClientId);
}
else
{
DPRINT("Server thread in Server. Handle: %lx\n", hProcess);
if (hProcess != NtCurrentProcess())
{
PCSR_CREATE_REMOTE_THREAD CsrCreateRemoteThread;
/* Get the direct CSRSRV export */
CsrCreateRemoteThread = (PCSR_CREATE_REMOTE_THREAD)
GetProcAddress(GetModuleHandleA("csrsrv"),
"CsrCreateRemoteThread");
if (CsrCreateRemoteThread)
{
/* Call it instead of going through LPC */
Status = CsrCreateRemoteThread(hThread, &ClientId);
}
}
}
if (!NT_SUCCESS(Status))
{
ASSERT(FALSE);

View file

@ -2,7 +2,7 @@
@ stdcall CsrCallServerFromServer(ptr ptr)
;@ stdcall CsrConnectToUser()
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
;@ stdcall CsrCreateRemoteThread(ptr ptr)
@ stdcall CsrCreateRemoteThread(ptr ptr)
@ stdcall CsrCreateThread(ptr ptr ptr)
;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
;@ stdcall CsrDebugProcess(ptr)

View file

@ -281,6 +281,107 @@ CsrRemoveThread(IN PCSR_THREAD CsrThread)
CsrThread->Flags |= CsrThreadInTermination;
}
/*++
* @name CsrCreateRemoteThread
* @implemented NT4
*
* The CsrCreateRemoteThread routine creates a CSR Thread object for
* an NT Thread which is not part of the current NT Process.
*
* @param hThread
* Handle to an existing NT Thread to which to associate this
* CSR Thread.
*
* @param ClientId
* Pointer to the Client ID structure of the NT Thread to associate
* with this CSR Thread.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateRemoteThread(IN HANDLE hThread,
IN PCLIENT_ID ClientId)
{
NTSTATUS Status;
HANDLE ThreadHandle;
PCSR_THREAD CsrThread;
PCSR_PROCESS CsrProcess;
KERNEL_USER_TIMES KernelTimes;
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Get the Thread Create Time */
Status = NtQueryInformationThread(hThread,
ThreadTimes,
&KernelTimes,
sizeof(KernelTimes),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to query thread times: %lx\n", Status);
return Status;
}
/* Lock the Owner Process */
Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("No known process for %lx\n", ClientId->UniqueProcess);
return Status;
}
/* Make sure the thread didn't terminate */
if (KernelTimes.ExitTime.QuadPart)
{
/* Unlock the process and return */
CsrUnlockProcess(CsrProcess);
DPRINT1("Dead thread: %I64x\n", KernelTimes.ExitTime.QuadPart);
return STATUS_THREAD_IS_TERMINATING;
}
/* Allocate a CSR Thread Structure */
CsrThread = CsrAllocateThread(CsrProcess);
if (!CsrThread)
{
DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
CsrUnlockProcess(CsrProcess);
return STATUS_NO_MEMORY;
}
/* Duplicate the Thread Handle */
Status = NtDuplicateObject(NtCurrentProcess(),
hThread,
NtCurrentProcess(),
&ThreadHandle,
0,
0,
DUPLICATE_SAME_ACCESS);
/* Allow failure */
if (!NT_SUCCESS(Status))
{
DPRINT1("Thread duplication failed: %lx\n", Status);
ThreadHandle = hThread;
}
/* Save the data we have */
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = *ClientId;
CsrThread->ThreadHandle = ThreadHandle;
ProtectHandle(ThreadHandle);
CsrThread->Flags = 0;
/* Insert the Thread into the Process */
CsrInsertThread(CsrProcess, CsrThread);
/* Release the lock and return */
CsrUnlockProcess(CsrProcess);
return STATUS_SUCCESS;
}
VOID
NTAPI
CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)