diff --git a/src/backend/corebackend.h b/src/backend/corebackend.h index c2e1153..e44b740 100644 --- a/src/backend/corebackend.h +++ b/src/backend/corebackend.h @@ -1,191 +1,189 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #if !defined(KPMCORE_COREBACKEND_H) #define KPMCORE_COREBACKEND_H #include "util/libpartitionmanagerexport.h" #include "fs/filesystem.h" #include #include #include class CoreBackendManager; class CoreBackendDevice; class Device; class PartitionTable; class QString; /** * Interface class for backend plugins. * @author Volker Lanz */ class LIBKPMCORE_EXPORT CoreBackend : public QObject { Q_OBJECT Q_DISABLE_COPY(CoreBackend) friend class CoreBackendManager; protected: CoreBackend(); virtual ~CoreBackend(); Q_SIGNALS: /** * Emitted to inform about progress of any kind. * @param i the progress in percent (from 0 to 100) */ void progress(int i); /** * Emitted to inform about scan progress. * @param deviceNode the device being scanned just now (e.g. "/dev/sda") * @param i the progress in percent (from 0 to 100) */ void scanProgress(const QString& deviceNode, int i); public: /** * Return the plugin's unique Id from JSON metadata * @return the plugin's unique Id from JSON metadata */ QString id() { return m_id; } /** * Return the plugin's version from JSON metadata * @return the plugin's version from JSON metadata */ QString version() { return m_version; } /** * Initialize the plugin's FileSystem support */ virtual void initFSSupport() = 0; /** * Scan for devices in the system. * @param excludeReadOnly when true, devices that are read-only * according to the kernel are left out of the list. * When false (the default) all devices, writable or * not, including CD ROM devices, are returned. * @return a QList of pointers to Device instances. The caller is responsible * for deleting these objects. * @note A Device object is a description of the device, not * an object to operate on. See openDevice(). */ virtual QList scanDevices(bool excludeReadOnly = false) = 0; /** * Scan a single device in the system. * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda1) * @return FileSystem type of the device on deviceNode */ virtual FileSystem::Type detectFileSystem(const QString& deviceNode) = 0; /** * Read a file system label * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda1) * @return FileSystem label on deviceNode */ virtual QString readLabel(const QString& deviceNode) const = 0; /** * Read a file system UUID * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda1) * @return FileSystem UUID on deviceNode */ virtual QString readUUID(const QString& deviceNode) const = 0; /** * Scan a single device in the system. * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda) * @return a pointer to a Device instance. The caller is responsible for deleting * this object. */ virtual Device* scanDevice(const QString& deviceNode) = 0; /** * Open a device for reading. * @param deviceNode The path of the device that is to be opened (e.g. /dev/sda) - * @return a pointer to a CoreBackendDevice or nullptr if the open failed. If a pointer to - * an instance is returned, it's the caller's responsibility to delete the - * object. + * @return a pointer to a CoreBackendDevice or nullptr if the open failed. */ virtual std::unique_ptr openDevice(const Device& d) = 0; /** * Open a device in exclusive mode for writing. * @param deviceNode The path of the device that is to be opened (e.g. /dev/sda) * @return a pointer to a CoreBackendDevice or nullptr if the open failed. */ virtual std::unique_ptr openDeviceExclusive(const Device& d) = 0; /** * Close a CoreBackendDevice that has previously been opened. * @param core_device Pointer to the CoreBackendDevice to be closed. Must not be nullptr. * @return true if closing the CoreBackendDevice succeeded, otherwise false. */ virtual bool closeDevice(std::unique_ptr coreDevice) = 0; /** * Emit progress. * @param i the progress in percent (from 0 to 100) * This is used to emit a progress() signal from somewhere deep inside the plugin * backend code if that is ever necessary. */ virtual void emitProgress(int i); /** * Emit scan progress. * @param deviceNode the path to the device just being scanned (e.g. /dev/sda) * @param i the progress in percent (from 0 to 100) * This is used to emit a scanProgress() signal from the backend device scanning * code. */ virtual void emitScanProgress(const QString& deviceNode, int i); protected: static void setPartitionTableForDevice(Device& d, PartitionTable* p); static void setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries); private: void setId(const QString& id) { m_id = id; } void setVersion(const QString& version) { m_version = version; } private: QString m_id, m_version; class CoreBackendPrivate; std::unique_ptr d; }; #endif diff --git a/src/backend/corebackenddevice.h b/src/backend/corebackenddevice.h index b3c3126..0629f33 100644 --- a/src/backend/corebackenddevice.h +++ b/src/backend/corebackenddevice.h @@ -1,104 +1,105 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #if !defined(KPMCORE_COREBACKENDDEVICE_H) #define KPMCORE_COREBACKENDDEVICE_H +#include #include class CoreBackendPartition; class CoreBackendPartitionTable; class Partition; class PartitionTable; class Report; /** * Interface class for devices in the backend plugin. * For a device description, see Device. This * CoreBackendDevice can be used for (read- and) write * operations on the raw device. * * @author Volker Lanz */ class CoreBackendDevice { public: CoreBackendDevice(const QString& deviceNode); virtual ~CoreBackendDevice() {} public: /** * Get the device path for this device (e.g. "/dev/sda") * @return the device path */ virtual const QString& deviceNode() const { return m_DeviceNode; } /** * Determine if this device is opened in exclusive mode. * @return true if it is opened in exclusive mode, otherwise false */ virtual bool isExclusive() const { return m_Exclusive; } /** * Open the backend device * @return true if successful */ virtual bool open() = 0; /** * Open the backend device in exclusive mode * @return true if successful */ virtual bool openExclusive() = 0; /** * Close the backend device * @return true if successful */ virtual bool close() = 0; /** * Open this backend device's partition table * @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case * of errors */ - virtual CoreBackendPartitionTable* openPartitionTable() = 0; + virtual std::unique_ptr openPartitionTable() = 0; /** * Create a new partition table on this device. * @param report the Report to write information to * @param ptable the PartitionTable to create on this backend device * @return true if successful */ virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0; protected: void setExclusive(bool b) { m_Exclusive = b; } private: const QString m_DeviceNode; bool m_Exclusive; }; #endif diff --git a/src/backend/corebackendmanager.cpp b/src/backend/corebackendmanager.cpp index db60de9..1fbca68 100644 --- a/src/backend/corebackendmanager.cpp +++ b/src/backend/corebackendmanager.cpp @@ -1,137 +1,144 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * Copyright (C) 2015 by Teo Mrnjavac * * Copyright (C) 2016-2018 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "backend/corebackendmanager.h" -#include "backend/corebackendmanager_p.h" #include "backend/corebackend.h" #include #include #include #include #include #include #include #include #include #include #include #include +struct CoreBackendManagerPrivate +{ + KAuth::ExecuteJob *m_job; + CoreBackend *m_Backend; + + QString m_Uuid; +}; + CoreBackendManager::CoreBackendManager() : d(std::make_unique()) { startExternalCommandHelper(); } CoreBackendManager* CoreBackendManager::self() { static CoreBackendManager* instance = nullptr; if (instance == nullptr) instance = new CoreBackendManager; return instance; } CoreBackend* CoreBackendManager::backend() { return d->m_Backend; } QVector CoreBackendManager::list() const { auto filter = [&](const KPluginMetaData &metaData) { return metaData.serviceTypes().contains(QStringLiteral("PartitionManager/Plugin")) && metaData.category().contains(QStringLiteral("BackendPlugin")); }; // find backend plugins in standard path (e.g. /usr/lib64/qt5/plugins) using filter from above return KPluginLoader::findPlugins(QString(), filter); } void CoreBackendManager::startExternalCommandHelper() { KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); action.setTimeout(10 * 24 * 3600 * 1000); // 10 days QVariantMap arguments; d->m_Uuid = QUuid::createUuid().toString(); arguments.insert(QStringLiteral("callerUuid"), Uuid()); action.setArguments(arguments); d->m_job = action.execute(); job()->start(); // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) QEventLoop loop; auto exitLoop = [&] () { loop.exit(); }; auto conn = QObject::connect(job(), &KAuth::ExecuteJob::newData, exitLoop); QObject::connect(job(), &KJob::finished, [=] () { if(d->m_job->error()) exitLoop(); } ); loop.exec(); QObject::disconnect(conn); } void CoreBackendManager::stopExternalCommandHelper() { QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); if (iface.isValid()) iface.call(QStringLiteral("exit"), CoreBackendManager::self()->Uuid()); } KAuth::ExecuteJob* CoreBackendManager::job() { return d->m_job; } QString& CoreBackendManager::Uuid() { return d->m_Uuid; } bool CoreBackendManager::load(const QString& name) { if (backend()) unload(); KPluginLoader loader(name); KPluginFactory* factory = loader.factory(); if (factory != nullptr) { d->m_Backend = factory->create(nullptr); QString id = loader.metaData().toVariantMap().value(QStringLiteral("MetaData")) .toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Id")).toString(); QString version = loader.metaData().toVariantMap().value(QStringLiteral("MetaData")) .toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Version")).toString(); if (id.isEmpty()) return false; backend()->setId(id); backend()->setVersion(version); qDebug() << "Loaded backend plugin: " << backend()->id(); return true; } qWarning() << "Could not load plugin for core backend " << name << ": " << loader.errorString(); return false; } void CoreBackendManager::unload() { } diff --git a/src/backend/corebackendmanager_p.h b/src/backend/corebackendmanager_p.h deleted file mode 100644 index d28bcb4..0000000 --- a/src/backend/corebackendmanager_p.h +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************* - * Copyright (C) 2018 by Andrius Štikonas * - * * - * This program 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. * - * * - * This program 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 this program. If not, see .* - *************************************************************************/ - -#ifndef KPMCORE_COREBACKENDMANAGER_P_H - -#define KPMCORE_COREBACKENDMANAGER_P_H - -struct CoreBackendManagerPrivate -{ - KAuth::ExecuteJob *m_job; - CoreBackend *m_Backend; - - QString m_Uuid; -}; - -#endif diff --git a/src/jobs/createfilesystemjob.cpp b/src/jobs/createfilesystemjob.cpp index ad20db7..09e63a2 100644 --- a/src/jobs/createfilesystemjob.cpp +++ b/src/jobs/createfilesystemjob.cpp @@ -1,94 +1,92 @@ /************************************************************************* * Copyright (C) 2008, 2011 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/createfilesystemjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/device.h" #include "core/partition.h" #include "fs/filesystem.h" #include "util/report.h" #include /** Creates a new CreateFileSystemJob @param p the Partition the FileSystem to create is on */ CreateFileSystemJob::CreateFileSystemJob(Device& d, Partition& p, const QString& label) : Job(), m_Device(d), m_Partition(p), m_Label(label) { } bool CreateFileSystemJob::run(Report& parent) { bool rval = false; Report* report = jobStarted(parent); if (partition().fileSystem().type() == FileSystem::Unformatted) return true; bool createResult; if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) { if (partition().fileSystem().supportCreateWithLabel() == FileSystem::cmdSupportFileSystem) createResult = partition().fileSystem().createWithLabel(*report, partition().deviceNode(), m_Label); else createResult = partition().fileSystem().create(*report, partition().deviceNode()); if (createResult) { if (device().type() == Device::Disk_Device) { std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { if (backendPartitionTable->setPartitionSystemType(*report, partition())) { rval = true; backendPartitionTable->commit(); } else report->line() << xi18nc("@info:progress", "Failed to set the system type for the file system on partition %1.", partition().deviceNode()); - - delete backendPartitionTable; } else report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); } else report->line() << xi18nc("@info:progress", "Could not open device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); } else if (device().type() == Device::LVM_Device) { rval = true; } } } jobFinished(*report, rval); return rval; } QString CreateFileSystemJob::description() const { return xi18nc("@info:progress", "Create file system %1 on partition %2", partition().fileSystem().name(), partition().deviceNode()); } diff --git a/src/jobs/createpartitionjob.cpp b/src/jobs/createpartitionjob.cpp index dae4bf7..a67a132 100644 --- a/src/jobs/createpartitionjob.cpp +++ b/src/jobs/createpartitionjob.cpp @@ -1,95 +1,93 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/createpartitionjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/lvmdevice.h" #include "util/report.h" #include /** Creates a new CreatePartitionJob @param d the Device the Partition to be created will be on @param p the Partition to create */ CreatePartitionJob::CreatePartitionJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool CreatePartitionJob::run(Report& parent) { Q_ASSERT(partition().devicePath() == device().deviceNode()); bool rval = false; Report* report = jobStarted(parent); if (device().type() == Device::Disk_Device) { std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { QString partitionPath = backendPartitionTable->createPartition(*report, partition()); if (partitionPath != QString()) { rval = true; partition().setPartitionPath(partitionPath); partition().setState(Partition::StateNone); backendPartitionTable->commit(); } else report->line() << xi18nc("@info/plain", "Failed to add partition %1 to device %2.", partition().deviceNode(), device().deviceNode()); - - delete backendPartitionTable; } else report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to create new partition %2.", device().deviceNode(), partition().deviceNode()); } else report->line() << xi18nc("@info:progress", "Could not open device %1 to create new partition %2.", device().deviceNode(), partition().deviceNode()); } else if (device().type() == Device::LVM_Device) { LvmDevice& dev = dynamic_cast(device()); partition().setState(Partition::StateNone); QString partPath = partition().partitionPath(); QString lvname = partPath.right(partPath.length() - partPath.lastIndexOf(QStringLiteral("/")) - 1); rval = LvmDevice::createLV(*report, dev, partition(), lvname); } jobFinished(*report, rval); return rval; } QString CreatePartitionJob::description() const { if (partition().number() > 0) return xi18nc("@info:progress", "Create new partition %1", partition().deviceNode()); return xi18nc("@info:progress", "Create new partition on device %1", device().deviceNode()); } diff --git a/src/jobs/deletefilesystemjob.cpp b/src/jobs/deletefilesystemjob.cpp index f01a3e3..6ff797e 100644 --- a/src/jobs/deletefilesystemjob.cpp +++ b/src/jobs/deletefilesystemjob.cpp @@ -1,107 +1,104 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/deletefilesystemjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "util/helpers.h" #include "util/report.h" #include #include /** Creates a new DeleteFileSystemJob @param d the Device the FileSystem to delete is on @param p the Partition the FileSystem to delete is on */ DeleteFileSystemJob::DeleteFileSystemJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool DeleteFileSystemJob::run(Report& parent) { Q_ASSERT(device().deviceNode() == partition().devicePath()); if (device().deviceNode() != partition().devicePath()) { qWarning() << "deviceNode: " << device().deviceNode() << ", partition path: " << partition().devicePath(); return false; } bool rval = false; Report* report = jobStarted(parent); if (isMounted(partition().partitionPath())) { report->line() << xi18nc("@info:progress", "Could not delete file system: file system on %1 is mounted.", partition().deviceNode()); jobFinished(*report, rval); return false; } if (partition().roles().has(PartitionRole::Extended)) { rval = true; } else if (device().type() == Device::LVM_Device) { rval = true; } else { if (!partition().fileSystem().remove(*report, partition().deviceNode())) { jobFinished(*report, rval); return false; } std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { rval = backendPartitionTable->clobberFileSystem(*report, partition()); if (!rval) report->line() << xi18nc("@info:progress", "Could not delete file system on %1.", partition().deviceNode()); else backendPartitionTable->commit(); - - delete backendPartitionTable; - } else report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to delete file system on %2.", device().deviceNode(), partition().deviceNode()); } else report->line() << xi18nc("@info:progress", "Could not delete file system signature for partition %1: Failed to open device %2.", partition().deviceNode(), device().deviceNode()); } jobFinished(*report, rval); return rval; } QString DeleteFileSystemJob::description() const { return xi18nc("@info:progress", "Delete file system on %1", partition().deviceNode()); } diff --git a/src/jobs/deletepartitionjob.cpp b/src/jobs/deletepartitionjob.cpp index 293496c..20bada2 100644 --- a/src/jobs/deletepartitionjob.cpp +++ b/src/jobs/deletepartitionjob.cpp @@ -1,93 +1,90 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/deletepartitionjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/lvmdevice.h" #include "util/report.h" #include #include /** Creates a new DeletePartitionJob @param d the Device the Partition to delete is on @param p the Partition to delete */ DeletePartitionJob::DeletePartitionJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool DeletePartitionJob::run(Report& parent) { Q_ASSERT(device().deviceNode() == partition().devicePath()); if (device().deviceNode() != partition().devicePath()) { qWarning() << "deviceNode: " << device().deviceNode() << ", partition path: " << partition().devicePath(); return false; } bool rval = false; Report* report = jobStarted(parent); if (device().type() == Device::Disk_Device) { std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { rval = backendPartitionTable->deletePartition(*report, partition()); if (!rval) report->line() << xi18nc("@info:progress", "Could not delete partition %1.", partition().deviceNode()); else backendPartitionTable->commit(); - - delete backendPartitionTable; - } else report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to delete partition %2.", device().deviceNode(), partition().deviceNode()); } else report->line() << xi18nc("@info:progress", "Deleting partition failed: Could not open device %1.", device().deviceNode()); } else if (device().type() == Device::LVM_Device) { LvmDevice& dev = dynamic_cast(device()); rval = LvmDevice::removeLV(*report, dev, partition()); } jobFinished(*report, rval); return rval; } QString DeletePartitionJob::description() const { return xi18nc("@info:progress", "Delete the partition %1", partition().deviceNode()); } diff --git a/src/jobs/resizefilesystemjob.cpp b/src/jobs/resizefilesystemjob.cpp index d86108a..f27bd70 100644 --- a/src/jobs/resizefilesystemjob.cpp +++ b/src/jobs/resizefilesystemjob.cpp @@ -1,148 +1,146 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/resizefilesystemjob.h" #include "core/partition.h" #include "core/device.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "fs/filesystem.h" #include "util/report.h" #include "util/capacity.h" #include #include #include /** Creates a new ResizeFileSystemJob @param d the Device the FileSystem to be resized is on @param p the Partition the FileSystem to be resized is on @param newlength the new length for the FileSystem; if -1, the FileSystem will be resized to fill the entire Partition */ ResizeFileSystemJob::ResizeFileSystemJob(Device& d, Partition& p, qint64 newlength) : Job(), m_Device(d), m_Partition(p), m_Maximize(newlength == -1), m_NewLength(isMaximizing() ? partition().length() : newlength) { } qint32 ResizeFileSystemJob::numSteps() const { return 100; } bool ResizeFileSystemJob::run(Report& parent) { Q_ASSERT(partition().fileSystem().firstSector() != -1); Q_ASSERT(partition().fileSystem().lastSector() != -1); Q_ASSERT(newLength() <= partition().length()); if (partition().fileSystem().firstSector() == -1 || partition().fileSystem().lastSector() == -1 || newLength() > partition().length()) { qWarning() << "file system first sector: " << partition().fileSystem().firstSector() << ", last sector: " << partition().fileSystem().lastSector() << ", new length: " << newLength() << ", partition length: " << partition().length(); return false; } bool rval = false; Report* report = jobStarted(parent); if (partition().fileSystem().length() == newLength()) { report->line() << xi18ncp("@info:progress", "The file system on partition %2 already has the requested length of 1 sector.", "The file system on partition %2 already has the requested length of %1 sectors.", newLength(), partition().deviceNode()); rval = true; } else { report->line() << i18nc("@info:progress", "Resizing file system from %1 to %2 sectors.", partition().fileSystem().length(), newLength()); FileSystem::CommandSupportType support = (newLength() < partition().fileSystem().length()) ? partition().fileSystem().supportShrink() : partition().fileSystem().supportGrow(); switch (support) { case FileSystem::cmdSupportBackend: { Report* childReport = report->newChild(); childReport->line() << xi18nc("@info:progress", "Resizing a %1 file system using internal backend functions.", partition().fileSystem().name()); rval = resizeFileSystemBackend(*childReport); break; } case FileSystem::cmdSupportFileSystem: { const qint64 newLengthInByte = Capacity(newLength() * device().logicalSize()).toInt(Capacity::Byte); if (partition().isMounted()) rval = partition().fileSystem().resizeOnline(*report, partition().deviceNode(), partition().mountPoint(), newLengthInByte); else rval = partition().fileSystem().resize(*report, partition().deviceNode(), newLengthInByte); break; } default: report->line() << xi18nc("@info:progress", "The file system on partition %1 cannot be resized because there is no support for it.", partition().deviceNode()); break; } if (rval) partition().fileSystem().setLastSector(partition().fileSystem().firstSector() + newLength() - 1); } jobFinished(*report, rval); return rval; } bool ResizeFileSystemJob::resizeFileSystemBackend(Report& report) { bool rval = false; std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { connect(CoreBackendManager::self()->backend(), &CoreBackend::progress, this, &ResizeFileSystemJob::progress); rval = backendPartitionTable->resizeFileSystem(report, partition(), newLength()); disconnect(CoreBackendManager::self()->backend(), &CoreBackend::progress, this, &ResizeFileSystemJob::progress); if (rval) { report.line() << xi18nc("@info:progress", "Successfully resized file system using internal backend functions."); backendPartitionTable->commit(); } - - delete backendPartitionTable; } else report.line() << xi18nc("@info:progress", "Could not open partition %1 while trying to resize the file system.", partition().deviceNode()); } else report.line() << xi18nc("@info:progress", "Could not read geometry for partition %1 while trying to resize the file system.", partition().deviceNode()); return rval; } QString ResizeFileSystemJob::description() const { if (isMaximizing()) return xi18nc("@info:progress", "Maximize file system on %1 to fill the partition", partition().deviceNode()); return xi18ncp("@info:progress", "Resize file system on partition %2 to 1 sector", "Resize file system on partition %2 to %1 sectors", newLength(), partition().deviceNode()); } diff --git a/src/jobs/restorefilesystemjob.cpp b/src/jobs/restorefilesystemjob.cpp index a9265da..fc62906 100644 --- a/src/jobs/restorefilesystemjob.cpp +++ b/src/jobs/restorefilesystemjob.cpp @@ -1,112 +1,112 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/restorefilesystemjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/copysourcefile.h" #include "core/copytargetdevice.h" #include "fs/filesystem.h" #include "fs/filesystemfactory.h" #include "util/report.h" #include /** Creates a new RestoreFileSystemJob @param targetdevice the Device the FileSystem is to be restored to @param targetpartition the Partition the FileSystem is to be restore to @param filename the file name with the image file to restore */ RestoreFileSystemJob::RestoreFileSystemJob(Device& targetdevice, Partition& targetpartition, const QString& filename) : Job(), m_TargetDevice(targetdevice), m_TargetPartition(targetpartition), m_FileName(filename) { } qint32 RestoreFileSystemJob::numSteps() const { return 100; } bool RestoreFileSystemJob::run(Report& parent) { // Restoring is file system independent because we currently have no way of // detecting the file system in a given image file. We cannot even find out if the // file the user gave us is a valid image file or just some junk. bool rval = false; Report* report = jobStarted(parent); // Again, a scope for copyTarget and copySource. See MoveFileSystemJob::run() { // FileSystems are restored to _partitions_, so don't use first and last sector of file system here CopyTargetDevice copyTarget(targetDevice(), targetPartition().firstByte(), targetPartition().lastByte()); CopySourceFile copySource(fileName()); if (!copySource.open()) report->line() << xi18nc("@info:progress", "Could not open backup file %1 to restore from.", fileName()); else if (!copyTarget.open()) report->line() << xi18nc("@info:progress", "Could not open target partition %1 to restore to.", targetPartition().deviceNode()); else { rval = copyBlocks(*report, copyTarget, copySource); if (rval) { // create a new file system for what was restored with the length of the image file const qint64 newLastSector = targetPartition().firstSector() + copySource.length() - 1; std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(targetDevice()); FileSystem::Type t = FileSystem::Unknown; if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) t = backendPartitionTable->detectFileSystemBySector(*report, targetDevice(), targetPartition().firstSector()); } FileSystem* fs = FileSystemFactory::create(t, targetPartition().firstSector(), newLastSector, targetPartition().sectorSize()); targetPartition().deleteFileSystem(); targetPartition().setFileSystem(fs); } report->line() << xi18nc("@info:progress", "Closing device. This may take a few seconds."); } } jobFinished(*report, rval); return rval; } QString RestoreFileSystemJob::description() const { return xi18nc("@info:progress", "Restore the file system from file %1 to partition %2", fileName(), targetPartition().deviceNode()); } diff --git a/src/jobs/setpartflagsjob.cpp b/src/jobs/setpartflagsjob.cpp index 33a3070..fceb583 100644 --- a/src/jobs/setpartflagsjob.cpp +++ b/src/jobs/setpartflagsjob.cpp @@ -1,105 +1,103 @@ /************************************************************************* * Copyright (C) 2008, 2010 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/setpartflagsjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/device.h" #include "core/partition.h" #include "core/partitionrole.h" #include "core/partitiontable.h" #include "util/report.h" #include /** Creates a new SetPartFlagsJob @param d the Device the Partition whose flags are to be set is on @param p the Partition whose flags are to be set @param flags the new flags for the Partition */ SetPartFlagsJob::SetPartFlagsJob(Device& d, Partition& p, PartitionTable::Flags flags) : Job(), m_Device(d), m_Partition(p), m_Flags(flags) { } qint32 SetPartFlagsJob::numSteps() const { return PartitionTable::flagList().size(); } bool SetPartFlagsJob::run(Report& parent) { bool rval = true; Report* report = jobStarted(parent); std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { int count = 0; for (const auto &f : PartitionTable::flagList()) { emit progress(++count); const bool oldState = (partition().activeFlags() & f) ? true : false; const bool state = (flags() & f) ? true : false; if (oldState == state) continue; if (!backendPartitionTable->setFlag(*report, partition(), f, state)) { report->line() << xi18nc("@info:progress", "There was an error setting flag %1 for partition %2 to state %3.", PartitionTable::flagName(f), partition().deviceNode(), state ? xi18nc("@info:progress flag turned on, active", "on") : xi18nc("@info:progress flag turned off, inactive", "off")); rval = false; } } if (rval) backendPartitionTable->commit(); - - delete backendPartitionTable; } else report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set partition flags for partition %2.", device().deviceNode(), partition().deviceNode()); } else report->line() << xi18nc("@info:progress", "Could not open device %1 to set partition flags for partition %2.", device().deviceNode(), partition().deviceNode()); if (rval) partition().setFlags(flags()); jobFinished(*report, rval); return rval; } QString SetPartFlagsJob::description() const { if (PartitionTable::flagNames(flags()).size() == 0) return xi18nc("@info:progress", "Clear flags for partition %1", partition().deviceNode()); return xi18nc("@info:progress", "Set the flags for partition %1 to \"%2\"", partition().deviceNode(), PartitionTable::flagNames(flags()).join(QStringLiteral(","))); } diff --git a/src/jobs/setpartgeometryjob.cpp b/src/jobs/setpartgeometryjob.cpp index 9c3a488..153c352 100644 --- a/src/jobs/setpartgeometryjob.cpp +++ b/src/jobs/setpartgeometryjob.cpp @@ -1,93 +1,91 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "jobs/setpartgeometryjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/lvmdevice.h" #include "util/report.h" #include /** Creates a new SetPartGeometryJob @param d the Device the Partition whose geometry is to be set is on @param p the Partition whose geometry is to be set @param newstart the new start sector for the Partition @param newlength the new length for the Partition @todo Wouldn't it be better to have newfirst (new first sector) and newlast (new last sector) as args instead? Having a length here doesn't seem to be very consistent with the rest of the app, right? */ SetPartGeometryJob::SetPartGeometryJob(Device& d, Partition& p, qint64 newstart, qint64 newlength) : Job(), m_Device(d), m_Partition(p), m_NewStart(newstart), m_NewLength(newlength) { } bool SetPartGeometryJob::run(Report& parent) { bool rval = false; Report* report = jobStarted(parent); if(device().type() == Device::Disk_Device) { std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { - CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); + std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { rval = backendPartitionTable->updateGeometry(*report, partition(), newStart(), newStart() + newLength() - 1); if (rval) { partition().setFirstSector(newStart()); partition().setLastSector(newStart() + newLength() - 1); backendPartitionTable->commit(); } - - delete backendPartitionTable; } } else report->line() << xi18nc("@info:progress", "Could not open device %1 while trying to resize/move partition %2.", device().deviceNode(), partition().deviceNode()); } else if (device().type() == Device::LVM_Device) { partition().setFirstSector(newStart()); partition().setLastSector(newStart() + newLength() - 1); rval = LvmDevice::resizeLV(*report, partition()); } jobFinished(*report, rval); return rval; } QString SetPartGeometryJob::description() const { return xi18nc("@info:progress", "Set geometry of partition %1: Start sector: %2, length: %3", partition().deviceNode(), newStart(), newLength()); } diff --git a/src/plugins/dummy/dummydevice.cpp b/src/plugins/dummy/dummydevice.cpp index d2b43e9..0ffa283 100644 --- a/src/plugins/dummy/dummydevice.cpp +++ b/src/plugins/dummy/dummydevice.cpp @@ -1,68 +1,61 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "plugins/dummy/dummydevice.h" #include "plugins/dummy/dummypartitiontable.h" #include "core/partitiontable.h" #include "util/globallog.h" #include "util/report.h" DummyDevice::DummyDevice(const QString& deviceNode) : CoreBackendDevice(deviceNode) { } DummyDevice::~DummyDevice() { } bool DummyDevice::open() { return true; } bool DummyDevice::openExclusive() { return true; } bool DummyDevice::close() { return true; } -CoreBackendPartitionTable* DummyDevice::openPartitionTable() +std::unique_ptr DummyDevice::openPartitionTable() { - CoreBackendPartitionTable* ptable = new DummyPartitionTable(); - - if (ptable == nullptr || !ptable->open()) { - delete ptable; - ptable = nullptr; - } - - return ptable; + return std::make_unique(DummyPartitionTable()); } bool DummyDevice::createPartitionTable(Report& report, const PartitionTable& ptable) { Q_UNUSED(report); Q_UNUSED(ptable); return true; } diff --git a/src/plugins/dummy/dummydevice.h b/src/plugins/dummy/dummydevice.h index 6895e65..746c346 100644 --- a/src/plugins/dummy/dummydevice.h +++ b/src/plugins/dummy/dummydevice.h @@ -1,49 +1,49 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #if !defined(KPMCORE_DUMMYDEVICE_H) #define KPMCORE_DUMMYDEVICE_H #include "backend/corebackenddevice.h" #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class DummyDevice : public CoreBackendDevice { Q_DISABLE_COPY(DummyDevice) public: DummyDevice(const QString& deviceNode); ~DummyDevice(); public: bool open() override; bool openExclusive() override; bool close() override; - CoreBackendPartitionTable* openPartitionTable() override; + std::unique_ptr openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; }; #endif diff --git a/src/plugins/sfdisk/sfdiskdevice.cpp b/src/plugins/sfdisk/sfdiskdevice.cpp index 7dfc248..d8e1887 100644 --- a/src/plugins/sfdisk/sfdiskdevice.cpp +++ b/src/plugins/sfdisk/sfdiskdevice.cpp @@ -1,81 +1,81 @@ /************************************************************************* * Copyright (C) 2017 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #include "plugins/sfdisk/sfdiskdevice.h" #include "plugins/sfdisk/sfdiskpartitiontable.h" #include "core/partitiontable.h" #include "util/externalcommand.h" #include "util/report.h" SfdiskDevice::SfdiskDevice(const Device& d) : CoreBackendDevice(d.deviceNode()), m_device(&d) { } SfdiskDevice::~SfdiskDevice() { close(); } bool SfdiskDevice::open() { return true; } bool SfdiskDevice::openExclusive() { setExclusive(true); return true; } bool SfdiskDevice::close() { if (isExclusive()) setExclusive(false); CoreBackendPartitionTable* ptable = new SfdiskPartitionTable(m_device); ptable->commit(); delete ptable; return true; } -CoreBackendPartitionTable* SfdiskDevice::openPartitionTable() +std::unique_ptr SfdiskDevice::openPartitionTable() { - return new SfdiskPartitionTable(m_device); + return std::make_unique(m_device); } bool SfdiskDevice::createPartitionTable(Report& report, const PartitionTable& ptable) { QByteArray tableType; if (ptable.type() == PartitionTable::msdos || ptable.type() == PartitionTable::msdos_sectorbased) tableType = QByteArrayLiteral("dos"); else tableType = ptable.typeName().toLocal8Bit(); ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { m_device->deviceNode() } ); if ( createCommand.write(QByteArrayLiteral("label: ") + tableType + QByteArrayLiteral("\nwrite\n")) && createCommand.start(-1) && createCommand.waitFor() ) { return createCommand.output().contains(QStringLiteral("Script header accepted.")); } return false; } diff --git a/src/plugins/sfdisk/sfdiskdevice.h b/src/plugins/sfdisk/sfdiskdevice.h index 096dd74..eab4a12 100644 --- a/src/plugins/sfdisk/sfdiskdevice.h +++ b/src/plugins/sfdisk/sfdiskdevice.h @@ -1,53 +1,53 @@ /************************************************************************* * Copyright (C) 2017 by Andrius Štikonas * * * * This program 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. * * * * This program 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 this program. If not, see .* *************************************************************************/ #if !defined(SFDISKDEVICE__H) #define SFDISKDEVICE__H #include "backend/corebackenddevice.h" #include "core/device.h" #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class SfdiskDevice : public CoreBackendDevice { Q_DISABLE_COPY(SfdiskDevice); public: SfdiskDevice(const Device& d); ~SfdiskDevice(); public: bool open() override; bool openExclusive() override; bool close() override; - CoreBackendPartitionTable* openPartitionTable() override; + std::unique_ptr openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; private: const Device *m_device; }; #endif