server: Add an open_file() function to the object operations.
[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_open_file,                 /* open_file */
126     no_close_handle,              /* close_handle */
127     named_pipe_destroy            /* destroy */
128 };
129
130 /* functions common to server and client */
131 static unsigned int pipe_map_access( struct object *obj, unsigned int access );
132
133 /* server end functions */
134 static void pipe_server_dump( struct object *obj, int verbose );
135 static struct fd *pipe_server_get_fd( struct object *obj );
136 static void pipe_server_destroy( struct object *obj);
137 static int pipe_server_flush( struct fd *fd, struct event **event );
138 static enum server_fd_type pipe_server_get_info( struct fd *fd, int *flags );
139
140 static const struct object_ops pipe_server_ops =
141 {
142     sizeof(struct pipe_server),   /* size */
143     pipe_server_dump,             /* dump */
144     default_fd_add_queue,         /* add_queue */
145     default_fd_remove_queue,      /* remove_queue */
146     default_fd_signaled,          /* signaled */
147     no_satisfied,                 /* satisfied */
148     no_signal,                    /* signal */
149     pipe_server_get_fd,           /* get_fd */
150     pipe_map_access,              /* map_access */
151     no_lookup_name,               /* lookup_name */
152     no_open_file,                 /* open_file */
153     fd_close_handle,              /* close_handle */
154     pipe_server_destroy           /* destroy */
155 };
156
157 static const struct fd_ops pipe_server_fd_ops =
158 {
159     default_fd_get_poll_events,     /* get_poll_events */
160     default_poll_event,           /* poll_event */
161     pipe_server_flush,            /* flush */
162     pipe_server_get_info,         /* get_file_info */
163     default_fd_queue_async,       /* queue_async */
164     default_fd_cancel_async,      /* cancel_async */
165 };
166
167 /* client end functions */
168 static void pipe_client_dump( struct object *obj, int verbose );
169 static struct fd *pipe_client_get_fd( struct object *obj );
170 static void pipe_client_destroy( struct object *obj );
171 static int pipe_client_flush( struct fd *fd, struct event **event );
172 static enum server_fd_type pipe_client_get_info( struct fd *fd, int *flags );
173
174 static const struct object_ops pipe_client_ops =
175 {
176     sizeof(struct pipe_client),   /* size */
177     pipe_client_dump,             /* dump */
178     default_fd_add_queue,         /* add_queue */
179     default_fd_remove_queue,      /* remove_queue */
180     default_fd_signaled,          /* signaled */
181     no_satisfied,                 /* satisfied */
182     no_signal,                    /* signal */
183     pipe_client_get_fd,           /* get_fd */
184     pipe_map_access,              /* map_access */
185     no_lookup_name,               /* lookup_name */
186     no_open_file,                 /* open_file */
187     fd_close_handle,              /* close_handle */
188     pipe_client_destroy           /* destroy */
189 };
190
191 static const struct fd_ops pipe_client_fd_ops =
192 {
193     default_fd_get_poll_events,   /* get_poll_events */
194     default_poll_event,           /* poll_event */
195     pipe_client_flush,            /* flush */
196     pipe_client_get_info,         /* get_file_info */
197     default_fd_queue_async,       /* queue_async */
198     default_fd_cancel_async       /* cancel_async */
199 };
200
201 static void named_pipe_device_dump( struct object *obj, int verbose );
202 static struct fd *named_pipe_device_get_fd( struct object *obj );
203 static struct object *named_pipe_device_lookup_name( struct object *obj,
204     struct unicode_str *name, unsigned int attr );
205 static void named_pipe_device_destroy( struct object *obj );
206 static enum server_fd_type named_pipe_device_get_file_info( struct fd *fd, int *flags );
207
208 static const struct object_ops named_pipe_device_ops =
209 {
210     sizeof(struct named_pipe_device), /* size */
211     named_pipe_device_dump,           /* dump */
212     no_add_queue,                     /* add_queue */
213     NULL,                             /* remove_queue */
214     NULL,                             /* signaled */
215     no_satisfied,                     /* satisfied */
216     no_signal,                        /* signal */
217     named_pipe_device_get_fd,         /* get_fd */
218     pipe_map_access,                  /* map_access */
219     named_pipe_device_lookup_name,    /* lookup_name */
220     no_open_file,                     /* open_file */
221     fd_close_handle,                  /* close_handle */
222     named_pipe_device_destroy         /* destroy */
223 };
224
225 static const struct fd_ops named_pipe_device_fd_ops =
226 {
227     default_fd_get_poll_events,       /* get_poll_events */
228     default_poll_event,               /* poll_event */
229     no_flush,                         /* flush */
230     named_pipe_device_get_file_info,  /* get_file_info */
231     default_fd_queue_async,           /* queue_async */
232     default_fd_cancel_async           /* cancel_async */
233 };
234
235 static void named_pipe_dump( struct object *obj, int verbose )
236 {
237     struct named_pipe *pipe = (struct named_pipe *) obj;
238     assert( obj->ops == &named_pipe_ops );
239     fprintf( stderr, "Named pipe " );
240     dump_object_name( &pipe->obj );
241     fprintf( stderr, "\n" );
242 }
243
244 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access )
245 {
246     if (access & GENERIC_READ)    access |= STANDARD_RIGHTS_READ;
247     if (access & GENERIC_WRITE)   access |= STANDARD_RIGHTS_WRITE | FILE_CREATE_PIPE_INSTANCE;
248     if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE;
249     if (access & GENERIC_ALL)     access |= STANDARD_RIGHTS_ALL;
250     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
251 }
252
253 static void pipe_server_dump( struct object *obj, int verbose )
254 {
255     struct pipe_server *server = (struct pipe_server *) obj;
256     assert( obj->ops == &pipe_server_ops );
257     fprintf( stderr, "Named pipe server pipe=%p state=%d\n", server->pipe, server->state );
258 }
259
260 static void pipe_client_dump( struct object *obj, int verbose )
261 {
262     struct pipe_client *client = (struct pipe_client *) obj;
263     assert( obj->ops == &pipe_client_ops );
264     fprintf( stderr, "Named pipe client server=%p\n", client->server );
265 }
266
267 static void named_pipe_destroy( struct object *obj)
268 {
269     struct named_pipe *pipe = (struct named_pipe *) obj;
270
271     assert( list_empty( &pipe->servers ) );
272     assert( !pipe->instances );
273     async_terminate_queue( &pipe->waiters, STATUS_HANDLES_CLOSED );
274 }
275
276 static struct fd *pipe_client_get_fd( struct object *obj )
277 {
278     struct pipe_client *client = (struct pipe_client *) obj;
279     if (client->fd)
280         return (struct fd *) grab_object( client->fd );
281     set_error( STATUS_PIPE_DISCONNECTED );
282     return NULL;
283 }
284
285 static struct fd *pipe_server_get_fd( struct object *obj )
286 {
287     struct pipe_server *server = (struct pipe_server *) obj;
288
289     switch(server->state)
290     {
291     case ps_connected_server:
292     case ps_wait_disconnect:
293         assert( server->fd );
294         return (struct fd *) grab_object( server->fd );
295
296     case ps_wait_open:
297     case ps_idle_server:
298         set_error( STATUS_PIPE_LISTENING );
299         break;
300
301     case ps_disconnected_server:
302     case ps_wait_connect:
303         set_error( STATUS_PIPE_DISCONNECTED );
304         break;
305     }
306     return NULL;
307 }
308
309
310 static void notify_empty( struct pipe_server *server )
311 {
312     if (!server->flush_poll)
313         return;
314     assert( server->state == ps_connected_server );
315     assert( server->event );
316     remove_timeout_user( server->flush_poll );
317     server->flush_poll = NULL;
318     set_event( server->event );
319     release_object( server->event );
320     server->event = NULL;
321 }
322
323 static void do_disconnect( struct pipe_server *server )
324 {
325     /* we may only have a server fd, if the client disconnected */
326     if (server->client)
327     {
328         assert( server->client->server == server );
329         assert( server->client->fd );
330         release_object( server->client->fd );
331         server->client->fd = NULL;
332     }
333     assert( server->fd );
334     release_object( server->fd );
335     server->fd = NULL;
336 }
337
338 static unsigned int pipe_map_access( struct object *obj, unsigned int access )
339 {
340     if (access & GENERIC_READ)    access |= FILE_GENERIC_READ;
341     if (access & GENERIC_WRITE)   access |= FILE_GENERIC_WRITE;
342     if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
343     if (access & GENERIC_ALL)     access |= FILE_ALL_ACCESS;
344     return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
345 }
346
347 static void pipe_server_destroy( struct object *obj)
348 {
349     struct pipe_server *server = (struct pipe_server *)obj;
350
351     assert( obj->ops == &pipe_server_ops );
352
353     if (server->fd)
354     {
355         notify_empty( server );
356         do_disconnect( server );
357     }
358
359     if (server->client)
360     {
361         server->client->server = NULL;
362         server->client = NULL;
363     }
364
365     async_terminate_head( &server->wait_q, STATUS_HANDLES_CLOSED );
366
367     assert( server->pipe->instances );
368     server->pipe->instances--;
369
370     list_remove( &server->entry );
371     release_object( server->pipe );
372 }
373
374 static void pipe_client_destroy( struct object *obj)
375 {
376     struct pipe_client *client = (struct pipe_client *)obj;
377     struct pipe_server *server = client->server;
378
379     assert( obj->ops == &pipe_client_ops );
380
381     if (server)
382     {
383         notify_empty( server );
384
385         switch(server->state)
386         {
387         case ps_connected_server:
388             /* Don't destroy the server's fd here as we can't
389                do a successful flush without it. */
390             server->state = ps_wait_disconnect;
391             release_object( client->fd );
392             client->fd = NULL;
393             break;
394         case ps_disconnected_server:
395             server->state = ps_wait_connect;
396             break;
397         case ps_idle_server:
398         case ps_wait_open:
399         case ps_wait_disconnect:
400         case ps_wait_connect:
401             assert( 0 );
402         }
403         assert( server->client );
404         server->client = NULL;
405         client->server = NULL;
406     }
407     assert( !client->fd );
408 }
409
410 static void named_pipe_device_dump( struct object *obj, int verbose )
411 {
412     assert( obj->ops == &named_pipe_device_ops );
413     fprintf( stderr, "Named pipe device\n" );
414 }
415
416 static struct fd *named_pipe_device_get_fd( struct object *obj )
417 {
418     struct named_pipe_device *device = (struct named_pipe_device *)obj;
419     return (struct fd *)grab_object( device->fd );
420 }
421
422 static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name,
423                                                      unsigned int attr )
424 {
425     struct named_pipe_device *device = (struct named_pipe_device*)obj;
426     struct object *found;
427
428     assert( obj->ops == &named_pipe_device_ops );
429     assert( device->pipes );
430
431     if ((found = find_object( device->pipes, name, attr | OBJ_CASE_INSENSITIVE )))
432         name->len = 0;
433
434     return found;
435 }
436
437 static void named_pipe_device_destroy( struct object *obj )
438 {
439     struct named_pipe_device *device = (struct named_pipe_device*)obj;
440     assert( obj->ops == &named_pipe_device_ops );
441     if (device->fd) release_object( device->fd );
442     free( device->pipes );
443 }
444
445 static enum server_fd_type named_pipe_device_get_file_info( struct fd *fd, int *flags )
446 {
447     *flags = 0;
448     return FD_TYPE_DEVICE;
449 }
450
451 void create_named_pipe_device( struct directory *root, const struct unicode_str *name )
452 {
453     struct named_pipe_device *dev;
454
455     if ((dev = create_named_object_dir( root, name, 0, &named_pipe_device_ops )) &&
456         get_error() != STATUS_OBJECT_NAME_EXISTS)
457     {
458         dev->pipes = NULL;
459         if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj )) ||
460             !(dev->pipes = create_namespace( 7 )))
461         {
462             release_object( dev );
463             dev = NULL;
464         }
465     }
466     if (dev) make_object_static( &dev->obj );
467 }
468
469 static int pipe_data_remaining( struct pipe_server *server )
470 {
471     struct pollfd pfd;
472     int fd;
473
474     assert( server->client );
475
476     fd = get_unix_fd( server->client->fd );
477     if (fd < 0)
478         return 0;
479     pfd.fd = fd;
480     pfd.events = POLLIN;
481     pfd.revents = 0;
482
483     if (0 > poll( &pfd, 1, 0 ))
484         return 0;
485  
486     return pfd.revents&POLLIN;
487 }
488
489 static void check_flushed( void *arg )
490 {
491     struct pipe_server *server = (struct pipe_server*) arg;
492
493     assert( server->event );
494     if (pipe_data_remaining( server ))
495     {
496         struct timeval tv = current_time;
497         add_timeout( &tv, 100 );
498         server->flush_poll = add_timeout_user( &tv, check_flushed, server );
499     }
500     else
501     {
502         /* notify_empty( server ); */
503         server->flush_poll = NULL;
504         set_event( server->event );
505         release_object( server->event );
506         server->event = NULL;
507     }
508 }
509
510 static int pipe_server_flush( struct fd *fd, struct event **event )
511 {
512     struct pipe_server *server = get_fd_user( fd );
513
514     if (!server)
515         return 0;
516
517     if (server->state != ps_connected_server)
518         return 0;
519
520     /* FIXME: if multiple threads flush the same pipe,
521               maybe should create a list of processes to notify */
522     if (server->flush_poll)
523         return 0;
524
525     if (pipe_data_remaining( server ))
526     {
527         struct timeval tv = current_time;
528
529         /* this kind of sux - 
530            there's no unix way to be alerted when a pipe becomes empty */
531         server->event = create_event( NULL, NULL, 0, 0, 0 );
532         if (!server->event)
533             return 0;
534         add_timeout( &tv, 100 );
535         server->flush_poll = add_timeout_user( &tv, check_flushed, server );
536         *event = server->event;
537     }
538
539     return 0; 
540 }
541
542 static int pipe_client_flush( struct fd *fd, struct event **event )
543 {
544     /* FIXME: what do we have to do for this? */
545     return 0;
546 }
547
548 static inline int is_overlapped( unsigned int options )
549 {
550     return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
551 }
552
553 static enum server_fd_type pipe_server_get_info( struct fd *fd, int *flags )
554 {
555     struct pipe_server *server = get_fd_user( fd );
556
557     *flags = FD_FLAG_AVAILABLE;
558     if (is_overlapped( server->options )) *flags |= FD_FLAG_OVERLAPPED;
559     return FD_TYPE_PIPE;
560 }
561
562 static enum server_fd_type pipe_client_get_info( struct fd *fd, int *flags )
563 {
564     struct pipe_client *client = get_fd_user( fd );
565
566     *flags = FD_FLAG_AVAILABLE;
567     if (is_overlapped( client->flags )) *flags |= FD_FLAG_OVERLAPPED;
568     return FD_TYPE_PIPE;
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             if (pipe->insize)
784             {
785                 setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
786                 setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
787             }
788             if (pipe->outsize)
789             {
790                 setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
791                 setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
792             }
793
794             client->fd = create_anonymous_fd( &pipe_client_fd_ops,
795                                             fds[1], &client->obj );
796             server->fd = create_anonymous_fd( &pipe_server_fd_ops,
797                                             fds[0], &server->obj );
798             if (client->fd && server->fd && res != 1)
799             {
800                 if (server->state == ps_wait_open)
801                     async_terminate_head( &server->wait_q, STATUS_SUCCESS );
802                 assert( list_empty( &server->wait_q ) );
803                 server->state = ps_connected_server;
804                 server->client = client;
805                 client->server = server;
806                 reply->handle = alloc_handle( current->process, client, req->access, req->attributes );
807             }
808         }
809         else
810             file_set_error();
811
812         release_object( client );
813     }
814     release_object( server );
815 }
816
817 DECL_HANDLER(connect_named_pipe)
818 {
819     struct pipe_server *server;
820
821     server = get_pipe_server_obj(current->process, req->handle, 0);
822     if (!server)
823         return;
824
825     switch(server->state)
826     {
827     case ps_idle_server:
828     case ps_wait_connect:
829         assert( !server->fd );
830         server->state = ps_wait_open;
831         create_async( current, NULL, &server->wait_q, &req->async );
832         async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
833         set_error( STATUS_PENDING );
834         break;
835     case ps_connected_server:
836         assert( server->fd );
837         set_error( STATUS_PIPE_CONNECTED );
838         break;
839     case ps_disconnected_server:
840         set_error( STATUS_PIPE_BUSY );
841         break;
842     case ps_wait_disconnect:
843         set_error( STATUS_NO_DATA_DETECTED );
844         break;
845     case ps_wait_open:
846         set_error( STATUS_INVALID_HANDLE );
847         break;
848     }
849
850     release_object(server);
851 }
852
853 DECL_HANDLER(wait_named_pipe)
854 {
855     struct named_pipe_device *device;
856     struct named_pipe *pipe;
857     struct pipe_server *server;
858     struct unicode_str name;
859
860     device = (struct named_pipe_device *)get_handle_obj( current->process, req->handle,
861                                                          FILE_READ_ATTRIBUTES, &named_pipe_device_ops );
862     if (!device) return;
863
864     get_req_unicode_str( &name );
865     pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE );
866     release_object( device );
867     if (!pipe)
868     {
869         set_error( STATUS_PIPE_NOT_AVAILABLE );
870         return;
871     }
872     server = find_server( pipe, ps_wait_open );
873     if (!server)
874     {
875         if (req->timeout == NMPWAIT_WAIT_FOREVER)
876         {
877             if (create_async( current, NULL, &pipe->waiters, &req->async ))
878                 set_error( STATUS_PENDING );
879         }
880         else
881         {
882             struct timeval when = current_time;
883             if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout );
884             else add_timeout( &when, req->timeout );
885             if (create_async( current, &when, &pipe->waiters, &req->async ))
886                 set_error( STATUS_PENDING );
887         }
888     }
889     else release_object( server );
890
891     release_object( pipe );
892 }
893
894 DECL_HANDLER(disconnect_named_pipe)
895 {
896     struct pipe_server *server;
897
898     server = get_pipe_server_obj( current->process, req->handle, 0 );
899     if (!server)
900         return;
901     switch(server->state)
902     {
903     case ps_connected_server:
904         assert( server->fd );
905         assert( server->client );
906         assert( server->client->fd );
907
908         notify_empty( server );
909
910         /* Dump the client and server fds, but keep the pointers
911            around - client loses all waiting data */
912         server->state = ps_disconnected_server;
913         do_disconnect( server );
914         break;
915
916     case ps_wait_disconnect:
917         assert( !server->client );
918         assert( server->fd );
919         do_disconnect( server );
920         server->state = ps_wait_connect;
921         break;
922
923     case ps_idle_server:
924     case ps_wait_open:
925     case ps_disconnected_server:
926     case ps_wait_connect:
927         set_error( STATUS_PIPE_DISCONNECTED );
928         break;
929     }
930     release_object( server );
931 }
932
933 DECL_HANDLER(get_named_pipe_info)
934 {
935     struct pipe_server *server;
936     struct pipe_client *client = NULL;
937
938     server = get_pipe_server_obj( current->process, req->handle, FILE_READ_ATTRIBUTES );
939     if (!server)
940     {
941         clear_error();
942         client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
943                                                        FILE_READ_ATTRIBUTES, &pipe_client_ops );
944         if (!client) return;
945         server = client->server;
946     }
947
948     reply->flags        = server->pipe->flags;
949     reply->maxinstances = server->pipe->maxinstances;
950     reply->instances    = server->pipe->instances;
951     reply->insize       = server->pipe->insize;
952     reply->outsize      = server->pipe->outsize;
953
954     if (client)
955         release_object(client);
956     else
957     {
958         reply->flags |= NAMED_PIPE_SERVER_END;
959         release_object(server);
960     }
961 }