server: Implement disconnecting message queue.
[wine.git] / server / named_pipe.c
blob6dc032d2a6a31cde03a667443875e5bb511bdb7c
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
5 * Copyright (C) 2001 Mike McCormack
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.
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.
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
21 * TODO:
22 * message mode
25 #include "config.h"
26 #include "wine/port.h"
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
45 #include "ntstatus.h"
46 #define WIN32_NO_STATUS
47 #include "windef.h"
48 #include "winternl.h"
49 #include "winioctl.h"
51 #include "file.h"
52 #include "handle.h"
53 #include "thread.h"
54 #include "request.h"
55 #include "security.h"
57 enum pipe_state
59 ps_idle_server,
60 ps_wait_open,
61 ps_connected_server,
62 ps_wait_disconnect,
63 ps_wait_connect
66 struct named_pipe;
68 struct pipe_message
70 struct list entry; /* entry in message queue */
71 data_size_t read_pos; /* already read bytes */
72 struct iosb *iosb; /* message iosb */
73 struct async *async; /* async of pending write */
76 struct pipe_end
78 struct object obj; /* object header */
79 struct fd *fd; /* pipe file descriptor */
80 unsigned int flags; /* pipe flags */
81 struct pipe_end *connection; /* the other end of the pipe */
82 data_size_t buffer_size;/* size of buffered data that doesn't block caller */
83 struct list message_queue;
86 struct pipe_server
88 struct pipe_end pipe_end; /* common header for pipe_client and pipe_server */
89 struct fd *ioctl_fd; /* file descriptor for ioctls when not connected */
90 struct list entry; /* entry in named pipe servers list */
91 enum pipe_state state; /* server state */
92 struct pipe_client *client; /* client that this server is connected to */
93 struct named_pipe *pipe;
94 struct timeout_user *flush_poll;
95 unsigned int options; /* pipe options */
98 struct pipe_client
100 struct pipe_end pipe_end; /* common header for pipe_client and pipe_server */
101 struct pipe_server *server; /* server that this client is connected to */
102 unsigned int flags; /* file flags */
105 struct named_pipe
107 struct object obj; /* object header */
108 unsigned int flags;
109 unsigned int sharing;
110 unsigned int maxinstances;
111 unsigned int outsize;
112 unsigned int insize;
113 unsigned int instances;
114 timeout_t timeout;
115 struct list servers; /* list of servers using this pipe */
116 struct async_queue *waiters; /* list of clients waiting to connect */
119 struct named_pipe_device
121 struct object obj; /* object header */
122 struct fd *fd; /* pseudo-fd for ioctls */
123 struct namespace *pipes; /* named pipe namespace */
126 static void named_pipe_dump( struct object *obj, int verbose );
127 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access );
128 static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent );
129 static struct object *named_pipe_open_file( struct object *obj, unsigned int access,
130 unsigned int sharing, unsigned int options );
131 static void named_pipe_destroy( struct object *obj );
133 static const struct object_ops named_pipe_ops =
135 sizeof(struct named_pipe), /* size */
136 named_pipe_dump, /* dump */
137 no_get_type, /* get_type */
138 no_add_queue, /* add_queue */
139 NULL, /* remove_queue */
140 NULL, /* signaled */
141 NULL, /* satisfied */
142 no_signal, /* signal */
143 no_get_fd, /* get_fd */
144 named_pipe_map_access, /* map_access */
145 default_get_sd, /* get_sd */
146 default_set_sd, /* set_sd */
147 no_lookup_name, /* lookup_name */
148 named_pipe_link_name, /* link_name */
149 default_unlink_name, /* unlink_name */
150 named_pipe_open_file, /* open_file */
151 no_close_handle, /* close_handle */
152 named_pipe_destroy /* destroy */
155 /* common server and client pipe end functions */
156 static void pipe_end_queue_async( struct fd *fd, struct async *async, int type, int count );
158 /* server end functions */
159 static void pipe_server_dump( struct object *obj, int verbose );
160 static struct fd *pipe_server_get_fd( struct object *obj );
161 static void pipe_server_destroy( struct object *obj);
162 static obj_handle_t pipe_server_flush( struct fd *fd, struct async *async, int blocking );
163 static enum server_fd_type pipe_server_get_fd_type( struct fd *fd );
164 static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async,
165 int blocking );
167 static const struct object_ops pipe_server_ops =
169 sizeof(struct pipe_server), /* size */
170 pipe_server_dump, /* dump */
171 no_get_type, /* get_type */
172 add_queue, /* add_queue */
173 remove_queue, /* remove_queue */
174 default_fd_signaled, /* signaled */
175 no_satisfied, /* satisfied */
176 no_signal, /* signal */
177 pipe_server_get_fd, /* get_fd */
178 default_fd_map_access, /* map_access */
179 default_get_sd, /* get_sd */
180 default_set_sd, /* set_sd */
181 no_lookup_name, /* lookup_name */
182 no_link_name, /* link_name */
183 NULL, /* unlink_name */
184 no_open_file, /* open_file */
185 fd_close_handle, /* close_handle */
186 pipe_server_destroy /* destroy */
189 static const struct fd_ops pipe_server_fd_ops =
191 default_fd_get_poll_events, /* get_poll_events */
192 default_poll_event, /* poll_event */
193 pipe_server_get_fd_type, /* get_fd_type */
194 no_fd_read, /* read */
195 no_fd_write, /* write */
196 pipe_server_flush, /* flush */
197 pipe_server_ioctl, /* ioctl */
198 pipe_end_queue_async, /* queue_async */
199 default_fd_reselect_async /* reselect_async */
202 /* client end functions */
203 static void pipe_client_dump( struct object *obj, int verbose );
204 static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry );
205 static struct fd *pipe_client_get_fd( struct object *obj );
206 static void pipe_client_destroy( struct object *obj );
207 static obj_handle_t pipe_client_flush( struct fd *fd, struct async *async, int blocking );
208 static enum server_fd_type pipe_client_get_fd_type( struct fd *fd );
210 static const struct object_ops pipe_client_ops =
212 sizeof(struct pipe_client), /* size */
213 pipe_client_dump, /* dump */
214 no_get_type, /* get_type */
215 add_queue, /* add_queue */
216 remove_queue, /* remove_queue */
217 pipe_client_signaled, /* signaled */
218 no_satisfied, /* satisfied */
219 no_signal, /* signal */
220 pipe_client_get_fd, /* get_fd */
221 default_fd_map_access, /* map_access */
222 default_get_sd, /* get_sd */
223 default_set_sd, /* set_sd */
224 no_lookup_name, /* lookup_name */
225 no_link_name, /* link_name */
226 NULL, /* unlink_name */
227 no_open_file, /* open_file */
228 fd_close_handle, /* close_handle */
229 pipe_client_destroy /* destroy */
232 static const struct fd_ops pipe_client_fd_ops =
234 default_fd_get_poll_events, /* get_poll_events */
235 default_poll_event, /* poll_event */
236 pipe_client_get_fd_type, /* get_fd_type */
237 no_fd_read, /* read */
238 no_fd_write, /* write */
239 pipe_client_flush, /* flush */
240 default_fd_ioctl, /* ioctl */
241 pipe_end_queue_async, /* queue_async */
242 default_fd_reselect_async /* reselect_async */
245 static void named_pipe_device_dump( struct object *obj, int verbose );
246 static struct object_type *named_pipe_device_get_type( struct object *obj );
247 static struct fd *named_pipe_device_get_fd( struct object *obj );
248 static struct object *named_pipe_device_lookup_name( struct object *obj,
249 struct unicode_str *name, unsigned int attr );
250 static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
251 unsigned int sharing, unsigned int options );
252 static void named_pipe_device_destroy( struct object *obj );
253 static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd );
254 static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code,
255 struct async *async, int blocking );
257 static const struct object_ops named_pipe_device_ops =
259 sizeof(struct named_pipe_device), /* size */
260 named_pipe_device_dump, /* dump */
261 named_pipe_device_get_type, /* get_type */
262 no_add_queue, /* add_queue */
263 NULL, /* remove_queue */
264 NULL, /* signaled */
265 no_satisfied, /* satisfied */
266 no_signal, /* signal */
267 named_pipe_device_get_fd, /* get_fd */
268 no_map_access, /* map_access */
269 default_get_sd, /* get_sd */
270 default_set_sd, /* set_sd */
271 named_pipe_device_lookup_name, /* lookup_name */
272 directory_link_name, /* link_name */
273 default_unlink_name, /* unlink_name */
274 named_pipe_device_open_file, /* open_file */
275 fd_close_handle, /* close_handle */
276 named_pipe_device_destroy /* destroy */
279 static const struct fd_ops named_pipe_device_fd_ops =
281 default_fd_get_poll_events, /* get_poll_events */
282 default_poll_event, /* poll_event */
283 named_pipe_device_get_fd_type, /* get_fd_type */
284 no_fd_read, /* read */
285 no_fd_write, /* write */
286 no_fd_flush, /* flush */
287 named_pipe_device_ioctl, /* ioctl */
288 default_fd_queue_async, /* queue_async */
289 default_fd_reselect_async /* reselect_async */
292 /* Returns if we handle I/O via server calls. Currently disabled. */
293 static int use_server_io( struct pipe_end *pipe_end )
295 return 0; /* FIXME */
298 static void named_pipe_dump( struct object *obj, int verbose )
300 fputs( "Named pipe\n", stderr );
303 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access )
305 if (access & GENERIC_READ) access |= STANDARD_RIGHTS_READ;
306 if (access & GENERIC_WRITE) access |= STANDARD_RIGHTS_WRITE | FILE_CREATE_PIPE_INSTANCE;
307 if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE;
308 if (access & GENERIC_ALL) access |= STANDARD_RIGHTS_ALL;
309 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
312 static void pipe_server_dump( struct object *obj, int verbose )
314 struct pipe_server *server = (struct pipe_server *) obj;
315 assert( obj->ops == &pipe_server_ops );
316 fprintf( stderr, "Named pipe server pipe=%p state=%d\n", server->pipe, server->state );
319 static void pipe_client_dump( struct object *obj, int verbose )
321 struct pipe_client *client = (struct pipe_client *) obj;
322 assert( obj->ops == &pipe_client_ops );
323 fprintf( stderr, "Named pipe client server=%p\n", client->server );
326 static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry )
328 struct pipe_client *client = (struct pipe_client *) obj;
330 return client->pipe_end.fd && is_fd_signaled(client->pipe_end.fd);
333 static void named_pipe_destroy( struct object *obj)
335 struct named_pipe *pipe = (struct named_pipe *) obj;
337 assert( list_empty( &pipe->servers ) );
338 assert( !pipe->instances );
339 free_async_queue( pipe->waiters );
342 static struct fd *pipe_client_get_fd( struct object *obj )
344 struct pipe_client *client = (struct pipe_client *) obj;
345 if (client->pipe_end.fd)
346 return (struct fd *) grab_object( client->pipe_end.fd );
347 set_error( STATUS_PIPE_DISCONNECTED );
348 return NULL;
351 static void set_server_state( struct pipe_server *server, enum pipe_state state )
353 server->state = state;
355 switch(state)
357 case ps_connected_server:
358 case ps_wait_disconnect:
359 assert( server->pipe_end.fd );
360 break;
361 case ps_wait_open:
362 case ps_idle_server:
363 assert( !server->pipe_end.fd );
364 set_no_fd_status( server->ioctl_fd, STATUS_PIPE_LISTENING );
365 break;
366 case ps_wait_connect:
367 assert( !server->pipe_end.fd );
368 set_no_fd_status( server->ioctl_fd, STATUS_PIPE_DISCONNECTED );
369 break;
373 static struct fd *pipe_server_get_fd( struct object *obj )
375 struct pipe_server *server = (struct pipe_server *) obj;
377 return (struct fd *)grab_object( server->pipe_end.fd ? server->pipe_end.fd : server->ioctl_fd );
381 static void notify_empty( struct pipe_server *server )
383 if (!server->flush_poll)
384 return;
385 assert( server->state == ps_connected_server );
386 remove_timeout_user( server->flush_poll );
387 server->flush_poll = NULL;
388 fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
391 static void free_message( struct pipe_message *message )
393 list_remove( &message->entry );
394 if (message->iosb) release_object( message->iosb );
395 free( message );
398 static void pipe_end_disconnect( struct pipe_end *pipe_end, unsigned int status )
400 struct pipe_end *connection = pipe_end->connection;
402 pipe_end->connection = NULL;
404 if (use_server_io( pipe_end ))
406 struct pipe_message *message, *next;
407 struct async *async;
408 if (pipe_end->fd) fd_async_wake_up( pipe_end->fd, ASYNC_TYPE_WAIT, status );
409 LIST_FOR_EACH_ENTRY_SAFE( message, next, &pipe_end->message_queue, struct pipe_message, entry )
411 async = message->async;
412 if (async || status == STATUS_PIPE_DISCONNECTED) free_message( message );
413 if (!async) continue;
414 async_terminate( async, status );
415 release_object( async );
417 if (status == STATUS_PIPE_DISCONNECTED) set_fd_signaled( pipe_end->fd, 0 );
419 if (connection)
421 connection->connection = NULL;
422 pipe_end_disconnect( connection, status );
426 static void do_disconnect( struct pipe_server *server )
428 /* we may only have a server fd, if the client disconnected */
429 if (server->client)
431 assert( server->client->server == server );
432 assert( server->client->pipe_end.fd );
433 release_object( server->client->pipe_end.fd );
434 server->client->pipe_end.fd = NULL;
436 assert( server->pipe_end.fd );
437 if (!use_server_io( &server->pipe_end ))
438 shutdown( get_unix_fd( server->pipe_end.fd ), SHUT_RDWR );
439 release_object( server->pipe_end.fd );
440 server->pipe_end.fd = NULL;
443 static void pipe_end_destroy( struct pipe_end *pipe_end )
445 struct pipe_message *message;
447 while (!list_empty( &pipe_end->message_queue ))
449 message = LIST_ENTRY( list_head(&pipe_end->message_queue), struct pipe_message, entry );
450 assert( !message->async );
451 free_message( message );
455 static void pipe_server_destroy( struct object *obj)
457 struct pipe_server *server = (struct pipe_server *)obj;
459 assert( obj->ops == &pipe_server_ops );
461 pipe_end_disconnect( &server->pipe_end, STATUS_PIPE_BROKEN );
463 if (server->pipe_end.fd)
465 notify_empty( server );
466 do_disconnect( server );
469 pipe_end_destroy( &server->pipe_end );
470 if (server->client)
472 server->client->server = NULL;
473 server->client = NULL;
476 assert( server->pipe->instances );
477 server->pipe->instances--;
479 if (server->ioctl_fd) release_object( server->ioctl_fd );
480 list_remove( &server->entry );
481 release_object( server->pipe );
484 static void pipe_client_destroy( struct object *obj)
486 struct pipe_client *client = (struct pipe_client *)obj;
487 struct pipe_server *server = client->server;
489 assert( obj->ops == &pipe_client_ops );
491 pipe_end_disconnect( &client->pipe_end, STATUS_PIPE_BROKEN );
493 if (server)
495 notify_empty( server );
497 switch(server->state)
499 case ps_connected_server:
500 /* Don't destroy the server's fd here as we can't
501 do a successful flush without it. */
502 set_server_state( server, ps_wait_disconnect );
503 break;
504 case ps_idle_server:
505 case ps_wait_open:
506 case ps_wait_disconnect:
507 case ps_wait_connect:
508 assert( 0 );
510 assert( server->client );
511 server->client = NULL;
512 client->server = NULL;
515 pipe_end_destroy( &client->pipe_end );
516 if (client->pipe_end.fd) release_object( client->pipe_end.fd );
519 static void named_pipe_device_dump( struct object *obj, int verbose )
521 fputs( "Named pipe device\n", stderr );
524 static struct object_type *named_pipe_device_get_type( struct object *obj )
526 static const WCHAR name[] = {'D','e','v','i','c','e'};
527 static const struct unicode_str str = { name, sizeof(name) };
528 return get_object_type( &str );
531 static struct fd *named_pipe_device_get_fd( struct object *obj )
533 struct named_pipe_device *device = (struct named_pipe_device *)obj;
534 return (struct fd *)grab_object( device->fd );
537 static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name,
538 unsigned int attr )
540 struct named_pipe_device *device = (struct named_pipe_device*)obj;
541 struct object *found;
543 assert( obj->ops == &named_pipe_device_ops );
544 assert( device->pipes );
546 if (!name) return NULL; /* open the device itself */
548 if ((found = find_object( device->pipes, name, attr | OBJ_CASE_INSENSITIVE )))
549 name->len = 0;
551 return found;
554 static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
555 unsigned int sharing, unsigned int options )
557 return grab_object( obj );
560 static void named_pipe_device_destroy( struct object *obj )
562 struct named_pipe_device *device = (struct named_pipe_device*)obj;
563 assert( obj->ops == &named_pipe_device_ops );
564 if (device->fd) release_object( device->fd );
565 free( device->pipes );
568 static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd )
570 return FD_TYPE_DEVICE;
573 struct object *create_named_pipe_device( struct object *root, const struct unicode_str *name )
575 struct named_pipe_device *dev;
577 if ((dev = create_named_object( root, &named_pipe_device_ops, name, 0, NULL )) &&
578 get_error() != STATUS_OBJECT_NAME_EXISTS)
580 dev->pipes = NULL;
581 if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj, 0 )) ||
582 !(dev->pipes = create_namespace( 7 )))
584 release_object( dev );
585 dev = NULL;
588 return &dev->obj;
591 static int pipe_data_remaining( struct pipe_server *server )
593 struct pollfd pfd;
594 int fd;
596 assert( server->client );
598 if (use_server_io( &server->pipe_end ))
599 return !list_empty( &server->client->pipe_end.message_queue );
601 fd = get_unix_fd( server->client->pipe_end.fd );
602 if (fd < 0)
603 return 0;
604 pfd.fd = fd;
605 pfd.events = POLLIN;
606 pfd.revents = 0;
608 if (0 > poll( &pfd, 1, 0 ))
609 return 0;
611 return pfd.revents&POLLIN;
614 static void check_flushed( void *arg )
616 struct pipe_server *server = (struct pipe_server*) arg;
618 if (pipe_data_remaining( server ))
620 server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server );
622 else
624 server->flush_poll = NULL;
625 fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
629 static obj_handle_t pipe_end_flush( struct pipe_end *pipe_end, struct async *async, int blocking )
631 obj_handle_t handle = 0;
633 if (!fd_queue_async( pipe_end->fd, async, ASYNC_TYPE_WAIT )) return 0;
635 if (!blocking || (handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 )))
636 set_error( STATUS_PENDING );
637 return handle;
640 static obj_handle_t pipe_server_flush( struct fd *fd, struct async *async, int blocking )
642 struct pipe_server *server = get_fd_user( fd );
643 obj_handle_t handle;
645 if (!server || server->state != ps_connected_server) return 0;
647 if (!pipe_data_remaining( server )) return 0;
649 handle = pipe_end_flush( &server->pipe_end, async, blocking );
651 /* there's no unix way to be alerted when a pipe becomes empty, so resort to polling */
652 if (handle && !use_server_io( &server->pipe_end ) && !server->flush_poll)
653 server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server );
654 return handle;
657 static obj_handle_t pipe_client_flush( struct fd *fd, struct async *async, int blocking )
659 /* FIXME: what do we have to do for this? */
660 return 0;
663 static void pipe_end_queue_async( struct fd *fd, struct async *async, int type, int count )
665 struct pipe_end *pipe_end = get_fd_user( fd );
666 if (use_server_io( pipe_end )) no_fd_queue_async( fd, async, type, count );
667 else default_fd_queue_async( fd, async, type, count );
670 static inline int is_overlapped( unsigned int options )
672 return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
675 static enum server_fd_type pipe_server_get_fd_type( struct fd *fd )
677 return FD_TYPE_PIPE;
680 static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
682 return FD_TYPE_PIPE;
685 static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async,
686 int blocking )
688 struct pipe_server *server = get_fd_user( fd );
689 obj_handle_t wait_handle = 0;
691 switch(code)
693 case FSCTL_PIPE_LISTEN:
694 switch(server->state)
696 case ps_idle_server:
697 case ps_wait_connect:
698 if (fd_queue_async( server->ioctl_fd, async, ASYNC_TYPE_WAIT ))
700 if (blocking) wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 );
701 set_server_state( server, ps_wait_open );
702 if (server->pipe->waiters) async_wake_up( server->pipe->waiters, STATUS_SUCCESS );
703 set_error( STATUS_PENDING );
704 return wait_handle;
706 break;
707 case ps_connected_server:
708 set_error( STATUS_PIPE_CONNECTED );
709 break;
710 case ps_wait_disconnect:
711 set_error( STATUS_NO_DATA_DETECTED );
712 break;
713 case ps_wait_open:
714 set_error( STATUS_INVALID_HANDLE );
715 break;
717 return 0;
719 case FSCTL_PIPE_DISCONNECT:
720 switch(server->state)
722 case ps_connected_server:
723 assert( server->client );
724 assert( server->client->pipe_end.fd );
726 notify_empty( server );
728 /* dump the client and server fds - client loses all waiting data */
729 pipe_end_disconnect( &server->pipe_end, STATUS_PIPE_DISCONNECTED );
730 do_disconnect( server );
731 server->client->server = NULL;
732 server->client = NULL;
733 set_server_state( server, ps_wait_connect );
734 break;
735 case ps_wait_disconnect:
736 assert( !server->client );
737 pipe_end_disconnect( &server->pipe_end, STATUS_PIPE_DISCONNECTED );
738 do_disconnect( server );
739 set_server_state( server, ps_wait_connect );
740 break;
741 case ps_idle_server:
742 case ps_wait_open:
743 set_error( STATUS_PIPE_LISTENING );
744 break;
745 case ps_wait_connect:
746 set_error( STATUS_PIPE_DISCONNECTED );
747 break;
749 return 0;
751 default:
752 return default_fd_ioctl( fd, code, async, blocking );
756 static struct pipe_server *get_pipe_server_obj( struct process *process,
757 obj_handle_t handle, unsigned int access )
759 struct object *obj;
760 obj = get_handle_obj( process, handle, access, &pipe_server_ops );
761 return (struct pipe_server *) obj;
764 static void init_pipe_end( struct pipe_end *pipe_end, unsigned int pipe_flags, data_size_t buffer_size )
766 pipe_end->fd = NULL;
767 pipe_end->flags = pipe_flags;
768 pipe_end->connection = NULL;
769 pipe_end->buffer_size = buffer_size;
770 list_init( &pipe_end->message_queue );
773 static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options,
774 unsigned int pipe_flags )
776 struct pipe_server *server;
778 server = alloc_object( &pipe_server_ops );
779 if (!server)
780 return NULL;
782 server->pipe = pipe;
783 server->client = NULL;
784 server->flush_poll = NULL;
785 server->options = options;
786 init_pipe_end( &server->pipe_end, pipe_flags, pipe->insize );
788 list_add_head( &pipe->servers, &server->entry );
789 grab_object( pipe );
790 if (!(server->ioctl_fd = alloc_pseudo_fd( &pipe_server_fd_ops, &server->pipe_end.obj, options )))
792 release_object( server );
793 return NULL;
795 set_fd_signaled( server->ioctl_fd, 1 );
796 set_server_state( server, ps_idle_server );
797 return server;
800 static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int pipe_flags, data_size_t buffer_size )
802 struct pipe_client *client;
804 client = alloc_object( &pipe_client_ops );
805 if (!client)
806 return NULL;
808 client->server = NULL;
809 client->flags = flags;
810 init_pipe_end( &client->pipe_end, pipe_flags, buffer_size );
812 return client;
815 static struct pipe_server *find_available_server( struct named_pipe *pipe )
817 struct pipe_server *server;
819 /* look for pipe servers that are listening */
820 LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
822 if (server->state == ps_wait_open)
823 return (struct pipe_server *)grab_object( server );
826 /* fall back to pipe servers that are idle */
827 LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
829 if (server->state == ps_idle_server)
830 return (struct pipe_server *)grab_object( server );
833 return NULL;
836 static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent )
838 struct named_pipe_device *dev = (struct named_pipe_device *)parent;
840 if (parent->ops != &named_pipe_device_ops)
842 set_error( STATUS_OBJECT_NAME_INVALID );
843 return 0;
845 namespace_add( dev->pipes, name );
846 name->parent = grab_object( parent );
847 return 1;
850 static struct object *named_pipe_open_file( struct object *obj, unsigned int access,
851 unsigned int sharing, unsigned int options )
853 struct named_pipe *pipe = (struct named_pipe *)obj;
854 struct pipe_server *server;
855 struct pipe_client *client;
856 unsigned int pipe_sharing;
857 int fds[2];
859 if (!(server = find_available_server( pipe )))
861 set_error( STATUS_PIPE_NOT_AVAILABLE );
862 return NULL;
865 pipe_sharing = server->pipe->sharing;
866 if (((access & GENERIC_READ) && !(pipe_sharing & FILE_SHARE_READ)) ||
867 ((access & GENERIC_WRITE) && !(pipe_sharing & FILE_SHARE_WRITE)))
869 set_error( STATUS_ACCESS_DENIED );
870 release_object( server );
871 return NULL;
874 if ((client = create_pipe_client( options, pipe->flags, pipe->outsize )))
876 if (use_server_io( &server->pipe_end ))
878 client->pipe_end.fd = alloc_pseudo_fd( &pipe_client_fd_ops, &client->pipe_end.obj, options );
879 if (client->pipe_end.fd)
881 set_fd_signaled( client->pipe_end.fd, 1 );
882 server->pipe_end.fd = (struct fd *)grab_object( server->ioctl_fd );
883 set_no_fd_status( server->ioctl_fd, STATUS_BAD_DEVICE_TYPE );
885 else
887 release_object( client );
888 client = NULL;
891 else if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
893 assert( !server->pipe_end.fd );
895 /* for performance reasons, only set nonblocking mode when using
896 * overlapped I/O. Otherwise, we will be doing too much busy
897 * looping */
898 if (is_overlapped( options )) fcntl( fds[1], F_SETFL, O_NONBLOCK );
899 if (is_overlapped( server->options )) fcntl( fds[0], F_SETFL, O_NONBLOCK );
901 if (pipe->insize)
903 setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
904 setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
906 if (pipe->outsize)
908 setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
909 setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
912 client->pipe_end.fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->pipe_end.obj, options );
913 server->pipe_end.fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->pipe_end.obj, server->options );
914 if (client->pipe_end.fd && server->pipe_end.fd)
916 fd_copy_completion( server->ioctl_fd, server->pipe_end.fd );
918 else
920 release_object( client );
921 client = NULL;
924 else
926 file_set_error();
927 release_object( client );
928 client = NULL;
930 if (client)
932 allow_fd_caching( client->pipe_end.fd );
933 allow_fd_caching( server->pipe_end.fd );
934 if (server->state == ps_wait_open)
935 fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
936 set_server_state( server, ps_connected_server );
937 server->client = client;
938 client->server = server;
939 server->pipe_end.connection = &client->pipe_end;
940 client->pipe_end.connection = &server->pipe_end;
943 release_object( server );
944 return &client->pipe_end.obj;
947 static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code,
948 struct async *async, int blocking )
950 struct named_pipe_device *device = get_fd_user( fd );
952 switch(code)
954 case FSCTL_PIPE_WAIT:
956 const FILE_PIPE_WAIT_FOR_BUFFER *buffer = get_req_data();
957 data_size_t size = get_req_data_size();
958 obj_handle_t wait_handle = 0;
959 struct named_pipe *pipe;
960 struct pipe_server *server;
961 struct unicode_str name;
962 timeout_t when;
964 if (size < sizeof(*buffer) ||
965 size < FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[buffer->NameLength/sizeof(WCHAR)]))
967 set_error( STATUS_INVALID_PARAMETER );
968 return 0;
970 name.str = buffer->Name;
971 name.len = (buffer->NameLength / sizeof(WCHAR)) * sizeof(WCHAR);
972 if (!(pipe = open_named_object( &device->obj, &named_pipe_ops, &name, 0 ))) return 0;
974 if (!(server = find_available_server( pipe )))
976 if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done;
978 queue_async( pipe->waiters, async );
979 when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout;
980 async_set_timeout( async, when, STATUS_IO_TIMEOUT );
981 if (blocking) wait_handle = alloc_handle( current->process, async, SYNCHRONIZE, 0 );
982 set_error( STATUS_PENDING );
984 else release_object( server );
986 done:
987 release_object( pipe );
988 return wait_handle;
991 default:
992 return default_fd_ioctl( fd, code, async, blocking );
997 DECL_HANDLER(create_named_pipe)
999 struct named_pipe *pipe;
1000 struct pipe_server *server;
1001 struct unicode_str name;
1002 struct object *root;
1003 const struct security_descriptor *sd;
1004 const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root );
1006 if (!objattr) return;
1008 if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1009 (!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ)))
1011 if (root) release_object( root );
1012 set_error( STATUS_INVALID_PARAMETER );
1013 return;
1016 if (!name.len) /* pipes need a root directory even without a name */
1018 if (!objattr->rootdir)
1020 set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
1021 return;
1023 if (!(root = get_directory_obj( current->process, objattr->rootdir ))) return;
1026 pipe = create_named_object( root, &named_pipe_ops, &name, objattr->attributes | OBJ_OPENIF, NULL );
1028 if (root) release_object( root );
1029 if (!pipe) return;
1031 if (get_error() != STATUS_OBJECT_NAME_EXISTS)
1033 /* initialize it if it didn't already exist */
1034 pipe->instances = 0;
1035 pipe->waiters = NULL;
1036 list_init( &pipe->servers );
1037 pipe->insize = req->insize;
1038 pipe->outsize = req->outsize;
1039 pipe->maxinstances = req->maxinstances;
1040 pipe->timeout = req->timeout;
1041 pipe->flags = req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE;
1042 pipe->sharing = req->sharing;
1044 else
1046 if (pipe->maxinstances <= pipe->instances)
1048 set_error( STATUS_INSTANCE_NOT_AVAILABLE );
1049 release_object( pipe );
1050 return;
1052 if (pipe->sharing != req->sharing)
1054 set_error( STATUS_ACCESS_DENIED );
1055 release_object( pipe );
1056 return;
1058 clear_error(); /* clear the name collision */
1061 server = create_pipe_server( pipe, req->options, req->flags );
1062 if (server)
1064 reply->handle = alloc_handle( current->process, server, req->access, objattr->attributes );
1065 server->pipe->instances++;
1066 if (sd) default_set_sd( &server->pipe_end.obj, sd, OWNER_SECURITY_INFORMATION |
1067 GROUP_SECURITY_INFORMATION |
1068 DACL_SECURITY_INFORMATION |
1069 SACL_SECURITY_INFORMATION );
1070 release_object( server );
1073 release_object( pipe );
1076 DECL_HANDLER(get_named_pipe_info)
1078 struct pipe_server *server;
1079 struct pipe_client *client = NULL;
1081 server = get_pipe_server_obj( current->process, req->handle, FILE_READ_ATTRIBUTES );
1082 if (!server)
1084 if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
1085 return;
1087 clear_error();
1088 client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
1089 0, &pipe_client_ops );
1090 if (!client) return;
1091 server = client->server;
1094 reply->flags = client ? client->pipe_end.flags : server->pipe_end.flags;
1095 if (server)
1097 reply->sharing = server->pipe->sharing;
1098 reply->maxinstances = server->pipe->maxinstances;
1099 reply->instances = server->pipe->instances;
1100 reply->insize = server->pipe->insize;
1101 reply->outsize = server->pipe->outsize;
1104 if (client)
1105 release_object(client);
1106 else
1108 reply->flags |= NAMED_PIPE_SERVER_END;
1109 release_object(server);
1113 DECL_HANDLER(set_named_pipe_info)
1115 struct pipe_server *server;
1116 struct pipe_client *client = NULL;
1118 server = get_pipe_server_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES );
1119 if (!server)
1121 if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
1122 return;
1124 clear_error();
1125 client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
1126 0, &pipe_client_ops );
1127 if (!client) return;
1128 if (!(server = client->server))
1130 release_object( client );
1131 return;
1135 if ((req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_READ | NAMED_PIPE_NONBLOCKING_MODE)) ||
1136 ((req->flags & NAMED_PIPE_MESSAGE_STREAM_READ) && !(server->pipe->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE)))
1138 set_error( STATUS_INVALID_PARAMETER );
1140 else if (client)
1142 client->pipe_end.flags = server->pipe->flags | req->flags;
1144 else
1146 server->pipe_end.flags = server->pipe->flags | req->flags;
1149 if (client)
1150 release_object(client);
1151 else
1152 release_object(server);