[PATCH] server: Use a separate object for each opened mailslot device file.

Zebediah Figura z.figura12 at gmail.com
Sat Aug 1 23:35:53 CDT 2020


This is essentially a straight port of 2600ecd4ed.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/ntdll/tests/file.c |   4 +-
 dlls/ntdll/tests/om.c   |   4 +-
 server/mailslot.c       | 117 +++++++++++++++++++++++++++++-----------
 3 files changed, 89 insertions(+), 36 deletions(-)

diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 9c749ace1fe..8b9ec4f624d 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -3813,7 +3813,6 @@ static void test_file_mode(void)
         UNICODE_STRING *file_name;
         ULONG options;
         ULONG mode;
-        BOOL todo;
     } option_tests[] = {
         { &file_name, 0, 0 },
         { &file_name, FILE_NON_DIRECTORY_FILE, 0 },
@@ -3827,7 +3826,7 @@ static void test_file_mode(void)
         { &pipe_dev_name, 0, 0 },
         { &pipe_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT },
         { &mailslot_dev_name, 0, 0 },
-        { &mailslot_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT, TRUE },
+        { &mailslot_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT },
         { &mountmgr_dev_name, 0, 0 },
         { &mountmgr_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT }
     };
@@ -3879,7 +3878,6 @@ static void test_file_mode(void)
         memset(&mode, 0xcc, sizeof(mode));
         status = pNtQueryInformationFile(file, &io, &mode, sizeof(mode), FileModeInformation);
         ok(status == STATUS_SUCCESS, "[%u] can't get FileModeInformation: %x\n", i, status);
-        todo_wine_if(option_tests[i].todo)
         ok(mode.Mode == option_tests[i].mode, "[%u] Mode = %x, expected %x\n",
            i, mode.Mode, option_tests[i].mode);
 
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index c83052d2881..a9da114cb5c 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -1445,8 +1445,8 @@ static void test_query_object(void)
     handle = CreateFileA( "\\\\.\\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
     ok( handle != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError() );
 
-    test_object_name( handle, L"\\Device\\Mailslot", FALSE );
-    test_object_type_todo( handle, L"File" );
+    test_object_name( handle, L"\\Device\\Mailslot", TRUE );
+    test_object_type( handle, L"File" );
     test_file_info( handle );
 
     pNtClose( handle );
diff --git a/server/mailslot.c b/server/mailslot.c
index 781e6f3141a..58d650cbb25 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -171,19 +171,23 @@ static const struct fd_ops mail_writer_fd_ops =
 struct mailslot_device
 {
     struct object       obj;         /* object header */
-    struct fd          *fd;          /* pseudo-fd for ioctls */
     struct namespace   *mailslots;   /* mailslot namespace */
 };
 
+struct mailslot_device_file
+{
+    struct object           obj;    /* object header */
+    struct fd              *fd;     /* pseudo-fd for ioctls */
+    struct mailslot_device *device; /* mailslot device */
+};
+
 static void mailslot_device_dump( struct object *obj, int verbose );
 static struct object_type *mailslot_device_get_type( struct object *obj );
-static struct fd *mailslot_device_get_fd( struct object *obj );
 static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name,
                                                    unsigned int attr );
 static struct object *mailslot_device_open_file( struct object *obj, unsigned int access,
                                                  unsigned int sharing, unsigned int options );
 static void mailslot_device_destroy( struct object *obj );
-static enum server_fd_type mailslot_device_get_fd_type( struct fd *fd );
 
 static const struct object_ops mailslot_device_ops =
 {
@@ -195,7 +199,7 @@ static const struct object_ops mailslot_device_ops =
     NULL,                           /* signaled */
     no_satisfied,                   /* satisfied */
     no_signal,                      /* signal */
-    mailslot_device_get_fd,         /* get_fd */
+    no_get_fd,                      /* get_fd */
     no_map_access,                  /* map_access */
     default_get_sd,                 /* get_sd */
     default_set_sd,                 /* set_sd */
@@ -204,23 +208,51 @@ static const struct object_ops mailslot_device_ops =
     default_unlink_name,            /* unlink_name */
     mailslot_device_open_file,      /* open_file */
     no_kernel_obj_list,             /* get_kernel_obj_list */
-    fd_close_handle,                /* close_handle */
+    no_close_handle,                /* close_handle */
     mailslot_device_destroy         /* destroy */
 };
 
+static void mailslot_device_file_dump( struct object *obj, int verbose );
+static struct fd *mailslot_device_file_get_fd( struct object *obj );
+static void mailslot_device_file_destroy( struct object *obj );
+static enum server_fd_type mailslot_device_file_get_fd_type( struct fd *fd );
+
+static const struct object_ops mailslot_device_file_ops =
+{
+    sizeof(struct mailslot_device_file),    /* size */
+    mailslot_device_file_dump,              /* dump */
+    file_get_type,                          /* get_type */
+    add_queue,                              /* add_queue */
+    remove_queue,                           /* remove_queue */
+    default_fd_signaled,                    /* signaled */
+    no_satisfied,                           /* satisfied */
+    no_signal,                              /* signal */
+    mailslot_device_file_get_fd,            /* get_fd */
+    default_fd_map_access,                  /* map_access */
+    default_get_sd,                         /* get_sd */
+    default_set_sd,                         /* set_sd */
+    no_lookup_name,                         /* lookup_name */
+    no_link_name,                           /* link_name */
+    NULL,                                   /* unlink_name */
+    no_open_file,                           /* open_file */
+    no_kernel_obj_list,                     /* get_kernel_obj_list */
+    fd_close_handle,                        /* close_handle */
+    mailslot_device_file_destroy            /* destroy */
+};
+
 static const struct fd_ops mailslot_device_fd_ops =
 {
-    default_fd_get_poll_events,     /* get_poll_events */
-    default_poll_event,             /* poll_event */
-    mailslot_device_get_fd_type,    /* get_fd_type */
-    no_fd_read,                     /* read */
-    no_fd_write,                    /* write */
-    no_fd_flush,                    /* flush */
-    default_fd_get_file_info,       /* get_file_info */
-    no_fd_get_volume_info,          /* get_volume_info */
-    default_fd_ioctl,               /* ioctl */
-    default_fd_queue_async,         /* queue_async */
-    default_fd_reselect_async       /* reselect_async */
+    default_fd_get_poll_events,         /* get_poll_events */
+    default_poll_event,                 /* poll_event */
+    mailslot_device_file_get_fd_type,   /* get_fd_type */
+    no_fd_read,                         /* read */
+    no_fd_write,                        /* write */
+    no_fd_flush,                        /* flush */
+    default_fd_get_file_info,           /* get_file_info */
+    no_fd_get_volume_info,              /* get_volume_info */
+    default_fd_ioctl,                   /* ioctl */
+    default_fd_queue_async,             /* queue_async */
+    default_fd_reselect_async           /* reselect_async */
 };
 
 static void mailslot_destroy( struct object *obj)
@@ -357,12 +389,6 @@ static struct object_type *mailslot_device_get_type( struct object *obj )
     return get_object_type( &str );
 }
 
-static struct fd *mailslot_device_get_fd( struct object *obj )
-{
-    struct mailslot_device *device = (struct mailslot_device *)obj;
-    return (struct fd *)grab_object( device->fd );
-}
-
 static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name,
                                                    unsigned int attr )
 {
@@ -382,22 +408,26 @@ static struct object *mailslot_device_lookup_name( struct object *obj, struct un
 static struct object *mailslot_device_open_file( struct object *obj, unsigned int access,
                                                  unsigned int sharing, unsigned int options )
 {
-    return grab_object( obj );
+    struct mailslot_device_file *file;
+
+    if (!(file = alloc_object( &mailslot_device_file_ops ))) return NULL;
+    file->device = (struct mailslot_device *)grab_object( obj );
+    if (!(file->fd = alloc_pseudo_fd( &mailslot_device_fd_ops, obj, options )))
+    {
+        release_object( file );
+        return NULL;
+    }
+    allow_fd_caching( file->fd );
+    return &file->obj;
 }
 
 static void mailslot_device_destroy( struct object *obj )
 {
     struct mailslot_device *device = (struct mailslot_device*)obj;
     assert( obj->ops == &mailslot_device_ops );
-    if (device->fd) release_object( device->fd );
     free( device->mailslots );
 }
 
-static enum server_fd_type mailslot_device_get_fd_type( struct fd *fd )
-{
-    return FD_TYPE_DEVICE;
-}
-
 struct object *create_mailslot_device( struct object *root, const struct unicode_str *name )
 {
     struct mailslot_device *dev;
@@ -406,8 +436,7 @@ struct object *create_mailslot_device( struct object *root, const struct unicode
         get_error() != STATUS_OBJECT_NAME_EXISTS)
     {
         dev->mailslots = NULL;
-        if (!(dev->fd = alloc_pseudo_fd( &mailslot_device_fd_ops, &dev->obj, 0 )) ||
-            !(dev->mailslots = create_namespace( 7 )))
+        if (!(dev->mailslots = create_namespace( 7 )))
         {
             release_object( dev );
             dev = NULL;
@@ -416,6 +445,32 @@ struct object *create_mailslot_device( struct object *root, const struct unicode
     return &dev->obj;
 }
 
+static void mailslot_device_file_dump( struct object *obj, int verbose )
+{
+    struct mailslot_device_file *file = (struct mailslot_device_file *)obj;
+
+    fprintf( stderr, "File on mailslot device %p\n", file->device );
+}
+
+static struct fd *mailslot_device_file_get_fd( struct object *obj )
+{
+    struct mailslot_device_file *file = (struct mailslot_device_file *)obj;
+    return (struct fd *)grab_object( file->fd );
+}
+
+static void mailslot_device_file_destroy( struct object *obj )
+{
+    struct mailslot_device_file *file = (struct mailslot_device_file*)obj;
+    assert( obj->ops == &mailslot_device_file_ops );
+    if (file->fd) release_object( file->fd );
+    release_object( file->device );
+}
+
+static enum server_fd_type mailslot_device_file_get_fd_type( struct fd *fd )
+{
+    return FD_TYPE_DEVICE;
+}
+
 static struct mailslot *create_mailslot( struct object *root,
                                          const struct unicode_str *name, unsigned int attr,
                                          int max_msgsize, timeout_t read_timeout,
-- 
2.27.0




More information about the wine-devel mailing list