kernel32: Move semaphore functions to kernelbase.
[wine.git] / dlls / kernelbase / sync.c
blob58d62ed44565947fed66a8fd96aa520630f78eb9
1 /*
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
23 #include <stdio.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #define NONAMELESSUNION
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "winnls.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ddk/wdm.h"
36 #include "kernelbase.h"
37 #include "wine/asm.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(sync);
42 /* check if current version is NT or Win95 */
43 static inline BOOL is_version_nt(void)
45 return !(GetVersion() & 0x80000000);
49 /***********************************************************************
50 * BaseGetNamedObjectDirectory (kernelbase.@)
52 NTSTATUS WINAPI BaseGetNamedObjectDirectory( HANDLE *dir )
54 static HANDLE handle;
55 static const WCHAR basenameW[] = {'\\','S','e','s','s','i','o','n','s','\\','%','u',
56 '\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',0};
57 WCHAR buffer[64];
58 UNICODE_STRING str;
59 OBJECT_ATTRIBUTES attr;
60 NTSTATUS status = STATUS_SUCCESS;
62 if (!handle)
64 HANDLE dir;
66 swprintf( buffer, ARRAY_SIZE(buffer), basenameW, NtCurrentTeb()->Peb->SessionId );
67 RtlInitUnicodeString( &str, buffer );
68 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
69 status = NtOpenDirectoryObject( &dir, DIRECTORY_CREATE_OBJECT|DIRECTORY_TRAVERSE, &attr );
70 if (!status && InterlockedCompareExchangePointer( &handle, dir, 0 ) != 0)
72 /* someone beat us here... */
73 CloseHandle( dir );
76 *dir = handle;
77 return status;
80 static void get_create_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
81 SECURITY_ATTRIBUTES *sa, const WCHAR *name )
83 attr->Length = sizeof(*attr);
84 attr->RootDirectory = 0;
85 attr->ObjectName = NULL;
86 attr->Attributes = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
87 attr->SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
88 attr->SecurityQualityOfService = NULL;
89 if (name)
91 RtlInitUnicodeString( nameW, name );
92 attr->ObjectName = nameW;
93 BaseGetNamedObjectDirectory( &attr->RootDirectory );
97 static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
98 BOOL inherit, const WCHAR *name )
100 HANDLE dir;
102 if (!name)
104 SetLastError( ERROR_INVALID_PARAMETER );
105 return FALSE;
107 RtlInitUnicodeString( nameW, name );
108 BaseGetNamedObjectDirectory( &dir );
109 InitializeObjectAttributes( attr, nameW, inherit ? OBJ_INHERIT : 0, dir, NULL );
110 return TRUE;
114 /***********************************************************************
115 * Events
116 ***********************************************************************/
119 /***********************************************************************
120 * CreateEventA (kernelbase.@)
122 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
123 BOOL initial_state, LPCSTR name )
125 DWORD flags = 0;
127 if (manual_reset) flags |= CREATE_EVENT_MANUAL_RESET;
128 if (initial_state) flags |= CREATE_EVENT_INITIAL_SET;
129 return CreateEventExA( sa, name, flags, EVENT_ALL_ACCESS );
133 /***********************************************************************
134 * CreateEventW (kernelbase.@)
136 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
137 BOOL initial_state, LPCWSTR name )
139 DWORD flags = 0;
141 if (manual_reset) flags |= CREATE_EVENT_MANUAL_RESET;
142 if (initial_state) flags |= CREATE_EVENT_INITIAL_SET;
143 return CreateEventExW( sa, name, flags, EVENT_ALL_ACCESS );
147 /***********************************************************************
148 * CreateEventExA (kernelbase.@)
150 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventExA( SECURITY_ATTRIBUTES *sa, LPCSTR name,
151 DWORD flags, DWORD access )
153 WCHAR buffer[MAX_PATH];
155 if (!name) return CreateEventExW( sa, NULL, flags, access );
157 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
159 SetLastError( ERROR_FILENAME_EXCED_RANGE );
160 return 0;
162 return CreateEventExW( sa, buffer, flags, access );
166 /***********************************************************************
167 * CreateEventExW (kernelbase.@)
169 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventExW( SECURITY_ATTRIBUTES *sa, LPCWSTR name,
170 DWORD flags, DWORD access )
172 HANDLE ret = 0;
173 UNICODE_STRING nameW;
174 OBJECT_ATTRIBUTES attr;
175 NTSTATUS status;
177 /* one buggy program needs this
178 * ("Van Dale Groot woordenboek der Nederlandse taal")
180 if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
182 ERR("Bad security attributes pointer %p\n",sa);
183 SetLastError( ERROR_INVALID_PARAMETER);
184 return 0;
187 get_create_object_attributes( &attr, &nameW, sa, name );
189 status = NtCreateEvent( &ret, access, &attr,
190 (flags & CREATE_EVENT_MANUAL_RESET) ? NotificationEvent : SynchronizationEvent,
191 (flags & CREATE_EVENT_INITIAL_SET) != 0 );
192 if (status == STATUS_OBJECT_NAME_EXISTS)
193 SetLastError( ERROR_ALREADY_EXISTS );
194 else
195 SetLastError( RtlNtStatusToDosError(status) );
196 return ret;
200 /***********************************************************************
201 * OpenEventA (kernelbase.@)
203 HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
205 WCHAR buffer[MAX_PATH];
207 if (!name) return OpenEventW( access, inherit, NULL );
209 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
211 SetLastError( ERROR_FILENAME_EXCED_RANGE );
212 return 0;
214 return OpenEventW( access, inherit, buffer );
218 /***********************************************************************
219 * OpenEventW (kernelbase.@)
221 HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
223 HANDLE ret;
224 UNICODE_STRING nameW;
225 OBJECT_ATTRIBUTES attr;
226 NTSTATUS status;
228 if (!is_version_nt()) access = EVENT_ALL_ACCESS;
230 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
232 status = NtOpenEvent( &ret, access, &attr );
233 if (status != STATUS_SUCCESS)
235 SetLastError( RtlNtStatusToDosError(status) );
236 return 0;
238 return ret;
241 /***********************************************************************
242 * PulseEvent (kernelbase.@)
244 BOOL WINAPI DECLSPEC_HOTPATCH PulseEvent( HANDLE handle )
246 return set_ntstatus( NtPulseEvent( handle, NULL ));
250 /***********************************************************************
251 * SetEvent (kernelbase.@)
253 BOOL WINAPI DECLSPEC_HOTPATCH SetEvent( HANDLE handle )
255 return set_ntstatus( NtSetEvent( handle, NULL ));
259 /***********************************************************************
260 * ResetEvent (kernelbase.@)
262 BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent( HANDLE handle )
264 return set_ntstatus( NtResetEvent( handle, NULL ));
268 /***********************************************************************
269 * Mutexes
270 ***********************************************************************/
273 /***********************************************************************
274 * CreateMutexA (kernelbase.@)
276 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
278 return CreateMutexExA( sa, name, owner ? CREATE_MUTEX_INITIAL_OWNER : 0, MUTEX_ALL_ACCESS );
282 /***********************************************************************
283 * CreateMutexW (kernelbase.@)
285 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
287 return CreateMutexExW( sa, name, owner ? CREATE_MUTEX_INITIAL_OWNER : 0, MUTEX_ALL_ACCESS );
291 /***********************************************************************
292 * CreateMutexExA (kernelbase.@)
294 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexExA( SECURITY_ATTRIBUTES *sa, LPCSTR name,
295 DWORD flags, DWORD access )
297 ANSI_STRING nameA;
298 NTSTATUS status;
300 if (!name) return CreateMutexExW( sa, NULL, flags, access );
302 RtlInitAnsiString( &nameA, name );
303 status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString, &nameA, FALSE );
304 if (status != STATUS_SUCCESS)
306 SetLastError( ERROR_FILENAME_EXCED_RANGE );
307 return 0;
309 return CreateMutexExW( sa, NtCurrentTeb()->StaticUnicodeString.Buffer, flags, access );
313 /***********************************************************************
314 * CreateMutexExW (kernelbase.@)
316 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexExW( SECURITY_ATTRIBUTES *sa, LPCWSTR name,
317 DWORD flags, DWORD access )
319 HANDLE ret = 0;
320 UNICODE_STRING nameW;
321 OBJECT_ATTRIBUTES attr;
322 NTSTATUS status;
324 get_create_object_attributes( &attr, &nameW, sa, name );
326 status = NtCreateMutant( &ret, access, &attr, (flags & CREATE_MUTEX_INITIAL_OWNER) != 0 );
327 if (status == STATUS_OBJECT_NAME_EXISTS)
328 SetLastError( ERROR_ALREADY_EXISTS );
329 else
330 SetLastError( RtlNtStatusToDosError(status) );
331 return ret;
335 /***********************************************************************
336 * OpenMutexW (kernelbase.@)
338 HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
340 HANDLE ret;
341 UNICODE_STRING nameW;
342 OBJECT_ATTRIBUTES attr;
343 NTSTATUS status;
345 if (!is_version_nt()) access = MUTEX_ALL_ACCESS;
347 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
349 status = NtOpenMutant( &ret, access, &attr );
350 if (status != STATUS_SUCCESS)
352 SetLastError( RtlNtStatusToDosError(status) );
353 return 0;
355 return ret;
359 /***********************************************************************
360 * ReleaseMutex (kernelbase.@)
362 BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex( HANDLE handle )
364 return set_ntstatus( NtReleaseMutant( handle, NULL ));
368 /***********************************************************************
369 * Semaphores
370 ***********************************************************************/
373 /***********************************************************************
374 * CreateSemaphoreW (kernelbase.@)
376 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
377 LONG max, LPCWSTR name )
379 return CreateSemaphoreExW( sa, initial, max, name, 0, SEMAPHORE_ALL_ACCESS );
383 /***********************************************************************
384 * CreateSemaphoreExW (kernelbase.@)
386 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreExW( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
387 LPCWSTR name, DWORD flags, DWORD access )
389 HANDLE ret = 0;
390 UNICODE_STRING nameW;
391 OBJECT_ATTRIBUTES attr;
392 NTSTATUS status;
394 get_create_object_attributes( &attr, &nameW, sa, name );
396 status = NtCreateSemaphore( &ret, access, &attr, initial, max );
397 if (status == STATUS_OBJECT_NAME_EXISTS)
398 SetLastError( ERROR_ALREADY_EXISTS );
399 else
400 SetLastError( RtlNtStatusToDosError(status) );
401 return ret;
405 /***********************************************************************
406 * OpenSemaphoreW (kernelbase.@)
408 HANDLE WINAPI DECLSPEC_HOTPATCH OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
410 HANDLE ret;
411 UNICODE_STRING nameW;
412 OBJECT_ATTRIBUTES attr;
413 NTSTATUS status;
415 if (!is_version_nt()) access = SEMAPHORE_ALL_ACCESS;
417 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
419 status = NtOpenSemaphore( &ret, access, &attr );
420 if (status != STATUS_SUCCESS)
422 SetLastError( RtlNtStatusToDosError(status) );
423 return 0;
425 return ret;
429 /***********************************************************************
430 * ReleaseSemaphore (kernelbase.@)
432 BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
434 return set_ntstatus( NtReleaseSemaphore( handle, count, (PULONG)previous ));