summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/binarycontent.cpp242
-rw-r--r--src/libs/installer/binarycontent.h17
-rw-r--r--src/libs/installer/binarylayout.cpp110
-rw-r--r--src/libs/installer/binarylayout.h70
-rw-r--r--src/libs/installer/installer.pro6
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp11
-rw-r--r--tests/auto/installer/binaryformat/tst_binaryformat.cpp107
-rw-r--r--tools/devtool/binaryreplace.cpp3
-rw-r--r--tools/devtool/binaryreplace.h2
-rw-r--r--tools/devtool/main.cpp104
10 files changed, 356 insertions, 316 deletions
diff --git a/src/libs/installer/binarycontent.cpp b/src/libs/installer/binarycontent.cpp
index 25032177b..7ba285f3a 100644
--- a/src/libs/installer/binarycontent.cpp
+++ b/src/libs/installer/binarycontent.cpp
@@ -41,6 +41,7 @@
#include "binarycontent.h"
+#include "binarylayout.h"
#include "errors.h"
#include "fileio.h"
#include "fileutils.h"
@@ -93,214 +94,107 @@ qint64 BinaryContent::findMagicCookie(QFile *in, quint64 magicCookie)
return -1; // never reached
}
-/*!
-* \class QInstaller::BinaryContent
-*
-* BinaryContent handles binary information embedded into executables.
-* Qt resources as well as resource collections can be stored.
-*
-* Explanation of the binary blob at the end of the installer or separate data file:
-*
-* \verbatim
-*
-* Meta data entry [1 ... n]
-* [Format]
-* Plain data (QResource)
-* [Format]
-* ----------------------------------------------------------
-* Operation count (qint64)
-* Operation entry [1 ... n]
-* [Format]
-* Name (qint64, QString)
-* XML (qint64, QString)
-* [Format]
-* Operation count (qint64)
-* ----------------------------------------------------------
-* Component count
-* Component data entry [1 ... n]
-* [Format]
-* Archive count (qint64),
-* Name entry [1 ... n]
-* [Format]
-* Name (qint64, QByteArray),
-* Offset (qint64),
-* Length (qint64),
-* [Format]
-* Archive data entry [1 ... n]
-* [Format]
-* Plain data
-* [Format]
-* [Format]
-* ----------------------------------------------------------
-* Component count (qint64)
-* Component index entry [1 ... n]
-* [Format]
-* Name (qint64, QByteArray)
-* Offset (qint64)
-* Length (qint64)
-* [Format]
-* Component count (qint64)
-* ----------------------------------------------------------
-* Component index block [Offset (qint64)]
-* Component index block [Length (qint64)]
-* ----------------------------------------------------------
-* Resource segments [1 ... n]
-* [Format]
-* Offset (qint64)
-* Length (qint64)
-* [Format]
-* ----------------------------------------------------------
-* Operations information block [Offset (qint64)]
-* Operations information block [Length (qint64)]
-* ----------------------------------------------------------
-* Meta data count (qint64)
-* ----------------------------------------------------------
-* Binary content size [Including Marker and Cookie (qint64)]
-* ----------------------------------------------------------
-* Magic marker (qint64)
-* Magic cookie (qint64)
-
-* \endverbatim
-*/
-
-/* static */
BinaryLayout BinaryContent::binaryLayout(QFile *file, quint64 magicCookie)
{
- const qint64 cookiePos = BinaryContent::findMagicCookie(file, magicCookie);
- const qint64 indexSize = 5 * sizeof(qint64);
- if (!file->seek(cookiePos - indexSize)) {
- throw Error(QCoreApplication::translate("BinaryContent",
- "Could not seek to binary layout section."));
- }
-
BinaryLayout layout;
- layout.operationsStart = QInstaller::retrieveInt64(file);
- layout.operationsEnd = QInstaller::retrieveInt64(file);
- layout.resourceCount = QInstaller::retrieveInt64(file);
- layout.dataBlockSize = QInstaller::retrieveInt64(file);
- layout.magicMarker = QInstaller::retrieveInt64(file);
- layout.magicCookie = QInstaller::retrieveInt64(file);
- layout.indexSize = indexSize + sizeof(qint64);
- layout.endOfData = file->pos();
-
- qDebug() << "Operations start:" << layout.operationsStart;
- qDebug() << "Operations end:" << layout.operationsEnd;
- qDebug() << "Resource count:" << layout.resourceCount;
- qDebug() << "Data block size:" << layout.dataBlockSize;
- qDebug() << "Magic marker:" << layout.magicMarker;
- qDebug() << "Magic cookie:" << layout.magicCookie;
- qDebug() << "Index size:" << layout.indexSize;
- qDebug() << "End of data:" << layout.endOfData;
-
- const qint64 resourceOffsetAndLengtSize = 2 * sizeof(qint64);
- const qint64 dataBlockStart = layout.endOfData - layout.dataBlockSize;
- for (int i = 0; i < layout.resourceCount; ++i) {
- const qint64 offset = layout.endOfData - layout.indexSize
- - (resourceOffsetAndLengtSize * (i + 1));
- if (!file->seek(offset)) {
- throw Error(QCoreApplication::translate("BinaryContent",
- "Could not seek to metadata index."));
- }
- const qint64 metadataResourceOffset = QInstaller::retrieveInt64(file);
- const qint64 metadataResourceLength = QInstaller::retrieveInt64(file);
- layout.metadataResourceSegments.append(Range<qint64>::fromStartAndLength(metadataResourceOffset
- + dataBlockStart, metadataResourceLength));
- }
-
- return layout;
-}
+ layout.endOfBinaryContent = BinaryContent::findMagicCookie(file, magicCookie) + sizeof(qint64);
-void BinaryContent::readBinaryContent(const QSharedPointer<QFile> &in,
- ResourceCollection *metaResources, QList<OperationBlob> *operations,
- ResourceCollectionManager *manager, qint64 *magicMarker, quint64 magicCookie)
-{
- const qint64 pos = BinaryContent::findMagicCookie(in.data(), magicCookie);
- const qint64 endOfBinaryContent = pos + sizeof(qint64);
-
- const qint64 posOfMetaDataCount = endOfBinaryContent - (4 * sizeof(qint64));
- if (!in->seek(posOfMetaDataCount)) {
- throw Error(QCoreApplication::translate("BinaryContent",
+ const qint64 posOfMetaDataCount = layout.endOfBinaryContent - (4 * sizeof(qint64));
+ if (!file->seek(posOfMetaDataCount)) {
+ throw QInstaller::Error(QCoreApplication::translate("BinaryLayout",
"Could not seek to %1 to read the embedded meta data count.").arg(posOfMetaDataCount));
}
+
// read the meta resources count
- const qint64 metaResourcesCount = QInstaller::retrieveInt64(in.data());
+ const qint64 metaResourcesCount = QInstaller::retrieveInt64(file);
- const qint64 posOfResourceCollectionsSegment = endOfBinaryContent
+ const qint64 posOfResourceCollectionsSegment = layout.endOfBinaryContent
- ((metaResourcesCount * (2 * sizeof(qint64))) // minus the size of the meta data segments
+ (8 * sizeof(qint64))); // meta count, offset/length component index, marker, cookie...
- if (!in->seek(posOfResourceCollectionsSegment)) {
- throw Error(QCoreApplication::translate("BinaryContent",
+ if (!file->seek(posOfResourceCollectionsSegment)) {
+ throw Error(QCoreApplication::translate("BinaryLayout",
"Could not seek to %1 to read the resource collection segment.")
.arg(posOfResourceCollectionsSegment));
}
+
// read the resource collection index offset and length
- const Range<qint64> resourceCollectionsSegment = QInstaller::retrieveInt64Range(in.data());
+ layout.resourceCollectionsSegment = QInstaller::retrieveInt64Range(file);
// read the meta data resource segments
- QVector<Range<qint64> > metaDataResourceSegments;
for (int i = 0; i < metaResourcesCount; ++i)
- metaDataResourceSegments.append(QInstaller::retrieveInt64Range(in.data()));
+ layout.metaResourceSegments.append(QInstaller::retrieveInt64Range(file));
+
+ if (metaResourcesCount != layout.metaResourceSegments.count()) {
+ throw Error(QCoreApplication::translate("BinaryLayout",
+ "Unexpected mismatch of meta resources. Read %1, expected: %2.")
+ .arg(layout.metaResourceSegments.count()).arg(metaResourcesCount));
+ }
// read the operations offset and length
- const Range<qint64> operationsSegment = QInstaller::retrieveInt64Range(in.data());
+ layout.operationsSegment = QInstaller::retrieveInt64Range(file);
// resources count
- Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
+ Q_UNUSED(QInstaller::retrieveInt64(file)) // read it, but deliberately not used
// read the binary content size
- const qint64 binaryContentSize = QInstaller::retrieveInt64(in.data());
- const qint64 endOfBinary = endOfBinaryContent - binaryContentSize; // end of "compiled" binary
+ layout.binaryContentSize = QInstaller::retrieveInt64(file);
+ layout.endOfExectuable = layout.endOfBinaryContent - layout.binaryContentSize;
- // read the marker
- const qint64 marker = QInstaller::retrieveInt64(in.data());
- if (magicMarker)
- *magicMarker = marker;
+ layout.magicMarker = QInstaller::retrieveInt64(file);
+ layout.magicCookie = QInstaller::retrieveInt64(file);
- // the cookie
- Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
+ // adjust the offsets to match the actual binary
+ for (int i = 0; i < layout.metaResourceSegments.count(); ++i)
+ layout.metaResourceSegments[i].move(layout.endOfExectuable);
+ layout.metaResourcesSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments
+ .first().start(), layout.metaResourceSegments.last().end());
- // append the calculated resource segments
- if (metaResources) {
- foreach (const Range<qint64> &segment, metaDataResourceSegments) {
- metaResources->appendResource(QSharedPointer<Resource>(new Resource(in,
- segment.moved(endOfBinary))));
- }
- }
+ layout.operationsSegment.move(layout.endOfExectuable);
+ layout.resourceCollectionsSegment.move(layout.endOfExectuable);
+
+ return layout;
+}
+
+void BinaryContent::readBinaryContent(const QSharedPointer<QFile> &in,
+ ResourceCollection *metaResources, QList<OperationBlob> *operations,
+ ResourceCollectionManager *manager, qint64 *magicMarker, quint64 magicCookie)
+{
+ const BinaryLayout layout = BinaryContent::binaryLayout(in.data(), magicCookie);
- const qint64 posOfOperationsBlock = endOfBinary + operationsSegment.start();
- if (!in->seek(posOfOperationsBlock)) {
- throw Error(QCoreApplication::translate("BinaryContent",
- "Could not seek to %1 to read the operation data.").arg(posOfOperationsBlock));
+ if (metaResources) { // append the meta resources
+ foreach (const Range<qint64> &segment, layout.metaResourceSegments)
+ metaResources->appendResource(QSharedPointer<Resource>(new Resource(in, segment)));
}
- // read the operations count
- qint64 operationsCount = QInstaller::retrieveInt64(in.data());
- // read the operations
- for (int i = 0; i < operationsCount; ++i) {
- const QString name = QInstaller::retrieveString(in.data());
- const QString xml = QInstaller::retrieveString(in.data());
- if (operations)
+
+ if (operations) {
+ const qint64 posOfOperationsBlock = layout.operationsSegment.start();
+ if (!in->seek(posOfOperationsBlock)) {
+ throw Error(QCoreApplication::translate("BinaryContent",
+ "Could not seek to %1 to read the operation data.").arg(posOfOperationsBlock));
+ }
+ // read the operations count
+ qint64 operationsCount = QInstaller::retrieveInt64(in.data());
+ // read the operations
+ for (int i = 0; i < operationsCount; ++i) {
+ const QString name = QInstaller::retrieveString(in.data());
+ const QString xml = QInstaller::retrieveString(in.data());
operations->append(OperationBlob(name, xml));
+ }
+ // operations count
+ Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
}
- // operations count
- Q_UNUSED(QInstaller::retrieveInt64(in.data())) // read it, but deliberately not used
- // read the resource collections count
- const qint64 collectionCount = QInstaller::retrieveInt64(in.data());
-
- const qint64 posOfResourceCollectionBlock = endOfBinary + resourceCollectionsSegment.start();
- if (!in->seek(posOfResourceCollectionBlock)) {
- throw Error(QCoreApplication::translate("BinaryContent",
- "Could not seek to %1 to read the resource collection block.")
- .arg(posOfResourceCollectionBlock));
- }
if (manager) { // read the component index and data
- manager->read(in, endOfBinary);
- if (manager->collectionCount() != collectionCount) {
- throw Error(QCoreApplication::translate("BinaryContent",
- "Unexpected mismatch of resource collections. Read %1, expected: %2.")
- .arg(manager->collectionCount()).arg(collectionCount));
+ const qint64 posOfResourceCollectionBlock = layout.resourceCollectionsSegment.start();
+ if (!in->seek(posOfResourceCollectionBlock)) {
+ throw Error(QCoreApplication::translate("BinaryContent", "Could not seek to %1 to "
+ "read the resource collection block.").arg(posOfResourceCollectionBlock));
}
+ manager->read(in, layout.endOfExectuable);
}
+
+ if (magicMarker)
+ *magicMarker = layout.magicMarker;
}
void BinaryContent::writeBinaryContent(const QSharedPointer<QFile> &out,
diff --git a/src/libs/installer/binarycontent.h b/src/libs/installer/binarycontent.h
index 2efe3d0fc..b4527a74a 100644
--- a/src/libs/installer/binarycontent.h
+++ b/src/libs/installer/binarycontent.h
@@ -43,9 +43,7 @@
#define BINARYCONTENT_H
#include "binaryformat.h"
-#include "range.h"
-
-#include <QVector>
+#include "binarylayout.h"
QT_BEGIN_NAMESPACE
class QFile;
@@ -53,19 +51,6 @@ QT_END_NAMESPACE
namespace QInstaller {
-struct BinaryLayout
-{
- QVector<Range<qint64> > metadataResourceSegments;
- qint64 operationsStart;
- qint64 operationsEnd;
- qint64 resourceCount;
- qint64 dataBlockSize;
- qint64 magicMarker;
- quint64 magicCookie;
- qint64 indexSize;
- qint64 endOfData;
-};
-
class INSTALLER_EXPORT BinaryContent
{
public:
diff --git a/src/libs/installer/binarylayout.cpp b/src/libs/installer/binarylayout.cpp
new file mode 100644
index 000000000..6437262af
--- /dev/null
+++ b/src/libs/installer/binarylayout.cpp
@@ -0,0 +1,110 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+/*!
+ \class QInstaller::BinaryLayout
+
+ BinaryLayout handles binary information embedded into executables.
+ Qt resources as well as resource collections can be stored.
+
+ Explanation of the binary blob at the end of the installer or separate data file:
+
+ \code
+
+ Meta data entry [1 ... n]
+ [Format]
+ Plain data (QResource)
+ [Format]
+ ----------------------------------------------------------
+ Operation count (qint64)
+ Operation entry [1 ... n]
+ [Format]
+ Name (qint64, QString)
+ XML (qint64, QString)
+ [Format]
+ Operation count (qint64)
+ ----------------------------------------------------------
+ Component count
+ Component data entry [1 ... n]
+ [Format]
+ Archive count (qint64),
+ Name entry [1 ... n]
+ [Format]
+ Name (qint64, QByteArray),
+ Offset (qint64),
+ Length (qint64),
+ [Format]
+ Archive data entry [1 ... n]
+ [Format]
+ Plain data
+ [Format]
+ [Format]
+ ----------------------------------------------------------
+ Component count (qint64)
+ Component index entry [1 ... n]
+ [Format]
+ Name (qint64, QByteArray)
+ Offset (qint64)
+ Length (qint64)
+ [Format]
+ Component count (qint64)
+ ----------------------------------------------------------
+ Component index block [Offset (qint64)]
+ Component index block [Length (qint64)]
+ ----------------------------------------------------------
+ Resource segments [1 ... n]
+ [Format]
+ Offset (qint64)
+ Length (qint64)
+ [Format]
+ ----------------------------------------------------------
+ Operations information block [Offset (qint64)]
+ Operations information block [Length (qint64)]
+ ----------------------------------------------------------
+ Meta data count (qint64)
+ ----------------------------------------------------------
+ Binary content size [Including Marker and Cookie (qint64)]
+ ----------------------------------------------------------
+ Magic marker (qint64)
+ Magic cookie (qint64)
+
+ \endcode
+*/
diff --git a/src/libs/installer/binarylayout.h b/src/libs/installer/binarylayout.h
new file mode 100644
index 000000000..87c8e97dd
--- /dev/null
+++ b/src/libs/installer/binarylayout.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef BINARYLAYOUT_H
+#define BINARYLAYOUT_H
+
+#include "range.h"
+
+#include <QVector>
+
+namespace QInstaller {
+
+struct BinaryLayout
+{
+ qint64 endOfExectuable;
+
+ QVector<Range<qint64> > metaResourceSegments;
+
+ Range<qint64> metaResourcesSegment;
+ Range<qint64> operationsSegment;
+ Range<qint64> resourceCollectionsSegment;
+
+ qint64 binaryContentSize;
+ qint64 magicMarker;
+ quint64 magicCookie;
+
+ qint64 endOfBinaryContent;
+};
+
+} // namespace QInstaller
+
+#endif // BINARYLAYOUT
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index ffe086053..0f8ec3bcb 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -118,7 +118,8 @@ HEADERS += packagemanagercore.h \
remoteserverconnection.h \
remoteserverconnection_p.h \
fileio.h \
- binarycontent.h
+ binarycontent.h \
+ binarylayout.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -186,7 +187,8 @@ SOURCES += packagemanagercore.cpp \
remotefileengine.cpp \
remoteserverconnection.cpp \
fileio.cpp \
- binarycontent.cpp
+ binarycontent.cpp \
+ binarylayout.cpp
RESOURCES += resources/patch_file_lists.qrc \
resources/installer.qrc
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index c9cd458a6..e182d1159 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -43,6 +43,7 @@
#include "adminauthorization.h"
#include "binarycontent.h"
#include "binaryformatenginehandler.h"
+#include "binarylayout.h"
#include "component.h"
#include "scriptengine.h"
#include "componentmodel.h"
@@ -1114,7 +1115,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
const qint64 dataBlockStart = output->pos();
QVector<Range<qint64> >resourceSegments;
- QVector<Range<qint64> >existingResourceSegments = layout.metadataResourceSegments;
+ QVector<Range<qint64> >existingResourceSegments = layout.metaResourceSegments;
const QString newDefaultResource = m_core->value(QString::fromLatin1("DefaultResourceReplacement"));
if (!newDefaultResource.isEmpty()) {
@@ -1168,7 +1169,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
QInstaller::appendInt64Range(output, segment.moved(-dataBlockStart));
QInstaller::appendInt64Range(output, Range<qint64>::fromStartAndEnd(operationsStart, operationsEnd)
.moved(-dataBlockStart));
- QInstaller::appendInt64(output, layout.resourceCount);
+ QInstaller::appendInt64(output, layout.metaResourceSegments.count());
// data block size, from end of .exe to end of file
QInstaller::appendInt64(output, output->pos() + 3 * sizeof(qint64) -dataBlockStart);
QInstaller::appendInt64(output, BinaryContent::MagicUninstallerMarker);
@@ -1368,7 +1369,8 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
layout = BinaryContent::binaryLayout(&input, BinaryContent::MagicCookie);
if (!newBinaryWritten) {
newBinaryWritten = true;
- writeMaintenanceToolBinary(&input, layout.endOfData - layout.dataBlockSize, true);
+ writeMaintenanceToolBinary(&input, layout.endOfBinaryContent
+ - layout.binaryContentSize, true);
}
#endif
}
@@ -1402,7 +1404,8 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
QFile tmp(isInstaller() ? installerBinaryPath() : maintenanceToolName());
QInstaller::openForRead(&tmp);
BinaryLayout tmpLayout = BinaryContent::binaryLayout(&tmp, BinaryContent::MagicCookie);
- writeMaintenanceToolBinary(&tmp, tmpLayout.endOfData - tmpLayout.dataBlockSize, false);
+ writeMaintenanceToolBinary(&tmp, tmpLayout.endOfBinaryContent
+ - tmpLayout.binaryContentSize, false);
}
QFile file(maintenanceToolName() + QLatin1String(".new"));
diff --git a/tests/auto/installer/binaryformat/tst_binaryformat.cpp b/tests/auto/installer/binaryformat/tst_binaryformat.cpp
index d313bbbcc..87a1f7ef8 100644
--- a/tests/auto/installer/binaryformat/tst_binaryformat.cpp
+++ b/tests/auto/installer/binaryformat/tst_binaryformat.cpp
@@ -54,22 +54,11 @@ static const qint64 scLargeSize = 2097152LL;
using namespace QInstaller;
-struct Layout
+struct Layout : public QInstaller::BinaryLayout
{
- Range<qint64> metaResourceSegment;
- QVector<Range<qint64> > metaResourceSegments;
-
+ qint64 metaSegmentsCount;
qint64 operationsCount;
- Range<qint64> operationsSegment;
-
qint64 collectionCount;
- Range<qint64> resourceCollectionIndexSegment;
-
- qint64 binaryContentSize;
- qint64 magicMarker;
- quint64 magicCookie;
-
- qint64 endOfBinary;
};
class TestOperation : public KDUpdater::UpdateOperation
@@ -165,23 +154,22 @@ private slots:
QInstaller::blockingWrite(&binary, QByteArray(scTinySize, '1'));
Layout layout;
- layout.endOfBinary = binary.pos();
+ layout.endOfExectuable = binary.pos();
layout.magicMarker = BinaryContent::MagicInstallerMarker;
layout.magicCookie = BinaryContent::MagicCookie;
qint64 start = binary.pos(); // write default resource (fake)
QInstaller::blockingWrite(&binary, QByteArray("Default resource data."));
qint64 end = binary.pos();
- layout.metaResourceSegments.append(Range<qint64>::fromStartAndEnd(start, end)
- .moved(-layout.endOfBinary));
+ layout.metaResourceSegments.append(Range<qint64>::fromStartAndEnd(start, end));
start = end; // // write additional resource (fake)
QInstaller::blockingWrite(&binary, QByteArray("Additional resource data."));
end = binary.pos();
- layout.metaResourceSegments.append(Range<qint64>::fromStartAndEnd(start, end)
- .moved(-layout.endOfBinary));
- layout.metaResourceSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments.first()
- .start(), layout.metaResourceSegments.last().end());
+ layout.metaResourceSegments.append(Range<qint64>::fromStartAndEnd(start, end));
+ layout.metaResourcesSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments
+ .first().start(), layout.metaResourceSegments.last().end());
+ layout.metaSegmentsCount = layout.metaResourceSegments.count();
start = end;
layout.operationsCount = m_operations.count();
@@ -192,8 +180,7 @@ private slots:
}
QInstaller::appendInt64(&binary, layout.operationsCount);
end = binary.pos();
- layout.operationsSegment = Range<qint64>::fromStartAndEnd(start, end).moved(-layout
- .endOfBinary);
+ layout.operationsSegment = Range<qint64>::fromStartAndEnd(start, end);
QTemporaryFile data;
QTemporaryFile data2;
@@ -227,25 +214,30 @@ private slots:
manager.insertCollection(collection2);
layout.collectionCount = manager.collectionCount();
- layout.resourceCollectionIndexSegment = manager.write(&binary, -layout.endOfBinary)
- .moved(-layout.endOfBinary);
+ layout.resourceCollectionsSegment = manager.write(&binary, -layout.endOfExectuable);
resource->close();
resource2->close();
}
- QInstaller::appendInt64Range(&binary, layout.resourceCollectionIndexSegment);
+ QInstaller::appendInt64Range(&binary, layout.resourceCollectionsSegment.moved(-layout
+ .endOfExectuable));
+
foreach (const Range<qint64> &segment, layout.metaResourceSegments)
- QInstaller::appendInt64Range(&binary, segment);
- QInstaller::appendInt64Range(&binary, layout.operationsSegment);
- QInstaller::appendInt64(&binary, layout.metaResourceSegments.count());
+ QInstaller::appendInt64Range(&binary, segment.moved(-layout.endOfExectuable));
- layout.binaryContentSize = (binary.pos() + (3 * sizeof(qint64))) - layout.endOfBinary;
+ QInstaller::appendInt64Range(&binary, layout.operationsSegment.moved(-layout
+ .endOfExectuable));
+
+ QInstaller::appendInt64(&binary, layout.metaSegmentsCount);
+ layout.binaryContentSize = (binary.pos() + (3 * sizeof(qint64))) - layout.endOfExectuable;
QInstaller::appendInt64(&binary, layout.binaryContentSize);
QInstaller::appendInt64(&binary, layout.magicMarker);
QInstaller::appendInt64(&binary, layout.magicCookie);
+ layout.endOfBinaryContent = binary.pos();
+
binary.close();
binary.setAutoRemove(false);
@@ -260,41 +252,48 @@ private slots:
QCOMPARE(QInstaller::retrieveData(binary.data(), scTinySize), QByteArray(scTinySize, '1'));
Layout layout;
- layout.endOfBinary = binary->pos();
- QCOMPARE(layout.endOfBinary, m_layout.endOfBinary);
+ layout.endOfExectuable = binary->pos();
+ QCOMPARE(layout.endOfExectuable, m_layout.endOfExectuable);
const qint64 pos = BinaryContent::findMagicCookie(binary.data(), BinaryContent::MagicCookie);
- const qint64 endOfBinaryContent = pos + sizeof(qint64);
+ layout.endOfBinaryContent = pos + sizeof(qint64);
+ QCOMPARE(layout.endOfBinaryContent, m_layout.endOfBinaryContent);
- binary->seek(endOfBinaryContent - (4 * sizeof(qint64)));
+ binary->seek(layout.endOfBinaryContent - (4 * sizeof(qint64)));
- qint64 metaSegmentsCount = QInstaller::retrieveInt64(binary.data());
- QCOMPARE(metaSegmentsCount, m_layout.metaResourceSegments.count());
+ layout.metaSegmentsCount = QInstaller::retrieveInt64(binary.data());
+ QCOMPARE(layout.metaSegmentsCount, m_layout.metaSegmentsCount);
- const qint64 offsetCollectionIndexSegments = endOfBinaryContent
- - ((metaSegmentsCount * (2 * sizeof(qint64))) // minus the size of the meta segments
+ const qint64 offsetCollectionIndexSegments = layout.endOfBinaryContent
+ - ((layout.metaSegmentsCount * (2 * sizeof(qint64))) // minus size of the meta segments
+ (8 * sizeof(qint64))); // meta count, offset/length component index, marker, cookie...
binary->seek(offsetCollectionIndexSegments);
- layout.resourceCollectionIndexSegment = QInstaller::retrieveInt64Range(binary.data());
- QCOMPARE(layout.resourceCollectionIndexSegment, m_layout.resourceCollectionIndexSegment);
+ layout.resourceCollectionsSegment = QInstaller::retrieveInt64Range(binary.data())
+ .moved(layout.endOfExectuable);
+ QCOMPARE(layout.resourceCollectionsSegment, m_layout.resourceCollectionsSegment);
- for (int i = 0; i < metaSegmentsCount; ++i)
- layout.metaResourceSegments.append(QInstaller::retrieveInt64Range(binary.data()));
- layout.metaResourceSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments
+ for (int i = 0; i < layout.metaSegmentsCount; ++i) {
+ layout.metaResourceSegments.append(QInstaller::retrieveInt64Range(binary.data())
+ .moved(layout.endOfExectuable));
+ }
+ layout.metaResourcesSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments
.first().start(), layout.metaResourceSegments.last().end());
- QCOMPARE(layout.metaResourceSegment, m_layout.metaResourceSegment);
- QCOMPARE(layout.metaResourceSegments, m_layout.metaResourceSegments);
- layout.operationsSegment = QInstaller::retrieveInt64Range(binary.data());
+ QCOMPARE(layout.metaResourcesSegment, m_layout.metaResourcesSegment);
+ QCOMPARE(layout.metaResourceSegments.first(), m_layout.metaResourceSegments.first());
+ QCOMPARE(layout.metaResourceSegments.last(), m_layout.metaResourceSegments.last());
+
+ layout.operationsSegment = QInstaller::retrieveInt64Range(binary.data()).moved(layout
+ .endOfExectuable);
QCOMPARE(layout.operationsSegment, m_layout.operationsSegment);
- QCOMPARE(metaSegmentsCount, QInstaller::retrieveInt64(binary.data()));
+ QCOMPARE(layout.metaSegmentsCount, QInstaller::retrieveInt64(binary.data()));
layout.binaryContentSize = QInstaller::retrieveInt64(binary.data());
QCOMPARE(layout.binaryContentSize, m_layout.binaryContentSize);
- QCOMPARE(layout.endOfBinary, endOfBinaryContent - layout.binaryContentSize);
+ QCOMPARE(layout.endOfExectuable, layout.endOfBinaryContent - layout.binaryContentSize);
layout.magicMarker = QInstaller::retrieveInt64(binary.data());
QCOMPARE(layout.magicMarker, m_layout.magicMarker);
@@ -302,7 +301,7 @@ private slots:
layout.magicCookie = QInstaller::retrieveInt64(binary.data());
QCOMPARE(layout.magicCookie, m_layout.magicCookie);
- binary->seek(layout.endOfBinary + layout.operationsSegment.start());
+ binary->seek(layout.operationsSegment.start());
layout.operationsCount = QInstaller::retrieveInt64(binary.data());
QCOMPARE(layout.operationsCount, m_layout.operationsCount);
@@ -318,8 +317,8 @@ private slots:
layout.collectionCount = QInstaller::retrieveInt64(binary.data());
QCOMPARE(layout.collectionCount, m_layout.collectionCount);
- binary->seek(layout.endOfBinary + layout.resourceCollectionIndexSegment.start());
- m_manager.read(binary, layout.endOfBinary);
+ binary->seek(layout.resourceCollectionsSegment.start());
+ m_manager.read(binary, layout.endOfExectuable);
const QList<ResourceCollection> components = m_manager.collections();
QCOMPARE(components.count(), m_layout.collectionCount);
@@ -357,7 +356,7 @@ private slots:
ResourceCollection resources;
foreach (const Range<qint64> &segment, m_layout.metaResourceSegments) {
resources.appendResource(QSharedPointer<Resource> (new Resource(existingBinary,
- segment.moved(m_layout.endOfBinary))));
+ segment)));
}
QList<OperationBlob> operations;
@@ -388,10 +387,8 @@ private slots:
QCOMPARE(magicMarker, m_layout.magicMarker);
QCOMPARE(collection.resources().count(), m_layout.metaResourceSegments.count());
- for (int i = 0; i < collection.resources().count(); ++i) {
- QCOMPARE(collection.resources().at(i)->segment(), m_layout.metaResourceSegments.at(i)
- .moved(m_layout.endOfBinary));
- }
+ for (int i = 0; i < collection.resources().count(); ++i)
+ QCOMPARE(collection.resources().at(i)->segment(), m_layout.metaResourceSegments.at(i));
QCOMPARE(operations.count(), m_operations.count());
for (int i = 0; i < operations.count(); ++i) {
diff --git a/tools/devtool/binaryreplace.cpp b/tools/devtool/binaryreplace.cpp
index a7213ecfe..4bd76178d 100644
--- a/tools/devtool/binaryreplace.cpp
+++ b/tools/devtool/binaryreplace.cpp
@@ -41,6 +41,7 @@
#include "binaryreplace.h"
+#include <binarycontent.h>
#include <copyfiletask.h>
#include <downloadfiletask.h>
#include <errors.h>
@@ -115,7 +116,7 @@ int BinaryReplace::replace(const QString &source, const QString &target)
installerBaseNew.seek(installerBaseNew.size());
if (m_binaryLayout.magicMarker == QInstaller::BinaryContent::MagicInstallerMarker) {
QInstaller::openForRead(&installerBaseOld);
- installerBaseOld.seek(m_binaryLayout.metadataResourceSegments.first().start());
+ installerBaseOld.seek(m_binaryLayout.metaResourcesSegment.start());
QInstaller::appendData(&installerBaseNew, &installerBaseOld, installerBaseOld
.size() - installerBaseOld.pos());
installerBaseOld.close();
diff --git a/tools/devtool/binaryreplace.h b/tools/devtool/binaryreplace.h
index 52f90c209..8d123356e 100644
--- a/tools/devtool/binaryreplace.h
+++ b/tools/devtool/binaryreplace.h
@@ -42,7 +42,7 @@
#ifndef BINARYREPLACE_H
#define BINARYREPLACE_H
-#include <binarycontent.h>
+#include <binarylayout.h>
class BinaryReplace
{
diff --git a/tools/devtool/main.cpp b/tools/devtool/main.cpp
index 0a9c677d2..005aadd61 100644
--- a/tools/devtool/main.cpp
+++ b/tools/devtool/main.cpp
@@ -101,80 +101,58 @@ int main(int argc, char *argv[])
int result = EXIT_FAILURE;
QVector<QByteArray> resourceMappings;
+ quint64 cookie = QInstaller::BinaryContent::MagicCookie;
try {
- QFile *file = new QFile(path);
- QInstaller::openForRead(file);
-
- QInstaller::BinaryLayout layout = QInstaller::BinaryContent::binaryLayout(file,
- QInstaller::BinaryContent::MagicCookie);
-
- if (layout.magicMarker == QInstaller::BinaryContent::MagicUninstallerMarker) {
- QFileInfo fi(path);
- if (QInstaller::isInBundle(fi.absoluteFilePath(), &bundlePath))
- fi.setFile(bundlePath);
- path = fi.absolutePath() + QLatin1Char('/') + fi.baseName() + QLatin1String(".dat");
-
- file->setFileName(path);
- layout = QInstaller::BinaryContent::binaryLayout(file,
- QInstaller::BinaryContent::MagicCookie);
+ {
+ QFile tmp(path);
+ QInstaller::openForRead(&tmp);
+
+ QInstaller::BinaryLayout layout = QInstaller::BinaryContent::binaryLayout(&tmp,
+ cookie);
+
+ if (layout.magicMarker == QInstaller::BinaryContent::MagicUninstallerMarker) {
+ QFileInfo fi(path);
+ if (QInstaller::isInBundle(fi.absoluteFilePath(), &bundlePath))
+ fi.setFile(bundlePath);
+ path = fi.absolutePath() + QLatin1Char('/') + fi.baseName() + QLatin1String(".dat");
+
+ tmp.setFileName(path);
+ cookie = QInstaller::BinaryContent::MagicCookieDat;
+ layout = QInstaller::BinaryContent::binaryLayout(&tmp, cookie);
+ }
+ tmp.close();
+
+ if (parser.isSet(update)) {
+ // To update the binary we do not need any mapping.
+ BinaryReplace br(layout);
+ return br.replace(parser.value(update), path);
+ }
}
- if (parser.isSet(update)) {
- // To update the binary we do not need any mapping.
- BinaryReplace br(layout);
- return br.replace(parser.value(update), path);
- }
+ QSharedPointer<QFile> file(new QFile(path));
+ QInstaller::openForRead(file.data());
+
+ qint64 magicMarker;
+ QInstaller::ResourceCollection meta;
+ QList<QInstaller::OperationBlob> operations;
+ QInstaller::ResourceCollectionManager manager;
+ QInstaller::BinaryContent::readBinaryContent(file, &meta, &operations, &manager,
+ &magicMarker, cookie);
// map the inbuilt resources
- foreach (const Range<qint64> &segment, layout.metadataResourceSegments) {
- if (segment.length() <= 0)
- continue;
- if (!file->seek(segment.start()))
- throw QInstaller::Error(QLatin1String("Could not seek to segment position."));
- const QByteArray ba = QInstaller::retrieveData(file, segment.length());
+ foreach (const QSharedPointer<QInstaller::Resource> &resource, meta.resources()) {
+ const bool opened = resource->open();
+ const QByteArray ba = resource->readAll();
if (!QResource::registerResource((const uchar*) ba.data(), QLatin1String(":/metadata")))
throw QInstaller::Error(QLatin1String("Could not register in-binary resource."));
resourceMappings.append(ba);
+ if (opened)
+ resource->close();
}
- // instantiate the operations we support
- const qint64 dataBlockStart = layout.endOfData - layout.dataBlockSize;
- const qint64 operationsStart = layout.operationsStart + dataBlockStart;
- if (!file->seek(operationsStart))
- throw QInstaller::Error(QLatin1String("Could not seek to operation list."));
-
- QList<QInstaller::OperationBlob> performedOperations;
- const qint64 operationsCount = QInstaller::retrieveInt64(file);
- for (int i = 0; i < operationsCount; ++i) {
- const QString name = QInstaller::retrieveString(file);
- const QString data = QInstaller::retrieveString(file);
- performedOperations.append(QInstaller::OperationBlob(name, data));
- }
-
- // seek to the position of the resource collections segment info
- const qint64 resourceOffsetAndLengtSize = 2 * sizeof(qint64);
- const qint64 resourceSectionSize = resourceOffsetAndLengtSize * layout.resourceCount;
- qint64 offset = layout.endOfData - layout.indexSize - resourceSectionSize
- - resourceOffsetAndLengtSize;
- if (!file->seek(offset)) {
- throw QInstaller::Error(QLatin1String("Could not seek to read the resource collection "
- "segment info."));
- }
-
- offset = QInstaller::retrieveInt64(file) + dataBlockStart;
- if (!file->seek(offset)) {
- throw QInstaller::Error(QLatin1String("Could not seek to start position of resource "
- "collection block."));
- }
-
- // setup the collection manager
- QSharedPointer<QFile> data(file);
- QInstaller::ResourceCollectionManager manager;
- manager.read(data, dataBlockStart);
-
if (parser.isSet(dump)) {
// To dump the content we do not need the binary format engine.
- if (layout.magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
+ if (magicMarker != QInstaller::BinaryContent::MagicInstallerMarker)
throw QInstaller::Error(QLatin1String("Source file is not an installer."));
BinaryDump bd;
return bd.dump(manager, parser.value(dump));
@@ -184,7 +162,7 @@ int main(int argc, char *argv[])
.collections()); // setup the binary format engine
if (parser.isSet(run)) {
- OperationRunner runner(layout.magicMarker, performedOperations);
+ OperationRunner runner(magicMarker, operations);
const QStringList arguments = parser.values(run);
if (arguments.first() == QLatin1String("DO"))
result = runner.runOperation(arguments.mid(1), OperationRunner::RunMode::Do);