Skip to content

Commit e329208

Browse files
committed
fix FileSystem::setModTime on x64 Windows with times > 2038
also removes some unused Utility methods Signed-off-by: Jyrki Gadinger <nilsding@nilsding.org>
1 parent e00b864 commit e329208

5 files changed

Lines changed: 27 additions & 46 deletions

File tree

src/common/utility.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,6 @@ namespace Utility {
294294
OCSYNC_EXPORT bool registryWalkValues(HKEY hRootKey, const QString &subKey, const std::function<void(const QString &, bool *)> &callback);
295295
OCSYNC_EXPORT QRect getTaskbarDimensions();
296296

297-
// Possibly refactor to share code with UnixTimevalToFileTime in c_time.c
298-
OCSYNC_EXPORT void UnixTimeToFiletime(time_t t, FILETIME *filetime);
299-
OCSYNC_EXPORT void FiletimeToLargeIntegerFiletime(FILETIME *filetime, LARGE_INTEGER *hundredNSecs);
300297
OCSYNC_EXPORT void UnixTimeToLargeIntegerFiletime(time_t t, LARGE_INTEGER *hundredNSecs);
301298

302299
OCSYNC_EXPORT QString formatWinError(long error);

src/common/utility_win.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -483,24 +483,9 @@ DWORD Utility::convertSizeToDWORD(size_t &convertVar)
483483
return static_cast<DWORD>(convertVar);
484484
}
485485

486-
void Utility::UnixTimeToFiletime(time_t t, FILETIME *filetime)
487-
{
488-
LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
489-
filetime->dwLowDateTime = (DWORD) ll;
490-
filetime->dwHighDateTime = ll >>32;
491-
}
492-
493-
void Utility::FiletimeToLargeIntegerFiletime(FILETIME *filetime, LARGE_INTEGER *hundredNSecs)
494-
{
495-
hundredNSecs->LowPart = filetime->dwLowDateTime;
496-
hundredNSecs->HighPart = filetime->dwHighDateTime;
497-
}
498-
499486
void Utility::UnixTimeToLargeIntegerFiletime(time_t t, LARGE_INTEGER *hundredNSecs)
500487
{
501-
LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
502-
hundredNSecs->LowPart = (DWORD) ll;
503-
hundredNSecs->HighPart = ll >>32;
488+
hundredNSecs->QuadPart = (t * 10000000LL) + 116444736000000000LL;
504489
}
505490

506491
bool Utility::canCreateFileInPath(const QString &path)

src/csync/std/c_time.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,43 +25,45 @@
2525
#include <QFile>
2626

2727
#ifdef HAVE_UTIMES
28-
int c_utimes(const QString &uri, const struct timeval *times) {
29-
int ret = utimes(QFile::encodeName(uri).constData(), times);
30-
return ret;
28+
int c_utimes(const QString &uri, const time_t time)
29+
{
30+
struct timeval times[2];
31+
times[0].tv_sec = times[1].tv_sec = time;
32+
times[0].tv_usec = times[1].tv_usec = 0;
33+
return utimes(QFile::encodeName(uri).constData(), times);
3134
}
35+
3236
#else // HAVE_UTIMES
3337

3438
#ifdef _WIN32
35-
// implementation for utimes taken from KDE mingw headers
39+
// based on the implementation for utimes from KDE mingw headers
3640

3741
#include <errno.h>
3842
#include <wtypes.h>
39-
#define CSYNC_SECONDS_SINCE_1601 11644473600LL
40-
#define CSYNC_USEC_IN_SEC 1000000LL
41-
//after Microsoft KB167296
42-
static void UnixTimevalToFileTime(struct timeval t, LPFILETIME pft)
43+
44+
constexpr long long CSYNC_SECONDS_SINCE_1601 = 11644473600LL;
45+
constexpr long long CSYNC_USEC_IN_SEC = 1000000LL;
46+
47+
// after Microsoft KB167296, except it uses a `time_t` instead of a `struct timeval`.
48+
//
49+
// `struct timeval` is defined in the winsock.h header of all places, and its fields are two `long`s,
50+
// which even on x64 Windows is 4 bytes wide (i.e. int32). `time_t` on the other hand is 8 bytes
51+
// wide (int64) on x64 Windows as well.
52+
static void UnixTimeToFiletime(const time_t time, LPFILETIME pft)
4353
{
44-
LONGLONG ll = 0;
45-
ll = Int32x32To64(t.tv_sec, CSYNC_USEC_IN_SEC*10) + t.tv_usec*10 + CSYNC_SECONDS_SINCE_1601*CSYNC_USEC_IN_SEC*10;
54+
LONGLONG ll = time * CSYNC_USEC_IN_SEC * 10 + CSYNC_SECONDS_SINCE_1601 * CSYNC_USEC_IN_SEC * 10;
4655
pft->dwLowDateTime = (DWORD)ll;
4756
pft->dwHighDateTime = ll >> 32;
4857
}
4958

50-
int c_utimes(const QString &uri, const struct timeval *times) {
51-
FILETIME LastAccessTime;
52-
FILETIME LastModificationTime;
59+
int c_utimes(const QString &uri, const time_t time)
60+
{
61+
FILETIME filetime;
5362
HANDLE hFile = nullptr;
5463

5564
auto wuri = uri.toStdWString();
5665

57-
if(times) {
58-
UnixTimevalToFileTime(times[0], &LastAccessTime);
59-
UnixTimevalToFileTime(times[1], &LastModificationTime);
60-
}
61-
else {
62-
GetSystemTimeAsFileTime(&LastAccessTime);
63-
GetSystemTimeAsFileTime(&LastModificationTime);
64-
}
66+
UnixTimeToFiletime(time, &filetime);
6567

6668
hFile=CreateFileW(wuri.data(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
6769
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, nullptr);
@@ -87,7 +89,7 @@ int c_utimes(const QString &uri, const struct timeval *times) {
8789
return -1;
8890
}
8991

90-
if(!SetFileTime(hFile, nullptr, &LastAccessTime, &LastModificationTime)) {
92+
if (!SetFileTime(hFile, nullptr, &filetime, &filetime)) {
9193
//can this happen?
9294
errno=ENOENT;
9395
CloseHandle(hFile);

src/csync/std/c_time.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include <sys/time.h>
3232
#endif
3333

34-
OCSYNC_EXPORT int c_utimes(const QString &uri, const struct timeval *times);
34+
OCSYNC_EXPORT int c_utimes(const QString &uri, time_t time);
3535

3636

3737
#endif /* _C_TIME_H */

src/libsync/filesystem.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,7 @@ time_t FileSystem::getModTime(const QString &filename)
196196

197197
bool FileSystem::setModTime(const QString &filename, time_t modTime)
198198
{
199-
struct timeval times[2];
200-
times[0].tv_sec = times[1].tv_sec = modTime;
201-
times[0].tv_usec = times[1].tv_usec = 0;
202-
int rc = c_utimes(filename, times);
199+
int rc = c_utimes(filename, modTime);
203200
if (rc != 0) {
204201
qCWarning(lcFileSystem) << "Error setting mtime for" << filename
205202
<< "failed: rc" << rc << ", errno:" << errno;

0 commit comments

Comments
 (0)