d3d8: Get rid of the format switching code in d3d8_device_CopyRects().
[wine.git] / server / named_pipe.c
blob3750d25e7906636ea249b5b51f69c42b4b8ed911
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"
56 enum pipe_state
58 ps_idle_server,
59 ps_wait_open,
60 ps_connected_server,
61 ps_wait_disconnect,
62 ps_disconnected_server,
63 ps_wait_connect
66 struct named_pipe;
68 struct pipe_server
70 struct object obj; /* object header */
71 struct fd *fd; /* pipe file descriptor */
72 struct fd *ioctl_fd; /* file descriptor for ioctls when not connected */
73 struct list entry; /* entry in named pipe servers list */
74 enum pipe_state state; /* server state */
75 struct pipe_client *client; /* client that this server is connected to */
76 struct named_pipe *pipe;
77 struct timeout_user *flush_poll;
78 struct event *event;
79 unsigned int options; /* pipe options */
80 unsigned int pipe_flags;
83 struct pipe_client
85 struct object obj; /* object header */
86 struct fd *fd; /* pipe file descriptor */
87 struct pipe_server *server; /* server that this client is connected to */
88 unsigned int flags; /* file flags */
89 unsigned int pipe_flags;
92 struct named_pipe
94 struct object obj; /* object header */
95 unsigned int flags;
96 unsigned int sharing;
97 unsigned int maxinstances;
98 unsigned int outsize;
99 unsigned int insize;
100 unsigned int instances;
101 timeout_t timeout;
102 struct list servers; /* list of servers using this pipe */
103 struct async_queue *waiters; /* list of clients waiting to connect */
106 struct named_pipe_device
108 struct object obj; /* object header */
109 struct fd *fd; /* pseudo-fd for ioctls */
110 struct namespace *pipes; /* named pipe namespace */
113 static void named_pipe_dump( struct object *obj, int verbose );
114 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access );
115 static struct object *named_pipe_open_file( struct object *obj, unsigned int access,
116 unsigned int sharing, unsigned int options );
117 static void named_pipe_destroy( struct object *obj );
119 static const struct object_ops named_pipe_ops =
121 sizeof(struct named_pipe), /* size */
122 named_pipe_dump, /* dump */
123 no_get_type, /* get_type */
124 no_add_queue, /* add_queue */
125 NULL, /* remove_queue */
126 NULL, /* signaled */
127 NULL, /* satisfied */
128 no_signal, /* signal */
129 no_get_fd, /* get_fd */
130 named_pipe_map_access, /* map_access */
131 default_get_sd, /* get_sd */
132 default_set_sd, /* set_sd */
133 no_lookup_name, /* lookup_name */
134 named_pipe_open_file, /* open_file */
135 no_close_handle, /* close_handle */
136 named_pipe_destroy /* destroy */
139 /* server end functions */
140 static void pipe_server_dump( struct object *obj, int verbose );
141 static struct fd *pipe_server_get_fd( struct object *obj );
142 static void pipe_server_destroy( struct object *obj);
143 static void pipe_server_flush( struct fd *fd, struct event **event );
144 static enum server_fd_type pipe_server_get_fd_type( struct fd *fd );
145 static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
146 int blocking, const void *data, data_size_t size );
148 static const struct object_ops pipe_server_ops =
150 sizeof(struct pipe_server), /* size */
151 pipe_server_dump, /* dump */
152 no_get_type, /* get_type */
153 add_queue, /* add_queue */
154 remove_queue, /* remove_queue */
155 default_fd_signaled, /* signaled */
156 no_satisfied, /* satisfied */
157 no_signal, /* signal */
158 pipe_server_get_fd, /* get_fd */
159 default_fd_map_access, /* map_access */
160 default_get_sd, /* get_sd */
161 default_set_sd, /* set_sd */
162 no_lookup_name, /* lookup_name */
163 no_open_file, /* open_file */
164 fd_close_handle, /* close_handle */
165 pipe_server_destroy /* destroy */
168 static const struct fd_ops pipe_server_fd_ops =
170 default_fd_get_poll_events, /* get_poll_events */
171 default_poll_event, /* poll_event */
172 pipe_server_flush, /* flush */
173 pipe_server_get_fd_type, /* get_fd_type */
174 pipe_server_ioctl, /* ioctl */
175 default_fd_queue_async, /* queue_async */
176 default_fd_reselect_async, /* reselect_async */
177 default_fd_cancel_async, /* cancel_async */
180 /* client end functions */
181 static void pipe_client_dump( struct object *obj, int verbose );
182 static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry );
183 static struct fd *pipe_client_get_fd( struct object *obj );
184 static void pipe_client_destroy( struct object *obj );
185 static void pipe_client_flush( struct fd *fd, struct event **event );
186 static enum server_fd_type pipe_client_get_fd_type( struct fd *fd );
188 static const struct object_ops pipe_client_ops =
190 sizeof(struct pipe_client), /* size */
191 pipe_client_dump, /* dump */
192 no_get_type, /* get_type */
193 add_queue, /* add_queue */
194 remove_queue, /* remove_queue */
195 pipe_client_signaled, /* signaled */
196 no_satisfied, /* satisfied */
197 no_signal, /* signal */
198 pipe_client_get_fd, /* get_fd */
199 default_fd_map_access, /* map_access */
200 default_get_sd, /* get_sd */
201 default_set_sd, /* set_sd */
202 no_lookup_name, /* lookup_name */
203 no_open_file, /* open_file */
204 fd_close_handle, /* close_handle */
205 pipe_client_destroy /* destroy */
208 static const struct fd_ops pipe_client_fd_ops =
210 default_fd_get_poll_events, /* get_poll_events */
211 default_poll_event, /* poll_event */
212 pipe_client_flush, /* flush */
213 pipe_client_get_fd_type, /* get_fd_type */
214 default_fd_ioctl, /* ioctl */
215 default_fd_queue_async, /* queue_async */
216 default_fd_reselect_async, /* reselect_async */
217 default_fd_cancel_async /* cancel_async */
220 static void named_pipe_device_dump( struct object *obj, int verbose );
221 static struct object_type *named_pipe_device_get_type( struct object *obj );
222 static struct fd *named_pipe_device_get_fd( struct object *obj );
223 static struct object *named_pipe_device_lookup_name( struct object *obj,
224 struct unicode_str *name, unsigned int attr );
225 static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
226 unsigned int sharing, unsigned int options );
227 static void named_pipe_device_destroy( struct object *obj );
228 static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd );
229 static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
230 int blocking, const void *data, data_size_t size );
232 static const struct object_ops named_pipe_device_ops =
234 sizeof(struct named_pipe_device), /* size */
235 named_pipe_device_dump, /* dump */
236 named_pipe_device_get_type, /* get_type */
237 no_add_queue, /* add_queue */
238 NULL, /* remove_queue */
239 NULL, /* signaled */
240 no_satisfied, /* satisfied */
241 no_signal, /* signal */
242 named_pipe_device_get_fd, /* get_fd */
243 no_map_access, /* map_access */
244 default_get_sd, /* get_sd */
245 default_set_sd, /* set_sd */
246 named_pipe_device_lookup_name, /* lookup_name */
247 named_pipe_device_open_file, /* open_file */
248 fd_close_handle, /* close_handle */
249 named_pipe_device_destroy /* destroy */
252 static const struct fd_ops named_pipe_device_fd_ops =
254 default_fd_get_poll_events, /* get_poll_events */
255 default_poll_event, /* poll_event */
256 no_flush, /* flush */
257 named_pipe_device_get_fd_type, /* get_fd_type */
258 named_pipe_device_ioctl, /* ioctl */
259 default_fd_queue_async, /* queue_async */
260 default_fd_reselect_async, /* reselect_async */
261 default_fd_cancel_async /* cancel_async */
264 static void named_pipe_dump( struct object *obj, int verbose )
266 struct named_pipe *pipe = (struct named_pipe *) obj;
267 assert( obj->ops == &named_pipe_ops );
268 fprintf( stderr, "Named pipe " );
269 dump_object_name( &pipe->obj );
270 fprintf( stderr, "\n" );
273 static unsigned int named_pipe_map_access( struct object *obj, unsigned int access )
275 if (access & GENERIC_READ) access |= STANDARD_RIGHTS_READ;
276 if (access & GENERIC_WRITE) access |= STANDARD_RIGHTS_WRITE | FILE_CREATE_PIPE_INSTANCE;
277 if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE;
278 if (access & GENERIC_ALL) access |= STANDARD_RIGHTS_ALL;
279 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
282 static void pipe_server_dump( struct object *obj, int verbose )
284 struct pipe_server *server = (struct pipe_server *) obj;
285 assert( obj->ops == &pipe_server_ops );
286 fprintf( stderr, "Named pipe server pipe=%p state=%d\n", server->pipe, server->state );
289 static void pipe_client_dump( struct object *obj, int verbose )
291 struct pipe_client *client = (struct pipe_client *) obj;
292 assert( obj->ops == &pipe_client_ops );
293 fprintf( stderr, "Named pipe client server=%p\n", client->server );
296 static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry )
298 struct pipe_client *client = (struct pipe_client *) obj;
300 return client->fd && is_fd_signaled(client->fd);
303 static void named_pipe_destroy( struct object *obj)
305 struct named_pipe *pipe = (struct named_pipe *) obj;
307 assert( list_empty( &pipe->servers ) );
308 assert( !pipe->instances );
309 free_async_queue( pipe->waiters );
312 static struct fd *pipe_client_get_fd( struct object *obj )
314 struct pipe_client *client = (struct pipe_client *) obj;
315 if (client->fd)
316 return (struct fd *) grab_object( client->fd );
317 set_error( STATUS_PIPE_DISCONNECTED );
318 return NULL;
321 static void set_server_state( struct pipe_server *server, enum pipe_state state )
323 server->state = state;
325 switch(state)
327 case ps_connected_server:
328 case ps_wait_disconnect:
329 assert( server->fd );
330 break;
331 case ps_wait_open:
332 case ps_idle_server:
333 assert( !server->fd );
334 set_no_fd_status( server->ioctl_fd, STATUS_PIPE_LISTENING );
335 break;
336 case ps_disconnected_server:
337 case ps_wait_connect:
338 assert( !server->fd );
339 set_no_fd_status( server->ioctl_fd, STATUS_PIPE_DISCONNECTED );
340 break;
344 static struct fd *pipe_server_get_fd( struct object *obj )
346 struct pipe_server *server = (struct pipe_server *) obj;
348 return (struct fd *)grab_object( server->fd ? server->fd : server->ioctl_fd );
352 static void notify_empty( struct pipe_server *server )
354 if (!server->flush_poll)
355 return;
356 assert( server->state == ps_connected_server );
357 assert( server->event );
358 remove_timeout_user( server->flush_poll );
359 server->flush_poll = NULL;
360 set_event( server->event );
361 release_object( server->event );
362 server->event = NULL;
365 static void do_disconnect( struct pipe_server *server )
367 /* we may only have a server fd, if the client disconnected */
368 if (server->client)
370 assert( server->client->server == server );
371 assert( server->client->fd );
372 release_object( server->client->fd );
373 server->client->fd = NULL;
375 assert( server->fd );
376 shutdown( get_unix_fd( server->fd ), SHUT_RDWR );
377 release_object( server->fd );
378 server->fd = NULL;
381 static void pipe_server_destroy( struct object *obj)
383 struct pipe_server *server = (struct pipe_server *)obj;
385 assert( obj->ops == &pipe_server_ops );
387 if (server->fd)
389 notify_empty( server );
390 do_disconnect( server );
393 if (server->client)
395 server->client->server = NULL;
396 server->client = NULL;
399 assert( server->pipe->instances );
400 server->pipe->instances--;
402 if (server->ioctl_fd) release_object( server->ioctl_fd );
403 list_remove( &server->entry );
404 release_object( server->pipe );
407 static void pipe_client_destroy( struct object *obj)
409 struct pipe_client *client = (struct pipe_client *)obj;
410 struct pipe_server *server = client->server;
412 assert( obj->ops == &pipe_client_ops );
414 if (server)
416 notify_empty( server );
418 switch(server->state)
420 case ps_connected_server:
421 /* Don't destroy the server's fd here as we can't
422 do a successful flush without it. */
423 set_server_state( server, ps_wait_disconnect );
424 break;
425 case ps_disconnected_server:
426 set_server_state( server, ps_wait_connect );
427 break;
428 case ps_idle_server:
429 case ps_wait_open:
430 case ps_wait_disconnect:
431 case ps_wait_connect:
432 assert( 0 );
434 assert( server->client );
435 server->client = NULL;
436 client->server = NULL;
438 if (client->fd) release_object( client->fd );
441 static void named_pipe_device_dump( struct object *obj, int verbose )
443 assert( obj->ops == &named_pipe_device_ops );
444 fprintf( stderr, "Named pipe device\n" );
447 static struct object_type *named_pipe_device_get_type( struct object *obj )
449 static const WCHAR name[] = {'D','e','v','i','c','e'};
450 static const struct unicode_str str = { name, sizeof(name) };
451 return get_object_type( &str );
454 static struct fd *named_pipe_device_get_fd( struct object *obj )
456 struct named_pipe_device *device = (struct named_pipe_device *)obj;
457 return (struct fd *)grab_object( device->fd );
460 static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name,
461 unsigned int attr )
463 struct named_pipe_device *device = (struct named_pipe_device*)obj;
464 struct object *found;
466 assert( obj->ops == &named_pipe_device_ops );
467 assert( device->pipes );
469 if ((found = find_object( device->pipes, name, attr | OBJ_CASE_INSENSITIVE )))
470 name->len = 0;
472 return found;
475 static struct object *named_pipe_device_open_file( struct object *obj, unsigned int access,
476 unsigned int sharing, unsigned int options )
478 return grab_object( obj );
481 static void named_pipe_device_destroy( struct object *obj )
483 struct named_pipe_device *device = (struct named_pipe_device*)obj;
484 assert( obj->ops == &named_pipe_device_ops );
485 if (device->fd) release_object( device->fd );
486 free( device->pipes );
489 static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd )
491 return FD_TYPE_DEVICE;
494 void create_named_pipe_device( struct directory *root, const struct unicode_str *name )
496 struct named_pipe_device *dev;
498 if ((dev = create_named_object_dir( root, name, 0, &named_pipe_device_ops )) &&
499 get_error() != STATUS_OBJECT_NAME_EXISTS)
501 dev->pipes = NULL;
502 if (!(dev->fd = alloc_pseudo_fd( &named_pipe_device_fd_ops, &dev->obj, 0 )) ||
503 !(dev->pipes = create_namespace( 7 )))
505 release_object( dev );
506 dev = NULL;
509 if (dev) make_object_static( &dev->obj );
512 static int pipe_data_remaining( struct pipe_server *server )
514 struct pollfd pfd;
515 int fd;
517 assert( server->client );
519 fd = get_unix_fd( server->client->fd );
520 if (fd < 0)
521 return 0;
522 pfd.fd = fd;
523 pfd.events = POLLIN;
524 pfd.revents = 0;
526 if (0 > poll( &pfd, 1, 0 ))
527 return 0;
529 return pfd.revents&POLLIN;
532 static void check_flushed( void *arg )
534 struct pipe_server *server = (struct pipe_server*) arg;
536 assert( server->event );
537 if (pipe_data_remaining( server ))
539 server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server );
541 else
543 /* notify_empty( server ); */
544 server->flush_poll = NULL;
545 set_event( server->event );
546 release_object( server->event );
547 server->event = NULL;
551 static void pipe_server_flush( struct fd *fd, struct event **event )
553 struct pipe_server *server = get_fd_user( fd );
555 if (!server || server->state != ps_connected_server) return;
557 /* FIXME: if multiple threads flush the same pipe,
558 maybe should create a list of processes to notify */
559 if (server->flush_poll) return;
561 if (pipe_data_remaining( server ))
563 /* this kind of sux -
564 there's no unix way to be alerted when a pipe becomes empty */
565 server->event = create_event( NULL, NULL, 0, 0, 0, NULL );
566 if (!server->event) return;
567 server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server );
568 *event = server->event;
572 static void pipe_client_flush( struct fd *fd, struct event **event )
574 /* FIXME: what do we have to do for this? */
577 static inline int is_overlapped( unsigned int options )
579 return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
582 static enum server_fd_type pipe_server_get_fd_type( struct fd *fd )
584 return FD_TYPE_PIPE;
587 static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
589 return FD_TYPE_PIPE;
592 static obj_handle_t alloc_wait_event( struct process *process )
594 obj_handle_t handle = 0;
595 struct event *event = create_event( NULL, NULL, 0, 1, 0, NULL );
597 if (event)
599 handle = alloc_handle( process, event, EVENT_ALL_ACCESS, 0 );
600 release_object( event );
602 return handle;
605 static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
606 int blocking, const void *data, data_size_t size )
608 struct pipe_server *server = get_fd_user( fd );
609 struct async *async;
610 obj_handle_t wait_handle = 0;
612 switch(code)
614 case FSCTL_PIPE_LISTEN:
615 switch(server->state)
617 case ps_idle_server:
618 case ps_wait_connect:
619 if (blocking)
621 async_data_t new_data = *async_data;
622 if (!(wait_handle = alloc_wait_event( current->process ))) break;
623 new_data.event = wait_handle;
624 if (!(async = fd_queue_async( server->ioctl_fd, &new_data, ASYNC_TYPE_WAIT )))
626 close_handle( current->process, wait_handle );
627 break;
630 else async = fd_queue_async( server->ioctl_fd, async_data, ASYNC_TYPE_WAIT );
632 if (async)
634 set_server_state( server, ps_wait_open );
635 if (server->pipe->waiters) async_wake_up( server->pipe->waiters, STATUS_SUCCESS );
636 release_object( async );
637 set_error( STATUS_PENDING );
638 return wait_handle;
640 break;
641 case ps_connected_server:
642 set_error( STATUS_PIPE_CONNECTED );
643 break;
644 case ps_disconnected_server:
645 set_error( STATUS_PIPE_BUSY );
646 break;
647 case ps_wait_disconnect:
648 set_error( STATUS_NO_DATA_DETECTED );
649 break;
650 case ps_wait_open:
651 set_error( STATUS_INVALID_HANDLE );
652 break;
654 return 0;
656 case FSCTL_PIPE_DISCONNECT:
657 switch(server->state)
659 case ps_connected_server:
660 assert( server->client );
661 assert( server->client->fd );
663 notify_empty( server );
665 /* dump the client and server fds, but keep the pointers
666 around - client loses all waiting data */
667 do_disconnect( server );
668 set_server_state( server, ps_disconnected_server );
669 break;
670 case ps_wait_disconnect:
671 assert( !server->client );
672 do_disconnect( server );
673 set_server_state( server, ps_wait_connect );
674 break;
675 case ps_idle_server:
676 case ps_wait_open:
677 set_error( STATUS_PIPE_LISTENING );
678 break;
679 case ps_disconnected_server:
680 case ps_wait_connect:
681 set_error( STATUS_PIPE_DISCONNECTED );
682 break;
684 return 0;
686 default:
687 return default_fd_ioctl( fd, code, async_data, blocking, data, size );
691 static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name,
692 unsigned int attr )
694 struct object *obj;
695 struct named_pipe *pipe = NULL;
696 struct unicode_str new_name;
698 if (!name || !name->len) return alloc_object( &named_pipe_ops );
700 if (!(obj = find_object_dir( root, name, attr, &new_name )))
702 set_error( STATUS_OBJECT_NAME_INVALID );
703 return NULL;
705 if (!new_name.len)
707 if (attr & OBJ_OPENIF && obj->ops == &named_pipe_ops)
708 set_error( STATUS_OBJECT_NAME_EXISTS );
709 else
711 release_object( obj );
712 obj = NULL;
713 if (attr & OBJ_OPENIF)
714 set_error( STATUS_OBJECT_TYPE_MISMATCH );
715 else
716 set_error( STATUS_OBJECT_NAME_COLLISION );
718 return (struct named_pipe *)obj;
721 if (obj->ops != &named_pipe_device_ops)
722 set_error( STATUS_OBJECT_NAME_INVALID );
723 else
725 struct named_pipe_device *dev = (struct named_pipe_device *)obj;
726 if ((pipe = create_object( dev->pipes, &named_pipe_ops, &new_name, NULL )))
727 clear_error();
730 release_object( obj );
731 return pipe;
734 static struct pipe_server *get_pipe_server_obj( struct process *process,
735 obj_handle_t handle, unsigned int access )
737 struct object *obj;
738 obj = get_handle_obj( process, handle, access, &pipe_server_ops );
739 return (struct pipe_server *) obj;
742 static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options,
743 unsigned int pipe_flags )
745 struct pipe_server *server;
747 server = alloc_object( &pipe_server_ops );
748 if (!server)
749 return NULL;
751 server->fd = NULL;
752 server->pipe = pipe;
753 server->client = NULL;
754 server->flush_poll = NULL;
755 server->options = options;
756 server->pipe_flags = pipe_flags;
758 list_add_head( &pipe->servers, &server->entry );
759 grab_object( pipe );
760 if (!(server->ioctl_fd = alloc_pseudo_fd( &pipe_server_fd_ops, &server->obj, options )))
762 release_object( server );
763 return NULL;
765 set_server_state( server, ps_idle_server );
766 return server;
769 static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int pipe_flags )
771 struct pipe_client *client;
773 client = alloc_object( &pipe_client_ops );
774 if (!client)
775 return NULL;
777 client->fd = NULL;
778 client->server = NULL;
779 client->flags = flags;
780 client->pipe_flags = pipe_flags;
782 return client;
785 static struct pipe_server *find_available_server( struct named_pipe *pipe )
787 struct pipe_server *server;
789 /* look for pipe servers that are listening */
790 LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
792 if (server->state == ps_wait_open)
793 return (struct pipe_server *)grab_object( server );
796 /* fall back to pipe servers that are idle */
797 LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
799 if (server->state == ps_idle_server)
800 return (struct pipe_server *)grab_object( server );
803 return NULL;
806 static struct object *named_pipe_open_file( struct object *obj, unsigned int access,
807 unsigned int sharing, unsigned int options )
809 struct named_pipe *pipe = (struct named_pipe *)obj;
810 struct pipe_server *server;
811 struct pipe_client *client;
812 unsigned int pipe_sharing;
813 int fds[2];
815 if (!(server = find_available_server( pipe )))
817 set_error( STATUS_PIPE_NOT_AVAILABLE );
818 return NULL;
821 pipe_sharing = server->pipe->sharing;
822 if (((access & GENERIC_READ) && !(pipe_sharing & FILE_SHARE_READ)) ||
823 ((access & GENERIC_WRITE) && !(pipe_sharing & FILE_SHARE_WRITE)))
825 set_error( STATUS_ACCESS_DENIED );
826 release_object( server );
827 return NULL;
830 if ((client = create_pipe_client( options, pipe->flags )))
832 if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
834 assert( !server->fd );
836 /* for performance reasons, only set nonblocking mode when using
837 * overlapped I/O. Otherwise, we will be doing too much busy
838 * looping */
839 if (is_overlapped( options )) fcntl( fds[1], F_SETFL, O_NONBLOCK );
840 if (is_overlapped( server->options )) fcntl( fds[0], F_SETFL, O_NONBLOCK );
842 if (pipe->insize)
844 setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
845 setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
847 if (pipe->outsize)
849 setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
850 setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
853 client->fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->obj, options );
854 server->fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->obj, server->options );
855 if (client->fd && server->fd)
857 allow_fd_caching( client->fd );
858 allow_fd_caching( server->fd );
859 fd_copy_completion( server->ioctl_fd, server->fd );
860 if (server->state == ps_wait_open)
861 fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
862 set_server_state( server, ps_connected_server );
863 server->client = client;
864 client->server = server;
866 else
868 release_object( client );
869 client = NULL;
872 else
874 file_set_error();
875 release_object( client );
876 client = NULL;
879 release_object( server );
880 return &client->obj;
883 static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
884 int blocking, const void *data, data_size_t size )
886 struct named_pipe_device *device = get_fd_user( fd );
888 switch(code)
890 case FSCTL_PIPE_WAIT:
892 const FILE_PIPE_WAIT_FOR_BUFFER *buffer = data;
893 obj_handle_t wait_handle = 0;
894 struct named_pipe *pipe;
895 struct pipe_server *server;
896 struct unicode_str name;
898 if (size < sizeof(*buffer) ||
899 size < FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[buffer->NameLength/sizeof(WCHAR)]))
901 set_error( STATUS_INVALID_PARAMETER );
902 return 0;
904 name.str = buffer->Name;
905 name.len = (buffer->NameLength / sizeof(WCHAR)) * sizeof(WCHAR);
906 if (!(pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE )))
908 set_error( STATUS_OBJECT_NAME_NOT_FOUND );
909 return 0;
911 if (!(server = find_available_server( pipe )))
913 struct async *async;
915 if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done;
917 if (blocking)
919 async_data_t new_data = *async_data;
920 if (!(wait_handle = alloc_wait_event( current->process ))) goto done;
921 new_data.event = wait_handle;
922 if (!(async = create_async( current, pipe->waiters, &new_data )))
924 close_handle( current->process, wait_handle );
925 wait_handle = 0;
928 else async = create_async( current, pipe->waiters, async_data );
930 if (async)
932 timeout_t when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout;
933 async_set_timeout( async, when, STATUS_IO_TIMEOUT );
934 release_object( async );
935 set_error( STATUS_PENDING );
938 else release_object( server );
940 done:
941 release_object( pipe );
942 return wait_handle;
945 default:
946 return default_fd_ioctl( fd, code, async_data, blocking, data, size );
951 DECL_HANDLER(create_named_pipe)
953 struct named_pipe *pipe;
954 struct pipe_server *server;
955 struct unicode_str name;
956 struct directory *root = NULL;
958 if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
959 (!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ)))
961 set_error( STATUS_INVALID_PARAMETER );
962 return;
965 reply->handle = 0;
966 get_req_unicode_str( &name );
967 if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
968 return;
970 pipe = create_named_pipe( root, &name, req->attributes | OBJ_OPENIF );
972 if (root) release_object( root );
973 if (!pipe) return;
975 if (get_error() != STATUS_OBJECT_NAME_EXISTS)
977 /* initialize it if it didn't already exist */
978 pipe->instances = 0;
979 pipe->waiters = NULL;
980 list_init( &pipe->servers );
981 pipe->insize = req->insize;
982 pipe->outsize = req->outsize;
983 pipe->maxinstances = req->maxinstances;
984 pipe->timeout = req->timeout;
985 pipe->flags = req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE;
986 pipe->sharing = req->sharing;
988 else
990 if (pipe->maxinstances <= pipe->instances)
992 set_error( STATUS_INSTANCE_NOT_AVAILABLE );
993 release_object( pipe );
994 return;
996 if (pipe->sharing != req->sharing)
998 set_error( STATUS_ACCESS_DENIED );
999 release_object( pipe );
1000 return;
1002 clear_error(); /* clear the name collision */
1005 server = create_pipe_server( pipe, req->options, req->flags );
1006 if (server)
1008 reply->handle = alloc_handle( current->process, server, req->access, req->attributes );
1009 server->pipe->instances++;
1010 release_object( server );
1013 release_object( pipe );
1016 DECL_HANDLER(get_named_pipe_info)
1018 struct pipe_server *server;
1019 struct pipe_client *client = NULL;
1021 server = get_pipe_server_obj( current->process, req->handle, FILE_READ_ATTRIBUTES );
1022 if (!server)
1024 if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
1025 return;
1027 clear_error();
1028 client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
1029 0, &pipe_client_ops );
1030 if (!client) return;
1031 server = client->server;
1034 reply->flags = client ? client->pipe_flags : server->pipe_flags;
1035 reply->sharing = server->pipe->sharing;
1036 reply->maxinstances = server->pipe->maxinstances;
1037 reply->instances = server->pipe->instances;
1038 reply->insize = server->pipe->insize;
1039 reply->outsize = server->pipe->outsize;
1041 if (client)
1042 release_object(client);
1043 else
1045 reply->flags |= NAMED_PIPE_SERVER_END;
1046 release_object(server);
1050 DECL_HANDLER(set_named_pipe_info)
1052 struct pipe_server *server;
1053 struct pipe_client *client = NULL;
1055 server = get_pipe_server_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES );
1056 if (!server)
1058 if (get_error() != STATUS_OBJECT_TYPE_MISMATCH)
1059 return;
1061 clear_error();
1062 client = (struct pipe_client *)get_handle_obj( current->process, req->handle,
1063 0, &pipe_client_ops );
1064 if (!client) return;
1065 server = client->server;
1068 if ((req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_READ | NAMED_PIPE_NONBLOCKING_MODE)) ||
1069 ((req->flags & NAMED_PIPE_MESSAGE_STREAM_READ) && !(server->pipe->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE)))
1071 set_error( STATUS_INVALID_PARAMETER );
1073 else if (client)
1075 client->pipe_flags = server->pipe->flags | req->flags;
1077 else
1079 server->pipe_flags = server->pipe->flags | req->flags;
1082 if (client)
1083 release_object(client);
1084 else
1085 release_object(server);