Module: wine Branch: master Commit: 773b97bb2b0f4421d213b466337dd6d66b2b0856 URL: https://source.winehq.org/git/wine.git/?a=commit;h=773b97bb2b0f4421d213b4663...
Author: Erich E. Hoover erich.e.hoover@gmail.com Date: Sat Nov 21 22:33:20 2020 -0700
ntdll: Fix converting large 32-bit time_t when time_t is signed.
Signed-off-by: Erich E. Hoover erich.e.hoover@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/tests/file.c | 12 ++++++++++++ dlls/ntdll/unix/file.c | 10 +++++----- dlls/ntdll/unix/sync.c | 12 +++++------- dlls/ntdll/unix/unix_private.h | 9 ++++++++- 4 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 8b9ec4f624d..2507437c8c3 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1361,6 +1361,18 @@ static void test_file_basic_information(void) 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 );
+ 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); ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res); diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index cf413f46e5c..6d6edfe8926 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -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, LARGE_INTEGER *atime, LARGE_INTEGER *creation ) { - mtime->QuadPart = st->st_mtime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - ctime->QuadPart = st->st_ctime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - atime->QuadPart = st->st_atime * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; + mtime->QuadPart = ticks_from_time_t( st->st_mtime ); + ctime->QuadPart = ticks_from_time_t( st->st_ctime ); + atime->QuadPart = ticks_from_time_t( st->st_atime ); #ifdef HAVE_STRUCT_STAT_ST_MTIM mtime->QuadPart += st->st_mtim.tv_nsec / 100; #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) @@ -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; #endif #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 creation->QuadPart += st->st_birthtim.tv_nsec / 100; #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) creation->QuadPart += st->st_birthtimespec.tv_nsec / 100; #endif #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 creation->QuadPart += st->__st_birthtim.tv_nsec / 100; #endif diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index bba7af7e34f..dcc8c5447ef 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -104,7 +104,7 @@ static inline ULONGLONG monotonic_counter(void) return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100; #endif 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 )
if (!clock_gettime( clock_id, &ts )) { - time->QuadPart = ts.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - time->QuadPart += (ts.tv_nsec + 50) / 100; + time->QuadPart = ticks_from_time_t( ts.tv_sec ) + (ts.tv_nsec + 50) / 100; } else #endif /* HAVE_CLOCK_GETTIME */ @@ -1401,8 +1400,7 @@ NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time ) struct timeval now;
gettimeofday( &now, 0 ); - time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - time->QuadPart += now.tv_usec * 10; + time->QuadPart = ticks_from_time_t( now.tv_sec ) + now.tv_usec * 10; } return STATUS_SUCCESS; } @@ -1475,10 +1473,10 @@ LONGLONG WINAPI RtlGetSystemTimePrecise(void) struct timespec 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 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; }
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index c3ad0a41098..23731f0fdc6 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -249,7 +249,14 @@ extern void WINAPI DECLSPEC_NORETURN call_raise_user_exception_dispatcher( NTSTA
#define TICKSPERSEC 10000000 #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 ) {