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