2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
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.
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.
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
22 #include "wine/port.h"
29 #ifdef HAVE_SYS_IOCTL_H
30 #include <sys/ioctl.h>
32 #ifdef HAVE_SYS_POLL_H
41 #include "wine/server.h"
42 #include "wine/unicode.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(win32);
49 /* check if current version is NT or Win95 */
50 inline static int is_version_nt(void)
52 return !(GetVersion() & 0x80000000);
56 /***********************************************************************
57 * CreateEventA (KERNEL32.@)
59 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
60 BOOL initial_state, LPCSTR name )
62 WCHAR buffer[MAX_PATH];
64 if (!name) return CreateEventW( sa, manual_reset, initial_state, NULL );
66 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
68 SetLastError( ERROR_FILENAME_EXCED_RANGE );
71 return CreateEventW( sa, manual_reset, initial_state, buffer );
75 /***********************************************************************
76 * CreateEventW (KERNEL32.@)
78 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
79 BOOL initial_state, LPCWSTR name )
82 DWORD len = name ? strlenW(name) : 0;
85 SetLastError( ERROR_FILENAME_EXCED_RANGE );
88 /* one buggy program needs this
89 * ("Van Dale Groot woordenboek der Nederlandse taal")
91 if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
93 ERR("Bad security attributes pointer %p\n",sa);
94 SetLastError( ERROR_INVALID_PARAMETER);
97 SERVER_START_REQ( create_event )
99 req->manual_reset = manual_reset;
100 req->initial_state = initial_state;
101 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
102 wine_server_add_data( req, name, len * sizeof(WCHAR) );
104 wine_server_call_err( req );
112 /***********************************************************************
113 * CreateW32Event (KERNEL.457)
115 HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
117 return CreateEventA( NULL, manual_reset, initial_state, NULL );
121 /***********************************************************************
122 * OpenEventA (KERNEL32.@)
124 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
126 WCHAR buffer[MAX_PATH];
128 if (!name) return OpenEventW( access, inherit, NULL );
130 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
132 SetLastError( ERROR_FILENAME_EXCED_RANGE );
135 return OpenEventW( access, inherit, buffer );
139 /***********************************************************************
140 * OpenEventW (KERNEL32.@)
142 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
145 DWORD len = name ? strlenW(name) : 0;
148 SetLastError( ERROR_FILENAME_EXCED_RANGE );
151 if (!is_version_nt()) access = EVENT_ALL_ACCESS;
153 SERVER_START_REQ( open_event )
155 req->access = access;
156 req->inherit = inherit;
157 wine_server_add_data( req, name, len * sizeof(WCHAR) );
158 wine_server_call_err( req );
166 /***********************************************************************
169 * Execute an event operation (set,reset,pulse).
171 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
174 SERVER_START_REQ( event_op )
176 req->handle = handle;
178 ret = !wine_server_call_err( req );
185 /***********************************************************************
186 * PulseEvent (KERNEL32.@)
188 BOOL WINAPI PulseEvent( HANDLE handle )
190 return EVENT_Operation( handle, PULSE_EVENT );
194 /***********************************************************************
195 * SetW32Event (KERNEL.458)
196 * SetEvent (KERNEL32.@)
198 BOOL WINAPI SetEvent( HANDLE handle )
200 return EVENT_Operation( handle, SET_EVENT );
204 /***********************************************************************
205 * ResetW32Event (KERNEL.459)
206 * ResetEvent (KERNEL32.@)
208 BOOL WINAPI ResetEvent( HANDLE handle )
210 return EVENT_Operation( handle, RESET_EVENT );
214 /***********************************************************************
215 * NOTE: The Win95 VWin32_Event routines given below are really low-level
216 * routines implemented directly by VWin32. The user-mode libraries
217 * implement Win32 synchronisation routines on top of these low-level
218 * primitives. We do it the other way around here :-)
221 /***********************************************************************
222 * VWin32_EventCreate (KERNEL.442)
224 HANDLE WINAPI VWin32_EventCreate(VOID)
226 HANDLE hEvent = CreateEventA( NULL, FALSE, 0, NULL );
227 return ConvertToGlobalHandle( hEvent );
230 /***********************************************************************
231 * VWin32_EventDestroy (KERNEL.443)
233 VOID WINAPI VWin32_EventDestroy(HANDLE event)
235 CloseHandle( event );
238 /***********************************************************************
239 * VWin32_EventWait (KERNEL.450)
241 VOID WINAPI VWin32_EventWait(HANDLE event)
245 ReleaseThunkLock( &mutex_count );
246 WaitForSingleObject( event, INFINITE );
247 RestoreThunkLock( mutex_count );
250 /***********************************************************************
251 * VWin32_EventSet (KERNEL.451)
252 * KERNEL_479 (KERNEL.479)
254 VOID WINAPI VWin32_EventSet(HANDLE event)
261 /***********************************************************************
262 * CreateMutexA (KERNEL32.@)
264 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
266 WCHAR buffer[MAX_PATH];
268 if (!name) return CreateMutexW( sa, owner, NULL );
270 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
272 SetLastError( ERROR_FILENAME_EXCED_RANGE );
275 return CreateMutexW( sa, owner, buffer );
279 /***********************************************************************
280 * CreateMutexW (KERNEL32.@)
282 HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
285 DWORD len = name ? strlenW(name) : 0;
288 SetLastError( ERROR_FILENAME_EXCED_RANGE );
291 SERVER_START_REQ( create_mutex )
294 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
295 wine_server_add_data( req, name, len * sizeof(WCHAR) );
297 wine_server_call_err( req );
305 /***********************************************************************
306 * OpenMutexA (KERNEL32.@)
308 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
310 WCHAR buffer[MAX_PATH];
312 if (!name) return OpenMutexW( access, inherit, NULL );
314 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
316 SetLastError( ERROR_FILENAME_EXCED_RANGE );
319 return OpenMutexW( access, inherit, buffer );
323 /***********************************************************************
324 * OpenMutexW (KERNEL32.@)
326 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
329 DWORD len = name ? strlenW(name) : 0;
332 SetLastError( ERROR_FILENAME_EXCED_RANGE );
335 if (!is_version_nt()) access = MUTEX_ALL_ACCESS;
337 SERVER_START_REQ( open_mutex )
339 req->access = access;
340 req->inherit = inherit;
341 wine_server_add_data( req, name, len * sizeof(WCHAR) );
342 wine_server_call_err( req );
350 /***********************************************************************
351 * ReleaseMutex (KERNEL32.@)
353 BOOL WINAPI ReleaseMutex( HANDLE handle )
356 SERVER_START_REQ( release_mutex )
358 req->handle = handle;
359 ret = !wine_server_call_err( req );
371 /***********************************************************************
372 * CreateSemaphoreA (KERNEL32.@)
374 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
376 WCHAR buffer[MAX_PATH];
378 if (!name) return CreateSemaphoreW( sa, initial, max, NULL );
380 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
382 SetLastError( ERROR_FILENAME_EXCED_RANGE );
385 return CreateSemaphoreW( sa, initial, max, buffer );
389 /***********************************************************************
390 * CreateSemaphoreW (KERNEL32.@)
392 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
393 LONG max, LPCWSTR name )
396 DWORD len = name ? strlenW(name) : 0;
398 /* Check parameters */
400 if ((max <= 0) || (initial < 0) || (initial > max))
402 SetLastError( ERROR_INVALID_PARAMETER );
407 SetLastError( ERROR_FILENAME_EXCED_RANGE );
411 SERVER_START_REQ( create_semaphore )
413 req->initial = (unsigned int)initial;
414 req->max = (unsigned int)max;
415 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
416 wine_server_add_data( req, name, len * sizeof(WCHAR) );
418 wine_server_call_err( req );
426 /***********************************************************************
427 * OpenSemaphoreA (KERNEL32.@)
429 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
431 WCHAR buffer[MAX_PATH];
433 if (!name) return OpenSemaphoreW( access, inherit, NULL );
435 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
437 SetLastError( ERROR_FILENAME_EXCED_RANGE );
440 return OpenSemaphoreW( access, inherit, buffer );
444 /***********************************************************************
445 * OpenSemaphoreW (KERNEL32.@)
447 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
450 DWORD len = name ? strlenW(name) : 0;
453 SetLastError( ERROR_FILENAME_EXCED_RANGE );
456 if (!is_version_nt()) access = SEMAPHORE_ALL_ACCESS;
458 SERVER_START_REQ( open_semaphore )
460 req->access = access;
461 req->inherit = inherit;
462 wine_server_add_data( req, name, len * sizeof(WCHAR) );
463 wine_server_call_err( req );
471 /***********************************************************************
472 * ReleaseSemaphore (KERNEL32.@)
474 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
476 NTSTATUS status = NtReleaseSemaphore( handle, count, previous );
477 if (status) SetLastError( RtlNtStatusToDosError(status) );
487 /***********************************************************************
488 * CreateWaitableTimerA (KERNEL32.@)
490 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
492 WCHAR buffer[MAX_PATH];
494 if (!name) return CreateWaitableTimerW( sa, manual, NULL );
496 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
498 SetLastError( ERROR_FILENAME_EXCED_RANGE );
501 return CreateWaitableTimerW( sa, manual, buffer );
505 /***********************************************************************
506 * CreateWaitableTimerW (KERNEL32.@)
508 HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
514 OBJECT_ATTRIBUTES oa;
516 if (name) RtlInitUnicodeString(&us, name);
517 if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle)
519 InitializeObjectAttributes(&oa, name ? &us : NULL, attr,
520 NULL /* FIXME */, NULL /* FIXME */);
521 status = NtCreateTimer(&handle, TIMER_ALL_ACCESS, &oa,
522 manual ? NotificationTimer : SynchronizationTimer);
524 if (status != STATUS_SUCCESS)
526 SetLastError( RtlNtStatusToDosError(status) );
533 /***********************************************************************
534 * OpenWaitableTimerA (KERNEL32.@)
536 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
538 WCHAR buffer[MAX_PATH];
540 if (!name) return OpenWaitableTimerW( access, inherit, NULL );
542 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
544 SetLastError( ERROR_FILENAME_EXCED_RANGE );
547 return OpenWaitableTimerW( access, inherit, buffer );
551 /***********************************************************************
552 * OpenWaitableTimerW (KERNEL32.@)
554 HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
560 OBJECT_ATTRIBUTES oa;
562 if (inherit) attr |= OBJ_INHERIT;
564 if (name) RtlInitUnicodeString(&us, name);
565 InitializeObjectAttributes(&oa, name ? &us : NULL, attr, NULL /* FIXME */, NULL /* FIXME */);
566 status = NtOpenTimer(&handle, access, &oa);
567 if (status != STATUS_SUCCESS)
569 SetLastError( RtlNtStatusToDosError(status) );
576 /***********************************************************************
577 * SetWaitableTimer (KERNEL32.@)
579 BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
580 PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
582 NTSTATUS status = NtSetTimer(handle, when, callback, arg, resume, period, NULL);
584 if (status != STATUS_SUCCESS)
586 SetLastError( RtlNtStatusToDosError(status) );
587 if (status != STATUS_TIMER_RESUME_IGNORED) return FALSE;
593 /***********************************************************************
594 * CancelWaitableTimer (KERNEL32.@)
596 BOOL WINAPI CancelWaitableTimer( HANDLE handle )
600 status = NtCancelTimer(handle, NULL);
601 if (status != STATUS_SUCCESS)
603 SetLastError( RtlNtStatusToDosError(status) );
610 /***********************************************************************
611 * CreateTimerQueue (KERNEL32.@)
613 HANDLE WINAPI CreateTimerQueue(void)
616 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
621 /***********************************************************************
622 * DeleteTimerQueueEx (KERNEL32.@)
624 BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
626 FIXME("(%p, %p): stub\n", TimerQueue, CompletionEvent);
627 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
631 /***********************************************************************
632 * CreateTimerQueueTimer (KERNEL32.@)
634 * Creates a timer-queue timer. This timer expires at the specified due
635 * time (in ms), then after every specified period (in ms). When the timer
636 * expires, the callback function is called.
639 * nonzero on success or zero on faillure
644 BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue,
645 WAITORTIMERCALLBACK Callback, PVOID Parameter,
646 DWORD DueTime, DWORD Period, ULONG Flags )
649 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
653 /***********************************************************************
654 * DeleteTimerQueueTimer (KERNEL32.@)
656 * Cancels a timer-queue timer.
659 * nonzero on success or zero on faillure
664 BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer,
665 HANDLE CompletionEvent )
668 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
678 /***********************************************************************
679 * CreateNamedPipeA (KERNEL32.@)
681 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
682 DWORD dwPipeMode, DWORD nMaxInstances,
683 DWORD nOutBufferSize, DWORD nInBufferSize,
684 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
686 WCHAR buffer[MAX_PATH];
688 if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances,
689 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
691 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
693 SetLastError( ERROR_FILENAME_EXCED_RANGE );
694 return INVALID_HANDLE_VALUE;
696 return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances,
697 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
701 /***********************************************************************
702 * CreateNamedPipeW (KERNEL32.@)
704 HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
705 DWORD dwPipeMode, DWORD nMaxInstances,
706 DWORD nOutBufferSize, DWORD nInBufferSize,
707 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
711 static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'};
713 TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
714 debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
715 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
719 SetLastError( ERROR_PATH_NOT_FOUND );
720 return INVALID_HANDLE_VALUE;
725 SetLastError( ERROR_FILENAME_EXCED_RANGE );
726 return INVALID_HANDLE_VALUE;
728 if (strncmpiW(name, leadin, sizeof(leadin)/sizeof(leadin[0])))
730 SetLastError( ERROR_INVALID_NAME );
731 return INVALID_HANDLE_VALUE;
733 SERVER_START_REQ( create_named_pipe )
735 req->openmode = dwOpenMode;
736 req->pipemode = dwPipeMode;
737 req->maxinstances = nMaxInstances;
738 req->outsize = nOutBufferSize;
739 req->insize = nInBufferSize;
740 req->timeout = nDefaultTimeOut;
741 wine_server_add_data( req, name, len * sizeof(WCHAR) );
743 if (!wine_server_call_err( req )) ret = reply->handle;
744 else ret = INVALID_HANDLE_VALUE;
751 /***********************************************************************
752 * PeekNamedPipe (KERNEL32.@)
754 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
755 LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
760 fd = FILE_GetUnixHandle(hPipe, GENERIC_READ);
761 if (fd == -1) return FALSE;
763 if (ioctl(fd,FIONREAD, &avail ) != 0)
765 TRACE("FIONREAD failed reason: %s\n",strerror(errno));
769 if (!avail) /* check for closed pipe */
771 struct pollfd pollfd;
773 pollfd.events = POLLIN;
775 switch (poll( &pollfd, 1, 0 ))
779 case 1: /* got something */
780 if (!(pollfd.revents & (POLLHUP | POLLERR))) break;
781 TRACE("POLLHUP | POLLERR\n");
785 SetLastError(ERROR_BROKEN_PIPE);
790 TRACE(" 0x%08x bytes available\n", avail );
791 if (!lpvBuffer && lpcbAvail)
796 #endif /* defined(FIONREAD) */
798 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
799 FIXME("function not implemented\n");
803 /***********************************************************************
804 * SYNC_CompletePipeOverlapped (Internal)
806 static void SYNC_CompletePipeOverlapped (LPOVERLAPPED overlapped, DWORD result)
808 TRACE("for %p result %08lx\n",overlapped,result);
811 overlapped->Internal = result;
812 SetEvent(overlapped->hEvent);
816 /***********************************************************************
817 * WaitNamedPipeA (KERNEL32.@)
819 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
821 WCHAR buffer[MAX_PATH];
823 if (!name) return WaitNamedPipeW( NULL, nTimeOut );
825 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
827 SetLastError( ERROR_FILENAME_EXCED_RANGE );
830 return WaitNamedPipeW( buffer, nTimeOut );
834 /***********************************************************************
835 * WaitNamedPipeW (KERNEL32.@)
837 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
839 DWORD len = name ? strlenW(name) : 0;
845 SetLastError( ERROR_FILENAME_EXCED_RANGE );
849 TRACE("%s 0x%08lx\n",debugstr_w(name),nTimeOut);
851 memset(&ov,0,sizeof ov);
852 ov.hEvent = CreateEventA( NULL, 0, 0, NULL );
856 SERVER_START_REQ( wait_named_pipe )
858 req->timeout = nTimeOut;
859 req->overlapped = &ov;
860 req->func = SYNC_CompletePipeOverlapped;
861 wine_server_add_data( req, name, len * sizeof(WCHAR) );
862 ret = !wine_server_call_err( req );
868 if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
870 SetLastError(ov.Internal);
871 ret = (ov.Internal==STATUS_SUCCESS);
874 CloseHandle(ov.hEvent);
879 /***********************************************************************
880 * SYNC_ConnectNamedPipe (Internal)
882 static BOOL SYNC_ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
889 overlapped->Internal = STATUS_PENDING;
891 SERVER_START_REQ( connect_named_pipe )
894 req->overlapped = overlapped;
895 req->func = SYNC_CompletePipeOverlapped;
896 ret = !wine_server_call_err( req );
903 /***********************************************************************
904 * ConnectNamedPipe (KERNEL32.@)
906 BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
911 TRACE("(%p,%p)\n",hPipe, overlapped);
914 return SYNC_ConnectNamedPipe(hPipe,overlapped);
916 memset(&ov,0,sizeof ov);
917 ov.hEvent = CreateEventA(NULL,0,0,NULL);
921 ret=SYNC_ConnectNamedPipe(hPipe, &ov);
924 if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
926 SetLastError(ov.Internal);
927 ret = (ov.Internal==STATUS_SUCCESS);
931 CloseHandle(ov.hEvent);
936 /***********************************************************************
937 * DisconnectNamedPipe (KERNEL32.@)
939 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
943 TRACE("(%p)\n",hPipe);
945 SERVER_START_REQ( disconnect_named_pipe )
948 ret = !wine_server_call_err( req );
949 if (ret && reply->fd != -1) close( reply->fd );
956 /***********************************************************************
957 * TransactNamedPipe (KERNEL32.@)
959 BOOL WINAPI TransactNamedPipe(
960 HANDLE hPipe, LPVOID lpInput, DWORD dwInputSize, LPVOID lpOutput,
961 DWORD dwOutputSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
963 FIXME("%p %p %ld %p %ld %p %p\n",
964 hPipe, lpInput, dwInputSize, lpOutput,
965 dwOutputSize, lpBytesRead, lpOverlapped);
971 /***********************************************************************
972 * GetNamedPipeInfo (KERNEL32.@)
974 BOOL WINAPI GetNamedPipeInfo(
975 HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
976 LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
980 TRACE("%p %p %p %p %p\n", hNamedPipe, lpFlags,
981 lpOutputBufferSize, lpInputBufferSize, lpMaxInstances);
983 SERVER_START_REQ( get_named_pipe_info )
985 req->handle = hNamedPipe;
986 ret = !wine_server_call_err( req );
987 if(lpFlags) *lpFlags = reply->flags;
988 if(lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
989 if(lpInputBufferSize) *lpInputBufferSize = reply->outsize;
990 if(lpMaxInstances) *lpMaxInstances = reply->maxinstances;
997 /***********************************************************************
998 * GetNamedPipeHandleStateA (KERNEL32.@)
1000 BOOL WINAPI GetNamedPipeHandleStateA(
1001 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1002 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1003 LPSTR lpUsername, DWORD nUsernameMaxSize)
1005 FIXME("%p %p %p %p %p %p %ld\n",
1006 hNamedPipe, lpState, lpCurInstances,
1007 lpMaxCollectionCount, lpCollectDataTimeout,
1008 lpUsername, nUsernameMaxSize);
1013 /***********************************************************************
1014 * GetNamedPipeHandleStateW (KERNEL32.@)
1016 BOOL WINAPI GetNamedPipeHandleStateW(
1017 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1018 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1019 LPWSTR lpUsername, DWORD nUsernameMaxSize)
1021 FIXME("%p %p %p %p %p %p %ld\n",
1022 hNamedPipe, lpState, lpCurInstances,
1023 lpMaxCollectionCount, lpCollectDataTimeout,
1024 lpUsername, nUsernameMaxSize);
1029 /***********************************************************************
1030 * SetNamedPipeHandleState (KERNEL32.@)
1032 BOOL WINAPI SetNamedPipeHandleState(
1033 HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
1034 LPDWORD lpCollectDataTimeout)
1036 FIXME("%p %p %p %p\n",
1037 hNamedPipe, lpMode, lpMaxCollectionCount, lpCollectDataTimeout);
1041 /***********************************************************************
1042 * CallNamedPipeA (KERNEL32.@)
1044 BOOL WINAPI CallNamedPipeA(
1045 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
1046 LPVOID lpOutput, DWORD lpOutputSize,
1047 LPDWORD lpBytesRead, DWORD nTimeout)
1049 FIXME("%s %p %ld %p %ld %p %ld\n",
1050 debugstr_a(lpNamedPipeName), lpInput, lpInputSize,
1051 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
1055 /***********************************************************************
1056 * CallNamedPipeW (KERNEL32.@)
1058 BOOL WINAPI CallNamedPipeW(
1059 LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
1060 LPVOID lpOutput, DWORD lpOutputSize,
1061 LPDWORD lpBytesRead, DWORD nTimeout)
1063 FIXME("%s %p %ld %p %ld %p %ld\n",
1064 debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
1065 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
1069 /******************************************************************
1070 * CreatePipe (KERNEL32.@)
1073 BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
1074 LPSECURITY_ATTRIBUTES sa, DWORD size )
1076 static unsigned index = 0;
1079 unsigned in_index = index;
1081 *hReadPipe = *hWritePipe = INVALID_HANDLE_VALUE;
1082 /* generate a unique pipe name (system wide) */
1085 sprintf(name, "\\\\.\\pipe\\Win32.Pipes.%08lu.%08u", GetCurrentProcessId(), ++index);
1086 hr = CreateNamedPipeA(name, PIPE_ACCESS_INBOUND,
1087 PIPE_TYPE_BYTE | PIPE_WAIT, 1, size, size,
1088 NMPWAIT_USE_DEFAULT_WAIT, sa);
1089 } while (hr == INVALID_HANDLE_VALUE && index != in_index);
1090 /* from completion sakeness, I think system resources might be exhausted before this happens !! */
1091 if (hr == INVALID_HANDLE_VALUE) return FALSE;
1093 hw = CreateFileA(name, GENERIC_WRITE, 0, sa, OPEN_EXISTING, 0, 0);
1094 if (hw == INVALID_HANDLE_VALUE)