Jacek Caban : server: Add support for querying FileNameInformation on named pipes.

Alexandre Julliard julliard at winehq.org
Fri Dec 22 11:15:05 CST 2017


Module: wine
Branch: master
Commit: d4d6330f0a9eb244b52edd25e0b6998223eb5417
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d4d6330f0a9eb244b52edd25e0b6998223eb5417

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Dec 21 16:12:12 2017 +0100

server: Add support for querying FileNameInformation on named pipes.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/pipe.c |  3 ---
 server/named_pipe.c     | 55 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index b0863ea..a878d8a 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -1168,9 +1168,7 @@ static void _test_file_name(unsigned line, HANDLE pipe)
     memset( buffer, 0xaa, sizeof(buffer) );
     memset( &iosb, 0xaa, sizeof(iosb) );
     status = NtQueryInformationFile( pipe, &iosb, buffer, sizeof(buffer), FileNameInformation );
-    todo_wine
     ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryInformationFile failed: %x\n", status );
-    if (status) return;
     ok_(__FILE__,line)( iosb.Status == STATUS_SUCCESS, "Status = %x\n", iosb.Status );
     ok_(__FILE__,line)( iosb.Information == sizeof(name_info->FileNameLength) + sizeof(nameW),
         "Information = %lu\n", iosb.Information );
@@ -1205,7 +1203,6 @@ static void test_file_info(void)
     test_file_name( server );
 
     DisconnectNamedPipe( server );
-    todo_wine
     test_file_name_fail( client, STATUS_PIPE_DISCONNECTED );
 
     CloseHandle( server );
diff --git a/server/named_pipe.c b/server/named_pipe.c
index febf2e3..c6b37ce 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -152,6 +152,7 @@ static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue );
 static void pipe_server_dump( struct object *obj, int verbose );
 static void pipe_server_destroy( struct object *obj);
 static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
+static void pipe_server_get_file_info( struct fd *fd, unsigned int info_class );
 
 static const struct object_ops pipe_server_ops =
 {
@@ -183,7 +184,7 @@ static const struct fd_ops pipe_server_fd_ops =
     pipe_end_read,                /* read */
     pipe_end_write,               /* write */
     pipe_end_flush,               /* flush */
-    no_fd_get_file_info,          /* get_file_info */
+    pipe_server_get_file_info,    /* get_file_info */
     pipe_end_get_volume_info,     /* get_volume_info */
     pipe_server_ioctl,            /* ioctl */
     no_fd_queue_async,            /* queue_async */
@@ -194,6 +195,7 @@ static const struct fd_ops pipe_server_fd_ops =
 static void pipe_client_dump( struct object *obj, int verbose );
 static void pipe_client_destroy( struct object *obj );
 static int pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
+static void pipe_client_get_file_info( struct fd *fd, unsigned int info_class );
 
 static const struct object_ops pipe_client_ops =
 {
@@ -225,7 +227,7 @@ static const struct fd_ops pipe_client_fd_ops =
     pipe_end_read,                /* read */
     pipe_end_write,               /* write */
     pipe_end_flush,               /* flush */
-    no_fd_get_file_info,          /* get_file_info */
+    pipe_client_get_file_info,    /* get_file_info */
     pipe_end_get_volume_info,     /* get_volume_info */
     pipe_client_ioctl,            /* ioctl */
     no_fd_queue_async,            /* queue_async */
@@ -545,6 +547,55 @@ static int pipe_end_flush( struct fd *fd, struct async *async )
     return 1;
 }
 
+static void pipe_end_get_file_info( struct fd *fd, struct named_pipe *pipe, unsigned int info_class )
+{
+    switch (info_class)
+    {
+    case FileNameInformation:
+        {
+            FILE_NAME_INFORMATION *name_info;
+            data_size_t name_len, reply_size;
+            const WCHAR *name;
+
+            if (get_reply_max_size() < sizeof(*name_info))
+            {
+                set_error( STATUS_INFO_LENGTH_MISMATCH );
+                return;
+            }
+
+            name = get_object_name( &pipe->obj, &name_len );
+            reply_size = offsetof( FILE_NAME_INFORMATION, FileName[name_len/sizeof(WCHAR) + 1] );
+            if (reply_size > get_reply_max_size())
+            {
+                reply_size = get_reply_max_size();
+                set_error( STATUS_BUFFER_OVERFLOW );
+            }
+
+            if (!(name_info = set_reply_data_size( reply_size ))) return;
+            name_info->FileNameLength = name_len + sizeof(WCHAR);
+            name_info->FileName[0] = '\\';
+            reply_size -= offsetof( FILE_NAME_INFORMATION, FileName[1] );
+            if (reply_size) memcpy( &name_info->FileName[1], name, reply_size );
+            break;
+        }
+    default:
+        no_fd_get_file_info( fd, info_class );
+    }
+}
+
+static void pipe_server_get_file_info( struct fd *fd, unsigned int info_class )
+{
+    struct pipe_server *server = get_fd_user( fd );
+    pipe_end_get_file_info( fd, server->pipe, info_class );
+}
+
+static void pipe_client_get_file_info( struct fd *fd, unsigned int info_class )
+{
+    struct pipe_client *client = get_fd_user( fd );
+    if (client->server) pipe_end_get_file_info( fd, client->server->pipe, info_class );
+    else set_error( STATUS_PIPE_DISCONNECTED );
+}
+
 static void pipe_end_get_volume_info( struct fd *fd, unsigned int info_class )
 {
     switch (info_class)




More information about the wine-cvs mailing list