2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
10 #include "wine/unicode.h"
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(win32
);
21 /***********************************************************************
22 * CreateEventA (KERNEL32.156)
24 HANDLE WINAPI
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
25 BOOL initial_state
, LPCSTR name
)
28 DWORD len
= name
? MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), NULL
, 0 ) : 0;
31 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
36 struct create_event_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
38 req
->manual_reset
= manual_reset
;
39 req
->initial_state
= initial_state
;
40 req
->inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
41 if (len
) MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), server_data_ptr(req
), len
);
43 server_call( REQ_CREATE_EVENT
);
51 /***********************************************************************
52 * CreateEventW (KERNEL32.157)
54 HANDLE WINAPI
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
55 BOOL initial_state
, LPCWSTR name
)
58 DWORD len
= name
? strlenW(name
) : 0;
61 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
64 /* one buggy program needs this
65 * ("Van Dale Groot woordenboek der Nederlandse taal")
67 if (sa
&& IsBadReadPtr(sa
,sizeof(SECURITY_ATTRIBUTES
)))
69 ERR("Bad security attributes pointer %p\n",sa
);
70 SetLastError( ERROR_INVALID_PARAMETER
);
75 struct create_event_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
77 req
->manual_reset
= manual_reset
;
78 req
->initial_state
= initial_state
;
79 req
->inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
80 memcpy( server_data_ptr(req
), name
, len
* sizeof(WCHAR
) );
82 server_call( REQ_CREATE_EVENT
);
90 /***********************************************************************
91 * WIN16_CreateEvent (KERNEL.457)
93 HANDLE WINAPI
WIN16_CreateEvent( BOOL manual_reset
, BOOL initial_state
)
95 return CreateEventA( NULL
, manual_reset
, initial_state
, NULL
);
99 /***********************************************************************
100 * OpenEventA (KERNEL32.536)
102 HANDLE WINAPI
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
105 DWORD len
= name
? MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), NULL
, 0 ) : 0;
108 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
113 struct open_event_request
*req
= server_alloc_req( sizeof(*req
), 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
);
118 server_call( REQ_OPEN_EVENT
);
126 /***********************************************************************
127 * OpenEventW (KERNEL32.537)
129 HANDLE WINAPI
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
132 DWORD len
= name
? strlenW(name
) : 0;
135 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
140 struct open_event_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
142 req
->access
= access
;
143 req
->inherit
= inherit
;
144 memcpy( server_data_ptr(req
), name
, len
* sizeof(WCHAR
) );
145 server_call( REQ_OPEN_EVENT
);
153 /***********************************************************************
156 * Execute an event operation (set,reset,pulse).
158 static BOOL
EVENT_Operation( HANDLE handle
, enum event_op op
)
163 struct event_op_request
*req
= server_alloc_req( sizeof(*req
), 0 );
164 req
->handle
= handle
;
166 ret
= !server_call( REQ_EVENT_OP
);
173 /***********************************************************************
174 * PulseEvent (KERNEL32.557)
176 BOOL WINAPI
PulseEvent( HANDLE handle
)
178 return EVENT_Operation( handle
, PULSE_EVENT
);
182 /***********************************************************************
183 * SetEvent (KERNEL.458)
184 * SetEvent (KERNEL32.644)
186 BOOL WINAPI
SetEvent( HANDLE handle
)
188 return EVENT_Operation( handle
, SET_EVENT
);
192 /***********************************************************************
193 * ResetEvent (KERNEL.459)
194 * ResetEvent (KERNEL32.586)
196 BOOL WINAPI
ResetEvent( HANDLE handle
)
198 return EVENT_Operation( handle
, RESET_EVENT
);
202 /***********************************************************************
203 * NOTE: The Win95 VWin32_Event routines given below are really low-level
204 * routines implemented directly by VWin32. The user-mode libraries
205 * implement Win32 synchronisation routines on top of these low-level
206 * primitives. We do it the other way around here :-)
209 /***********************************************************************
210 * VWin32_EventCreate (KERNEL.442)
212 HANDLE WINAPI
VWin32_EventCreate(VOID
)
214 HANDLE hEvent
= CreateEventA( NULL
, FALSE
, 0, NULL
);
215 return ConvertToGlobalHandle( hEvent
);
218 /***********************************************************************
219 * VWin32_EventDestroy (KERNEL.443)
221 VOID WINAPI
VWin32_EventDestroy(HANDLE event
)
223 CloseHandle( event
);
226 /***********************************************************************
227 * VWin32_EventWait (KERNEL.450)
229 VOID WINAPI
VWin32_EventWait(HANDLE event
)
233 ReleaseThunkLock( &mutex_count
);
234 WaitForSingleObject( event
, INFINITE
);
235 RestoreThunkLock( mutex_count
);
238 /***********************************************************************
239 * VWin32_EventSet (KERNEL.479)
241 VOID WINAPI
VWin32_EventSet(HANDLE event
)
248 /***********************************************************************
249 * CreateMutexA (KERNEL32.166)
251 HANDLE WINAPI
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
254 DWORD len
= name
? MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), NULL
, 0 ) : 0;
257 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
262 struct create_mutex_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
265 req
->inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
266 if (len
) MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), server_data_ptr(req
), len
);
268 server_call( REQ_CREATE_MUTEX
);
276 /***********************************************************************
277 * CreateMutexW (KERNEL32.167)
279 HANDLE WINAPI
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
282 DWORD len
= name
? strlenW(name
) : 0;
285 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
290 struct create_mutex_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
293 req
->inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
294 memcpy( server_data_ptr(req
), name
, len
* sizeof(WCHAR
) );
296 server_call( REQ_CREATE_MUTEX
);
309 /***********************************************************************
310 * OpenMutexA (KERNEL32.541)
312 HANDLE WINAPI
OpenMutexA( DWORD access
, BOOL inherit
, LPCSTR name
)
315 DWORD len
= name
? MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), NULL
, 0 ) : 0;
318 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
323 struct open_mutex_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
325 req
->access
= access
;
326 req
->inherit
= inherit
;
327 if (len
) MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), server_data_ptr(req
), len
);
328 server_call( REQ_OPEN_MUTEX
);
336 /***********************************************************************
337 * OpenMutexW (KERNEL32.542)
339 HANDLE WINAPI
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
342 DWORD len
= name
? strlenW(name
) : 0;
345 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
350 struct open_mutex_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
352 req
->access
= access
;
353 req
->inherit
= inherit
;
354 memcpy( server_data_ptr(req
), name
, len
* sizeof(WCHAR
) );
355 server_call( REQ_OPEN_MUTEX
);
363 /***********************************************************************
364 * ReleaseMutex (KERNEL32.582)
366 BOOL WINAPI
ReleaseMutex( HANDLE handle
)
371 struct release_mutex_request
*req
= server_alloc_req( sizeof(*req
), 0 );
372 req
->handle
= handle
;
373 ret
= !server_call( REQ_RELEASE_MUTEX
);
385 /***********************************************************************
386 * CreateSemaphoreA (KERNEL32.174)
388 HANDLE WINAPI
CreateSemaphoreA( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
, LPCSTR name
)
391 DWORD len
= name
? MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), NULL
, 0 ) : 0;
393 /* Check parameters */
395 if ((max
<= 0) || (initial
< 0) || (initial
> max
))
397 SetLastError( ERROR_INVALID_PARAMETER
);
402 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
408 struct create_semaphore_request
*req
= server_alloc_req( sizeof(*req
),
409 len
* sizeof(WCHAR
) );
411 req
->initial
= (unsigned int)initial
;
412 req
->max
= (unsigned int)max
;
413 req
->inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
414 if (len
) MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), server_data_ptr(req
), len
);
416 server_call( REQ_CREATE_SEMAPHORE
);
424 /***********************************************************************
425 * CreateSemaphoreW (KERNEL32.175)
427 HANDLE WINAPI
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
428 LONG max
, LPCWSTR name
)
431 DWORD len
= name
? strlenW(name
) : 0;
433 /* Check parameters */
435 if ((max
<= 0) || (initial
< 0) || (initial
> max
))
437 SetLastError( ERROR_INVALID_PARAMETER
);
442 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
448 struct create_semaphore_request
*req
= server_alloc_req( sizeof(*req
),
449 len
* sizeof(WCHAR
) );
451 req
->initial
= (unsigned int)initial
;
452 req
->max
= (unsigned int)max
;
453 req
->inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
454 memcpy( server_data_ptr(req
), name
, len
* sizeof(WCHAR
) );
456 server_call( REQ_CREATE_SEMAPHORE
);
464 /***********************************************************************
465 * OpenSemaphoreA (KERNEL32.545)
467 HANDLE WINAPI
OpenSemaphoreA( DWORD access
, BOOL inherit
, LPCSTR name
)
470 DWORD len
= name
? MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), NULL
, 0 ) : 0;
473 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
478 struct open_semaphore_request
*req
= server_alloc_req( sizeof(*req
),
479 len
* sizeof(WCHAR
) );
480 req
->access
= access
;
481 req
->inherit
= inherit
;
482 if (len
) MultiByteToWideChar( CP_ACP
, 0, name
, strlen(name
), server_data_ptr(req
), len
);
483 server_call( REQ_OPEN_SEMAPHORE
);
491 /***********************************************************************
492 * OpenSemaphoreW (KERNEL32.546)
494 HANDLE WINAPI
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
497 DWORD len
= name
? strlenW(name
) : 0;
500 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
505 struct open_semaphore_request
*req
= server_alloc_req( sizeof(*req
), len
* sizeof(WCHAR
) );
506 req
->access
= access
;
507 req
->inherit
= inherit
;
508 memcpy( server_data_ptr(req
), name
, len
* sizeof(WCHAR
) );
509 server_call( REQ_OPEN_SEMAPHORE
);
517 /***********************************************************************
518 * ReleaseSemaphore (KERNEL32.583)
520 BOOL WINAPI
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
522 NTSTATUS status
= NtReleaseSemaphore( handle
, count
, previous
);
523 if (status
) SetLastError( RtlNtStatusToDosError(status
) );
533 /***********************************************************************
534 * CreateNamedPipeA (KERNEL32.168)
536 HANDLE WINAPI
CreateNamedPipeA( LPCSTR name
, DWORD dwOpenMode
,
537 DWORD dwPipeMode
, DWORD nMaxInstances
,
538 DWORD nOutBufferSize
, DWORD nInBufferSize
,
539 DWORD nDefaultTimeOut
, LPSECURITY_ATTRIBUTES attr
)
541 FIXME("(Name=%s, OpenMode=%#08lx, dwPipeMode=%#08lx, MaxInst=%ld, OutBSize=%ld, InBuffSize=%ld, DefTimeOut=%ld, SecAttr=%p): stub\n",
542 debugstr_a(name
), dwOpenMode
, dwPipeMode
, nMaxInstances
,
543 nOutBufferSize
, nInBufferSize
, nDefaultTimeOut
, attr
);
544 SetLastError (ERROR_UNKNOWN
);
545 return INVALID_HANDLE_VALUE
;
549 /***********************************************************************
550 * CreateNamedPipeW (KERNEL32.169)
552 HANDLE WINAPI
CreateNamedPipeW( LPCWSTR name
, DWORD dwOpenMode
,
553 DWORD dwPipeMode
, DWORD nMaxInstances
,
554 DWORD nOutBufferSize
, DWORD nInBufferSize
,
555 DWORD nDefaultTimeOut
, LPSECURITY_ATTRIBUTES attr
)
557 FIXME("(Name=%s, OpenMode=%#08lx, dwPipeMode=%#08lx, MaxInst=%ld, OutBSize=%ld, InBuffSize=%ld, DefTimeOut=%ld, SecAttr=%p): stub\n",
558 debugstr_w(name
), dwOpenMode
, dwPipeMode
, nMaxInstances
,
559 nOutBufferSize
, nInBufferSize
, nDefaultTimeOut
, attr
);
561 SetLastError (ERROR_UNKNOWN
);
562 return INVALID_HANDLE_VALUE
;
566 /***********************************************************************
567 * PeekNamedPipe (KERNEL32.552)
569 BOOL WINAPI
PeekNamedPipe( HANDLE hPipe
, LPVOID lpvBuffer
, DWORD cbBuffer
,
570 LPDWORD lpcbRead
, LPDWORD lpcbAvail
, LPDWORD lpcbMessage
)
572 FIXME("(%08x, %p, %08lx, %p, %p, %p): stub\n",
573 hPipe
, lpvBuffer
, cbBuffer
, lpcbRead
, lpcbAvail
, lpcbMessage
);
574 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
579 /***********************************************************************
580 * WaitNamedPipeA (KERNEL32.725)
582 BOOL WINAPI
WaitNamedPipeA (LPCSTR lpNamedPipeName
, DWORD nTimeOut
)
584 FIXME("%s 0x%08lx\n",lpNamedPipeName
,nTimeOut
);
585 SetLastError(ERROR_PIPE_NOT_CONNECTED
);
590 /***********************************************************************
591 * WaitNamedPipeW (KERNEL32.726)
593 BOOL WINAPI
WaitNamedPipeW (LPCWSTR lpNamedPipeName
, DWORD nTimeOut
)
595 FIXME("%s 0x%08lx\n",debugstr_w(lpNamedPipeName
),nTimeOut
);
596 SetLastError(ERROR_PIPE_NOT_CONNECTED
);