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