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