Commit 4c9b3996 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ntdll: Implement NtQueryInformationThread(ThreadIsTerminated).

parent 72590048
......@@ -3697,6 +3697,44 @@ static void test_debuggee_dbgport(int argc, char **argv)
winetest_pop_context();
}
static DWORD WINAPI test_ThreadIsTerminated_thread( void *stop_event )
{
WaitForSingleObject( stop_event, INFINITE );
return STATUS_PENDING;
}
static void test_ThreadIsTerminated(void)
{
HANDLE thread, stop_event;
ULONG terminated;
NTSTATUS status;
stop_event = CreateEventW( NULL, FALSE, FALSE, NULL );
thread = CreateThread( NULL, 0, test_ThreadIsTerminated_thread, stop_event, 0, NULL );
ok( thread != INVALID_HANDLE_VALUE, "failed, error %ld\n", GetLastError() );
status = pNtQueryInformationThread( thread, ThreadIsTerminated, &terminated, sizeof(terminated) * 2, NULL );
ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx.\n", status );
terminated = 0xdeadbeef;
status = pNtQueryInformationThread( thread, ThreadIsTerminated, &terminated, sizeof(terminated), NULL );
ok( !status, "got %#lx.\n", status );
ok( !terminated, "got %lu.\n", terminated );
SetEvent( stop_event );
WaitForSingleObject( thread, INFINITE );
status = pNtQueryInformationThread( thread, ThreadIsTerminated, &terminated, sizeof(terminated), NULL );
ok( !status, "got %#lx.\n", status );
ok( terminated == 1, "got %lu.\n", terminated );
CloseHandle(stop_event);
CloseHandle(thread);
status = pNtQueryInformationThread( thread, ThreadIsTerminated, &terminated, sizeof(terminated), NULL );
ok( status == STATUS_INVALID_HANDLE, "got %#lx.\n", status );
}
START_TEST(info)
{
char **argv;
......@@ -3760,6 +3798,7 @@ START_TEST(info)
test_thread_start_address();
test_thread_lookup();
test_thread_ideal_processor();
test_ThreadIsTerminated();
test_affinity();
test_debug_object();
......
......@@ -2143,6 +2143,25 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
if (ret_len) *ret_len = sizeof(BOOL);
return STATUS_SUCCESS;
case ThreadIsTerminated:
{
ULONG terminated;
if (length != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
SERVER_START_REQ( get_thread_info )
{
req->handle = wine_server_obj_handle( handle );
if (!(status = wine_server_call( req ))) terminated = !!(reply->flags & GET_THREAD_INFO_FLAG_TERMINATED);
}
SERVER_END_REQ;
if (!status)
{
*(ULONG *)data = terminated;
if (ret_len) *ret_len = sizeof(ULONG);
}
return status;
}
case ThreadSuspendCount:
if (length != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
if (!data) return STATUS_ACCESS_VIOLATION;
......@@ -2196,7 +2215,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
req->handle = wine_server_obj_handle( handle );
req->access = THREAD_QUERY_INFORMATION;
if ((status = wine_server_call( req ))) return status;
*(BOOLEAN*)data = reply->dbg_hidden;
*(BOOLEAN*)data = !!(reply->flags & GET_THREAD_INFO_FLAG_DBG_HIDDEN);
}
SERVER_END_REQ;
if (ret_len) *ret_len = sizeof(BOOLEAN);
......
......@@ -688,6 +688,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationThread( UINT *args )
case ThreadEnableAlignmentFaultFixup: /* set only */
case ThreadAmILastThread: /* ULONG */
case ThreadIsIoPending: /* ULONG */
case ThreadIsTerminated: /* ULONG */
case ThreadHideFromDebugger: /* BOOLEAN */
case ThreadSuspendCount: /* ULONG */
case ThreadPriorityBoost: /* ULONG */
......
......@@ -1162,10 +1162,12 @@ struct get_thread_info_reply
int priority;
int last;
int suspend_count;
int dbg_hidden;
unsigned int flags;
data_size_t desc_len;
/* VARARG(desc,unicode_str); */
};
#define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01
#define GET_THREAD_INFO_FLAG_TERMINATED 0x02
......@@ -6504,7 +6506,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 784
#define SERVER_PROTOCOL_VERSION 785
/* ### protocol_version end ### */
......
......@@ -1085,10 +1085,12 @@ typedef struct
int priority; /* thread priority level */
int last; /* last thread in process */
int suspend_count; /* thread suspend count */
int dbg_hidden; /* thread hidden from debugger */
unsigned int flags; /* GET_THREAD_INFO_FLAG_ flags */
data_size_t desc_len; /* description length in bytes */
VARARG(desc,unicode_str); /* description string */
@END
#define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01
#define GET_THREAD_INFO_FLAG_TERMINATED 0x02
/* Retrieve information about thread times */
......
......@@ -860,7 +860,7 @@ C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, exit_code) == 40 );
C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, priority) == 44 );
C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, last) == 48 );
C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, suspend_count) == 52 );
C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, dbg_hidden) == 56 );
C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, flags) == 56 );
C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, desc_len) == 60 );
C_ASSERT( sizeof(struct get_thread_info_reply) == 64 );
C_ASSERT( FIELD_OFFSET(struct get_thread_times_request, handle) == 12 );
......
......@@ -1496,8 +1496,12 @@ DECL_HANDLER(get_thread_info)
reply->affinity = thread->affinity;
reply->last = thread->process->running_threads == 1;
reply->suspend_count = thread->suspend;
reply->dbg_hidden = thread->dbg_hidden;
reply->desc_len = thread->desc_len;
reply->flags = 0;
if (thread->dbg_hidden)
reply->flags |= GET_THREAD_INFO_FLAG_DBG_HIDDEN;
if (thread->state == TERMINATED)
reply->flags |= GET_THREAD_INFO_FLAG_TERMINATED;
if (thread->desc && get_reply_max_size())
{
......
......@@ -1604,7 +1604,7 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req
fprintf( stderr, ", priority=%d", req->priority );
fprintf( stderr, ", last=%d", req->last );
fprintf( stderr, ", suspend_count=%d", req->suspend_count );
fprintf( stderr, ", dbg_hidden=%d", req->dbg_hidden );
fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", desc_len=%u", req->desc_len );
dump_varargs_unicode_str( ", desc=", cur_size );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment