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 * InitializeCriticalSection (KERNEL32.@)
59 void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit )
61 NTSTATUS ret = RtlInitializeCriticalSection( crit );
62 if (ret) RtlRaiseStatus( ret );
65 /***********************************************************************
66 * InitializeCriticalSectionAndSpinCount (KERNEL32.@)
68 BOOL WINAPI InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION *crit, DWORD spincount )
70 NTSTATUS ret = RtlInitializeCriticalSectionAndSpinCount( crit, spincount );
71 if (ret) RtlRaiseStatus( ret );
75 /***********************************************************************
76 * SetCriticalSectionSpinCount (KERNEL32.@)
77 * This function is available on NT4SP3 or later, but not Win98
80 DWORD WINAPI SetCriticalSectionSpinCount( CRITICAL_SECTION *crit, DWORD spincount )
82 ULONG_PTR oldspincount = crit->SpinCount;
83 if(spincount) FIXME("critsection=%p: spincount=%ld not supported\n", crit, spincount);
84 crit->SpinCount = spincount;
88 /***********************************************************************
89 * MakeCriticalSectionGlobal (KERNEL32.@)
91 void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
93 /* let's assume that only one thread at a time will try to do this */
94 HANDLE sem = crit->LockSemaphore;
95 if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
96 crit->LockSemaphore = ConvertToGlobalHandle( sem );
99 RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
100 crit->DebugInfo = NULL;
105 /***********************************************************************
106 * ReinitializeCriticalSection (KERNEL32.@)
108 void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
110 if ( !crit->LockSemaphore )
111 RtlInitializeCriticalSection( crit );
115 /***********************************************************************
116 * UninitializeCriticalSection (KERNEL32.@)
118 void WINAPI UninitializeCriticalSection( CRITICAL_SECTION *crit )
120 RtlDeleteCriticalSection( crit );
124 /***********************************************************************
125 * CreateEventA (KERNEL32.@)
127 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
128 BOOL initial_state, LPCSTR name )
130 WCHAR buffer[MAX_PATH];
132 if (!name) return CreateEventW( sa, manual_reset, initial_state, NULL );
134 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
136 SetLastError( ERROR_FILENAME_EXCED_RANGE );
139 return CreateEventW( sa, manual_reset, initial_state, buffer );
143 /***********************************************************************
144 * CreateEventW (KERNEL32.@)
146 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
147 BOOL initial_state, LPCWSTR name )
150 DWORD len = name ? strlenW(name) : 0;
153 SetLastError( ERROR_FILENAME_EXCED_RANGE );
156 /* one buggy program needs this
157 * ("Van Dale Groot woordenboek der Nederlandse taal")
159 if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
161 ERR("Bad security attributes pointer %p\n",sa);
162 SetLastError( ERROR_INVALID_PARAMETER);
165 SERVER_START_REQ( create_event )
167 req->manual_reset = manual_reset;
168 req->initial_state = initial_state;
169 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
170 wine_server_add_data( req, name, len * sizeof(WCHAR) );
172 wine_server_call_err( req );
180 /***********************************************************************
181 * CreateW32Event (KERNEL.457)
183 HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
185 return CreateEventA( NULL, manual_reset, initial_state, NULL );
189 /***********************************************************************
190 * OpenEventA (KERNEL32.@)
192 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
194 WCHAR buffer[MAX_PATH];
196 if (!name) return OpenEventW( access, inherit, NULL );
198 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
200 SetLastError( ERROR_FILENAME_EXCED_RANGE );
203 return OpenEventW( access, inherit, buffer );
207 /***********************************************************************
208 * OpenEventW (KERNEL32.@)
210 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
213 DWORD len = name ? strlenW(name) : 0;
216 SetLastError( ERROR_FILENAME_EXCED_RANGE );
219 if (!is_version_nt()) access = EVENT_ALL_ACCESS;
221 SERVER_START_REQ( open_event )
223 req->access = access;
224 req->inherit = inherit;
225 wine_server_add_data( req, name, len * sizeof(WCHAR) );
226 wine_server_call_err( req );
234 /***********************************************************************
237 * Execute an event operation (set,reset,pulse).
239 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
242 SERVER_START_REQ( event_op )
244 req->handle = handle;
246 ret = !wine_server_call_err( req );
253 /***********************************************************************
254 * PulseEvent (KERNEL32.@)
256 BOOL WINAPI PulseEvent( HANDLE handle )
258 return EVENT_Operation( handle, PULSE_EVENT );
262 /***********************************************************************
263 * SetW32Event (KERNEL.458)
264 * SetEvent (KERNEL32.@)
266 BOOL WINAPI SetEvent( HANDLE handle )
268 return EVENT_Operation( handle, SET_EVENT );
272 /***********************************************************************
273 * ResetW32Event (KERNEL.459)
274 * ResetEvent (KERNEL32.@)
276 BOOL WINAPI ResetEvent( HANDLE handle )
278 return EVENT_Operation( handle, RESET_EVENT );
282 /***********************************************************************
283 * NOTE: The Win95 VWin32_Event routines given below are really low-level
284 * routines implemented directly by VWin32. The user-mode libraries
285 * implement Win32 synchronisation routines on top of these low-level
286 * primitives. We do it the other way around here :-)
289 /***********************************************************************
290 * VWin32_EventCreate (KERNEL.442)
292 HANDLE WINAPI VWin32_EventCreate(VOID)
294 HANDLE hEvent = CreateEventA( NULL, FALSE, 0, NULL );
295 return ConvertToGlobalHandle( hEvent );
298 /***********************************************************************
299 * VWin32_EventDestroy (KERNEL.443)
301 VOID WINAPI VWin32_EventDestroy(HANDLE event)
303 CloseHandle( event );
306 /***********************************************************************
307 * VWin32_EventWait (KERNEL.450)
309 VOID WINAPI VWin32_EventWait(HANDLE event)
313 ReleaseThunkLock( &mutex_count );
314 WaitForSingleObject( event, INFINITE );
315 RestoreThunkLock( mutex_count );
318 /***********************************************************************
319 * VWin32_EventSet (KERNEL.451)
320 * KERNEL_479 (KERNEL.479)
322 VOID WINAPI VWin32_EventSet(HANDLE event)
329 /***********************************************************************
330 * CreateMutexA (KERNEL32.@)
332 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
334 WCHAR buffer[MAX_PATH];
336 if (!name) return CreateMutexW( sa, owner, NULL );
338 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
340 SetLastError( ERROR_FILENAME_EXCED_RANGE );
343 return CreateMutexW( sa, owner, buffer );
347 /***********************************************************************
348 * CreateMutexW (KERNEL32.@)
350 HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
353 DWORD len = name ? strlenW(name) : 0;
356 SetLastError( ERROR_FILENAME_EXCED_RANGE );
359 SERVER_START_REQ( create_mutex )
362 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
363 wine_server_add_data( req, name, len * sizeof(WCHAR) );
365 wine_server_call_err( req );
373 /***********************************************************************
374 * OpenMutexA (KERNEL32.@)
376 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
378 WCHAR buffer[MAX_PATH];
380 if (!name) return OpenMutexW( access, inherit, NULL );
382 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
384 SetLastError( ERROR_FILENAME_EXCED_RANGE );
387 return OpenMutexW( access, inherit, buffer );
391 /***********************************************************************
392 * OpenMutexW (KERNEL32.@)
394 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
397 DWORD len = name ? strlenW(name) : 0;
400 SetLastError( ERROR_FILENAME_EXCED_RANGE );
403 if (!is_version_nt()) access = MUTEX_ALL_ACCESS;
405 SERVER_START_REQ( open_mutex )
407 req->access = access;
408 req->inherit = inherit;
409 wine_server_add_data( req, name, len * sizeof(WCHAR) );
410 wine_server_call_err( req );
418 /***********************************************************************
419 * ReleaseMutex (KERNEL32.@)
421 BOOL WINAPI ReleaseMutex( HANDLE handle )
424 SERVER_START_REQ( release_mutex )
426 req->handle = handle;
427 ret = !wine_server_call_err( req );
439 /***********************************************************************
440 * CreateSemaphoreA (KERNEL32.@)
442 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
444 WCHAR buffer[MAX_PATH];
446 if (!name) return CreateSemaphoreW( sa, initial, max, NULL );
448 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
450 SetLastError( ERROR_FILENAME_EXCED_RANGE );
453 return CreateSemaphoreW( sa, initial, max, buffer );
457 /***********************************************************************
458 * CreateSemaphoreW (KERNEL32.@)
460 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
461 LONG max, LPCWSTR name )
464 DWORD len = name ? strlenW(name) : 0;
466 /* Check parameters */
468 if ((max <= 0) || (initial < 0) || (initial > max))
470 SetLastError( ERROR_INVALID_PARAMETER );
475 SetLastError( ERROR_FILENAME_EXCED_RANGE );
479 SERVER_START_REQ( create_semaphore )
481 req->initial = (unsigned int)initial;
482 req->max = (unsigned int)max;
483 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
484 wine_server_add_data( req, name, len * sizeof(WCHAR) );
486 wine_server_call_err( req );
494 /***********************************************************************
495 * OpenSemaphoreA (KERNEL32.@)
497 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
499 WCHAR buffer[MAX_PATH];
501 if (!name) return OpenSemaphoreW( access, inherit, NULL );
503 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
505 SetLastError( ERROR_FILENAME_EXCED_RANGE );
508 return OpenSemaphoreW( access, inherit, buffer );
512 /***********************************************************************
513 * OpenSemaphoreW (KERNEL32.@)
515 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
518 DWORD len = name ? strlenW(name) : 0;
521 SetLastError( ERROR_FILENAME_EXCED_RANGE );
524 if (!is_version_nt()) access = SEMAPHORE_ALL_ACCESS;
526 SERVER_START_REQ( open_semaphore )
528 req->access = access;
529 req->inherit = inherit;
530 wine_server_add_data( req, name, len * sizeof(WCHAR) );
531 wine_server_call_err( req );
539 /***********************************************************************
540 * ReleaseSemaphore (KERNEL32.@)
542 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
544 NTSTATUS status = NtReleaseSemaphore( handle, count, previous );
545 if (status) SetLastError( RtlNtStatusToDosError(status) );
555 /***********************************************************************
556 * CreateWaitableTimerA (KERNEL32.@)
558 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
560 WCHAR buffer[MAX_PATH];
562 if (!name) return CreateWaitableTimerW( sa, manual, NULL );
564 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
566 SetLastError( ERROR_FILENAME_EXCED_RANGE );
569 return CreateWaitableTimerW( sa, manual, buffer );
573 /***********************************************************************
574 * CreateWaitableTimerW (KERNEL32.@)
576 HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
582 OBJECT_ATTRIBUTES oa;
584 if (name) RtlInitUnicodeString(&us, name);
585 if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle)
587 InitializeObjectAttributes(&oa, name ? &us : NULL, attr,
588 NULL /* FIXME */, NULL /* FIXME */);
589 status = NtCreateTimer(&handle, TIMER_ALL_ACCESS, &oa,
590 manual ? NotificationTimer : SynchronizationTimer);
592 if (status != STATUS_SUCCESS)
594 SetLastError( RtlNtStatusToDosError(status) );
601 /***********************************************************************
602 * OpenWaitableTimerA (KERNEL32.@)
604 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
606 WCHAR buffer[MAX_PATH];
608 if (!name) return OpenWaitableTimerW( access, inherit, NULL );
610 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
612 SetLastError( ERROR_FILENAME_EXCED_RANGE );
615 return OpenWaitableTimerW( access, inherit, buffer );
619 /***********************************************************************
620 * OpenWaitableTimerW (KERNEL32.@)
622 HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
628 OBJECT_ATTRIBUTES oa;
630 if (inherit) attr |= OBJ_INHERIT;
632 if (name) RtlInitUnicodeString(&us, name);
633 InitializeObjectAttributes(&oa, name ? &us : NULL, attr, NULL /* FIXME */, NULL /* FIXME */);
634 status = NtOpenTimer(&handle, access, &oa);
635 if (status != STATUS_SUCCESS)
637 SetLastError( RtlNtStatusToDosError(status) );
644 /***********************************************************************
645 * SetWaitableTimer (KERNEL32.@)
647 BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
648 PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
650 NTSTATUS status = NtSetTimer(handle, when, callback, arg, resume, period, NULL);
652 if (status != STATUS_SUCCESS)
654 SetLastError( RtlNtStatusToDosError(status) );
655 if (status != STATUS_TIMER_RESUME_IGNORED) return FALSE;
661 /***********************************************************************
662 * CancelWaitableTimer (KERNEL32.@)
664 BOOL WINAPI CancelWaitableTimer( HANDLE handle )
668 status = NtCancelTimer(handle, NULL);
669 if (status != STATUS_SUCCESS)
671 SetLastError( RtlNtStatusToDosError(status) );
678 /***********************************************************************
679 * CreateTimerQueue (KERNEL32.@)
681 HANDLE WINAPI CreateTimerQueue(void)
684 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
689 /***********************************************************************
690 * DeleteTimerQueueEx (KERNEL32.@)
692 BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
694 FIXME("(%p, %p): stub\n", TimerQueue, CompletionEvent);
695 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
699 /***********************************************************************
700 * CreateTimerQueueTimer (KERNEL32.@)
702 * Creates a timer-queue timer. This timer expires at the specified due
703 * time (in ms), then after every specified period (in ms). When the timer
704 * expires, the callback function is called.
707 * nonzero on success or zero on faillure
712 BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue,
713 WAITORTIMERCALLBACK Callback, PVOID Parameter,
714 DWORD DueTime, DWORD Period, ULONG Flags )
717 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
721 /***********************************************************************
722 * DeleteTimerQueueTimer (KERNEL32.@)
724 * Cancels a timer-queue timer.
727 * nonzero on success or zero on faillure
732 BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer,
733 HANDLE CompletionEvent )
736 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
746 /***********************************************************************
747 * CreateNamedPipeA (KERNEL32.@)
749 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
750 DWORD dwPipeMode, DWORD nMaxInstances,
751 DWORD nOutBufferSize, DWORD nInBufferSize,
752 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
754 WCHAR buffer[MAX_PATH];
756 if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances,
757 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
759 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
761 SetLastError( ERROR_FILENAME_EXCED_RANGE );
762 return INVALID_HANDLE_VALUE;
764 return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances,
765 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
769 /***********************************************************************
770 * CreateNamedPipeW (KERNEL32.@)
772 HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
773 DWORD dwPipeMode, DWORD nMaxInstances,
774 DWORD nOutBufferSize, DWORD nInBufferSize,
775 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
779 static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'};
781 TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
782 debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
783 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
787 SetLastError( ERROR_PATH_NOT_FOUND );
788 return INVALID_HANDLE_VALUE;
793 SetLastError( ERROR_FILENAME_EXCED_RANGE );
794 return INVALID_HANDLE_VALUE;
796 if (strncmpiW(name, leadin, sizeof(leadin)/sizeof(leadin[0])))
798 SetLastError( ERROR_INVALID_NAME );
799 return INVALID_HANDLE_VALUE;
801 SERVER_START_REQ( create_named_pipe )
803 req->openmode = dwOpenMode;
804 req->pipemode = dwPipeMode;
805 req->maxinstances = nMaxInstances;
806 req->outsize = nOutBufferSize;
807 req->insize = nInBufferSize;
808 req->timeout = nDefaultTimeOut;
809 wine_server_add_data( req, name, len * sizeof(WCHAR) );
811 if (!wine_server_call_err( req )) ret = reply->handle;
812 else ret = INVALID_HANDLE_VALUE;
819 /***********************************************************************
820 * PeekNamedPipe (KERNEL32.@)
822 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
823 LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
828 fd = FILE_GetUnixHandle(hPipe, GENERIC_READ);
829 if (fd == -1) return FALSE;
831 if (ioctl(fd,FIONREAD, &avail ) != 0)
833 TRACE("FIONREAD failed reason: %s\n",strerror(errno));
837 if (!avail) /* check for closed pipe */
839 struct pollfd pollfd;
841 pollfd.events = POLLIN;
843 switch (poll( &pollfd, 1, 0 ))
847 case 1: /* got something */
848 if (!(pollfd.revents & (POLLHUP | POLLERR))) break;
849 TRACE("POLLHUP | POLLERR\n");
853 SetLastError(ERROR_BROKEN_PIPE);
858 TRACE(" 0x%08x bytes available\n", avail );
859 if (!lpvBuffer && lpcbAvail)
864 #endif /* defined(FIONREAD) */
866 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
867 FIXME("function not implemented\n");
871 /***********************************************************************
872 * SYNC_CompletePipeOverlapped (Internal)
874 static void SYNC_CompletePipeOverlapped (LPOVERLAPPED overlapped, DWORD result)
876 TRACE("for %p result %08lx\n",overlapped,result);
879 overlapped->Internal = result;
880 SetEvent(overlapped->hEvent);
884 /***********************************************************************
885 * WaitNamedPipeA (KERNEL32.@)
887 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
889 WCHAR buffer[MAX_PATH];
891 if (!name) return WaitNamedPipeW( NULL, nTimeOut );
893 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
895 SetLastError( ERROR_FILENAME_EXCED_RANGE );
898 return WaitNamedPipeW( buffer, nTimeOut );
902 /***********************************************************************
903 * WaitNamedPipeW (KERNEL32.@)
905 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
907 DWORD len = name ? strlenW(name) : 0;
913 SetLastError( ERROR_FILENAME_EXCED_RANGE );
917 TRACE("%s 0x%08lx\n",debugstr_w(name),nTimeOut);
919 memset(&ov,0,sizeof(ov));
920 ov.hEvent = CreateEventA( NULL, 0, 0, NULL );
924 SERVER_START_REQ( wait_named_pipe )
926 req->timeout = nTimeOut;
927 req->overlapped = &ov;
928 req->func = SYNC_CompletePipeOverlapped;
929 wine_server_add_data( req, name, len * sizeof(WCHAR) );
930 ret = !wine_server_call_err( req );
936 if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
938 SetLastError(ov.Internal);
939 ret = (ov.Internal==STATUS_SUCCESS);
942 CloseHandle(ov.hEvent);
947 /***********************************************************************
948 * SYNC_ConnectNamedPipe (Internal)
950 static BOOL SYNC_ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
957 overlapped->Internal = STATUS_PENDING;
959 SERVER_START_REQ( connect_named_pipe )
962 req->overlapped = overlapped;
963 req->func = SYNC_CompletePipeOverlapped;
964 ret = !wine_server_call_err( req );
971 /***********************************************************************
972 * ConnectNamedPipe (KERNEL32.@)
974 BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
979 TRACE("(%p,%p)\n",hPipe, overlapped);
983 if(SYNC_ConnectNamedPipe(hPipe,overlapped))
984 SetLastError( ERROR_IO_PENDING );
988 memset(&ov,0,sizeof(ov));
989 ov.hEvent = CreateEventA(NULL,0,0,NULL);
993 ret=SYNC_ConnectNamedPipe(hPipe, &ov);
996 if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE))
998 SetLastError(ov.Internal);
999 ret = (ov.Internal==STATUS_SUCCESS);
1003 CloseHandle(ov.hEvent);
1008 /***********************************************************************
1009 * DisconnectNamedPipe (KERNEL32.@)
1011 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
1015 TRACE("(%p)\n",hPipe);
1017 SERVER_START_REQ( disconnect_named_pipe )
1019 req->handle = hPipe;
1020 ret = !wine_server_call_err( req );
1021 if (ret && reply->fd != -1) close( reply->fd );
1028 /***********************************************************************
1029 * TransactNamedPipe (KERNEL32.@)
1031 BOOL WINAPI TransactNamedPipe(
1032 HANDLE hPipe, LPVOID lpInput, DWORD dwInputSize, LPVOID lpOutput,
1033 DWORD dwOutputSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
1035 FIXME("%p %p %ld %p %ld %p %p\n",
1036 hPipe, lpInput, dwInputSize, lpOutput,
1037 dwOutputSize, lpBytesRead, lpOverlapped);
1043 /***********************************************************************
1044 * GetNamedPipeInfo (KERNEL32.@)
1046 BOOL WINAPI GetNamedPipeInfo(
1047 HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
1048 LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
1052 TRACE("%p %p %p %p %p\n", hNamedPipe, lpFlags,
1053 lpOutputBufferSize, lpInputBufferSize, lpMaxInstances);
1055 SERVER_START_REQ( get_named_pipe_info )
1057 req->handle = hNamedPipe;
1058 ret = !wine_server_call_err( req );
1059 if(lpFlags) *lpFlags = reply->flags;
1060 if(lpOutputBufferSize) *lpOutputBufferSize = reply->outsize;
1061 if(lpInputBufferSize) *lpInputBufferSize = reply->outsize;
1062 if(lpMaxInstances) *lpMaxInstances = reply->maxinstances;
1069 /***********************************************************************
1070 * GetNamedPipeHandleStateA (KERNEL32.@)
1072 BOOL WINAPI GetNamedPipeHandleStateA(
1073 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1074 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1075 LPSTR lpUsername, DWORD nUsernameMaxSize)
1077 FIXME("%p %p %p %p %p %p %ld\n",
1078 hNamedPipe, lpState, lpCurInstances,
1079 lpMaxCollectionCount, lpCollectDataTimeout,
1080 lpUsername, nUsernameMaxSize);
1085 /***********************************************************************
1086 * GetNamedPipeHandleStateW (KERNEL32.@)
1088 BOOL WINAPI GetNamedPipeHandleStateW(
1089 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1090 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1091 LPWSTR lpUsername, DWORD nUsernameMaxSize)
1093 FIXME("%p %p %p %p %p %p %ld\n",
1094 hNamedPipe, lpState, lpCurInstances,
1095 lpMaxCollectionCount, lpCollectDataTimeout,
1096 lpUsername, nUsernameMaxSize);
1101 /***********************************************************************
1102 * SetNamedPipeHandleState (KERNEL32.@)
1104 BOOL WINAPI SetNamedPipeHandleState(
1105 HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
1106 LPDWORD lpCollectDataTimeout)
1108 FIXME("%p %p %p %p\n",
1109 hNamedPipe, lpMode, lpMaxCollectionCount, lpCollectDataTimeout);
1113 /***********************************************************************
1114 * CallNamedPipeA (KERNEL32.@)
1116 BOOL WINAPI CallNamedPipeA(
1117 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
1118 LPVOID lpOutput, DWORD lpOutputSize,
1119 LPDWORD lpBytesRead, DWORD nTimeout)
1121 FIXME("%s %p %ld %p %ld %p %ld\n",
1122 debugstr_a(lpNamedPipeName), lpInput, lpInputSize,
1123 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
1127 /***********************************************************************
1128 * CallNamedPipeW (KERNEL32.@)
1130 BOOL WINAPI CallNamedPipeW(
1131 LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
1132 LPVOID lpOutput, DWORD lpOutputSize,
1133 LPDWORD lpBytesRead, DWORD nTimeout)
1135 FIXME("%s %p %ld %p %ld %p %ld\n",
1136 debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
1137 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
1141 /******************************************************************
1142 * CreatePipe (KERNEL32.@)
1145 BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
1146 LPSECURITY_ATTRIBUTES sa, DWORD size )
1148 static unsigned index = 0;
1151 unsigned in_index = index;
1153 *hReadPipe = *hWritePipe = INVALID_HANDLE_VALUE;
1154 /* generate a unique pipe name (system wide) */
1157 sprintf(name, "\\\\.\\pipe\\Win32.Pipes.%08lu.%08u", GetCurrentProcessId(), ++index);
1158 hr = CreateNamedPipeA(name, PIPE_ACCESS_INBOUND,
1159 PIPE_TYPE_BYTE | PIPE_WAIT, 1, size, size,
1160 NMPWAIT_USE_DEFAULT_WAIT, sa);
1161 } while (hr == INVALID_HANDLE_VALUE && index != in_index);
1162 /* from completion sakeness, I think system resources might be exhausted before this happens !! */
1163 if (hr == INVALID_HANDLE_VALUE) return FALSE;
1165 hw = CreateFileA(name, GENERIC_WRITE, 0, sa, OPEN_EXISTING, 0, 0);
1166 if (hw == INVALID_HANDLE_VALUE)
1180 /***********************************************************************
1181 * InterlockedCompareExchange (KERNEL32.@)
1183 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
1184 __ASM_GLOBAL_FUNC(InterlockedCompareExchange,
1185 "movl 12(%esp),%eax\n\t"
1186 "movl 8(%esp),%ecx\n\t"
1187 "movl 4(%esp),%edx\n\t"
1188 "lock; cmpxchgl %ecx,(%edx)\n\t"
1191 /***********************************************************************
1192 * InterlockedExchange (KERNEL32.@)
1194 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
1195 __ASM_GLOBAL_FUNC(InterlockedExchange,
1196 "movl 8(%esp),%eax\n\t"
1197 "movl 4(%esp),%edx\n\t"
1198 "lock; xchgl %eax,(%edx)\n\t"
1201 /***********************************************************************
1202 * InterlockedExchangeAdd (KERNEL32.@)
1204 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
1205 __ASM_GLOBAL_FUNC(InterlockedExchangeAdd,
1206 "movl 8(%esp),%eax\n\t"
1207 "movl 4(%esp),%edx\n\t"
1208 "lock; xaddl %eax,(%edx)\n\t"
1211 /***********************************************************************
1212 * InterlockedIncrement (KERNEL32.@)
1214 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
1215 __ASM_GLOBAL_FUNC(InterlockedIncrement,
1216 "movl 4(%esp),%edx\n\t"
1218 "lock; xaddl %eax,(%edx)\n\t"
1222 /***********************************************************************
1223 * InterlockedDecrement (KERNEL32.@)
1225 __ASM_GLOBAL_FUNC(InterlockedDecrement,
1226 "movl 4(%esp),%edx\n\t"
1228 "lock; xaddl %eax,(%edx)\n\t"
1232 #else /* __i386__ */
1234 /***********************************************************************
1235 * InterlockedCompareExchange (KERNEL32.@)
1237 LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare )
1239 return interlocked_cmpxchg( dest, xchg, compare );
1242 /***********************************************************************
1243 * InterlockedExchange (KERNEL32.@)
1245 LONG WINAPI InterlockedExchange( PLONG dest, LONG val )
1247 return interlocked_xchg( dest, val );
1250 /***********************************************************************
1251 * InterlockedExchangeAdd (KERNEL32.@)
1253 LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr )
1255 return interlocked_xchg_add( dest, incr );
1258 /***********************************************************************
1259 * InterlockedIncrement (KERNEL32.@)
1261 LONG WINAPI InterlockedIncrement( PLONG dest )
1263 return interlocked_xchg_add( dest, 1 ) + 1;
1266 /***********************************************************************
1267 * InterlockedDecrement (KERNEL32.@)
1269 LONG WINAPI InterlockedDecrement( PLONG dest )
1271 return interlocked_xchg_add( dest, -1 ) - 1;
1274 #endif /* __i386__ */