170 lines
7.4 KiB
C++
170 lines
7.4 KiB
C++
/*************************************************************************
|
|
* 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::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)
|