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 * FIXME: correct ? Is the timezone param of settimeofday() needed ?
37 * I don't have any docu about SetLocal/SystemTime(), argl...
39 BOOL WINAPI SetLocalTime(const SYSTEMTIME *systime)
44 time_t oldsec=time(NULL);
47 /* get the number of seconds */
48 t.tm_sec = systime->wSecond;
49 t.tm_min = systime->wMinute;
50 t.tm_hour = systime->wHour;
51 t.tm_mday = systime->wDay;
52 t.tm_mon = systime->wMonth - 1;
53 t.tm_year = systime->wYear - 1900;
57 /* set the new time */
59 tv.tv_usec = systime->wMilliseconds * 1000;
61 /* error and sanity check*/
62 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
64 SetLastError(ERROR_INVALID_PARAMETER);
66 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
69 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
71 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
72 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
73 systime->wMinute, systime->wSecond,
74 sec-oldsec, err == -1 ? "No Permission" :
75 sec==(time_t)-1 ? "" : "is too large." );
80 /***********************************************************************
81 * GetSystemTimeAdjustment (KERNEL32.407)
84 DWORD WINAPI GetSystemTimeAdjustment( LPDWORD lpTimeAdjustment,
85 LPDWORD lpTimeIncrement,
86 LPBOOL lpTimeAdjustmentDisabled )
88 *lpTimeAdjustment = 0;
90 *lpTimeAdjustmentDisabled = TRUE;
95 /***********************************************************************
96 * SetSystemTime (KERNEL32.507)
98 BOOL WINAPI SetSystemTime(const SYSTEMTIME *systime)
107 /* call gettimeofday to get the current timezone */
108 gettimeofday(&tv, &tz);
110 /* get delta local time from utc */
111 bias=TIME_GetBias(oldsec,&dst);
113 /* get the number of seconds */
114 t.tm_sec = systime->wSecond;
115 t.tm_min = systime->wMinute;
116 t.tm_hour = systime->wHour;
117 t.tm_mday = systime->wDay;
118 t.tm_mon = systime->wMonth - 1;
119 t.tm_year = systime->wYear - 1900;
122 /* correct for timezone and daylight */
125 /* set the new time */
127 tv.tv_usec = systime->wMilliseconds * 1000;
129 /* error and sanity check*/
130 if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){
132 SetLastError(ERROR_INVALID_PARAMETER);
134 err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */
137 SetLastError(ERROR_PRIVILEGE_NOT_HELD);
139 ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n",
140 systime->wYear, systime->wMonth, systime->wDay, systime->wHour,
141 systime->wMinute, systime->wSecond,
142 sec-oldsec, err == -1 ? "No Permission" :
143 sec==(time_t)-1 ? "" : "is too large." );
148 /***********************************************************************
149 * GetTimeZoneInformation (KERNEL32.302)
151 DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION tzinfo)
156 memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION));
159 bias=TIME_GetBias(gmt,&daylight);
161 tzinfo->Bias = -bias / 60;
162 tzinfo->StandardBias = 0;
163 tzinfo->DaylightBias = -60;
165 return TIME_ZONE_ID_STANDARD;
169 /***********************************************************************
170 * SetTimeZoneInformation (KERNEL32.515)
172 BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION tzinfo)
176 tz.tz_minuteswest = tzinfo->Bias;
178 tz.tz_dsttime = DST_NONE;
182 return !settimeofday(NULL, &tz);
186 /***********************************************************************
187 * SystemTimeToTzSpecificLocalTime (KERNEL32.683)
189 BOOL WINAPI SystemTimeToTzSpecificLocalTime(
190 LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
191 LPSYSTEMTIME lpUniversalTime,
192 LPSYSTEMTIME lpLocalTime)
195 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
200 /***********************************************************************
201 * GetSystemTimeAsFileTime (KERNEL32)
203 VOID WINAPI GetSystemTimeAsFileTime( LPFILETIME time )
205 NtQuerySystemTime( (LARGE_INTEGER *)time );
209 /*********************************************************************
210 * TIME_ClockTimeToFileTime
211 * (olorin@fandra.org, 20-Sep-1998)
212 * Converts clock_t into FILETIME.
213 * Used by GetProcessTime.
214 * Differences to UnixTimeToFileTime:
215 * 1) Divided by CLK_TCK
216 * 2) Time is relative. There is no 'starting date', so there is
217 * no need in offset correction, like in UnixTimeToFileTime
219 static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
221 LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
222 ((LARGE_INTEGER *)filetime)->QuadPart = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
225 /*********************************************************************
226 * GetProcessTimes [KERNEL32.262]
228 * FIXME: lpCreationTime, lpExitTime are NOT INITIALIZED.
229 * olorin@fandra.org: Would be nice to substract the cpu time,
230 * used by Wine at startup.
231 * Also, there is a need to separate times
232 * used by different applications.
234 BOOL WINAPI GetProcessTimes( HANDLE hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,
235 LPFILETIME lpKernelTime, LPFILETIME lpUserTime )
240 TIME_ClockTimeToFileTime(tms.tms_utime,lpUserTime);
241 TIME_ClockTimeToFileTime(tms.tms_stime,lpKernelTime);