From c2a329ce5e87af552705411db4ab8971bc82dcb6 Mon Sep 17 00:00:00 2001 From: Clinton Stimpson <clinton@elemtech.com> Date: Tue, 1 Jul 2014 06:17:36 -0600 Subject: [PATCH] Encoding: Fixes uses of stat() on Windows to work with unicode. SystemTools::ModifiedTime() and SystemTools::CreationTime() are fixed to work with unicode. Change-Id: Iaf137340cf2e235d46a79a49621c11890b85ab84 --- SystemTools.cxx | 67 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/SystemTools.cxx b/SystemTools.cxx index 18e2419..db94510 100644 --- a/SystemTools.cxx +++ b/SystemTools.cxx @@ -187,6 +187,21 @@ static inline char *realpath(const char *path, char *resolved_path) } #endif +#ifdef _WIN32 +static time_t windows_filetime_to_posix_time(const FILETIME& ft) +{ + LARGE_INTEGER date; + date.HighPart = ft.dwHighDateTime; + date.LowPart = ft.dwLowDateTime; + + // removes the diff between 1970 and 1601 + date.QuadPart -= ((LONGLONG)(369 * 365 + 89) * 24 * 3600 * 10000000); + + // converts back from 100-nanoseconds to seconds + return date.QuadPart / 10000000; +} +#endif + #if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) #include <wctype.h> @@ -2312,28 +2327,28 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination, // return size of file; also returns zero if no file exists unsigned long SystemTools::FileLength(const char* filename) { + unsigned long length = 0; #ifdef _WIN32 WIN32_FILE_ATTRIBUTE_DATA fs; if (GetFileAttributesExW( SystemTools::ConvertToWindowsExtendedPath(filename).c_str(), - GetFileExInfoStandard, &fs) == TRUE) + GetFileExInfoStandard, &fs) != 0) { /* To support the full 64-bit file size, use fs.nFileSizeHigh * and fs.nFileSizeLow to construct the 64 bit size + + length = ((__int64)fs.nFileSizeHigh << 32) + fs.nFileSizeLow; */ - return static_cast<unsigned long>(fs.nFileSizeLow); + length = static_cast<unsigned long>(fs.nFileSizeLow); } #else struct stat fs; if (stat(filename, &fs) == 0) { - return static_cast<unsigned long>(fs.st_size); + length = static_cast<unsigned long>(fs.st_size); } #endif - else - { - return 0; - } + return length; } int SystemTools::Strucmp(const char *s1, const char *s2) @@ -2352,29 +2367,47 @@ int SystemTools::Strucmp(const char *s1, const char *s2) // return file's modified time long int SystemTools::ModifiedTime(const char* filename) { - struct stat fs; - if (stat(filename, &fs) != 0) + long int mt = 0; +#ifdef _WIN32 + WIN32_FILE_ATTRIBUTE_DATA fs; + if (GetFileAttributesExW( + SystemTools::ConvertToWindowsExtendedPath(filename).c_str(), + GetFileExInfoStandard, + &fs) != 0) { - return 0; + mt = windows_filetime_to_posix_time(fs.ftLastWriteTime); } - else +#else + struct stat fs; + if (stat(filename, &fs) == 0) { - return static_cast<long int>(fs.st_mtime); + mt = static_cast<long int>(fs.st_mtime); } +#endif + return mt; } // return file's creation time long int SystemTools::CreationTime(const char* filename) { - struct stat fs; - if (stat(filename, &fs) != 0) + long int ct = 0; +#ifdef _WIN32 + WIN32_FILE_ATTRIBUTE_DATA fs; + if (GetFileAttributesExW( + SystemTools::ConvertToWindowsExtendedPath(filename).c_str(), + GetFileExInfoStandard, + &fs) != 0) { - return 0; + ct = windows_filetime_to_posix_time(fs.ftCreationTime); } - else +#else + struct stat fs; + if (stat(filename, &fs) == 0) { - return fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0; + ct = fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0; } +#endif + return ct; } bool SystemTools::ConvertDateMacroString(const char *str, time_t *tmt) -- GitLab