Misc fixes in LISTVIEW_SetImageList, LISTVIEW_SetItemCount,
[wine.git] / dlls / kernel / time.c
blob933e74bf901a03bdc281191d59b0d5aaae42c066
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 "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(win32);
19 /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */
20 #define SETTIME_MAX_ADJUST 120
22 /* TIME_GetBias: helper function calculates delta local time from UTC */
23 static int TIME_GetBias( time_t utc, int *pdaylight)
25 struct tm *ptm = localtime(&utc);
26 *pdaylight = ptm->tm_isdst; /* daylight for local timezone */
27 ptm = gmtime(&utc);
28 ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */
29 return (int)(utc-mktime(ptm));
33 /***********************************************************************
34 * SetLocalTime (KERNEL32.655)
36 * Sets the local time using current time zone and daylight
37 * savings settings.
39 * RETURNS
41 * True if the time was set, false if the time was invalid or the
42 * necessary permissions were not held.
44 BOOL WINAPI SetLocalTime( const SYSTEMTIME *systime /* The desired local time. */ )
46 struct timeval tv;
47 struct tm t;
48 time_t sec;
49 time_t oldsec=time(NULL);
50 int err;
52 /* get the number of seconds */
53 t.tm_sec = systime->wSecond;
54 t.tm_min = systime->wMinute;
55 t.tm_hour = systime->wHour;
56 t.tm_mday = systime->wDay;
57 t.tm_mon = systime->wMonth - 1;
58 t.tm_year = systime->wYear - 1900;
59 t.tm_isdst = -1;
60 sec = mktime (&t);
62 /* set the new time */
63 tv.tv_sec = sec;
64 tv.tv_usec = systime->wMilliseconds * 1000;
66 /* error and sanity check*/
67 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
68 err = 1;
69 SetLastError(ERROR_INVALID_PARAMETER);
70 } else {
71 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
72 if(err == 0)
73 return TRUE;
74 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
76 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
77 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
78 systime->wMinute, systime->wSecond,
79 sec-oldsec, err == -1 ? "No Permission" :
80 sec==(time_t)-1 ? "" : "is too large." );
81 return FALSE;
85 /***********************************************************************
86 * GetSystemTimeAdjustment (KERNEL32.407)
88 * Indicates the period between clock interrupt and the amount the clock
89 * is adjusted each interrupt so as to keep it insync with an external source.
91 * RETURNS
93 * Always returns true.
95 * BUGS
97 * Only the special case of disabled time adjustments is supported.
98 * (also the signature is wrong it should have a return type of BOOL)
100 DWORD WINAPI GetSystemTimeAdjustment(
101 LPDWORD lpTimeAdjustment, /* The clock adjustment per interupt in 100's of nanoseconds. */
102 LPDWORD lpTimeIncrement, /* The time between clock interupts in 100's of nanoseconds. */
103 LPBOOL lpTimeAdjustmentDisabled /* The clock synchonisation has been disabled. */ )
105 *lpTimeAdjustment = 0;
106 *lpTimeIncrement = 0;
107 *lpTimeAdjustmentDisabled = TRUE;
108 return TRUE;
112 /***********************************************************************
113 * SetSystemTime (KERNEL32.507)
115 * Sets the system time (utc).
117 * RETURNS
119 * True if the time was set, false if the time was invalid or the
120 * necessary permissions were not held.
122 BOOL WINAPI SetSystemTime(
123 const SYSTEMTIME *systime /* The desired system time. */)
125 struct timeval tv;
126 struct timezone tz;
127 struct tm t;
128 time_t sec, oldsec;
129 int dst, bias;
130 int err;
132 /* call gettimeofday to get the current timezone */
133 gettimeofday(&tv, &tz);
134 oldsec=tv.tv_sec;
135 /* get delta local time from utc */
136 bias=TIME_GetBias(oldsec,&dst);
138 /* get the number of seconds */
139 t.tm_sec = systime->wSecond;
140 t.tm_min = systime->wMinute;
141 t.tm_hour = systime->wHour;
142 t.tm_mday = systime->wDay;
143 t.tm_mon = systime->wMonth - 1;
144 t.tm_year = systime->wYear - 1900;
145 t.tm_isdst = dst;
146 sec = mktime (&t);
147 /* correct for timezone and daylight */
148 sec += bias;
150 /* set the new time */
151 tv.tv_sec = sec;
152 tv.tv_usec = systime->wMilliseconds * 1000;
154 /* error and sanity check*/
155 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
156 err = 1;
157 SetLastError(ERROR_INVALID_PARAMETER);
158 } else {
159 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
160 if(err == 0)
161 return TRUE;
162 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
164 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
165 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
166 systime->wMinute, systime->wSecond,
167 sec-oldsec, err == -1 ? "No Permission" :
168 sec==(time_t)-1 ? "" : "is too large." );
169 return FALSE;
173 /***********************************************************************
174 * GetTimeZoneInformation (KERNEL32.302)
176 * Fills in the a time zone information structure with values based on
177 * the current local time.
179 * RETURNS
181 * The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
183 DWORD WINAPI GetTimeZoneInformation(
184 LPTIME_ZONE_INFORMATION tzinfo /* The time zone structure to be filled in. */)
186 time_t gmt;
187 int bias, daylight;
189 memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
191 gmt = time(NULL);
192 bias=TIME_GetBias(gmt,&daylight);
194 tzinfo->Bias = -bias / 60;
195 tzinfo->StandardBias = 0;
196 tzinfo->DaylightBias = -60;
198 return TIME_ZONE_ID_STANDARD;
202 /***********************************************************************
203 * SetTimeZoneInformation (KERNEL32.515)
205 * Set the local time zone with values based on the time zone structure.
207 * RETURNS
209 * True on successful setting of the time zone.
211 * BUGS
213 * Use the obsolete unix timezone structure and tz_dsttime member.
215 BOOL WINAPI SetTimeZoneInformation(
216 const LPTIME_ZONE_INFORMATION tzinfo /* The new time zone. */)
218 struct timezone tz;
220 tz.tz_minuteswest = tzinfo->Bias;
221 #ifdef DST_NONE
222 tz.tz_dsttime = DST_NONE;
223 #else
224 tz.tz_dsttime = 0;
225 #endif
226 return !settimeofday(NULL, &tz);
230 /***********************************************************************
231 * SystemTimeToTzSpecificLocalTime (KERNEL32.683)
233 * Converts the system time (utc) to the local time in the specified time zone.
235 * RETURNS
237 * Returns true when the local time was calculated.
239 * BUGS
241 * Does not handle daylight savings time adjustments correctly.
243 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
244 LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* The desired time zone. */
245 LPSYSTEMTIME lpUniversalTime, /* The utc time to base local time on. */
246 LPSYSTEMTIME lpLocalTime /* The local time in the time zone. */)
248 FIXME(":stub\n");
249 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
250 return FALSE;
254 /***********************************************************************
255 * GetSystemTimeAsFileTime (KERNEL32)
257 * Fills in a file time structure with the current time in UTC format.
259 VOID WINAPI GetSystemTimeAsFileTime(
260 LPFILETIME time /* The file time struct to be filled with the system time. */)
262 NtQuerySystemTime( (LARGE_INTEGER *)time );
266 /*********************************************************************
267 * TIME_ClockTimeToFileTime (olorin@fandra.org, 20-Sep-1998)
269 * Used by GetProcessTimes to convert clock_t into FILETIME.
271 * Differences to UnixTimeToFileTime:
272 * 1) Divided by CLK_TCK
273 * 2) Time is relative. There is no 'starting date', so there is
274 * no need in offset correction, like in UnixTimeToFileTime
276 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
278 LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
279 ((LARGE_INTEGER *)filetime)->QuadPart = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
282 /*********************************************************************
283 * GetProcessTimes [KERNEL32.262]
285 * Returns the user and kernel execution times of a process,
286 * along with the creation and exit times if known.
288 * olorin@fandra.org:
289 * Would be nice to subtract the cpu time, used by Wine at startup.
290 * Also, there is a need to separate times used by different applications.
292 * RETURNS
294 * Always returns true.
296 * BUGS
298 * lpCreationTime, lpExitTime are NOT INITIALIZED.
300 BOOL WINAPI GetProcessTimes(
301 HANDLE hprocess, /* The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
302 LPFILETIME lpCreationTime, /* The creation time of the process. */
303 LPFILETIME lpExitTime, /* The exit time of the process if exited. */
304 LPFILETIME lpKernelTime, /* The time spent in kernal routines in 100's of nanoseconds. */
305 LPFILETIME lpUserTime /* The time spent in user routines in 100's of nanoseconds. */)
307 struct tms tms;
309 times(&tms);
310 TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
311 TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);
312 return TRUE;