2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
11 #include <sys/times.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 */
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
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(
45 const SYSTEMTIME *systime) /* [in] The desired local time. */
50 time_t oldsec=time(NULL);
53 /* get the number of seconds */
54 t.tm_sec = systime->wSecond;
55 t.tm_min = systime->wMinute;
56 t.tm_hour = systime->wHour;
57 t.tm_mday = systime->wDay;
58 t.tm_mon = systime->wMonth - 1;
59 t.tm_year = systime->wYear - 1900;
63 /* set the new time */
65 tv.tv_usec = systime->wMilliseconds * 1000;
67 /* error and sanity check*/
68 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
70 SetLastError(ERROR_INVALID_PARAMETER);
72 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
75 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
77 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
78 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
79 systime->wMinute, systime->wSecond,
80 sec-oldsec, err == -1 ? "No Permission" :
81 sec==(time_t)-1 ? "" : "is too large." );
86 /***********************************************************************
87 * GetSystemTimeAdjustment (KERNEL32.407)
89 * Indicates the period between clock interrupt and the amount the clock
90 * is adjusted each interrupt so as to keep it insync with an external source.
94 * Always returns true.
98 * Only the special case of disabled time adjustments is supported.
99 * (also the signature is wrong it should have a return type of BOOL)
101 DWORD WINAPI GetSystemTimeAdjustment(
102 LPDWORD lpTimeAdjustment, /* [out] The clock adjustment per interupt in 100's of nanoseconds. */
103 LPDWORD lpTimeIncrement, /* [out] The time between clock interupts in 100's of nanoseconds. */
104 LPBOOL lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */
106 *lpTimeAdjustment = 0;
107 *lpTimeIncrement = 0;
108 *lpTimeAdjustmentDisabled = TRUE;
113 /***********************************************************************
114 * SetSystemTime (KERNEL32.665)
116 * Sets the system time (utc).
120 * True if the time was set, false if the time was invalid or the
121 * necessary permissions were not held.
123 BOOL WINAPI SetSystemTime(
124 const SYSTEMTIME *systime) /* [in] The desired system time. */
133 /* call gettimeofday to get the current timezone */
134 gettimeofday(&tv, &tz);
136 /* get delta local time from utc */
137 bias=TIME_GetBias(oldsec,&dst);
139 /* get the number of seconds */
140 t.tm_sec = systime->wSecond;
141 t.tm_min = systime->wMinute;
142 t.tm_hour = systime->wHour;
143 t.tm_mday = systime->wDay;
144 t.tm_mon = systime->wMonth - 1;
145 t.tm_year = systime->wYear - 1900;
148 /* correct for timezone and daylight */
151 /* set the new time */
153 tv.tv_usec = systime->wMilliseconds * 1000;
155 /* error and sanity check*/
156 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
158 SetLastError(ERROR_INVALID_PARAMETER);
160 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
163 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
165 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
166 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
167 systime->wMinute, systime->wSecond,
168 sec-oldsec, err == -1 ? "No Permission" :
169 sec==(time_t)-1 ? "" : "is too large." );
174 /***********************************************************************
175 * GetTimeZoneInformation (KERNEL32.424)
177 * Fills in the a time zone information structure with values based on
178 * the current local time.
182 * The daylight savings time standard or TIME_ZONE_ID_INVALID if the call failed.
184 DWORD WINAPI GetTimeZoneInformation(
185 LPTIME_ZONE_INFORMATION tzinfo) /* [out] The time zone structure to be filled in. */
190 memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
193 bias=TIME_GetBias(gmt,&daylight);
195 tzinfo->Bias = -bias / 60;
196 tzinfo->StandardBias = 0;
197 tzinfo->DaylightBias = -60;
199 return TIME_ZONE_ID_STANDARD;
203 /***********************************************************************
204 * SetTimeZoneInformation (KERNEL32.673)
206 * Set the local time zone with values based on the time zone structure.
210 * True on successful setting of the time zone.
214 * Use the obsolete unix timezone structure and tz_dsttime member.
216 BOOL WINAPI SetTimeZoneInformation(
217 const LPTIME_ZONE_INFORMATION tzinfo) /* [in] The new time zone. */
221 tz.tz_minuteswest = tzinfo->Bias;
223 tz.tz_dsttime = DST_NONE;
227 return !settimeofday(NULL, &tz);
231 /***********************************************************************
232 * SystemTimeToTzSpecificLocalTime (KERNEL32.683)
234 * Converts the system time (utc) to the local time in the specified time zone.
238 * Returns true when the local time was calculated.
242 * Does not handle daylight savings time adjustments correctly.
244 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
245 LPTIME_ZONE_INFORMATION lpTimeZoneInformation, /* [in] The desired time zone. */
246 LPSYSTEMTIME lpUniversalTime, /* [in] The utc time to base local time on. */
247 LPSYSTEMTIME lpLocalTime) /* [out] The local time in the time zone. */
250 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
255 /***********************************************************************
256 * GetSystemTimeAsFileTime (KERNEL32.408)
258 * Fills in a file time structure with the current time in UTC format.
260 VOID WINAPI GetSystemTimeAsFileTime(
261 LPFILETIME time) /* [out] The file time struct to be filled with the system time. */
263 NtQuerySystemTime( (LARGE_INTEGER *)time );
267 /*********************************************************************
268 * TIME_ClockTimeToFileTime (olorin@fandra.org, 20-Sep-1998)
270 * Used by GetProcessTimes to convert clock_t into FILETIME.
272 * Differences to UnixTimeToFileTime:
273 * 1) Divided by CLK_TCK
274 * 2) Time is relative. There is no 'starting date', so there is
275 * no need in offset correction, like in UnixTimeToFileTime
277 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
279 LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
280 ((LARGE_INTEGER *)filetime)->QuadPart = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
283 /*********************************************************************
284 * GetProcessTimes (KERNEL32.378)
286 * Returns the user and kernel execution times of a process,
287 * along with the creation and exit times if known.
290 * Would be nice to subtract the cpu time, used by Wine at startup.
291 * Also, there is a need to separate times used by different applications.
295 * Always returns true.
299 * lpCreationTime, lpExitTime are NOT INITIALIZED.
301 BOOL WINAPI GetProcessTimes(
302 HANDLE hprocess, /* [in] The process to be queried (obtained from PROCESS_QUERY_INFORMATION). */
303 LPFILETIME lpCreationTime, /* [out] The creation time of the process. */
304 LPFILETIME lpExitTime, /* [out] The exit time of the process if exited. */
305 LPFILETIME lpKernelTime, /* [out] The time spent in kernal routines in 100's of nanoseconds. */
306 LPFILETIME lpUserTime) /* [out] The time spent in user routines in 100's of nanoseconds. */
311 TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
312 TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);