server: Implement device object. [Try 2]

Vitaliy Margolen wine-patch at kievinfo.com
Wed Dec 14 18:22:28 CST 2005


This time with fd associated stuff.

ChangeLog:
server: Implement device object.

 server/Makefile.in  |    1 
 server/device.c     |  150 +++++++++++++++++++++++++++++++++++++++++++++++++++
 server/protocol.def |    9 +++
 3 files changed, 160 insertions(+), 0 deletions(-)
 create mode 100644 server/device.c
-------------- next part --------------
ae004c3a7a15d3e5db913416dd25a2e9c78fb0ff
diff --git a/server/Makefile.in b/server/Makefile.in
index ee4a15a..86462eb 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -17,6 +17,7 @@ C_SRCS = \
 	context_sparc.c \
 	context_x86_64.c \
 	debugger.c \
+	device.c \
 	directory.c \
 	event.c \
 	fd.c \
diff --git a/server/device.c b/server/device.c
new file mode 100644
index 0000000..2b552f0
--- /dev/null
+++ b/server/device.c
@@ -0,0 +1,150 @@
+/*
+ * Server-side device object management
+ *
+ * Copyright (C) 2005 Vitaliy Margolen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "file.h"
+#include "handle.h"
+#include "request.h"
+#include "object.h"
+#include "unicode.h"
+
+struct device
+{
+    struct object obj;            /* object header */
+    struct fd    *fd;             /* pseudo-fd for ioctls */
+    obj_handle_t  kernel_handle;  /* handle we give to ntoskrnl */
+};
+
+static void device_dump( struct object *obj, int verbose );
+static struct fd *device_get_fd( struct object *obj );
+static unsigned int device_map_access( struct object *obj, unsigned int access );
+static void device_destroy( struct object *obj );
+static int device_get_file_info( struct fd *fd );
+
+static const struct object_ops device_ops =
+{
+    sizeof(struct device),        /* size */
+    device_dump,                  /* dump */
+    no_add_queue,                 /* add_queue */
+    NULL,                         /* remove_queue */
+    NULL,                         /* signaled */
+    NULL,                         /* satisfied */
+    no_signal,                    /* signal */
+    device_get_fd,                /* get_fd */
+    device_map_access,            /* map_access */
+    no_lookup_name,               /* lookup_name */
+    no_close_handle,              /* close_handle */
+    device_destroy                /* destroy */
+};
+
+static const struct fd_ops device_fd_ops =
+{
+    default_fd_get_poll_events,   /* get_poll_events */
+    default_poll_event,           /* poll_event */
+    no_flush,                     /* flush */
+    device_get_file_info,         /* get_file_info */
+    default_fd_queue_async,       /* queue_async */
+    default_fd_cancel_async       /* cancel_async */
+};
+
+static void device_dump( struct object *obj, int verbose )
+{
+    struct device *device = (struct device *)obj;
+    assert( obj->ops == &device_ops );
+    fprintf( stderr, "Device " );
+    dump_object_name( obj );
+    if (verbose)
+    {
+        fprintf( stderr, " kernel_handle=%p", device->kernel_handle );
+    }
+    fputc( '\n', stderr );
+}
+
+static struct fd *device_get_fd( struct object *obj )
+{
+    struct device *device = (struct device *)obj;
+    return (struct fd *)grab_object( device->fd );
+}
+
+static unsigned int device_map_access( struct object *obj, unsigned int access )
+{
+    if (access & GENERIC_READ)    access |= FILE_GENERIC_READ;
+    if (access & GENERIC_WRITE)   access |= FILE_GENERIC_WRITE;
+    if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
+    if (access & GENERIC_ALL)     access |= FILE_ALL_ACCESS;
+    return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
+}
+
+static void device_destroy( struct object *obj )
+{
+    struct device *device = (struct device*)obj;
+    assert( obj->ops == &device_ops );
+    if (device->fd) release_object( device->fd );
+}
+
+static int device_get_file_info( struct fd *fd )
+{
+    return 0;
+}
+
+struct device *create_device( unsigned int attr, const struct unicode_str *name )
+{
+    struct device *dev;
+    if ((dev = create_named_object_dir( NULL, name, attr, &device_ops )) &&
+        get_error() != STATUS_OBJECT_NAME_EXISTS)
+    {
+        dev->kernel_handle = 0;
+        if (!(dev->fd = alloc_pseudo_fd( &device_fd_ops, &dev->obj )))
+        {
+            release_object( dev );
+            dev = NULL;
+        }
+    }
+    return dev;
+}
+
+/* create a device object */
+DECL_HANDLER(create_device)
+{
+    struct device *dev;
+    struct unicode_str name;
+
+    reply->handle = 0;
+    get_req_unicode_str( &name );
+    if ((dev = create_device( req->attributes, &name )))
+    {
+        reply->handle = alloc_handle( current->process, dev, 0, 0 );
+        if (!dev->kernel_handle) dev->kernel_handle = reply->handle;
+
+        release_object( dev );
+    }
+}
diff --git a/server/protocol.def b/server/protocol.def
index 39851b2..f3befce 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2595,3 +2595,12 @@ enum message_type
 @REPLY
     VARARG(target_name,unicode_str); /* target name */
 @END
+
+
+/* Create device object */
+ at REQ(create_device)
+    unsigned int   attributes;    /* object attributes */
+    VARARG(device_name,unicode_str); /* Device name */
+ at REPLY
+    obj_handle_t   handle;        /* handle to the device */
+ at END


More information about the wine-patches mailing list