server: Use create_request_async in ioctl request handler.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-06-26 12:20:10 +02:00 committed by Alexandre Julliard
parent 4e02a3bb13
commit c56c42ff79
8 changed files with 71 additions and 73 deletions

View File

@ -1543,7 +1543,11 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
status = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->wait );
options = reply->options;
if (status != STATUS_PENDING) io->Information = wine_server_reply_size( reply );
if (wait_handle && status != STATUS_PENDING)
{
io->u.Status = status;
io->Information = wine_server_reply_size( reply );
}
}
SERVER_END_REQ;
@ -1557,10 +1561,8 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event,
{
NtWaitForSingleObject( wait_handle, (options & FILE_SYNCHRONOUS_IO_ALERT), NULL );
status = io->u.Status;
NtClose( wait_handle );
}
if (status != STATUS_PENDING && code != FSCTL_PIPE_LISTEN) io->u.Status = status;
return status;
}

View File

@ -724,7 +724,7 @@ static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
ok( !reserved, "reserved is not 0: %x\n", reserved );
}
static void test_peek(HANDLE pipe)
static void test_peek(HANDLE pipe, BOOL is_msgmode)
{
FILE_PIPE_PEEK_BUFFER buf;
IO_STATUS_BLOCK iosb;
@ -743,7 +743,7 @@ static void test_peek(HANDLE pipe)
ok(!status || status == STATUS_PENDING, "NtFsControlFile failed: %x\n", status);
ok(buf.ReadDataAvailable == 1, "ReadDataAvailable = %u\n", buf.ReadDataAvailable);
ok(!iosb.Status, "iosb.Status = %x\n", iosb.Status);
todo_wine
todo_wine_if(!is_msgmode)
ok(is_signaled(event), "event is not signaled\n");
CloseHandle(event);
@ -855,7 +855,7 @@ static void read_pipe_test(ULONG pipe_flags, ULONG pipe_type)
ret = WriteFile( write, buffer, 1, &written, NULL );
ok(ret && written == 1, "WriteFile error %d\n", GetLastError());
test_peek(read);
test_peek(read, pipe_type & PIPE_TYPE_MESSAGE);
status = NtReadFile( read, event, apc, &apc_count, &iosb, buffer, 1, NULL, NULL );
ok( status == STATUS_SUCCESS, "wrong status %x\n", status );

View File

@ -177,7 +177,7 @@ static enum server_fd_type device_file_get_fd_type( struct fd *fd );
static int device_file_read( struct fd *fd, struct async *async, file_pos_t pos );
static int device_file_write( struct fd *fd, struct async *async, file_pos_t pos );
static obj_handle_t device_file_flush( struct fd *fd, struct async *async );
static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static int device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static const struct object_ops device_file_ops =
{
@ -546,7 +546,7 @@ static obj_handle_t device_file_flush( struct fd *fd, struct async *async )
return handle;
}
static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
static int device_file_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct device_file *file = get_fd_user( fd );
struct irp_call *irp;
@ -561,7 +561,7 @@ static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, struct
irp = create_irp( file, &params, async );
if (!irp) return 0;
handle = queue_irp( file, irp, async, 1 );
handle = queue_irp( file, irp, async, 0 );
release_object( irp );
return handle;
}

View File

@ -2179,20 +2179,20 @@ obj_handle_t no_fd_flush( struct fd *fd, struct async *async )
}
/* default ioctl() routine */
obj_handle_t no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
int no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
return 0;
}
/* default ioctl() routine */
obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
int default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
switch(code)
{
case FSCTL_DISMOUNT_VOLUME:
unmount_device( fd );
return 0;
return 1;
default:
set_error( STATUS_NOT_SUPPORTED );
return 0;
@ -2481,20 +2481,15 @@ DECL_HANDLER(ioctl)
unsigned int access = (req->code >> 14) & (FILE_READ_DATA|FILE_WRITE_DATA);
struct fd *fd = get_handle_fd_obj( current->process, req->async.handle, access );
struct async *async;
struct iosb *iosb;
if (!fd) return;
if ((iosb = create_iosb( get_req_data(), get_req_data_size(), get_reply_max_size() )))
if ((async = create_request_async( fd, &req->async )))
{
if ((async = create_async( fd, current, &req->async, iosb )))
{
reply->wait = fd->fd_ops->ioctl( fd, req->code, async );
reply->wait = async_handoff( async, fd->fd_ops->ioctl( fd, req->code, async ), NULL );
reply->options = fd->options;
release_object( async );
}
release_object( iosb );
}
release_object( fd );
}

View File

@ -58,7 +58,7 @@ struct fd_ops
/* flush the object buffers */
obj_handle_t (*flush)(struct fd *, struct async *);
/* perform an ioctl on the file */
obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, struct async *async );
int (*ioctl)(struct fd *fd, ioctl_code_t code, struct async *async );
/* queue an async operation */
void (*queue_async)(struct fd *, struct async *async, int type, int count);
/* selected events for async i/o need an update */
@ -103,8 +103,8 @@ extern void fd_reselect_async( struct fd *fd, struct async_queue *queue );
extern int no_fd_read( struct fd *fd, struct async *async, file_pos_t pos );
extern int no_fd_write( struct fd *fd, struct async *async, file_pos_t pos );
extern obj_handle_t no_fd_flush( struct fd *fd, struct async *async );
extern obj_handle_t no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
extern int no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
extern int default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
extern void no_fd_queue_async( struct fd *fd, struct async *async, int type, int count );
extern void default_fd_queue_async( struct fd *fd, struct async *async, int type, int count );
extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue );

View File

@ -164,7 +164,7 @@ static void pipe_server_dump( struct object *obj, int verbose );
static struct fd *pipe_server_get_fd( struct object *obj );
static void pipe_server_destroy( struct object *obj);
static obj_handle_t pipe_server_flush( struct fd *fd, struct async *async );
static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static const struct object_ops pipe_server_ops =
{
@ -207,7 +207,7 @@ static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *en
static struct fd *pipe_client_get_fd( struct object *obj );
static void pipe_client_destroy( struct object *obj );
static obj_handle_t pipe_client_flush( struct fd *fd, struct async *async );
static obj_handle_t pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static int pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static const struct object_ops pipe_client_ops =
{
@ -253,8 +253,7 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned
unsigned int sharing, unsigned int options );
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,
struct async *async );
static int named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static const struct object_ops named_pipe_device_ops =
{
@ -889,7 +888,7 @@ static enum server_fd_type pipe_end_get_fd_type( struct fd *fd )
return FD_TYPE_PIPE;
}
static void pipe_end_peek( struct pipe_end *pipe_end )
static int pipe_end_peek( struct pipe_end *pipe_end )
{
unsigned reply_size = get_reply_max_size();
FILE_PIPE_PEEK_BUFFER *buffer;
@ -900,13 +899,13 @@ static void pipe_end_peek( struct pipe_end *pipe_end )
if (!use_server_io( pipe_end ))
{
set_error( STATUS_NOT_SUPPORTED );
return;
return 0;
}
if (reply_size < offsetof( FILE_PIPE_PEEK_BUFFER, Data ))
{
set_error( STATUS_INFO_LENGTH_MISMATCH );
return;
return 0;
}
reply_size -= offsetof( FILE_PIPE_PEEK_BUFFER, Data );
@ -921,18 +920,18 @@ static void pipe_end_peek( struct pipe_end *pipe_end )
}
else reply_size = 0;
if (!(buffer = set_reply_data_size( offsetof( FILE_PIPE_PEEK_BUFFER, Data[reply_size] )))) return;
if (!(buffer = set_reply_data_size( offsetof( FILE_PIPE_PEEK_BUFFER, Data[reply_size] )))) return 0;
buffer->NamedPipeState = 0; /* FIXME */
buffer->ReadDataAvailable = avail;
buffer->NumberOfMessages = 0; /* FIXME */
buffer->MessageLength = message_length;
if (reply_size) memcpy( buffer->Data, (const char *)message->iosb->in_data + message->read_pos, reply_size );
return 1;
}
static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct pipe_server *server = get_fd_user( fd );
obj_handle_t wait_handle = 0;
switch(code)
{
@ -943,11 +942,10 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct
case ps_wait_connect:
if (fd_queue_async( server->ioctl_fd, async, ASYNC_TYPE_WAIT ))
{
if (async_is_blocking( async )) wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 );
set_server_state( server, ps_wait_open );
if (server->pipe->waiters) async_wake_up( server->pipe->waiters, STATUS_SUCCESS );
set_error( STATUS_PENDING );
return wait_handle;
return 1;
}
break;
case ps_connected_server:
@ -987,31 +985,29 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct
case ps_idle_server:
case ps_wait_open:
set_error( STATUS_PIPE_LISTENING );
break;
return 0;
case ps_wait_connect:
set_error( STATUS_PIPE_DISCONNECTED );
break;
}
return 0;
}
return 1;
case FSCTL_PIPE_PEEK:
pipe_end_peek( &server->pipe_end );
return 0;
return pipe_end_peek( &server->pipe_end );
default:
return default_fd_ioctl( fd, code, async );
}
}
static obj_handle_t pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
static int pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct pipe_client *client = get_fd_user( fd );
switch(code)
{
case FSCTL_PIPE_PEEK:
pipe_end_peek( &client->pipe_end );
return 0;
return pipe_end_peek( &client->pipe_end );
default:
return default_fd_ioctl( fd, code, async );
@ -1211,7 +1207,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
return &client->pipe_end.obj;
}
static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
static int named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct named_pipe_device *device = get_fd_user( fd );
@ -1221,7 +1217,6 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, s
{
const FILE_PIPE_WAIT_FOR_BUFFER *buffer = get_req_data();
data_size_t size = get_req_data_size();
obj_handle_t wait_handle = 0;
struct named_pipe *pipe;
struct pipe_server *server;
struct unicode_str name;
@ -1244,14 +1239,15 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, s
queue_async( pipe->waiters, async );
when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout;
async_set_timeout( async, when, STATUS_IO_TIMEOUT );
if (async_is_blocking( async )) wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 );
release_object( pipe );
set_error( STATUS_PENDING );
return 1;
}
else release_object( server );
done:
release_object( pipe );
return wait_handle;
return 0;
}
default:

View File

@ -63,7 +63,7 @@ static struct fd *serial_get_fd( struct object *obj );
static void serial_destroy(struct object *obj);
static enum server_fd_type serial_get_fd_type( struct fd *fd );
static obj_handle_t serial_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static int serial_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static void serial_queue_async( struct fd *fd, struct async *async, int type, int count );
static void serial_reselect_async( struct fd *fd, struct async_queue *queue );
@ -175,42 +175,49 @@ static enum server_fd_type serial_get_fd_type( struct fd *fd )
return FD_TYPE_SERIAL;
}
static obj_handle_t serial_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
static int serial_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct serial *serial = get_fd_user( fd );
switch (code)
{
case IOCTL_SERIAL_GET_TIMEOUTS:
if (get_reply_max_size() >= sizeof(serial->timeouts))
set_reply_data( &serial->timeouts, sizeof(serial->timeouts ));
else
if (get_reply_max_size() < sizeof(serial->timeouts))
{
set_error( STATUS_BUFFER_TOO_SMALL );
return 0;
}
set_reply_data( &serial->timeouts, sizeof(serial->timeouts ));
return 1;
case IOCTL_SERIAL_SET_TIMEOUTS:
if (get_req_data_size() >= sizeof(serial->timeouts))
memcpy( &serial->timeouts, get_req_data(), sizeof(serial->timeouts) );
else
if (get_req_data_size() < sizeof(serial->timeouts))
{
set_error( STATUS_BUFFER_TOO_SMALL );
return 0;
}
memcpy( &serial->timeouts, get_req_data(), sizeof(serial->timeouts) );
return 1;
case IOCTL_SERIAL_GET_WAIT_MASK:
if (get_reply_max_size() >= sizeof(serial->eventmask))
set_reply_data( &serial->eventmask, sizeof(serial->eventmask) );
else
if (get_reply_max_size() < sizeof(serial->eventmask))
{
set_error( STATUS_BUFFER_TOO_SMALL );
return 0;
}
set_reply_data( &serial->eventmask, sizeof(serial->eventmask) );
return 1;
case IOCTL_SERIAL_SET_WAIT_MASK:
if (get_req_data_size() >= sizeof(serial->eventmask))
if (get_req_data_size() < sizeof(serial->eventmask))
{
set_error( STATUS_BUFFER_TOO_SMALL );
return 0;
}
serial->eventmask = *(unsigned int *)get_req_data();
serial->generation++;
fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
}
else set_error( STATUS_BUFFER_TOO_SMALL );
return 0;
return 1;
default:
set_error( STATUS_NOT_SUPPORTED );

View File

@ -129,7 +129,7 @@ static void sock_destroy_ifchange_q( struct sock *sock );
static int sock_get_poll_events( struct fd *fd );
static void sock_poll_event( struct fd *fd, int event );
static enum server_fd_type sock_get_fd_type( struct fd *fd );
static obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
static void sock_queue_async( struct fd *fd, struct async *async, int type, int count );
static void sock_reselect_async( struct fd *fd, struct async_queue *queue );
@ -534,10 +534,9 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd )
return FD_TYPE_SOCKET;
}
obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct sock *sock = get_fd_user( fd );
obj_handle_t wait_handle = 0;
struct async_queue *ifchange_q;
assert( sock->obj.ops == &sock_ops );
@ -552,9 +551,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
}
if (!(ifchange_q = sock_get_ifchange_q( sock ))) return 0;
queue_async( ifchange_q, async );
if (async_is_blocking( async )) wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 );
set_error( STATUS_PENDING );
return wait_handle;
return 1;
default:
set_error( STATUS_NOT_SUPPORTED );
return 0;