fs/FileInfo: use GetFileAttributesEx() on WIN32

This commit is contained in:
Max Kellermann 2015-02-28 21:49:06 +01:00
parent ee327db517
commit d09b8b5bd7
1 changed files with 49 additions and 1 deletions

View File

@ -25,7 +25,29 @@
#include "util/Error.hxx" #include "util/Error.hxx"
#include <stdint.h> #include <stdint.h>
#ifdef WIN32
#include <fileapi.h>
#else
#include <sys/stat.h> #include <sys/stat.h>
#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 { class FileInfo {
friend bool GetFileInfo(Path path, FileInfo &info, friend bool GetFileInfo(Path path, FileInfo &info,
@ -33,23 +55,43 @@ class FileInfo {
friend bool GetFileInfo(Path path, FileInfo &info, friend bool GetFileInfo(Path path, FileInfo &info,
Error &error); Error &error);
#ifdef WIN32
WIN32_FILE_ATTRIBUTE_DATA data;
#else
struct stat st; struct stat st;
#endif
public: public:
bool IsRegular() const { bool IsRegular() const {
#ifdef WIN32
return data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL;
#else
return S_ISREG(st.st_mode); return S_ISREG(st.st_mode);
#endif
} }
bool IsDirectory() const { bool IsDirectory() const {
#ifdef WIN32
return data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
#else
return S_ISDIR(st.st_mode); return S_ISDIR(st.st_mode);
#endif
} }
uint64_t GetSize() const { uint64_t GetSize() const {
#ifdef WIN32
return ConstructUint64(data.nFileSizeLow, data.nFileSizeHigh);
#else
return st.st_size; return st.st_size;
#endif
} }
time_t GetModificationTime() const { time_t GetModificationTime() const {
#ifdef WIN32
return FileTimeToTimeT(data.ftLastWriteTime);
#else
return st.st_mtime; return st.st_mtime;
#endif
} }
#ifndef WIN32 #ifndef WIN32
@ -76,7 +118,8 @@ GetFileInfo(Path path, FileInfo &info, bool follow_symlinks=true)
{ {
#ifdef WIN32 #ifdef WIN32
(void)follow_symlinks; (void)follow_symlinks;
return stat(path.c_str(), &info.st) == 0; return GetFileAttributesEx(path.c_str(), GetFileExInfoStandard,
&info.data);
#else #else
int ret = follow_symlinks int ret = follow_symlinks
? stat(path.c_str(), &info.st) ? 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); bool success = GetFileInfo(path, info, follow_symlinks);
if (!success) { if (!success) {
const auto path_utf8 = path.ToUTF8(); 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()); error.FormatErrno("Failed to access %s", path_utf8.c_str());
#endif
} }
return success; return success;