diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 344f66049b5..d9cae64da8b 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -5523,14 +5523,14 @@ static void test_named_pipe_security(HANDLE token) STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }; static const struct { - int todo, generic, mapped; + int generic, mapped; } map[] = { - { 0, 0, 0 }, - { 1, GENERIC_READ, FILE_GENERIC_READ }, - { 1, GENERIC_WRITE, FILE_GENERIC_WRITE }, - { 1, GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, - { 1, GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } + { 0, 0 }, + { GENERIC_READ, FILE_GENERIC_READ }, + { GENERIC_WRITE, FILE_GENERIC_WRITE }, + { GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, + { GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } }; static const struct { @@ -5610,9 +5610,7 @@ static void test_named_pipe_security(HANDLE token) ok(ret, "DuplicateHandle error %d\n", GetLastError()); access = get_obj_access(dup); - todo_wine_if (map[i].todo) - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); - + ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); CloseHandle(dup); } } diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index e84324c6bec..56a438b9733 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3574,7 +3574,7 @@ static void test_file_mode(void) { &file_name, FILE_DELETE_ON_CLOSE, 0 }, { &file_name, FILE_RANDOM_ACCESS | FILE_NO_COMPRESSION, 0 }, { &pipe_dev_name, 0, 0 }, - { &pipe_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT, TRUE }, + { &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 }, { &mountmgr_dev_name, 0, 0 }, diff --git a/server/named_pipe.c b/server/named_pipe.c index f643140637d..19a5426b1ff 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -99,10 +99,16 @@ struct named_pipe struct named_pipe_device { struct object obj; /* object header */ - struct fd *fd; /* pseudo-fd for ioctls */ struct namespace *pipes; /* named pipe namespace */ }; +struct named_pipe_device_file +{ + struct object obj; /* object header */ + struct fd *fd; /* pseudo-fd for ioctls */ + struct named_pipe_device *device; /* named pipe device */ +}; + static void named_pipe_dump( struct object *obj, int verbose ); static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ); static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent ); @@ -232,14 +238,11 @@ static const struct fd_ops pipe_client_fd_ops = static void named_pipe_device_dump( struct object *obj, int verbose ); static struct object_type *named_pipe_device_get_type( struct object *obj ); -static struct fd *named_pipe_device_get_fd( struct object *obj ); static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static void named_pipe_device_destroy( struct object *obj ); -static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd ); -static int named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); static const struct object_ops named_pipe_device_ops = { @@ -251,7 +254,7 @@ static const struct object_ops named_pipe_device_ops = NULL, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ - named_pipe_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 */ @@ -259,23 +262,51 @@ static const struct object_ops named_pipe_device_ops = directory_link_name, /* link_name */ default_unlink_name, /* unlink_name */ named_pipe_device_open_file, /* open_file */ - fd_close_handle, /* close_handle */ + no_close_handle, /* close_handle */ named_pipe_device_destroy /* destroy */ }; +static void named_pipe_device_file_dump( struct object *obj, int verbose ); +static struct fd *named_pipe_device_file_get_fd( struct object *obj ); +static int named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); +static enum server_fd_type named_pipe_device_file_get_fd_type( struct fd *fd ); +static void named_pipe_device_file_destroy( struct object *obj ); + +static const struct object_ops named_pipe_device_file_ops = +{ + sizeof(struct named_pipe_device_file), /* size */ + named_pipe_device_file_dump, /* dump */ + no_get_type, /* get_type */ + add_queue, /* add_queue */ + remove_queue, /* remove_queue */ + default_fd_signaled, /* signaled */ + no_satisfied, /* satisfied */ + no_signal, /* signal */ + named_pipe_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 */ + fd_close_handle, /* close_handle */ + named_pipe_device_file_destroy /* destroy */ +}; + static const struct fd_ops named_pipe_device_fd_ops = { - default_fd_get_poll_events, /* get_poll_events */ - default_poll_event, /* poll_event */ - named_pipe_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 */ - named_pipe_device_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 */ + named_pipe_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 */ + named_pipe_device_ioctl, /* ioctl */ + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async /* reselect_async */ }; static void named_pipe_dump( struct object *obj, int verbose ) @@ -437,12 +468,6 @@ static struct object_type *named_pipe_device_get_type( struct object *obj ) return get_object_type( &str ); } -static struct fd *named_pipe_device_get_fd( struct object *obj ) -{ - struct named_pipe_device *device = (struct named_pipe_device *)obj; - return (struct fd *)grab_object( device->fd ); -} - static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) { @@ -463,22 +488,26 @@ static struct object *named_pipe_device_lookup_name( struct object *obj, struct static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { - return grab_object( obj ); + struct named_pipe_device_file *file; + + if (!(file = alloc_object( &named_pipe_device_file_ops ))) return NULL; + file->device = (struct named_pipe_device *)grab_object( obj ); + if (!(file->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, obj, options ))) + { + release_object( file ); + return NULL; + } + allow_fd_caching( file->fd ); + return &file->obj; } static void named_pipe_device_destroy( struct object *obj ) { struct named_pipe_device *device = (struct named_pipe_device*)obj; assert( obj->ops == &named_pipe_device_ops ); - if (device->fd) release_object( device->fd ); free( device->pipes ); } -static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd ) -{ - return FD_TYPE_DEVICE; -} - struct object *create_named_pipe_device( struct object *root, const struct unicode_str *name ) { struct named_pipe_device *dev; @@ -487,8 +516,7 @@ struct object *create_named_pipe_device( struct object *root, const struct unico get_error() != STATUS_OBJECT_NAME_EXISTS) { dev->pipes = NULL; - if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj, 0 )) || - !(dev->pipes = create_namespace( 7 ))) + if (!(dev->pipes = create_namespace( 7 ))) { release_object( dev ); dev = NULL; @@ -497,6 +525,32 @@ struct object *create_named_pipe_device( struct object *root, const struct unico return &dev->obj; } +static void named_pipe_device_file_dump( struct object *obj, int verbose ) +{ + struct named_pipe_device_file *file = (struct named_pipe_device_file *)obj; + + fprintf( stderr, "File on named pipe device %p\n", file->device ); +} + +static struct fd *named_pipe_device_file_get_fd( struct object *obj ) +{ + struct named_pipe_device_file *file = (struct named_pipe_device_file *)obj; + return (struct fd *)grab_object( file->fd ); +} + +static enum server_fd_type named_pipe_device_file_get_fd_type( struct fd *fd ) +{ + return FD_TYPE_DEVICE; +} + +static void named_pipe_device_file_destroy( struct object *obj ) +{ + struct named_pipe_device_file *file = (struct named_pipe_device_file*)obj; + assert( obj->ops == &named_pipe_device_file_ops ); + if (file->fd) release_object( file->fd ); + release_object( file->device ); +} + static int pipe_end_flush( struct fd *fd, struct async *async ) { struct pipe_end *pipe_end = get_fd_user( fd );