Handle WM_CHARs and pass them to TREEVIEW_ProcessLetterKeys. See also
[wine] / dlls / kernel / sync.c
1 /*
2  * Kernel synchronization objects
3  *
4  * Copyright 1998 Alexandre Julliard
5  */
6
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"
13
14 DEFAULT_DEBUG_CHANNEL(win32);
15
16 /*
17  * Events
18  */
19
20
21 /***********************************************************************
22  *           CreateEventA    (KERNEL32.156)
23  */
24 HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
25                             BOOL initial_state, LPCSTR name )
26 {
27     HANDLE ret;
28     DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
29     if (len >= MAX_PATH)
30     {
31         SetLastError( ERROR_FILENAME_EXCED_RANGE );
32         return 0;
33     }
34     SERVER_START_REQ
35     {
36         struct create_event_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
37
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;
45     }
46     SERVER_END_REQ;
47     return ret;
48 }
49
50
51 /***********************************************************************
52  *           CreateEventW    (KERNEL32.157)
53  */
54 HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
55                             BOOL initial_state, LPCWSTR name )
56 {
57     HANDLE ret;
58     DWORD len = name ? strlenW(name) : 0;
59     if (len >= MAX_PATH)
60     {
61         SetLastError( ERROR_FILENAME_EXCED_RANGE );
62         return 0;
63     }
64     /* one buggy program needs this
65      * ("Van Dale Groot woordenboek der Nederlandse taal")
66      */
67     if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
68     {
69         ERR("Bad security attributes pointer %p\n",sa);
70         SetLastError( ERROR_INVALID_PARAMETER);
71         return 0;
72     }
73     SERVER_START_REQ
74     {
75         struct create_event_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
76
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;
84     }
85     SERVER_END_REQ;
86     return ret;
87 }
88
89
90 /***********************************************************************
91  *           WIN16_CreateEvent    (KERNEL.457)
92  */
93 HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state )
94 {
95     return CreateEventA( NULL, manual_reset, initial_state, NULL );
96 }
97
98
99 /***********************************************************************
100  *           OpenEventA    (KERNEL32.536)
101  */
102 HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
103 {
104     HANDLE ret;
105     DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
106     if (len >= MAX_PATH)
107     {
108         SetLastError( ERROR_FILENAME_EXCED_RANGE );
109         return 0;
110     }
111     SERVER_START_REQ
112     {
113         struct open_event_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
114
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;
120     }
121     SERVER_END_REQ;
122     return ret;
123 }
124
125
126 /***********************************************************************
127  *           OpenEventW    (KERNEL32.537)
128  */
129 HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
130 {
131     HANDLE ret;
132     DWORD len = name ? strlenW(name) : 0;
133     if (len >= MAX_PATH)
134     {
135         SetLastError( ERROR_FILENAME_EXCED_RANGE );
136         return 0;
137     }
138     SERVER_START_REQ
139     {
140         struct open_event_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
141
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;
147     }
148     SERVER_END_REQ;
149     return ret;
150 }
151
152
153 /***********************************************************************
154  *           EVENT_Operation
155  *
156  * Execute an event operation (set,reset,pulse).
157  */
158 static BOOL EVENT_Operation( HANDLE handle, enum event_op op )
159 {
160     BOOL ret;
161     SERVER_START_REQ
162     {
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 );
167     }
168     SERVER_END_REQ;
169     return ret;
170 }
171
172
173 /***********************************************************************
174  *           PulseEvent    (KERNEL32.557)
175  */
176 BOOL WINAPI PulseEvent( HANDLE handle )
177 {
178     return EVENT_Operation( handle, PULSE_EVENT );
179 }
180
181
182 /***********************************************************************
183  *           SetEvent    (KERNEL.458)
184  *           SetEvent    (KERNEL32.644)
185  */
186 BOOL WINAPI SetEvent( HANDLE handle )
187 {
188     return EVENT_Operation( handle, SET_EVENT );
189 }
190
191
192 /***********************************************************************
193  *           ResetEvent    (KERNEL.459)
194  *           ResetEvent    (KERNEL32.586)
195  */
196 BOOL WINAPI ResetEvent( HANDLE handle )
197 {
198     return EVENT_Operation( handle, RESET_EVENT );
199 }
200
201
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 :-)
207  */
208
209 /***********************************************************************
210  *       VWin32_EventCreate     (KERNEL.442)
211  */
212 HANDLE WINAPI VWin32_EventCreate(VOID)
213 {
214     HANDLE hEvent = CreateEventA( NULL, FALSE, 0, NULL );
215     return ConvertToGlobalHandle( hEvent );
216 }
217
218 /***********************************************************************
219  *       VWin32_EventDestroy    (KERNEL.443)
220  */
221 VOID WINAPI VWin32_EventDestroy(HANDLE event)
222 {
223     CloseHandle( event );
224 }
225
226 /***********************************************************************
227  *       VWin32_EventWait       (KERNEL.450) 
228  */
229 VOID WINAPI VWin32_EventWait(HANDLE event)
230 {
231     DWORD mutex_count;
232
233     ReleaseThunkLock( &mutex_count );
234     WaitForSingleObject( event, INFINITE );
235     RestoreThunkLock( mutex_count );
236 }
237
238 /***********************************************************************
239  *       VWin32_EventSet        (KERNEL.479)
240  */
241 VOID WINAPI VWin32_EventSet(HANDLE event)
242 {
243     SetEvent( event );
244 }
245
246
247
248 /***********************************************************************
249  *           CreateMutexA   (KERNEL32.166)
250  */
251 HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
252 {
253     HANDLE ret;
254     DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
255     if (len >= MAX_PATH)
256     {
257         SetLastError( ERROR_FILENAME_EXCED_RANGE );
258         return 0;
259     }
260     SERVER_START_REQ
261     {
262         struct create_mutex_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
263
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;
270     }
271     SERVER_END_REQ;
272     return ret;
273 }
274
275
276 /***********************************************************************
277  *           CreateMutexW   (KERNEL32.167)
278  */
279 HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
280 {
281     HANDLE ret;
282     DWORD len = name ? strlenW(name) : 0;
283     if (len >= MAX_PATH)
284     {
285         SetLastError( ERROR_FILENAME_EXCED_RANGE );
286         return 0;
287     }
288     SERVER_START_REQ
289     {
290         struct create_mutex_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
291
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;
298     }
299     SERVER_END_REQ;
300     return ret;
301 }
302
303
304 /*
305  * Mutexes
306  */
307
308
309 /***********************************************************************
310  *           OpenMutexA   (KERNEL32.541)
311  */
312 HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
313 {
314     HANDLE ret;
315     DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
316     if (len >= MAX_PATH)
317     {
318         SetLastError( ERROR_FILENAME_EXCED_RANGE );
319         return 0;
320     }
321     SERVER_START_REQ
322     {
323         struct open_mutex_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
324
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;
330     }
331     SERVER_END_REQ;
332     return ret;
333 }
334
335
336 /***********************************************************************
337  *           OpenMutexW   (KERNEL32.542)
338  */
339 HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
340 {
341     HANDLE ret;
342     DWORD len = name ? strlenW(name) : 0;
343     if (len >= MAX_PATH)
344     {
345         SetLastError( ERROR_FILENAME_EXCED_RANGE );
346         return 0;
347     }
348     SERVER_START_REQ
349     {
350         struct open_mutex_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
351
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;
357     }
358     SERVER_END_REQ;
359     return ret;
360 }
361
362
363 /***********************************************************************
364  *           ReleaseMutex   (KERNEL32.582)
365  */
366 BOOL WINAPI ReleaseMutex( HANDLE handle )
367 {
368     BOOL ret;
369     SERVER_START_REQ
370     {
371         struct release_mutex_request *req = server_alloc_req( sizeof(*req), 0 );
372         req->handle = handle;
373         ret = !server_call( REQ_RELEASE_MUTEX );
374     }
375     SERVER_END_REQ;
376     return ret;
377 }
378
379
380 /*
381  * Semaphores
382  */
383
384
385 /***********************************************************************
386  *           CreateSemaphoreA   (KERNEL32.174)
387  */
388 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
389 {
390     HANDLE ret;
391     DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
392
393     /* Check parameters */
394
395     if ((max <= 0) || (initial < 0) || (initial > max))
396     {
397         SetLastError( ERROR_INVALID_PARAMETER );
398         return 0;
399     }
400     if (len >= MAX_PATH)
401     {
402         SetLastError( ERROR_FILENAME_EXCED_RANGE );
403         return 0;
404     }
405
406     SERVER_START_REQ
407     {
408         struct create_semaphore_request *req = server_alloc_req( sizeof(*req),
409                                                                  len * sizeof(WCHAR) );
410
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;
418     }
419     SERVER_END_REQ;
420     return ret;
421 }
422
423
424 /***********************************************************************
425  *           CreateSemaphoreW   (KERNEL32.175)
426  */
427 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
428                                     LONG max, LPCWSTR name )
429 {
430     HANDLE ret;
431     DWORD len = name ? strlenW(name) : 0;
432
433     /* Check parameters */
434
435     if ((max <= 0) || (initial < 0) || (initial > max))
436     {
437         SetLastError( ERROR_INVALID_PARAMETER );
438         return 0;
439     }
440     if (len >= MAX_PATH)
441     {
442         SetLastError( ERROR_FILENAME_EXCED_RANGE );
443         return 0;
444     }
445
446     SERVER_START_REQ
447     {
448         struct create_semaphore_request *req = server_alloc_req( sizeof(*req),
449                                                                  len * sizeof(WCHAR) );
450
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;
458     }
459     SERVER_END_REQ;
460     return ret;
461 }
462
463
464 /***********************************************************************
465  *           OpenSemaphoreA   (KERNEL32.545)
466  */
467 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
468 {
469     HANDLE ret;
470     DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
471     if (len >= MAX_PATH)
472     {
473         SetLastError( ERROR_FILENAME_EXCED_RANGE );
474         return 0;
475     }
476     SERVER_START_REQ
477     {
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;
485     }
486     SERVER_END_REQ;
487     return ret;
488 }
489
490
491 /***********************************************************************
492  *           OpenSemaphoreW   (KERNEL32.546)
493  */
494 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
495 {
496     HANDLE ret;
497     DWORD len = name ? strlenW(name) : 0;
498     if (len >= MAX_PATH)
499     {
500         SetLastError( ERROR_FILENAME_EXCED_RANGE );
501         return 0;
502     }
503     SERVER_START_REQ
504     {
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;
511     }
512     SERVER_END_REQ;
513     return ret;
514 }
515
516
517 /***********************************************************************
518  *           ReleaseSemaphore   (KERNEL32.583)
519  */
520 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
521 {
522     NTSTATUS status = NtReleaseSemaphore( handle, count, previous );
523     if (status) SetLastError( RtlNtStatusToDosError(status) );
524     return !status;
525 }
526
527
528 /*
529  * Pipes
530  */
531
532
533 /***********************************************************************
534  *           CreateNamedPipeA   (KERNEL32.168)
535  */
536 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
537                                 DWORD dwPipeMode, DWORD nMaxInstances,
538                                 DWORD nOutBufferSize, DWORD nInBufferSize,
539                                 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
540 {
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;
546 }
547
548
549 /***********************************************************************
550  *           CreateNamedPipeW   (KERNEL32.169)
551  */
552 HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
553                                 DWORD dwPipeMode, DWORD nMaxInstances,
554                                 DWORD nOutBufferSize, DWORD nInBufferSize,
555                                 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
556 {
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 );
560
561     SetLastError (ERROR_UNKNOWN);
562     return INVALID_HANDLE_VALUE;
563 }
564
565
566 /***********************************************************************
567  *           PeekNamedPipe   (KERNEL32.552)
568  */
569 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
570                            LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
571 {
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;
576 }
577
578
579 /***********************************************************************
580  *           WaitNamedPipeA   (KERNEL32.725)
581  */
582 BOOL WINAPI WaitNamedPipeA (LPCSTR lpNamedPipeName, DWORD nTimeOut)
583 {
584     FIXME("%s 0x%08lx\n",lpNamedPipeName,nTimeOut);
585     SetLastError(ERROR_PIPE_NOT_CONNECTED);
586     return FALSE;
587 }
588
589
590 /***********************************************************************
591  *           WaitNamedPipeW   (KERNEL32.726)
592  */
593 BOOL WINAPI WaitNamedPipeW (LPCWSTR lpNamedPipeName, DWORD nTimeOut)
594 {
595     FIXME("%s 0x%08lx\n",debugstr_w(lpNamedPipeName),nTimeOut);
596     SetLastError(ERROR_PIPE_NOT_CONNECTED);
597     return FALSE;
598 }