ntdll: Implement NtQueryInformationThread(ThreadIsTerminated).
This commit is contained in:
parent
72590048b2
commit
4c9b39964c
8 changed files with 74 additions and 7 deletions
|
@ -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 );
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue