diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 2781827140..3e95fd4154 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -1203,14 +1203,26 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, case ThreadHideFromDebugger: /* pretend the call succeeded to satisfy some code protectors */ return STATUS_SUCCESS; - + case ThreadQuerySetWin32StartAddress: + { + const PRTL_THREAD_START_ROUTINE *entry = data; + if (length != sizeof(PRTL_THREAD_START_ROUTINE)) return STATUS_INVALID_PARAMETER; + SERVER_START_REQ( set_thread_info ) + { + req->handle = wine_server_obj_handle( handle ); + req->mask = SET_THREAD_INFO_ENTRYPOINT; + req->entry_point = wine_server_client_ptr( *entry ); + status = wine_server_call( req ); + } + SERVER_END_REQ; + } + return status; case ThreadBasicInformation: case ThreadTimes: case ThreadPriority: case ThreadDescriptorTableEntry: case ThreadEnableAlignmentFaultFixup: case ThreadEventPair_Reusable: - case ThreadQuerySetWin32StartAddress: case ThreadPerformanceCount: case ThreadAmILastThread: case ThreadIdealProcessor: diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index ac0d2d0b6a..200b27a5f8 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -922,16 +922,18 @@ struct set_thread_info_request int mask; int priority; affinity_t affinity; + client_ptr_t entry_point; obj_handle_t token; - char __pad_36[4]; + char __pad_44[4]; }; struct set_thread_info_reply { struct reply_header __header; }; -#define SET_THREAD_INFO_PRIORITY 0x01 -#define SET_THREAD_INFO_AFFINITY 0x02 -#define SET_THREAD_INFO_TOKEN 0x04 +#define SET_THREAD_INFO_PRIORITY 0x01 +#define SET_THREAD_INFO_AFFINITY 0x02 +#define SET_THREAD_INFO_TOKEN 0x04 +#define SET_THREAD_INFO_ENTRYPOINT 0x08 @@ -6111,6 +6113,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 482 +#define SERVER_PROTOCOL_VERSION 483 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 3d7f7bef6a..4279cb6d78 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -863,11 +863,13 @@ struct rawinput_device int mask; /* setting mask (see below) */ int priority; /* priority class */ affinity_t affinity; /* affinity mask */ + client_ptr_t entry_point; /* thread entry point */ obj_handle_t token; /* impersonation token */ @END -#define SET_THREAD_INFO_PRIORITY 0x01 -#define SET_THREAD_INFO_AFFINITY 0x02 -#define SET_THREAD_INFO_TOKEN 0x04 +#define SET_THREAD_INFO_PRIORITY 0x01 +#define SET_THREAD_INFO_AFFINITY 0x02 +#define SET_THREAD_INFO_TOKEN 0x04 +#define SET_THREAD_INFO_ENTRYPOINT 0x08 /* Retrieve information about a module */ diff --git a/server/request.h b/server/request.h index 299b4adfba..2ba8b45707 100644 --- a/server/request.h +++ b/server/request.h @@ -782,8 +782,9 @@ C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, mask) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, priority) == 20 ); C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, affinity) == 24 ); -C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, token) == 32 ); -C_ASSERT( sizeof(struct set_thread_info_request) == 40 ); +C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, entry_point) == 32 ); +C_ASSERT( FIELD_OFFSET(struct set_thread_info_request, token) == 40 ); +C_ASSERT( sizeof(struct set_thread_info_request) == 48 ); C_ASSERT( FIELD_OFFSET(struct get_dll_info_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_dll_info_request, base_address) == 16 ); C_ASSERT( sizeof(struct get_dll_info_request) == 24 ); diff --git a/server/thread.c b/server/thread.c index b8c73c6519..f0209088b3 100644 --- a/server/thread.c +++ b/server/thread.c @@ -175,6 +175,7 @@ static inline void init_thread_structure( struct thread *thread ) thread->context = NULL; thread->suspend_context = NULL; thread->teb = 0; + thread->entry_point = 0; thread->debug_ctx = NULL; thread->debug_event = NULL; thread->debug_break = 0; @@ -497,6 +498,8 @@ static void set_thread_info( struct thread *thread, } if (req->mask & SET_THREAD_INFO_TOKEN) security_set_thread_token( thread, req->token ); + if (req->mask & SET_THREAD_INFO_ENTRYPOINT) + thread->entry_point = req->entry_point; } /* stop a thread (at the Unix level) */ @@ -1284,6 +1287,7 @@ DECL_HANDLER(init_thread) current->unix_pid = req->unix_pid; current->unix_tid = req->unix_tid; current->teb = req->teb; + current->entry_point = req->entry; if (!process->peb) /* first thread, initialize the process too */ { diff --git a/server/thread.h b/server/thread.h index 996d95bd8c..282199149e 100644 --- a/server/thread.h +++ b/server/thread.h @@ -79,6 +79,7 @@ struct thread context_t *context; /* current context if in an exception handler */ context_t *suspend_context; /* current context if suspended */ client_ptr_t teb; /* TEB address (in client address space) */ + client_ptr_t entry_point; /* entry point (in client address space) */ affinity_t affinity; /* affinity mask */ int priority; /* priority level */ int suspend; /* suspend count */ diff --git a/server/trace.c b/server/trace.c index 3aa5271374..da4f5b8c10 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1323,6 +1323,7 @@ static void dump_set_thread_info_request( const struct set_thread_info_request * fprintf( stderr, ", mask=%d", req->mask ); fprintf( stderr, ", priority=%d", req->priority ); dump_uint64( ", affinity=", &req->affinity ); + dump_uint64( ", entry_point=", &req->entry_point ); fprintf( stderr, ", token=%04x", req->token ); }