/************************************************************************* * 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 .* *************************************************************************/ #include "plugins/libparted/libparteddevice.h" #include "plugins/libparted/libpartedpartitiontable.h" #include "core/partitiontable.h" #include "util/globallog.h" #include "util/report.h" #include LibPartedDevice::LibPartedDevice(const QString& deviceNode) : CoreBackendDevice(deviceNode), m_PedDevice(nullptr) { } LibPartedDevice::~LibPartedDevice() { if (pedDevice()) close(); } bool LibPartedDevice::open() { Q_ASSERT(pedDevice() == nullptr); if (pedDevice()) return false; m_PedDevice = ped_device_get(deviceNode().toLocal8Bit().constData()); return m_PedDevice != nullptr; } bool LibPartedDevice::openExclusive() { bool rval = open() && ped_device_open(pedDevice()); if (rval) setExclusive(true); return rval; } bool LibPartedDevice::close() { Q_ASSERT(pedDevice()); if (pedDevice() && isExclusive()) { ped_device_close(pedDevice()); setExclusive(false); } m_PedDevice = nullptr; return true; } CoreBackendPartitionTable* LibPartedDevice::openPartitionTable() { CoreBackendPartitionTable* ptable = new LibPartedPartitionTable(pedDevice()); if (ptable == nullptr || !ptable->open()) { delete ptable; ptable = nullptr; } return ptable; } bool LibPartedDevice::createPartitionTable(Report& report, const PartitionTable& ptable) { PedDiskType* pedDiskType = ped_disk_type_get(ptable.typeName().toLocal8Bit().constData()); if (pedDiskType == nullptr) { report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not retrieve partition table type \"%1\" for %2.", ptable.typeName(), deviceNode()); return false; } PedDevice* dev = ped_device_get(deviceNode().toLocal8Bit().constData()); if (dev == nullptr) { report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not open backend device %1.", deviceNode()); return false; } PedDisk* disk = ped_disk_new_fresh(dev, pedDiskType); if (disk == nullptr) { report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not create a new partition table in the backend for device %1.", deviceNode()); return false; } return LibPartedPartitionTable::commit(disk); } bool LibPartedDevice::readData(QByteArray& buffer, qint64 offset, qint64 size) { if (!isExclusive()) return false; void *data = malloc(size); bool rval = ped_device_read(pedDevice(), data, offset / pedDevice()->sector_size, size / pedDevice()->sector_size); buffer = QByteArray(static_cast(data), size); free(data); return rval; } bool LibPartedDevice::writeData(QByteArray& buffer, qint64 offset) { if (!isExclusive()) return false; return ped_device_write(pedDevice(), static_cast(buffer.constData()), offset / pedDevice()->sector_size, buffer.size() / pedDevice()->sector_size); }