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