Added LGPL standard comment, and copyright notices where necessary.
[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 <assert.h>
22 #include <string.h>
23 #include "winerror.h"
24 #include "winnls.h"
25 #include "wine/unicode.h"
26 #include "file.h"  /* for FILETIME routines */
27 #include "wine/server.h"
28
29
30 /***********************************************************************
31  *           CreateWaitableTimerA    (KERNEL32.@)
32  */
33 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
34 {
35     WCHAR buffer[MAX_PATH];
36
37     if (!name) return CreateWaitableTimerW( sa, manual, NULL );
38
39     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
40     {
41         SetLastError( ERROR_FILENAME_EXCED_RANGE );
42         return 0;
43     }
44     return CreateWaitableTimerW( sa, manual, buffer );
45 }
46
47
48 /***********************************************************************
49  *           CreateWaitableTimerW    (KERNEL32.@)
50  */
51 HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
52 {
53     HANDLE ret;
54     DWORD len = name ? strlenW(name) : 0;
55     if (len >= MAX_PATH)
56     {
57         SetLastError( ERROR_FILENAME_EXCED_RANGE );
58         return 0;
59     }
60     SERVER_START_REQ( create_timer )
61     {
62         req->manual  = manual;
63         req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
64         wine_server_add_data( req, name, len * sizeof(WCHAR) );
65         SetLastError(0);
66         wine_server_call_err( req );
67         ret = reply->handle;
68     }
69     SERVER_END_REQ;
70     return ret;
71 }
72
73
74 /***********************************************************************
75  *           OpenWaitableTimerA    (KERNEL32.@)
76  */
77 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
78 {
79     WCHAR buffer[MAX_PATH];
80
81     if (!name) return OpenWaitableTimerW( access, inherit, NULL );
82
83     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
84     {
85         SetLastError( ERROR_FILENAME_EXCED_RANGE );
86         return 0;
87     }
88     return OpenWaitableTimerW( access, inherit, buffer );
89 }
90
91
92 /***********************************************************************
93  *           OpenWaitableTimerW    (KERNEL32.@)
94  */
95 HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
96 {
97     HANDLE ret;
98     DWORD len = name ? strlenW(name) : 0;
99     if (len >= MAX_PATH)
100     {
101         SetLastError( ERROR_FILENAME_EXCED_RANGE );
102         return 0;
103     }
104     SERVER_START_REQ( open_timer )
105     {
106         req->access  = access;
107         req->inherit = inherit;
108         wine_server_add_data( req, name, len * sizeof(WCHAR) );
109         wine_server_call_err( req );
110         ret = reply->handle;
111     }
112     SERVER_END_REQ;
113     return ret;
114 }
115
116
117 /***********************************************************************
118  *           SetWaitableTimer    (KERNEL32.@)
119  */
120 BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
121                               PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
122 {
123     BOOL ret;
124     LARGE_INTEGER exp = *when;
125
126     if (exp.s.HighPart < 0)  /* relative time */
127     {
128         LARGE_INTEGER now;
129         NtQuerySystemTime( &now );
130         exp.QuadPart = RtlLargeIntegerSubtract( now.QuadPart, exp.QuadPart );
131     }
132
133     SERVER_START_REQ( set_timer )
134     {
135         if (!exp.s.LowPart && !exp.s.HighPart)
136         {
137             /* special case to start timeout on now+period without too many calculations */
138             req->sec  = 0;
139             req->usec = 0;
140         }
141         else
142         {
143             DWORD remainder;
144             req->sec  = DOSFS_FileTimeToUnixTime( (FILETIME *)&exp, &remainder );
145             req->usec = remainder / 10;  /* convert from 100-ns to us units */
146         }
147         req->handle   = handle;
148         req->period   = period;
149         req->callback = callback;
150         req->arg      = arg;
151         if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */
152         ret = !wine_server_call_err( req );
153     }
154     SERVER_END_REQ;
155     return ret;
156 }
157
158
159 /***********************************************************************
160  *           CancelWaitableTimer    (KERNEL32.@)
161  */
162 BOOL WINAPI CancelWaitableTimer( HANDLE handle )
163 {
164     BOOL ret;
165     SERVER_START_REQ( cancel_timer )
166     {
167         req->handle = handle;
168         ret = !wine_server_call_err( req );
169     }
170     SERVER_END_REQ;
171     return ret;
172 }