Move mailslot devices into directory name space.
Vitaliy Margolen
wine-patch at kievinfo.com
Fri Dec 2 14:09:22 CST 2005
ChangeLog:
Move mailslot devices into directory name space.
dlls/ntdll/file.c | 20 +++---
server/directory.c | 3 +
server/mailslot.c | 167 +++++++++++++++++++++++++++++++++++++++++----------
server/object.h | 1
server/protocol.def | 2 +
5 files changed, 151 insertions(+), 42 deletions(-)
-------------- next part --------------
c6bc057e89b8fc5e382053267c379d7dc5b0a65c
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 6b6df2c..21838bc 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -173,11 +173,6 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE ha
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) &&
@@ -187,9 +182,10 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE ha
{
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;
}
@@ -197,6 +193,11 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE ha
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) );
@@ -2064,10 +2065,11 @@ NTSTATUS WINAPI NtCreateMailslotFile(PHA
{
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;
diff --git a/server/directory.c b/server/directory.c
index e7c392e..bf860b3 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -301,6 +301,7 @@ obj_handle_t open_object_dir( struct dir
static struct directory *dir_driver, *dir_device;
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)
{
@@ -340,6 +341,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 );
@@ -350,6 +352,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 );
diff --git a/server/mailslot.c b/server/mailslot.c
index 2c04fe2..979b0bb 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -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_f
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,20 +242,103 @@ static void mailslot_queue_async( struct
fd_queue_async_timeout( fd, apc, user, iosb, type, count, timeout );
}
-static struct mailslot *create_mailslot( const struct unicode_str *name, unsigned int attr,
- int max_msgsize, int read_timeout )
+static void mailslot_device_dump( struct object *obj, int verbose )
{
- struct mailslot *mailslot;
- int fds[2];
- static const WCHAR slot[] = {'m','a','i','l','s','l','o','t','\\'};
+ assert( obj->ops == &mailslot_device_ops );
+ fprintf( stderr, "Mail slot device\n" );
+}
- if ((name->len <= sizeof(slot)) || strncmpiW( slot, name->str, sizeof(slot)/sizeof(WCHAR) ))
+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 );
+ assert( device->mailslots );
+
+ if (!name || !name->len) return NULL;
+
+ if ((found = find_object( device->mailslots, name, attr | OBJ_CASE_INSENSITIVE )))
{
- set_error( STATUS_OBJECT_NAME_INVALID );
- return NULL;
+ name->str = NULL;
+ 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 );
+}
- mailslot = create_named_object( sync_namespace, &mailslot_ops, name, attr );
+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_helper( struct directory *root,
+ const struct unicode_str *name, unsigned int attr )
+{
+ struct object *obj;
+ struct mailslot *mailslot = NULL;
+ struct unicode_str new_name;
+
+ 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)
+ {
+ if (attr & OBJ_OPENIF && obj->ops == &mailslot_ops)
+ set_error( STATUS_OBJECT_NAME_EXISTS );
+ else
+ {
+ release_object( obj );
+ obj = NULL;
+ if (attr & OBJ_OPENIF)
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
+ else
+ set_error( STATUS_OBJECT_NAME_COLLISION );
+ }
+ return (struct mailslot *)obj;
+ }
+
+ if (obj->ops != &mailslot_device_ops)
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
+ else
+ {
+ struct mailslot_device *dev = (struct mailslot_device *)obj;
+ if ((mailslot = create_object( dev->mailslots, &mailslot_ops, &new_name, NULL )))
+ clear_error();
+ }
+
+ release_object( obj );
+ return mailslot;
+}
+
+static struct mailslot *create_mailslot( struct directory *root,
+ const struct unicode_str *name, unsigned int attr,
+ int max_msgsize, int read_timeout )
+{
+ struct mailslot *mailslot;
+ int fds[2];
+
+ mailslot = create_mailslot_helper( root, name, attr );
if (!mailslot)
return NULL;
@@ -262,24 +371,6 @@ static struct mailslot *create_mailslot(
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 +434,7 @@ static struct mail_writer *create_mail_w
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 +443,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 +467,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 +478,12 @@ 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 = (struct mailslot*)reference_by_name( root, &name, req->attributes, &mailslot_ops );
+ if (root) release_object( root );
+
if (mailslot)
{
struct mail_writer *writer;
diff --git a/server/object.h b/server/object.h
index ade820e..298160c 100644
--- a/server/object.h
+++ b/server/object.h
@@ -202,6 +202,7 @@ extern struct symlink *create_symlink( s
/* devices */
extern struct named_pipe_device *create_named_pipe_device( void );
+extern struct mailslot_device *create_mailslot_device( void );
/* global variables */
diff --git a/server/protocol.def b/server/protocol.def
index 905e0ff..dc302b0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -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
More information about the wine-patches
mailing list