QList<VolumeInfo> RunInfo::mountedVolumes() { QList<VolumeInfo> result; FSVolumeRefNum volume; FSVolumeInfo info; HFSUniStr255 volName; FSRef ref; int i = 0; while (FSGetVolumeInfo(kFSInvalidVolumeRefNum, ++i, &volume, kFSVolInfoFSInfo, &info, &volName, &ref) == 0) { UInt8 path[PATH_MAX + 1]; if (FSRefMakePath(&ref, path, PATH_MAX) == 0) { FSGetVolumeInfo(volume, 0, 0, kFSVolInfoSizes, &info, 0, 0); VolumeInfo v; v.setSize(quint64(info.totalBytes)); v.setAvailableSize(quint64(info.freeBytes)); v.setMountPath(QString::fromLocal8Bit(reinterpret_cast< char* >(path))); struct statfs data; if (statfs(qPrintable(v.mountPath() + QLatin1String("/.")), &data) == 0) { v.setFileSystemType(QLatin1String(data.f_fstypename)); v.setVolumeDescriptor(QLatin1String(data.f_mntfromname)); } result.append(v); } } return result; }
/*! Returns a list of volume info objects that are mounted as network drive shares. */ QList<VolumeInfo> networkVolumeInfosFromMountPoints() { QList<VolumeInfo> volumes; QFileInfoList drives = QDir::drives(); foreach (const QFileInfo &drive, drives) { const QString driveLetter = QDir::toNativeSeparators(drive.canonicalPath()); const uint driveType = GetDriveTypeA(qPrintable(driveLetter)); switch (driveType) { case DRIVE_REMOTE: { char buffer[1024] = ""; DWORD bufferLength = 1024; UNIVERSAL_NAME_INFOA *universalNameInfo = (UNIVERSAL_NAME_INFOA*) &buffer; if (WNetGetUniversalNameA(qPrintable(driveLetter), UNIVERSAL_NAME_INFO_LEVEL, LPVOID(universalNameInfo), &bufferLength) == NO_ERROR) { VolumeInfo info; info.setMountPath(driveLetter); info.setVolumeDescriptor(QLatin1String(universalNameInfo->lpUniversalName)); volumes.append(info); } } break; default: break; } } return volumes; }
QList<VolumeInfo> mountedVolumes() { QList<VolumeInfo> result; QFile f(QLatin1String("/etc/mtab")); if (!f.open(QIODevice::ReadOnly)) { qCritical("%s: Cannot open %s: %s", Q_FUNC_INFO, qPrintable(f.fileName()), qPrintable(f.errorString())); return result; //better error-handling? } QTextStream stream(&f); while (true) { const QString s = stream.readLine(); if (s.isNull()) return result; if (!s.startsWith(QLatin1Char('/')) && !s.startsWith(QLatin1String("tmpfs ") + QDir::tempPath())) continue; const QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts); VolumeInfo v; v.setMountPath(parts.at(1)); v.setVolumeDescriptor(parts.at(0)); v.setFileSystemType(parts.value(2)); struct statvfs data; if (statvfs(qPrintable(v.mountPath() + QLatin1String("/.")), &data) == 0) { v.setSize(quint64(static_cast<quint64>(data.f_blocks) * data.f_bsize)); v.setAvailableSize(quint64(static_cast<quint64>(data.f_bavail) * data.f_bsize)); } result.append(v); } return result; }
/*! Returns a list of volume info objects based on the given \a volumeGUID. The function also solves mounted volume folder paths. It does not return any network drive shares. */ QList<VolumeInfo> localVolumeInfosFromMountPoints(PTCHAR volumeGUID) { #ifndef UNICODE #define fromWCharArray fromLatin1 #endif QList<VolumeInfo> volumes; DWORD bufferSize; TCHAR volumeNames[MAX_PATH + 1] = { 0 }; if (GetVolumePathNamesForVolumeName(volumeGUID, volumeNames, MAX_PATH, &bufferSize)) { QStringList mountedPaths = QString::fromWCharArray(volumeNames, bufferSize).split(QLatin1Char(char(0)), QString::SkipEmptyParts); foreach (const QString &mountedPath, mountedPaths) { VolumeInfo info; info.setMountPath(mountedPath); info.setVolumeDescriptor(QString::fromWCharArray(volumeGUID)); volumes.append(info); }