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( const SYSTEMTIME
*systime
/* The desired local time. */ )
49 time_t oldsec
=time(NULL
);
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;
62 /* set the new time */
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
){
69 SetLastError(ERROR_INVALID_PARAMETER
);
71 err
=settimeofday(&tv
, NULL
); /* 0 is OK, -1 is error */
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." );
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.
93 * Always returns true.
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
;
112 /***********************************************************************
113 * SetSystemTime (KERNEL32.665)
115 * Sets the system time (utc).
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. */)
132 /* call gettimeofday to get the current timezone */
133 gettimeofday(&tv
, &tz
);
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;
147 /* correct for timezone and daylight */
150 /* set the new time */
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
){
157 SetLastError(ERROR_INVALID_PARAMETER
);
159 err
=settimeofday(&tv
, NULL
); /* 0 is OK, -1 is error */
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." );
173 /***********************************************************************
174 * GetTimeZoneInformation (KERNEL32.424)
176 * Fills in the a time zone information structure with values based on
177 * the current local time.
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. */)
189 memset(tzinfo
, 0, sizeof(TIME_ZONE_INFORMATION
));
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.673)
205 * Set the local time zone with values based on the time zone structure.
209 * True on successful setting of the time zone.
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. */)
220 tz
.tz_minuteswest
= tzinfo
->Bias
;
222 tz
.tz_dsttime
= DST_NONE
;
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.
237 * Returns true when the local time was calculated.
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. */)
249 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
254 /***********************************************************************
255 * GetSystemTimeAsFileTime (KERNEL32.408)
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.378)
285 * Returns the user and kernel execution times of a process,
286 * along with the creation and exit times if known.
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.
294 * Always returns true.
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. */)
310 TIME_ClockTimeToFileTime(tms
.tms_utime
,lpUserTime
);
311 TIME_ClockTimeToFileTime(tms
.tms_stime
,lpKernelTime
);