116 lines
4.0 KiB
C++
116 lines
4.0 KiB
C++
#include <QApplication>
|
|
#include <QDebug>
|
|
#include <QDir>
|
|
#include <QFileInfo>
|
|
#include <QMessageBox>
|
|
#include <QSaveFile>
|
|
#include <QTranslator>
|
|
|
|
#include "MainWindow.h"
|
|
#include "../Common/ConfigHelper.h"
|
|
#include "../Common/IntegrityHelper.h"
|
|
#include "../Common/TicketHelper.h"
|
|
|
|
namespace {
|
|
|
|
QString configValue(const QString& key, const QString& fallback = QString())
|
|
{
|
|
const QString value = ConfigHelper::instance().getValue(QString(), key).trimmed();
|
|
return value.isEmpty() ? fallback : value;
|
|
}
|
|
|
|
QString productCode()
|
|
{
|
|
return configValue(QStringLiteral("product_code"),
|
|
configValue(QStringLiteral("app_id")));
|
|
}
|
|
|
|
bool configFlag(const QString& key)
|
|
{
|
|
const QString value = configValue(key).toLower();
|
|
return value == QStringLiteral("true")
|
|
|| value == QStringLiteral("1")
|
|
|| value == QStringLiteral("yes")
|
|
|| value == QStringLiteral("on");
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
QApplication a(argc, argv);
|
|
QTranslator translator;
|
|
if (translator.load(QStringLiteral(":/i18n/update-client_zh_CN.qm")))
|
|
a.installTranslator(&translator);
|
|
|
|
const int elevatedWriteExitCode = ConfigHelper::runElevatedWriteCommandIfRequested();
|
|
if (elevatedWriteExitCode >= 0)
|
|
return elevatedWriteExitCode;
|
|
|
|
qDebug() << Qt::endl << "entered main app" << Qt::endl;
|
|
|
|
ConfigHelper& config = ConfigHelper::instance();
|
|
QString launcherExecutable = config.getValue(QStringLiteral("Runtime"), QStringLiteral("launcher_executable")).trimmed();
|
|
launcherExecutable = ConfigHelper::executableNameForCurrentPlatform(launcherExecutable, QStringLiteral("Launcher"));
|
|
|
|
QString ticketFilePath;
|
|
QString healthFilePath;
|
|
for (int i = 1; i < argc; ++i)
|
|
{
|
|
const QString arg(argv[i]);
|
|
if (arg.startsWith(QStringLiteral("--ticket-file=")))
|
|
ticketFilePath = arg.mid(QStringLiteral("--ticket-file=").size());
|
|
else if (arg.startsWith(QStringLiteral("--health-file=")))
|
|
healthFilePath = arg.mid(QStringLiteral("--health-file=").size());
|
|
}
|
|
|
|
QString ticketError;
|
|
if (ticketFilePath.isEmpty()
|
|
|| !TicketHelper::consumeAndVerify(ticketFilePath,
|
|
productCode(), config.getValue(QStringLiteral("Update"), QStringLiteral("device_id")),
|
|
config.getValue(QStringLiteral("App"), QStringLiteral("current_version")),
|
|
config.getValue(QStringLiteral("App"), QStringLiteral("launch_token")),
|
|
&ticketError))
|
|
{
|
|
QMessageBox::critical(nullptr, "Startup Restriction",
|
|
QString("Invalid or missing one-time launch ticket: %1\nPlease use %2.")
|
|
.arg(ticketError, launcherExecutable));
|
|
return -1;
|
|
}
|
|
|
|
const QString installRoot = config.installRoot();
|
|
if (configFlag(QStringLiteral("verify_installed_on_start"))) {
|
|
IntegrityHelper integrity(installRoot);
|
|
if (!integrity.verifyInstalledVersion(
|
|
productCode(),
|
|
config.getValue(QStringLiteral("App"), QStringLiteral("channel")),
|
|
config.getValue(QStringLiteral("App"), QStringLiteral("current_version"))))
|
|
{
|
|
QMessageBox::critical(nullptr, "Integrity Check Failed",
|
|
QString("Startup blocked because the installed files failed local Manifest verification.\n\nDetails:\n%1")
|
|
.arg(integrity.errorString()));
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (!healthFilePath.isEmpty())
|
|
{
|
|
QDir().mkpath(QFileInfo(healthFilePath).path());
|
|
QSaveFile healthFile(healthFilePath);
|
|
const QByteArray healthy("ok\n");
|
|
if (!healthFile.open(QIODevice::WriteOnly)
|
|
|| healthFile.write(healthy) != healthy.size()
|
|
|| !healthFile.commit())
|
|
{
|
|
QMessageBox::critical(nullptr, "Startup Error", "Cannot write update health confirmation file.");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
MainWindow w;
|
|
w.show();
|
|
|
|
qDebug() << "Main program MainApp is running normally";
|
|
return a.exec();
|
|
}
|