Use KAuth to get privileges needed for detecting partitions.
This commit is contained in:
parent
99886f32fc
commit
e64a82ff19
|
@ -52,6 +52,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
|||
|
||||
# Load the frameworks we need
|
||||
find_package(KF5 REQUIRED
|
||||
Auth
|
||||
I18n
|
||||
IconThemes
|
||||
KIO
|
||||
|
|
|
@ -58,10 +58,10 @@ Q_SIGNALS:
|
|||
|
||||
/**
|
||||
* Emitted to inform about scan progress.
|
||||
* @param device_node the device being scanned just now (e.g. "/dev/sda")
|
||||
* @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& device_node, int i);
|
||||
void scanProgress(const QString& deviceNode, int i);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -101,29 +101,29 @@ public:
|
|||
|
||||
/**
|
||||
* Scan a single device in the system.
|
||||
* @param device_node The path to the device that is to be scanned (e.g. /dev/sda)
|
||||
* @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& device_node) = 0;
|
||||
virtual Device* scanDevice(const QString& deviceNode) = 0;
|
||||
|
||||
/**
|
||||
* Open a device for reading.
|
||||
* @param device_node The path of the device that is to be opened (e.g. /dev/sda)
|
||||
* @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.
|
||||
*/
|
||||
virtual CoreBackendDevice* openDevice(const QString& device_node) = 0;
|
||||
virtual CoreBackendDevice* openDevice(const QString& deviceNode) = 0;
|
||||
|
||||
/**
|
||||
* Open a device in exclusive mode for writing.
|
||||
* @param device_node The path of the device that is to be opened (e.g. /dev/sda)
|
||||
* @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.
|
||||
*/
|
||||
virtual CoreBackendDevice* openDeviceExclusive(const QString& device_node) = 0;
|
||||
virtual CoreBackendDevice* openDeviceExclusive(const QString& deviceNode) = 0;
|
||||
|
||||
/**
|
||||
* Close a CoreBackendDevice that has previously been opened.
|
||||
|
@ -144,12 +144,12 @@ public:
|
|||
|
||||
/**
|
||||
* Emit scan progress.
|
||||
* @param device_node the path to the device just being scanned (e.g. /dev/sda)
|
||||
* @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& device_node, int i);
|
||||
virtual void emitScanProgress(const QString& deviceNode, int i);
|
||||
|
||||
protected:
|
||||
static void setPartitionTableForDevice(Device& d, PartitionTable* p);
|
||||
|
|
|
@ -91,6 +91,7 @@ public:
|
|||
};
|
||||
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
Q_FLAG(Flag)
|
||||
|
||||
public:
|
||||
PartitionTable(TableType type, qint64 first_usable, qint64 last_usable);
|
||||
|
|
|
@ -34,8 +34,10 @@ set (pmlibpartedbackendplugin_SRCS
|
|||
|
||||
add_library(pmlibpartedbackendplugin SHARED ${pmlibpartedbackendplugin_SRCS})
|
||||
|
||||
target_link_libraries(pmlibpartedbackendplugin kpmcore ${LIBPARTED_LIBS} KF5::KIOCore KF5::I18n)
|
||||
target_link_libraries(pmlibpartedbackendplugin kpmcore ${LIBPARTED_LIBS} KF5::Auth KF5::KIOCore KF5::I18n)
|
||||
|
||||
install(TARGETS pmlibpartedbackendplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})
|
||||
kcoreaddons_desktop_to_json(pmlibpartedbackendplugin pmlibpartedbackendplugin.desktop)
|
||||
install(FILES pmlibpartedbackendplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})
|
||||
|
||||
add_subdirectory(helpers)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
add_executable(kpmcore_scan scan.cpp)
|
||||
target_link_libraries(kpmcore_scan ${LIBPARTED_LIBS} KF5::Auth)
|
||||
install(TARGETS kpmcore_scan DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
|
||||
|
||||
kauth_install_helper_files(kpmcore_scan org.kde.kpmcore.scan root)
|
||||
kauth_install_actions(org.kde.kpmcore.scan org.kde.kpmcore.scan.actions)
|
|
@ -0,0 +1,17 @@
|
|||
[org.kde.kpmcore.scan.scandevices]
|
||||
Name=Scan devices action
|
||||
Description=Scan available devices
|
||||
Policy=yes
|
||||
Persistence=session
|
||||
|
||||
[org.kde.kpmcore.scan.scandevice]
|
||||
Name=Scan device action
|
||||
Description=Scan device
|
||||
Policy=yes
|
||||
Persistence=session
|
||||
|
||||
[org.kde.kpmcore.scan.readsectorsused]
|
||||
Name=Read used sectors action
|
||||
Description=Read used sectors
|
||||
Policy=yes
|
||||
Persistence=session
|
|
@ -0,0 +1,198 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "scan.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "plugins/libparted/pedflags.h"
|
||||
|
||||
ActionReply Scan::scandevices(const QVariantMap& args)
|
||||
{
|
||||
ActionReply reply;
|
||||
|
||||
ped_device_probe_all();
|
||||
PedDevice* pedDevice = nullptr;
|
||||
QList<QVariant> paths;
|
||||
bool excludeReadOnly = args[QLatin1String("excludeReadOnly")].toBool();
|
||||
|
||||
while (true) {
|
||||
pedDevice = ped_device_get_next(pedDevice);
|
||||
if (!pedDevice)
|
||||
break;
|
||||
if (pedDevice->type == PED_DEVICE_DM)
|
||||
continue;
|
||||
if (excludeReadOnly && (
|
||||
pedDevice->type == PED_DEVICE_LOOP ||
|
||||
pedDevice->read_only))
|
||||
continue;
|
||||
|
||||
paths.append(QString::fromUtf8(pedDevice->path));
|
||||
}
|
||||
|
||||
QVariantMap returnArgs;
|
||||
returnArgs[QLatin1String("paths")] = paths;
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
ActionReply Scan::scandevice(const QVariantMap& args)
|
||||
{
|
||||
ActionReply reply;
|
||||
|
||||
QString deviceNode = args[QLatin1String("deviceNode")].toString();
|
||||
PedDevice* pedDevice = ped_device_get(deviceNode.toLocal8Bit().constData());
|
||||
|
||||
QVariantMap returnArgs;
|
||||
if (!pedDevice) {
|
||||
returnArgs[QLatin1String("pedDeviceError")] = true;
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
returnArgs[QLatin1String("model")] = QString::fromUtf8(pedDevice->model);
|
||||
returnArgs[QLatin1String("path")] = QString::fromUtf8(pedDevice->path);
|
||||
returnArgs[QLatin1String("heads")] = pedDevice->bios_geom.heads;
|
||||
returnArgs[QLatin1String("sectors")] = pedDevice->bios_geom.sectors;
|
||||
returnArgs[QLatin1String("cylinders")] = pedDevice->bios_geom.cylinders;
|
||||
returnArgs[QLatin1String("sectorSize")] = pedDevice->sector_size;
|
||||
|
||||
PedDisk* pedDisk = ped_disk_new(pedDevice);
|
||||
|
||||
if (!pedDisk) {
|
||||
returnArgs[QLatin1String("pedDiskError")] = true;
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
quint64 firstUsableSector = pedDisk->dev->bios_geom.sectors;
|
||||
|
||||
if (strcmp(pedDisk->type->name, "gpt") == 0) {
|
||||
GPTDiskData* gpt_disk_data = reinterpret_cast<GPTDiskData*>(pedDisk->disk_specific);
|
||||
PedGeometry* geom = reinterpret_cast<PedGeometry*>(&gpt_disk_data->data_area);
|
||||
|
||||
if (geom)
|
||||
firstUsableSector = geom->start;
|
||||
else
|
||||
firstUsableSector += 32;
|
||||
}
|
||||
|
||||
quint64 lastUsableSector = 0;
|
||||
lastUsableSector = static_cast< quint64 >( pedDisk->dev->bios_geom.sectors ) *
|
||||
pedDisk->dev->bios_geom.heads *
|
||||
pedDisk->dev->bios_geom.cylinders - 1;
|
||||
|
||||
if (strcmp(pedDisk->type->name, "gpt") == 0) {
|
||||
GPTDiskData* gpt_disk_data = reinterpret_cast<GPTDiskData*>(pedDisk->disk_specific);
|
||||
PedGeometry* geom = reinterpret_cast<PedGeometry*>(&gpt_disk_data->data_area);
|
||||
|
||||
if (geom)
|
||||
lastUsableSector = geom->end;
|
||||
else
|
||||
lastUsableSector -= 32;
|
||||
}
|
||||
|
||||
returnArgs[QLatin1String("pedDeviceError")] = false;
|
||||
returnArgs[QLatin1String("pedDiskError")] = false;
|
||||
|
||||
returnArgs[QLatin1String("typeName")] = QString::fromUtf8(pedDisk->type->name);
|
||||
returnArgs[QLatin1String("maxPrimaryPartitionCount")] = ped_disk_get_max_primary_partition_count(pedDisk);
|
||||
returnArgs[QLatin1String("firstUsableSector")] = firstUsableSector;
|
||||
returnArgs[QLatin1String("lastUsableSector")] = lastUsableSector;
|
||||
|
||||
PedPartition* pedPartition = nullptr;
|
||||
QList<QVariant> partitionPath;
|
||||
QList<QVariant> partitionType;
|
||||
QList<QVariant> partitionStart;
|
||||
QList<QVariant> partitionEnd;
|
||||
QList<QVariant> partitionBusy;
|
||||
QList<QVariant> availableFlags;
|
||||
QList<QVariant> activeFlags;
|
||||
|
||||
while ((pedPartition = ped_disk_next_partition(pedDisk, pedPartition))) {
|
||||
if (pedPartition->num < 1)
|
||||
continue;
|
||||
|
||||
partitionPath.append(QLatin1String(ped_partition_get_path(pedPartition)));
|
||||
partitionType.append(pedPartition->type);
|
||||
partitionStart.append(pedPartition->geom.start);
|
||||
partitionEnd.append(pedPartition->geom.end);
|
||||
partitionBusy.append(ped_partition_is_busy(pedPartition));
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Get list of available flags
|
||||
|
||||
PartitionTable::Flags flags;
|
||||
|
||||
// We might get here with a pedPartition just picked up from libparted that is
|
||||
// unallocated. Libparted doesn't like it if we ask for flags for unallocated
|
||||
// space.
|
||||
if (pedPartition->num > 0)
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (ped_partition_is_flag_available(pedPartition, flagmap[i].pedFlag))
|
||||
// Workaround: libparted claims the hidden flag is available for extended partitions, but
|
||||
// throws an error when we try to set or clear it. So skip this combination. Also see setFlag.
|
||||
if (pedPartition->type != PED_PARTITION_EXTENDED || flagmap[i].flag != PartitionTable::FlagHidden)
|
||||
flags |= flagmap[i].flag;
|
||||
|
||||
availableFlags.append(static_cast<qint32>(flags));
|
||||
// --------------------------------------------------------------------------
|
||||
// Get list of active flags
|
||||
|
||||
flags = PartitionTable::FlagNone;
|
||||
if (pedPartition->num > 0)
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (ped_partition_is_flag_available(pedPartition, flagmap[i].pedFlag) && ped_partition_get_flag(pedPartition, flagmap[i].pedFlag))
|
||||
flags |= flagmap[i].flag;
|
||||
|
||||
activeFlags.append(static_cast<qint32>(flags));
|
||||
// --------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
returnArgs[QLatin1String("availableFlags")] = availableFlags;
|
||||
returnArgs[QLatin1String("activeFlags")] = activeFlags;
|
||||
returnArgs[QLatin1String("partitionPath")] = partitionPath;
|
||||
returnArgs[QLatin1String("partitionType")] = partitionType;
|
||||
returnArgs[QLatin1String("partitionStart")] = partitionStart;
|
||||
returnArgs[QLatin1String("partitionEnd")] = partitionEnd;
|
||||
returnArgs[QLatin1String("partitionBusy")] = partitionBusy;
|
||||
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
ActionReply Scan::readsectorsused(const QVariantMap& args)
|
||||
{
|
||||
ActionReply reply;
|
||||
|
||||
QString deviceNode = args[QLatin1String("deviceNode")].toString();
|
||||
qint64 firstSector = args[QLatin1String("firstSector")].toLongLong();
|
||||
qint64 rval = -1;
|
||||
|
||||
if (PedDevice* pedDevice = ped_device_get(deviceNode.toLocal8Bit().constData()))
|
||||
if (PedDisk* pedDisk = ped_disk_new(pedDevice))
|
||||
if (PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk, firstSector))
|
||||
if (PedFileSystem* pedFileSystem = ped_file_system_open(&pedPartition->geom))
|
||||
if (PedConstraint* pedConstraint = ped_file_system_get_resize_constraint(pedFileSystem))
|
||||
rval = pedConstraint->min_size;
|
||||
|
||||
QVariantMap returnArgs;
|
||||
returnArgs[QLatin1String("sectorsUsed")] = rval;
|
||||
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
KAUTH_HELPER_MAIN("org.kde.kpmcore.scan", Scan)
|
|
@ -0,0 +1,66 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(SCAN__H)
|
||||
|
||||
#define SCAN__H
|
||||
|
||||
#include <KAuth>
|
||||
#include <parted/parted.h>
|
||||
|
||||
using namespace KAuth;
|
||||
|
||||
class Scan : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public Q_SLOTS:
|
||||
ActionReply scandevices(const QVariantMap& args);
|
||||
ActionReply scandevice(const QVariantMap& args);
|
||||
ActionReply readsectorsused(const QVariantMap& args);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// The following structs and the typedef come from libparted's internal gpt sources.
|
||||
// It's very unfortunate there is no public API to get at the first and last usable
|
||||
// sector for GPT a partition table, so this is the only (libparted) way to get that
|
||||
// information (another way would be to read the GPT header and parse the
|
||||
// information ourselves; if the libparted devs begin changing these internal
|
||||
// structs for each point release and break our code, we'll have to do just that).
|
||||
|
||||
typedef struct {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_and_version;
|
||||
uint8_t clock_seq_hi_and_reserved;
|
||||
uint8_t clock_seq_low;
|
||||
uint8_t node[6];
|
||||
} /* __attribute__ ((packed)) */ efi_guid_t;
|
||||
|
||||
|
||||
struct __attribute__((packed)) _GPTDiskData {
|
||||
PedGeometry data_area;
|
||||
int entry_count;
|
||||
efi_guid_t uuid;
|
||||
};
|
||||
|
||||
typedef struct _GPTDiskData GPTDiskData;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#endif
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "plugins/libparted/libpartedbackend.h"
|
||||
#include "plugins/libparted/libparteddevice.h"
|
||||
#include "plugins/libparted/pedflags.h"
|
||||
|
||||
#include "core/device.h"
|
||||
#include "core/partition.h"
|
||||
|
@ -45,40 +46,16 @@
|
|||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <KAuth>
|
||||
#include <KLocalizedString>
|
||||
#include <KMountPoint>
|
||||
#include <KDiskFreeSpaceInfo>
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <unistd.h>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON(LibPartedBackendFactory, "pmlibpartedbackendplugin.json", registerPlugin<LibPartedBackend>();)
|
||||
|
||||
static struct {
|
||||
PedPartitionFlag pedFlag;
|
||||
PartitionTable::Flag flag;
|
||||
} flagmap[] = {
|
||||
{ PED_PARTITION_BOOT, PartitionTable::FlagBoot },
|
||||
{ PED_PARTITION_ROOT, PartitionTable::FlagRoot },
|
||||
{ PED_PARTITION_SWAP, PartitionTable::FlagSwap },
|
||||
{ PED_PARTITION_HIDDEN, PartitionTable::FlagHidden },
|
||||
{ PED_PARTITION_RAID, PartitionTable::FlagRaid },
|
||||
{ PED_PARTITION_LVM, PartitionTable::FlagLvm },
|
||||
{ PED_PARTITION_LBA, PartitionTable::FlagLba },
|
||||
{ PED_PARTITION_HPSERVICE, PartitionTable::FlagHpService },
|
||||
{ PED_PARTITION_PALO, PartitionTable::FlagPalo },
|
||||
{ PED_PARTITION_PREP, PartitionTable::FlagPrep },
|
||||
{ PED_PARTITION_MSFT_RESERVED, PartitionTable::FlagMsftReserved },
|
||||
{ PED_PARTITION_BIOS_GRUB, PartitionTable::FlagBiosGrub },
|
||||
{ PED_PARTITION_APPLE_TV_RECOVERY, PartitionTable::FlagAppleTvRecovery },
|
||||
{ PED_PARTITION_DIAG, PartitionTable::FlagDiag }, // generic diagnostics flag
|
||||
{ PED_PARTITION_LEGACY_BOOT, PartitionTable::FlagLegacyBoot },
|
||||
{ PED_PARTITION_MSFT_DATA, PartitionTable::FlagMsftData },
|
||||
{ PED_PARTITION_IRST, PartitionTable::FlagIrst }, // Intel Rapid Start partition
|
||||
{ PED_PARTITION_ESP, PartitionTable::FlagEsp } // EFI system
|
||||
};
|
||||
|
||||
static QString s_lastPartedExceptionMessage;
|
||||
|
||||
/** Callback to handle exceptions from libparted
|
||||
|
@ -91,133 +68,37 @@ static PedExceptionOption pedExceptionHandler(PedException* e)
|
|||
return PED_EXCEPTION_UNHANDLED;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// The following structs and the typedef come from libparted's internal gpt sources.
|
||||
// It's very unfortunate there is no public API to get at the first and last usable
|
||||
// sector for GPT a partition table, so this is the only (libparted) way to get that
|
||||
// information (another way would be to read the GPT header and parse the
|
||||
// information ourselves; if the libparted devs begin changing these internal
|
||||
// structs for each point release and break our code, we'll have to do just that).
|
||||
|
||||
typedef struct {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_and_version;
|
||||
uint8_t clock_seq_hi_and_reserved;
|
||||
uint8_t clock_seq_low;
|
||||
uint8_t node[6];
|
||||
} /* __attribute__ ((packed)) */ efi_guid_t;
|
||||
|
||||
|
||||
struct __attribute__((packed)) _GPTDiskData {
|
||||
PedGeometry data_area;
|
||||
int entry_count;
|
||||
efi_guid_t uuid;
|
||||
};
|
||||
|
||||
typedef struct _GPTDiskData GPTDiskData;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/** Get the first sector a Partition may cover on a given Device
|
||||
@param d the Device in question
|
||||
@return the first sector usable by a Partition
|
||||
*/
|
||||
static quint64 firstUsableSector(const Device& d)
|
||||
{
|
||||
PedDevice* pedDevice = ped_device_get(d.deviceNode().toLatin1().constData());
|
||||
PedDisk* pedDisk = pedDevice ? ped_disk_new(pedDevice) : nullptr;
|
||||
|
||||
quint64 rval = 0;
|
||||
if (pedDisk)
|
||||
rval = pedDisk->dev->bios_geom.sectors;
|
||||
|
||||
if (pedDisk && strcmp(pedDisk->type->name, "gpt") == 0) {
|
||||
GPTDiskData* gpt_disk_data = reinterpret_cast<GPTDiskData*>(pedDisk->disk_specific);
|
||||
PedGeometry* geom = reinterpret_cast<PedGeometry*>(&gpt_disk_data->data_area);
|
||||
|
||||
if (geom)
|
||||
rval = geom->start;
|
||||
else
|
||||
rval += 32;
|
||||
}
|
||||
|
||||
ped_disk_destroy(pedDisk);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/** Get the last sector a Partition may cover on a given Device
|
||||
@param d the Device in question
|
||||
@return the last sector usable by a Partition
|
||||
*/
|
||||
static quint64 lastUsableSector(const Device& d)
|
||||
{
|
||||
PedDevice* pedDevice = ped_device_get(d.deviceNode().toLatin1().constData());
|
||||
PedDisk* pedDisk = pedDevice ? ped_disk_new(pedDevice) : nullptr;
|
||||
|
||||
quint64 rval = 0;
|
||||
if (pedDisk)
|
||||
rval = static_cast< quint64 >( pedDisk->dev->bios_geom.sectors ) *
|
||||
pedDisk->dev->bios_geom.heads *
|
||||
pedDisk->dev->bios_geom.cylinders - 1;
|
||||
|
||||
if (pedDisk && strcmp(pedDisk->type->name, "gpt") == 0) {
|
||||
GPTDiskData* gpt_disk_data = reinterpret_cast<GPTDiskData*>(pedDisk->disk_specific);
|
||||
PedGeometry* geom = reinterpret_cast<PedGeometry*>(&gpt_disk_data->data_area);
|
||||
|
||||
if (geom)
|
||||
rval = geom->end;
|
||||
else
|
||||
rval -= 32;
|
||||
}
|
||||
|
||||
ped_disk_destroy(pedDisk);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/** Reads sectors used on a FileSystem using libparted functions.
|
||||
@param pedDisk pointer to pedDisk where the Partition and its FileSystem are
|
||||
@param p the Partition the FileSystem is on
|
||||
@return the number of sectors used
|
||||
*/
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
static qint64 readSectorsUsedLibParted(PedDisk* pedDisk, const Partition& p)
|
||||
static qint64 readSectorsUsedLibParted(const Partition& p)
|
||||
{
|
||||
Q_ASSERT(pedDisk);
|
||||
QVariantMap args;
|
||||
args[QLatin1String("deviceNode")] = p.deviceNode();
|
||||
args[QLatin1String("firstSector")] = p.firstSector();
|
||||
|
||||
qint64 rval = -1;
|
||||
|
||||
PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk, p.firstSector());
|
||||
|
||||
if (pedPartition) {
|
||||
PedFileSystem* pedFileSystem = ped_file_system_open(&pedPartition->geom);
|
||||
|
||||
if (pedFileSystem) {
|
||||
if (PedConstraint* pedConstraint = ped_file_system_get_resize_constraint(pedFileSystem)) {
|
||||
rval = pedConstraint->min_size;
|
||||
ped_constraint_destroy(pedConstraint);
|
||||
}
|
||||
|
||||
ped_file_system_close(pedFileSystem);
|
||||
}
|
||||
KAuth::Action scanAction = QStringLiteral("org.kde.kpmcore.scan.readsectorsused");
|
||||
scanAction.setHelperId(QStringLiteral("org.kde.kpmcore.scan"));
|
||||
scanAction.setArguments(args);
|
||||
KAuth::ExecuteJob *job = scanAction.execute();
|
||||
if (!job->exec()) {
|
||||
qWarning() << "KAuth returned an error code: " << job->errorString();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rval;
|
||||
return job->data()[QLatin1String("sectorsUsed")].toLongLong();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Reads the sectors used in a FileSystem and stores the result in the Partition's FileSystem object.
|
||||
@param pedDisk pointer to pedDisk where the Partition and its FileSystem are
|
||||
@param p the Partition the FileSystem is on
|
||||
@param mountPoint mount point of the partition in question
|
||||
*/
|
||||
static void readSectorsUsed(PedDisk* pedDisk, const Device& d, Partition& p, const QString& mountPoint)
|
||||
static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint)
|
||||
{
|
||||
Q_ASSERT(pedDisk);
|
||||
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
|
||||
if (p.isMounted() && freeSpaceInfo.isValid() && mountPoint != QString())
|
||||
|
@ -225,49 +106,11 @@ static void readSectorsUsed(PedDisk* pedDisk, const Device& d, Partition& p, con
|
|||
else if (p.fileSystem().supportGetUsed() == FileSystem::cmdSupportFileSystem)
|
||||
p.fileSystem().setSectorsUsed(p.fileSystem().readUsedCapacity(p.deviceNode()) / d.logicalSectorSize());
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
else if (p.fileSystem().supportGetUsed() == FileSystem::cmdSupportCore)
|
||||
p.fileSystem().setSectorsUsed(readSectorsUsedLibParted(pedDisk, p));
|
||||
#else
|
||||
Q_UNUSED(pedDisk);
|
||||
else if (p.fileSystem().supportGetUsed() == FileSystem::cmdSupportBackend)
|
||||
p.fileSystem().setSectorsUsed(readSectorsUsedLibParted(p));
|
||||
#endif
|
||||
}
|
||||
|
||||
static PartitionTable::Flags activeFlags(PedPartition* p)
|
||||
{
|
||||
PartitionTable::Flags flags = PartitionTable::FlagNone;
|
||||
|
||||
// We might get here with a pedPartition just picked up from libparted that is
|
||||
// unallocated. Libparted doesn't like it if we ask for flags for unallocated
|
||||
// space.
|
||||
if (p->num <= 0)
|
||||
return flags;
|
||||
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (ped_partition_is_flag_available(p, flagmap[i].pedFlag) && ped_partition_get_flag(p, flagmap[i].pedFlag))
|
||||
flags |= flagmap[i].flag;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static PartitionTable::Flags availableFlags(PedPartition* p)
|
||||
{
|
||||
PartitionTable::Flags flags;
|
||||
|
||||
// see above.
|
||||
if (p->num <= 0)
|
||||
return flags;
|
||||
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (ped_partition_is_flag_available(p, flagmap[i].pedFlag)) {
|
||||
// Workaround: libparted claims the hidden flag is available for extended partitions, but
|
||||
// throws an error when we try to set or clear it. So skip this combination. Also see setFlag.
|
||||
if (p->type != PED_PARTITION_EXTENDED || flagmap[i].flag != PartitionTable::FlagHidden)
|
||||
flags |= flagmap[i].flag;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/** Constructs a LibParted object. */
|
||||
LibPartedBackend::LibPartedBackend(QObject*, const QList<QVariant>&) :
|
||||
CoreBackend()
|
||||
|
@ -298,40 +141,78 @@ void LibPartedBackend::initFSSupport()
|
|||
#endif
|
||||
}
|
||||
|
||||
/** Scans a Device for Partitions.
|
||||
|
||||
This method will scan a Device for all Partitions on it, detect the FileSystem for each Partition,
|
||||
try to determine the FileSystem usage, read the FileSystem label and store it all in newly created
|
||||
objects that are in the end added to the Device's PartitionTable.
|
||||
|
||||
@param d Device
|
||||
@param pedDisk libparted pointer to the partition table
|
||||
/** Create a Device for the given deviceNode and scan it for partitions.
|
||||
@param deviceNode the device node (e.g. "/dev/sda")
|
||||
@return the created Device object. callers need to free this.
|
||||
*/
|
||||
void LibPartedBackend::scanDevicePartitions(Device& d, PedDisk* pedDisk)
|
||||
Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
||||
{
|
||||
Q_ASSERT(pedDisk);
|
||||
Q_ASSERT(d.partitionTable());
|
||||
QVariantMap args;
|
||||
args[QLatin1String("deviceNode")] = deviceNode;
|
||||
|
||||
PedPartition* pedPartition = nullptr;
|
||||
KAuth::Action scanAction = QStringLiteral("org.kde.kpmcore.scan.scandevice");
|
||||
scanAction.setHelperId(QStringLiteral("org.kde.kpmcore.scan"));
|
||||
scanAction.setArguments(args);
|
||||
KAuth::ExecuteJob *job = scanAction.execute();
|
||||
if (!job->exec()) {
|
||||
qWarning() << "KAuth returned an error code: " << job->errorString();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool pedDeviceError = job->data()[QLatin1String("pedDeviceError")].toBool();
|
||||
|
||||
if (pedDeviceError) {
|
||||
Log(Log::warning) << xi18nc("@info:status", "Could not access device <filename>%1</filename>", deviceNode);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString model = job->data()[QLatin1String("model")].toString();
|
||||
QString path = job->data()[QLatin1String("path")].toString();
|
||||
int heads = job->data()[QLatin1String("heads")].toInt();
|
||||
int sectors = job->data()[QLatin1String("sectors")].toInt();
|
||||
int cylinders = job->data()[QLatin1String("cylinders")].toInt();
|
||||
int sectorSize = job->data()[QLatin1String("sectorSize")].toInt();
|
||||
bool pedDiskError = job->data()[QLatin1String("pedDiskError")].toBool();
|
||||
|
||||
Log(Log::information) << xi18nc("@info:status", "Device found: %1", model);
|
||||
|
||||
Device* d = new Device(model, path, heads, sectors, cylinders, sectorSize);
|
||||
|
||||
if (pedDiskError)
|
||||
return d;
|
||||
|
||||
QString typeName = job->data()[QLatin1String("typeName")].toString();
|
||||
qint32 maxPrimaryPartitionCount = job->data()[QLatin1String("maxPrimaryPartitionCount")].toInt();
|
||||
quint64 firstUsableSector = job->data()[QLatin1String("firstUsableSector")].toULongLong();
|
||||
quint64 lastUsableSector = job->data()[QLatin1String("lastUsableSector")].toULongLong();
|
||||
|
||||
const PartitionTable::TableType type = PartitionTable::nameToTableType(typeName);
|
||||
CoreBackend::setPartitionTableForDevice(*d, new PartitionTable(type, firstUsableSector, lastUsableSector));
|
||||
CoreBackend::setPartitionTableMaxPrimaries(*d->partitionTable(), maxPrimaryPartitionCount);
|
||||
|
||||
KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::NeedRealDeviceName);
|
||||
mountPoints.append(KMountPoint::possibleMountPoints(KMountPoint::NeedRealDeviceName));
|
||||
|
||||
QList<Partition*> partitions;
|
||||
QList<QVariant> partitionPath = job->data()[QLatin1String("partitionPath")].toList();
|
||||
QList<QVariant> partitionType = job->data()[QLatin1String("partitionType")].toList();
|
||||
QList<QVariant> partitionStart = job->data()[QLatin1String("partitionStart")].toList();
|
||||
QList<QVariant> partitionEnd = job->data()[QLatin1String("partitionEnd")].toList();
|
||||
QList<QVariant> partitionBusy = job->data()[QLatin1String("partitionBusy")].toList();
|
||||
|
||||
while ((pedPartition = ped_disk_next_partition(pedDisk, pedPartition))) {
|
||||
if (pedPartition->num < 1)
|
||||
continue;
|
||||
quint32 totalPartitions = partitionPath.size();
|
||||
QList<Partition*> partitions;
|
||||
for (quint32 i = 0; i < totalPartitions; ++i) {
|
||||
QString partitionNode = partitionPath[i].toString();
|
||||
int type = partitionType[i].toInt();
|
||||
qint64 start = partitionStart[i].toLongLong();
|
||||
qint64 end = partitionEnd[i].toLongLong();
|
||||
bool busy = partitionBusy[i].toBool();
|
||||
|
||||
PartitionRole::Roles r = PartitionRole::None;
|
||||
|
||||
FileSystem::Type type = FileSystem::Unknown;
|
||||
char* pedPath = ped_partition_get_path(pedPartition);
|
||||
if (pedPath)
|
||||
type = detectFileSystem(QString::fromUtf8(pedPath));
|
||||
free(pedPath);
|
||||
FileSystem::Type fsType = detectFileSystem(partitionNode);
|
||||
|
||||
switch (pedPartition->type) {
|
||||
switch (type) {
|
||||
case PED_PARTITION_NORMAL:
|
||||
r = PartitionRole::Primary;
|
||||
break;
|
||||
|
@ -350,30 +231,27 @@ void LibPartedBackend::scanDevicePartitions(Device& d, PedDisk* pedDisk)
|
|||
}
|
||||
|
||||
// Find an extended partition this partition is in.
|
||||
PartitionNode* parent = d.partitionTable()->findPartitionBySector(pedPartition->geom.start, PartitionRole(PartitionRole::Extended));
|
||||
PartitionNode* parent = d->partitionTable()->findPartitionBySector(start, PartitionRole(PartitionRole::Extended));
|
||||
|
||||
// None found, so it's a primary in the device's partition table.
|
||||
if (parent == nullptr)
|
||||
parent = d.partitionTable();
|
||||
parent = d->partitionTable();
|
||||
|
||||
pedPath = ped_partition_get_path(pedPartition);
|
||||
const QString node = QString::fromUtf8(pedPath);
|
||||
free(pedPath);
|
||||
FileSystem* fs = FileSystemFactory::create(type, pedPartition->geom.start, pedPartition->geom.end);
|
||||
FileSystem* fs = FileSystemFactory::create(fsType, start, end);
|
||||
|
||||
// libparted does not handle LUKS partitions
|
||||
QString mountPoint;
|
||||
bool mounted = false;
|
||||
if (type == FileSystem::Luks) {
|
||||
if (fsType == FileSystem::Luks) {
|
||||
r |= PartitionRole::Luks;
|
||||
FS::luks* luksFs = dynamic_cast<FS::luks*>(fs);
|
||||
QString mapperNode = FS::luks::mapperName(node);
|
||||
QString mapperNode = FS::luks::mapperName(partitionNode);
|
||||
bool isCryptOpen = !mapperNode.isEmpty();
|
||||
luksFs->setCryptOpen(isCryptOpen);
|
||||
luksFs->setLogicalSectorSize(d.logicalSectorSize());
|
||||
luksFs->setLogicalSectorSize(d->logicalSectorSize());
|
||||
|
||||
if (isCryptOpen) {
|
||||
luksFs->loadInnerFileSystem(node, mapperNode);
|
||||
luksFs->loadInnerFileSystem(partitionNode, mapperNode);
|
||||
|
||||
mountPoint = mountPoints.findByDevice(mapperNode) ?
|
||||
mountPoints.findByDevice(mapperNode)->mountPoint() :
|
||||
|
@ -384,7 +262,7 @@ void LibPartedBackend::scanDevicePartitions(Device& d, PedDisk* pedDisk)
|
|||
if (mounted) {
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
if (freeSpaceInfo.isValid() && mountPoint != QString())
|
||||
luksFs->setSectorsUsed(freeSpaceInfo.used() / d.logicalSectorSize() + luksFs->getPayloadOffset(node));
|
||||
luksFs->setSectorsUsed(freeSpaceInfo.used() / d->logicalSectorSize() + luksFs->getPayloadOffset(partitionNode));
|
||||
}
|
||||
} else {
|
||||
mounted = false;
|
||||
|
@ -392,16 +270,20 @@ void LibPartedBackend::scanDevicePartitions(Device& d, PedDisk* pedDisk)
|
|||
|
||||
luksFs->setMounted(mounted);
|
||||
} else {
|
||||
mountPoint = mountPoints.findByDevice(node) ?
|
||||
mountPoints.findByDevice(node)->mountPoint() :
|
||||
mountPoint = mountPoints.findByDevice(partitionNode) ?
|
||||
mountPoints.findByDevice(partitionNode)->mountPoint() :
|
||||
QString();
|
||||
mounted = ped_partition_is_busy(pedPartition);
|
||||
mounted = busy;
|
||||
}
|
||||
|
||||
Partition* part = new Partition(parent, d, PartitionRole(r), fs, pedPartition->geom.start, pedPartition->geom.end, node, availableFlags(pedPartition), mountPoint, mounted, activeFlags(pedPartition));
|
||||
QList<QVariant> availableFlags = job->data()[QLatin1String("availableFlags")].toList();
|
||||
PartitionTable::Flags available = static_cast<PartitionTable::Flag>(availableFlags[i].toInt());
|
||||
QList<QVariant> activeFlags = job->data()[QLatin1String("activeFlags")].toList();
|
||||
PartitionTable::Flags active = static_cast<PartitionTable::Flag>(activeFlags[i].toInt());
|
||||
Partition* part = new Partition(parent, *d, PartitionRole(r), fs, start, end, partitionNode, available, mountPoint, mounted, active);
|
||||
|
||||
if (!part->roles().has(PartitionRole::Luks))
|
||||
readSectorsUsed(pedDisk, d, *part, mountPoint);
|
||||
readSectorsUsed(*d, *part, mountPoint);
|
||||
|
||||
if (fs->supportGetLabel() != FileSystem::cmdSupportNone)
|
||||
fs->setLabel(fs->readLabel(part->deviceNode()));
|
||||
|
@ -413,73 +295,39 @@ void LibPartedBackend::scanDevicePartitions(Device& d, PedDisk* pedDisk)
|
|||
partitions.append(part);
|
||||
}
|
||||
|
||||
d.partitionTable()->updateUnallocated(d);
|
||||
d->partitionTable()->updateUnallocated(*d);
|
||||
|
||||
if (d.partitionTable()->isSectorBased(d))
|
||||
d.partitionTable()->setType(d, PartitionTable::msdos_sectorbased);
|
||||
if (d->partitionTable()->isSectorBased(*d))
|
||||
d->partitionTable()->setType(*d, PartitionTable::msdos_sectorbased);
|
||||
|
||||
foreach(const Partition * part, partitions)
|
||||
PartitionAlignment::isAligned(d, *part);
|
||||
PartitionAlignment::isAligned(*d, *part);
|
||||
|
||||
ped_disk_destroy(pedDisk);
|
||||
}
|
||||
|
||||
/** Create a Device for the given device_node and scan it for partitions.
|
||||
@param device_node the device node (e.g. "/dev/sda")
|
||||
@return the created Device object. callers need to free this.
|
||||
*/
|
||||
Device* LibPartedBackend::scanDevice(const QString& device_node)
|
||||
{
|
||||
PedDevice* pedDevice = ped_device_get(device_node.toLocal8Bit().constData());
|
||||
|
||||
if (pedDevice == nullptr) {
|
||||
Log(Log::warning) << xi18nc("@info:status", "Could not access device <filename>%1</filename>", device_node);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Log(Log::information) << xi18nc("@info:status", "Device found: %1", QString::fromUtf8(pedDevice->model));
|
||||
|
||||
Device* d = new Device(QString::fromUtf8(pedDevice->model), QString::fromUtf8(pedDevice->path), pedDevice->bios_geom.heads, pedDevice->bios_geom.sectors, pedDevice->bios_geom.cylinders, pedDevice->sector_size);
|
||||
|
||||
PedDisk* pedDisk = ped_disk_new(pedDevice);
|
||||
|
||||
if (pedDisk) {
|
||||
const PartitionTable::TableType type = PartitionTable::nameToTableType(QString::fromUtf8(pedDisk->type->name));
|
||||
CoreBackend::setPartitionTableForDevice(*d, new PartitionTable(type, firstUsableSector(*d), lastUsableSector(*d)));
|
||||
CoreBackend::setPartitionTableMaxPrimaries(*d->partitionTable(), ped_disk_get_max_primary_partition_count(pedDisk));
|
||||
|
||||
scanDevicePartitions(*d, pedDisk);
|
||||
}
|
||||
|
||||
ped_device_destroy(pedDevice);
|
||||
return d;
|
||||
}
|
||||
|
||||
QList<Device*> LibPartedBackend::scanDevices(bool excludeReadOnly)
|
||||
{
|
||||
QList<Device*> result;
|
||||
QVariantMap args;
|
||||
args[QLatin1String("excludeReadOnly")] = excludeReadOnly;
|
||||
|
||||
ped_device_probe_all();
|
||||
PedDevice* pedDevice = nullptr;
|
||||
QVector<QString> path;
|
||||
quint32 totalDevices = 0;
|
||||
while (true) {
|
||||
pedDevice = ped_device_get_next(pedDevice);
|
||||
if (!pedDevice)
|
||||
break;
|
||||
if (pedDevice->type == PED_DEVICE_DM)
|
||||
continue;
|
||||
if (excludeReadOnly && (
|
||||
pedDevice->type == PED_DEVICE_LOOP ||
|
||||
pedDevice->read_only))
|
||||
continue;
|
||||
|
||||
path.push_back(QString::fromUtf8(pedDevice->path));
|
||||
++totalDevices;
|
||||
KAuth::Action scanAction = QStringLiteral("org.kde.kpmcore.scan.scandevices");
|
||||
scanAction.setHelperId(QStringLiteral("org.kde.kpmcore.scan"));
|
||||
scanAction.setArguments(args);
|
||||
KAuth::ExecuteJob *job = scanAction.execute();
|
||||
if (!job->exec()) {
|
||||
qWarning() << "KAuth returned an error code: " << job->errorString();
|
||||
return result;
|
||||
}
|
||||
QList<QVariant> paths = job->data()[QLatin1String("paths")].toList();
|
||||
|
||||
quint32 totalDevices = paths.size();
|
||||
for (quint32 i = 0; i < totalDevices; ++i) {
|
||||
emitScanProgress(path[i], i * 100 / totalDevices);
|
||||
Device* d = scanDevice(path[i]);
|
||||
QString path = paths[i].toString();
|
||||
emitScanProgress(path, i * 100 / totalDevices);
|
||||
Device* d = scanDevice(path);
|
||||
if (d)
|
||||
result.append(d);
|
||||
}
|
||||
|
@ -546,9 +394,9 @@ FileSystem::Type LibPartedBackend::detectFileSystem(const QString& partitionPath
|
|||
return rval;
|
||||
}
|
||||
|
||||
CoreBackendDevice* LibPartedBackend::openDevice(const QString& device_node)
|
||||
CoreBackendDevice* LibPartedBackend::openDevice(const QString& deviceNode)
|
||||
{
|
||||
LibPartedDevice* device = new LibPartedDevice(device_node);
|
||||
LibPartedDevice* device = new LibPartedDevice(deviceNode);
|
||||
|
||||
if (device == nullptr || !device->open()) {
|
||||
delete device;
|
||||
|
@ -558,9 +406,9 @@ CoreBackendDevice* LibPartedBackend::openDevice(const QString& device_node)
|
|||
return device;
|
||||
}
|
||||
|
||||
CoreBackendDevice* LibPartedBackend::openDeviceExclusive(const QString& device_node)
|
||||
CoreBackendDevice* LibPartedBackend::openDeviceExclusive(const QString& deviceNode)
|
||||
{
|
||||
LibPartedDevice* device = new LibPartedDevice(device_node);
|
||||
LibPartedDevice* device = new LibPartedDevice(deviceNode);
|
||||
|
||||
if (device == nullptr || !device->openExclusive()) {
|
||||
delete device;
|
||||
|
|
|
@ -61,10 +61,10 @@ private:
|
|||
public:
|
||||
void initFSSupport() override;
|
||||
|
||||
CoreBackendDevice* openDevice(const QString& device_node) override;
|
||||
CoreBackendDevice* openDeviceExclusive(const QString& device_node) override;
|
||||
CoreBackendDevice* openDevice(const QString& deviceNode) override;
|
||||
CoreBackendDevice* openDeviceExclusive(const QString& deviceNode) override;
|
||||
bool closeDevice(CoreBackendDevice* core_device) override;
|
||||
Device* scanDevice(const QString& device_node) override;
|
||||
Device* scanDevice(const QString& deviceNode) override;
|
||||
QList<Device*> scanDevices(bool excludeReadOnly = false) override;
|
||||
FileSystem::Type detectFileSystem(const QString& partitionPath) override;
|
||||
|
||||
|
@ -72,7 +72,6 @@ public:
|
|||
|
||||
private:
|
||||
static PedPartitionFlag getPedFlag(PartitionTable::Flag flag);
|
||||
void scanDevicePartitions(Device& d, PedDisk* pedDisk);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue