ws2_32: Make certain winsock functions generate i/o completion messages.
diff --git a/server/fd.c b/server/fd.c
index cb3aea8..4bfb3e1 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2056,3 +2056,14 @@
         release_object( fd );
     }
 }
+
+/* push new completion msg into a completion queue attached to the fd */
+DECL_HANDLER(add_fd_completion)
+{
+    struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+    if (fd)
+    {
+        fd_add_completion( fd, req->cvalue, req->status, req->information );
+        release_object( fd );
+    }
+}
diff --git a/server/protocol.def b/server/protocol.def
index 93e4887..cf3ffa1 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3006,3 +3006,12 @@
     obj_handle_t  chandle;        /* port handle */
     unsigned long ckey;           /* completion key */
 @END
+
+
+/* check for associated completion and push msg */
+@REQ(add_fd_completion)
+    obj_handle_t   handle;        /* async' object */
+    unsigned long  cvalue;        /* completion value */
+    unsigned int   status;        /* completion status */
+    unsigned long  information;   /* IO_STATUS_BLOCK Information */
+@END
diff --git a/server/request.h b/server/request.h
index 90ec2e1..cd53e16 100644
--- a/server/request.h
+++ b/server/request.h
@@ -337,6 +337,7 @@
 DECL_HANDLER(remove_completion);
 DECL_HANDLER(query_completion);
 DECL_HANDLER(set_completion_info);
+DECL_HANDLER(add_fd_completion);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -570,6 +571,7 @@
     (req_handler)req_remove_completion,
     (req_handler)req_query_completion,
     (req_handler)req_set_completion_info,
+    (req_handler)req_add_fd_completion,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/trace.c b/server/trace.c
index 7275e65..c580139 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3698,6 +3698,14 @@
     fprintf( stderr, " ckey=%lx", req->ckey );
 }
 
+static void dump_add_fd_completion_request( const struct add_fd_completion_request *req )
+{
+    fprintf( stderr, " handle=%p,", req->handle );
+    fprintf( stderr, " cvalue=%lx,", req->cvalue );
+    fprintf( stderr, " status=%08x,", req->status );
+    fprintf( stderr, " information=%lx", req->information );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -3926,6 +3934,7 @@
     (dump_func)dump_remove_completion_request,
     (dump_func)dump_query_completion_request,
     (dump_func)dump_set_completion_info_request,
+    (dump_func)dump_add_fd_completion_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -4156,6 +4165,7 @@
     (dump_func)dump_remove_completion_reply,
     (dump_func)dump_query_completion_reply,
     (dump_func)0,
+    (dump_func)0,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4386,6 +4396,7 @@
     "remove_completion",
     "query_completion",
     "set_completion_info",
+    "add_fd_completion",
 };
 
 static const struct