File indexing completed on 2024-04-28 04:58:03

0001 /*
0002     icoutils_wrestool.cpp - Extract Microsoft Window icons and images using icoutils package
0003 
0004     SPDX-FileCopyrightText: 2009-2010 Pali Rohár <pali.rohar@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "icoutils.h"
0010 
0011 #include <QProcess>
0012 #include <QRegularExpression>
0013 #include <QString>
0014 
0015 bool IcoUtils::loadIcoImageFromExe(const QString &inputFileName, QIODevice *outputDevice)
0016 {
0017     QProcess wrestool;
0018 
0019     // list all resources with type RT_GROUP_ICON=14
0020     wrestool.start(QStringLiteral("wrestool"), {QStringLiteral("-t14"), QStringLiteral("-l"), inputFileName});
0021     wrestool.waitForFinished();
0022 
0023     if (wrestool.exitCode() != 0) {
0024         return false;
0025     }
0026 
0027     const QString output = QString::fromUtf8(wrestool.readAll());
0028 
0029     // 16 bit binaries don't have "--language"
0030     const QRegularExpression regExp(QStringLiteral("--type=\\d+ --name=(\\S+) (?:--language=.* )?\\[.*\\]"));
0031 
0032     // https://docs.microsoft.com/en-us/windows/win32/menurc/about-icons#icon-display
0033     // "Select the RT_GROUP_ICON resource. If more than one such resource exists,
0034     // the system uses the first resource listed in the resource scrip."
0035     auto match = regExp.match(output);
0036     if (!match.hasMatch()) {
0037         return false;
0038     }
0039 
0040     QString name = match.captured(1);
0041     if (name.at(0) == '\'') {
0042         name = name.mid(1, name.size() - 2);
0043     }
0044 
0045     wrestool.start(QStringLiteral("wrestool"), {QStringLiteral("-x"), QStringLiteral("-t14"), QStringLiteral("-n"), name, inputFileName});
0046     wrestool.waitForFinished();
0047 
0048     if (wrestool.exitCode() != 0) {
0049         return false;
0050     }
0051 
0052     const QByteArray iconData = wrestool.readAllStandardOutput();
0053     if (outputDevice->write(iconData) != iconData.size()) {
0054         return false;
0055     }
0056 
0057     return true;
0058 }