diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 3696c8e8cf7..2781827140d 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -962,12 +962,10 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, case ThreadTimes: { KERNEL_USER_TIMES kusrt; - /* We need to do a server call to get the creation time or exit time */ - /* This works on any thread */ - SERVER_START_REQ( get_thread_info ) + + SERVER_START_REQ( get_thread_times ) { req->handle = wine_server_obj_handle( handle ); - req->tid_in = 0; status = wine_server_call( req ); if (status == STATUS_SUCCESS) { diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 8b186fa3196..ac0d2d0b6aa 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -893,12 +893,24 @@ struct get_thread_info_reply thread_id_t tid; client_ptr_t teb; affinity_t affinity; - timeout_t creation_time; - timeout_t exit_time; int exit_code; int priority; int last; - char __pad_60[4]; + char __pad_44[4]; +}; + + + +struct get_thread_times_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_thread_times_reply +{ + struct reply_header __header; + timeout_t creation_time; + timeout_t exit_time; }; @@ -5295,6 +5307,7 @@ enum request REQ_get_process_info, REQ_set_process_info, REQ_get_thread_info, + REQ_get_thread_times, REQ_set_thread_info, REQ_get_dll_info, REQ_suspend_thread, @@ -5568,6 +5581,7 @@ union generic_request struct get_process_info_request get_process_info_request; struct set_process_info_request set_process_info_request; struct get_thread_info_request get_thread_info_request; + struct get_thread_times_request get_thread_times_request; struct set_thread_info_request set_thread_info_request; struct get_dll_info_request get_dll_info_request; struct suspend_thread_request suspend_thread_request; @@ -5839,6 +5853,7 @@ union generic_reply struct get_process_info_reply get_process_info_reply; struct set_process_info_reply set_process_info_reply; struct get_thread_info_reply get_thread_info_reply; + struct get_thread_times_reply get_thread_times_reply; struct set_thread_info_reply set_thread_info_reply; struct get_dll_info_reply get_dll_info_reply; struct suspend_thread_reply suspend_thread_reply; @@ -6096,6 +6111,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 481 +#define SERVER_PROTOCOL_VERSION 482 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 0ff1a6bd37c..3d7f7bef6a1 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -842,14 +842,21 @@ struct rawinput_device thread_id_t tid; /* server thread id */ client_ptr_t teb; /* thread teb pointer */ affinity_t affinity; /* thread affinity mask */ - timeout_t creation_time; /* thread creation time */ - timeout_t exit_time; /* thread exit time */ int exit_code; /* thread exit code */ int priority; /* thread priority level */ int last; /* last thread in process */ @END +/* Retrieve information about thread times */ +@REQ(get_thread_times) + obj_handle_t handle; /* thread handle */ +@REPLY + timeout_t creation_time; /* thread creation time */ + timeout_t exit_time; /* thread exit time */ +@END + + /* Set a thread information */ @REQ(set_thread_info) obj_handle_t handle; /* thread handle */ diff --git a/server/request.h b/server/request.h index 760466ce44b..299b4adfbac 100644 --- a/server/request.h +++ b/server/request.h @@ -117,6 +117,7 @@ DECL_HANDLER(terminate_thread); DECL_HANDLER(get_process_info); DECL_HANDLER(set_process_info); DECL_HANDLER(get_thread_info); +DECL_HANDLER(get_thread_times); DECL_HANDLER(set_thread_info); DECL_HANDLER(get_dll_info); DECL_HANDLER(suspend_thread); @@ -389,6 +390,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_get_process_info, (req_handler)req_set_process_info, (req_handler)req_get_thread_info, + (req_handler)req_get_thread_times, (req_handler)req_set_thread_info, (req_handler)req_get_dll_info, (req_handler)req_suspend_thread, @@ -767,12 +769,15 @@ C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, pid) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, tid) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, teb) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, affinity) == 24 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, creation_time) == 32 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, exit_time) == 40 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, exit_code) == 48 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, priority) == 52 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, last) == 56 ); -C_ASSERT( sizeof(struct get_thread_info_reply) == 64 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, exit_code) == 32 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, priority) == 36 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, last) == 40 ); +C_ASSERT( sizeof(struct get_thread_info_reply) == 48 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_times_request, handle) == 12 ); +C_ASSERT( sizeof(struct get_thread_times_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_times_reply, creation_time) == 8 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_times_reply, exit_time) == 16 ); +C_ASSERT( sizeof(struct get_thread_times_reply) == 24 ); 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 ); diff --git a/server/thread.c b/server/thread.c index 84716517224..b8c73c65190 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1374,9 +1374,21 @@ DECL_HANDLER(get_thread_info) reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING; reply->priority = thread->priority; reply->affinity = thread->affinity; + reply->last = thread->process->running_threads == 1; + + release_object( thread ); + } +} + +/* fetch information about thread times */ +DECL_HANDLER(get_thread_times) +{ + struct thread *thread; + + if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION ))) + { reply->creation_time = thread->creation_time; reply->exit_time = thread->exit_time; - reply->last = thread->process->running_threads == 1; release_object( thread ); } diff --git a/server/trace.c b/server/trace.c index 42cff99c8b9..3aa52713748 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1301,13 +1301,22 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req fprintf( stderr, ", tid=%04x", req->tid ); dump_uint64( ", teb=", &req->teb ); dump_uint64( ", affinity=", &req->affinity ); - dump_timeout( ", creation_time=", &req->creation_time ); - dump_timeout( ", exit_time=", &req->exit_time ); fprintf( stderr, ", exit_code=%d", req->exit_code ); fprintf( stderr, ", priority=%d", req->priority ); fprintf( stderr, ", last=%d", req->last ); } +static void dump_get_thread_times_request( const struct get_thread_times_request *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + +static void dump_get_thread_times_reply( const struct get_thread_times_reply *req ) +{ + dump_timeout( " creation_time=", &req->creation_time ); + dump_timeout( ", exit_time=", &req->exit_time ); +} + static void dump_set_thread_info_request( const struct set_thread_info_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); @@ -4256,6 +4265,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_process_info_request, (dump_func)dump_set_process_info_request, (dump_func)dump_get_thread_info_request, + (dump_func)dump_get_thread_times_request, (dump_func)dump_set_thread_info_request, (dump_func)dump_get_dll_info_request, (dump_func)dump_suspend_thread_request, @@ -4525,6 +4535,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_process_info_reply, NULL, (dump_func)dump_get_thread_info_reply, + (dump_func)dump_get_thread_times_reply, NULL, (dump_func)dump_get_dll_info_reply, (dump_func)dump_suspend_thread_reply, @@ -4794,6 +4805,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "get_process_info", "set_process_info", "get_thread_info", + "get_thread_times", "set_thread_info", "get_dll_info", "suspend_thread",