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