Move mailslot devices into directory name space.

This commit is contained in:
Vitaliy Margolen 2005-12-05 13:30:26 +01:00 committed by Alexandre Julliard
parent babfa79436
commit cf21d4d7ca
7 changed files with 136 additions and 46 deletions

View File

@ -173,12 +173,6 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
return io->u.Status; return io->u.Status;
} }
if (attr->RootDirectory)
{
FIXME( "RootDirectory %p not supported\n", attr->RootDirectory );
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* check for mailslot */ /* check for mailslot */
if (attr->ObjectName->Length > sizeof(mailslotW) && if (attr->ObjectName->Length > sizeof(mailslotW) &&
@ -188,9 +182,10 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
{ {
req->access = access & GENERIC_WRITE; req->access = access & GENERIC_WRITE;
req->attributes = (attr) ? attr->Attributes : 0; req->attributes = (attr) ? attr->Attributes : 0;
req->rootdir = attr ? attr->RootDirectory : 0;
req->sharing = sharing; req->sharing = sharing;
wine_server_add_data( req, attr->ObjectName->Buffer + 4, wine_server_add_data( req, attr->ObjectName->Buffer,
attr->ObjectName->Length - 4*sizeof(WCHAR) ); attr->ObjectName->Length );
io->u.Status = wine_server_call( req ); io->u.Status = wine_server_call( req );
*handle = reply->handle; *handle = reply->handle;
} }
@ -198,6 +193,12 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
return io->u.Status; return io->u.Status;
} }
if (attr->RootDirectory)
{
FIXME( "RootDirectory %p not supported\n", attr->RootDirectory );
return STATUS_OBJECT_NAME_NOT_FOUND;
}
io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, disposition, io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, disposition,
!(attr->Attributes & OBJ_CASE_INSENSITIVE) ); !(attr->Attributes & OBJ_CASE_INSENSITIVE) );
@ -2065,10 +2066,11 @@ NTSTATUS WINAPI NtCreateMailslotFile(PHANDLE pHandle, ULONG DesiredAccess,
{ {
req->access = DesiredAccess; req->access = DesiredAccess;
req->attributes = (attr) ? attr->Attributes : 0; req->attributes = (attr) ? attr->Attributes : 0;
req->rootdir = attr ? attr->RootDirectory : 0;
req->max_msgsize = MaxMessageSize; req->max_msgsize = MaxMessageSize;
req->read_timeout = (TimeOut->QuadPart <= 0) ? TimeOut->QuadPart / -10000 : -1; req->read_timeout = (TimeOut->QuadPart <= 0) ? TimeOut->QuadPart / -10000 : -1;
wine_server_add_data( req, attr->ObjectName->Buffer + 4, wine_server_add_data( req, attr->ObjectName->Buffer,
attr->ObjectName->Length - 4*sizeof(WCHAR) ); attr->ObjectName->Length );
ret = wine_server_call( req ); ret = wine_server_call( req );
if( ret == STATUS_SUCCESS ) if( ret == STATUS_SUCCESS )
*pHandle = reply->handle; *pHandle = reply->handle;

View File

@ -3543,6 +3543,7 @@ struct create_mailslot_request
struct request_header __header; struct request_header __header;
unsigned int access; unsigned int access;
unsigned int attributes; unsigned int attributes;
obj_handle_t rootdir;
unsigned int max_msgsize; unsigned int max_msgsize;
int read_timeout; int read_timeout;
/* VARARG(name,unicode_str); */ /* VARARG(name,unicode_str); */
@ -3560,6 +3561,7 @@ struct open_mailslot_request
struct request_header __header; struct request_header __header;
unsigned int access; unsigned int access;
unsigned int attributes; unsigned int attributes;
obj_handle_t rootdir;
unsigned int sharing; unsigned int sharing;
/* VARARG(name,unicode_str); */ /* VARARG(name,unicode_str); */
}; };
@ -4314,6 +4316,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 206 #define SERVER_PROTOCOL_VERSION 207
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -286,6 +286,7 @@ void *open_object_dir( struct directory *root, const struct unicode_str *name,
static struct directory *dir_driver; static struct directory *dir_driver;
static struct symlink *link_dosdev, *link_global1, *link_global2, *link_local; static struct symlink *link_dosdev, *link_global1, *link_global2, *link_local;
static struct named_pipe_device *dev_named_pipe; static struct named_pipe_device *dev_named_pipe;
static struct mailslot_device *dev_mailslot;
void init_directories(void) void init_directories(void)
{ {
@ -325,6 +326,7 @@ void init_directories(void)
/* devices */ /* devices */
dev_named_pipe = create_named_pipe_device(); dev_named_pipe = create_named_pipe_device();
dev_mailslot = create_mailslot_device();
/* the symlinks or devices hold references so we can release these */ /* the symlinks or devices hold references so we can release these */
release_object( dir_device ); release_object( dir_device );
@ -335,6 +337,7 @@ void init_directories(void)
void close_directories(void) void close_directories(void)
{ {
release_object( dev_named_pipe ); release_object( dev_named_pipe );
release_object( dev_mailslot );
release_object( link_dosdev ); release_object( link_dosdev );
release_object( link_global1 ); release_object( link_global1 );

View File

@ -62,6 +62,12 @@ struct mailslot
struct list writers; struct list writers;
}; };
struct mailslot_device
{
struct object obj; /* object header */
struct namespace *mailslots; /* mailslot namespace */
};
/* mailslot functions */ /* mailslot functions */
static void mailslot_dump( struct object*, int ); static void mailslot_dump( struct object*, int );
static struct fd *mailslot_get_fd( struct object * ); static struct fd *mailslot_get_fd( struct object * );
@ -135,6 +141,26 @@ static const struct fd_ops mail_writer_fd_ops =
NULL /* cancel_async */ NULL /* cancel_async */
}; };
static void mailslot_device_dump( struct object *obj, int verbose );
static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name,
unsigned int attr );
static void mailslot_device_destroy( struct object *obj );
static const struct object_ops mailslot_device_ops =
{
sizeof(struct mailslot_device), /* size */
mailslot_device_dump, /* dump */
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
mailslot_device_lookup_name, /* lookup_name */
no_close_handle, /* close_handle */
mailslot_device_destroy /* destroy */
};
static void mailslot_destroy( struct object *obj) static void mailslot_destroy( struct object *obj)
{ {
struct mailslot *mailslot = (struct mailslot *) obj; struct mailslot *mailslot = (struct mailslot *) obj;
@ -216,30 +242,91 @@ static void mailslot_queue_async( struct fd *fd, void *apc, void *user,
fd_queue_async_timeout( fd, apc, user, iosb, type, count, timeout ); fd_queue_async_timeout( fd, apc, user, iosb, type, count, timeout );
} }
static struct mailslot *create_mailslot( const struct unicode_str *name, unsigned int attr, static void mailslot_device_dump( struct object *obj, int verbose )
{
assert( obj->ops == &mailslot_device_ops );
fprintf( stderr, "Mail slot device\n" );
}
static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name,
unsigned int attr )
{
struct mailslot_device *device = (struct mailslot_device*)obj;
struct object *found;
assert( obj->ops == &mailslot_device_ops );
if ((found = find_object( device->mailslots, name, attr | OBJ_CASE_INSENSITIVE )))
name->len = 0;
return found;
}
static void mailslot_device_destroy( struct object *obj )
{
struct mailslot_device *device = (struct mailslot_device*)obj;
assert( obj->ops == &mailslot_device_ops );
free( device->mailslots );
}
struct mailslot_device *create_mailslot_device( void )
{
static const WCHAR mailslotW[] = {'\\','?','?','\\','M','A','I','L','S','L','O','T'};
static struct unicode_str mailslot = {mailslotW, sizeof(mailslotW)};
struct mailslot_device *dev;
if ((dev = create_named_object_dir( NULL, &mailslot, 0, &mailslot_device_ops )) &&
get_error() != STATUS_OBJECT_NAME_EXISTS)
{
if (!(dev->mailslots = create_namespace( 7 )))
{
release_object( dev );
dev = NULL;
}
}
return dev;
}
static struct mailslot *create_mailslot( struct directory *root,
const struct unicode_str *name, unsigned int attr,
int max_msgsize, int read_timeout ) int max_msgsize, int read_timeout )
{ {
struct object *obj;
struct unicode_str new_name;
struct mailslot_device *dev;
struct mailslot *mailslot; struct mailslot *mailslot;
int fds[2]; int fds[2];
static const WCHAR slot[] = {'m','a','i','l','s','l','o','t','\\'};
if ((name->len <= sizeof(slot)) || strncmpiW( slot, name->str, sizeof(slot)/sizeof(WCHAR) )) if (!name || !name->len) return alloc_object( &mailslot_ops );
if (!(obj = find_object_dir( root, name, attr, &new_name ))) return NULL;
if (!new_name.len)
{ {
set_error( STATUS_OBJECT_NAME_INVALID ); if (attr & OBJ_OPENIF && obj->ops == &mailslot_ops)
return NULL;
}
mailslot = create_named_object( sync_namespace, &mailslot_ops, name, attr );
if (!mailslot)
return NULL;
/* it already exists - there can only be one mailslot to read from */ /* it already exists - there can only be one mailslot to read from */
if (get_error() == STATUS_OBJECT_NAME_EXISTS) set_error( STATUS_OBJECT_NAME_EXISTS );
{ else if (attr & OBJ_OPENIF)
release_object( mailslot ); set_error( STATUS_OBJECT_TYPE_MISMATCH );
else
set_error( STATUS_OBJECT_NAME_COLLISION );
release_object( obj );
return NULL; return NULL;
} }
if (obj->ops != &mailslot_device_ops)
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
release_object( obj );
return NULL;
}
dev = (struct mailslot_device *)obj;
mailslot = create_object( dev->mailslots, &mailslot_ops, &new_name, NULL );
release_object( dev );
if (!mailslot) return NULL;
mailslot->fd = NULL; mailslot->fd = NULL;
mailslot->write_fd = NULL; mailslot->write_fd = NULL;
mailslot->max_msgsize = max_msgsize; mailslot->max_msgsize = max_msgsize;
@ -262,24 +349,6 @@ static struct mailslot *create_mailslot( const struct unicode_str *name, unsigne
return NULL; return NULL;
} }
static struct mailslot *open_mailslot( const struct unicode_str *name, unsigned int attr )
{
struct object *obj;
obj = find_object( sync_namespace, name, attr );
if (obj)
{
if (obj->ops == &mailslot_ops)
return (struct mailslot *)obj;
release_object( obj );
set_error( STATUS_OBJECT_TYPE_MISMATCH );
}
else
set_error( STATUS_OBJECT_NAME_NOT_FOUND );
return NULL;
}
static void mail_writer_dump( struct object *obj, int verbose ) static void mail_writer_dump( struct object *obj, int verbose )
{ {
fprintf( stderr, "Mailslot writer\n" ); fprintf( stderr, "Mailslot writer\n" );
@ -343,9 +412,7 @@ static struct mail_writer *create_mail_writer( struct mailslot *mailslot, unsign
static struct mailslot *get_mailslot_obj( struct process *process, obj_handle_t handle, static struct mailslot *get_mailslot_obj( struct process *process, obj_handle_t handle,
unsigned int access ) unsigned int access )
{ {
struct object *obj; return (struct mailslot *)get_handle_obj( process, handle, access, &mailslot_ops );
obj = get_handle_obj( process, handle, access, &mailslot_ops );
return (struct mailslot *) obj;
} }
@ -354,16 +421,22 @@ DECL_HANDLER(create_mailslot)
{ {
struct mailslot *mailslot; struct mailslot *mailslot;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL;
reply->handle = 0; reply->handle = 0;
get_req_unicode_str( &name ); get_req_unicode_str( &name );
mailslot = create_mailslot( &name, req->attributes, req->max_msgsize, req->read_timeout ); if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
if (mailslot) return;
if ((mailslot = create_mailslot( root, &name, req->attributes, req->max_msgsize,
req->read_timeout )))
{ {
reply->handle = alloc_handle( current->process, mailslot, reply->handle = alloc_handle( current->process, mailslot,
req->access, req->attributes & OBJ_INHERIT ); req->access, req->attributes & OBJ_INHERIT );
release_object( mailslot ); release_object( mailslot );
} }
if (root) release_object( root );
} }
@ -372,6 +445,7 @@ DECL_HANDLER(open_mailslot)
{ {
struct mailslot *mailslot; struct mailslot *mailslot;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL;
reply->handle = 0; reply->handle = 0;
get_req_unicode_str( &name ); get_req_unicode_str( &name );
@ -382,7 +456,11 @@ DECL_HANDLER(open_mailslot)
return; return;
} }
mailslot = open_mailslot( &name, req->attributes ); if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
return;
mailslot = open_object_dir( root, &name, req->attributes, &mailslot_ops );
if (root) release_object( root );
if (mailslot) if (mailslot)
{ {
struct mail_writer *writer; struct mail_writer *writer;

View File

@ -199,6 +199,7 @@ extern struct symlink *create_symlink( struct directory *root, const struct unic
/* devices */ /* devices */
extern struct named_pipe_device *create_named_pipe_device( void ); extern struct named_pipe_device *create_named_pipe_device( void );
extern struct mailslot_device *create_mailslot_device( void );
/* global variables */ /* global variables */

View File

@ -2486,6 +2486,7 @@ enum message_type
@REQ(create_mailslot) @REQ(create_mailslot)
unsigned int access; /* wanted access rights */ unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */ unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
unsigned int max_msgsize; unsigned int max_msgsize;
int read_timeout; int read_timeout;
VARARG(name,unicode_str); /* mailslot name */ VARARG(name,unicode_str); /* mailslot name */
@ -2498,6 +2499,7 @@ enum message_type
@REQ(open_mailslot) @REQ(open_mailslot)
unsigned int access; unsigned int access;
unsigned int attributes; /* object attributes */ unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
unsigned int sharing; /* sharing mode */ unsigned int sharing; /* sharing mode */
VARARG(name,unicode_str); /* mailslot name */ VARARG(name,unicode_str); /* mailslot name */
@REPLY @REPLY

View File

@ -3065,6 +3065,7 @@ static void dump_create_mailslot_request( const struct create_mailslot_request *
{ {
fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes ); fprintf( stderr, " attributes=%08x,", req->attributes );
fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize ); fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize );
fprintf( stderr, " read_timeout=%d,", req->read_timeout ); fprintf( stderr, " read_timeout=%d,", req->read_timeout );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
@ -3080,6 +3081,7 @@ static void dump_open_mailslot_request( const struct open_mailslot_request *req
{ {
fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes ); fprintf( stderr, " attributes=%08x,", req->attributes );
fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " sharing=%08x,", req->sharing ); fprintf( stderr, " sharing=%08x,", req->sharing );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size ); dump_varargs_unicode_str( cur_size );