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:
parent
f003ac5e62
commit
2600ecd4ed
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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,15 +262,43 @@ 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 */
|
||||||
|
@ -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 );
|
||||||
|
|
Loading…
Reference in New Issue