Commit cf21d4d7 authored by Vitaliy Margolen's avatar Vitaliy Margolen Committed by Alexandre Julliard

Move mailslot devices into directory name space.

parent babfa794
......@@ -173,12 +173,6 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
return io->u.Status;
}
if (attr->RootDirectory)
{
FIXME( "RootDirectory %p not supported\n", attr->RootDirectory );
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* check for mailslot */
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->attributes = (attr) ? attr->Attributes : 0;
req->rootdir = attr ? attr->RootDirectory : 0;
req->sharing = sharing;
wine_server_add_data( req, attr->ObjectName->Buffer + 4,
attr->ObjectName->Length - 4*sizeof(WCHAR) );
wine_server_add_data( req, attr->ObjectName->Buffer,
attr->ObjectName->Length );
io->u.Status = wine_server_call( req );
*handle = reply->handle;
}
......@@ -198,6 +193,12 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
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,
!(attr->Attributes & OBJ_CASE_INSENSITIVE) );
......@@ -2065,10 +2066,11 @@ NTSTATUS WINAPI NtCreateMailslotFile(PHANDLE pHandle, ULONG DesiredAccess,
{
req->access = DesiredAccess;
req->attributes = (attr) ? attr->Attributes : 0;
req->rootdir = attr ? attr->RootDirectory : 0;
req->max_msgsize = MaxMessageSize;
req->read_timeout = (TimeOut->QuadPart <= 0) ? TimeOut->QuadPart / -10000 : -1;
wine_server_add_data( req, attr->ObjectName->Buffer + 4,
attr->ObjectName->Length - 4*sizeof(WCHAR) );
wine_server_add_data( req, attr->ObjectName->Buffer,
attr->ObjectName->Length );
ret = wine_server_call( req );
if( ret == STATUS_SUCCESS )
*pHandle = reply->handle;
......
......@@ -3543,6 +3543,7 @@ struct create_mailslot_request
struct request_header __header;
unsigned int access;
unsigned int attributes;
obj_handle_t rootdir;
unsigned int max_msgsize;
int read_timeout;
/* VARARG(name,unicode_str); */
......@@ -3560,6 +3561,7 @@ struct open_mailslot_request
struct request_header __header;
unsigned int access;
unsigned int attributes;
obj_handle_t rootdir;
unsigned int sharing;
/* VARARG(name,unicode_str); */
};
......@@ -4314,6 +4316,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply;
};
#define SERVER_PROTOCOL_VERSION 206
#define SERVER_PROTOCOL_VERSION 207
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -286,6 +286,7 @@ void *open_object_dir( struct directory *root, const struct unicode_str *name,
static struct directory *dir_driver;
static struct symlink *link_dosdev, *link_global1, *link_global2, *link_local;
static struct named_pipe_device *dev_named_pipe;
static struct mailslot_device *dev_mailslot;
void init_directories(void)
{
......@@ -325,6 +326,7 @@ void init_directories(void)
/* devices */
dev_named_pipe = create_named_pipe_device();
dev_mailslot = create_mailslot_device();
/* the symlinks or devices hold references so we can release these */
release_object( dir_device );
......@@ -335,6 +337,7 @@ void init_directories(void)
void close_directories(void)
{
release_object( dev_named_pipe );
release_object( dev_mailslot );
release_object( link_dosdev );
release_object( link_global1 );
......
......@@ -62,6 +62,12 @@ struct mailslot
struct list writers;
};
struct mailslot_device
{
struct object obj; /* object header */
struct namespace *mailslots; /* mailslot namespace */
};
/* mailslot functions */
static void mailslot_dump( struct object*, int );
static struct fd *mailslot_get_fd( struct object * );
......@@ -135,6 +141,26 @@ static const struct fd_ops mail_writer_fd_ops =
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)
{
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 );
}
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 )
{
struct object *obj;
struct unicode_str new_name;
struct mailslot_device *dev;
struct mailslot *mailslot;
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)
/* it already exists - there can only be one mailslot to read from */
set_error( STATUS_OBJECT_NAME_EXISTS );
else if (attr & OBJ_OPENIF)
set_error( STATUS_OBJECT_TYPE_MISMATCH );
else
set_error( STATUS_OBJECT_NAME_COLLISION );
release_object( obj );
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 */
if (get_error() == STATUS_OBJECT_NAME_EXISTS)
if (obj->ops != &mailslot_device_ops)
{
release_object( mailslot );
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->write_fd = NULL;
mailslot->max_msgsize = max_msgsize;
......@@ -262,24 +349,6 @@ static struct mailslot *create_mailslot( const struct unicode_str *name, unsigne
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 )
{
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,
unsigned int access )
{
struct object *obj;
obj = get_handle_obj( process, handle, access, &mailslot_ops );
return (struct mailslot *) obj;
return (struct mailslot *)get_handle_obj( process, handle, access, &mailslot_ops );
}
......@@ -354,16 +421,22 @@ DECL_HANDLER(create_mailslot)
{
struct mailslot *mailslot;
struct unicode_str name;
struct directory *root = NULL;
reply->handle = 0;
get_req_unicode_str( &name );
mailslot = create_mailslot( &name, req->attributes, req->max_msgsize, req->read_timeout );
if (mailslot)
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
return;
if ((mailslot = create_mailslot( root, &name, req->attributes, req->max_msgsize,
req->read_timeout )))
{
reply->handle = alloc_handle( current->process, mailslot,
req->access, req->attributes & OBJ_INHERIT );
release_object( mailslot );
}
if (root) release_object( root );
}
......@@ -372,6 +445,7 @@ DECL_HANDLER(open_mailslot)
{
struct mailslot *mailslot;
struct unicode_str name;
struct directory *root = NULL;
reply->handle = 0;
get_req_unicode_str( &name );
......@@ -382,7 +456,11 @@ DECL_HANDLER(open_mailslot)
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)
{
struct mail_writer *writer;
......
......@@ -199,6 +199,7 @@ extern struct symlink *create_symlink( struct directory *root, const struct unic
/* devices */
extern struct named_pipe_device *create_named_pipe_device( void );
extern struct mailslot_device *create_mailslot_device( void );
/* global variables */
......
......@@ -2486,6 +2486,7 @@ enum message_type
@REQ(create_mailslot)
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
unsigned int max_msgsize;
int read_timeout;
VARARG(name,unicode_str); /* mailslot name */
......@@ -2498,6 +2499,7 @@ enum message_type
@REQ(open_mailslot)
unsigned int access;
unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
unsigned int sharing; /* sharing mode */
VARARG(name,unicode_str); /* mailslot name */
@REPLY
......
......@@ -3065,6 +3065,7 @@ static void dump_create_mailslot_request( const struct create_mailslot_request *
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " attributes=%08x,", req->attributes );
fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize );
fprintf( stderr, " read_timeout=%d,", req->read_timeout );
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, " attributes=%08x,", req->attributes );
fprintf( stderr, " rootdir=%p,", req->rootdir );
fprintf( stderr, " sharing=%08x,", req->sharing );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment