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
26 #define WIN32_NO_STATUS
27 #define NONAMELESSUNION
36 #include "kernelbase.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
)
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};
59 OBJECT_ATTRIBUTES attr
;
60 NTSTATUS status
= STATUS_SUCCESS
;
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... */
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
;
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
)
104 SetLastError( ERROR_INVALID_PARAMETER
);
107 RtlInitUnicodeString( nameW
, name
);
108 BaseGetNamedObjectDirectory( &dir
);
109 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
114 /***********************************************************************
116 ***********************************************************************/
119 /***********************************************************************
120 * CreateEventA (kernelbase.@)
122 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
123 BOOL initial_state
, LPCSTR name
)
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
)
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
);
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
)
173 UNICODE_STRING nameW
;
174 OBJECT_ATTRIBUTES attr
;
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
);
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
);
195 SetLastError( RtlNtStatusToDosError(status
) );
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
);
214 return OpenEventW( access
, inherit
, buffer
);
218 /***********************************************************************
219 * OpenEventW (kernelbase.@)
221 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
224 UNICODE_STRING nameW
;
225 OBJECT_ATTRIBUTES attr
;
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
) );
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 /***********************************************************************
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
)
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
);
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
)
320 UNICODE_STRING nameW
;
321 OBJECT_ATTRIBUTES attr
;
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
);
330 SetLastError( RtlNtStatusToDosError(status
) );
335 /***********************************************************************
336 * OpenMutexW (kernelbase.@)
338 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
341 UNICODE_STRING nameW
;
342 OBJECT_ATTRIBUTES attr
;
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
) );
359 /***********************************************************************
360 * ReleaseMutex (kernelbase.@)
362 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
364 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
368 /***********************************************************************
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
)
390 UNICODE_STRING nameW
;
391 OBJECT_ATTRIBUTES attr
;
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
);
400 SetLastError( RtlNtStatusToDosError(status
) );
405 /***********************************************************************
406 * OpenSemaphoreW (kernelbase.@)
408 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
411 UNICODE_STRING nameW
;
412 OBJECT_ATTRIBUTES attr
;
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
) );
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
));