diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 0a070b5e885..1dfbd0140c3 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1198,6 +1198,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, SERVER_START_REQ( ioctl ) { req->code = code; + req->blocking = !apc && !event; req->async.handle = wine_server_obj_handle( handle ); req->async.callback = ioctl_completion; req->async.iosb = io; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 521f7275413..91656dfd4d4 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2710,6 +2710,7 @@ struct ioctl_request struct request_header __header; ioctl_code_t code; async_data_t async; + int blocking; /* VARARG(in_data,bytes); */ }; struct ioctl_reply @@ -5059,6 +5060,6 @@ union generic_reply struct set_window_layered_info_reply set_window_layered_info_reply; }; -#define SERVER_PROTOCOL_VERSION 370 +#define SERVER_PROTOCOL_VERSION 371 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/device.c b/server/device.c index 48bccd26fb0..9de2f548c34 100644 --- a/server/device.c +++ b/server/device.c @@ -125,7 +125,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static enum server_fd_type device_get_fd_type( struct fd *fd ); static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, - const void *data, data_size_t size ); + int blocking, const void *data, data_size_t size ); static const struct object_ops device_ops = { @@ -308,7 +308,7 @@ static struct ioctl_call *find_ioctl_call( struct device *device, struct thread } static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, - const void *data, data_size_t size ) + int blocking, const void *data, data_size_t size ) { struct device *device = get_fd_user( fd ); struct ioctl_call *ioctl; diff --git a/server/fd.c b/server/fd.c index 09b93ce06e1..c8b6f7aa702 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1912,7 +1912,7 @@ static void unmount_device( struct fd *device_fd ) /* default ioctl() routine */ obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, - const void *data, data_size_t size ) + int blocking, const void *data, data_size_t size ) { switch(code) { @@ -2015,7 +2015,7 @@ DECL_HANDLER(ioctl) if (fd) { - reply->wait = fd->fd_ops->ioctl( fd, req->code, &req->async, + reply->wait = fd->fd_ops->ioctl( fd, req->code, &req->async, req->blocking, get_req_data(), get_req_data_size() ); reply->options = fd->options; release_object( fd ); diff --git a/server/file.h b/server/file.h index b9a83c3f83d..3abfc0289f4 100644 --- a/server/file.h +++ b/server/file.h @@ -39,7 +39,7 @@ struct fd_ops /* get file information */ enum server_fd_type (*get_fd_type)(struct fd *fd); /* perform an ioctl on the file */ - obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, + obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking, const void *data, data_size_t size); /* queue an async operation */ void (*queue_async)(struct fd *, const async_data_t *data, int type, int count); @@ -79,7 +79,7 @@ extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, in extern void fd_async_wake_up( struct fd *fd, int type, unsigned int status ); extern void fd_reselect_async( struct fd *fd, struct async_queue *queue ); extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, - const void *data, data_size_t size ); + int blocking, const void *data, data_size_t size ); extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ); extern void default_fd_cancel_async( struct fd *fd ); diff --git a/server/named_pipe.c b/server/named_pipe.c index e9cb14a31d7..1651a67ff46 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -140,7 +140,7 @@ static void pipe_server_destroy( struct object *obj); static void pipe_server_flush( struct fd *fd, struct event **event ); static enum server_fd_type pipe_server_get_fd_type( struct fd *fd ); static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, - const void *data, data_size_t size ); + int blocking, const void *data, data_size_t size ); static const struct object_ops pipe_server_ops = { @@ -223,7 +223,7 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned static void named_pipe_device_destroy( struct object *obj ); static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd ); static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, - const void *data, data_size_t size ); + int blocking, const void *data, data_size_t size ); static const struct object_ops named_pipe_device_ops = { @@ -592,7 +592,7 @@ static obj_handle_t alloc_wait_event( struct process *process ) } static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, - const void *data, data_size_t size ) + int blocking, const void *data, data_size_t size ) { struct pipe_server *server = get_fd_user( fd ); struct async *async; @@ -605,7 +605,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a { case ps_idle_server: case ps_wait_connect: - if (!async_data->event && !async_data->apc) + if (blocking) { async_data_t new_data = *async_data; if (!(wait_handle = alloc_wait_event( current->process ))) break; @@ -673,7 +673,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a return 0; default: - return default_fd_ioctl( fd, code, async_data, data, size ); + return default_fd_ioctl( fd, code, async_data, blocking, data, size ); } } @@ -854,7 +854,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc } static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, - const void *data, data_size_t size ) + int blocking, const void *data, data_size_t size ) { struct named_pipe_device *device = get_fd_user( fd ); @@ -887,7 +887,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done; - if (!async_data->event && !async_data->apc) + if (blocking) { async_data_t new_data = *async_data; if (!(wait_handle = alloc_wait_event( current->process ))) goto done; @@ -916,7 +916,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c } default: - return default_fd_ioctl( fd, code, async_data, data, size ); + return default_fd_ioctl( fd, code, async_data, blocking, data, size ); } } diff --git a/server/protocol.def b/server/protocol.def index 62717a5fa32..397c54e1d7f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2003,6 +2003,7 @@ enum message_type @REQ(ioctl) ioctl_code_t code; /* ioctl code */ async_data_t async; /* async I/O parameters */ + int blocking; /* whether it's a blocking ioctl */ VARARG(in_data,bytes); /* ioctl input data */ @REPLY obj_handle_t wait; /* handle to wait on for blocking ioctl */ diff --git a/server/trace.c b/server/trace.c index d2a7cec7507..60b23183c3d 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2591,6 +2591,7 @@ static void dump_ioctl_request( const struct ioctl_request *req ) fprintf( stderr, " async=" ); dump_async_data( &req->async ); fprintf( stderr, "," ); + fprintf( stderr, " blocking=%d,", req->blocking ); fprintf( stderr, " in_data=" ); dump_varargs_bytes( cur_size ); }