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