ntdll: Abuse RtlCreateUserThread to call the thread function for CreateThread directly.

This commit is contained in:
Alexandre Julliard 2007-01-18 15:02:11 +01:00
parent 21d631e270
commit 7a383cf83f
2 changed files with 45 additions and 52 deletions

View file

@ -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 hProcess, SECURITY_ATTRIBUTES *sa, SIZE
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 hProcess, SECURITY_ATTRIBUTES *sa, SIZE
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 hProcess, SECURITY_ATTRIBUTES *sa, SIZE
}
else
{
RtlFreeHeap( GetProcessHeap(), 0, info );
SetLastError( RtlNtStatusToDosError(status) );
handle = 0;
}

View file

@ -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
@ -348,6 +349,47 @@ static PUNHANDLED_EXCEPTION_FILTER get_unhandled_exception_filter(void)
return unhandled_exception_filter;
}
/***********************************************************************
* 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
*
@ -397,7 +439,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
{
__TRY
{
MODULE_DllThreadAttach( NULL );
call_thread_func( func, arg );
}
__EXCEPT(get_unhandled_exception_filter())
{
@ -406,9 +448,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
__ENDTRY
}
else
MODULE_DllThreadAttach( NULL );
func( arg );
call_thread_func( func, arg );
}