server: Use separate handles for thread and context in get_thread_context.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-06-23 11:41:21 +02:00
parent 2ff7a7676c
commit f626349c0a
6 changed files with 17 additions and 12 deletions

View File

@ -1316,6 +1316,7 @@ NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USH
NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT machine ) NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT machine )
{ {
NTSTATUS ret; NTSTATUS ret;
HANDLE context_handle;
context_t server_context; context_t server_context;
unsigned int flags = get_server_context_flags( context, machine ); unsigned int flags = get_server_context_flags( context, machine );
@ -1326,17 +1327,17 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma
wine_server_set_reply( req, &server_context, sizeof(server_context) ); wine_server_set_reply( req, &server_context, sizeof(server_context) );
ret = wine_server_call( req ); ret = wine_server_call( req );
*self = reply->self; *self = reply->self;
handle = wine_server_ptr_handle( reply->handle ); context_handle = wine_server_ptr_handle( reply->handle );
} }
SERVER_END_REQ; SERVER_END_REQ;
if (ret == STATUS_PENDING) if (ret == STATUS_PENDING)
{ {
NtWaitForSingleObject( handle, FALSE, NULL ); NtWaitForSingleObject( context_handle, FALSE, NULL );
SERVER_START_REQ( get_thread_context ) SERVER_START_REQ( get_thread_context )
{ {
req->handle = wine_server_obj_handle( handle ); req->context = wine_server_obj_handle( context_handle );
req->flags = flags; req->flags = flags;
wine_server_set_reply( req, &server_context, sizeof(server_context) ); wine_server_set_reply( req, &server_context, sizeof(server_context) );
ret = wine_server_call( req ); ret = wine_server_call( req );

View File

@ -2460,8 +2460,8 @@ struct get_thread_context_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t handle;
obj_handle_t context;
unsigned int flags; unsigned int flags;
char __pad_20[4];
}; };
struct get_thread_context_reply struct get_thread_context_reply
{ {

View File

@ -1882,7 +1882,8 @@ struct process_info
/* Retrieve the current context of a thread */ /* Retrieve the current context of a thread */
@REQ(get_thread_context) @REQ(get_thread_context)
obj_handle_t handle; /* thread or context handle */ obj_handle_t handle; /* thread handle */
obj_handle_t context; /* context handle */
unsigned int flags; /* context flags */ unsigned int flags; /* context flags */
@REPLY @REPLY
int self; /* was it a handle to the current thread? */ int self; /* was it a handle to the current thread? */

View File

@ -1253,7 +1253,8 @@ C_ASSERT( FIELD_OFFSET(struct get_timer_info_reply, when) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_timer_info_reply, signaled) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_timer_info_reply, signaled) == 16 );
C_ASSERT( sizeof(struct get_timer_info_reply) == 24 ); C_ASSERT( sizeof(struct get_timer_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, flags) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, context) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, flags) == 20 );
C_ASSERT( sizeof(struct get_thread_context_request) == 24 ); C_ASSERT( sizeof(struct get_thread_context_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 );

View File

@ -1797,14 +1797,15 @@ DECL_HANDLER(get_thread_context)
return; return;
} }
if ((thread_context = (struct context *)get_handle_obj( current->process, req->handle, 0, &context_ops ))) if (req->context)
{ {
close_handle( current->process, req->handle ); /* avoid extra server call */ if (!(thread_context = (struct context *)get_handle_obj( current->process, req->context, 0, &context_ops )))
system_flags = get_context_system_regs( thread_context->regs.machine ); return;
close_handle( current->process, req->context ); /* avoid extra server call */
} }
else if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) else
{ {
clear_error(); if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
system_flags = get_context_system_regs( thread->process->machine ); system_flags = get_context_system_regs( thread->process->machine );
if (thread->state == RUNNING) if (thread->state == RUNNING)
{ {
@ -1831,8 +1832,8 @@ DECL_HANDLER(get_thread_context)
} }
else set_error( STATUS_UNSUCCESSFUL ); else set_error( STATUS_UNSUCCESSFUL );
release_object( thread ); release_object( thread );
if (!thread_context) return;
} }
if (get_error() || !thread_context) return;
set_error( thread_context->status ); set_error( thread_context->status );
if (!thread_context->status && (context = set_reply_data_size( sizeof(context_t) ))) if (!thread_context->status && (context = set_reply_data_size( sizeof(context_t) )))

View File

@ -2534,6 +2534,7 @@ static void dump_get_timer_info_reply( const struct get_timer_info_reply *req )
static void dump_get_thread_context_request( const struct get_thread_context_request *req ) static void dump_get_thread_context_request( const struct get_thread_context_request *req )
{ {
fprintf( stderr, " handle=%04x", req->handle ); fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", context=%04x", req->context );
fprintf( stderr, ", flags=%08x", req->flags ); fprintf( stderr, ", flags=%08x", req->flags );
} }