widl: Follow type references in procformat and typeformat string generation.
[wine] / server / named_pipe.c
1 /*
2  * Server-side pipe management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  * Copyright (C) 2001 Mike McCormack
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * TODO:
22  *   message mode
23  */
24
25 #include "config.h"
26 #include "wine/port.h"
27
28 #include <assert.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #ifdef HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
38 #endif
39 #include <time.h>
40 #include <unistd.h>
41 #ifdef HAVE_POLL_H
42 #include <poll.h>
43 #endif
44
45 #include "ntstatus.h"
46 #define WIN32_NO_STATUS
47 #include "windef.h"
48 #include "winternl.h"
49
50 #include "file.h"
51 #include "handle.h"
52 #include "thread.h"
53 #include "request.h"
54
55 enum pipe_state
56 {
57     ps_idle_server,
58     ps_wait_open,
59     ps_connected_server,
60     ps_wait_disconnect,
61     ps_disconnected_server,
62     ps_wait_connect
63 };
64
65 struct named_pipe;
66
67 struct pipe_server
68 {
69     struct object        obj;        /* object header */
70     struct fd           *fd;         /* pipe file descriptor */
71     struct list          entry;      /* entry in named pipe servers list */
72     enum pipe_state      state;      /* server state */
73     struct pipe_client  *client;     /* client that this server is connected to */
74     struct named_pipe   *pipe;
75     struct timeout_user *flush_poll;
76     struct event        *event;
77     struct list          wait_q;     /* only a single one can be queued */
78     unsigned int         options;    /* pipe options */
79 };
80
81 struct pipe_client
82 {
83     struct object        obj;        /* object header */
84     struct fd           *fd;         /* pipe file descriptor */
85     struct pipe_server  *server;     /* server that this client is connected to */
86     unsigned int         flags;      /* file flags */
87 };
88
89 struct named_pipe
90 {
91     struct object       obj;         /* object header */
92     unsigned int        flags;
93     unsigned int        maxinstances;
94     unsigned int        outsize;
95     unsigned int        insize;
96     unsigned int        timeout;
97     unsigned int        instances;
98     struct list         servers;     /* list of servers using this pipe */
99     struct list         waiters;     /* list of clients waiting to connect */
100 };
101
102 struct named_pipe_device
103 {
104     struct object       obj;         /* object header */
105     struct fd          *fd;          /* pseudo-fd for ioctls */
106     struct namespace   *pipes;       /* named pipe namespace */
107 };
108
109 static void named_pipe_dump( struct object *obj, int verbose );
110 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access );
111 static void named_pipe_destroy( struct object *obj );
112
113 static const struct object_ops named_pipe_ops =
114 {
115     sizeof(struct named_pipe),    /* size */
116     named_pipe_dump,              /* dump */
117     no_add_queue,                 /* add_queue */
118     NULL,                         /* remove_queue */
119     NULL,                         /* signaled */
120     NULL,                         /* satisfied */
121     no_signal,                    /* signal */
122     no_get_fd,                    /* get_fd */
123     named_pipe_map_access,        /* map_access */
124     no_lookup_name,               /* lookup_name */
125     no_close_handle,              /* close_handle */
126     named_pipe_destroy            /* destroy */
127 };
128
129 /* functions common to server and client */
130 static unsigned int pipe_map_access( struct object *obj, unsigned int access );
131
132 /* server end functions */
133 static void pipe_server_dump( struct object *obj, int verbose );
134 static struct fd *pipe_server_get_fd( struct object *obj );
135 static void pipe_server_destroy( struct object *obj);
136 static int pipe_server_flush( struct fd *fd, struct event **event );
137 static int pipe_server_get_info( struct fd *fd );
138
139 static const struct object_ops pipe_server_ops =
140 {
141     sizeof(struct pipe_server),   /* size */
142     pipe_server_dump,             /* dump */
143     default_fd_add_queue,         /* add_queue */
144     default_fd_remove_queue,      /* remove_queue */
145     default_fd_signaled,          /* signaled */
146     no_satisfied,                 /* satisfied */
147     no_signal,                    /* signal */
148     pipe_server_get_fd,           /* get_fd */
149     pipe_map_access,              /* map_access */
150     no_lookup_name,               /* lookup_name */
151     no_close_handle,              /* close_handle */
152     pipe_server_destroy           /* destroy */
153 };
154
155 static const struct fd_ops pipe_server_fd_ops =
156 {
157     default_fd_get_poll_events,     /* get_poll_events */
158     default_poll_event,           /* poll_event */
159     pipe_server_flush,            /* flush */
160     pipe_server_get_info,         /* get_file_info */
161     default_fd_queue_async,       /* queue_async */
162     default_fd_cancel_async,      /* cancel_async */
163 };
164
165 /* client end functions */
166 static void pipe_client_dump( struct object *obj, int verbose );
167 static struct fd *pipe_client_get_fd( struct object *obj );
168 static void pipe_client_destroy( struct object *obj );
169 static int pipe_client_flush( struct fd *fd, struct event **event );
170 static int pipe_client_get_info( struct fd *fd );
171
172 static const struct object_ops pipe_client_ops =
173 {
174     sizeof(struct pipe_client),   /* size */
175     pipe_client_dump,             /* dump */
176     default_fd_add_queue,         /* add_queue */
177     default_fd_remove_queue,      /* remove_queue */
178     default_fd_signaled,          /* signaled */
179     no_satisfied,                 /* satisfied */
180     no_signal,                    /* signal */
181     pipe_client_get_fd,           /* get_fd */
182     pipe_map_access,              /* map_access */
183     no_lookup_name,               /* lookup_name */
184     no_close_handle,              /* close_handle */
185     pipe_client_destroy           /* destroy */
186 };
187
188 static const struct fd_ops pipe_client_fd_ops =
189 {
190     default_fd_get_poll_events,   /* get_poll_events */
191     default_poll_event,           /* poll_event */
192     pipe_client_flush,            /* flush */
193     pipe_client_get_info,         /* get_file_info */
194     default_fd_queue_async,       /* queue_async */
195     default_fd_cancel_async       /* cancel_async */
196 };
197
198 static void named_pipe_device_dump( struct object *obj, int verbose );
199 static struct fd *named_pipe_device_get_fd( struct object *obj );
200 static struct object *named_pipe_device_lookup_name( struct object *obj,
201     struct unicode_str *name, unsigned int attr );
202 static void named_pipe_device_destroy( struct object *obj );
203 static int named_pipe_device_get_file_info( struct fd *fd );
204
205 static const struct object_ops named_pipe_device_ops =
206 {
207     sizeof(struct named_pipe_device), /* size */
208     named_pipe_device_dump,           /* dump */
209     no_add_queue,                     /* add_queue */
210     NULL,                             /* remove_queue */
211     NULL,                             /* signaled */
212     no_satisfied,                     /* satisfied */
213     no_signal,                        /* signal */
214     named_pipe_device_get_fd,         /* get_fd */
215     pipe_map_access,                  /* map_access */
216     named_pipe_device_lookup_name,    /* lookup_name */
217     no_close_handle,                  /* close_handle */
218     named_pipe_device_destroy         /* destroy */
219 };
220
221 static const struct fd_ops named_pipe_device_fd_ops =
222 {
223     default_fd_get_poll_events,       /* get_poll_events */
224     default_poll_event,               /* poll_event */
225     no_flush,                         /* flush */
226     named_pipe_device_get_file_info,  /* get_file_info */
227     default_fd_queue_async,           /* queue_async */
228     default_fd_cancel_async           /* cancel_async */
229 };
230
231 static void named_pipe_dump( struct object *obj, int verbose )
232 {
233     struct named_pipe *pipe = (struct named_pipe *) obj;
234     assert( obj->ops == &named_pipe_ops );
235     fprintf( stderr, "Named pipe " );
236     dump_object_name( &pipe->obj );
237     fprintf( stderr, "\n" );
238 }
239
240 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access )
241 {
242     if (access & GENERIC_READ)    access |= STANDARD_RIGHTS_READ;
243     if (access & GENERIC_WRITE)   access |= STANDARD_RIGHTS_WRITE | FILE_CREATE_PIPE_INSTANCE;
244     if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE;
245     if (access & GENERIC_ALL)     access |= STANDARD_RIGHTS_ALL;
246     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
247 }
248
249 static void pipe_server_dump( struct object *obj, int verbose )
250 {
251     struct pipe_server *server = (struct pipe_server *) obj;
252     assert( obj->ops == &pipe_server_ops );
253     fprintf( stderr, "Named pipe server pipe=%p state=%d\n", server->pipe, server->state );
254 }
255
256 static void pipe_client_dump( struct object *obj, int verbose )
257 {
258     struct pipe_client *client = (struct pipe_client *) obj;
259     assert( obj->ops == &pipe_client_ops );
260     fprintf( stderr, "Named pipe client server=%p\n", client->server );
261 }
262
263 static void named_pipe_destroy( struct object *obj)
264 {
265     struct named_pipe *pipe = (struct named_pipe *) obj;
266
267     assert( list_empty( &pipe->servers ) );
268     assert( !pipe->instances );
269     async_terminate_queue( &pipe->waiters, STATUS_HANDLES_CLOSED );
270 }
271
272 static struct fd *pipe_client_get_fd( struct object *obj )
273 {
274     struct pipe_client *client = (struct pipe_client *) obj;
275     if (client->fd)
276         return (struct fd *) grab_object( client->fd );
277     set_error( STATUS_PIPE_DISCONNECTED );
278     return NULL;
279 }
280
281 static struct fd *pipe_server_get_fd( struct object *obj )
282 {
283     struct pipe_server *server = (struct pipe_server *) obj;
284
285     switch(server->state)
286     {
287     case ps_connected_server:
288     case ps_wait_disconnect:
289         assert( server->fd );
290         return (struct fd *) grab_object( server->fd );
291
292     case ps_wait_open:
293     case ps_idle_server:
294         set_error( STATUS_PIPE_LISTENING );
295         break;
296
297     case ps_disconnected_server:
298     case ps_wait_connect:
299         set_error( STATUS_PIPE_DISCONNECTED );
300         break;
301     }
302     return NULL;
303 }
304
305
306 static void notify_empty( struct pipe_server *server )
307 {
308     if (!server->flush_poll)
309         return;
310     assert( server->state == ps_connected_server );
311     assert( server->event );
312     remove_timeout_user( server->flush_poll );
313     server->flush_poll = NULL;
314     set_event( server->event );
315     release_object( server->event );
316     server->event = NULL;
317 }
318
319 static void do_disconnect( struct pipe_server *server )
320 {
321     /* we may only have a server fd, if the client disconnected */
322     if (server->client)
323     {
324         assert( server->client->server == server );
325         assert( server->client->fd );
326         release_object( server->client->fd );
327         server->client->fd = NULL;
328     }
329     assert( server->fd );
330     release_object( server->fd );
331     server->fd = NULL;
332 }
333
334 static unsigned int pipe_map_access( struct object *obj, unsigned int access )
335 {
336     if (access & GENERIC_READ)    access |= FILE_GENERIC_READ;
337     if (access & GENERIC_WRITE)   access |= FILE_GENERIC_WRITE;
338     if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
339     if (access & GENERIC_ALL)     access |= FILE_ALL_ACCESS;
340     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
341 }
342
343 static void pipe_server_destroy( struct object *obj)
344 {
345     struct pipe_server *server = (struct pipe_server *)obj;
346
347     assert( obj->ops == &pipe_server_ops );
348
349     if (server->fd)
350     {
351         notify_empty( server );
352         do_disconnect( server );
353     }
354
355     if (server->client)
356     {
357         server->client->server = NULL;
358         server->client = NULL;
359     }
360
361     async_terminate_head( &server->wait_q, STATUS_HANDLES_CLOSED );
362
363     assert( server->pipe->instances );
364     server->pipe->instances--;
365
366     list_remove( &server->entry );
367     release_object( server->pipe );
368 }
369
370 static void pipe_client_destroy( struct object *obj)
371 {
372     struct pipe_client *client = (struct pipe_client *)obj;
373     struct pipe_server *server = client->server;
374
375     assert( obj->ops == &pipe_client_ops );
376
377     if (server)
378     {
379         notify_empty( server );
380
381         switch(server->state)
382         {
383         case ps_connected_server:
384             /* Don't destroy the server's fd here as we can't
385                do a successful flush without it. */
386             server->state = ps_wait_disconnect;
387             release_object( client->fd );
388             client->fd = NULL;
389             break;
390         case ps_disconnected_server:
391             server->state = ps_wait_connect;
392             break;
393         case ps_idle_server:
394         case ps_wait_open:
395         case ps_wait_disconnect:
396         case ps_wait_connect:
397             assert( 0 );
398         }
399         assert( server->client );
400         server->client = NULL;
401         client->server = NULL;
402     }
403     assert( !client->fd );
404 }
405
406 static void named_pipe_device_dump( struct object *obj, int verbose )
407 {
408     assert( obj->ops == &named_pipe_device_ops );
409     fprintf( stderr, "Named pipe device\n" );
410 }
411
412 static struct fd *named_pipe_device_get_fd( struct object *obj )
413 {
414     struct named_pipe_device *device = (struct named_pipe_device *)obj;
415     return (struct fd *)grab_object( device->fd );
416 }
417
418 static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name,
419                                                      unsigned int attr )
420 {
421     struct named_pipe_device *device = (struct named_pipe_device*)obj;
422     struct object *found;
423
424     assert( obj->ops == &named_pipe_device_ops );
425     assert( device->pipes );
426
427     if ((found = find_object( device->pipes, name, attr | OBJ_CASE_INSENSITIVE )))
428         name->len = 0;
429
430     return found;
431 }
432
433 static void named_pipe_device_destroy( struct object *obj )
434 {
435     struct named_pipe_device *device = (struct named_pipe_device*)obj;
436     assert( obj->ops == &named_pipe_device_ops );
437     if (device->fd) release_object( device->fd );
438     if (device->pipes) free( device->pipes );
439 }
440
441 static int named_pipe_device_get_file_info( struct fd *fd )
442 {
443     return 0;
444 }
445
446 struct named_pipe_device *create_named_pipe_device( struct directory *root,
447                                                     const struct unicode_str *name )
448 {
449     struct named_pipe_device *dev;
450
451     if ((dev = create_named_object_dir( root, name, 0, &named_pipe_device_ops )) &&
452         get_error() != STATUS_OBJECT_NAME_EXISTS)
453     {
454         dev->pipes = NULL;
455         if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj )) ||
456             !(dev->pipes = create_namespace( 7 )))
457         {
458             release_object( dev );
459             dev = NULL;
460         }
461     }
462     return dev;
463 }
464
465 static int pipe_data_remaining( struct pipe_server *server )
466 {
467     struct pollfd pfd;
468     int fd;
469
470     assert( server->client );
471
472     fd = get_unix_fd( server->client->fd );
473     if (fd < 0)
474         return 0;
475     pfd.fd = fd;
476     pfd.events = POLLIN;
477     pfd.revents = 0;
478
479     if (0 > poll( &pfd, 1, 0 ))
480         return 0;
481  
482     return pfd.revents&POLLIN;
483 }
484
485 static void check_flushed( void *arg )
486 {
487     struct pipe_server *server = (struct pipe_server*) arg;
488
489     assert( server->event );
490     if (pipe_data_remaining( server ))
491     {
492         struct timeval tv;
493
494         gettimeofday( &tv, NULL );
495         add_timeout( &tv, 100 );
496         server->flush_poll = add_timeout_user( &tv, check_flushed, server );
497     }
498     else
499     {
500         /* notify_empty( server ); */
501         server->flush_poll = NULL;
502         set_event( server->event );
503         release_object( server->event );
504         server->event = NULL;
505     }
506 }
507
508 static int pipe_server_flush( struct fd *fd, struct event **event )
509 {
510     struct pipe_server *server = get_fd_user( fd );
511
512     if (!server)
513         return 0;
514
515     if (server->state != ps_connected_server)
516         return 0;
517
518     /* FIXME: if multiple threads flush the same pipe,
519               maybe should create a list of processes to notify */
520     if (server->flush_poll)
521         return 0;
522
523     if (pipe_data_remaining( server ))
524     {
525         struct timeval tv;
526
527         /* this kind of sux - 
528            there's no unix way to be alerted when a pipe becomes empty */
529         server->event = create_event( NULL, NULL, 0, 0, 0 );
530         if (!server->event)
531             return 0;
532         gettimeofday( &tv, NULL );
533         add_timeout( &tv, 100 );
534         server->flush_poll = add_timeout_user( &tv, check_flushed, server );
535         *event = server->event;
536     }
537
538     return 0; 
539 }
540
541 static int pipe_client_flush( struct fd *fd, struct event **event )
542 {
543     /* FIXME: what do we have to do for this? */
544     return 0;
545 }
546
547 static inline int is_overlapped( unsigned int options )
548 {
549     return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
550 }
551
552 static int pipe_server_get_info( struct fd *fd )
553 {
554     struct pipe_server *server = get_fd_user( fd );
555     int flags = FD_FLAG_AVAILABLE;
556  
557     if (is_overlapped( server->options )) flags |= FD_FLAG_OVERLAPPED;
558
559     return flags;
560 }
561
562 static int pipe_client_get_info( struct fd *fd )
563 {
564     struct pipe_client *client = get_fd_user( fd );
565     int flags = FD_FLAG_AVAILABLE;
566
567     if (is_overlapped( client->flags )) flags |= FD_FLAG_OVERLAPPED;
568
569     return flags;
570 }
571
572 static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name,
573                                              unsigned int attr )
574 {
575     struct object *obj;
576     struct named_pipe *pipe = NULL;
577     struct unicode_str new_name;
578
579     if (!name || !name->len) return alloc_object( &named_pipe_ops );
580
581     if (!(obj = find_object_dir( root, name, attr, &new_name ))) return NULL;
582     if (!new_name.len)
583     {
584         if (attr & OBJ_OPENIF && obj->ops == &named_pipe_ops)
585             set_error( STATUS_OBJECT_NAME_EXISTS );
586         else
587         {
588             release_object( obj );
589             obj = NULL;
590             if (attr & OBJ_OPENIF)
591                 set_error( STATUS_OBJECT_TYPE_MISMATCH );
592             else
593                 set_error( STATUS_OBJECT_NAME_COLLISION );
594         }
595         return (struct named_pipe *)obj;
596     }
597
598     if (obj->ops != &named_pipe_device_ops)
599         set_error( STATUS_OBJECT_TYPE_MISMATCH );
600     else
601     {
602         struct named_pipe_device *dev = (struct named_pipe_device *)obj;
603         if ((pipe = create_object( dev->pipes, &named_pipe_ops, &new_name, NULL )))
604             clear_error();
605     }
606
607     release_object( obj );
608     return pipe;
609 }
610
611 static struct pipe_server *get_pipe_server_obj( struct process *process,
612                                 obj_handle_t handle, unsigned int access )
613 {
614     struct object *obj;
615     obj = get_handle_obj( process, handle, access, &pipe_server_ops );
616     return (struct pipe_server *) obj;
617 }
618
619 static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options )
620 {
621     struct pipe_server *server;
622
623     server = alloc_object( &pipe_server_ops );
624     if (!server)
625         return NULL;
626
627     server->fd = NULL;
628     server->pipe = pipe;
629     server->state = ps_idle_server;
630     server->client = NULL;
631     server->flush_poll = NULL;
632     server->options = options;
633     list_init( &server->wait_q );
634
635     list_add_head( &pipe->servers, &server->entry );
636     grab_object( pipe );
637
638     return server;
639 }
640
641 static struct pipe_client *create_pipe_client( struct pipe_server *server, unsigned int flags )
642 {
643     struct pipe_client *client;
644
645     client = alloc_object( &pipe_client_ops );
646     if (!client)
647         return NULL;
648
649     client->fd = NULL;
650     client->server = server;
651     client->flags = flags;
652
653     return client;
654 }
655
656 static inline struct pipe_server *find_server( struct named_pipe *pipe, enum pipe_state state )
657 {
658     struct pipe_server *server;
659
660     LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
661     {
662         if (server->state == state) return (struct pipe_server *)grab_object( server );
663     }
664     return NULL;
665 }
666
667 static inline struct pipe_server *find_server2( struct named_pipe *pipe,
668                                                 enum pipe_state state1, enum pipe_state state2 )
669 {
670     struct pipe_server *server;
671
672     LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
673     {
674         if (server->state == state1 || server->state == state2)
675             return (struct pipe_server *)grab_object( server );
676     }
677     return NULL;
678 }
679
680 DECL_HANDLER(create_named_pipe)
681 {
682     struct named_pipe *pipe;
683     struct pipe_server *server;
684     struct unicode_str name;
685     struct directory *root = NULL;
686
687     reply->handle = 0;
688     get_req_unicode_str( &name );
689     if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
690         return;
691
692     pipe = create_named_pipe( root, &name, req->attributes | OBJ_OPENIF );
693
694     if (root) release_object( root );
695     if (!pipe) return;
696
697     if (get_error() != STATUS_OBJECT_NAME_EXISTS)
698     {
699         /* initialize it if it didn't already exist */
700         pipe->instances = 0;
701         list_init( &pipe->servers );
702         list_init( &pipe->waiters );
703         pipe->insize = req->insize;
704         pipe->outsize = req->outsize;
705         pipe->maxinstances = req->maxinstances;
706         pipe->timeout = req->timeout;
707         pipe->flags = req->flags;
708     }
709     else
710     {
711         if (pipe->maxinstances <= pipe->instances)
712         {
713             set_error( STATUS_INSTANCE_NOT_AVAILABLE );
714             release_object( pipe );
715             return;
716         }
717         if ((pipe->maxinstances != req->maxinstances) ||
718             (pipe->timeout != req->timeout) ||
719             (pipe->flags != req->flags))
720         {
721             set_error( STATUS_ACCESS_DENIED );
722             release_object( pipe );
723             return;
724         }
725         set_error( 0 );  /* clear the name collision */
726     }
727
728     server = create_pipe_server( pipe, req->options );
729     if (server)
730     {
731         reply->handle = alloc_handle( current->process, server, req->access, req->attributes );
732         server->pipe->instances++;
733         release_object( server );
734     }
735
736     release_object( pipe );
737 }
738
739 DECL_HANDLER(open_named_pipe)
740 {
741     struct pipe_server *server;
742     struct pipe_client *client;
743     struct unicode_str name;
744     struct directory *root = NULL;
745     struct named_pipe *pipe;
746     int fds[2];
747
748     get_req_unicode_str( &name );
749     if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
750         return;
751
752     pipe = open_object_dir( root, &name, req->attributes, &named_pipe_ops );
753
754     if (root) release_object( root );
755     if (!pipe) return;
756
757     server = find_server2( pipe, ps_idle_server, ps_wait_open );
758     release_object( pipe );
759
760     if (!server)
761     {
762         set_error( STATUS_PIPE_NOT_AVAILABLE );
763         return;
764     }
765
766     client = create_pipe_client( server, req->flags );
767     if (client)
768     {
769         if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
770         {
771             int res = 0;
772
773             assert( !client->fd );
774             assert( !server->fd );
775
776             /* for performance reasons, only set nonblocking mode when using
777              * overlapped I/O. Otherwise, we will be doing too much busy
778              * looping */
779             if (is_overlapped( req->flags ))
780                 res = fcntl( fds[1], F_SETFL, O_NONBLOCK );
781             if ((res != -1) && is_overlapped( server->options ))
782                 res = fcntl( fds[0], F_SETFL, O_NONBLOCK );
783
784             client->fd = create_anonymous_fd( &pipe_client_fd_ops,
785                                             fds[1], &client->obj );
786             server->fd = create_anonymous_fd( &pipe_server_fd_ops,
787                                             fds[0], &server->obj );
788             if (client->fd && server->fd && res != 1)
789             {
790                 if (server->state == ps_wait_open)
791                     async_terminate_head( &server->wait_q, STATUS_SUCCESS );
792                 assert( list_empty( &server->wait_q ) );
793                 server->state = ps_connected_server;
794                 server->client = client;
795                 client->server = server;
796                 reply->handle = alloc_handle( current->process, client, req->access, req->attributes );
797             }
798         }
799         else
800             file_set_error();
801
802         release_object( client );
803     }
804     release_object( server );
805 }
806
807 DECL_HANDLER(connect_named_pipe)
808 {
809     struct pipe_server *server;
810
811     server = get_pipe_server_obj(current->process, req->handle, 0);
812     if (!server)
813         return;
814
815     switch(server->state)
816     {
817     case ps_idle_server:
818     case ps_wait_connect:
819         assert( !server->fd );
820         server->state = ps_wait_open;
821         create_async( current, NULL, &server->wait_q,
822                       req->func, req->event, NULL );
823         async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
824         break;
825     case ps_connected_server:
826         assert( server->fd );
827         set_error( STATUS_PIPE_CONNECTED );
828         break;
829     case ps_disconnected_server:
830         set_error( STATUS_PIPE_BUSY );
831         break;
832     case ps_wait_disconnect:
833         set_error( STATUS_NO_DATA_DETECTED );
834         break;
835     case ps_wait_open:
836         set_error( STATUS_INVALID_HANDLE );
837         break;
838     }
839
840     release_object(server);
841 }
842
843 DECL_HANDLER(wait_named_pipe)
844 {
845     struct named_pipe_device *device;
846     struct named_pipe *pipe;
847     struct pipe_server *server;
848     struct unicode_str name;
849
850     device = (struct named_pipe_device *)get_handle_obj( current->process, req->handle,
851                                                          FILE_READ_ATTRIBUTES, &named_pipe_device_ops );
852     if (!device) return;
853
854     get_req_unicode_str( &name );
855     pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE );
856     release_object( device );
857     if (!pipe)
858     {
859         set_error( STATUS_PIPE_NOT_AVAILABLE );
860         return;
861     }
862     server = find_server( pipe, ps_wait_open );
863     if (server)
864     {
865         /* there's already a server waiting for a client to connect */
866         thread_queue_apc( current, NULL, req->func, APC_ASYNC_IO,
867                           1, req->event, NULL, (void *)STATUS_SUCCESS );
868         release_object( server );
869     }
870     else
871     {
872         int timeout;
873         if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT)
874             timeout = pipe->timeout;
875         else
876             timeout = req->timeout;
877
878         if (req->timeout == NMPWAIT_WAIT_FOREVER)
879             create_async( current, NULL, &pipe->waiters,
880                           req->func, req->event, NULL );
881         else
882             create_async( current, &timeout, &pipe->waiters,
883                           req->func, req->event, NULL );
884     }
885
886     release_object( pipe );
887 }
888
889 DECL_HANDLER(disconnect_named_pipe)
890 {
891     struct pipe_server *server;
892
893     reply->fd = -1;
894     server = get_pipe_server_obj( current->process, req->handle, 0 );
895     if (!server)
896         return;
897     switch(server->state)
898     {
899     case ps_connected_server:
900         assert( server->fd );
901         assert( server->client );
902         assert( server->client->fd );
903
904         notify_empty( server );
905
906         /* Dump the client and server fds, but keep the pointers
907            around - client loses all waiting data */
908         server->state = ps_disconnected_server;
909         do_disconnect( server );
910         reply->fd = flush_cached_fd( current->process, req->handle );
911         break;
912
913     case ps_wait_disconnect:
914         assert( !server->client );
915         assert( server->fd );
916         do_disconnect( server );
917         server->state = ps_wait_connect;
918         reply->fd = flush_cached_fd( current->process, req->handle );
919         break;
920
921     case ps_idle_server:
922     case ps_wait_open:
923     case ps_disconnected_server:
924     case ps_wait_connect:
925         set_error( STATUS_PIPE_DISCONNECTED );
926         break;
927     }
928     release_object( server );
929 }
930
931 DECL_HANDLER(get_named_pipe_info)
932 {
933     struct pipe_server *server;
934
935     server = get_pipe_server_obj( current->process, req->handle, 0 );
936     if (!server)
937         return;
938
939     reply->flags        = server->pipe->flags;
940     reply->maxinstances = server->pipe->maxinstances;
941     reply->insize       = server->pipe->insize;
942     reply->outsize      = server->pipe->outsize;
943
944     release_object(server);
945 }