Jacek Caban : server: Add FSCTL_PIPE_TRANSCEIVE implementation.
Alexandre Julliard
julliard at winehq.org
Thu Mar 29 19:13:28 CDT 2018
Module: wine
Branch: master
Commit: c9833f89e50d34b57c42b7e34cbf08e1a2f2279c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c9833f89e50d34b57c42b7e34cbf08e1a2f2279c
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Mar 28 22:46:38 2018 +0200
server: Add FSCTL_PIPE_TRANSCEIVE implementation.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/named_pipe.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 8 deletions(-)
diff --git a/server/named_pipe.c b/server/named_pipe.c
index d7467dc..3d260c7 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -900,6 +900,61 @@ static int pipe_end_peek( struct pipe_end *pipe_end )
return 1;
}
+static int pipe_end_transceive( struct pipe_end *pipe_end, struct async *async )
+{
+ struct pipe_message *message;
+ struct iosb *iosb;
+
+ if ((pipe_end->flags & (NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ))
+ != (NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ))
+ {
+ set_error( STATUS_INVALID_READ_MODE );
+ return 0;
+ }
+
+ if (!pipe_end->connection)
+ {
+ set_error( STATUS_PIPE_BROKEN );
+ return 0;
+ }
+
+ /* not allowed if we already have read data buffered */
+ if (!list_empty( &pipe_end->message_queue ))
+ {
+ set_error( STATUS_PIPE_BUSY );
+ return 0;
+ }
+
+ iosb = async_get_iosb( async );
+ /* ignore output buffer copy transferred because of METHOD_NEITHER */
+ iosb->in_size -= iosb->out_size;
+ /* transaction never blocks on write, so just queue a message without async */
+ message = queue_message( pipe_end->connection, iosb );
+ release_object( iosb );
+ if (!message) return 0;
+ reselect_read_queue( pipe_end->connection );
+
+ queue_async( &pipe_end->read_q, async );
+ reselect_read_queue( pipe_end );
+ set_error( STATUS_PENDING );
+ return 1;
+}
+
+static int pipe_end_ioctl( struct pipe_end *pipe_end, ioctl_code_t code, struct async *async )
+{
+ switch(code)
+ {
+ case FSCTL_PIPE_PEEK:
+ return pipe_end_peek( pipe_end );
+
+ case FSCTL_PIPE_TRANSCEIVE:
+ return pipe_end_transceive( pipe_end, async );
+
+ default:
+ return default_fd_ioctl( pipe_end->fd, code, async );
+ }
+}
+
static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
struct pipe_server *server = get_fd_user( fd );
@@ -955,11 +1010,8 @@ static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *as
}
return 1;
- case FSCTL_PIPE_PEEK:
- return pipe_end_peek( &server->pipe_end );
-
default:
- return default_fd_ioctl( fd, code, async );
+ return pipe_end_ioctl( &server->pipe_end, code, async );
}
}
@@ -973,11 +1025,8 @@ static int pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *as
set_error( STATUS_ILLEGAL_FUNCTION );
return 0;
- case FSCTL_PIPE_PEEK:
- return pipe_end_peek( &client->pipe_end );
-
default:
- return default_fd_ioctl( fd, code, async );
+ return pipe_end_ioctl( &client->pipe_end, code, async );
}
}
More information about the wine-cvs
mailing list