Module: wine Branch: master Commit: f626349c0a84bb4b163054b5f7f5bc1307475561 URL: https://source.winehq.org/git/wine.git/?a=commit;h=f626349c0a84bb4b163054b5f...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jun 23 11:41:21 2021 +0200
server: Use separate handles for thread and context in get_thread_context.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/unix/thread.c | 7 ++++--- include/wine/server_protocol.h | 2 +- server/protocol.def | 3 ++- server/request.h | 3 ++- server/thread.c | 13 +++++++------ server/trace.c | 1 + 6 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 3c9e375d665..65f80a392da 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -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 ret; + HANDLE context_handle; context_t server_context; 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) ); ret = wine_server_call( req ); *self = reply->self; - handle = wine_server_ptr_handle( reply->handle ); + context_handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ;
if (ret == STATUS_PENDING) { - NtWaitForSingleObject( handle, FALSE, NULL ); + NtWaitForSingleObject( context_handle, FALSE, NULL );
SERVER_START_REQ( get_thread_context ) { - req->handle = wine_server_obj_handle( handle ); + req->context = wine_server_obj_handle( context_handle ); req->flags = flags; wine_server_set_reply( req, &server_context, sizeof(server_context) ); ret = wine_server_call( req ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 095c2ac7d04..5135b1e5e06 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2460,8 +2460,8 @@ struct get_thread_context_request { struct request_header __header; obj_handle_t handle; + obj_handle_t context; unsigned int flags; - char __pad_20[4]; }; struct get_thread_context_reply { diff --git a/server/protocol.def b/server/protocol.def index 343febda6c5..22b03d0c91b 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1882,7 +1882,8 @@ struct process_info
/* Retrieve the current context of a thread */ @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 */ @REPLY int self; /* was it a handle to the current thread? */ diff --git a/server/request.h b/server/request.h index d38ddae6c5e..2106e3a3224 100644 --- a/server/request.h +++ b/server/request.h @@ -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( 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, 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( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 ); diff --git a/server/thread.c b/server/thread.c index 0c7f11c0da1..70e0b3fad15 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1797,14 +1797,15 @@ DECL_HANDLER(get_thread_context) 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 */ - system_flags = get_context_system_regs( thread_context->regs.machine ); + if (!(thread_context = (struct context *)get_handle_obj( current->process, req->context, 0, &context_ops ))) + 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 ); if (thread->state == RUNNING) { @@ -1831,8 +1832,8 @@ DECL_HANDLER(get_thread_context) } else set_error( STATUS_UNSUCCESSFUL ); release_object( thread ); + if (!thread_context) return; } - if (get_error() || !thread_context) return;
set_error( thread_context->status ); if (!thread_context->status && (context = set_reply_data_size( sizeof(context_t) ))) diff --git a/server/trace.c b/server/trace.c index 81b482b8338..49d97f77d08 100644 --- a/server/trace.c +++ b/server/trace.c @@ -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 ) { fprintf( stderr, " handle=%04x", req->handle ); + fprintf( stderr, ", context=%04x", req->context ); fprintf( stderr, ", flags=%08x", req->flags ); }