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