server: Use a separated object for each opened named pipe device file.

Allows using proper options for ioctl pseudo fd.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2018-10-29 15:49:47 +01:00 committed by Alexandre Julliard
parent f003ac5e62
commit 2600ecd4ed
3 changed files with 94 additions and 42 deletions

View file

@ -5523,14 +5523,14 @@ static void test_named_pipe_security(HANDLE token)
STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }; STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS };
static const struct static const struct
{ {
int todo, generic, mapped; int generic, mapped;
} map[] = } map[] =
{ {
{ 0, 0, 0 }, { 0, 0 },
{ 1, GENERIC_READ, FILE_GENERIC_READ }, { GENERIC_READ, FILE_GENERIC_READ },
{ 1, GENERIC_WRITE, FILE_GENERIC_WRITE }, { GENERIC_WRITE, FILE_GENERIC_WRITE },
{ 1, GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, { GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
{ 1, GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } { GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
}; };
static const struct static const struct
{ {
@ -5610,9 +5610,7 @@ static void test_named_pipe_security(HANDLE token)
ok(ret, "DuplicateHandle error %d\n", GetLastError()); ok(ret, "DuplicateHandle error %d\n", GetLastError());
access = get_obj_access(dup); 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); CloseHandle(dup);
} }
} }

View file

@ -3574,7 +3574,7 @@ static void test_file_mode(void)
{ &file_name, FILE_DELETE_ON_CLOSE, 0 }, { &file_name, FILE_DELETE_ON_CLOSE, 0 },
{ &file_name, FILE_RANDOM_ACCESS | FILE_NO_COMPRESSION, 0 }, { &file_name, FILE_RANDOM_ACCESS | FILE_NO_COMPRESSION, 0 },
{ &pipe_dev_name, 0, 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, 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, TRUE },
{ &mountmgr_dev_name, 0, 0 }, { &mountmgr_dev_name, 0, 0 },

View file

@ -99,10 +99,16 @@ struct named_pipe
struct named_pipe_device struct named_pipe_device
{ {
struct object obj; /* object header */ struct object obj; /* object header */
struct fd *fd; /* pseudo-fd for ioctls */
struct namespace *pipes; /* named pipe namespace */ 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 void named_pipe_dump( struct object *obj, int verbose );
static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ); 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 ); 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 void named_pipe_device_dump( struct object *obj, int verbose );
static struct object_type *named_pipe_device_get_type( struct object *obj ); 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, static struct object *named_pipe_device_lookup_name( struct object *obj,
struct unicode_str *name, unsigned int attr ); struct unicode_str *name, unsigned int attr );
static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access, static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options ); unsigned int sharing, unsigned int options );
static void named_pipe_device_destroy( struct object *obj ); 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 = static const struct object_ops named_pipe_device_ops =
{ {
@ -251,7 +254,7 @@ static const struct object_ops named_pipe_device_ops =
NULL, /* signaled */ NULL, /* signaled */
no_satisfied, /* satisfied */ no_satisfied, /* satisfied */
no_signal, /* signal */ no_signal, /* signal */
named_pipe_device_get_fd, /* get_fd */ no_get_fd, /* get_fd */
no_map_access, /* map_access */ no_map_access, /* map_access */
default_get_sd, /* get_sd */ default_get_sd, /* get_sd */
default_set_sd, /* set_sd */ default_set_sd, /* set_sd */
@ -259,23 +262,51 @@ static const struct object_ops named_pipe_device_ops =
directory_link_name, /* link_name */ directory_link_name, /* link_name */
default_unlink_name, /* unlink_name */ default_unlink_name, /* unlink_name */
named_pipe_device_open_file, /* open_file */ named_pipe_device_open_file, /* open_file */
fd_close_handle, /* close_handle */ no_close_handle, /* close_handle */
named_pipe_device_destroy /* destroy */ 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 = static const struct fd_ops named_pipe_device_fd_ops =
{ {
default_fd_get_poll_events, /* get_poll_events */ default_fd_get_poll_events, /* get_poll_events */
default_poll_event, /* poll_event */ default_poll_event, /* poll_event */
named_pipe_device_get_fd_type, /* get_fd_type */ named_pipe_device_file_get_fd_type, /* get_fd_type */
no_fd_read, /* read */ no_fd_read, /* read */
no_fd_write, /* write */ no_fd_write, /* write */
no_fd_flush, /* flush */ no_fd_flush, /* flush */
default_fd_get_file_info, /* get_file_info */ default_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */ no_fd_get_volume_info, /* get_volume_info */
named_pipe_device_ioctl, /* ioctl */ named_pipe_device_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */ default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */ default_fd_reselect_async /* reselect_async */
}; };
static void named_pipe_dump( struct object *obj, int verbose ) 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 ); 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, static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name,
unsigned int attr ) 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, static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options ) 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 ) static void named_pipe_device_destroy( struct object *obj )
{ {
struct named_pipe_device *device = (struct named_pipe_device*)obj; struct named_pipe_device *device = (struct named_pipe_device*)obj;
assert( obj->ops == &named_pipe_device_ops ); assert( obj->ops == &named_pipe_device_ops );
if (device->fd) release_object( device->fd );
free( device->pipes ); 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 object *create_named_pipe_device( struct object *root, const struct unicode_str *name )
{ {
struct named_pipe_device *dev; 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) get_error() != STATUS_OBJECT_NAME_EXISTS)
{ {
dev->pipes = NULL; dev->pipes = NULL;
if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj, 0 )) || if (!(dev->pipes = create_namespace( 7 )))
!(dev->pipes = create_namespace( 7 )))
{ {
release_object( dev ); release_object( dev );
dev = NULL; dev = NULL;
@ -497,6 +525,32 @@ struct object *create_named_pipe_device( struct object *root, const struct unico
return &dev->obj; 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 ) static int pipe_end_flush( struct fd *fd, struct async *async )
{ {
struct pipe_end *pipe_end = get_fd_user( fd ); struct pipe_end *pipe_end = get_fd_user( fd );