1

I am building a qt framework to download and install application updates (like sparkle for obj-c). The download works, the downloaded zip file is valid and i can extract the contents manually but when I let my framework unzip the contents via quazip the files (dll and exe) contains this and only this string: "MZ" and a special char which is wrong encoded (some kind of square on windows and "ê" on mac), so exactly 3 bytes. When I include a text file (or xml) in the zip file, it will be unzipped correctly, manually and with quazip, so I assume that the library was compiled correctly. Where is my error?

I think this can be part of the solution http://en.wikipedia.org/wiki/DOS_MZ_executable?

Here is my method to install the update:

QuaZip archiveWrapper(filename); // The downloaded zip file

if (archiveWrapper.open(QuaZip::mdUnzip)) {
    QuaZipFile archive(&archiveWrapper);

    qDebug() << "Extracting files" << archiveWrapper.getFileNameList();

    for (bool more = archiveWrapper.goToFirstFile(); more; more = archiveWrapper.goToNextFile()) {
        QString filePath = archiveWrapper.getCurrentFileName();
        QString destinationPath = QDir::cleanPath(QDir::currentPath() + QDir::separator() + filePath);
        QString destinationBackup = destinationPath + "_backup";

        qDebug() << "Extract" << filePath << "to" << destinationPath;

        QuaZipFile zip(archive.getZipName(), filePath);
        zip.open(QIODevice::ReadOnly);
        QByteArray data = zip.readAll();
        zip.close();

        QFile oldFile(destinationPath);
        if (oldFile.exists()) {
            qDebug() << "Rename" << destinationPath << "to" << destinationBackup;

            if (!oldFile.rename(destinationBackup)) {
                qWarning("Could not rename %s to %s!", destinationPath.toUtf8().constData(), destinationBackup.toUtf8().constData());
            }
        }

        QFile destination(destinationPath);
        destination.open(QIODevice::WriteOnly);
        destination.write(data.data());
        destination.close();

        if (oldFile.exists()) {
            qDebug() << "Deleting backup of" << destinationPath;

            if (!oldFile.remove()) {
                qWarning("Could not delete %s!", destinationPath.toUtf8().constData());
            }
        }
    }

    if (archive.getZipError() == UNZ_OK) {
        qDebug() << "All files extracted successfully";
        qDebug() << "Restarting application...";

        archiveWrapper.close();

        qApp->quit();
        QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
    } else {
        qWarning("Error while extracting files (Error %d)", archive.getZipError());
        archiveWrapper.close();
    }
} else {
    qWarning("Could not open archive to extract contents");
}

Edit:

I found out that data (QByteArray) has the expected size, so I think the problem is that QFile does not write the contents of QByteArray into the exe/dll files the way it should be?

Edit 2:

I've found one error, the file size to write:

destination.write(data.data(), data.size());

instead of

destination.write(data.data());

but still, the exe does not have an icon or is executable (but with the correct file size). For a short time a dos window opens and closes. There is a antivirus software running but there is no alert (and because this is a corporate notebook i am not able to shut it down and the update framework should also be running whether there is a antivirus software running or not).

Edit 3:

Although I thought writing exe files is complicated, it was a mixture of stupid bugs I "implemented" for testing purposes. So the simple

QFile destination(destinationPath);
destination.open(QIODevice::WriteOnly);
destination.write(data.data(), data.size())

is sufficient.

Tim
  • 929
  • 1
  • 14
  • 28
  • Are you sure you don't have an AntiVirus that might interfere with your program ? Writing into EXE and DLL files could be considered a suspicious activity by some security software, especially if your QT based executable is not signed. – SirDarius Apr 04 '14 at 09:17
  • Then I can recommend you to diff the original file with the extracted one using a tool like http://www.cjmweb.net/vbindiff/ to see what really makes it invalid. – SirDarius Apr 04 '14 at 10:09
  • Had the same idea a few minutes ago and used a tool named PE explorer http://www.heaventools.de/overview.htm. I am using mac and linux so windows is pretty new for me;) The file sizes differ (original: 730624 bytes, extracted: 731360 bytes) and the tool says that the extracted file is not a valid exe file. – Tim Apr 04 '14 at 10:14
  • Tried your tool vbindiff: 3 bytes were added before the MZ header and the other differences also were bytes added to the original exe, where do they come from? I also tried to use a QDataStream and the writeRawData method but there is no difference. – Tim Apr 04 '14 at 10:26
  • This could happen if using the QIODevice::Text open mode, where 0A characters would be converted into 0D 0A pairs, but I see it is not the case in your code, see http://qt-project.org/doc/qt-5/qiodevice.html#OpenModeFlag-enum – SirDarius Apr 04 '14 at 10:28
  • And I used the Text mode for testing purposes...:D That was the final solution, thank you! – Tim Apr 04 '14 at 10:32
  • Glad to have helped :) This demonstrates how code pasted in questions should be exactly the same as the one that has a problem ;) – SirDarius Apr 04 '14 at 10:55
  • The code was the same...but experimented with it. I don't want that you do all the work for me:P – Tim Apr 04 '14 at 14:56

0 Answers0