fd21a1be57f875facd9a5d06657c62700740bca6
[reactos.git] / reactos / dll / win32 / kernel32 / synch / timer.c
1 /*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/synch/timer.c
5 * PURPOSE: Wrappers for the NT Timer 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 CreateWaitableTimerExA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
24 IN LPCSTR lpTimerName OPTIONAL,
25 IN DWORD dwFlags,
26 IN DWORD dwDesiredAccess)
27 {
28 NTSTATUS Status;
29 ANSI_STRING AnsiName;
30 PUNICODE_STRING UnicodeCache;
31 LPCWSTR UnicodeName = NULL;
32
33 /* Check for a name */
34 if (lpTimerName)
35 {
36 /* Use TEB Cache */
37 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
38
39 /* Convert to unicode */
40 RtlInitAnsiString(&AnsiName, lpTimerName);
41 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
42 if (!NT_SUCCESS(Status))
43 {
44 /* Conversion failed */
45 SetLastErrorByStatus(Status);
46 return NULL;
47 }
48
49 /* Otherwise, save the buffer */
50 UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
51 }
52
53 /* Call the Unicode API */
54 return CreateWaitableTimerExW(lpTimerAttributes,
55 UnicodeName,
56 dwFlags,
57 dwDesiredAccess);
58 }
59
60 /*
61 * @implemented
62 */
63 HANDLE
64 WINAPI
65 CreateWaitableTimerExW(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
66 IN LPCWSTR lpTimerName OPTIONAL,
67 IN DWORD dwFlags,
68 IN DWORD dwDesiredAccess)
69 {
70 NTSTATUS Status;
71 OBJECT_ATTRIBUTES LocalAttributes;
72 POBJECT_ATTRIBUTES ObjectAttributes;
73 HANDLE Handle;
74 UNICODE_STRING ObjectName;
75 TIMER_TYPE TimerType;
76
77 /* Now check if we got a name */
78 if (lpTimerName) RtlInitUnicodeString(&ObjectName, lpTimerName);
79
80 if (dwFlags & ~(CREATE_WAITABLE_TIMER_MANUAL_RESET))
81 {
82 SetLastError(ERROR_INVALID_PARAMETER);
83 return NULL;
84 }
85
86 TimerType = (dwFlags & CREATE_WAITABLE_TIMER_MANUAL_RESET) ? NotificationTimer : SynchronizationTimer;
87
88 /* Now convert the object attributes */
89 ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes,
90 lpTimerAttributes,
91 lpTimerName ? &ObjectName : NULL);
92
93 /* Create the timer */
94 Status = NtCreateTimer(&Handle,
95 (ACCESS_MASK)dwDesiredAccess,
96 ObjectAttributes,
97 TimerType);
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 /*
125 * @implemented
126 */
127 HANDLE
128 WINAPI
129 CreateWaitableTimerW(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
130 IN BOOL bManualReset,
131 IN LPCWSTR lpTimerName OPTIONAL)
132 {
133 DWORD dwFlags = 0;
134
135 if (bManualReset)
136 dwFlags |= CREATE_WAITABLE_TIMER_MANUAL_RESET;
137
138 return CreateWaitableTimerExW(lpTimerAttributes,
139 lpTimerName,
140 dwFlags,
141 TIMER_ALL_ACCESS);
142 }
143
144 /*
145 * @implemented
146 */
147 HANDLE
148 WINAPI
149 CreateWaitableTimerA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
150 IN BOOL bManualReset,
151 IN LPCSTR lpTimerName OPTIONAL)
152 {
153 DWORD dwFlags = 0;
154
155 if (bManualReset)
156 dwFlags |= CREATE_WAITABLE_TIMER_MANUAL_RESET;
157
158 return CreateWaitableTimerExA(lpTimerAttributes,
159 lpTimerName,
160 dwFlags,
161 TIMER_ALL_ACCESS);
162 }
163
164 /*
165 * @implemented
166 */
167 HANDLE
168 WINAPI
169 OpenWaitableTimerW(IN DWORD dwDesiredAccess,
170 IN BOOL bInheritHandle,
171 IN LPCWSTR lpTimerName)
172 {
173 OBJECT_ATTRIBUTES ObjectAttributes;
174 UNICODE_STRING ObjectName;
175 NTSTATUS Status;
176 HANDLE Handle;
177
178 /* Make sure we got a name */
179 if (!lpTimerName)
180 {
181 /* Fail without one */
182 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
183 return NULL;
184 }
185
186 /* Initialize the object name and attributes */
187 RtlInitUnicodeString(&ObjectName, lpTimerName);
188 InitializeObjectAttributes(&ObjectAttributes,
189 &ObjectName,
190 bInheritHandle ? OBJ_INHERIT : 0,
191 hBaseDir,
192 NULL);
193
194 /* Open the timer */
195 Status = NtOpenTimer(&Handle, dwDesiredAccess, &ObjectAttributes);
196 if (!NT_SUCCESS(Status))
197 {
198 /* Convert the status and fail */
199 SetLastErrorByStatus(Status);
200 return NULL;
201 }
202
203 /* Return the handle */
204 return Handle;
205 }
206
207 /*
208 * @implemented
209 */
210 HANDLE
211 WINAPI
212 OpenWaitableTimerA(IN DWORD dwDesiredAccess,
213 IN BOOL bInheritHandle,
214 IN LPCSTR lpTimerName)
215 {
216 NTSTATUS Status;
217 ANSI_STRING AnsiName;
218 PUNICODE_STRING UnicodeCache;
219
220 /* Check for a name */
221 if (lpTimerName)
222 {
223 /* Use TEB Cache */
224 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
225
226 /* Convert to unicode */
227 RtlInitAnsiString(&AnsiName, lpTimerName);
228 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
229 if (!NT_SUCCESS(Status))
230 {
231 /* Conversion failed */
232 SetLastErrorByStatus(Status);
233 return NULL;
234 }
235 }
236 else
237 {
238 /* We need a name */
239 SetLastError(ERROR_INVALID_PARAMETER);
240 return NULL;
241 }
242
243 /* Call the Unicode API */
244 return OpenWaitableTimerW(dwDesiredAccess,
245 bInheritHandle,
246 (LPCWSTR)UnicodeCache->Buffer);
247 }
248
249 /*
250 * @implemented
251 */
252 BOOL
253 WINAPI
254 SetWaitableTimer(IN HANDLE hTimer,
255 IN const LARGE_INTEGER *pDueTime,
256 IN LONG lPeriod,
257 IN PTIMERAPCROUTINE pfnCompletionRoutine OPTIONAL,
258 IN OPTIONAL LPVOID lpArgToCompletionRoutine,
259 IN BOOL fResume)
260 {
261 NTSTATUS Status;
262
263 /* Set the timer */
264 Status = NtSetTimer(hTimer,
265 (PLARGE_INTEGER)pDueTime,
266 (PTIMER_APC_ROUTINE)pfnCompletionRoutine,
267 lpArgToCompletionRoutine,
268 (BOOLEAN)fResume,
269 lPeriod,
270 NULL);
271 if (NT_SUCCESS(Status)) return TRUE;
272
273 /* If we got here, then we failed */
274 SetLastErrorByStatus(Status);
275 return FALSE;
276 }
277
278 /*
279 * @implemented
280 */
281 BOOL
282 WINAPI
283 CancelWaitableTimer(IN HANDLE hTimer)
284 {
285 NTSTATUS Status;
286
287 /* Cancel the timer */
288 Status = NtCancelTimer(hTimer, NULL);
289 if (NT_SUCCESS(Status)) return TRUE;
290
291 /* If we got here, then we failed */
292 SetLastErrorByStatus(Status);
293 return FALSE;
294 }
295
296 /* EOF */