1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
3 // Copyright (C) 2004-2016 LoRd_MuldeR <MuldeR2@GMX.de>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
22 #include "thread_binaries.h"
27 #include <QMutexLocker>
28 #include <QApplication>
34 #include "model_sysinfo.h"
35 #include "win_updater.h"
36 #include "encoder_factory.h"
37 #include "source_factory.h"
40 #include <MUtils/Global.h>
41 #include <MUtils/OSSupport.h>
44 QMutex BinariesCheckThread::m_binLock;
45 QScopedPointer<QFile> BinariesCheckThread::m_binPath[MAX_BINARIES];
48 #define NEXT(X) ((*reinterpret_cast<int*>(&(X)))++)
49 #define SHFL(X) ((*reinterpret_cast<int*>(&(X))) <<= 1)
52 QString AVS_CHECK_BINARY(const SysinfoModel *sysinfo, const bool& x64);
54 //-------------------------------------
56 //-------------------------------------
58 bool BinariesCheckThread::check(SysinfoModel *sysinfo)
60 QMutexLocker lock(&m_binLock);
63 BinariesCheckThread thread(sysinfo);
65 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
67 connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
68 connect(&thread, SIGNAL(terminated()), &loop, SLOT(quit()));
71 QTimer::singleShot(30000, &loop, SLOT(quit()));
73 qDebug("Binaries checker thread has been created, please wait...");
74 loop.exec(QEventLoop::ExcludeUserInputEvents);
75 qDebug("Binaries checker thread finished.");
77 QApplication::restoreOverrideCursor();
79 if(!thread.wait(1000))
81 qWarning("Binaries checker thread encountered timeout -> probably deadlock!");
87 if(thread.getException())
89 qWarning("Binaries checker thread encountered an exception !!!");
93 return thread.getSuccess();
96 //-------------------------------------
98 //-------------------------------------
100 BinariesCheckThread::BinariesCheckThread(const SysinfoModel *const sysinfo)
104 m_success = m_exception = false;
107 BinariesCheckThread::~BinariesCheckThread(void)
111 void BinariesCheckThread::run(void)
113 m_success = m_exception = false;
114 checkBinaries1(m_success, m_sysinfo, &m_exception);
117 void BinariesCheckThread::checkBinaries1(volatile bool &success, const SysinfoModel *const sysinfo, volatile bool *exception)
121 checkBinaries2(success, sysinfo, exception);
126 qWarning("Unhandled exception error in binaries checker thread !!!");
130 void BinariesCheckThread::checkBinaries2(volatile bool &success, const SysinfoModel *const sysinfo, volatile bool *exception)
134 return checkBinaries3(success, sysinfo);
139 qWarning("Binaries checker initializdation raised an C++ exception!");
143 void BinariesCheckThread::checkBinaries3(volatile bool &success, const SysinfoModel *const sysinfo)
147 //Create list of all required binary files
148 typedef QPair<QString, bool> FileEntry;
149 QList<FileEntry> binFiles;
150 for(OptionsModel::EncType encdr = OptionsModel::EncType_MIN; encdr <= OptionsModel::EncType_MAX; NEXT(encdr))
152 const AbstractEncoderInfo &encInfo = EncoderFactory::getEncoderInfo(encdr);
153 const QFlags<OptionsModel::EncVariant> variants = encInfo.getVariants();
154 for(OptionsModel::EncArch arch = OptionsModel::EncArch_x86_32; arch <= OptionsModel::EncArch_x86_64; NEXT(arch))
156 for(OptionsModel::EncVariant varnt = OptionsModel::EncVariant_MIN; varnt <= OptionsModel::EncVariant_MAX; SHFL(varnt))
158 if(variants.testFlag(varnt))
160 binFiles << qMakePair(encInfo.getBinaryPath(sysinfo, arch, varnt), false);
161 const QStringList dependencies = encInfo.getDependencies(sysinfo, arch, varnt);
162 if (!dependencies.empty())
164 for (QStringList::ConstIterator iter = dependencies.constBegin(); iter != dependencies.constEnd(); iter++)
166 binFiles << qMakePair(*iter, true);
173 for(int i = 0; i < 2; i++)
175 binFiles << qMakePair(SourceFactory::getSourceInfo(SourceFactory::SourceType_AVS).getBinaryPath(sysinfo, bool(i)), false);
176 binFiles << qMakePair(AVS_CHECK_BINARY(sysinfo, bool(i)), false);
178 for(size_t i = 0; UpdaterDialog::BINARIES[i].name; i++)
180 if(UpdaterDialog::BINARIES[i].exec)
182 binFiles << qMakePair(QString("%1/toolset/common/%2").arg(sysinfo->getAppPath(), QString::fromLatin1(UpdaterDialog::BINARIES[i].name)), false);
186 //Actually validate the binaries
187 size_t currentFile = 0;
188 for(QList<FileEntry>::ConstIterator iter = binFiles.constBegin(); iter != binFiles.constEnd(); iter++)
190 QScopedPointer<QFile> file(new QFile(iter->first));
191 qDebug("%s", MUTILS_UTF8(file->fileName()));
193 if(file->open(QIODevice::ReadOnly))
195 if(!(iter->second || MUtils::OS::is_executable_file(file->fileName())))
198 qWarning("Required tool does NOT look like a valid Win32/Win64 binary:\n%s\n", MUTILS_UTF8(file->fileName()));
201 if(currentFile < MAX_BINARIES)
203 m_binPath[currentFile++].reset(file.take());
206 qFatal("Current binary file exceeds max. number of binaries!");
211 qWarning("Required tool could not be found or access denied:\n%s\n", MUTILS_UTF8(file->fileName()));