Added NONAMELESSUNION/STRUCT defines.
[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 INVALID_HANDLE_VALUE;
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;
511     static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'};
512
513     TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
514           debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
515           nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
516
517     if (!name)
518     {
519         SetLastError( ERROR_PATH_NOT_FOUND );
520         return INVALID_HANDLE_VALUE;
521     }
522     len = strlenW(name);
523     if (len >= MAX_PATH)
524     {
525         SetLastError( ERROR_FILENAME_EXCED_RANGE );
526         return INVALID_HANDLE_VALUE;
527     }
528     if (strncmpiW(name, leadin, sizeof(leadin)/sizeof(leadin[0])))
529     {
530         SetLastError( ERROR_INVALID_NAME );
531         return INVALID_HANDLE_VALUE;
532     }
533     SERVER_START_REQ( create_named_pipe )
534     {
535         req->openmode = dwOpenMode;
536         req->pipemode = dwPipeMode;
537         req->maxinstances = nMaxInstances;
538         req->outsize = nOutBufferSize;
539         req->insize = nInBufferSize;
540         req->timeout = nDefaultTimeOut;
541         wine_server_add_data( req, name, len * sizeof(WCHAR) );
542         SetLastError(0);
543         if (!wine_server_call_err( req )) ret = reply->handle;
544         else ret = INVALID_HANDLE_VALUE;
545     }
546     SERVER_END_REQ;
547     return ret;
548 }
549
550
551 /***********************************************************************
552  *           PeekNamedPipe   (KERNEL32.@)
553  */
554 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
555                            LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
556 {
557 #ifdef FIONREAD
558     int avail=0,fd;
559
560     fd = FILE_GetUnixHandle(hPipe, GENERIC_READ);
561     if (fd == -1) return FALSE;
562
563     if (ioctl(fd,FIONREAD, &avail ) != 0)
564     {
565         TRACE("FIONREAD failed reason: %s\n",strerror(errno));
566         close(fd);
567         return FALSE;
568     }
569     if (!avail)  /* check for closed pipe */
570     {
571         struct pollfd pollfd;
572         pollfd.fd = fd;
573         pollfd.events = POLLIN;
574         pollfd.revents = 0;
575         switch (poll( &pollfd, 1, 0 ))
576         {
577         case 0:
578             break;
579         case 1:  /* got something */
580             if (!(pollfd.revents & (POLLHUP | POLLERR))) break;
581             TRACE("POLLHUP | POLLERR\n");
582             /* fall through */
583         case -1:
584             close(fd);
585             SetLastError(ERROR_BROKEN_PIPE);
586             return FALSE;
587         }
588     }
589     close(fd);
590     TRACE(" 0x%08x bytes available\n", avail );
591     if (!lpvBuffer && lpcbAvail)
592       {
593         *lpcbAvail= avail;
594         return TRUE;
595       }
596 #endif /* defined(FIONREAD) */
597
598     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
599     FIXME("function not implemented\n");
600     return FALSE;
601 }
602
603 /***********************************************************************
604  *           SYNC_CompletePipeOverlapped   (Internal)
605  */
606 static void SYNC_CompletePipeOverlapped (LPOVERLAPPED overlapped, DWORD result)
607 {
608     TRACE("for %p result %08lx\n",overlapped,result);
609     if(!overlapped)
610         return;
611     overlapped->Internal = result;
612     SetEvent(overlapped->hEvent);
613 }
614
615
616 /***********************************************************************
617  *           WaitNamedPipeA   (KERNEL32.@)
618  */
619 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
620 {
621     WCHAR buffer[MAX_PATH];
622
623     if (!name) return WaitNamedPipeW( NULL, nTimeOut );
624
625     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
626     {
627         SetLastError( ERROR_FILENAME_EXCED_RANGE );
628         return 0;
629     }
630     return WaitNamedPipeW( buffer, nTimeOut );
631 }
632
633
634 /***********************************************************************
635  *           WaitNamedPipeW   (KERNEL32.@)
636  */
637 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
638 {
639     DWORD len = name ? strlenW(name) : 0;
640     BOOL ret;
641     OVERLAPPED ov;
642
643     if (len >= MAX_PATH)
644     {
645         SetLastError( ERROR_FILENAME_EXCED_RANGE );
646         return FALSE;
647     }
648
649     TRACE("%s 0x%08lx\n",debugstr_w(name),nTimeOut);
650
651     memset(&ov,0,sizeof ov);
652     ov.hEvent = CreateEventA( NULL, 0, 0, NULL );
653     if (!ov.hEvent)
654         return FALSE;
655
656     SERVER_START_REQ( wait_named_pipe )
657     {
658         req->timeout = nTimeOut;
659         req->overlapped = &ov;
660         req->func = SYNC_CompletePipeOverlapped;
661         wine_server_add_data( req, name, len * sizeof(WCHAR) );
662         ret = !wine_server_call_err( req );
663     }
664     SERVER_END_REQ;
665
666     if(ret)
667     {
668         if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
669         {
670             SetLastError(ov.Internal);
671             ret = (ov.Internal==STATUS_SUCCESS);
672         }
673     }
674     CloseHandle(ov.hEvent);
675     return ret;
676 }
677
678
679 /***********************************************************************
680  *           SYNC_ConnectNamedPipe   (Internal)
681  */
682 static BOOL SYNC_ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
683 {
684     BOOL ret;
685
686     if(!overlapped)
687         return FALSE;
688
689     overlapped->Internal = STATUS_PENDING;
690
691     SERVER_START_REQ( connect_named_pipe )
692     {
693         req->handle = hPipe;
694         req->overlapped = overlapped;
695         req->func = SYNC_CompletePipeOverlapped;
696         ret = !wine_server_call_err( req );
697     }
698     SERVER_END_REQ;
699
700     return ret;
701 }
702
703 /***********************************************************************
704  *           ConnectNamedPipe   (KERNEL32.@)
705  */
706 BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
707 {
708     OVERLAPPED ov;
709     BOOL ret;
710
711     TRACE("(%p,%p)\n",hPipe, overlapped);
712
713     if(overlapped)
714         return SYNC_ConnectNamedPipe(hPipe,overlapped);
715
716     memset(&ov,0,sizeof ov);
717     ov.hEvent = CreateEventA(NULL,0,0,NULL);
718     if (!ov.hEvent)
719         return FALSE;
720
721     ret=SYNC_ConnectNamedPipe(hPipe, &ov);
722     if(ret)
723     {
724         if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
725         {
726             SetLastError(ov.Internal);
727             ret = (ov.Internal==STATUS_SUCCESS);
728         }
729     }
730
731     CloseHandle(ov.hEvent);
732
733     return ret;
734 }
735
736 /***********************************************************************
737  *           DisconnectNamedPipe   (KERNEL32.@)
738  */
739 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
740 {
741     BOOL ret;
742
743     TRACE("(%p)\n",hPipe);
744
745     SERVER_START_REQ( disconnect_named_pipe )
746     {
747         req->handle = hPipe;
748         ret = !wine_server_call_err( req );
749     }
750     SERVER_END_REQ;
751
752     return ret;
753 }
754
755 /***********************************************************************
756  *           TransactNamedPipe   (KERNEL32.@)
757  */
758 BOOL WINAPI TransactNamedPipe(
759     HANDLE hPipe, LPVOID lpInput, DWORD dwInputSize, LPVOID lpOutput,
760     DWORD dwOutputSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
761 {
762     FIXME("%p %p %ld %p %ld %p %p\n",
763           hPipe, lpInput, dwInputSize, lpOutput,
764           dwOutputSize, lpBytesRead, lpOverlapped);
765     if(lpBytesRead)
766         *lpBytesRead=0;
767     return FALSE;
768 }
769
770 /***********************************************************************
771  *           GetNamedPipeInfo   (KERNEL32.@)
772  */
773 BOOL WINAPI GetNamedPipeInfo(
774     HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
775     LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
776 {
777     BOOL ret;
778
779     TRACE("%p %p %p %p %p\n", hNamedPipe, lpFlags,
780           lpOutputBufferSize, lpInputBufferSize, lpMaxInstances);
781
782     SERVER_START_REQ( get_named_pipe_info )
783     {
784         req->handle = hNamedPipe;
785         ret = !wine_server_call_err( req );
786         if(lpFlags) *lpFlags = reply->flags;
787         if(lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
788         if(lpInputBufferSize) *lpInputBufferSize = reply->outsize;
789         if(lpMaxInstances) *lpMaxInstances = reply->maxinstances;
790     }
791     SERVER_END_REQ;
792
793     return ret;
794 }
795
796 /***********************************************************************
797  *           GetNamedPipeHandleStateA  (KERNEL32.@)
798  */
799 BOOL WINAPI GetNamedPipeHandleStateA(
800     HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
801     LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
802     LPSTR lpUsername, DWORD nUsernameMaxSize)
803 {
804     FIXME("%p %p %p %p %p %p %ld\n",
805           hNamedPipe, lpState, lpCurInstances,
806           lpMaxCollectionCount, lpCollectDataTimeout,
807           lpUsername, nUsernameMaxSize);
808
809     return FALSE;
810 }
811
812 /***********************************************************************
813  *           GetNamedPipeHandleStateW  (KERNEL32.@)
814  */
815 BOOL WINAPI GetNamedPipeHandleStateW(
816     HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
817     LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
818     LPWSTR lpUsername, DWORD nUsernameMaxSize)
819 {
820     FIXME("%p %p %p %p %p %p %ld\n",
821           hNamedPipe, lpState, lpCurInstances,
822           lpMaxCollectionCount, lpCollectDataTimeout,
823           lpUsername, nUsernameMaxSize);
824
825     return FALSE;
826 }
827
828 /***********************************************************************
829  *           SetNamedPipeHandleState  (KERNEL32.@)
830  */
831 BOOL WINAPI SetNamedPipeHandleState(
832     HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
833     LPDWORD lpCollectDataTimeout)
834 {
835     FIXME("%p %p %p %p\n",
836           hNamedPipe, lpMode, lpMaxCollectionCount, lpCollectDataTimeout);
837     return FALSE;
838 }
839
840 /***********************************************************************
841  *           CallNamedPipeA  (KERNEL32.@)
842  */
843 BOOL WINAPI CallNamedPipeA(
844     LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
845     LPVOID lpOutput, DWORD lpOutputSize,
846     LPDWORD lpBytesRead, DWORD nTimeout)
847 {
848     FIXME("%s %p %ld %p %ld %p %ld\n",
849            debugstr_a(lpNamedPipeName), lpInput, lpInputSize,
850            lpOutput, lpOutputSize, lpBytesRead, nTimeout);
851     return FALSE;
852 }
853
854 /***********************************************************************
855  *           CallNamedPipeW  (KERNEL32.@)
856  */
857 BOOL WINAPI CallNamedPipeW(
858     LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
859     LPVOID lpOutput, DWORD lpOutputSize,
860     LPDWORD lpBytesRead, DWORD nTimeout)
861 {
862     FIXME("%s %p %ld %p %ld %p %ld\n",
863            debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
864            lpOutput, lpOutputSize, lpBytesRead, nTimeout);
865     return FALSE;
866 }