summaryrefslogtreecommitdiffstats
path: root/tools/extractbinarydata
diff options
context:
space:
mode:
authorkh1 <karsten.heimrich@nokia.com>2011-08-22 10:05:16 +0200
committerTim Jenssen <tim.jenssen@nokia.com>2011-08-22 10:53:02 +0200
commita3642c09c9d856ee1eecebefdceaa3e6d272e059 (patch)
tree9ac8952891c7edea0aebed8e8c47a9fe72afa260 /tools/extractbinarydata
parent334b5e6c977fd33d479fbaa5983ed87bcf692170 (diff)
Tool to extract binary data + resources.
Pass the old maintenance and a new installerbase to the app to be able to update an existing installation without actual maintenance tool update from server. Renames the old maintenance to file.org. Change-Id: I11ab12e861d65b3bfc8f9adb08f3b6da1faf2dff Reviewed-on: http://codereview.qt.nokia.com/3272 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Tim Jenssen <tim.jenssen@nokia.com>
Diffstat (limited to 'tools/extractbinarydata')
-rw-r--r--tools/extractbinarydata/extractbinarydata.pro17
-rw-r--r--tools/extractbinarydata/main.cpp189
2 files changed, 206 insertions, 0 deletions
diff --git a/tools/extractbinarydata/extractbinarydata.pro b/tools/extractbinarydata/extractbinarydata.pro
new file mode 100644
index 000000000..fe30f20b2
--- /dev/null
+++ b/tools/extractbinarydata/extractbinarydata.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+DEPENDPATH += . .. ../../installerbuilder/common
+INCLUDEPATH += . ..
+
+DESTDIR = ../../installerbuilder/bin
+
+CONFIG += console
+CONFIG -= app_bundle
+
+include(../../installerbuilder/libinstaller/libinstaller.pri)
+
+# Input
+SOURCES += main.cpp
+
+HEADERS +=
+
+LIBS = -L../../installerbuilder/lib -linstaller $$LIBS
diff --git a/tools/extractbinarydata/main.cpp b/tools/extractbinarydata/main.cpp
new file mode 100644
index 000000000..4b25d3354
--- /dev/null
+++ b/tools/extractbinarydata/main.cpp
@@ -0,0 +1,189 @@
+/**************************************************************************
+**
+** This file is part of Qt SDK**
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).*
+**
+** Contact: Nokia Corporation qt-info@nokia.com**
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception version
+** 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you are unsure which license is appropriate for your use, please contact
+** (qt-info@nokia.com).
+**
+**************************************************************************/
+#include <common/binaryformat.h>
+#include <common/errors.h>
+#include <common/fileutils.h>
+#include <common/utils.h>
+
+#include <init.h>
+
+#include <KDToolsCore/KDSaveFile>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QStringList>
+
+#include <iostream>
+
+using namespace QInstaller;
+using namespace QInstallerCreator;
+
+void writeMaintenanceBinary(const QString &maintenanceTool, QFile *const input, qint64 size)
+{
+ KDSaveFile out(maintenanceTool + QLatin1String(".new"));
+ openForWrite(&out, out.fileName()); // throws an exception in case of error
+
+ if (!input->seek(0)) {
+ throw Error(QObject::tr("Failed to seek in file %1. Reason: %2.").arg(input->fileName(),
+ input->errorString()));
+ }
+
+ appendData(&out, input, size);
+ appendInt64(&out, 0); // resource count
+ appendInt64(&out, 4 * sizeof(qint64)); // data block size
+ appendInt64(&out, QInstaller::MagicUninstallerMarker);
+ appendInt64(&out, QInstaller::MagicCookie);
+
+ out.setPermissions(out.permissions() | QFile::WriteUser | QFile::ReadGroup | QFile::ReadOther
+ | QFile::ExeOther | QFile::ExeGroup | QFile::ExeUser);
+
+ if (!out.commit(KDSaveFile::OverwriteExistingFile)) {
+ throw Error(QString::fromLatin1("Could not write new maintenance-tool to %1. Reason: %2.").arg(out
+ .fileName(), out.errorString()));
+ }
+}
+
+void writeBinaryDataFile(QIODevice *output, QFile *const input, const OperationList &performedOperations,
+ const BinaryLayout &layout)
+{
+ const qint64 dataBlockStart = output->pos();
+
+ QVector<Range<qint64> >resourceSegments;
+ foreach (const Range<qint64> &segment, layout.metadataResourceSegments) {
+ input->seek(segment.start());
+ resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), segment.length()));
+ appendData(output, input, segment.length());
+ }
+
+ const qint64 operationsStart = output->pos();
+ appendInt64(output, performedOperations.count());
+ foreach (Operation *operation, performedOperations) {
+ // the installer can't be put into XML, remove it first
+ operation->clearValue(QLatin1String("installer"));
+
+ appendString(output, operation->name());
+ appendString(output, operation->toXml().toString());
+
+ // for the ui not to get blocked
+ qApp->processEvents();
+ }
+ appendInt64(output, performedOperations.count());
+ const qint64 operationsEnd = output->pos();
+
+ // we don't save any component-indexes.
+ const qint64 numComponents = 0;
+ appendInt64(output, numComponents); // for the indexes
+ // we don't save any components.
+ const qint64 compIndexStart = output->pos();
+ appendInt64(output, numComponents); // and 2 times number of components,
+ appendInt64(output, numComponents); // one before and one after the components
+ const qint64 compIndexEnd = output->pos();
+
+ appendInt64Range(output, Range<qint64>::fromStartAndEnd(compIndexStart, compIndexEnd)
+ .moved(-dataBlockStart));
+ foreach (const Range<qint64> segment, resourceSegments)
+ appendInt64Range(output, segment.moved(-dataBlockStart));
+ appendInt64Range(output, Range<qint64>::fromStartAndEnd(operationsStart, operationsEnd)
+ .moved(-dataBlockStart));
+ appendInt64(output, layout.resourceCount);
+ //data block size, from end of .exe to end of file
+ appendInt64(output, output->pos() + 3 * sizeof(qint64) - dataBlockStart);
+ appendInt64(output, MagicUninstallerMarker);
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QStringList arguments = app.arguments();
+ if (arguments.count() < 3) {
+ std::cout << "Usage: extractbinarydata [--verbose] maintenance-tool installer-base" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ {
+ QInstaller::init();
+ QInstaller::setVerbose(arguments.contains(QLatin1String("--verbose")));
+ arguments.removeAll(QLatin1String("--verbose"));
+
+ try {
+ // write out the new maintenance tool
+ QFile installerBase(arguments.at(2));
+ openForRead(&installerBase, installerBase.fileName());
+ writeMaintenanceBinary(arguments.at(1), &installerBase, installerBase.size());
+ } catch (const Error &error) {
+ verbose() << error.message() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ BinaryLayout layout;
+ QFile input(arguments.at(1));
+ try {
+ openForRead(&input, input.fileName());
+ layout = BinaryContent::readBinaryLayout(&input, findMagicCookie(&input, MagicCookie));
+ } catch (const Error &error) {
+ verbose() << error.message() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (layout.magicMarker != MagicUninstallerMarker) {
+ std::cout << "Extracting binary data only supported for maintenance tools." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ try {
+ KDSaveFile file(QFileInfo(arguments.at(1)).absolutePath() + QDir::separator()
+ + QFileInfo(arguments.at(1)).baseName() + QLatin1String(".dat"));
+ openForWrite(&file, file.fileName());
+ BinaryContent content = BinaryContent::readFromBinary(arguments.at(1));
+ writeBinaryDataFile(&file, &input, content.performedOperations(), layout);
+ appendInt64(&file, MagicCookieDat);
+ file.setPermissions(file.permissions() | QFile::WriteUser | QFile::ReadGroup
+ | QFile::ReadOther);
+ if (!file.commit(KDSaveFile::OverwriteExistingFile)) {
+ throw Error(QString::fromLatin1("Couldn't write binary data to %1. Reason: %2").arg(file
+ .fileName(), file.errorString()));
+ }
+ file.close();
+ input.close();
+ } catch (const Error &error) {
+ verbose() << error.message() << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ QFile::rename(arguments.at(1), arguments.at(1) + QLatin1String(".org"));
+ QFile::rename(arguments.at(1) + QLatin1String(".new"), arguments.at(1));
+
+ return EXIT_SUCCESS;
+}