| /* | |
| * Win32 kernel functions | |
| * | |
| * Copyright 1995 Martin von Loewis and Cameron Heide | |
| */ | |
| #include <string.h> | |
| #include <time.h> | |
| #include <sys/time.h> | |
| #include <unistd.h> | |
| #include "file.h" | |
| #include "winerror.h" | |
| #include "debugtools.h" | |
| DEFAULT_DEBUG_CHANNEL(win32) | |
| /* maximum time adjustment in seconds for SetLocalTime and SetSystemTime */ | |
| #define SETTIME_MAX_ADJUST 120 | |
| /* TIME_GetBias: helper function calculates delta local time from UTC */ | |
| static int TIME_GetBias( time_t utc, int *pdaylight) | |
| { | |
| struct tm *ptm = localtime(&utc); | |
| *pdaylight = ptm->tm_isdst; /* daylight for local timezone */ | |
| ptm = gmtime(&utc); | |
| ptm->tm_isdst = *pdaylight; /* use local daylight, not that of Greenwich */ | |
| return (int)(utc-mktime(ptm)); | |
| } | |
| /*********************************************************************** | |
| * GetLocalTime (KERNEL32.228) | |
| */ | |
| VOID WINAPI GetLocalTime(LPSYSTEMTIME systime) | |
| { | |
| time_t local_time; | |
| struct tm *local_tm; | |
| struct timeval tv; | |
| gettimeofday(&tv, NULL); | |
| local_time = tv.tv_sec; | |
| local_tm = localtime(&local_time); | |
| systime->wYear = local_tm->tm_year + 1900; | |
| systime->wMonth = local_tm->tm_mon + 1; | |
| systime->wDayOfWeek = local_tm->tm_wday; | |
| systime->wDay = local_tm->tm_mday; | |
| systime->wHour = local_tm->tm_hour; | |
| systime->wMinute = local_tm->tm_min; | |
| systime->wSecond = local_tm->tm_sec; | |
| systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; | |
| } | |
| /*********************************************************************** | |
| * SetLocalTime (KERNEL32.655) | |
| * | |
| * FIXME: correct ? Is the timezone param of settimeofday() needed ? | |
| * I don't have any docu about SetLocal/SystemTime(), argl... | |
| */ | |
| BOOL WINAPI SetLocalTime(const SYSTEMTIME *systime) | |
| { | |
| struct timeval tv; | |
| struct tm t; | |
| time_t sec; | |
| time_t oldsec=time(NULL); | |
| int err; | |
| /* get the number of seconds */ | |
| t.tm_sec = systime->wSecond; | |
| t.tm_min = systime->wMinute; | |
| t.tm_hour = systime->wHour; | |
| t.tm_mday = systime->wDay; | |
| t.tm_mon = systime->wMonth - 1; | |
| t.tm_year = systime->wYear - 1900; | |
| t.tm_isdst = -1; | |
| sec = mktime (&t); | |
| /* set the new time */ | |
| tv.tv_sec = sec; | |
| tv.tv_usec = systime->wMilliseconds * 1000; | |
| /* error and sanity check*/ | |
| if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){ | |
| err = 1; | |
| SetLastError(ERROR_INVALID_PARAMETER); | |
| } else { | |
| err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */ | |
| if(err == 0) | |
| return TRUE; | |
| SetLastError(ERROR_PRIVILEGE_NOT_HELD); | |
| } | |
| ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n", | |
| systime->wYear, systime->wMonth, systime->wDay, systime->wHour, | |
| systime->wMinute, systime->wSecond, | |
| sec-oldsec, err == -1 ? "No Permission" : | |
| sec==(time_t)-1 ? "" : "is too large." ); | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * GetSystemTime (KERNEL32.285) | |
| */ | |
| VOID WINAPI GetSystemTime(LPSYSTEMTIME systime) | |
| { | |
| time_t local_time; | |
| struct tm *local_tm; | |
| struct timeval tv; | |
| gettimeofday(&tv, NULL); | |
| local_time = tv.tv_sec; | |
| local_tm = gmtime(&local_time); | |
| systime->wYear = local_tm->tm_year + 1900; | |
| systime->wMonth = local_tm->tm_mon + 1; | |
| systime->wDayOfWeek = local_tm->tm_wday; | |
| systime->wDay = local_tm->tm_mday; | |
| systime->wHour = local_tm->tm_hour; | |
| systime->wMinute = local_tm->tm_min; | |
| systime->wSecond = local_tm->tm_sec; | |
| systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; | |
| } | |
| /*********************************************************************** | |
| * SetSystemTime (KERNEL32.507) | |
| */ | |
| BOOL WINAPI SetSystemTime(const SYSTEMTIME *systime) | |
| { | |
| struct timeval tv; | |
| struct timezone tz; | |
| struct tm t; | |
| time_t sec, oldsec; | |
| int dst, bias; | |
| int err; | |
| /* call gettimeofday to get the current timezone */ | |
| gettimeofday(&tv, &tz); | |
| oldsec=tv.tv_sec; | |
| /* get delta local time from utc */ | |
| bias=TIME_GetBias(oldsec,&dst); | |
| /* get the number of seconds */ | |
| t.tm_sec = systime->wSecond; | |
| t.tm_min = systime->wMinute; | |
| t.tm_hour = systime->wHour; | |
| t.tm_mday = systime->wDay; | |
| t.tm_mon = systime->wMonth - 1; | |
| t.tm_year = systime->wYear - 1900; | |
| t.tm_isdst = dst; | |
| sec = mktime (&t); | |
| /* correct for timezone and daylight */ | |
| sec += bias; | |
| /* set the new time */ | |
| tv.tv_sec = sec; | |
| tv.tv_usec = systime->wMilliseconds * 1000; | |
| /* error and sanity check*/ | |
| if( sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST ){ | |
| err = 1; | |
| SetLastError(ERROR_INVALID_PARAMETER); | |
| } else { | |
| err=settimeofday(&tv, NULL); /* 0 is OK, -1 is error */ | |
| if(err == 0) | |
| return TRUE; | |
| SetLastError(ERROR_PRIVILEGE_NOT_HELD); | |
| } | |
| ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n", | |
| systime->wYear, systime->wMonth, systime->wDay, systime->wHour, | |
| systime->wMinute, systime->wSecond, | |
| sec-oldsec, err == -1 ? "No Permission" : | |
| sec==(time_t)-1 ? "" : "is too large." ); | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * GetTimeZoneInformation (KERNEL32.302) | |
| */ | |
| DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION tzinfo) | |
| { | |
| time_t gmt; | |
| int bias, daylight; | |
| memset(tzinfo, 0, sizeof(TIME_ZONE_INFORMATION)); | |
| gmt = time(NULL); | |
| bias=TIME_GetBias(gmt,&daylight); | |
| tzinfo->Bias = -bias / 60; | |
| tzinfo->StandardBias = 0; | |
| tzinfo->DaylightBias = -60; | |
| return TIME_ZONE_ID_UNKNOWN; | |
| } | |
| /*********************************************************************** | |
| * SetTimeZoneInformation (KERNEL32.515) | |
| */ | |
| BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION tzinfo) | |
| { | |
| struct timezone tz; | |
| tz.tz_minuteswest = tzinfo->Bias; | |
| #ifdef DST_NONE | |
| tz.tz_dsttime = DST_NONE; | |
| #else | |
| tz.tz_dsttime = 0; | |
| #endif | |
| return !settimeofday(NULL, &tz); | |
| } | |
| /*********************************************************************** | |
| * GetSystemTimeAsFileTime (KERNEL32) | |
| */ | |
| VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME systemtimeAsfiletime) | |
| { | |
| struct timeval now; | |
| gettimeofday( &now, 0 ); | |
| /* FIXME: convert to UTC */ | |
| DOSFS_UnixTimeToFileTime( now.tv_sec, systemtimeAsfiletime, now.tv_usec * 10 ); | |
| } | |
| /*********************************************************************** | |
| * SystemTimeToTzSpecificLocalTime (KERNEL32.683) | |
| */ | |
| BOOL WINAPI SystemTimeToTzSpecificLocalTime( | |
| LPTIME_ZONE_INFORMATION lpTimeZoneInformation, | |
| LPSYSTEMTIME lpUniversalTime, | |
| LPSYSTEMTIME lpLocalTime) { | |
| FIXME(":stub\n"); | |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
| return FALSE; | |
| } |