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:
parent
4e02a3bb13
commit
c56c42ff79
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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, ¶ms, async );
|
||||
if (!irp) return 0;
|
||||
|
||||
handle = queue_irp( file, irp, async, 1 );
|
||||
handle = queue_irp( file, irp, async, 0 );
|
||||
release_object( irp );
|
||||
return handle;
|
||||
}
|
||||
|
|
19
server/fd.c
19
server/fd.c
|
@ -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,19 +2481,14 @@ 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->options = fd->options;
|
||||
release_object( async );
|
||||
}
|
||||
release_object( iosb );
|
||||
reply->wait = async_handoff( async, fd->fd_ops->ioctl( fd, req->code, async ), NULL );
|
||||
reply->options = fd->options;
|
||||
release_object( async );
|
||||
}
|
||||
release_object( fd );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 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:
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
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;
|
||||
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))
|
||||
{
|
||||
serial->eventmask = *(unsigned int *)get_req_data();
|
||||
serial->generation++;
|
||||
fd_async_wake_up( serial->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
||||
set_error( STATUS_BUFFER_TOO_SMALL );
|
||||
return 0;
|
||||
}
|
||||
else 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 );
|
||||
return 1;
|
||||
|
||||
default:
|
||||
set_error( STATUS_NOT_SUPPORTED );
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue