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 };
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);
}
}

View File

@ -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 },

View File

@ -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 );