2 * Win32 waitable timers
4 * Copyright 1999 Alexandre Julliard
10 #include "wine/unicode.h"
11 #include "file.h" /* for FILETIME routines */
15 /***********************************************************************
16 * CreateWaitableTimerA (KERNEL32.861)
18 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
21 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
24 SetLastError( ERROR_FILENAME_EXCED_RANGE );
29 struct create_timer_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
32 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
33 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
35 server_call( REQ_CREATE_TIMER );
39 if (ret == -1) ret = 0; /* must return 0 on failure, not -1 */
44 /***********************************************************************
45 * CreateWaitableTimerW (KERNEL32.862)
47 HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
50 DWORD len = name ? strlenW(name) : 0;
53 SetLastError( ERROR_FILENAME_EXCED_RANGE );
58 struct create_timer_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
61 req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
62 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
64 server_call( REQ_CREATE_TIMER );
68 if (ret == -1) ret = 0; /* must return 0 on failure, not -1 */
73 /***********************************************************************
74 * OpenWaitableTimerA (KERNEL32.881)
76 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
79 DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0;
82 SetLastError( ERROR_FILENAME_EXCED_RANGE );
87 struct open_timer_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
90 req->inherit = inherit;
91 if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len );
92 server_call( REQ_OPEN_TIMER );
96 if (ret == -1) ret = 0; /* must return 0 on failure, not -1 */
101 /***********************************************************************
102 * OpenWaitableTimerW (KERNEL32.882)
104 HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
107 DWORD len = name ? strlenW(name) : 0;
110 SetLastError( ERROR_FILENAME_EXCED_RANGE );
115 struct open_timer_request *req = server_alloc_req( sizeof(*req), len * sizeof(WCHAR) );
117 req->access = access;
118 req->inherit = inherit;
119 memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) );
120 server_call( REQ_OPEN_TIMER );
124 if (ret == -1) ret = 0; /* must return 0 on failure, not -1 */
129 /***********************************************************************
130 * SetWaitableTimer (KERNEL32.894)
132 BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
133 PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
139 if (when->s.HighPart < 0) /* relative time */
142 GetSystemTimeAsFileTime( &ft );
143 low = ft.dwLowDateTime;
144 ft.dwLowDateTime -= when->s.LowPart;
145 ft.dwHighDateTime -= when->s.HighPart;
146 if (low < ft.dwLowDateTime) ft.dwHighDateTime--; /* overflow */
148 else /* absolute time */
150 ft.dwLowDateTime = when->s.LowPart;
151 ft.dwHighDateTime = when->s.HighPart;
156 struct set_timer_request *req = server_alloc_req( sizeof(*req), 0 );
158 if (!ft.dwLowDateTime && !ft.dwHighDateTime)
160 /* special case to start timeout on now+period without too many calculations */
166 req->sec = DOSFS_FileTimeToUnixTime( &ft, &remainder );
167 req->usec = remainder / 10; /* convert from 100-ns to us units */
169 req->handle = handle;
170 req->period = period;
171 req->callback = callback;
173 if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */
174 ret = !server_call( REQ_SET_TIMER );
181 /***********************************************************************
182 * CancelWaitableTimer (KERNEL32.857)
184 BOOL WINAPI CancelWaitableTimer( HANDLE handle )
189 struct cancel_timer_request *req = server_alloc_req( sizeof(*req), 0 );
190 req->handle = handle;
191 ret = !server_call( REQ_CANCEL_TIMER );