diff --git a/src/partitionmanager.cpp b/src/partitionmanager.cpp index f557d5c..66ac962 100644 --- a/src/partitionmanager.cpp +++ b/src/partitionmanager.cpp @@ -276,13 +276,14 @@ void PartitionManagerPrivate::refresh(const Partitions &partitions, Partitions & } } -void PartitionManagerPrivate::lock(const Partition &partition) +void PartitionManagerPrivate::lock(const QString &devicePath) { - qCInfo(lcMemoryCardLog) << "Can lock:" << externalMedia.match(partition.deviceName()).hasMatch() << partition.devicePath(); - if (externalMedia.match(partition.deviceName()).hasMatch()) { - m_udisksMonitor->lock(partition.devicePath()); + QString deviceName = devicePath.section(QChar('/'), 2); + qCInfo(lcMemoryCardLog) << "Can lock:" << externalMedia.match(deviceName) << devicePath; + if (externalMedia.match(deviceName).hasMatch()) { + m_udisksMonitor->lock(devicePath); } else { - qCWarning(lcMemoryCardLog) << "Lock allowed only for external memory cards," << partition.devicePath() << "is not allowed"; + qCWarning(lcMemoryCardLog) << "Lock allowed only for external memory cards," << devicePath << "is not allowed"; } } diff --git a/src/partitionmanager_p.h b/src/partitionmanager_p.h index 1553a74..0ab9374 100644 --- a/src/partitionmanager_p.h +++ b/src/partitionmanager_p.h @@ -66,7 +66,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData void refresh(PartitionPrivate *partition); void refresh(const Partitions &partitions, Partitions &changedPartitions); - void lock(const Partition &partition); + void lock(const QString &devicePath); void unlock(const Partition &partition, const QString &passphrase); void mount(const Partition &partition); void unmount(const Partition &partition); diff --git a/src/partitionmodel.cpp b/src/partitionmodel.cpp index 95d4d6a..b7b8151 100644 --- a/src/partitionmodel.cpp +++ b/src/partitionmodel.cpp @@ -122,11 +122,7 @@ void PartitionModel::refresh(int index) void PartitionModel::lock(const QString &devicePath) { qCInfo(lcMemoryCardLog) << Q_FUNC_INFO << devicePath << m_partitions.count(); - if (const Partition *partition = getPartition(devicePath)) { - m_manager->lock(*partition); - } else { - qCWarning(lcMemoryCardLog) << "Unable to lock unknown device:" << devicePath; - } + m_manager->lock(devicePath); } void PartitionModel::unlock(const QString &devicePath, const QString &passphrase) diff --git a/src/udisks2block.cpp b/src/udisks2block.cpp index 5db1817..4b07434 100644 --- a/src/udisks2block.cpp +++ b/src/udisks2block.cpp @@ -16,6 +16,7 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap & , m_mountable(interfacePropertyMap.contains(UDISKS2_FILESYSTEM_INTERFACE)) , m_encrypted(interfacePropertyMap.contains(UDISKS2_ENCRYPTED_INTERFACE)) , m_formatting(false) + , m_locking(false) , m_pendingFileSystem(nullptr) , m_pendingBlock(nullptr) , m_pendingEncrypted(nullptr) @@ -204,6 +205,16 @@ void UDisks2::Block::setFormatting() m_formatting = true; } +bool UDisks2::Block::isLocking() const +{ + return m_locking; +} + +void UDisks2::Block::setLocking() +{ + m_locking = true; +} + bool UDisks2::Block::isReadOnly() const { return value(QStringLiteral("ReadOnly")).toBool(); diff --git a/src/udisks2block_p.h b/src/udisks2block_p.h index 75f9ccf..65e9423 100644 --- a/src/udisks2block_p.h +++ b/src/udisks2block_p.h @@ -76,6 +76,9 @@ class Block : public QObject bool isFormatting() const; void setFormatting(); + bool isLocking() const; + void setLocking(); + bool isReadOnly() const; bool isExternal() const; @@ -117,6 +120,7 @@ private slots: bool m_mountable; bool m_encrypted; bool m_formatting; + bool m_locking; QDBusPendingCallWatcher *m_pendingFileSystem; QDBusPendingCallWatcher *m_pendingBlock; diff --git a/src/udisks2monitor.cpp b/src/udisks2monitor.cpp index dc10ca8..622bcc2 100644 --- a/src/udisks2monitor.cpp +++ b/src/udisks2monitor.cpp @@ -137,7 +137,23 @@ void UDisks2::Monitor::lock(const QString &devicePath) QVariantList arguments; QVariantMap options; arguments << options; - startLuksOperation(devicePath, UDISKS2_ENCRYPTED_LOCK, objectPath(devicePath), arguments); + + for (QMap::const_iterator i = m_blockDevices.begin(); i != m_blockDevices.end(); ++i) { + Block *block = i.value(); + if (block->device() == devicePath || block->cryptoBackingDevicePath() == devicePath) { + block->dumpInfo(); + block->setLocking(); + + // Unmount if mounted. + if (!block->mountPath().isEmpty()) { + m_operationQueue.enqueue(Operation(UDISKS2_ENCRYPTED_LOCK, devicePath)); + unmount(block->device()); + } else { + startLuksOperation(devicePath, UDISKS2_ENCRYPTED_LOCK, objectPath(devicePath), arguments); + } + break; + } + } } void UDisks2::Monitor::unlock(const QString &devicePath, const QString &passphrase) @@ -194,7 +210,7 @@ void UDisks2::Monitor::format(const QString &devicePath, const QString &type, co for (auto partition : affectedPartitions) { if (partition->status == Partition::Mounted) { - m_operationQueue.enqueue(Operation(QStringLiteral("format"), devicePath, objectPath, type, arguments)); + m_operationQueue.enqueue(Operation(UDISKS2_BLOCK_FORMAT, devicePath, objectPath, type, arguments)); unmount(devicePath); return; } @@ -263,6 +279,13 @@ void UDisks2::Monitor::interfacesRemoved(const QDBusObjectPath &objectPath, cons } UDisks2::Block *block = m_blockDevices.take(path); + + // Crypto device got removed + bool deviceMapped = path.startsWith(QStringLiteral("/org/freedesktop/UDisks2/block_devices/dm_")); + if (deviceMapped && block->isLocking()) { + createBlockDevice(block->cryptoBackingDeviceObjectPath(), UDisks2::InterfacePropertyMap()); + } + block->deleteLater(); } else if (m_blockDevices.contains(path) && interfaces.contains(UDISKS2_FILESYSTEM_INTERFACE)) { UDisks2::Block *block = m_blockDevices.value(path); @@ -648,9 +671,12 @@ void UDisks2::Monitor::createBlockDevice(const QString &dbusObjectPath, const UD if (!m_operationQueue.isEmpty()) { Operation op = m_operationQueue.head(); - if (op.command == QStringLiteral("format") && block->mountPath().isEmpty()) { + if (op.command == UDISKS2_BLOCK_FORMAT && block->mountPath().isEmpty()) { m_operationQueue.dequeue(); doFormat(op.devicePath, op.dbusObjectPath, op.type, op.arguments); + } else if (op.command == UDISKS2_ENCRYPTED_LOCK && block->mountPath().isEmpty()) { + m_operationQueue.dequeue(); + lock(op.devicePath); } } }); @@ -720,6 +746,8 @@ QString UDisks2::Monitor::objectPath(const QString &devicePath) const Block *block = i.value(); if (block->device() == devicePath) { return block->path(); + } else if (block->cryptoBackingDevicePath() == devicePath) { + return block->cryptoBackingDeviceObjectPath(); } } diff --git a/src/udisks2monitor_p.h b/src/udisks2monitor_p.h index b45590e..d508927 100644 --- a/src/udisks2monitor_p.h +++ b/src/udisks2monitor_p.h @@ -54,7 +54,7 @@ class Job; struct Operation { - Operation(const QString &command, const QString &devicePath, const QString &dbusObjectPath, const QString &type, const QVariantHash &arguments) + Operation(const QString &command, const QString &devicePath, const QString &dbusObjectPath = QString(), const QString &type = QString(), const QVariantHash &arguments = QVariantHash()) : command(command) , devicePath(devicePath) , dbusObjectPath(dbusObjectPath)