move from branch
[reactos.git] / reactos / dll / win32 / kernel32 / synch / sem.c
1 /*
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)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <k32.h>
12
13 #define NDEBUG
14 #include "debug.h"
15
16 /* FUNCTIONS ****************************************************************/
17
18 /*
19 * @implemented
20 */
21 HANDLE
22 WINAPI
23 CreateSemaphoreExA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
24 IN LONG lInitialCount,
25 IN LONG lMaximumCount,
26 IN LPCSTR lpName OPTIONAL,
27 IN DWORD dwFlags,
28 IN DWORD dwDesiredAccess)
29 {
30 NTSTATUS Status;
31 ANSI_STRING AnsiName;
32 PUNICODE_STRING UnicodeCache;
33 LPCWSTR UnicodeName = NULL;
34
35 /* Check for a name */
36 if (lpName)
37 {
38 /* Use TEB Cache */
39 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
40
41 /* Convert to unicode */
42 RtlInitAnsiString(&AnsiName, lpName);
43 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
44 if (!NT_SUCCESS(Status))
45 {
46 /* Conversion failed */
47 SetLastErrorByStatus(Status);
48 return NULL;
49 }
50
51 /* Otherwise, save the buffer */
52 UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
53 }
54
55 /* Call the Unicode API */
56 return CreateSemaphoreExW(lpSemaphoreAttributes,
57 lInitialCount,
58 lMaximumCount,
59 UnicodeName,
60 dwFlags,
61 dwDesiredAccess);
62 }
63
64 /*
65 * @implemented
66 */
67 HANDLE
68 WINAPI
69 CreateSemaphoreExW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
70 IN LONG lInitialCount,
71 IN LONG lMaximumCount,
72 IN LPCWSTR lpName OPTIONAL,
73 IN DWORD dwFlags,
74 IN DWORD dwDesiredAccess)
75 {
76 NTSTATUS Status;
77 OBJECT_ATTRIBUTES LocalAttributes;
78 POBJECT_ATTRIBUTES ObjectAttributes;
79 HANDLE Handle;
80 UNICODE_STRING ObjectName;
81
82 /* Now check if we got a name */
83 if (lpName) RtlInitUnicodeString(&ObjectName, lpName);
84
85 if (dwFlags != 0)
86 {
87 SetLastError(ERROR_INVALID_PARAMETER);
88 return NULL;
89 }
90
91 /* Now convert the object attributes */
92 ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes,
93 lpSemaphoreAttributes,
94 lpName ? &ObjectName : NULL);
95
96 /* Create the semaphore */
97 Status = NtCreateSemaphore(&Handle,
98 (ACCESS_MASK)dwDesiredAccess,
99 ObjectAttributes,
100 lInitialCount,
101 lMaximumCount);
102 if (NT_SUCCESS(Status))
103 {
104 /* Check if the object already existed */
105 if (Status == STATUS_OBJECT_NAME_EXISTS)
106 {
107 /* Set distinguished Win32 error code */
108 SetLastError(ERROR_ALREADY_EXISTS);
109 }
110 else
111 {
112 /* Otherwise, set success */
113 SetLastError(ERROR_SUCCESS);
114 }
115
116 /* Return the handle */
117 return Handle;
118 }
119 else
120 {
121 /* Convert the NT Status and fail */
122 SetLastErrorByStatus(Status);
123 return NULL;
124 }
125
126 }
127
128
129 /*
130 * @implemented
131 */
132 HANDLE
133 WINAPI
134 CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
135 IN LONG lInitialCount,
136 IN LONG lMaximumCount,
137 IN LPCSTR lpName OPTIONAL)
138 {
139 return CreateSemaphoreExA(lpSemaphoreAttributes,
140 lInitialCount,
141 lMaximumCount,
142 lpName,
143 0,
144 SEMAPHORE_ALL_ACCESS);
145 }
146
147 /*
148 * @implemented
149 */
150 HANDLE
151 WINAPI
152 CreateSemaphoreW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
153 IN LONG lInitialCount,
154 IN LONG lMaximumCount,
155 IN LPCWSTR lpName OPTIONAL)
156 {
157 return CreateSemaphoreExW(lpSemaphoreAttributes,
158 lInitialCount,
159 lMaximumCount,
160 lpName,
161 0,
162 SEMAPHORE_ALL_ACCESS);
163 }
164
165 /*
166 * @implemented
167 */
168 HANDLE
169 WINAPI
170 OpenSemaphoreA(IN DWORD dwDesiredAccess,
171 IN BOOL bInheritHandle,
172 IN LPCSTR lpName)
173 {
174 NTSTATUS Status;
175 ANSI_STRING AnsiName;
176 PUNICODE_STRING UnicodeCache;
177
178 /* Check for a name */
179 if (lpName)
180 {
181 /* Use TEB Cache */
182 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
183
184 /* Convert to unicode */
185 RtlInitAnsiString(&AnsiName, lpName);
186 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
187 if (!NT_SUCCESS(Status))
188 {
189 /* Conversion failed */
190 SetLastErrorByStatus(Status);
191 return NULL;
192 }
193 }
194 else
195 {
196 /* We need a name */
197 SetLastError(ERROR_INVALID_PARAMETER);
198 return NULL;
199 }
200
201 /* Call the Unicode API */
202 return OpenSemaphoreW(dwDesiredAccess,
203 bInheritHandle,
204 (LPCWSTR)UnicodeCache->Buffer);
205 }
206
207 /*
208 * @implemented
209 */
210 HANDLE
211 WINAPI
212 OpenSemaphoreW(IN DWORD dwDesiredAccess,
213 IN BOOL bInheritHandle,
214 IN LPCWSTR lpName)
215 {
216 OBJECT_ATTRIBUTES ObjectAttributes;
217 UNICODE_STRING ObjectName;
218 NTSTATUS Status;
219 HANDLE Handle;
220
221 /* Make sure we got a name */
222 if (!lpName)
223 {
224 /* Fail without one */
225 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
226 return NULL;
227 }
228
229 /* Initialize the object name and attributes */
230 RtlInitUnicodeString(&ObjectName, lpName);
231 InitializeObjectAttributes(&ObjectAttributes,
232 &ObjectName,
233 bInheritHandle ? OBJ_INHERIT : 0,
234 hBaseDir,
235 NULL);
236
237 /* Open the semaphore */
238 Status = NtOpenSemaphore(&Handle, dwDesiredAccess, &ObjectAttributes);
239 if (!NT_SUCCESS(Status))
240 {
241 /* Convert the status and fail */
242 SetLastErrorByStatus(Status);
243 return NULL;
244 }
245
246 /* Return the handle */
247 return Handle;
248 }
249
250 /*
251 * @implemented
252 */
253 BOOL
254 WINAPI
255 ReleaseSemaphore(IN HANDLE hSemaphore,
256 IN LONG lReleaseCount,
257 IN LPLONG lpPreviousCount)
258 {
259 NTSTATUS Status;
260
261 /* Release the semaphore */
262 Status = NtReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount);
263 if (NT_SUCCESS(Status)) return TRUE;
264
265 /* If we got here, then we failed */
266 SetLastErrorByStatus(Status);
267 return FALSE;
268 }
269
270 /* EOF */