#include "FileFunctions.h" #include QString Sao::longFilePath(const QString& path) { // get full path DWORD size = GetFullPathNameW((LPCWSTR)path.utf16(), 0, NULL, NULL); if (size < 2) return QString(); QString longPath(size - 1, 0); size = GetFullPathNameW((LPCWSTR)path.utf16(), size, (LPWSTR)longPath.data(), NULL); if (size < DWORD(longPath.size())) longPath.resize(size); // the actual number of characters might be less than the initial estimate // prepend long path syntax if (longPath.startsWith(QStringLiteral("\\\\?\\"))) return longPath; // already long path syntax if (longPath.startsWith(QStringLiteral("\\\\"))) longPath.insert(2, QStringLiteral("?\\UNC\\")); else longPath.prepend(QStringLiteral("\\\\?\\")); return longPath; } quint32 Sao::fileAttributes(const QString& path, quint32 mask /*= 0xFFFFFFFF*/) { return (GetFileAttributesW((LPCWSTR)longFilePath(path).utf16()) & mask); } bool Sao::setFileAttributes(const QString& path, quint32 attributes, quint32 mask /*= 0xFFFFFFFF*/) { quint32 attr = fileAttributes(path); if ((attr & mask) == (attributes & mask)) return true; // existing attributes are correct attr = (attr & ~mask) | (attributes & mask); return (SetFileAttributesW((LPCWSTR)longFilePath(path).utf16(), attr) != 0); } bool Sao::hasFileAttributeReadOnly(const QString& path) { return (fileAttributes(path, FILE_ATTRIBUTE_READONLY) != 0); } bool Sao::hasFileAttributeHidden(const QString& path) { return (fileAttributes(path, FILE_ATTRIBUTE_HIDDEN) != 0); } bool Sao::hasFileAttributeSystem(const QString& path) { return (fileAttributes(path, FILE_ATTRIBUTE_SYSTEM) != 0); } bool Sao::setFileAttributeReadOnly(const QString& path, bool readOnly) { return setFileAttributes(path, readOnly ? FILE_ATTRIBUTE_READONLY : 0, FILE_ATTRIBUTE_READONLY); } bool Sao::setFileAttributeHidden(const QString& path, bool hidden) { return setFileAttributes(path, hidden ? FILE_ATTRIBUTE_HIDDEN : 0, FILE_ATTRIBUTE_HIDDEN); } bool Sao::setFileAttributeSystem(const QString& path, bool system) { return setFileAttributes(path, system ? FILE_ATTRIBUTE_SYSTEM : 0, FILE_ATTRIBUTE_SYSTEM); } bool Sao::fileExists(const QString& path) { return (fileAttributes(path) != INVALID_FILE_ATTRIBUTES); } namespace // local helpers { bool getFileAttributes(const QString& path, WIN32_FILE_ATTRIBUTE_DATA* attributes) { return GetFileAttributesExW((LPCWSTR)Sao::longFilePath(path).utf16(), GetFileExInfoStandard, attributes); } QDateTime dateTimeFromLocalTime(const SYSTEMTIME& localTime) { QDate date(localTime.wYear, localTime.wMonth, localTime.wDay); QTime time(localTime.wHour, localTime.wMinute, localTime.wSecond, localTime.wMilliseconds); return QDateTime(date, time); } QDateTime dateTimeFromFileTime(const FILETIME& fileTime) { SYSTEMTIME systemTime; if (!FileTimeToSystemTime(&fileTime, &systemTime)) return QDateTime(); SYSTEMTIME localTime; if (!SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime)) return QDateTime(); return dateTimeFromLocalTime(localTime); } } // end local helpers quint64 Sao::fileSize(const QString& path) { WIN32_FILE_ATTRIBUTE_DATA attributes; if (!getFileAttributes(path, &attributes)) return quint64(INVALID_FILE_SIZE) << 32 | INVALID_FILE_SIZE; return quint64(attributes.nFileSizeHigh) << 32 | attributes.nFileSizeLow; } QDateTime Sao::fileTimeCreated(const QString& path) { WIN32_FILE_ATTRIBUTE_DATA attributes; if (!getFileAttributes(path, &attributes)) return QDateTime(); return dateTimeFromFileTime(attributes.ftCreationTime); } QDateTime Sao::fileTimeLastModified(const QString& path) { WIN32_FILE_ATTRIBUTE_DATA attributes; if (!getFileAttributes(path, &attributes)) return QDateTime(); return dateTimeFromFileTime(attributes.ftLastWriteTime); } QDateTime Sao::fileTimeLastAccessed(const QString& path) { WIN32_FILE_ATTRIBUTE_DATA attributes; if (!getFileAttributes(path, &attributes)) return QDateTime(); return dateTimeFromFileTime(attributes.ftLastAccessTime); }