ntdll: Implement thread description as information class.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fd3fb2efdb
commit
b934f6626e
|
@ -1115,6 +1115,36 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
*(BOOL*)data = FALSE;
|
||||
if (ret_len) *ret_len = sizeof(BOOL);
|
||||
return STATUS_SUCCESS;
|
||||
case ThreadDescription:
|
||||
{
|
||||
THREAD_DESCRIPTION_INFORMATION *info = data;
|
||||
data_size_t len, desc_len = 0;
|
||||
WCHAR *ptr;
|
||||
|
||||
len = length >= sizeof(*info) ? length - sizeof(*info) : 0;
|
||||
ptr = info ? (WCHAR *)(info + 1) : NULL;
|
||||
|
||||
SERVER_START_REQ( get_thread_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
if (ptr) wine_server_set_reply( req, ptr, len );
|
||||
status = wine_server_call( req );
|
||||
desc_len = reply->desc_len;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!info)
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
else if (status == STATUS_SUCCESS)
|
||||
{
|
||||
info->Length = desc_len << 16 | desc_len;
|
||||
info->Description = ptr;
|
||||
}
|
||||
|
||||
if (ret_len && (status == STATUS_SUCCESS || status == STATUS_BUFFER_TOO_SMALL))
|
||||
*ret_len = sizeof(*info) + desc_len;
|
||||
}
|
||||
return status;
|
||||
case ThreadPriority:
|
||||
case ThreadBasePriority:
|
||||
case ThreadImpersonationToken:
|
||||
|
@ -1270,6 +1300,28 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
SERVER_END_REQ;
|
||||
}
|
||||
return status;
|
||||
case ThreadDescription:
|
||||
{
|
||||
const THREAD_DESCRIPTION_INFORMATION *info = data;
|
||||
data_size_t desc_len;
|
||||
|
||||
if (length != sizeof(*info)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
if (!info) return STATUS_ACCESS_VIOLATION;
|
||||
|
||||
desc_len = info->Length & 0xffff;
|
||||
if (info->Length >> 16 != desc_len) return STATUS_INVALID_PARAMETER;
|
||||
if (info->Length && !info->Description) return STATUS_ACCESS_VIOLATION;
|
||||
|
||||
SERVER_START_REQ( set_thread_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->mask = SET_THREAD_INFO_DESCRIPTION;
|
||||
wine_server_add_data( req, info->Description, desc_len );
|
||||
status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
return status;
|
||||
case ThreadBasicInformation:
|
||||
case ThreadTimes:
|
||||
case ThreadPriority:
|
||||
|
|
|
@ -1006,7 +1006,8 @@ struct get_thread_info_reply
|
|||
int exit_code;
|
||||
int priority;
|
||||
int last;
|
||||
char __pad_52[4];
|
||||
data_size_t desc_len;
|
||||
/* VARARG(desc,unicode_str); */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1034,6 +1035,7 @@ struct set_thread_info_request
|
|||
affinity_t affinity;
|
||||
client_ptr_t entry_point;
|
||||
obj_handle_t token;
|
||||
/* VARARG(desc,unicode_str); */
|
||||
char __pad_44[4];
|
||||
};
|
||||
struct set_thread_info_reply
|
||||
|
@ -1044,6 +1046,7 @@ struct set_thread_info_reply
|
|||
#define SET_THREAD_INFO_AFFINITY 0x02
|
||||
#define SET_THREAD_INFO_TOKEN 0x04
|
||||
#define SET_THREAD_INFO_ENTRYPOINT 0x08
|
||||
#define SET_THREAD_INFO_DESCRIPTION 0x10
|
||||
|
||||
|
||||
|
||||
|
@ -6697,6 +6700,6 @@ union generic_reply
|
|||
struct resume_process_reply resume_process_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 591
|
||||
#define SERVER_PROTOCOL_VERSION 592
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -944,6 +944,8 @@ struct rawinput_device
|
|||
int exit_code; /* thread exit code */
|
||||
int priority; /* thread priority level */
|
||||
int last; /* last thread in process */
|
||||
data_size_t desc_len; /* description length in bytes */
|
||||
VARARG(desc,unicode_str); /* description string */
|
||||
@END
|
||||
|
||||
|
||||
|
@ -964,11 +966,13 @@ struct rawinput_device
|
|||
affinity_t affinity; /* affinity mask */
|
||||
client_ptr_t entry_point; /* thread entry point */
|
||||
obj_handle_t token; /* impersonation token */
|
||||
VARARG(desc,unicode_str); /* description string */
|
||||
@END
|
||||
#define SET_THREAD_INFO_PRIORITY 0x01
|
||||
#define SET_THREAD_INFO_AFFINITY 0x02
|
||||
#define SET_THREAD_INFO_TOKEN 0x04
|
||||
#define SET_THREAD_INFO_ENTRYPOINT 0x08
|
||||
#define SET_THREAD_INFO_DESCRIPTION 0x10
|
||||
|
||||
|
||||
/* Retrieve information about a module */
|
||||
|
|
|
@ -849,6 +849,7 @@ C_ASSERT( FIELD_OFFSET(struct get_thread_info_reply, affinity) == 32 );
|
|||
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, desc_len) == 52 );
|
||||
C_ASSERT( sizeof(struct get_thread_info_reply) == 56 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_thread_times_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct get_thread_times_request) == 16 );
|
||||
|
|
|
@ -201,6 +201,8 @@ static inline void init_thread_structure( struct thread *thread )
|
|||
thread->suspend = 0;
|
||||
thread->desktop_users = 0;
|
||||
thread->token = NULL;
|
||||
thread->desc = NULL;
|
||||
thread->desc_len = 0;
|
||||
|
||||
thread->creation_time = current_time;
|
||||
thread->exit_time = 0;
|
||||
|
@ -336,6 +338,7 @@ static void cleanup_thread( struct thread *thread )
|
|||
thread->inflight[i].client = thread->inflight[i].server = -1;
|
||||
}
|
||||
}
|
||||
free( thread->desc );
|
||||
thread->req_data = NULL;
|
||||
thread->reply_data = NULL;
|
||||
thread->request_fd = NULL;
|
||||
|
@ -344,6 +347,8 @@ static void cleanup_thread( struct thread *thread )
|
|||
thread->context = NULL;
|
||||
thread->suspend_context = NULL;
|
||||
thread->desktop = 0;
|
||||
thread->desc = NULL;
|
||||
thread->desc_len = 0;
|
||||
}
|
||||
|
||||
/* destroy a thread when its refcount is 0 */
|
||||
|
@ -551,6 +556,28 @@ static void set_thread_info( struct thread *thread,
|
|||
security_set_thread_token( thread, req->token );
|
||||
if (req->mask & SET_THREAD_INFO_ENTRYPOINT)
|
||||
thread->entry_point = req->entry_point;
|
||||
if (req->mask & SET_THREAD_INFO_DESCRIPTION)
|
||||
{
|
||||
WCHAR *desc;
|
||||
data_size_t desc_len = get_req_data_size();
|
||||
|
||||
if (desc_len)
|
||||
{
|
||||
if ((desc = mem_alloc( desc_len )))
|
||||
{
|
||||
memcpy( desc, get_req_data(), desc_len );
|
||||
free( thread->desc );
|
||||
thread->desc = desc;
|
||||
thread->desc_len = desc_len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free( thread->desc );
|
||||
thread->desc = NULL;
|
||||
thread->desc_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stop a thread (at the Unix level) */
|
||||
|
@ -1436,6 +1463,15 @@ DECL_HANDLER(get_thread_info)
|
|||
reply->priority = thread->priority;
|
||||
reply->affinity = thread->affinity;
|
||||
reply->last = thread->process->running_threads == 1;
|
||||
reply->desc_len = thread->desc_len;
|
||||
|
||||
if (thread->desc && get_reply_max_size())
|
||||
{
|
||||
if (thread->desc_len <= get_reply_max_size())
|
||||
set_reply_data( thread->desc, thread->desc_len );
|
||||
else
|
||||
set_error( STATUS_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
release_object( thread );
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ struct thread
|
|||
timeout_t exit_time; /* Thread exit time */
|
||||
struct token *token; /* security token associated with this thread */
|
||||
struct list kernel_object; /* list of kernel object pointers */
|
||||
data_size_t desc_len; /* thread description length in bytes */
|
||||
WCHAR *desc; /* thread description string */
|
||||
};
|
||||
|
||||
struct thread_snapshot
|
||||
|
|
|
@ -1423,6 +1423,8 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req
|
|||
fprintf( stderr, ", exit_code=%d", req->exit_code );
|
||||
fprintf( stderr, ", priority=%d", req->priority );
|
||||
fprintf( stderr, ", last=%d", req->last );
|
||||
fprintf( stderr, ", desc_len=%u", req->desc_len );
|
||||
dump_varargs_unicode_str( ", desc=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_thread_times_request( const struct get_thread_times_request *req )
|
||||
|
@ -1444,6 +1446,7 @@ static void dump_set_thread_info_request( const struct set_thread_info_request *
|
|||
dump_uint64( ", affinity=", &req->affinity );
|
||||
dump_uint64( ", entry_point=", &req->entry_point );
|
||||
fprintf( stderr, ", token=%04x", req->token );
|
||||
dump_varargs_unicode_str( ", desc=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_dll_info_request( const struct get_dll_info_request *req )
|
||||
|
|
Loading…
Reference in New Issue