Andrey Turkin : server: Allow completion object to be attached to an fd object.

Alexandre Julliard julliard at winehq.org
Fri Sep 28 06:46:03 CDT 2007


Module: wine
Branch: master
Commit: d1a8155882e83378add14a5d0785477ad8fccb56
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d1a8155882e83378add14a5d0785477ad8fccb56

Author: Andrey Turkin <andrey.turkin at gmail.com>
Date:   Fri Sep 28 00:03:39 2007 +0400

server: Allow completion object to be attached to an fd object.

---

 dlls/ntdll/file.c              |   17 +++++++++++++++++
 include/wine/server_protocol.h |   19 ++++++++++++++++++-
 server/completion.c            |    3 ++-
 server/fd.c                    |   22 ++++++++++++++++++++++
 server/file.h                  |    5 +++++
 server/protocol.def            |    8 ++++++++
 server/request.h               |    2 ++
 server/trace.c                 |   10 ++++++++++
 8 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index bf35a47..bbb071b 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1658,6 +1658,23 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
         }
         break;
 
+    case FileCompletionInformation:
+        if (len >= sizeof(FILE_COMPLETION_INFORMATION))
+        {
+            FILE_COMPLETION_INFORMATION *info = (FILE_COMPLETION_INFORMATION *)ptr;
+
+            SERVER_START_REQ( set_completion_info )
+            {
+                req->handle   = handle;
+                req->chandle  = info->CompletionPort;
+                req->ckey     = info->CompletionKey;
+                io->u.Status  = wine_server_call( req );
+            }
+            SERVER_END_REQ;
+        } else
+            io->u.Status = STATUS_INVALID_PARAMETER_3;
+        break;
+
     default:
         FIXME("Unsupported class (%d)\n", class);
         io->u.Status = STATUS_NOT_IMPLEMENTED;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index e37f25c..314a3a6 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4156,6 +4156,20 @@ struct query_completion_reply
 };
 
 
+
+struct set_completion_info_request
+{
+    struct request_header __header;
+    obj_handle_t  handle;
+    obj_handle_t  chandle;
+    unsigned long ckey;
+};
+struct set_completion_info_reply
+{
+    struct reply_header __header;
+};
+
+
 enum request
 {
     REQ_new_process,
@@ -4383,6 +4397,7 @@ enum request
     REQ_add_completion,
     REQ_remove_completion,
     REQ_query_completion,
+    REQ_set_completion_info,
     REQ_NB_REQUESTS
 };
 
@@ -4615,6 +4630,7 @@ union generic_request
     struct add_completion_request add_completion_request;
     struct remove_completion_request remove_completion_request;
     struct query_completion_request query_completion_request;
+    struct set_completion_info_request set_completion_info_request;
 };
 union generic_reply
 {
@@ -4845,8 +4861,9 @@ union generic_reply
     struct add_completion_reply add_completion_reply;
     struct remove_completion_reply remove_completion_reply;
     struct query_completion_reply query_completion_reply;
+    struct set_completion_info_reply set_completion_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 314
+#define SERVER_PROTOCOL_VERSION 315
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/completion.c b/server/completion.c
index 1282bb4..13f5939 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -39,6 +39,7 @@
 
 #include "wine/unicode.h"
 #include "object.h"
+#include "file.h"
 #include "handle.h"
 #include "request.h"
 
@@ -124,7 +125,7 @@ static struct completion *create_completion( struct directory *root, const struc
     return completion;
 }
 
-static struct completion *get_completion_obj( struct process *process, obj_handle_t handle, unsigned int access )
+struct completion *get_completion_obj( struct process *process, obj_handle_t handle, unsigned int access )
 {
     return (struct completion *) get_handle_obj( process, handle, access, &completion_ops );
 }
diff --git a/server/fd.c b/server/fd.c
index 31e1c9f..d671a1c 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -180,6 +180,8 @@ struct fd
     struct async_queue  *read_q;      /* async readers of this fd */
     struct async_queue  *write_q;     /* async writers of this fd */
     struct async_queue  *wait_q;      /* other async waiters of this fd */
+    struct completion   *completion;  /* completion object attached to this fd */
+    unsigned long        comp_key;    /* completion key to set in completion events */
 };
 
 static void fd_dump( struct object *obj, int verbose );
@@ -1329,6 +1331,7 @@ static void fd_destroy( struct object *obj )
     free_async_queue( fd->write_q );
     free_async_queue( fd->wait_q );
 
+    if (fd->completion) release_object( fd->completion );
     remove_fd_locks( fd );
     list_remove( &fd->inode_entry );
     if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index );
@@ -1406,6 +1409,7 @@ static struct fd *alloc_fd_object(void)
     fd->read_q     = NULL;
     fd->write_q    = NULL;
     fd->wait_q     = NULL;
+    fd->completion = NULL;
     list_init( &fd->inode_entry );
     list_init( &fd->locks );
 
@@ -1438,6 +1442,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
     fd->read_q     = NULL;
     fd->write_q    = NULL;
     fd->wait_q     = NULL;
+    fd->completion = NULL;
     fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
     list_init( &fd->inode_entry );
     list_init( &fd->locks );
@@ -2009,3 +2014,20 @@ DECL_HANDLER(cancel_async)
         release_object( fd );
     }
 }
+
+/* attach completion object to a fd */
+DECL_HANDLER(set_completion_info)
+{
+    struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+
+    if (fd)
+    {
+        if (!fd->completion)
+        {
+            fd->completion = get_completion_obj( current->process, req->chandle, IO_COMPLETION_MODIFY_STATE );
+            fd->comp_key = req->ckey;
+        }
+        else set_error( STATUS_INVALID_PARAMETER );
+        release_object( fd );
+    }
+}
diff --git a/server/file.h b/server/file.h
index c84f0b8..d56aad0 100644
--- a/server/file.h
+++ b/server/file.h
@@ -25,6 +25,7 @@
 
 struct fd;
 struct async_queue;
+struct completion;
 
 typedef unsigned __int64 file_pos_t;
 
@@ -120,6 +121,10 @@ extern void do_change_notify( int unix_fd );
 extern void sigio_callback(void);
 extern struct object *create_dir_obj( struct fd *fd );
 
+/* completion */
+
+struct completion *get_completion_obj( struct process *process, obj_handle_t handle, unsigned int access );
+
 /* serial port functions */
 
 extern int is_serial_fd( struct fd *fd );
diff --git a/server/protocol.def b/server/protocol.def
index 8eec8a7..2e83c12 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2983,3 +2983,11 @@ enum message_type
 @REPLY
     unsigned int  depth;          /* completion queue depth */
 @END
+
+
+/* associate object with completion port */
+ at REQ(set_completion_info)
+    obj_handle_t  handle;         /* object handle */
+    obj_handle_t  chandle;        /* port handle */
+    unsigned long ckey;           /* completion key */
+ at END
diff --git a/server/request.h b/server/request.h
index 7411565..0a013ab 100644
--- a/server/request.h
+++ b/server/request.h
@@ -335,6 +335,7 @@ DECL_HANDLER(open_completion);
 DECL_HANDLER(add_completion);
 DECL_HANDLER(remove_completion);
 DECL_HANDLER(query_completion);
+DECL_HANDLER(set_completion_info);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -566,6 +567,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_add_completion,
     (req_handler)req_remove_completion,
     (req_handler)req_query_completion,
+    (req_handler)req_set_completion_info,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/trace.c b/server/trace.c
index b431413..d1575e1 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3628,6 +3628,13 @@ static void dump_query_completion_reply( const struct query_completion_reply *re
     fprintf( stderr, " depth=%08x", req->depth );
 }
 
+static void dump_set_completion_info_request( const struct set_completion_info_request *req )
+{
+    fprintf( stderr, " handle=%p,", req->handle );
+    fprintf( stderr, " chandle=%p,", req->chandle );
+    fprintf( stderr, " ckey=%lx", req->ckey );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -3854,6 +3861,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_add_completion_request,
     (dump_func)dump_remove_completion_request,
     (dump_func)dump_query_completion_request,
+    (dump_func)dump_set_completion_info_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -4082,6 +4090,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)0,
     (dump_func)dump_remove_completion_reply,
     (dump_func)dump_query_completion_reply,
+    (dump_func)0,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4310,6 +4319,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "add_completion",
     "remove_completion",
     "query_completion",
+    "set_completion_info",
 };
 
 static const struct




More information about the wine-cvs mailing list