Make ConnectNamedPipe work in overlapped mode.

diff --git a/server/named_pipe.c b/server/named_pipe.c
index edc92e8..57013d9 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -48,7 +48,9 @@
     struct named_pipe  *pipe;
     struct pipe_user   *next;
     struct pipe_user   *prev;
-    struct event       *event;
+    void               *thread;
+    void               *func;
+    void               *overlapped;
 };
 
 struct named_pipe
@@ -122,18 +124,28 @@
     assert( !pipe->users );
 }
 
+static void notify_waiter( struct pipe_user *user, unsigned int status)
+{
+    if(user->thread && user->func && user->overlapped)
+    {
+        /* queue a system APC, to notify a waiting thread */
+        thread_queue_apc(user->thread,NULL,user->func,
+            APC_ASYNC,1,2,user->overlapped,status);
+    }
+    user->thread = NULL;
+    user->func = NULL;
+    user->overlapped=NULL;
+}
+
 static void pipe_user_destroy( struct object *obj)
 {
     struct pipe_user *user = (struct pipe_user *)obj;
 
     assert( obj->ops == &pipe_user_ops );
 
-    if(user->event)
-    {
-        /* FIXME: signal waiter of failure */
-        release_object(user->event);
-        user->event = NULL;
-    }
+    if(user->overlapped)
+        notify_waiter(user,STATUS_HANDLES_CLOSED);
+
     if(user->other)
     {
         close(user->other->obj.fd);
@@ -217,8 +229,10 @@
 
     user->pipe = pipe;
     user->state = ps_none;
-    user->event = NULL;   /* thread wait on this pipe */
     user->other = NULL;
+    user->thread = NULL;
+    user->func = NULL;
+    user->overlapped = NULL;
 
     /* add to list of pipe users */
     if ((user->next = pipe->users)) user->next->prev = user;
@@ -301,9 +315,7 @@
                 if( (user = create_pipe_user (pipe, fds[1])) )
                 {
                     partner->obj.fd = fds[0];
-                    set_event(partner->event);
-                    release_object(partner->event);
-                    partner->event = NULL;
+                    notify_waiter(partner,STATUS_SUCCESS);
                     partner->state = ps_connected_server;
                     partner->other = user;
                     user->state = ps_connected_client;
@@ -334,7 +346,6 @@
 DECL_HANDLER(connect_named_pipe)
 {
     struct pipe_user *user, *partner;
-    struct event *event;
 
     user = get_pipe_user_obj(current->process, req->handle, 0);
     if(!user)
@@ -347,16 +358,14 @@
     else
     {
         user->state = ps_wait_open;
-        event = get_event_obj(current->process, req->event, 0);
-        if(event)
-            user->event = event;
+        user->thread = current;
+        user->func = req->func;
+        user->overlapped = req->overlapped;
 
         /* notify all waiters that a pipe just became available */
         while( (partner = find_partner(user->pipe,ps_wait_connect)) )
         {
-            set_event(partner->event);
-            release_object(partner->event);
-            partner->event = NULL;
+            notify_waiter(partner,STATUS_SUCCESS);
             release_object(partner);
             release_object(partner);
         }
@@ -367,13 +376,8 @@
 
 DECL_HANDLER(wait_named_pipe)
 {
-    struct event *event;
     struct named_pipe *pipe;
 
-    event = get_event_obj(current->process, req->event, 0);
-    if(!event)
-        return;
-
     pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) );
     if( pipe )
     {
@@ -385,7 +389,10 @@
             set_error(STATUS_SUCCESS);
             if( (partner = find_partner(pipe,ps_wait_open)) )
             {
-                set_event(event);
+                /* this should use notify_waiter, 
+                   but no pipe_user object exists now... */
+                thread_queue_apc(current,NULL,req->func,
+                    APC_ASYNC,1,2,req->overlapped,STATUS_SUCCESS);
                 release_object(partner);
             }
             else
@@ -394,8 +401,10 @@
 
                 if( (user = create_pipe_user (pipe, -1)) )
                 {
-                    user->event = (struct event *)grab_object( event );
                     user->state = ps_wait_connect;
+                    user->thread = current;
+                    user->func = req->func;
+                    user->overlapped = req->overlapped;
                     /* don't release it */
                 }
             }
@@ -406,7 +415,6 @@
         }
         release_object(pipe);
     }
-    release_object(event);
 }
 
 DECL_HANDLER(disconnect_named_pipe)
diff --git a/server/protocol.def b/server/protocol.def
index 07c7f79..5e6c8a0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1392,14 +1392,16 @@
 /* Connect to a named pipe */
 @REQ(connect_named_pipe)
     handle_t       handle;
-    handle_t       event;      /* set this event when it's ready */
+    void*          overlapped;
+    void*          func;
 @END
 
 
 /* Wait for a named pipe */
 @REQ(wait_named_pipe)
     unsigned int   timeout;
-    handle_t       event;       /* set this event when it's ready */
+    void*          overlapped;
+    void*          func;
     VARARG(filename,string);    /* pipe name */
 @END
 
diff --git a/server/trace.c b/server/trace.c
index ba98c0a..012286b 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1661,13 +1661,15 @@
 static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
-    fprintf( stderr, " event=%d", req->event );
+    fprintf( stderr, " overlapped=%p,", req->overlapped );
+    fprintf( stderr, " func=%p", req->func );
 }
 
 static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *req )
 {
     fprintf( stderr, " timeout=%08x,", req->timeout );
-    fprintf( stderr, " event=%d,", req->event );
+    fprintf( stderr, " overlapped=%p,", req->overlapped );
+    fprintf( stderr, " func=%p,", req->func );
     fprintf( stderr, " filename=" );
     cur_pos += dump_varargs_string( req );
 }