Added a few missing stubs to KERNEL32 and USER32.
[wine.git] / dlls / kernel / time.c
blobd2b3a2b8f556ea465ac55e41a5df9daa888f388b
1 /*
2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
5 */
7 #include <string.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <sys/time.h>
11 #include <sys/times.h>
12 #include "file.h"
13 #include "ntddk.h"
14 #include "winerror.h"
15 #include "winnls.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(win32);
20 /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */
21 #define SETTIME_MAX_ADJUST 120
23 /* TIME_GetBias: helper function calculates delta local time from UTC */
24 static int TIME_GetBias( time_t utc, int *pdaylight)
26 struct tm *ptm = localtime(&utc);
27 *pdaylight = ptm->tm_isdst; /* daylight for local timezone */
28 ptm = gmtime(&utc);
29 ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */
30 return (int)(utc-mktime(ptm));
34 /***********************************************************************
35 * SetLocalTime (KERNEL32.655)
37 * Sets the local time using current time zone and daylight
38 * savings settings.
40 * RETURNS
42 * True if the time was set, false if the time was invalid or the
43 * necessary permissions were not held.
45 BOOL WINAPI SetLocalTime(
46 const SYSTEMTIME *systime) /* [in] The desired local time. */
48 struct timeval tv;
49 struct tm t;
50 time_t sec;
51 time_t oldsec=time(NULL);
52 int err;
54 /* get the number of seconds */
55 t.tm_sec = systime->wSecond;
56 t.tm_min = systime->wMinute;
57 t.tm_hour = systime->wHour;
58 t.tm_mday = systime->wDay;
59 t.tm_mon = systime->wMonth - 1;
60 t.tm_year = systime->wYear - 1900;
61 t.tm_isdst = -1;
62 sec = mktime (&t);
64 /* set the new time */
65 tv.tv_sec = sec;
66 tv.tv_usec = systime->wMilliseconds * 1000;
68 /* error and sanity check*/
69 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
70 err = 1;
71 SetLastError(ERROR_INVALID_PARAMETER);
72 } else {
73 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
74 if(err == 0)
75 return TRUE;
76 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
78 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
79 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
80 systime->wMinute, systime->wSecond,
81 sec-oldsec, err == -1 ? "No Permission" :
82 sec==(time_t)-1 ? "" : "is too large." );
83 return FALSE;
87 /***********************************************************************
88 * GetSystemTimeAdjustment (KERNEL32.407)
90 * Indicates the period between clock interrupt and the amount the clock
91 * is adjusted each interrupt so as to keep it insync with an external source.
93 * RETURNS
95 * Always returns true.
97 * BUGS
99 * Only the special case of disabled time adjustments is supported.
100 * (also the signature is wrong it should have a return type of BOOL)
102 DWORD WINAPI GetSystemTimeAdjustment(
103 LPDWORD lpTimeAdjustment, /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
104 LPDWORD lpTimeIncrement, /* [out] The time between clock interupts in 100's of nanoseconds. */
105 LPBOOL lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
107 *lpTimeAdjustment = 0;
108 *lpTimeIncrement = 0;
109 *lpTimeAdjustmentDisabled = TRUE;
110 return TRUE;
114 /***********************************************************************
115 * SetSystemTime (KERNEL32.665)
117 * Sets the system time (utc).
119 * RETURNS
121 * True if the time was set, false if the time was invalid or the
122 * necessary permissions were not held.
124 BOOL WINAPI SetSystemTime(
125 const SYSTEMTIME *systime) /* [in] The desired system time. */
127 struct timeval tv;
128 struct timezone tz;
129 struct tm t;
130 time_t sec, oldsec;
131 int dst, bias;
132 int err;
134 /* call gettimeofday to get the current timezone */
135 gettimeofday(&tv, &tz);
136 oldsec=tv.tv_sec;
137 /* get delta local time from utc */
138 bias=TIME_GetBias(oldsec,&dst);
140 /* get the number of seconds */
141 t.tm_sec = systime->wSecond;
142 t.tm_min = systime->wMinute;
143 t.tm_hour = systime->wHour;
144 t.tm_mday = systime->wDay;
145 t.tm_mon = systime->wMonth - 1;
146 t.tm_year = systime->wYear - 1900;
147 t.tm_isdst = dst;
148 sec = mktime (&t);
149 /* correct for timezone and daylight */
150 sec += bias;
152 /* set the new time */
153 tv.tv_sec = sec;
154 tv.tv_usec = systime->wMilliseconds * 1000;
156 /* error and sanity check*/
157 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
158 err = 1;
159 SetLastError(ERROR_INVALID_PARAMETER);
160 } else {
161 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
162 if(err == 0)
163 return TRUE;
164 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
166 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
167 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
168 systime->wMinute, systime->wSecond,
169 sec-oldsec, err == -1 ? "No Permission" :
170 sec==(time_t)-1 ? "" : "is too large." );
171 return FALSE;
175 /***********************************************************************
176 * GetTimeZoneInformation (KERNEL32.424)
178 * Fills in the a time zone information structure with values based on
179 * the current local time.
181 * RETURNS
183 * The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
185 DWORD WINAPI GetTimeZoneInformation(
186 LPTIME_ZONE_INFORMATION tzinfo) /* [out] The time zone structure to be filled in. */
188 time_t gmt;
189 int bias, daylight;
191 memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
193 gmt = time(NULL);
194 bias=TIME_GetBias(gmt,&daylight);
196 tzinfo->Bias = -bias / 60;
197 tzinfo->StandardBias = 0;
198 tzinfo->DaylightBias = -60;
200 return TIME_ZONE_ID_STANDARD;
204 /***********************************************************************
205 * SetTimeZoneInformation (KERNEL32.673)
207 * Set the local time zone with values based on the time zone structure.
209 * RETURNS
211 * True on successful setting of the time zone.
213 * BUGS
215 * Use the obsolete unix timezone structure and tz_dsttime member.
217 BOOL WINAPI SetTimeZoneInformation(
218 const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
220 struct timezone tz;
222 tz.tz_minuteswest = tzinfo->Bias;
223 #ifdef DST_NONE
224 tz.tz_dsttime = DST_NONE;
225 #else
226 tz.tz_dsttime = 0;
227 #endif
228 return !settimeofday(NULL, &tz);
232 /***********************************************************************
233 * SystemTimeToTzSpecificLocalTime (KERNEL32.683)
235 * Converts the system time (utc) to the local time in the specified time zone.
237 * RETURNS
239 * Returns true when the local time was calculated.
241 * BUGS
243 * Does not handle daylight savings time adjustments correctly.
245 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
246 LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
247 LPSYSTEMTIME lpUniversalTime, /* [in] The utc time to base local time on. */
248 LPSYSTEMTIME lpLocalTime) /* [out] The local time in the time zone. */
250 FIXME(":stub\n");
251 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
252 return FALSE;
256 /***********************************************************************
257 * GetSystemTimeAsFileTime (KERNEL32.408)
259 * Fills in a file time structure with the current time in UTC format.
261 VOID WINAPI GetSystemTimeAsFileTime(
262 LPFILETIME time) /* [out] The file time struct to be filled with the system time. */
264 NtQuerySystemTime( (LARGE_INTEGER *)time );
268 /*********************************************************************
269 * TIME_ClockTimeToFileTime (olorin@fandra.org, 20-Sep-1998)
271 * Used by GetProcessTimes to convert clock_t into FILETIME.
273 * Differences to UnixTimeToFileTime:
274 * 1) Divided by CLK_TCK
275 * 2) Time is relative. There is no 'starting date', so there is
276 * no need in offset correction, like in UnixTimeToFileTime
278 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
280 LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
281 ((LARGE_INTEGER *)filetime)->QuadPart = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
284 /*********************************************************************
285 * GetProcessTimes (KERNEL32.378)
287 * Returns the user and kernel execution times of a process,
288 * along with the creation and exit times if known.
290 * olorin@fandra.org:
291 * Would be nice to subtract the cpu time, used by Wine at startup.
292 * Also, there is a need to separate times used by different applications.
294 * RETURNS
296 * Always returns true.
298 * BUGS
300 * lpCreationTime, lpExitTime are NOT INITIALIZED.
302 BOOL WINAPI GetProcessTimes(
303 HANDLE hprocess, /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
304 LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
305 LPFILETIME lpExitTime, /* [out] The exit time of the process if exited. */
306 LPFILETIME lpKernelTime, /* [out] The time spent in kernal routines in 100's of nanoseconds. */
307 LPFILETIME lpUserTime) /* [out] The time spent in user routines in 100's of nanoseconds. */
309 struct tms tms;
311 times(&tms);
312 TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
313 TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
314 return TRUE;
317 /*********************************************************************
318 * GetCalendarInfoA (KERNEL32)
321 int WINAPI GetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType,
322 LPSTR lpCalData, int cchData, LPDWORD lpValue)
324 FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): stub\n",
325 Locale, Calendar, CalType, lpCalData, cchData, lpValue);
326 return 0;
329 /*********************************************************************
330 * GetCalendarInfoW (KERNEL32)
333 int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
334 LPWSTR lpCalData, int cchData, LPDWORD lpValue)
336 FIXME("(%08lx,%08lx,%08lx,%p,%d,%p): stub\n",
337 Locale, Calendar, CalType, lpCalData, cchData, lpValue);
338 return 0;
341 /*********************************************************************
342 * SetCalendarInfoA (KERNEL32)
345 int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
347 FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
348 Locale, Calendar, CalType, debugstr_a(lpCalData));
349 return 0;
352 /*********************************************************************
353 * SetCalendarInfoW (KERNEL32)
356 int WINAPI SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
358 FIXME("(%08lx,%08lx,%08lx,%s): stub\n",
359 Locale, Calendar, CalType, debugstr_w(lpCalData));
360 return 0;