Added a few missing stubs to KERNEL32 and USER32.
[wine.git] / dlls / kernel / sync.c
blob1c5ff981fa96c3f417f5e202363b74c1bda3a3a6
1 /*
2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
5 */
7 #include <string.h>
8 #include "winerror.h"
9 #include "winnls.h"
10 #include "wine/unicode.h"
11 #include "server.h"
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(win32);
17 * Events
21 /***********************************************************************
22 * CreateEventA (KERNEL32.156)
24 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
25 BOOL initial_state, LPCSTR name )
27 HANDLE ret;
28 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
29 if (len >= MAX_PATH)
31 SetLastError( ERROR_FILENAME_EXCED_RANGE );
32 return 0;
34 SERVER_START_REQ
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 );
42 SetLastError(0);
43 server_call( REQ_CREATE_EVENT );
44 ret = req->handle;
46 SERVER_END_REQ;
47 return ret;
51 /***********************************************************************
52 * CreateEventW (KERNEL32.157)
54 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
55 BOOL initial_state, LPCWSTR name )
57 HANDLE ret;
58 DWORD len = name ? strlenW(name) : 0;
59 if (len >= MAX_PATH)
61 SetLastError( ERROR_FILENAME_EXCED_RANGE );
62 return 0;
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);
71 return 0;
73 SERVER_START_REQ
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) );
81 SetLastError(0);
82 server_call( REQ_CREATE_EVENT );
83 ret = req->handle;
85 SERVER_END_REQ;
86 return ret;
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 )
104 HANDLE ret;
105 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
106 if (len >= MAX_PATH)
108 SetLastError( ERROR_FILENAME_EXCED_RANGE );
109 return 0;
111 SERVER_START_REQ
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 );
119 ret = req->handle;
121 SERVER_END_REQ;
122 return ret;
126 /***********************************************************************
127 * OpenEventW (KERNEL32.537)
129 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
131 HANDLE ret;
132 DWORD len = name ? strlenW(name) : 0;
133 if (len >= MAX_PATH)
135 SetLastError( ERROR_FILENAME_EXCED_RANGE );
136 return 0;
138 SERVER_START_REQ
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 );
146 ret = req->handle;
148 SERVER_END_REQ;
149 return ret;
153 /***********************************************************************
154 * EVENT_Operation
156 * Execute an event operation (set,reset,pulse).
158 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
160 BOOL ret;
161 SERVER_START_REQ
163 struct event_op_request *req = server_alloc_req( sizeof(*req), 0 );
164 req->handle = handle;
165 req->op = op;
166 ret = !server_call( REQ_EVENT_OP );
168 SERVER_END_REQ;
169 return ret;
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)
231 DWORD mutex_count;
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)
243 SetEvent( event );
248 /***********************************************************************
249 * CreateMutexA (KERNEL32.166)
251 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
253 HANDLE ret;
254 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
255 if (len >= MAX_PATH)
257 SetLastError( ERROR_FILENAME_EXCED_RANGE );
258 return 0;
260 SERVER_START_REQ
262 struct create_mutex_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
264 req->owned = owner;
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 );
267 SetLastError(0);
268 server_call( REQ_CREATE_MUTEX );
269 ret = req->handle;
271 SERVER_END_REQ;
272 return ret;
276 /***********************************************************************
277 * CreateMutexW (KERNEL32.167)
279 HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
281 HANDLE ret;
282 DWORD len = name ? strlenW(name) : 0;
283 if (len >= MAX_PATH)
285 SetLastError( ERROR_FILENAME_EXCED_RANGE );
286 return 0;
288 SERVER_START_REQ
290 struct create_mutex_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
292 req->owned = owner;
293 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
294 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
295 SetLastError(0);
296 server_call( REQ_CREATE_MUTEX );
297 ret = req->handle;
299 SERVER_END_REQ;
300 return ret;
305 * Mutexes
309 /***********************************************************************
310 * OpenMutexA (KERNEL32.541)
312 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
314 HANDLE ret;
315 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
316 if (len >= MAX_PATH)
318 SetLastError( ERROR_FILENAME_EXCED_RANGE );
319 return 0;
321 SERVER_START_REQ
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 );
329 ret = req->handle;
331 SERVER_END_REQ;
332 return ret;
336 /***********************************************************************
337 * OpenMutexW (KERNEL32.542)
339 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
341 HANDLE ret;
342 DWORD len = name ? strlenW(name) : 0;
343 if (len >= MAX_PATH)
345 SetLastError( ERROR_FILENAME_EXCED_RANGE );
346 return 0;
348 SERVER_START_REQ
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 );
356 ret = req->handle;
358 SERVER_END_REQ;
359 return ret;
363 /***********************************************************************
364 * ReleaseMutex (KERNEL32.582)
366 BOOL WINAPI ReleaseMutex( HANDLE handle )
368 BOOL ret;
369 SERVER_START_REQ
371 struct release_mutex_request *req = server_alloc_req( sizeof(*req), 0 );
372 req->handle = handle;
373 ret = !server_call( REQ_RELEASE_MUTEX );
375 SERVER_END_REQ;
376 return ret;
381 * Semaphores
385 /***********************************************************************
386 * CreateSemaphoreA (KERNEL32.174)
388 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
390 HANDLE ret;
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 );
398 return 0;
400 if (len >= MAX_PATH)
402 SetLastError( ERROR_FILENAME_EXCED_RANGE );
403 return 0;
406 SERVER_START_REQ
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 );
415 SetLastError(0);
416 server_call( REQ_CREATE_SEMAPHORE );
417 ret = req->handle;
419 SERVER_END_REQ;
420 return ret;
424 /***********************************************************************
425 * CreateSemaphoreW (KERNEL32.175)
427 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
428 LONG max, LPCWSTR name )
430 HANDLE ret;
431 DWORD len = name ? strlenW(name) : 0;
433 /* Check parameters */
435 if ((max <= 0) || (initial < 0) || (initial > max))
437 SetLastError( ERROR_INVALID_PARAMETER );
438 return 0;
440 if (len >= MAX_PATH)
442 SetLastError( ERROR_FILENAME_EXCED_RANGE );
443 return 0;
446 SERVER_START_REQ
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) );
455 SetLastError(0);
456 server_call( REQ_CREATE_SEMAPHORE );
457 ret = req->handle;
459 SERVER_END_REQ;
460 return ret;
464 /***********************************************************************
465 * OpenSemaphoreA (KERNEL32.545)
467 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
469 HANDLE ret;
470 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
471 if (len >= MAX_PATH)
473 SetLastError( ERROR_FILENAME_EXCED_RANGE );
474 return 0;
476 SERVER_START_REQ
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 );
484 ret = req->handle;
486 SERVER_END_REQ;
487 return ret;
491 /***********************************************************************
492 * OpenSemaphoreW (KERNEL32.546)
494 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
496 HANDLE ret;
497 DWORD len = name ? strlenW(name) : 0;
498 if (len >= MAX_PATH)
500 SetLastError( ERROR_FILENAME_EXCED_RANGE );
501 return 0;
503 SERVER_START_REQ
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 );
510 ret = req->handle;
512 SERVER_END_REQ;
513 return ret;
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) );
524 return !status;
529 * Pipes
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);
575 return FALSE;
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);
586 return FALSE;
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);
597 return FALSE;