Author: ion
Date: Sun Feb 19 20:09:49 2012
New Revision: 55720
URL:
http://svn.reactos.org/svn/reactos?rev=55720&view=rev
Log:
[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.
Modified:
trunk/reactos/dll/win32/kernel32/client/proc.c
trunk/reactos/dll/win32/kernel32/client/thread.c
trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec
trunk/reactos/subsystems/win32/csrss/csrsrv/thredsup.c
Modified: trunk/reactos/dll/win32/kernel32/client/proc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Sun Feb 19 20:09:49 2012
@@ -459,8 +459,6 @@
WINAPI
BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
{
- UINT uExitCode = 0;
-
DPRINT("BaseProcessStartup(..) - setting up exception frame.\n");
_SEH2_TRY
@@ -472,17 +470,23 @@
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
Modified: trunk/reactos/dll/win32/kernel32/client/thread.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/thread.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/thread.c [iso-8859-1] Sun Feb 19 20:09:49 2012
@@ -18,6 +18,8 @@
/* FIXME: NDK */
#define HIGH_PRIORITY 31
#define SXS_SUPPORT_FIXME
+
+typedef NTSTATUS (NTAPI *PCSR_CREATE_REMOTE_THREAD)(IN HANDLE ThreadHandle, IN PCLIENT_ID
ClientId);
NTSTATUS
WINAPI
@@ -239,7 +241,29 @@
}
/* 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);
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/csrsrv.spec [iso-8859-1] Sun Feb 19
20:09:49 2012
@@ -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)
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/thredsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/thredsup.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/thredsup.c [iso-8859-1] Sun Feb 19
20:09:49 2012
@@ -281,6 +281,107 @@
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)