2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
11 #include <sys/times.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 */
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
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. */
51 time_t oldsec
=time(NULL
);
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;
64 /* set the new time */
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
){
71 SetLastError(ERROR_INVALID_PARAMETER
);
73 err
=settimeofday(&tv
, NULL
); /* 0 is OK, -1 is error */
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." );
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.
95 * Always returns true.
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
;
114 /***********************************************************************
115 * SetSystemTime (KERNEL32.665)
117 * Sets the system time (utc).
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. */
134 /* call gettimeofday to get the current timezone */
135 gettimeofday(&tv
, &tz
);
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;
149 /* correct for timezone and daylight */
152 /* set the new time */
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
){
159 SetLastError(ERROR_INVALID_PARAMETER
);
161 err
=settimeofday(&tv
, NULL
); /* 0 is OK, -1 is error */
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." );
175 /***********************************************************************
176 * GetTimeZoneInformation (KERNEL32.424)
178 * Fills in the a time zone information structure with values based on
179 * the current local time.
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. */
191 memset(tzinfo
, 0, sizeof(TIME_ZONE_INFORMATION
));
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.
211 * True on successful setting of the time zone.
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. */
222 tz
.tz_minuteswest
= tzinfo
->Bias
;
224 tz
.tz_dsttime
= DST_NONE
;
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.
239 * Returns true when the local time was calculated.
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. */
251 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
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.
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.
296 * Always returns true.
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. */
312 TIME_ClockTimeToFileTime(tms
.tms_utime
,lpUserTime
);
313 TIME_ClockTimeToFileTime(tms
.tms_stime
,lpKernelTime
);
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
);
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
);
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
));
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
));