From d09b8b5bd74919f0d1d70399ad0d3da3544bc588 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 28 Feb 2015 21:49:06 +0100 Subject: [PATCH] fs/FileInfo: use GetFileAttributesEx() on WIN32 --- src/fs/FileInfo.hxx | 50 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/fs/FileInfo.hxx b/src/fs/FileInfo.hxx index 6fe24cb90..3805d3ef0 100644 --- a/src/fs/FileInfo.hxx +++ b/src/fs/FileInfo.hxx @@ -25,7 +25,29 @@ #include "util/Error.hxx" #include + +#ifdef WIN32 +#include +#else #include +#endif + +#ifdef WIN32 + +static inline constexpr uint64_t +ConstructUint64(DWORD lo, DWORD hi) +{ + return uint64_t(lo) | (uint64_t(hi) << 32); +} + +static constexpr time_t +FileTimeToTimeT(FILETIME ft) +{ + return (ConstructUint64(ft.dwLowDateTime, ft.dwHighDateTime) + - 116444736000000000) / 10000000; +} + +#endif class FileInfo { friend bool GetFileInfo(Path path, FileInfo &info, @@ -33,23 +55,43 @@ class FileInfo { friend bool GetFileInfo(Path path, FileInfo &info, Error &error); +#ifdef WIN32 + WIN32_FILE_ATTRIBUTE_DATA data; +#else struct stat st; +#endif public: bool IsRegular() const { +#ifdef WIN32 + return data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL; +#else return S_ISREG(st.st_mode); +#endif } bool IsDirectory() const { +#ifdef WIN32 + return data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; +#else return S_ISDIR(st.st_mode); +#endif } uint64_t GetSize() const { +#ifdef WIN32 + return ConstructUint64(data.nFileSizeLow, data.nFileSizeHigh); +#else return st.st_size; +#endif } time_t GetModificationTime() const { +#ifdef WIN32 + return FileTimeToTimeT(data.ftLastWriteTime); +#else return st.st_mtime; +#endif } #ifndef WIN32 @@ -76,7 +118,8 @@ GetFileInfo(Path path, FileInfo &info, bool follow_symlinks=true) { #ifdef WIN32 (void)follow_symlinks; - return stat(path.c_str(), &info.st) == 0; + return GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, + &info.data); #else int ret = follow_symlinks ? stat(path.c_str(), &info.st) @@ -91,7 +134,12 @@ GetFileInfo(Path path, FileInfo &info, bool follow_symlinks, Error &error) bool success = GetFileInfo(path, info, follow_symlinks); if (!success) { const auto path_utf8 = path.ToUTF8(); +#ifdef WIN32 + error.FormatLastError("Failed to access %s", + path_utf8.c_str()); +#else error.FormatErrno("Failed to access %s", path_utf8.c_str()); +#endif } return success;