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