Take advantage of the recursive nature of .gitignore for Makefile entries.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 void create_named_pipe_device( struct directory *root, const struct unicode_str *name )
447 {
448     struct named_pipe_device *dev;
449
450     if ((dev = create_named_object_dir( root, name, 0, &named_pipe_device_ops )) &&
451         get_error() != STATUS_OBJECT_NAME_EXISTS)
452     {
453         dev->pipes = NULL;
454         if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj )) ||
455             !(dev->pipes = create_namespace( 7 )))
456         {
457             release_object( dev );
458             dev = NULL;
459         }
460     }
461     if (dev) make_object_static( &dev->obj );
462 }
463
464 static int pipe_data_remaining( struct pipe_server *server )
465 {
466     struct pollfd pfd;
467     int fd;
468
469     assert( server->client );
470
471     fd = get_unix_fd( server->client->fd );
472     if (fd < 0)
473         return 0;
474     pfd.fd = fd;
475     pfd.events = POLLIN;
476     pfd.revents = 0;
477
478     if (0 > poll( &pfd, 1, 0 ))
479         return 0;
480  
481     return pfd.revents&POLLIN;
482 }
483
484 static void check_flushed( void *arg )
485 {
486     struct pipe_server *server = (struct pipe_server*) arg;
487
488     assert( server->event );
489     if (pipe_data_remaining( server ))
490     {
491         struct timeval tv;
492
493         gettimeofday( &tv, NULL );
494         add_timeout( &tv, 100 );
495         server->flush_poll = add_timeout_user( &tv, check_flushed, server );
496     }
497     else
498     {
499         /* notify_empty( server ); */
500         server->flush_poll = NULL;
501         set_event( server->event );
502         release_object( server->event );
503         server->event = NULL;
504     }
505 }
506
507 static int pipe_server_flush( struct fd *fd, struct event **event )
508 {
509     struct pipe_server *server = get_fd_user( fd );
510
511     if (!server)
512         return 0;
513
514     if (server->state != ps_connected_server)
515         return 0;
516
517     /* FIXME: if multiple threads flush the same pipe,
518               maybe should create a list of processes to notify */
519     if (server->flush_poll)
520         return 0;
521
522     if (pipe_data_remaining( server ))
523     {
524         struct timeval tv;
525
526         /* this kind of sux - 
527            there's no unix way to be alerted when a pipe becomes empty */
528         server->event = create_event( NULL, NULL, 0, 0, 0 );
529         if (!server->event)
530             return 0;
531         gettimeofday( &tv, NULL );
532         add_timeout( &tv, 100 );
533         server->flush_poll = add_timeout_user( &tv, check_flushed, server );
534         *event = server->event;
535     }
536
537     return 0; 
538 }
539
540 static int pipe_client_flush( struct fd *fd, struct event **event )
541 {
542     /* FIXME: what do we have to do for this? */
543     return 0;
544 }
545
546 static inline int is_overlapped( unsigned int options )
547 {
548     return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
549 }
550
551 static int pipe_server_get_info( struct fd *fd )
552 {
553     struct pipe_server *server = get_fd_user( fd );
554     int flags = FD_FLAG_AVAILABLE;
555  
556     if (is_overlapped( server->options )) flags |= FD_FLAG_OVERLAPPED;
557
558     return flags;
559 }
560
561 static int pipe_client_get_info( struct fd *fd )
562 {
563     struct pipe_client *client = get_fd_user( fd );
564     int flags = FD_FLAG_AVAILABLE;
565
566     if (is_overlapped( client->flags )) flags |= FD_FLAG_OVERLAPPED;
567
568     return flags;
569 }
570
571 static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name,
572                                              unsigned int attr )
573 {
574     struct object *obj;
575     struct named_pipe *pipe = NULL;
576     struct unicode_str new_name;
577
578     if (!name || !name->len) return alloc_object( &named_pipe_ops );
579
580     if (!(obj = find_object_dir( root, name, attr, &new_name ))) return NULL;
581     if (!new_name.len)
582     {
583         if (attr & OBJ_OPENIF && obj->ops == &named_pipe_ops)
584             set_error( STATUS_OBJECT_NAME_EXISTS );
585         else
586         {
587             release_object( obj );
588             obj = NULL;
589             if (attr & OBJ_OPENIF)
590                 set_error( STATUS_OBJECT_TYPE_MISMATCH );
591             else
592                 set_error( STATUS_OBJECT_NAME_COLLISION );
593         }
594         return (struct named_pipe *)obj;
595     }
596
597     if (obj->ops != &named_pipe_device_ops)
598         set_error( STATUS_OBJECT_TYPE_MISMATCH );
599     else
600     {
601         struct named_pipe_device *dev = (struct named_pipe_device *)obj;
602         if ((pipe = create_object( dev->pipes, &named_pipe_ops, &new_name, NULL )))
603             clear_error();
604     }
605
606     release_object( obj );
607     return pipe;
608 }
609
610 static struct pipe_server *get_pipe_server_obj( struct process *process,
611                                 obj_handle_t handle, unsigned int access )
612 {
613     struct object *obj;
614     obj = get_handle_obj( process, handle, access, &pipe_server_ops );
615     return (struct pipe_server *) obj;
616 }
617
618 static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options )
619 {
620     struct pipe_server *server;
621
622     server = alloc_object( &pipe_server_ops );
623     if (!server)
624         return NULL;
625
626     server->fd = NULL;
627     server->pipe = pipe;
628     server->state = ps_idle_server;
629     server->client = NULL;
630     server->flush_poll = NULL;
631     server->options = options;
632     list_init( &server->wait_q );
633
634     list_add_head( &pipe->servers, &server->entry );
635     grab_object( pipe );
636
637     return server;
638 }
639
640 static struct pipe_client *create_pipe_client( unsigned int flags )
641 {
642     struct pipe_client *client;
643
644     client = alloc_object( &pipe_client_ops );
645     if (!client)
646         return NULL;
647
648     client->fd = NULL;
649     client->server = NULL;
650     client->flags = flags;
651
652     return client;
653 }
654
655 static inline struct pipe_server *find_server( struct named_pipe *pipe, enum pipe_state state )
656 {
657     struct pipe_server *server;
658
659     LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
660     {
661         if (server->state == state) return (struct pipe_server *)grab_object( server );
662     }
663     return NULL;
664 }
665
666 static inline struct pipe_server *find_server2( struct named_pipe *pipe,
667                                                 enum pipe_state state1, enum pipe_state state2 )
668 {
669     struct pipe_server *server;
670
671     LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
672     {
673         if (server->state == state1 || server->state == state2)
674             return (struct pipe_server *)grab_object( server );
675     }
676     return NULL;
677 }
678
679 DECL_HANDLER(create_named_pipe)
680 {
681     struct named_pipe *pipe;
682     struct pipe_server *server;
683     struct unicode_str name;
684     struct directory *root = NULL;
685
686     reply->handle = 0;
687     get_req_unicode_str( &name );
688     if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
689         return;
690
691     pipe = create_named_pipe( root, &name, req->attributes | OBJ_OPENIF );
692
693     if (root) release_object( root );
694     if (!pipe) return;
695
696     if (get_error() != STATUS_OBJECT_NAME_EXISTS)
697     {
698         /* initialize it if it didn't already exist */
699         pipe->instances = 0;
700         list_init( &pipe->servers );
701         list_init( &pipe->waiters );
702         pipe->insize = req->insize;
703         pipe->outsize = req->outsize;
704         pipe->maxinstances = req->maxinstances;
705         pipe->timeout = req->timeout;
706         pipe->flags = req->flags;
707     }
708     else
709     {
710         if (pipe->maxinstances <= pipe->instances)
711         {
712             set_error( STATUS_INSTANCE_NOT_AVAILABLE );
713             release_object( pipe );
714             return;
715         }
716         if ((pipe->maxinstances != req->maxinstances) ||
717             (pipe->timeout != req->timeout) ||
718             (pipe->flags != req->flags))
719         {
720             set_error( STATUS_ACCESS_DENIED );
721             release_object( pipe );
722             return;
723         }
724         clear_error(); /* clear the name collision */
725     }
726
727     server = create_pipe_server( pipe, req->options );
728     if (server)
729     {
730         reply->handle = alloc_handle( current->process, server, req->access, req->attributes );
731         server->pipe->instances++;
732         release_object( server );
733     }
734
735     release_object( pipe );
736 }
737
738 DECL_HANDLER(open_named_pipe)
739 {
740     struct pipe_server *server;
741     struct pipe_client *client;
742     struct unicode_str name;
743     struct directory *root = NULL;
744     struct named_pipe *pipe;
745     int fds[2];
746
747     get_req_unicode_str( &name );
748     if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
749         return;
750
751     pipe = open_object_dir( root, &name, req->attributes, &named_pipe_ops );
752
753     if (root) release_object( root );
754     if (!pipe) return;
755
756     server = find_server2( pipe, ps_idle_server, ps_wait_open );
757     release_object( pipe );
758
759     if (!server)
760     {
761         set_error( STATUS_PIPE_NOT_AVAILABLE );
762         return;
763     }
764
765     client = create_pipe_client( req->flags );
766     if (client)
767     {
768         if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
769         {
770             int res = 0;
771
772             assert( !client->fd );
773             assert( !server->fd );
774
775             /* for performance reasons, only set nonblocking mode when using
776              * overlapped I/O. Otherwise, we will be doing too much busy
777              * looping */
778             if (is_overlapped( req->flags ))
779                 res = fcntl( fds[1], F_SETFL, O_NONBLOCK );
780             if ((res != -1) && is_overlapped( server->options ))
781                 res = fcntl( fds[0], F_SETFL, O_NONBLOCK );
782
783             client->fd = create_anonymous_fd( &pipe_client_fd_ops,
784                                             fds[1], &client->obj );
785             server->fd = create_anonymous_fd( &pipe_server_fd_ops,
786                                             fds[0], &server->obj );
787             if (client->fd && server->fd && res != 1)
788             {
789                 if (server->state == ps_wait_open)
790                     async_terminate_head( &server->wait_q, STATUS_SUCCESS );
791                 assert( list_empty( &server->wait_q ) );
792                 server->state = ps_connected_server;
793                 server->client = client;
794                 client->server = server;
795                 reply->handle = alloc_handle( current->process, client, req->access, req->attributes );
796             }
797         }
798         else
799             file_set_error();
800
801         release_object( client );
802     }
803     release_object( server );
804 }
805
806 DECL_HANDLER(connect_named_pipe)
807 {
808     struct pipe_server *server;
809
810     server = get_pipe_server_obj(current->process, req->handle, 0);
811     if (!server)
812         return;
813
814     switch(server->state)
815     {
816     case ps_idle_server:
817     case ps_wait_connect:
818         assert( !server->fd );
819         server->state = ps_wait_open;
820         create_async( current, NULL, &server->wait_q,
821                       req->func, req->event, NULL );
822         async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
823         break;
824     case ps_connected_server:
825         assert( server->fd );
826         set_error( STATUS_PIPE_CONNECTED );
827         break;
828     case ps_disconnected_server:
829         set_error( STATUS_PIPE_BUSY );
830         break;
831     case ps_wait_disconnect:
832         set_error( STATUS_NO_DATA_DETECTED );
833         break;
834     case ps_wait_open:
835         set_error( STATUS_INVALID_HANDLE );
836         break;
837     }
838
839     release_object(server);
840 }
841
842 DECL_HANDLER(wait_named_pipe)
843 {
844     struct named_pipe_device *device;
845     struct named_pipe *pipe;
846     struct pipe_server *server;
847     struct unicode_str name;
848
849     device = (struct named_pipe_device *)get_handle_obj( current->process, req->handle,
850                                                          FILE_READ_ATTRIBUTES, &named_pipe_device_ops );
851     if (!device) return;
852
853     get_req_unicode_str( &name );
854     pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE );
855     release_object( device );
856     if (!pipe)
857     {
858         set_error( STATUS_PIPE_NOT_AVAILABLE );
859         return;
860     }
861     server = find_server( pipe, ps_wait_open );
862     if (server)
863     {
864         /* there's already a server waiting for a client to connect */
865         thread_queue_apc( current, NULL, req->func, APC_ASYNC_IO,
866                           1, req->event, NULL, (void *)STATUS_SUCCESS );
867         release_object( server );
868     }
869     else
870     {
871         int timeout;
872         if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT)
873             timeout = pipe->timeout;
874         else
875             timeout = req->timeout;
876
877         if (req->timeout == NMPWAIT_WAIT_FOREVER)
878             create_async( current, NULL, &pipe->waiters,
879                           req->func, req->event, NULL );
880         else
881             create_async( current, &timeout, &pipe->waiters,
882                           req->func, req->event, NULL );
883     }
884
885     release_object( pipe );
886 }
887
888 DECL_HANDLER(disconnect_named_pipe)
889 {
890     struct pipe_server *server;
891
892     reply->fd = -1;
893     server = get_pipe_server_obj( current->process, req->handle, 0 );
894     if (!server)
895         return;
896     switch(server->state)
897     {
898     case ps_connected_server:
899         assert( server->fd );
900         assert( server->client );
901         assert( server->client->fd );
902
903         notify_empty( server );
904
905         /* Dump the client and server fds, but keep the pointers
906            around - client loses all waiting data */
907         server->state = ps_disconnected_server;
908         do_disconnect( server );
909         reply->fd = flush_cached_fd( current->process, req->handle );
910         break;
911
912     case ps_wait_disconnect:
913         assert( !server->client );
914         assert( server->fd );
915         do_disconnect( server );
916         server->state = ps_wait_connect;
917         reply->fd = flush_cached_fd( current->process, req->handle );
918         break;
919
920     case ps_idle_server:
921     case ps_wait_open:
922     case ps_disconnected_server:
923     case ps_wait_connect:
924         set_error( STATUS_PIPE_DISCONNECTED );
925         break;
926     }
927     release_object( server );
928 }
929
930 DECL_HANDLER(get_named_pipe_info)
931 {
932     struct pipe_server *server;
933     struct pipe_client *client = NULL;
934
935     server = get_pipe_server_obj( current->process, req->handle, FILE_READ_ATTRIBUTES );
936     if (!server)
937     {
938         clear_error();
939         client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
940                                                        FILE_READ_ATTRIBUTES, &pipe_client_ops );
941         if (!client) return;
942         server = client->server;
943     }
944
945     reply->flags        = server->pipe->flags;
946     reply->maxinstances = server->pipe->maxinstances;
947     reply->instances    = server->pipe->instances;
948     reply->insize       = server->pipe->insize;
949     reply->outsize      = server->pipe->outsize;
950
951     if (client)
952         release_object(client);
953     else
954     {
955         reply->flags |= NAMED_PIPE_SERVER_END;
956         release_object(server);
957     }
958 }