Jacek Caban : server: Added server-side FSCTL_PIPE_PEEK implementation.
Alexandre Julliard
julliard at winehq.org
Wed Mar 22 15:52:36 CDT 2017
Module: wine
Branch: master
Commit: 134c83203a03c08f50701f97cd08f1ce7b2a6847
URL: http://source.winehq.org/git/wine.git/?a=commit;h=134c83203a03c08f50701f97cd08f1ce7b2a6847
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Mar 21 13:03:55 2017 +0100
server: Added server-side FSCTL_PIPE_PEEK implementation.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/file.c | 5 +++++
server/named_pipe.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index c2678d5..c153e7b 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1727,7 +1727,12 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
}
if ((status = server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, NULL, NULL )))
+ {
+ if (status == STATUS_BAD_DEVICE_TYPE)
+ status = server_ioctl_file( handle, event, apc, apc_context, io, code,
+ in_buffer, in_size, out_buffer, out_size );
break;
+ }
#ifdef FIONREAD
if (ioctl( fd, FIONREAD, &avail ) != 0)
diff --git a/server/named_pipe.c b/server/named_pipe.c
index adc27ca..85521e0 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -208,6 +208,8 @@ 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, int blocking );
+static obj_handle_t pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async,
+ int blocking );
static enum server_fd_type pipe_client_get_fd_type( struct fd *fd );
static const struct object_ops pipe_client_ops =
@@ -240,7 +242,7 @@ static const struct fd_ops pipe_client_fd_ops =
no_fd_read, /* read */
pipe_end_write, /* write */
pipe_client_flush, /* flush */
- default_fd_ioctl, /* ioctl */
+ pipe_client_ioctl, /* ioctl */
pipe_end_queue_async, /* queue_async */
pipe_end_reselect_async /* reselect_async */
};
@@ -792,6 +794,44 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
return FD_TYPE_PIPE;
}
+static void pipe_end_peek( struct pipe_end *pipe_end )
+{
+ unsigned reply_size = get_reply_max_size();
+ FILE_PIPE_PEEK_BUFFER *buffer;
+ struct pipe_message *message;
+ data_size_t avail = 0;
+
+ if (!use_server_io( pipe_end ))
+ {
+ set_error( STATUS_NOT_SUPPORTED );
+ return;
+ }
+
+ if (reply_size < offsetof( FILE_PIPE_PEEK_BUFFER, Data ))
+ {
+ set_error( STATUS_INFO_LENGTH_MISMATCH );
+ return;
+ }
+ reply_size -= offsetof( FILE_PIPE_PEEK_BUFFER, Data );
+
+ LIST_FOR_EACH_ENTRY( message, &pipe_end->message_queue, struct pipe_message, entry )
+ avail += message->iosb->in_size - message->read_pos;
+
+ if (avail)
+ {
+ message = LIST_ENTRY( list_head(&pipe_end->message_queue), struct pipe_message, entry );
+ reply_size = min( reply_size, message->iosb->in_size - message->read_pos );
+ }
+ else reply_size = 0;
+
+ if (!(buffer = set_reply_data_size( offsetof( FILE_PIPE_PEEK_BUFFER, Data[reply_size] )))) return;
+ buffer->NamedPipeState = 0; /* FIXME */
+ buffer->ReadDataAvailable = avail;
+ buffer->NumberOfMessages = 0; /* FIXME */
+ buffer->MessageLength = 0; /* FIXME */
+ if (reply_size) memcpy( buffer->Data, (const char *)message->iosb->in_data + message->read_pos, reply_size );
+}
+
static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async,
int blocking )
{
@@ -858,6 +898,26 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct
}
return 0;
+ case FSCTL_PIPE_PEEK:
+ pipe_end_peek( &server->pipe_end );
+ return 0;
+
+ default:
+ return default_fd_ioctl( fd, code, async, blocking );
+ }
+}
+
+static obj_handle_t pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async,
+ int blocking )
+{
+ struct pipe_client *client = get_fd_user( fd );
+
+ switch(code)
+ {
+ case FSCTL_PIPE_PEEK:
+ pipe_end_peek( &client->pipe_end );
+ return 0;
+
default:
return default_fd_ioctl( fd, code, async, blocking );
}
More information about the wine-cvs
mailing list