server: Allow passing suspend context in select request.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
85f9f51df8
commit
e70b684ded
|
@ -624,6 +624,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
|||
req->cookie = wine_server_client_ptr( &cookie );
|
||||
req->prev_apc = apc_handle;
|
||||
req->timeout = abs_timeout;
|
||||
req->size = size;
|
||||
wine_server_add_data( req, &result, sizeof(result) );
|
||||
wine_server_add_data( req, select_op, size );
|
||||
ret = server_call_unlocked( req );
|
||||
|
|
|
@ -1257,16 +1257,18 @@ struct select_request
|
|||
int flags;
|
||||
client_ptr_t cookie;
|
||||
abstime_t timeout;
|
||||
data_size_t size;
|
||||
obj_handle_t prev_apc;
|
||||
/* VARARG(result,apc_result); */
|
||||
/* VARARG(data,select_op); */
|
||||
char __pad_36[4];
|
||||
/* VARARG(data,select_op,size); */
|
||||
/* VARARG(context,context); */
|
||||
};
|
||||
struct select_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
apc_call_t call;
|
||||
obj_handle_t apc_handle;
|
||||
/* VARARG(context,context); */
|
||||
char __pad_52[4];
|
||||
};
|
||||
#define SELECT_ALERTABLE 1
|
||||
|
@ -6716,7 +6718,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 598
|
||||
#define SERVER_PROTOCOL_VERSION 599
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -1106,12 +1106,15 @@ struct rawinput_device
|
|||
int flags; /* wait flags (see below) */
|
||||
client_ptr_t cookie; /* magic cookie to return to client */
|
||||
abstime_t timeout; /* timeout */
|
||||
data_size_t size; /* size of select_op */
|
||||
obj_handle_t prev_apc; /* handle to previous APC */
|
||||
VARARG(result,apc_result); /* result of previous APC */
|
||||
VARARG(data,select_op); /* operation-specific data */
|
||||
VARARG(data,select_op,size); /* operation-specific data */
|
||||
VARARG(context,context); /* suspend context */
|
||||
@REPLY
|
||||
apc_call_t call; /* APC call arguments */
|
||||
obj_handle_t apc_handle; /* handle to next APC */
|
||||
VARARG(context,context); /* suspend context */
|
||||
@END
|
||||
#define SELECT_ALERTABLE 1
|
||||
#define SELECT_INTERRUPTIBLE 2
|
||||
|
|
|
@ -938,7 +938,8 @@ C_ASSERT( sizeof(struct open_thread_reply) == 16 );
|
|||
C_ASSERT( FIELD_OFFSET(struct select_request, flags) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_request, cookie) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_request, timeout) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_request, prev_apc) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_request, size) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_request, prev_apc) == 36 );
|
||||
C_ASSERT( sizeof(struct select_request) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_reply, call) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct select_reply, apc_handle) == 48 );
|
||||
|
|
|
@ -1536,18 +1536,36 @@ DECL_HANDLER(select)
|
|||
struct thread_apc *apc;
|
||||
const apc_result_t *result = get_req_data();
|
||||
|
||||
if (get_req_data_size() < sizeof(*result))
|
||||
if (get_req_data_size() < sizeof(*result) ||
|
||||
get_req_data_size() - sizeof(*result) < req->size ||
|
||||
req->size & 3)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_req_data_size() - sizeof(*result) - req->size == sizeof(context_t))
|
||||
{
|
||||
const context_t *context = (const context_t *)((const char *)(result + 1) + req->size);
|
||||
if (current->context || context->cpu != current->process->cpu)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(current->suspend_context = mem_alloc( sizeof(*context) ))) return;
|
||||
memcpy( current->suspend_context, context, sizeof(*context) );
|
||||
current->suspend_context->flags = 0; /* to keep track of what is modified */
|
||||
current->context = current->suspend_context;
|
||||
}
|
||||
|
||||
if (!req->cookie)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
|
||||
op_size = min( get_req_data_size() - sizeof(*result), sizeof(select_op) );
|
||||
op_size = min( req->size, sizeof(select_op) );
|
||||
memset( &select_op, 0, sizeof(select_op) );
|
||||
memcpy( &select_op, result + 1, op_size );
|
||||
|
||||
|
|
|
@ -1588,15 +1588,18 @@ static void dump_select_request( const struct select_request *req )
|
|||
fprintf( stderr, " flags=%d", req->flags );
|
||||
dump_uint64( ", cookie=", &req->cookie );
|
||||
dump_abstime( ", timeout=", &req->timeout );
|
||||
fprintf( stderr, ", size=%u", req->size );
|
||||
fprintf( stderr, ", prev_apc=%04x", req->prev_apc );
|
||||
dump_varargs_apc_result( ", result=", cur_size );
|
||||
dump_varargs_select_op( ", data=", cur_size );
|
||||
dump_varargs_select_op( ", data=", min(cur_size,req->size) );
|
||||
dump_varargs_context( ", context=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_select_reply( const struct select_reply *req )
|
||||
{
|
||||
dump_apc_call( " call=", &req->call );
|
||||
fprintf( stderr, ", apc_handle=%04x", req->apc_handle );
|
||||
dump_varargs_context( ", context=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_create_event_request( const struct create_event_request *req )
|
||||
|
|
Loading…
Reference in New Issue