Alexandre Julliard : ntdll:
Abuse RtlCreateUserThread to call the thread function for CreateThread
directly .
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jan 19 06:29:17 CST 2007
Module: wine
Branch: master
Commit: 7a383cf83f1f2896f67352a76c07b13510baff1d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7a383cf83f1f2896f67352a76c07b13510baff1d
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jan 18 15:02:11 2007 +0100
ntdll: Abuse RtlCreateUserThread to call the thread function for CreateThread directly.
---
dlls/kernel32/thread.c | 49 +-----------------------------------------------
dlls/ntdll/thread.c | 48 +++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 45 insertions(+), 52 deletions(-)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 4f2594c..cdbe1e1 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -45,42 +45,6 @@
#include "kernel_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread);
-WINE_DECLARE_DEBUG_CHANNEL(relay);
-
-
-struct new_thread_info
-{
- LPTHREAD_START_ROUTINE func;
- void *arg;
-};
-
-
-/***********************************************************************
- * THREAD_Start
- *
- * Start execution of a newly created thread. Does not return.
- */
-static void CALLBACK THREAD_Start( void *ptr )
-{
- struct new_thread_info *info = ptr;
- LPTHREAD_START_ROUTINE func = info->func;
- void *arg = info->arg;
-
- RtlFreeHeap( GetProcessHeap(), 0, info );
-
- if (TRACE_ON(relay))
- DPRINTF("%04x:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
-
- __TRY
- {
- ExitThread( func( arg ) );
- }
- __EXCEPT(UnhandledExceptionFilter)
- {
- TerminateThread( GetCurrentThread(), GetExceptionCode() );
- }
- __ENDTRY
-}
/***********************************************************************
@@ -120,22 +84,13 @@ HANDLE WINAPI CreateRemoteThread( HANDLE
CLIENT_ID client_id;
NTSTATUS status;
SIZE_T stack_reserve = 0, stack_commit = 0;
- struct new_thread_info *info;
-
- if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) )))
- {
- SetLastError( ERROR_NOT_ENOUGH_MEMORY );
- return 0;
- }
- info->func = start;
- info->arg = param;
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
else stack_commit = stack;
status = RtlCreateUserThread( hProcess, NULL, TRUE,
NULL, stack_reserve, stack_commit,
- THREAD_Start, info, &handle, &client_id );
+ (PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id );
if (status == STATUS_SUCCESS)
{
if (id) *id = (DWORD)client_id.UniqueThread;
@@ -147,7 +102,6 @@ HANDLE WINAPI CreateRemoteThread( HANDLE
if (NtResumeThread( handle, &ret ))
{
NtClose( handle );
- RtlFreeHeap( GetProcessHeap(), 0, info );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
handle = 0;
}
@@ -155,7 +109,6 @@ HANDLE WINAPI CreateRemoteThread( HANDLE
}
else
{
- RtlFreeHeap( GetProcessHeap(), 0, info );
SetLastError( RtlNtStatusToDosError(status) );
handle = 0;
}
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 4d99195..b06d1a3 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -43,6 +43,7 @@
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread);
+WINE_DECLARE_DEBUG_CHANNEL(relay);
/* info passed to a starting thread */
struct startup_info
@@ -349,6 +350,47 @@ static PUNHANDLED_EXCEPTION_FILTER get_u
}
/***********************************************************************
+ * call_thread_func
+ *
+ * Hack to make things compatible with the thread procedures used by kernel32.CreateThread.
+ */
+static void DECLSPEC_NORETURN call_thread_func( PRTL_THREAD_START_ROUTINE rtl_func, void *arg )
+{
+ LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)rtl_func;
+ DWORD exit_code;
+ BOOL last;
+
+ MODULE_DllThreadAttach( NULL );
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Starting thread proc %p (arg=%p)\n", GetCurrentThreadId(), func, arg );
+
+ exit_code = func( arg );
+
+ /* send the exit code to the server */
+ SERVER_START_REQ( terminate_thread )
+ {
+ req->handle = GetCurrentThread();
+ req->exit_code = exit_code;
+ wine_server_call( req );
+ last = reply->last;
+ }
+ SERVER_END_REQ;
+
+ if (last)
+ {
+ LdrShutdownProcess();
+ exit( exit_code );
+ }
+ else
+ {
+ LdrShutdownThread();
+ server_exit_thread( exit_code );
+ }
+}
+
+
+/***********************************************************************
* start_thread
*
* Startup routine for a newly created thread.
@@ -397,7 +439,7 @@ static void start_thread( struct wine_pt
{
__TRY
{
- MODULE_DllThreadAttach( NULL );
+ call_thread_func( func, arg );
}
__EXCEPT(get_unhandled_exception_filter())
{
@@ -406,9 +448,7 @@ static void start_thread( struct wine_pt
__ENDTRY
}
else
- MODULE_DllThreadAttach( NULL );
-
- func( arg );
+ call_thread_func( func, arg );
}
More information about the wine-cvs
mailing list