Merged wine_call_to_16_long and wine_call_to_16_short into a single
[wine] / scheduler / timer.c
1 /*
2  * Win32 waitable timers
3  *
4  * Copyright 1999 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <assert.h>
25 #include <string.h>
26 #include "winerror.h"
27 #include "winnls.h"
28 #include "wine/unicode.h"
29 #include "file.h"  /* for FILETIME routines */
30 #include "wine/server.h"
31 #include "wine/debug.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(timer);
34
35
36 /***********************************************************************
37  *           CreateWaitableTimerA    (KERNEL32.@)
38  */
39 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
40 {
41     WCHAR buffer[MAX_PATH];
42
43     if (!name) return CreateWaitableTimerW( sa, manual, NULL );
44
45     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
46     {
47         SetLastError( ERROR_FILENAME_EXCED_RANGE );
48         return 0;
49     }
50     return CreateWaitableTimerW( sa, manual, buffer );
51 }
52
53
54 /***********************************************************************
55  *           CreateWaitableTimerW    (KERNEL32.@)
56  */
57 HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
58 {
59     HANDLE ret;
60     DWORD len = name ? strlenW(name) : 0;
61     if (len >= MAX_PATH)
62     {
63         SetLastError( ERROR_FILENAME_EXCED_RANGE );
64         return 0;
65     }
66     SERVER_START_REQ( create_timer )
67     {
68         req->manual  = manual;
69         req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
70         wine_server_add_data( req, name, len * sizeof(WCHAR) );
71         SetLastError(0);
72         wine_server_call_err( req );
73         ret = reply->handle;
74     }
75     SERVER_END_REQ;
76     return ret;
77 }
78
79
80 /***********************************************************************
81  *           OpenWaitableTimerA    (KERNEL32.@)
82  */
83 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
84 {
85     WCHAR buffer[MAX_PATH];
86
87     if (!name) return OpenWaitableTimerW( access, inherit, NULL );
88
89     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
90     {
91         SetLastError( ERROR_FILENAME_EXCED_RANGE );
92         return 0;
93     }
94     return OpenWaitableTimerW( access, inherit, buffer );
95 }
96
97
98 /***********************************************************************
99  *           OpenWaitableTimerW    (KERNEL32.@)
100  */
101 HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
102 {
103     HANDLE ret;
104     DWORD len = name ? strlenW(name) : 0;
105     if (len >= MAX_PATH)
106     {
107         SetLastError( ERROR_FILENAME_EXCED_RANGE );
108         return 0;
109     }
110     SERVER_START_REQ( open_timer )
111     {
112         req->access  = access;
113         req->inherit = inherit;
114         wine_server_add_data( req, name, len * sizeof(WCHAR) );
115         wine_server_call_err( req );
116         ret = reply->handle;
117     }
118     SERVER_END_REQ;
119     return ret;
120 }
121
122
123 /***********************************************************************
124  *           SetWaitableTimer    (KERNEL32.@)
125  */
126 BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
127                               PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
128 {
129     BOOL ret;
130     LARGE_INTEGER exp = *when;
131
132     if (exp.s.HighPart < 0)  /* relative time */
133     {
134         LARGE_INTEGER now;
135         NtQuerySystemTime( &now );
136         exp.QuadPart = RtlLargeIntegerSubtract( now.QuadPart, exp.QuadPart );
137     }
138
139     SERVER_START_REQ( set_timer )
140     {
141         if (!exp.s.LowPart && !exp.s.HighPart)
142         {
143             /* special case to start timeout on now+period without too many calculations */
144             req->sec  = 0;
145             req->usec = 0;
146         }
147         else
148         {
149             DWORD remainder;
150             req->sec  = DOSFS_FileTimeToUnixTime( (FILETIME *)&exp, &remainder );
151             req->usec = remainder / 10;  /* convert from 100-ns to us units */
152         }
153         req->handle   = handle;
154         req->period   = period;
155         req->callback = callback;
156         req->arg      = arg;
157         if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */
158         ret = !wine_server_call_err( req );
159     }
160     SERVER_END_REQ;
161     return ret;
162 }
163
164
165 /***********************************************************************
166  *           CancelWaitableTimer    (KERNEL32.@)
167  */
168 BOOL WINAPI CancelWaitableTimer( HANDLE handle )
169 {
170     BOOL ret;
171     SERVER_START_REQ( cancel_timer )
172     {
173         req->handle = handle;
174         ret = !wine_server_call_err( req );
175     }
176     SERVER_END_REQ;
177     return ret;
178 }
179
180
181 /***********************************************************************
182  *           CreateTimerQueueTimer  (KERNEL32.@)
183  *
184  * Creates a timer-queue timer. This timer expires at the specified due
185  * time (in ms), then after every specified period (in ms). When the timer
186  * expires, the callback function is called.
187  *
188  * RETURNS
189  *   nonzero on success or zero on faillure
190  *
191  * BUGS
192  *   Unimplemented
193  */
194 BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue,
195                                    WAITORTIMERCALLBACK Callback, PVOID Parameter,
196                                    DWORD DueTime, DWORD Period, ULONG Flags )
197 {
198     FIXME("stub\n");
199     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
200     return TRUE;
201 }
202
203 /***********************************************************************
204  *           DeleteTimerQueueTimer  (KERNEL32.@)
205  *
206  * Cancels a timer-queue timer. 
207  *
208  * RETURNS
209  *   nonzero on success or zero on faillure
210  *
211  * BUGS
212  *   Unimplemented
213  */
214 BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer,
215                                    HANDLE CompletionEvent )
216 {
217     FIXME("stub\n");
218     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
219     return TRUE;
220 }