Move mailslot devices into directory name space.
This commit is contained in:
parent
babfa79436
commit
cf21d4d7ca
|
@ -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 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mailslot = create_named_object( sync_namespace, &mailslot_ops, name, attr );
|
||||
if (!mailslot)
|
||||
return NULL;
|
||||
|
||||
if (attr & OBJ_OPENIF && obj->ops == &mailslot_ops)
|
||||
/* it already exists - there can only be one mailslot to read from */
|
||||
if (get_error() == STATUS_OBJECT_NAME_EXISTS)
|
||||
{
|
||||
release_object( mailslot );
|
||||
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;
|
||||
}
|
||||
|
||||
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->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 );
|
||||
|
|
Loading…
Reference in New Issue