1 /*
2     kdiskfreespaceinfo.h
3     SPDX-FileCopyrightText: 2008 Sebastian Trug <trueg@kde.org>
4 
5     Based on kdiskfreespace.h
6     SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org>
7     SPDX-FileCopyrightText: 2008 Dirk Mueller <mueller@kde.org>
8 
9     SPDX-License-Identifier: LGPL-2.0-only
10 */
11 
12 #include "kdiskfreespaceinfo.h"
13 
14 #include <QFile>
15 #include <QSharedData>
16 
17 #include <kmountpoint.h>
18 
19 #ifdef Q_OS_WIN
20 #include <QDir>
21 #include <qt_windows.h>
22 #else
23 #include <sys/statvfs.h>
24 #endif
25 
26 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 88)
27 class KDiskFreeSpaceInfoPrivate : public QSharedData
28 {
29 public:
30     bool m_valid = false;
31     QString m_mountPoint;
32     KIO::filesize_t m_size = 0;
33     KIO::filesize_t m_available = 0;
34 };
35 
KDiskFreeSpaceInfo()36 KDiskFreeSpaceInfo::KDiskFreeSpaceInfo()
37     : d(new KDiskFreeSpaceInfoPrivate)
38 {
39 }
40 
KDiskFreeSpaceInfo(const KDiskFreeSpaceInfo & other)41 KDiskFreeSpaceInfo::KDiskFreeSpaceInfo(const KDiskFreeSpaceInfo &other)
42 {
43     d = other.d;
44 }
45 
~KDiskFreeSpaceInfo()46 KDiskFreeSpaceInfo::~KDiskFreeSpaceInfo()
47 {
48 }
49 
operator =(const KDiskFreeSpaceInfo & other)50 KDiskFreeSpaceInfo &KDiskFreeSpaceInfo::operator=(const KDiskFreeSpaceInfo &other)
51 {
52     d = other.d;
53     return *this;
54 }
55 
isValid() const56 bool KDiskFreeSpaceInfo::isValid() const
57 {
58     return d->m_valid;
59 }
60 
mountPoint() const61 QString KDiskFreeSpaceInfo::mountPoint() const
62 {
63     return d->m_mountPoint;
64 }
65 
size() const66 KIO::filesize_t KDiskFreeSpaceInfo::size() const
67 {
68     return d->m_size;
69 }
70 
available() const71 KIO::filesize_t KDiskFreeSpaceInfo::available() const
72 {
73     return d->m_available;
74 }
75 
used() const76 KIO::filesize_t KDiskFreeSpaceInfo::used() const
77 {
78     return d->m_size - d->m_available;
79 }
80 
freeSpaceInfo(const QString & path)81 KDiskFreeSpaceInfo KDiskFreeSpaceInfo::freeSpaceInfo(const QString &path)
82 {
83     KDiskFreeSpaceInfo info;
84 
85     // determine the mount point
86     KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(path);
87     if (mp) {
88         info.d->m_mountPoint = mp->mountPoint();
89     }
90 
91 #ifdef Q_OS_WIN
92     quint64 availUser;
93     QFileInfo fi(info.d->m_mountPoint);
94     QString dir = QDir::toNativeSeparators(fi.absoluteDir().canonicalPath());
95 
96     if (GetDiskFreeSpaceExW((LPCWSTR)dir.utf16(), (PULARGE_INTEGER)&availUser, (PULARGE_INTEGER)&info.d->m_size, (PULARGE_INTEGER)&info.d->m_available) != 0) {
97         info.d->m_valid = true;
98     }
99 #else
100     struct statvfs statvfs_buf;
101 
102     // Prefer mountPoint if available, so that it even works with non-existing files.
103     const QString pathArg = info.d->m_mountPoint.isEmpty() ? path : info.d->m_mountPoint;
104     if (!statvfs(QFile::encodeName(pathArg).constData(), &statvfs_buf)) {
105         const quint64 blksize = quint64(statvfs_buf.f_frsize); // cast to avoid overflow
106         info.d->m_available = statvfs_buf.f_bavail * blksize;
107         info.d->m_size = statvfs_buf.f_blocks * blksize;
108         info.d->m_valid = true;
109     }
110 #endif
111 
112     return info;
113 }
114 #endif // Deprecation
115