2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/synch/sem.c
5 * PURPOSE: Wrappers for the NT Semaphore Implementation
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ****************************************************************/
23 CreateSemaphoreExA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL
,
24 IN LONG lInitialCount
,
25 IN LONG lMaximumCount
,
26 IN LPCSTR lpName OPTIONAL
,
28 IN DWORD dwDesiredAccess
)
32 PUNICODE_STRING UnicodeCache
;
33 LPCWSTR UnicodeName
= NULL
;
35 /* Check for a name */
39 UnicodeCache
= &NtCurrentTeb()->StaticUnicodeString
;
41 /* Convert to unicode */
42 RtlInitAnsiString(&AnsiName
, lpName
);
43 Status
= RtlAnsiStringToUnicodeString(UnicodeCache
, &AnsiName
, FALSE
);
44 if (!NT_SUCCESS(Status
))
46 /* Conversion failed */
47 SetLastErrorByStatus(Status
);
51 /* Otherwise, save the buffer */
52 UnicodeName
= (LPCWSTR
)UnicodeCache
->Buffer
;
55 /* Call the Unicode API */
56 return CreateSemaphoreExW(lpSemaphoreAttributes
,
69 CreateSemaphoreExW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL
,
70 IN LONG lInitialCount
,
71 IN LONG lMaximumCount
,
72 IN LPCWSTR lpName OPTIONAL
,
74 IN DWORD dwDesiredAccess
)
77 OBJECT_ATTRIBUTES LocalAttributes
;
78 POBJECT_ATTRIBUTES ObjectAttributes
;
80 UNICODE_STRING ObjectName
;
82 /* Now check if we got a name */
83 if (lpName
) RtlInitUnicodeString(&ObjectName
, lpName
);
87 SetLastError(ERROR_INVALID_PARAMETER
);
91 /* Now convert the object attributes */
92 ObjectAttributes
= BasepConvertObjectAttributes(&LocalAttributes
,
93 lpSemaphoreAttributes
,
94 lpName
? &ObjectName
: NULL
);
96 /* Create the semaphore */
97 Status
= NtCreateSemaphore(&Handle
,
98 (ACCESS_MASK
)dwDesiredAccess
,
102 if (NT_SUCCESS(Status
))
104 /* Check if the object already existed */
105 if (Status
== STATUS_OBJECT_NAME_EXISTS
)
107 /* Set distinguished Win32 error code */
108 SetLastError(ERROR_ALREADY_EXISTS
);
112 /* Otherwise, set success */
113 SetLastError(ERROR_SUCCESS
);
116 /* Return the handle */
121 /* Convert the NT Status and fail */
122 SetLastErrorByStatus(Status
);
134 CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL
,
135 IN LONG lInitialCount
,
136 IN LONG lMaximumCount
,
137 IN LPCSTR lpName OPTIONAL
)
139 return CreateSemaphoreExA(lpSemaphoreAttributes
,
144 SEMAPHORE_ALL_ACCESS
);
152 CreateSemaphoreW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL
,
153 IN LONG lInitialCount
,
154 IN LONG lMaximumCount
,
155 IN LPCWSTR lpName OPTIONAL
)
157 return CreateSemaphoreExW(lpSemaphoreAttributes
,
162 SEMAPHORE_ALL_ACCESS
);
170 OpenSemaphoreA(IN DWORD dwDesiredAccess
,
171 IN BOOL bInheritHandle
,
175 ANSI_STRING AnsiName
;
176 PUNICODE_STRING UnicodeCache
;
178 /* Check for a name */
182 UnicodeCache
= &NtCurrentTeb()->StaticUnicodeString
;
184 /* Convert to unicode */
185 RtlInitAnsiString(&AnsiName
, lpName
);
186 Status
= RtlAnsiStringToUnicodeString(UnicodeCache
, &AnsiName
, FALSE
);
187 if (!NT_SUCCESS(Status
))
189 /* Conversion failed */
190 SetLastErrorByStatus(Status
);
197 SetLastError(ERROR_INVALID_PARAMETER
);
201 /* Call the Unicode API */
202 return OpenSemaphoreW(dwDesiredAccess
,
204 (LPCWSTR
)UnicodeCache
->Buffer
);
212 OpenSemaphoreW(IN DWORD dwDesiredAccess
,
213 IN BOOL bInheritHandle
,
216 OBJECT_ATTRIBUTES ObjectAttributes
;
217 UNICODE_STRING ObjectName
;
221 /* Make sure we got a name */
224 /* Fail without one */
225 SetLastErrorByStatus(STATUS_INVALID_PARAMETER
);
229 /* Initialize the object name and attributes */
230 RtlInitUnicodeString(&ObjectName
, lpName
);
231 InitializeObjectAttributes(&ObjectAttributes
,
233 bInheritHandle
? OBJ_INHERIT
: 0,
237 /* Open the semaphore */
238 Status
= NtOpenSemaphore(&Handle
, dwDesiredAccess
, &ObjectAttributes
);
239 if (!NT_SUCCESS(Status
))
241 /* Convert the status and fail */
242 SetLastErrorByStatus(Status
);
246 /* Return the handle */
255 ReleaseSemaphore(IN HANDLE hSemaphore
,
256 IN LONG lReleaseCount
,
257 IN LPLONG lpPreviousCount
)
261 /* Release the semaphore */
262 Status
= NtReleaseSemaphore(hSemaphore
, lReleaseCount
, lpPreviousCount
);
263 if (NT_SUCCESS(Status
)) return TRUE
;
265 /* If we got here, then we failed */
266 SetLastErrorByStatus(Status
);