server: Add a structure to pass the parameters of a select request.
This commit is contained in:
parent
e69670f76b
commit
c2ab7a625e
|
@ -1109,18 +1109,19 @@ NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_re
|
|||
NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
|
||||
const LARGE_INTEGER *timeout, HANDLE signal_object )
|
||||
{
|
||||
select_op_t select_op;
|
||||
NTSTATUS ret;
|
||||
UINT i;
|
||||
int cookie;
|
||||
BOOL user_apc = FALSE;
|
||||
obj_handle_t obj_handles[MAXIMUM_WAIT_OBJECTS];
|
||||
obj_handle_t apc_handle = 0;
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||
|
||||
memset( &result, 0, sizeof(result) );
|
||||
for (i = 0; i < count; i++) obj_handles[i] = wine_server_obj_handle( handles[i] );
|
||||
select_op.wait.op = SELECT_WAIT;
|
||||
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1132,7 +1133,7 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
|
|||
req->prev_apc = apc_handle;
|
||||
req->timeout = abs_timeout;
|
||||
wine_server_add_data( req, &result, sizeof(result) );
|
||||
wine_server_add_data( req, obj_handles, count * sizeof(*obj_handles) );
|
||||
wine_server_add_data( req, &select_op, offsetof( select_op_t, wait.handles[count] ));
|
||||
ret = wine_server_call( req );
|
||||
abs_timeout = reply->timeout;
|
||||
apc_handle = reply->apc_handle;
|
||||
|
|
|
@ -404,6 +404,22 @@ struct token_groups
|
|||
|
||||
};
|
||||
|
||||
enum select_op
|
||||
{
|
||||
SELECT_NONE,
|
||||
SELECT_WAIT
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
enum select_op op;
|
||||
struct
|
||||
{
|
||||
enum select_op op;
|
||||
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
||||
} wait;
|
||||
} select_op_t;
|
||||
|
||||
enum apc_type
|
||||
{
|
||||
APC_NONE,
|
||||
|
@ -1056,7 +1072,7 @@ struct select_request
|
|||
obj_handle_t prev_apc;
|
||||
timeout_t timeout;
|
||||
/* VARARG(result,apc_result); */
|
||||
/* VARARG(handles,handles); */
|
||||
/* VARARG(data,select_op); */
|
||||
};
|
||||
struct select_reply
|
||||
{
|
||||
|
@ -5771,6 +5787,6 @@ union generic_reply
|
|||
struct set_suspend_context_reply set_suspend_context_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 443
|
||||
#define SERVER_PROTOCOL_VERSION 444
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -420,6 +420,22 @@ struct token_groups
|
|||
/* VARARG(sids,SID); */
|
||||
};
|
||||
|
||||
enum select_op
|
||||
{
|
||||
SELECT_NONE,
|
||||
SELECT_WAIT
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
enum select_op op;
|
||||
struct
|
||||
{
|
||||
enum select_op op; /* SELECT_WAIT */
|
||||
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
|
||||
} wait;
|
||||
} select_op_t;
|
||||
|
||||
enum apc_type
|
||||
{
|
||||
APC_NONE,
|
||||
|
@ -924,7 +940,7 @@ struct rawinput_device
|
|||
obj_handle_t prev_apc; /* handle to previous APC */
|
||||
timeout_t timeout; /* timeout */
|
||||
VARARG(result,apc_result); /* result of previous APC */
|
||||
VARARG(handles,handles); /* handles to select on */
|
||||
VARARG(data,select_op); /* operation-specific data */
|
||||
@REPLY
|
||||
timeout_t timeout; /* timeout converted to absolute */
|
||||
apc_call_t call; /* APC call arguments */
|
||||
|
|
|
@ -710,23 +710,39 @@ static int signal_object( obj_handle_t handle )
|
|||
}
|
||||
|
||||
/* select on a list of handles */
|
||||
static timeout_t select_on( unsigned int count, client_ptr_t cookie, const obj_handle_t *handles,
|
||||
static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, client_ptr_t cookie,
|
||||
int flags, timeout_t timeout, obj_handle_t signal_obj )
|
||||
{
|
||||
int ret;
|
||||
unsigned int i;
|
||||
unsigned int i, count;
|
||||
struct object *objects[MAXIMUM_WAIT_OBJECTS];
|
||||
|
||||
if (timeout <= 0) timeout = current_time - timeout;
|
||||
|
||||
if (count > MAXIMUM_WAIT_OBJECTS)
|
||||
switch (select_op->op)
|
||||
{
|
||||
case SELECT_NONE:
|
||||
count = 0;
|
||||
break;
|
||||
|
||||
case SELECT_WAIT:
|
||||
count = (op_size - offsetof( select_op_t, wait.handles )) / sizeof(select_op->wait.handles[0]);
|
||||
if (op_size < offsetof( select_op_t, wait.handles ) || count > MAXIMUM_WAIT_OBJECTS)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (!(objects[i] = get_handle_obj( current->process, handles[i], SYNCHRONIZE, NULL )))
|
||||
if (!(objects[i] = get_handle_obj( current->process, select_op->wait.handles[i],
|
||||
SYNCHRONIZE, NULL )))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1310,17 +1326,19 @@ DECL_HANDLER(resume_thread)
|
|||
/* select on a handle list */
|
||||
DECL_HANDLER(select)
|
||||
{
|
||||
select_op_t select_op;
|
||||
data_size_t op_size;
|
||||
struct thread_apc *apc;
|
||||
unsigned int count;
|
||||
const apc_result_t *result = get_req_data();
|
||||
const obj_handle_t *handles = (const obj_handle_t *)(result + 1);
|
||||
|
||||
if (get_req_data_size() < sizeof(*result))
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
count = (get_req_data_size() - sizeof(*result)) / sizeof(obj_handle_t);
|
||||
op_size = min( get_req_data_size() - sizeof(*result), sizeof(select_op) );
|
||||
memset( &select_op, 0, sizeof(select_op) );
|
||||
memcpy( &select_op, result + 1, op_size );
|
||||
|
||||
/* first store results of previous apc */
|
||||
if (req->prev_apc)
|
||||
|
@ -1348,7 +1366,7 @@ DECL_HANDLER(select)
|
|||
release_object( apc );
|
||||
}
|
||||
|
||||
reply->timeout = select_on( count, req->cookie, handles, req->flags, req->timeout, req->signal );
|
||||
reply->timeout = select_on( &select_op, op_size, req->cookie, req->flags, req->timeout, req->signal );
|
||||
|
||||
if (get_error() == STATUS_USER_APC)
|
||||
{
|
||||
|
|
|
@ -66,6 +66,19 @@ static void dump_uints( const int *ptr, int len )
|
|||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_handles( const char *prefix, const obj_handle_t *data, data_size_t size )
|
||||
{
|
||||
data_size_t len = size / sizeof(*data);
|
||||
|
||||
fprintf( stderr,"%s{", prefix );
|
||||
while (len > 0)
|
||||
{
|
||||
fprintf( stderr, "%04x", *data++ );
|
||||
if (--len) fputc( ',', stderr );
|
||||
}
|
||||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_timeout( const char *prefix, const timeout_t *time )
|
||||
{
|
||||
fprintf( stderr, "%s%s", prefix, get_timeout_str(*time) );
|
||||
|
@ -367,16 +380,33 @@ static void dump_varargs_apc_result( const char *prefix, data_size_t size )
|
|||
remove_data( size );
|
||||
}
|
||||
|
||||
static void dump_varargs_handles( const char *prefix, data_size_t size )
|
||||
static void dump_varargs_select_op( const char *prefix, data_size_t size )
|
||||
{
|
||||
const obj_handle_t *data = cur_data;
|
||||
data_size_t len = size / sizeof(*data);
|
||||
select_op_t data;
|
||||
|
||||
fprintf( stderr,"%s{", prefix );
|
||||
while (len > 0)
|
||||
if (!size)
|
||||
{
|
||||
fprintf( stderr, "%04x", *data++ );
|
||||
if (--len) fputc( ',', stderr );
|
||||
fprintf( stderr, "%s{}", prefix );
|
||||
return;
|
||||
}
|
||||
memset( &data, 0, sizeof(data) );
|
||||
memcpy( &data, cur_data, min( size, sizeof(data) ));
|
||||
|
||||
fprintf( stderr, "%s{", prefix );
|
||||
switch (data.op)
|
||||
{
|
||||
case SELECT_NONE:
|
||||
fprintf( stderr, "NONE" );
|
||||
break;
|
||||
case SELECT_WAIT:
|
||||
fprintf( stderr, "WAIT" );
|
||||
if (size > offsetof( select_op_t, wait.handles ))
|
||||
dump_handles( ",handles=", data.wait.handles,
|
||||
min( size, sizeof(data.wait) ) - offsetof( select_op_t, wait.handles ));
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "op=%u", data.op );
|
||||
break;
|
||||
}
|
||||
fputc( '}', stderr );
|
||||
remove_data( size );
|
||||
|
@ -1361,7 +1391,7 @@ static void dump_select_request( const struct select_request *req )
|
|||
fprintf( stderr, ", prev_apc=%04x", req->prev_apc );
|
||||
dump_timeout( ", timeout=", &req->timeout );
|
||||
dump_varargs_apc_result( ", result=", cur_size );
|
||||
dump_varargs_handles( ", handles=", cur_size );
|
||||
dump_varargs_select_op( ", data=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_select_reply( const struct select_reply *req )
|
||||
|
|
Loading…
Reference in New Issue