Some time functions were broken and/or needed some work to act the same way as on Windows. GetSystemTimeAdjustment's (GSTA) prototype wasn't correct, and it was absent from all headers. DosDateTimeToFileTime (DDTTFT) was wrong (call to mktime rather than timegm or equivalent). FileTimeToDosDateTime (FTTDDT) was also wrong (did a TZ conversion when it wasn't necessary). LocalFileTimeToFileTime (LFTTFT) wasn't handling correctly the daylight saving. FileTimeToLocalFileTime (FTTLFT) didn't returned the same thing whether timegm was present or not. If it was absent, localtime and gmtime were returning the same static structure (info libc says not to use localtime/gmtime/ctime in multithreaded apps: can more than one API be called at the same time by different Windows processes? Or Wine threads?), so the subsequent conversion was false. I streamlined it, but the call to mktime in the second way doesn't take daylight saving into account automatically, so I had to do it manually. Lastly, SystemTimeToFileTime (STTFT), when timegm was absent, also used both localtime and gmtime. Furthermore, the result of the call to localtime was never reused. I'll now read François's presentation on regression tests and implement some for those functions. I already have a basis, I just need to do it the same way as the rest of the regression tests. Changelog: - Fixed GetSystemTimeAdjustment prototype and added it to winbase.h. - Fixed DosDateTimeToFileTime, FileTimeToDosDateTime, LocalFileTimeToFileTime, FileTimeToLocalFileTime and SystemTimeToFileTime. Vincent
diff -urN wine-orig/dlls/kernel/time.c wine-pas-compilé/dlls/kernel/time.c --- wine-orig/dlls/kernel/time.c Wed May 15 22:28:45 2002 +++ wine-pas-compilé/dlls/kernel/time.c Fri May 24 17:28:05 2002 @@ -353,12 +353,11 @@ * BUGS * * Only the special case of disabled time adjustments is supported. - * (also the signature is wrong it should have a return type of BOOL) */ -DWORD WINAPI GetSystemTimeAdjustment( - LPDWORD lpTimeAdjustment, /* [out] The clock adjustment per interupt in 100's of nanoseconds. */ - LPDWORD lpTimeIncrement, /* [out] The time between clock interupts in 100's of nanoseconds. */ - LPBOOL lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */ +BOOL WINAPI GetSystemTimeAdjustment( + PDWORD lpTimeAdjustment, /* [out] The clock adjustment per interupt in 100's of nanoseconds. */ + PDWORD lpTimeIncrement, /* [out] The time between clock interupts in 100's of nanoseconds. */ + PBOOL lpTimeAdjustmentDisabled) /* [out] The clock synchonisation has been disabled. */ { *lpTimeAdjustment = 0; *lpTimeIncrement = 0; diff -urN wine-orig/files/dos_fs.c wine-pas-compilé/files/dos_fs.c --- wine-orig/files/dos_fs.c Thu May 23 16:36:46 2002 +++ wine-pas-compilé/files/dos_fs.c Fri May 24 17:24:21 2002 @@ -2126,6 +2126,10 @@ BOOL WINAPI DosDateTimeToFileTime( WORD fatdate, WORD fattime, LPFILETIME ft) { struct tm newtm; +#ifndef HAVE_TIMEGM + struct tm *gtm; + time_t time1, time2; +#endif newtm.tm_sec = (fattime & 0x1f) * 2; newtm.tm_min = (fattime >> 5) & 0x3f; @@ -2133,7 +2137,14 @@ newtm.tm_mday = (fatdate & 0x1f); newtm.tm_mon = ((fatdate >> 5) & 0x0f) - 1; newtm.tm_year = (fatdate >> 9) + 80; - RtlSecondsSince1970ToTime( mktime( &newtm ), ft ); +#ifdef HAVE_TIMEGM + RtlSecondsSince1970ToTime( timegm(&newtm), ft ); +#else + time1 = mktime(&newtm); + gtm = gmtime(&time1); + time2 = mktime(gtm); + RtlSecondsSince1970ToTime( 2*time1-time2, ft ); +#endif return TRUE; } @@ -2145,7 +2156,7 @@ LPWORD fattime ) { time_t unixtime = DOSFS_FileTimeToUnixTime( ft, NULL ); - struct tm *tm = localtime( &unixtime ); + struct tm *tm = gmtime( &unixtime ); if (fattime) *fattime = (tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2); if (fatdate) @@ -2163,11 +2174,14 @@ { struct tm *xtm; DWORD remainder; + time_t utctime; - /* convert from local to UTC. Perhaps not correct. FIXME */ - time_t unixtime = DOSFS_FileTimeToUnixTime( localft, &remainder ); - xtm = gmtime( &unixtime ); - DOSFS_UnixTimeToFileTime( mktime(xtm), utcft, remainder ); + /* Converts from local to UTC. */ + time_t localtime = DOSFS_FileTimeToUnixTime( localft, &remainder ); + xtm = gmtime( &localtime ); + utctime = mktime(xtm); + if(xtm->tm_isdst) utctime-=3600; + DOSFS_UnixTimeToFileTime( utctime, utcft, remainder ); return TRUE; } @@ -2179,7 +2193,7 @@ LPFILETIME localft ) { DWORD remainder; - /* convert from UTC to local. Perhaps not correct. FIXME */ + /* Converts from UTC to local. */ time_t unixtime = DOSFS_FileTimeToUnixTime( utcft, &remainder ); #ifdef HAVE_TIMEGM struct tm *xtm = localtime( &unixtime ); @@ -2189,14 +2203,13 @@ DOSFS_UnixTimeToFileTime( localtime, localft, remainder ); #else - struct tm *xtm,*gtm; - time_t time1,time2; + struct tm *xtm; + time_t time; - xtm = localtime( &unixtime ); - gtm = gmtime( &unixtime ); - time1 = mktime(xtm); - time2 = mktime(gtm); - DOSFS_UnixTimeToFileTime( 2*time1-time2, localft, remainder ); + xtm = gmtime( &unixtime ); + time = mktime(xtm); + if(xtm->tm_isdst) time-=3600; + DOSFS_UnixTimeToFileTime( 2*unixtime-time, localft, remainder ); #endif return TRUE; } @@ -2291,7 +2304,7 @@ struct tm xtm; time_t utctime; #else - struct tm xtm,*local_tm,*utc_tm; + struct tm xtm,*utc_tm; time_t localtim,utctime; #endif @@ -2309,7 +2322,6 @@ syst->wMilliseconds * 10000 ); #else localtim = mktime(&xtm); /* now we've got local time */ - local_tm = localtime(&localtim); utc_tm = gmtime(&localtim); utctime = mktime(utc_tm); DOSFS_UnixTimeToFileTime( 2*localtim -utctime, ft, diff -urN wine-orig/include/winbase.h wine-pas-compilé/include/winbase.h --- wine-orig/include/winbase.h Thu May 23 10:49:53 2002 +++ wine-pas-compilé/include/winbase.h Fri May 24 16:33:33 2002 @@ -1321,6 +1321,7 @@ VOID WINAPI GetSystemInfo(LPSYSTEM_INFO); BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS); VOID WINAPI GetSystemTime(LPSYSTEMTIME); +BOOL WINAPI GetSystemTimeAdjustment(PDWORD,PDWORD,PBOOL); VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME); DWORD WINAPI GetTapeParameters(HANDLE,DWORD,LPDWORD,LPVOID); DWORD WINAPI GetTapePosition(HANDLE,DWORD,LPDWORD,LPDWORD,LPDWORD);