Add an explicit ReadData method to polkit helper instead of relying on copyblocks with empty target device.
This commit is contained in:
parent
502ebc0474
commit
b0e5fa66c4
|
@ -452,10 +452,9 @@ bool SfdiskBackend::updateDevicePartitionTable(Device &d, const QJsonObject &jso
|
|||
qint32 maxEntries;
|
||||
QByteArray gptHeader;
|
||||
CopySourceDevice source(d, 512, 1023);
|
||||
CopyTargetByteArray target(gptHeader);
|
||||
|
||||
ExternalCommand copyCmd;
|
||||
if (copyCmd.copyBlocks(source, target)) {
|
||||
ExternalCommand readCmd;
|
||||
if (readCmd.readData(source, gptHeader)) {
|
||||
QByteArray gptMaxEntries = gptHeader.mid(80, 4);
|
||||
QDataStream stream(&gptMaxEntries, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
|
|
@ -187,6 +187,35 @@ bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target)
|
|||
return rval;
|
||||
}
|
||||
|
||||
bool ExternalCommand::readData(const CopySourceDevice& source, QByteArray& target)
|
||||
{
|
||||
auto interface = helperInterface();
|
||||
if (!interface)
|
||||
return false;
|
||||
|
||||
QDBusPendingCall pcall = interface->ReadData(source.path(), source.firstByte(), source.length());
|
||||
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
|
||||
QEventLoop loop;
|
||||
|
||||
auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) {
|
||||
loop.exit();
|
||||
|
||||
if (watcher->isError())
|
||||
qWarning() << watcher->error();
|
||||
else {
|
||||
QDBusPendingReply<QByteArray> reply = *watcher;
|
||||
|
||||
target = reply.value();
|
||||
}
|
||||
};
|
||||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop);
|
||||
loop.exec();
|
||||
|
||||
return target != QByteArray();
|
||||
}
|
||||
|
||||
bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte)
|
||||
{
|
||||
d->m_Report = commandReport.newChild();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
class KJob;
|
||||
class Report;
|
||||
class CopySource;
|
||||
class CopySourceDevice;
|
||||
class CopyTarget;
|
||||
class QDBusInterface;
|
||||
class QDBusPendingCall;
|
||||
|
@ -54,6 +55,7 @@ public:
|
|||
|
||||
public:
|
||||
bool copyBlocks(const CopySource& source, CopyTarget& target);
|
||||
bool readData(const CopySourceDevice& source, QByteArray& target);
|
||||
bool writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte); // same as copyBlocks but from QByteArray
|
||||
bool createFile(const QByteArray& filePath, const QString& fileContents); // similar to writeData but creates a new file
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr
|
|||
{
|
||||
QFile device(targetDevice);
|
||||
|
||||
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered | QIODevice::Append;
|
||||
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered;
|
||||
if (!device.open(flags)) {
|
||||
qCritical() << xi18n("Could not open device <filename>%1</filename> for writing.", targetDevice);
|
||||
return false;
|
||||
|
@ -165,13 +165,9 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
|||
}
|
||||
|
||||
// Prevent some out of memory situations
|
||||
constexpr qint64 MiB = 1 << 30;
|
||||
if (blockSize > 100 * MiB) {
|
||||
return QVariantMap();
|
||||
}
|
||||
if (targetDevice.isEmpty() && sourceLength > MiB) {
|
||||
return QVariantMap();
|
||||
}
|
||||
|
||||
QVariantMap reply;
|
||||
reply[QStringLiteral("success")] = true;
|
||||
|
@ -222,7 +218,7 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
|||
|
||||
bool rval = true;
|
||||
|
||||
while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) {
|
||||
while (blocksCopied < blocksToCopy) {
|
||||
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
|
||||
break;
|
||||
|
||||
|
@ -255,10 +251,7 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
|||
rval = readData(sourceDevice, buffer, lastBlockReadOffset, lastBlock);
|
||||
|
||||
if (rval) {
|
||||
if (targetDevice.isEmpty())
|
||||
reply[QStringLiteral("targetByteArray")] = buffer;
|
||||
else
|
||||
rval = writeData(targetDevice, buffer, lastBlockWriteOffset);
|
||||
rval = writeData(targetDevice, buffer, lastBlockWriteOffset);
|
||||
}
|
||||
|
||||
if (rval) {
|
||||
|
@ -274,6 +267,24 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
|||
return reply;
|
||||
}
|
||||
|
||||
QByteArray ExternalCommandHelper::ReadData(const QString& device, const qint64 offset, const qint64 length)
|
||||
{
|
||||
if (!isCallerAuthorized()) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (length > MiB) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray buffer;
|
||||
bool rval = readData(device, buffer, offset, length);
|
||||
if (rval) {
|
||||
return buffer;
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
bool ExternalCommandHelper::WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetOffset)
|
||||
{
|
||||
if (!isCallerAuthorized()) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <QDBusContext>
|
||||
|
||||
class QDBusServiceWatcher;
|
||||
constexpr qint64 MiB = 1 << 30;
|
||||
|
||||
class ExternalCommandHelper : public QObject, public QDBusContext
|
||||
{
|
||||
|
@ -37,7 +38,9 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
Q_SCRIPTABLE QVariantMap RunCommand(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode);
|
||||
Q_SCRIPTABLE QVariantMap CopyBlocks(const QString& sourceDevice, const qint64 sourceOffset, const qint64 sourceLength, const QString& targetDevice, const qint64 targetOffset, const qint64 blockSize);
|
||||
Q_SCRIPTABLE QVariantMap CopyBlocks(const QString& sourceDevice, const qint64 sourceOffset, const qint64 sourceLength,
|
||||
const QString& targetDevice, const qint64 targetOffset, const qint64 blockSize);
|
||||
Q_SCRIPTABLE QByteArray ReadData(const QString& device, const qint64 offset, const qint64 length);
|
||||
Q_SCRIPTABLE bool WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetOffset);
|
||||
Q_SCRIPTABLE bool CreateFile(const QString& filePath, const QByteArray& fileContents);
|
||||
|
||||
|
|
Loading…
Reference in New Issue