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;
|
qint32 maxEntries;
|
||||||
QByteArray gptHeader;
|
QByteArray gptHeader;
|
||||||
CopySourceDevice source(d, 512, 1023);
|
CopySourceDevice source(d, 512, 1023);
|
||||||
CopyTargetByteArray target(gptHeader);
|
|
||||||
|
|
||||||
ExternalCommand copyCmd;
|
ExternalCommand readCmd;
|
||||||
if (copyCmd.copyBlocks(source, target)) {
|
if (readCmd.readData(source, gptHeader)) {
|
||||||
QByteArray gptMaxEntries = gptHeader.mid(80, 4);
|
QByteArray gptMaxEntries = gptHeader.mid(80, 4);
|
||||||
QDataStream stream(&gptMaxEntries, QIODevice::ReadOnly);
|
QDataStream stream(&gptMaxEntries, QIODevice::ReadOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
|
@ -187,6 +187,35 @@ bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target)
|
||||||
return rval;
|
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)
|
bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte)
|
||||||
{
|
{
|
||||||
d->m_Report = commandReport.newChild();
|
d->m_Report = commandReport.newChild();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
class KJob;
|
class KJob;
|
||||||
class Report;
|
class Report;
|
||||||
class CopySource;
|
class CopySource;
|
||||||
|
class CopySourceDevice;
|
||||||
class CopyTarget;
|
class CopyTarget;
|
||||||
class QDBusInterface;
|
class QDBusInterface;
|
||||||
class QDBusPendingCall;
|
class QDBusPendingCall;
|
||||||
|
@ -54,6 +55,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool copyBlocks(const CopySource& source, CopyTarget& target);
|
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 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
|
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);
|
QFile device(targetDevice);
|
||||||
|
|
||||||
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered | QIODevice::Append;
|
auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered;
|
||||||
if (!device.open(flags)) {
|
if (!device.open(flags)) {
|
||||||
qCritical() << xi18n("Could not open device <filename>%1</filename> for writing.", targetDevice);
|
qCritical() << xi18n("Could not open device <filename>%1</filename> for writing.", targetDevice);
|
||||||
return false;
|
return false;
|
||||||
|
@ -165,13 +165,9 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent some out of memory situations
|
// Prevent some out of memory situations
|
||||||
constexpr qint64 MiB = 1 << 30;
|
|
||||||
if (blockSize > 100 * MiB) {
|
if (blockSize > 100 * MiB) {
|
||||||
return QVariantMap();
|
return QVariantMap();
|
||||||
}
|
}
|
||||||
if (targetDevice.isEmpty() && sourceLength > MiB) {
|
|
||||||
return QVariantMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantMap reply;
|
QVariantMap reply;
|
||||||
reply[QStringLiteral("success")] = true;
|
reply[QStringLiteral("success")] = true;
|
||||||
|
@ -222,7 +218,7 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
||||||
|
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) {
|
while (blocksCopied < blocksToCopy) {
|
||||||
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
|
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -255,9 +251,6 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
||||||
rval = readData(sourceDevice, buffer, lastBlockReadOffset, lastBlock);
|
rval = readData(sourceDevice, buffer, lastBlockReadOffset, lastBlock);
|
||||||
|
|
||||||
if (rval) {
|
if (rval) {
|
||||||
if (targetDevice.isEmpty())
|
|
||||||
reply[QStringLiteral("targetByteArray")] = buffer;
|
|
||||||
else
|
|
||||||
rval = writeData(targetDevice, buffer, lastBlockWriteOffset);
|
rval = writeData(targetDevice, buffer, lastBlockWriteOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +267,24 @@ QVariantMap ExternalCommandHelper::CopyBlocks(const QString& sourceDevice, const
|
||||||
return reply;
|
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)
|
bool ExternalCommandHelper::WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetOffset)
|
||||||
{
|
{
|
||||||
if (!isCallerAuthorized()) {
|
if (!isCallerAuthorized()) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <QDBusContext>
|
#include <QDBusContext>
|
||||||
|
|
||||||
class QDBusServiceWatcher;
|
class QDBusServiceWatcher;
|
||||||
|
constexpr qint64 MiB = 1 << 30;
|
||||||
|
|
||||||
class ExternalCommandHelper : public QObject, public QDBusContext
|
class ExternalCommandHelper : public QObject, public QDBusContext
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,9 @@ public:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
Q_SCRIPTABLE QVariantMap RunCommand(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode);
|
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 WriteData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetOffset);
|
||||||
Q_SCRIPTABLE bool CreateFile(const QString& filePath, const QByteArray& fileContents);
|
Q_SCRIPTABLE bool CreateFile(const QString& filePath, const QByteArray& fileContents);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue