Correct 2 bugs connected to asynchronous shutdown():
[wine] / dlls / kernel / sync.c
1 /*
2  * Kernel synchronization objects
3  *
4  * Copyright 1998 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <string.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28 #include <errno.h>
29 #ifdef HAVE_SYS_IOCTL_H
30 #include <sys/ioctl.h>
31 #endif
32 #ifdef HAVE_SYS_POLL_H
33 #include <sys/poll.h>
34 #endif
35
36 #include "winbase.h"
37 #include "winerror.h"
38 #include "winnls.h"
39
40 #include "wine/server.h"
41 #include "wine/unicode.h"
42 #include "file.h"
43
44 #include "wine/debug.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(win32);
47
48 /*
49  * Events
50  */
51
52
53 /***********************************************************************
54  *           CreateEventA    (KERNEL32.@)
55  */
56 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
57                             BOOL initial_state, LPCSTR name )
58 {
59     WCHAR buffer[MAX_PATH];
60
61     if (!name) return CreateEventW( sa, manual_reset, initial_state, NULL );
62
63     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
64     {
65         SetLastError( ERROR_FILENAME_EXCED_RANGE );
66         return 0;
67     }
68     return CreateEventW( sa, manual_reset, initial_state, buffer );
69 }
70
71
72 /***********************************************************************
73  *           CreateEventW    (KERNEL32.@)
74  */
75 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
76                             BOOL initial_state, LPCWSTR name )
77 {
78     HANDLE ret;
79     DWORD len = name ? strlenW(name) : 0;
80     if (len >= MAX_PATH)
81     {
82         SetLastError( ERROR_FILENAME_EXCED_RANGE );
83         return 0;
84     }
85     /* one buggy program needs this
86      * ("Van Dale Groot woordenboek der Nederlandse taal")
87      */
88     if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
89     {
90         ERR("Bad security attributes pointer %p\n",sa);
91         SetLastError( ERROR_INVALID_PARAMETER);
92         return 0;
93     }
94     SERVER_START_REQ( create_event )
95     {
96         req->manual_reset = manual_reset;
97         req->initial_state = initial_state;
98         req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
99         wine_server_add_data( req, name, len * sizeof(WCHAR) );
100         SetLastError(0);
101         wine_server_call_err( req );
102         ret = reply->handle;
103     }
104     SERVER_END_REQ;
105     return ret;
106 }
107
108
109 /***********************************************************************
110  *           CreateW32Event    (KERNEL.457)
111  */
112 HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
113 {
114     return CreateEventA( NULL, manual_reset, initial_state, NULL );
115 }
116
117
118 /***********************************************************************
119  *           OpenEventA    (KERNEL32.@)
120  */
121 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
122 {
123     WCHAR buffer[MAX_PATH];
124
125     if (!name) return OpenEventW( access, inherit, NULL );
126
127     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
128     {
129         SetLastError( ERROR_FILENAME_EXCED_RANGE );
130         return 0;
131     }
132     return OpenEventW( access, inherit, buffer );
133 }
134
135
136 /***********************************************************************
137  *           OpenEventW    (KERNEL32.@)
138  */
139 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
140 {
141     HANDLE ret;
142     DWORD len = name ? strlenW(name) : 0;
143     if (len >= MAX_PATH)
144     {
145         SetLastError( ERROR_FILENAME_EXCED_RANGE );
146         return 0;
147     }
148     SERVER_START_REQ( open_event )
149     {
150         req->access  = access;
151         req->inherit = inherit;
152         wine_server_add_data( req, name, len * sizeof(WCHAR) );
153         wine_server_call_err( req );
154         ret = reply->handle;
155     }
156     SERVER_END_REQ;
157     return ret;
158 }
159
160
161 /***********************************************************************
162  *           EVENT_Operation
163  *
164  * Execute an event operation (set,reset,pulse).
165  */
166 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
167 {
168     BOOL ret;
169     SERVER_START_REQ( event_op )
170     {
171         req->handle = handle;
172         req->op     = op;
173         ret = !wine_server_call_err( req );
174     }
175     SERVER_END_REQ;
176     return ret;
177 }
178
179
180 /***********************************************************************
181  *           PulseEvent    (KERNEL32.@)
182  */
183 BOOL WINAPI PulseEvent( HANDLE handle )
184 {
185     return EVENT_Operation( handle, PULSE_EVENT );
186 }
187
188
189 /***********************************************************************
190  *           SetW32Event (KERNEL.458)
191  *           SetEvent    (KERNEL32.@)
192  */
193 BOOL WINAPI SetEvent( HANDLE handle )
194 {
195     return EVENT_Operation( handle, SET_EVENT );
196 }
197
198
199 /***********************************************************************
200  *           ResetW32Event (KERNEL.459)
201  *           ResetEvent    (KERNEL32.@)
202  */
203 BOOL WINAPI ResetEvent( HANDLE handle )
204 {
205     return EVENT_Operation( handle, RESET_EVENT );
206 }
207
208
209 /***********************************************************************
210  * NOTE: The Win95 VWin32_Event routines given below are really low-level
211  *       routines implemented directly by VWin32. The user-mode libraries
212  *       implement Win32 synchronisation routines on top of these low-level
213  *       primitives. We do it the other way around here :-)
214  */
215
216 /***********************************************************************
217  *       VWin32_EventCreate     (KERNEL.442)
218  */
219 HANDLE WINAPI VWin32_EventCreate(VOID)
220 {
221     HANDLE hEvent = CreateEventA( NULL, FALSE, 0, NULL );
222     return ConvertToGlobalHandle( hEvent );
223 }
224
225 /***********************************************************************
226  *       VWin32_EventDestroy    (KERNEL.443)
227  */
228 VOID WINAPI VWin32_EventDestroy(HANDLE event)
229 {
230     CloseHandle( event );
231 }
232
233 /***********************************************************************
234  *       VWin32_EventWait       (KERNEL.450)
235  */
236 VOID WINAPI VWin32_EventWait(HANDLE event)
237 {
238     DWORD mutex_count;
239
240     ReleaseThunkLock( &mutex_count );
241     WaitForSingleObject( event, INFINITE );
242     RestoreThunkLock( mutex_count );
243 }
244
245 /***********************************************************************
246  *       VWin32_EventSet        (KERNEL.451)
247  *       KERNEL_479             (KERNEL.479)
248  */
249 VOID WINAPI VWin32_EventSet(HANDLE event)
250 {
251     SetEvent( event );
252 }
253
254
255
256 /***********************************************************************
257  *           CreateMutexA   (KERNEL32.@)
258  */
259 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
260 {
261     WCHAR buffer[MAX_PATH];
262
263     if (!name) return CreateMutexW( sa, owner, NULL );
264
265     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
266     {
267         SetLastError( ERROR_FILENAME_EXCED_RANGE );
268         return 0;
269     }
270     return CreateMutexW( sa, owner, buffer );
271 }
272
273
274 /***********************************************************************
275  *           CreateMutexW   (KERNEL32.@)
276  */
277 HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
278 {
279     HANDLE ret;
280     DWORD len = name ? strlenW(name) : 0;
281     if (len >= MAX_PATH)
282     {
283         SetLastError( ERROR_FILENAME_EXCED_RANGE );
284         return 0;
285     }
286     SERVER_START_REQ( create_mutex )
287     {
288         req->owned   = owner;
289         req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
290         wine_server_add_data( req, name, len * sizeof(WCHAR) );
291         SetLastError(0);
292         wine_server_call_err( req );
293         ret = reply->handle;
294     }
295     SERVER_END_REQ;
296     return ret;
297 }
298
299
300 /***********************************************************************
301  *           OpenMutexA   (KERNEL32.@)
302  */
303 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
304 {
305     WCHAR buffer[MAX_PATH];
306
307     if (!name) return OpenMutexW( access, inherit, NULL );
308
309     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
310     {
311         SetLastError( ERROR_FILENAME_EXCED_RANGE );
312         return 0;
313     }
314     return OpenMutexW( access, inherit, buffer );
315 }
316
317
318 /***********************************************************************
319  *           OpenMutexW   (KERNEL32.@)
320  */
321 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
322 {
323     HANDLE ret;
324     DWORD len = name ? strlenW(name) : 0;
325     if (len >= MAX_PATH)
326     {
327         SetLastError( ERROR_FILENAME_EXCED_RANGE );
328         return 0;
329     }
330     SERVER_START_REQ( open_mutex )
331     {
332         req->access  = access;
333         req->inherit = inherit;
334         wine_server_add_data( req, name, len * sizeof(WCHAR) );
335         wine_server_call_err( req );
336         ret = reply->handle;
337     }
338     SERVER_END_REQ;
339     return ret;
340 }
341
342
343 /***********************************************************************
344  *           ReleaseMutex   (KERNEL32.@)
345  */
346 BOOL WINAPI ReleaseMutex( HANDLE handle )
347 {
348     BOOL ret;
349     SERVER_START_REQ( release_mutex )
350     {
351         req->handle = handle;
352         ret = !wine_server_call_err( req );
353     }
354     SERVER_END_REQ;
355     return ret;
356 }
357
358
359 /*
360  * Semaphores
361  */
362
363
364 /***********************************************************************
365  *           CreateSemaphoreA   (KERNEL32.@)
366  */
367 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
368 {
369     WCHAR buffer[MAX_PATH];
370
371     if (!name) return CreateSemaphoreW( sa, initial, max, NULL );
372
373     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
374     {
375         SetLastError( ERROR_FILENAME_EXCED_RANGE );
376         return 0;
377     }
378     return CreateSemaphoreW( sa, initial, max, buffer );
379 }
380
381
382 /***********************************************************************
383  *           CreateSemaphoreW   (KERNEL32.@)
384  */
385 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
386                                     LONG max, LPCWSTR name )
387 {
388     HANDLE ret;
389     DWORD len = name ? strlenW(name) : 0;
390
391     /* Check parameters */
392
393     if ((max <= 0) || (initial < 0) || (initial > max))
394     {
395         SetLastError( ERROR_INVALID_PARAMETER );
396         return 0;
397     }
398     if (len >= MAX_PATH)
399     {
400         SetLastError( ERROR_FILENAME_EXCED_RANGE );
401         return 0;
402     }
403
404     SERVER_START_REQ( create_semaphore )
405     {
406         req->initial = (unsigned int)initial;
407         req->max     = (unsigned int)max;
408         req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
409         wine_server_add_data( req, name, len * sizeof(WCHAR) );
410         SetLastError(0);
411         wine_server_call_err( req );
412         ret = reply->handle;
413     }
414     SERVER_END_REQ;
415     return ret;
416 }
417
418
419 /***********************************************************************
420  *           OpenSemaphoreA   (KERNEL32.@)
421  */
422 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
423 {
424     WCHAR buffer[MAX_PATH];
425
426     if (!name) return OpenSemaphoreW( access, inherit, NULL );
427
428     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
429     {
430         SetLastError( ERROR_FILENAME_EXCED_RANGE );
431         return 0;
432     }
433     return OpenSemaphoreW( access, inherit, buffer );
434 }
435
436
437 /***********************************************************************
438  *           OpenSemaphoreW   (KERNEL32.@)
439  */
440 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
441 {
442     HANDLE ret;
443     DWORD len = name ? strlenW(name) : 0;
444     if (len >= MAX_PATH)
445     {
446         SetLastError( ERROR_FILENAME_EXCED_RANGE );
447         return 0;
448     }
449     SERVER_START_REQ( open_semaphore )
450     {
451         req->access  = access;
452         req->inherit = inherit;
453         wine_server_add_data( req, name, len * sizeof(WCHAR) );
454         wine_server_call_err( req );
455         ret = reply->handle;
456     }
457     SERVER_END_REQ;
458     return ret;
459 }
460
461
462 /***********************************************************************
463  *           ReleaseSemaphore   (KERNEL32.@)
464  */
465 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
466 {
467     NTSTATUS status = NtReleaseSemaphore( handle, count, previous );
468     if (status) SetLastError( RtlNtStatusToDosError(status) );
469     return !status;
470 }
471
472
473 /*
474  * Pipes
475  */
476
477
478 /***********************************************************************
479  *           CreateNamedPipeA   (KERNEL32.@)
480  */
481 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
482                                 DWORD dwPipeMode, DWORD nMaxInstances,
483                                 DWORD nOutBufferSize, DWORD nInBufferSize,
484                                 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
485 {
486     WCHAR buffer[MAX_PATH];
487
488     if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances,
489                                         nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
490
491     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
492     {
493         SetLastError( ERROR_FILENAME_EXCED_RANGE );
494         return 0;
495     }
496     return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances,
497                              nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
498 }
499
500
501 /***********************************************************************
502  *           CreateNamedPipeW   (KERNEL32.@)
503  */
504 HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
505                                 DWORD dwPipeMode, DWORD nMaxInstances,
506                                 DWORD nOutBufferSize, DWORD nInBufferSize,
507                                 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
508 {
509     HANDLE ret;
510     DWORD len = name ? strlenW(name) : 0;
511
512     TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
513           debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
514           nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
515
516     if (len >= MAX_PATH)
517     {
518         SetLastError( ERROR_FILENAME_EXCED_RANGE );
519         return 0;
520     }
521     SERVER_START_REQ( create_named_pipe )
522     {
523         req->openmode = dwOpenMode;
524         req->pipemode = dwPipeMode;
525         req->maxinstances = nMaxInstances;
526         req->outsize = nOutBufferSize;
527         req->insize = nInBufferSize;
528         req->timeout = nDefaultTimeOut;
529         wine_server_add_data( req, name, len * sizeof(WCHAR) );
530         SetLastError(0);
531         wine_server_call_err( req );
532         ret = reply->handle;
533     }
534     SERVER_END_REQ;
535     return ret;
536 }
537
538
539 /***********************************************************************
540  *           PeekNamedPipe   (KERNEL32.@)
541  */
542 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
543                            LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
544 {
545 #ifdef FIONREAD
546     int avail=0,fd;
547
548     fd = FILE_GetUnixHandle(hPipe, GENERIC_READ);
549     if (fd == -1) return FALSE;
550
551     if (ioctl(fd,FIONREAD, &avail ) != 0)
552     {
553         TRACE("FIONREAD failed reason: %s\n",strerror(errno));
554         close(fd);
555         return FALSE;
556     }
557     if (!avail)  /* check for closed pipe */
558     {
559         struct pollfd pollfd;
560         pollfd.fd = fd;
561         pollfd.events = POLLIN;
562         pollfd.revents = 0;
563         switch (poll( &pollfd, 1, 0 ))
564         {
565         case 0:
566             break;
567         case 1:  /* got something */
568             if (!(pollfd.revents & (POLLHUP | POLLERR))) break;
569             TRACE("POLLHUP | POLLERR\n");
570             /* fall through */
571         case -1:
572             close(fd);
573             SetLastError(ERROR_BROKEN_PIPE);
574             return FALSE;
575         }
576     }
577     close(fd);
578     TRACE(" 0x%08x bytes available\n", avail );
579     if (!lpvBuffer && lpcbAvail)
580       {
581         *lpcbAvail= avail;
582         return TRUE;
583       }
584 #endif /* defined(FIONREAD) */
585
586     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
587     FIXME("function not implemented\n");
588     return FALSE;
589 }
590
591 /***********************************************************************
592  *           SYNC_CompletePipeOverlapped   (Internal)
593  */
594 static void SYNC_CompletePipeOverlapped (LPOVERLAPPED overlapped, DWORD result)
595 {
596     TRACE("for %p result %08lx\n",overlapped,result);
597     if(!overlapped)
598         return;
599     overlapped->Internal = result;
600     SetEvent(overlapped->hEvent);
601 }
602
603
604 /***********************************************************************
605  *           WaitNamedPipeA   (KERNEL32.@)
606  */
607 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
608 {
609     WCHAR buffer[MAX_PATH];
610
611     if (!name) return WaitNamedPipeW( NULL, nTimeOut );
612
613     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
614     {
615         SetLastError( ERROR_FILENAME_EXCED_RANGE );
616         return 0;
617     }
618     return WaitNamedPipeW( buffer, nTimeOut );
619 }
620
621
622 /***********************************************************************
623  *           WaitNamedPipeW   (KERNEL32.@)
624  */
625 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
626 {
627     DWORD len = name ? strlenW(name) : 0;
628     BOOL ret;
629     OVERLAPPED ov;
630
631     if (len >= MAX_PATH)
632     {
633         SetLastError( ERROR_FILENAME_EXCED_RANGE );
634         return FALSE;
635     }
636
637     TRACE("%s 0x%08lx\n",debugstr_w(name),nTimeOut);
638
639     memset(&ov,0,sizeof ov);
640     ov.hEvent = CreateEventA( NULL, 0, 0, NULL );
641     if (!ov.hEvent)
642         return FALSE;
643
644     SERVER_START_REQ( wait_named_pipe )
645     {
646         req->timeout = nTimeOut;
647         req->overlapped = &ov;
648         req->func = SYNC_CompletePipeOverlapped;
649         wine_server_add_data( req, name, len * sizeof(WCHAR) );
650         ret = !wine_server_call_err( req );
651     }
652     SERVER_END_REQ;
653
654     if(ret)
655     {
656         if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
657         {
658             SetLastError(ov.Internal);
659             ret = (ov.Internal==STATUS_SUCCESS);
660         }
661     }
662     CloseHandle(ov.hEvent);
663     return ret;
664 }
665
666
667 /***********************************************************************
668  *           SYNC_ConnectNamedPipe   (Internal)
669  */
670 static BOOL SYNC_ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
671 {
672     BOOL ret;
673
674     if(!overlapped)
675         return FALSE;
676
677     overlapped->Internal = STATUS_PENDING;
678
679     SERVER_START_REQ( connect_named_pipe )
680     {
681         req->handle = hPipe;
682         req->overlapped = overlapped;
683         req->func = SYNC_CompletePipeOverlapped;
684         ret = !wine_server_call_err( req );
685     }
686     SERVER_END_REQ;
687
688     return ret;
689 }
690
691 /***********************************************************************
692  *           ConnectNamedPipe   (KERNEL32.@)
693  */
694 BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
695 {
696     OVERLAPPED ov;
697     BOOL ret;
698
699     TRACE("(%p,%p)\n",hPipe, overlapped);
700
701     if(overlapped)
702         return SYNC_ConnectNamedPipe(hPipe,overlapped);
703
704     memset(&ov,0,sizeof ov);
705     ov.hEvent = CreateEventA(NULL,0,0,NULL);
706     if (!ov.hEvent)
707         return FALSE;
708
709     ret=SYNC_ConnectNamedPipe(hPipe, &ov);
710     if(ret)
711     {
712         if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
713         {
714             SetLastError(ov.Internal);
715             ret = (ov.Internal==STATUS_SUCCESS);
716         }
717     }
718
719     CloseHandle(ov.hEvent);
720
721     return ret;
722 }
723
724 /***********************************************************************
725  *           DisconnectNamedPipe   (KERNEL32.@)
726  */
727 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
728 {
729     BOOL ret;
730
731     TRACE("(%p)\n",hPipe);
732
733     SERVER_START_REQ( disconnect_named_pipe )
734     {
735         req->handle = hPipe;
736         ret = !wine_server_call_err( req );
737     }
738     SERVER_END_REQ;
739
740     return ret;
741 }
742
743 /***********************************************************************
744  *           TransactNamedPipe   (KERNEL32.@)
745  */
746 BOOL WINAPI TransactNamedPipe(
747     HANDLE hPipe, LPVOID lpInput, DWORD dwInputSize, LPVOID lpOutput,
748     DWORD dwOutputSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
749 {
750     FIXME("%p %p %ld %p %ld %p %p\n",
751           hPipe, lpInput, dwInputSize, lpOutput,
752           dwOutputSize, lpBytesRead, lpOverlapped);
753     if(lpBytesRead)
754         *lpBytesRead=0;
755     return FALSE;
756 }
757
758 /***********************************************************************
759  *           GetNamedPipeInfo   (KERNEL32.@)
760  */
761 BOOL WINAPI GetNamedPipeInfo(
762     HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
763     LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
764 {
765     BOOL ret;
766
767     TRACE("%p %p %p %p %p\n", hNamedPipe, lpFlags,
768           lpOutputBufferSize, lpInputBufferSize, lpMaxInstances);
769
770     SERVER_START_REQ( get_named_pipe_info )
771     {
772         req->handle = hNamedPipe;
773         ret = !wine_server_call_err( req );
774         if(lpFlags) *lpFlags = reply->flags;
775         if(lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
776         if(lpInputBufferSize) *lpInputBufferSize = reply->outsize;
777         if(lpMaxInstances) *lpMaxInstances = reply->maxinstances;
778     }
779     SERVER_END_REQ;
780
781     return ret;
782 }
783
784 /***********************************************************************
785  *           GetNamedPipeHandleStateA  (KERNEL32.@)
786  */
787 BOOL WINAPI GetNamedPipeHandleStateA(
788     HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
789     LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
790     LPSTR lpUsername, DWORD nUsernameMaxSize)
791 {
792     FIXME("%p %p %p %p %p %p %ld\n",
793           hNamedPipe, lpState, lpCurInstances,
794           lpMaxCollectionCount, lpCollectDataTimeout,
795           lpUsername, nUsernameMaxSize);
796
797     return FALSE;
798 }
799
800 /***********************************************************************
801  *           GetNamedPipeHandleStateW  (KERNEL32.@)
802  */
803 BOOL WINAPI GetNamedPipeHandleStateW(
804     HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
805     LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
806     LPWSTR lpUsername, DWORD nUsernameMaxSize)
807 {
808     FIXME("%p %p %p %p %p %p %ld\n",
809           hNamedPipe, lpState, lpCurInstances,
810           lpMaxCollectionCount, lpCollectDataTimeout,
811           lpUsername, nUsernameMaxSize);
812
813     return FALSE;
814 }
815
816 /***********************************************************************
817  *           SetNamedPipeHandleState  (KERNEL32.@)
818  */
819 BOOL WINAPI SetNamedPipeHandleState(
820     HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
821     LPDWORD lpCollectDataTimeout)
822 {
823     FIXME("%p %p %p %p\n",
824           hNamedPipe, lpMode, lpMaxCollectionCount, lpCollectDataTimeout);
825     return FALSE;
826 }
827
828 /***********************************************************************
829  *           CallNamedPipeA  (KERNEL32.@)
830  */
831 BOOL WINAPI CallNamedPipeA(
832     LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
833     LPVOID lpOutput, DWORD lpOutputSize,
834     LPDWORD lpBytesRead, DWORD nTimeout)
835 {
836     FIXME("%s %p %ld %p %ld %p %ld\n",
837            debugstr_a(lpNamedPipeName), lpInput, lpInputSize,
838            lpOutput, lpOutputSize, lpBytesRead, nTimeout);
839     return FALSE;
840 }
841
842 /***********************************************************************
843  *           CallNamedPipeW  (KERNEL32.@)
844  */
845 BOOL WINAPI CallNamedPipeW(
846     LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
847     LPVOID lpOutput, DWORD lpOutputSize,
848     LPDWORD lpBytesRead, DWORD nTimeout)
849 {
850     FIXME("%s %p %ld %p %ld %p %ld\n",
851            debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
852            lpOutput, lpOutputSize, lpBytesRead, nTimeout);
853     return FALSE;
854 }