Commit 773b97bb authored by Erich E. Hoover's avatar Erich E. Hoover Committed by Alexandre Julliard

ntdll: Fix converting large 32-bit time_t when time_t is signed.

parent dfe1bb7b
...@@ -1362,6 +1362,18 @@ static void test_file_basic_information(void) ...@@ -1362,6 +1362,18 @@ static void test_file_basic_information(void)
ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status ); ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status );
memset(&fbi2, 0, sizeof(fbi2)); memset(&fbi2, 0, sizeof(fbi2));
fbi2.LastAccessTime.QuadPart = 0x200deadcafebeef;
U(io).Status = 0xdeadbeef;
res = pNtSetInformationFile(h, &io, &fbi2, sizeof(fbi2), FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res );
ok ( U(io).Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %x\n", U(io).Status );
res = pNtQueryInformationFile(h, &io, &fbi, sizeof(fbi), FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't get system attribute, NtQueryInformationFile returned %x\n", res );
ok ( U(io).Status == STATUS_SUCCESS, "can't get system attribute, io.Status is %x\n", U(io).Status );
ok ( fbi2.LastAccessTime.QuadPart == fbi.LastAccessTime.QuadPart,
"large access time set/get does not match.\n" );
memset(&fbi2, 0, sizeof(fbi2));
res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation); res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
ok ( fbi2.LastWriteTime.QuadPart == fbi.LastWriteTime.QuadPart, "unexpected write time.\n"); ok ( fbi2.LastWriteTime.QuadPart == fbi.LastWriteTime.QuadPart, "unexpected write time.\n");
......
...@@ -1631,9 +1631,9 @@ static NTSTATUS set_file_times( int fd, const LARGE_INTEGER *mtime, const LARGE_ ...@@ -1631,9 +1631,9 @@ static NTSTATUS set_file_times( int fd, const LARGE_INTEGER *mtime, const LARGE_
static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime, LARGE_INTEGER *ctime, static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime, LARGE_INTEGER *ctime,
LARGE_INTEGER *atime, LARGE_INTEGER *creation ) LARGE_INTEGER *atime, LARGE_INTEGER *creation )
{ {
mtime->QuadPart = st->st_mtime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; mtime->QuadPart = ticks_from_time_t( st->st_mtime );
ctime->QuadPart = st->st_ctime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; ctime->QuadPart = ticks_from_time_t( st->st_ctime );
atime->QuadPart = st->st_atime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; atime->QuadPart = ticks_from_time_t( st->st_atime );
#ifdef HAVE_STRUCT_STAT_ST_MTIM #ifdef HAVE_STRUCT_STAT_ST_MTIM
mtime->QuadPart += st->st_mtim.tv_nsec / 100; mtime->QuadPart += st->st_mtim.tv_nsec / 100;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
...@@ -1650,14 +1650,14 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime, ...@@ -1650,14 +1650,14 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime,
atime->QuadPart += st->st_atimespec.tv_nsec / 100; atime->QuadPart += st->st_atimespec.tv_nsec / 100;
#endif #endif
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
creation->QuadPart = st->st_birthtime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; creation->QuadPart = ticks_from_time_t( st->st_birthtime );
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIM #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIM
creation->QuadPart += st->st_birthtim.tv_nsec / 100; creation->QuadPart += st->st_birthtim.tv_nsec / 100;
#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
creation->QuadPart += st->st_birthtimespec.tv_nsec / 100; creation->QuadPart += st->st_birthtimespec.tv_nsec / 100;
#endif #endif
#elif defined(HAVE_STRUCT_STAT___ST_BIRTHTIME) #elif defined(HAVE_STRUCT_STAT___ST_BIRTHTIME)
creation->QuadPart = st->__st_birthtime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; creation->QuadPart = ticks_from_time_t( st->__st_birthtime );
#ifdef HAVE_STRUCT_STAT___ST_BIRTHTIM #ifdef HAVE_STRUCT_STAT___ST_BIRTHTIM
creation->QuadPart += st->__st_birthtim.tv_nsec / 100; creation->QuadPart += st->__st_birthtim.tv_nsec / 100;
#endif #endif
......
...@@ -104,7 +104,7 @@ static inline ULONGLONG monotonic_counter(void) ...@@ -104,7 +104,7 @@ static inline ULONGLONG monotonic_counter(void)
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100; return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
#endif #endif
gettimeofday( &now, 0 ); gettimeofday( &now, 0 );
return now.tv_sec * (ULONGLONG)TICKSPERSEC + now.tv_usec * 10 + TICKS_1601_TO_1970 - server_start_time; return ticks_from_time_t( now.tv_sec ) + now.tv_usec * 10 - server_start_time;
} }
...@@ -1392,8 +1392,7 @@ NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time ) ...@@ -1392,8 +1392,7 @@ NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time )
if (!clock_gettime( clock_id, &ts )) if (!clock_gettime( clock_id, &ts ))
{ {
time->QuadPart = ts.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; time->QuadPart = ticks_from_time_t( ts.tv_sec ) + (ts.tv_nsec + 50) / 100;
time->QuadPart += (ts.tv_nsec + 50) / 100;
} }
else else
#endif /* HAVE_CLOCK_GETTIME */ #endif /* HAVE_CLOCK_GETTIME */
...@@ -1401,8 +1400,7 @@ NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time ) ...@@ -1401,8 +1400,7 @@ NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time )
struct timeval now; struct timeval now;
gettimeofday( &now, 0 ); gettimeofday( &now, 0 );
time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; time->QuadPart = ticks_from_time_t( now.tv_sec ) + now.tv_usec * 10;
time->QuadPart += now.tv_usec * 10;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
...@@ -1475,10 +1473,10 @@ LONGLONG WINAPI RtlGetSystemTimePrecise(void) ...@@ -1475,10 +1473,10 @@ LONGLONG WINAPI RtlGetSystemTimePrecise(void)
struct timespec ts; struct timespec ts;
if (!clock_gettime( CLOCK_REALTIME, &ts )) if (!clock_gettime( CLOCK_REALTIME, &ts ))
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970 + (ts.tv_nsec + 50) / 100; return ticks_from_time_t( ts.tv_sec ) + (ts.tv_nsec + 50) / 100;
#endif #endif
gettimeofday( &now, 0 ); gettimeofday( &now, 0 );
return now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970 + now.tv_usec * 10; return ticks_from_time_t( now.tv_sec ) + now.tv_usec * 10;
} }
......
...@@ -249,7 +249,14 @@ extern void WINAPI DECLSPEC_NORETURN call_raise_user_exception_dispatcher( NTSTA ...@@ -249,7 +249,14 @@ extern void WINAPI DECLSPEC_NORETURN call_raise_user_exception_dispatcher( NTSTA
#define TICKSPERSEC 10000000 #define TICKSPERSEC 10000000
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400) #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
static inline ULONGLONG ticks_from_time_t( time_t time )
{
if (sizeof(time_t) == sizeof(int)) /* time_t may be signed */
return ((ULONGLONG)(ULONG)time + SECS_1601_TO_1970) * TICKSPERSEC;
else
return ((ULONGLONG)time + SECS_1601_TO_1970) * TICKSPERSEC;
}
static inline const char *debugstr_us( const UNICODE_STRING *us ) static inline const char *debugstr_us( const UNICODE_STRING *us )
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment