2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
15 #include "wine/server.h"
16 #include "wine/unicode.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(win32);
27 /***********************************************************************
28 * CreateEventA (KERNEL32.@)
30 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
31 BOOL initial_state, LPCSTR name )
34 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
37 SetLastError( ERROR_FILENAME_EXCED_RANGE );
40 SERVER_START_VAR_REQ( create_event, len * sizeof(WCHAR) )
42 req->manual_reset = manual_reset;
43 req->initial_state = initial_state;
44 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
45 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
55 /***********************************************************************
56 * CreateEventW (KERNEL32.@)
58 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
59 BOOL initial_state, LPCWSTR name )
62 DWORD len = name ? strlenW(name) : 0;
65 SetLastError( ERROR_FILENAME_EXCED_RANGE );
68 /* one buggy program needs this
69 * ("Van Dale Groot woordenboek der Nederlandse taal")
71 if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
73 ERR("Bad security attributes pointer %p\n",sa);
74 SetLastError( ERROR_INVALID_PARAMETER);
77 SERVER_START_VAR_REQ( create_event, len * sizeof(WCHAR) )
79 req->manual_reset = manual_reset;
80 req->initial_state = initial_state;
81 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
82 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
92 /***********************************************************************
93 * CreateW32Event (KERNEL.457)
95 HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
97 return CreateEventA( NULL, manual_reset, initial_state, NULL );
101 /***********************************************************************
102 * OpenEventA (KERNEL32.@)
104 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
107 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
110 SetLastError( ERROR_FILENAME_EXCED_RANGE );
113 SERVER_START_VAR_REQ( open_event, len * sizeof(WCHAR) )
115 req->access = access;
116 req->inherit = inherit;
117 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
126 /***********************************************************************
127 * OpenEventW (KERNEL32.@)
129 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
132 DWORD len = name ? strlenW(name) : 0;
135 SetLastError( ERROR_FILENAME_EXCED_RANGE );
138 SERVER_START_VAR_REQ( open_event, len * sizeof(WCHAR) )
140 req->access = access;
141 req->inherit = inherit;
142 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
151 /***********************************************************************
154 * Execute an event operation (set,reset,pulse).
156 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
159 SERVER_START_REQ( event_op )
161 req->handle = handle;
163 ret = !SERVER_CALL_ERR();
170 /***********************************************************************
171 * PulseEvent (KERNEL32.@)
173 BOOL WINAPI PulseEvent( HANDLE handle )
175 return EVENT_Operation( handle, PULSE_EVENT );
179 /***********************************************************************
180 * SetW32Event (KERNEL.458)
181 * SetEvent (KERNEL32.@)
183 BOOL WINAPI SetEvent( HANDLE handle )
185 return EVENT_Operation( handle, SET_EVENT );
189 /***********************************************************************
190 * ResetW32Event (KERNEL.459)
191 * ResetEvent (KERNEL32.@)
193 BOOL WINAPI ResetEvent( HANDLE handle )
195 return EVENT_Operation( handle, RESET_EVENT );
199 /***********************************************************************
200 * NOTE: The Win95 VWin32_Event routines given below are really low-level
201 * routines implemented directly by VWin32. The user-mode libraries
202 * implement Win32 synchronisation routines on top of these low-level
203 * primitives. We do it the other way around here :-)
206 /***********************************************************************
207 * VWin32_EventCreate (KERNEL.442)
209 HANDLE WINAPI VWin32_EventCreate(VOID)
211 HANDLE hEvent = CreateEventA( NULL, FALSE, 0, NULL );
212 return ConvertToGlobalHandle( hEvent );
215 /***********************************************************************
216 * VWin32_EventDestroy (KERNEL.443)
218 VOID WINAPI VWin32_EventDestroy(HANDLE event)
220 CloseHandle( event );
223 /***********************************************************************
224 * VWin32_EventWait (KERNEL.450)
226 VOID WINAPI VWin32_EventWait(HANDLE event)
230 ReleaseThunkLock( &mutex_count );
231 WaitForSingleObject( event, INFINITE );
232 RestoreThunkLock( mutex_count );
235 /***********************************************************************
236 * VWin32_EventSet (KERNEL.451)
237 * KERNEL_479 (KERNEL.479)
239 VOID WINAPI VWin32_EventSet(HANDLE event)
246 /***********************************************************************
247 * CreateMutexA (KERNEL32.@)
249 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
252 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
255 SetLastError( ERROR_FILENAME_EXCED_RANGE );
258 SERVER_START_VAR_REQ( create_mutex, len * sizeof(WCHAR) )
261 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
262 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
272 /***********************************************************************
273 * CreateMutexW (KERNEL32.@)
275 HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
278 DWORD len = name ? strlenW(name) : 0;
281 SetLastError( ERROR_FILENAME_EXCED_RANGE );
284 SERVER_START_VAR_REQ( create_mutex, len * sizeof(WCHAR) )
287 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
288 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
303 /***********************************************************************
304 * OpenMutexA (KERNEL32.@)
306 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
309 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
312 SetLastError( ERROR_FILENAME_EXCED_RANGE );
315 SERVER_START_VAR_REQ( open_mutex, len * sizeof(WCHAR) )
317 req->access = access;
318 req->inherit = inherit;
319 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
328 /***********************************************************************
329 * OpenMutexW (KERNEL32.@)
331 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
334 DWORD len = name ? strlenW(name) : 0;
337 SetLastError( ERROR_FILENAME_EXCED_RANGE );
340 SERVER_START_VAR_REQ( open_mutex, len * sizeof(WCHAR) )
342 req->access = access;
343 req->inherit = inherit;
344 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
353 /***********************************************************************
354 * ReleaseMutex (KERNEL32.@)
356 BOOL WINAPI ReleaseMutex( HANDLE handle )
359 SERVER_START_REQ( release_mutex )
361 req->handle = handle;
362 ret = !SERVER_CALL_ERR();
374 /***********************************************************************
375 * CreateSemaphoreA (KERNEL32.@)
377 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
380 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
382 /* Check parameters */
384 if ((max <= 0) || (initial < 0) || (initial > max))
386 SetLastError( ERROR_INVALID_PARAMETER );
391 SetLastError( ERROR_FILENAME_EXCED_RANGE );
395 SERVER_START_VAR_REQ( create_semaphore, len * sizeof(WCHAR) )
397 req->initial = (unsigned int)initial;
398 req->max = (unsigned int)max;
399 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
400 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
410 /***********************************************************************
411 * CreateSemaphoreW (KERNEL32.@)
413 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
414 LONG max, LPCWSTR name )
417 DWORD len = name ? strlenW(name) : 0;
419 /* Check parameters */
421 if ((max <= 0) || (initial < 0) || (initial > max))
423 SetLastError( ERROR_INVALID_PARAMETER );
428 SetLastError( ERROR_FILENAME_EXCED_RANGE );
432 SERVER_START_VAR_REQ( create_semaphore, len * sizeof(WCHAR) )
434 req->initial = (unsigned int)initial;
435 req->max = (unsigned int)max;
436 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
437 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
447 /***********************************************************************
448 * OpenSemaphoreA (KERNEL32.@)
450 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
453 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
456 SetLastError( ERROR_FILENAME_EXCED_RANGE );
459 SERVER_START_VAR_REQ( open_semaphore, len * sizeof(WCHAR) )
461 req->access = access;
462 req->inherit = inherit;
463 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
472 /***********************************************************************
473 * OpenSemaphoreW (KERNEL32.@)
475 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
478 DWORD len = name ? strlenW(name) : 0;
481 SetLastError( ERROR_FILENAME_EXCED_RANGE );
484 SERVER_START_VAR_REQ( open_semaphore, len * sizeof(WCHAR) )
486 req->access = access;
487 req->inherit = inherit;
488 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
497 /***********************************************************************
498 * ReleaseSemaphore (KERNEL32.@)
500 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
502 NTSTATUS status = NtReleaseSemaphore( handle, count, previous );
503 if (status) SetLastError( RtlNtStatusToDosError(status) );
513 /***********************************************************************
514 * CreateNamedPipeA (KERNEL32.@)
516 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
517 DWORD dwPipeMode, DWORD nMaxInstances,
518 DWORD nOutBufferSize, DWORD nInBufferSize,
519 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
522 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
524 TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p): stub\n",
525 debugstr_a(name), dwOpenMode, dwPipeMode, nMaxInstances,
526 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
530 SetLastError( ERROR_FILENAME_EXCED_RANGE );
533 SERVER_START_VAR_REQ( create_named_pipe, len * sizeof(WCHAR) )
535 req->openmode = dwOpenMode;
536 req->pipemode = dwPipeMode;
537 req->maxinstances = nMaxInstances;
538 req->outsize = nOutBufferSize;
539 req->insize = nInBufferSize;
540 req->timeout = nDefaultTimeOut;
542 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
548 TRACE("Returned %d\n",ret);
553 /***********************************************************************
554 * CreateNamedPipeW (KERNEL32.@)
556 HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
557 DWORD dwPipeMode, DWORD nMaxInstances,
558 DWORD nOutBufferSize, DWORD nInBufferSize,
559 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
562 DWORD len = name ? strlenW(name) : 0;
564 TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
565 debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
566 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
570 SetLastError( ERROR_FILENAME_EXCED_RANGE );
573 SERVER_START_VAR_REQ( create_named_pipe, len * sizeof(WCHAR) )
575 req->openmode = dwOpenMode;
576 req->pipemode = dwPipeMode;
577 req->maxinstances = nMaxInstances;
578 req->outsize = nOutBufferSize;
579 req->insize = nInBufferSize;
580 req->timeout = nDefaultTimeOut;
582 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
592 /***********************************************************************
593 * PeekNamedPipe (KERNEL32.@)
595 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
596 LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
598 FIXME("(%08x, %p, %08lx, %p, %p, %p): stub\n",
599 hPipe, lpvBuffer, cbBuffer, lpcbRead, lpcbAvail, lpcbMessage);
600 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
605 /***********************************************************************
606 * WaitNamedPipeA (KERNEL32.@)
608 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
610 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
614 TRACE("%s 0x%08lx\n",debugstr_a(name),nTimeOut);
618 SetLastError( ERROR_FILENAME_EXCED_RANGE );
622 if (!(event = CreateEventA( NULL, 0, 0, NULL ))) return FALSE;
624 SERVER_START_VAR_REQ( wait_named_pipe, len * sizeof(WCHAR) )
626 req->timeout = nTimeOut;
628 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
629 ret = !SERVER_CALL_ERR();
633 if (ret) WaitForSingleObject(event,INFINITE);
640 /***********************************************************************
641 * WaitNamedPipeW (KERNEL32.@)
643 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
645 DWORD len = name ? strlenW(name) : 0;
649 TRACE("%s 0x%08lx\n",debugstr_w(name),nTimeOut);
653 SetLastError( ERROR_FILENAME_EXCED_RANGE );
657 if (!(event = CreateEventA( NULL, 0, 0, NULL ))) return FALSE;
659 SERVER_START_VAR_REQ( wait_named_pipe, len * sizeof(WCHAR) )
661 req->timeout = nTimeOut;
663 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
664 ret = !SERVER_CALL_ERR();
668 if (ret) WaitForSingleObject(event,INFINITE);
675 /***********************************************************************
676 * ConnectNamedPipe (KERNEL32.@)
678 BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
683 TRACE("(%d,%p)\n",hPipe, overlapped);
687 FIXME("overlapped operation not supported\n");
688 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
692 if (!(event = CreateEventA(NULL,0,0,NULL))) return FALSE;
694 SERVER_START_REQ( connect_named_pipe )
698 ret = !SERVER_CALL_ERR();
702 if (ret) WaitForSingleObject(event,INFINITE);
708 /***********************************************************************
709 * DisconnectNamedPipe (KERNEL32.@)
711 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
715 TRACE("(%d)\n",hPipe);
717 SERVER_START_REQ( disconnect_named_pipe )
720 ret = !SERVER_CALL_ERR();
727 /***********************************************************************
728 * TransactNamedPipe (KERNEL32.@)
730 BOOL WINAPI TransactNamedPipe(
731 HANDLE hPipe, LPVOID lpInput, DWORD dwInputSize, LPVOID lpOutput,
732 DWORD dwOutputSize, LPDWORD lpBytesRead, LPOVERLAPPED lpOverlapped)
734 FIXME("%d %p %ld %p %ld %p %p\n",
735 hPipe, lpInput, dwInputSize, lpOutput,
736 dwOutputSize, lpBytesRead, lpOverlapped);
742 /***********************************************************************
743 * GetNamedPipeInfo (KERNEL32.@)
745 BOOL WINAPI GetNamedPipeInfo(
746 HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
747 LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
751 TRACE("%d %p %p %p %p\n", hNamedPipe, lpFlags,
752 lpOutputBufferSize, lpInputBufferSize, lpMaxInstances);
754 SERVER_START_REQ( get_named_pipe_info )
756 req->handle = hNamedPipe;
757 ret = !SERVER_CALL_ERR();
759 *lpFlags = req->flags;
760 if(lpOutputBufferSize)
761 *lpOutputBufferSize = req->outsize;
762 if(lpInputBufferSize)
763 *lpInputBufferSize = req->outsize;
765 *lpMaxInstances = req->maxinstances;
772 /***********************************************************************
773 * GetNamedPipeHandleStateA (KERNEL32.@)
775 BOOL WINAPI GetNamedPipeHandleStateA(
776 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
777 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
778 LPSTR lpUsername, DWORD nUsernameMaxSize)
780 FIXME("%d %p %p %p %p %p %ld\n",
781 hNamedPipe, lpState, lpCurInstances,
782 lpMaxCollectionCount, lpCollectDataTimeout,
783 lpUsername, nUsernameMaxSize);
788 /***********************************************************************
789 * GetNamedPipeHandleStateW (KERNEL32.@)
791 BOOL WINAPI GetNamedPipeHandleStateW(
792 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
793 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
794 LPWSTR lpUsername, DWORD nUsernameMaxSize)
796 FIXME("%d %p %p %p %p %p %ld\n",
797 hNamedPipe, lpState, lpCurInstances,
798 lpMaxCollectionCount, lpCollectDataTimeout,
799 lpUsername, nUsernameMaxSize);
804 /***********************************************************************
805 * SetNamedPipeHandleState (KERNEL32.@)
807 BOOL WINAPI SetNamedPipeHandleState(
808 HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
809 LPDWORD lpCollectDataTimeout)
811 FIXME("%d %p %p %p\n",
812 hNamedPipe, lpMode, lpMaxCollectionCount, lpCollectDataTimeout);
816 /***********************************************************************
817 * CallNamedPipeA (KERNEL32.@)
819 BOOL WINAPI CallNamedPipeA(
820 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
821 LPVOID lpOutput, DWORD lpOutputSize,
822 LPDWORD lpBytesRead, DWORD nTimeout)
824 FIXME("%s %p %ld %p %ld %p %ld\n",
825 debugstr_a(lpNamedPipeName), lpInput, lpInputSize,
826 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
830 /***********************************************************************
831 * CallNamedPipeW (KERNEL32.@)
833 BOOL WINAPI CallNamedPipeW(
834 LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
835 LPVOID lpOutput, DWORD lpOutputSize,
836 LPDWORD lpBytesRead, DWORD nTimeout)
838 FIXME("%s %p %ld %p %ld %p %ld\n",
839 debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
840 lpOutput, lpOutputSize, lpBytesRead, nTimeout);