- Merge from trunk up to r45543
[reactos.git] / dll / win32 / kernel32 / synch / event.c
1 /*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/synch/event.c
5 * PURPOSE: Wrappers for the NT Event Implementation
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <k32.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS ****************************************************************/
16
17 HANDLE
18 WINAPI
19 CreateEventExA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL,
20 IN LPCSTR lpName OPTIONAL,
21 IN DWORD dwFlags,
22 IN DWORD dwDesiredAccess)
23 {
24 NTSTATUS Status;
25 ANSI_STRING AnsiName;
26 PUNICODE_STRING UnicodeCache;
27 LPCWSTR UnicodeName = NULL;
28
29 /* Check for a name */
30 if (lpName)
31 {
32 /* Use TEB Cache */
33 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
34
35 /* Convert to unicode */
36 RtlInitAnsiString(&AnsiName, lpName);
37 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
38 if (!NT_SUCCESS(Status))
39 {
40 /* Conversion failed */
41 SetLastErrorByStatus(Status);
42 return NULL;
43 }
44
45 /* Otherwise, save the buffer */
46 UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
47 }
48
49 /* Call the Unicode API */
50 return CreateEventExW(lpEventAttributes,
51 UnicodeName,
52 dwFlags,
53 dwDesiredAccess);
54
55 }
56
57 HANDLE
58 WINAPI
59 CreateEventExW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL,
60 IN LPCWSTR lpName OPTIONAL,
61 IN DWORD dwFlags,
62 IN DWORD dwDesiredAccess)
63 {
64 NTSTATUS Status;
65 OBJECT_ATTRIBUTES LocalAttributes;
66 POBJECT_ATTRIBUTES ObjectAttributes;
67 HANDLE Handle;
68 UNICODE_STRING ObjectName;
69 BOOLEAN InitialState;
70 EVENT_TYPE EventType;
71
72 /* Now check if we got a name */
73 if (lpName) RtlInitUnicodeString(&ObjectName, lpName);
74
75 /* Check for invalid flags */
76 if (dwFlags & ~(CREATE_EVENT_INITIAL_SET | CREATE_EVENT_MANUAL_RESET))
77 {
78 /* Fail */
79 SetLastError(ERROR_INVALID_PARAMETER);
80 return NULL;
81 }
82
83 /* Set initial state and event type */
84 InitialState = (dwFlags & CREATE_EVENT_INITIAL_SET) ? TRUE : FALSE;
85 EventType = (dwFlags & CREATE_EVENT_MANUAL_RESET) ? NotificationEvent : SynchronizationEvent;
86
87 /* Now convert the object attributes */
88 ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes,
89 lpEventAttributes,
90 lpName ? &ObjectName : NULL);
91
92 /* Create the event */
93 Status = NtCreateEvent(&Handle,
94 (ACCESS_MASK)dwDesiredAccess,
95 ObjectAttributes,
96 EventType,
97 InitialState);
98 if (NT_SUCCESS(Status))
99 {
100 /* Check if the object already existed */
101 if (Status == STATUS_OBJECT_NAME_EXISTS)
102 {
103 /* Set distinguished Win32 error code */
104 SetLastError(ERROR_ALREADY_EXISTS);
105 }
106 else
107 {
108 /* Otherwise, set success */
109 SetLastError(ERROR_SUCCESS);
110 }
111
112 /* Return the handle */
113 return Handle;
114 }
115 else
116 {
117 /* Convert the NT Status and fail */
118 SetLastErrorByStatus(Status);
119 return NULL;
120 }
121
122 }
123
124 HANDLE
125 WINAPI
126 CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL,
127 IN BOOL bManualReset,
128 IN BOOL bInitialState,
129 IN LPCSTR lpName OPTIONAL)
130 {
131 DWORD dwFlags = 0;
132
133 /* Set new flags */
134 if (bManualReset) dwFlags |= CREATE_EVENT_MANUAL_RESET;
135 if (bInitialState) dwFlags |= CREATE_EVENT_INITIAL_SET;
136
137 /* Call the newer API */
138 return CreateEventExA(lpEventAttributes,
139 lpName,
140 dwFlags,
141 EVENT_ALL_ACCESS);
142 }
143
144 HANDLE
145 WINAPI
146 CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL,
147 IN BOOL bManualReset,
148 IN BOOL bInitialState,
149 IN LPCWSTR lpName OPTIONAL)
150 {
151 DWORD dwFlags = 0;
152
153 /* Set new flags */
154 if (bManualReset) dwFlags |= CREATE_EVENT_MANUAL_RESET;
155 if (bInitialState) dwFlags |= CREATE_EVENT_INITIAL_SET;
156
157 /* Call the newer API */
158 return CreateEventExW(lpEventAttributes,
159 lpName,
160 dwFlags,
161 EVENT_ALL_ACCESS);
162 }
163
164 HANDLE
165 WINAPI
166 OpenEventA(IN DWORD dwDesiredAccess,
167 IN BOOL bInheritHandle,
168 IN LPCSTR lpName)
169 {
170 NTSTATUS Status;
171 ANSI_STRING AnsiName;
172 PUNICODE_STRING UnicodeCache;
173
174 /* Check for a name */
175 if (lpName)
176 {
177 /* Use TEB Cache */
178 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
179
180 /* Convert to unicode */
181 RtlInitAnsiString(&AnsiName, lpName);
182 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
183 if (!NT_SUCCESS(Status))
184 {
185 /* Conversion failed */
186 SetLastErrorByStatus(Status);
187 return NULL;
188 }
189 }
190 else
191 {
192 /* We need a name */
193 SetLastError(ERROR_INVALID_PARAMETER);
194 return NULL;
195 }
196
197 /* Call the Unicode API */
198 return OpenEventW(dwDesiredAccess,
199 bInheritHandle,
200 (LPCWSTR)UnicodeCache->Buffer);
201 }
202
203 HANDLE
204 WINAPI
205 OpenEventW(IN DWORD dwDesiredAccess,
206 IN BOOL bInheritHandle,
207 IN LPCWSTR lpName)
208 {
209 OBJECT_ATTRIBUTES ObjectAttributes;
210 UNICODE_STRING ObjectName;
211 NTSTATUS Status;
212 HANDLE Handle;
213
214 /* Make sure we got a name */
215 if (!lpName)
216 {
217 /* Fail without one */
218 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
219 return NULL;
220 }
221
222 /* Initialize the object name and attributes */
223 RtlInitUnicodeString(&ObjectName, lpName);
224 InitializeObjectAttributes(&ObjectAttributes,
225 &ObjectName,
226 bInheritHandle ? OBJ_INHERIT : 0,
227 hBaseDir,
228 NULL);
229
230 /* Open the event */
231 Status = NtOpenEvent(&Handle, dwDesiredAccess, &ObjectAttributes);
232 if (!NT_SUCCESS(Status))
233 {
234 /* Convert the status and fail */
235 SetLastErrorByStatus(Status);
236 return NULL;
237 }
238
239 /* Return the handle */
240 return Handle;
241 }
242
243 /*
244 * @implemented
245 */
246 BOOL
247 WINAPI
248 PulseEvent(IN HANDLE hEvent)
249 {
250 NTSTATUS Status;
251
252 /* Pulse the event */
253 Status = NtPulseEvent(hEvent, NULL);
254 if (NT_SUCCESS(Status)) return TRUE;
255
256 /* If we got here, then we failed */
257 SetLastErrorByStatus(Status);
258 return FALSE;
259 }
260
261 /*
262 * @implemented
263 */
264 BOOL
265 WINAPI
266 ResetEvent(IN HANDLE hEvent)
267 {
268 NTSTATUS Status;
269
270 /* Clear the event */
271 Status = NtResetEvent(hEvent, NULL);
272 if (NT_SUCCESS(Status)) return TRUE;
273
274 /* If we got here, then we failed */
275 SetLastErrorByStatus(Status);
276 return FALSE;
277 }
278
279 /*
280 * @implemented
281 */
282 BOOL
283 WINAPI
284 SetEvent(IN HANDLE hEvent)
285 {
286 NTSTATUS Status;
287
288 /* Set the event */
289 Status = NtSetEvent(hEvent, NULL);
290 if (NT_SUCCESS(Status)) return TRUE;
291
292 /* If we got here, then we failed */
293 SetLastErrorByStatus(Status);
294 return FALSE;
295 }
296
297 /* EOF */