2019-02-22 20:24:38 +01:00
|
|
|
/*
|
|
|
|
* Strawberry Music Player
|
|
|
|
* This file was part of Clementine.
|
|
|
|
* Copyright 2016, Valeriy Malov <jazzvoid@gmail.com>
|
2021-03-20 21:14:47 +01:00
|
|
|
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
2019-02-22 20:24:38 +01:00
|
|
|
*
|
|
|
|
* Strawberry is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Strawberry is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2021-06-21 15:40:25 +02:00
|
|
|
#include <memory>
|
2021-08-22 23:26:53 +02:00
|
|
|
#include <utility>
|
2021-06-21 15:40:25 +02:00
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QMutex>
|
|
|
|
#include <QList>
|
2022-08-28 03:09:33 +02:00
|
|
|
#include <QVariantList>
|
|
|
|
#include <QVariantMap>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QString>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QUrl>
|
|
|
|
#include <QReadLocker>
|
|
|
|
#include <QWriteLocker>
|
|
|
|
#include <QDBusObjectPath>
|
2018-02-27 18:06:05 +01:00
|
|
|
#include <QDBusConnection>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QDBusError>
|
|
|
|
#include <QDBusPendingReply>
|
|
|
|
#include <QDBusArgument>
|
|
|
|
#include <QJsonArray>
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
#include "core/logging.h"
|
2023-07-21 05:55:24 +02:00
|
|
|
#include "core/scoped_ptr.h"
|
|
|
|
#include "core/shared_ptr.h"
|
2022-12-28 03:12:00 +01:00
|
|
|
#include "utilities/diskutils.h"
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
#include "udisks2lister.h"
|
|
|
|
|
2022-09-13 17:53:57 +02:00
|
|
|
#include "objectmanager.h"
|
|
|
|
#include "udisks2block.h"
|
|
|
|
#include "udisks2drive.h"
|
|
|
|
#include "udisks2filesystem.h"
|
|
|
|
#include "udisks2job.h"
|
|
|
|
|
2023-07-21 05:55:24 +02:00
|
|
|
using std::make_unique;
|
|
|
|
using std::make_shared;
|
|
|
|
|
2021-06-20 19:04:08 +02:00
|
|
|
Udisks2Lister::Udisks2Lister(QObject *parent) : DeviceLister(parent) {}
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2021-06-21 15:38:58 +02:00
|
|
|
Udisks2Lister::~Udisks2Lister() = default;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
QStringList Udisks2Lister::DeviceUniqueIDs() {
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
return device_data_.keys();
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariantList Udisks2Lister::DeviceIcons(const QString &id) {
|
2020-09-02 19:34:46 +02:00
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return QVariantList();
|
|
|
|
QString path = device_data_[id].mount_paths.at(0);
|
|
|
|
|
|
|
|
return QVariantList() << GuessIconForPath(path) << GuessIconForModel(DeviceManufacturer(id), DeviceModel(id));
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QString Udisks2Lister::DeviceManufacturer(const QString &id) {
|
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return "";
|
|
|
|
return device_data_[id].vendor;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Udisks2Lister::DeviceModel(const QString &id) {
|
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return "";
|
|
|
|
return device_data_[id].model;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
quint64 Udisks2Lister::DeviceCapacity(const QString &id) {
|
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return 0;
|
|
|
|
return device_data_[id].capacity;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
quint64 Udisks2Lister::DeviceFreeSpace(const QString &id) {
|
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return 0;
|
|
|
|
return device_data_[id].free_space;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariantMap Udisks2Lister::DeviceHardwareInfo(const QString &id) {
|
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return QVariantMap();
|
|
|
|
|
|
|
|
QVariantMap result;
|
|
|
|
|
2021-08-22 23:27:25 +02:00
|
|
|
const PartitionData &data = device_data_[id];
|
2021-06-25 18:19:37 +02:00
|
|
|
result[QT_TR_NOOP("D-Bus path")] = data.dbus_path;
|
|
|
|
result[QT_TR_NOOP("Serial number")] = data.serial;
|
|
|
|
result[QT_TR_NOOP("Mount points")] = data.mount_paths.join(", ");
|
|
|
|
result[QT_TR_NOOP("Partition label")] = data.label;
|
|
|
|
result[QT_TR_NOOP("UUID")] = data.uuid;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Udisks2Lister::MakeFriendlyName(const QString &id) {
|
2020-09-02 19:34:46 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return "";
|
|
|
|
return device_data_[id].friendly_name;
|
2020-09-02 19:34:46 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QList<QUrl> Udisks2Lister::MakeDeviceUrls(const QString &id) {
|
2020-09-02 19:34:46 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
QReadLocker locker(&device_data_lock_);
|
2019-07-19 19:22:14 +02:00
|
|
|
QList<QUrl> ret;
|
|
|
|
if (!device_data_.contains(id)) return ret;
|
2020-09-02 19:34:46 +02:00
|
|
|
ret << MakeUrlFromLocalPath(device_data_[id].mount_paths.at(0));
|
2019-07-19 19:22:14 +02:00
|
|
|
return ret;
|
2020-09-02 19:34:46 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Udisks2Lister::UnmountDevice(const QString &id) {
|
|
|
|
|
|
|
|
QReadLocker locker(&device_data_lock_);
|
|
|
|
if (!device_data_.contains(id)) return;
|
|
|
|
|
2018-03-10 13:02:56 +01:00
|
|
|
OrgFreedesktopUDisks2FilesystemInterface filesystem(udisks2_service_, device_data_[id].dbus_path, QDBusConnection::systemBus());
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
if (filesystem.isValid()) {
|
|
|
|
auto unmount_result = filesystem.Unmount(QVariantMap());
|
|
|
|
unmount_result.waitForFinished();
|
|
|
|
|
|
|
|
if (unmount_result.isError()) {
|
|
|
|
qLog(Warning) << "Failed to unmount " << id << ": " << unmount_result.error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
OrgFreedesktopUDisks2DriveInterface drive(udisks2_service_, device_data_[id].dbus_drive_path, QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
if (drive.isValid()) {
|
|
|
|
auto eject_result = drive.Eject(QVariantMap());
|
|
|
|
eject_result.waitForFinished();
|
|
|
|
|
2021-08-23 21:21:08 +02:00
|
|
|
if (eject_result.isError()) {
|
2018-02-27 18:06:05 +01:00
|
|
|
qLog(Warning) << "Failed to eject " << id << ": " << eject_result.error();
|
2021-08-23 21:21:08 +02:00
|
|
|
}
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
device_data_.remove(id);
|
2021-03-21 04:47:11 +01:00
|
|
|
emit DeviceRemoved(id);
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Udisks2Lister::UpdateDeviceFreeSpace(const QString &id) {
|
|
|
|
QWriteLocker locker(&device_data_lock_);
|
2018-05-01 00:41:33 +02:00
|
|
|
device_data_[id].free_space = Utilities::FileSystemFreeSpace(device_data_[id].mount_paths.at(0));
|
2018-02-27 18:06:05 +01:00
|
|
|
emit DeviceChanged(id);
|
|
|
|
}
|
|
|
|
|
2018-12-29 02:57:22 +01:00
|
|
|
bool Udisks2Lister::Init() {
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2023-07-21 05:55:24 +02:00
|
|
|
udisks2_interface_ = make_unique<OrgFreedesktopDBusObjectManagerInterface>(udisks2_service_, "/org/freedesktop/UDisks2", QDBusConnection::systemBus());
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
QDBusPendingReply<ManagedObjectList> reply = udisks2_interface_->GetManagedObjects();
|
|
|
|
reply.waitForFinished();
|
|
|
|
|
|
|
|
if (!reply.isValid()) {
|
|
|
|
qLog(Warning) << "Error enumerating udisks2 devices:" << reply.error().name() << reply.error().message();
|
|
|
|
udisks2_interface_.reset();
|
2018-12-29 02:57:22 +01:00
|
|
|
return false;
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
2021-03-21 04:47:11 +01:00
|
|
|
QList<QDBusObjectPath> paths = reply.value().keys();
|
|
|
|
for (const QDBusObjectPath &path : paths) {
|
2021-08-22 23:29:44 +02:00
|
|
|
PartitionData partition_data = ReadPartitionData(path);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
if (!partition_data.dbus_path.isEmpty()) {
|
|
|
|
QWriteLocker locker(&device_data_lock_);
|
|
|
|
device_data_[partition_data.unique_id()] = partition_data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-21 04:47:11 +01:00
|
|
|
QStringList ids = device_data_.keys();
|
|
|
|
for (const QString &id : ids) {
|
2018-02-27 18:06:05 +01:00
|
|
|
emit DeviceAdded(id);
|
|
|
|
}
|
|
|
|
|
2023-07-21 05:55:24 +02:00
|
|
|
QObject::connect(&*udisks2_interface_, &OrgFreedesktopDBusObjectManagerInterface::InterfacesAdded, this, &Udisks2Lister::DBusInterfaceAdded);
|
|
|
|
QObject::connect(&*udisks2_interface_, &OrgFreedesktopDBusObjectManagerInterface::InterfacesRemoved, this, &Udisks2Lister::DBusInterfaceRemoved);
|
2018-03-10 13:02:56 +01:00
|
|
|
|
2018-12-29 02:57:22 +01:00
|
|
|
return true;
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Udisks2Lister::DBusInterfaceAdded(const QDBusObjectPath &path, const InterfacesAndProperties &interfaces) {
|
|
|
|
|
|
|
|
for (auto interface = interfaces.constBegin(); interface != interfaces.constEnd(); ++interface) {
|
|
|
|
|
|
|
|
if (interface.key() != "org.freedesktop.UDisks2.Job") continue;
|
|
|
|
|
2023-07-21 05:55:24 +02:00
|
|
|
SharedPtr<OrgFreedesktopUDisks2JobInterface> job = make_shared<OrgFreedesktopUDisks2JobInterface>(udisks2_service_, path.path(), QDBusConnection::systemBus());
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
if (!job->isValid()) continue;
|
|
|
|
|
|
|
|
bool is_mount_job = false;
|
|
|
|
if (job->operation() == "filesystem-mount") {
|
|
|
|
is_mount_job = true;
|
|
|
|
}
|
|
|
|
else if (job->operation() == "filesystem-unmount") {
|
|
|
|
is_mount_job = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto mounted_partitions = job->objects();
|
|
|
|
|
|
|
|
if (mounted_partitions.isEmpty()) {
|
|
|
|
qLog(Warning) << "Empty Udisks2 mount/umount job " << path.path();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&jobs_lock_);
|
|
|
|
qLog(Debug) << "Adding pending job | DBus Path = " << job->path() << " | IsMountJob = " << is_mount_job << " | First partition = " << mounted_partitions.at(0).path();
|
|
|
|
mounting_jobs_[path].dbus_interface = job;
|
|
|
|
mounting_jobs_[path].is_mount = is_mount_job;
|
|
|
|
mounting_jobs_[path].mounted_partitions = mounted_partitions;
|
2023-07-21 05:55:24 +02:00
|
|
|
QObject::connect(&*job, &OrgFreedesktopUDisks2JobInterface::Completed, this, &Udisks2Lister::JobCompleted);
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-14 18:58:24 +02:00
|
|
|
void Udisks2Lister::DBusInterfaceRemoved(const QDBusObjectPath &path, const QStringList &interfaces) {
|
|
|
|
Q_UNUSED(interfaces);
|
2018-02-27 18:06:05 +01:00
|
|
|
if (!isPendingJob(path)) RemoveDevice(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Udisks2Lister::isPendingJob(const QDBusObjectPath &job_path) {
|
2018-03-10 13:02:56 +01:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
QMutexLocker locker(&jobs_lock_);
|
|
|
|
|
|
|
|
if (!mounting_jobs_.contains(job_path)) return false;
|
|
|
|
|
|
|
|
mounting_jobs_.remove(job_path);
|
|
|
|
return true;
|
2018-03-10 13:02:56 +01:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Udisks2Lister::RemoveDevice(const QDBusObjectPath &device_path) {
|
|
|
|
|
|
|
|
QWriteLocker locker(&device_data_lock_);
|
|
|
|
QString id;
|
2021-08-22 23:26:53 +02:00
|
|
|
for (const PartitionData &data : std::as_const(device_data_)) {
|
2018-02-27 18:06:05 +01:00
|
|
|
if (data.dbus_path == device_path.path()) {
|
|
|
|
id = data.unique_id();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (id.isEmpty()) return;
|
|
|
|
|
|
|
|
qLog(Debug) << "UDisks2 device removed: " << device_path.path();
|
|
|
|
device_data_.remove(id);
|
2021-03-21 04:47:11 +01:00
|
|
|
|
|
|
|
emit DeviceRemoved(id);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<QDBusObjectPath> Udisks2Lister::GetMountedPartitionsFromDBusArgument(const QDBusArgument &input) {
|
|
|
|
|
|
|
|
QList<QDBusObjectPath> result;
|
|
|
|
|
|
|
|
input.beginArray();
|
|
|
|
while (!input.atEnd()) {
|
|
|
|
QDBusObjectPath extractedPath;
|
|
|
|
input >> extractedPath;
|
|
|
|
result.push_back(extractedPath);
|
|
|
|
}
|
|
|
|
input.endArray();
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-06-12 16:06:30 +02:00
|
|
|
void Udisks2Lister::JobCompleted(const bool success, const QString &message) {
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2019-09-15 20:27:32 +02:00
|
|
|
Q_UNUSED(message);
|
|
|
|
|
2021-08-22 23:27:25 +02:00
|
|
|
OrgFreedesktopUDisks2JobInterface *job = qobject_cast<OrgFreedesktopUDisks2JobInterface*>(sender());
|
2018-02-27 18:06:05 +01:00
|
|
|
QDBusObjectPath jobPath(job->path());
|
|
|
|
|
2021-08-23 21:21:08 +02:00
|
|
|
if (!job->isValid() || !success || !mounting_jobs_.contains(jobPath)) {
|
|
|
|
return;
|
|
|
|
}
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
qLog(Debug) << "Pending Job Completed | Path = " << job->path() << " | Mount? = " << mounting_jobs_[jobPath].is_mount << " | Success = " << success;
|
|
|
|
|
|
|
|
for (const auto &mounted_object : mounting_jobs_[jobPath].mounted_partitions) {
|
|
|
|
auto partition_data = ReadPartitionData(mounted_object);
|
|
|
|
if (partition_data.dbus_path.isEmpty()) continue;
|
|
|
|
|
|
|
|
mounting_jobs_[jobPath].is_mount ? HandleFinishedMountJob(partition_data) : HandleFinishedUnmountJob(partition_data, mounted_object);
|
|
|
|
}
|
2018-03-10 13:02:56 +01:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
2021-08-22 23:29:44 +02:00
|
|
|
void Udisks2Lister::HandleFinishedMountJob(const PartitionData &partition_data) {
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
qLog(Debug) << "UDisks2 mount job finished: Drive = " << partition_data.dbus_drive_path << " | Partition = " << partition_data.dbus_path;
|
|
|
|
QWriteLocker locker(&device_data_lock_);
|
|
|
|
device_data_[partition_data.unique_id()] = partition_data;
|
2021-03-21 04:47:11 +01:00
|
|
|
|
|
|
|
emit DeviceAdded(partition_data.unique_id());
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-08-22 23:29:44 +02:00
|
|
|
void Udisks2Lister::HandleFinishedUnmountJob(const PartitionData &partition_data, const QDBusObjectPath &mounted_object) {
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
QWriteLocker locker(&device_data_lock_);
|
|
|
|
QString id;
|
2021-08-22 23:27:25 +02:00
|
|
|
for (PartitionData &data : device_data_) {
|
2018-02-27 18:06:05 +01:00
|
|
|
if (data.mount_paths.contains(mounted_object.path())) {
|
|
|
|
qLog(Debug) << "UDisks2 umount job finished, found corresponding device: Drive = " << data.dbus_drive_path << " | Partition = " << data.dbus_path;
|
|
|
|
data.mount_paths.removeOne(mounted_object.path());
|
|
|
|
if (data.mount_paths.empty()) id = data.unique_id();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!id.isEmpty()) {
|
2018-03-10 13:02:56 +01:00
|
|
|
qLog(Debug) << "Partition " << partition_data.dbus_path << " has no more mount points, removing it from device list";
|
2018-02-27 18:06:05 +01:00
|
|
|
device_data_.remove(id);
|
2021-03-21 04:47:11 +01:00
|
|
|
emit DeviceRemoved(id);
|
2018-02-27 18:06:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Udisks2Lister::PartitionData Udisks2Lister::ReadPartitionData(const QDBusObjectPath &path) {
|
|
|
|
|
|
|
|
PartitionData result;
|
|
|
|
OrgFreedesktopUDisks2FilesystemInterface filesystem(udisks2_service_, path.path(), QDBusConnection::systemBus());
|
|
|
|
OrgFreedesktopUDisks2BlockInterface block(udisks2_service_, path.path(), QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
if (filesystem.isValid() && block.isValid() && !filesystem.mountPoints().empty()) {
|
|
|
|
OrgFreedesktopUDisks2DriveInterface drive(udisks2_service_, block.drive().path(), QDBusConnection::systemBus());
|
|
|
|
|
|
|
|
if (drive.isValid() && drive.mediaRemovable()) {
|
|
|
|
result.dbus_path = path.path();
|
|
|
|
result.dbus_drive_path = block.drive().path();
|
|
|
|
|
|
|
|
result.serial = drive.serial();
|
|
|
|
result.vendor = drive.vendor();
|
|
|
|
result.model = drive.model();
|
|
|
|
|
|
|
|
result.label = block.idLabel();
|
|
|
|
result.uuid = block.idUUID();
|
|
|
|
result.capacity = drive.size();
|
|
|
|
|
2020-12-06 18:46:30 +01:00
|
|
|
if (result.label.isEmpty()) {
|
2018-02-27 18:06:05 +01:00
|
|
|
result.friendly_name = result.model + " " + result.uuid;
|
2020-12-06 18:46:30 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
result.friendly_name = result.label;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const QByteArray &p : filesystem.mountPoints()) {
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // Workaround a bytearray to string conversion issue with Qt 6
|
2021-10-30 02:21:29 +02:00
|
|
|
QString mountpoint = QByteArray(p.data(), static_cast<qint64>(strlen(p.data())));
|
2020-12-06 18:46:30 +01:00
|
|
|
#else
|
|
|
|
QString mountpoint = p;
|
|
|
|
#endif
|
|
|
|
result.mount_paths.push_back(mountpoint);
|
|
|
|
}
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
result.free_space = Utilities::FileSystemFreeSpace(result.mount_paths.at(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Udisks2Lister::PartitionData::unique_id() const {
|
|
|
|
return QString("Udisks2/%1/%2/%3/%4/%5")
|
|
|
|
.arg(serial, vendor, model)
|
|
|
|
.arg(capacity)
|
|
|
|
.arg(uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
Udisks2Lister::Udisks2Job::Udisks2Job() : is_mount(true) {}
|
|
|
|
|
|
|
|
Udisks2Lister::PartitionData::PartitionData() : capacity(0), free_space(0) {}
|