#include #include #include #include #include #include #include "MainWindow.h" #include "../Common/ConfigHelper.h" #include "../Common/PolicyHelper.h" #include "../Common/LocalStateHelper.h" #include "../Common/TicketHelper.h" #include "../Common/IntegrityHelper.h" #include "../Common/DeviceIdentityHelper.h" #include "../Common/TranslationHelper.h" int main(int argc, char* argv[]) { QApplication a(argc, argv); QApplication::setApplicationName("Marsco MainApp"); TranslationHelper translation; translation.installForSystemLocale(); qDebug() << Qt::endl << "entered main app" << Qt::endl; ConfigHelper& config = ConfigHelper::instance(); QString launcherExecutable = config.getValue("Runtime", "launcher_executable").trimmed(); if (launcherExecutable.isEmpty()) launcherExecutable = "Launcher.exe"; QString ticketFilePath; QString healthFilePath; for (int i = 1; i < argc; ++i) { const QString arg(argv[i]); if (arg.startsWith("--ticket-file=")) ticketFilePath = arg.mid(QString("--ticket-file=").size()); else if (arg.startsWith("--health-file=")) healthFilePath = arg.mid(QString("--health-file=").size()); } QString ticketError; if (ticketFilePath.isEmpty() || !TicketHelper::consumeAndVerify(ticketFilePath, config.getValue("App", "app_id"), config.getValue("Update", "device_id"), config.getValue("App", "current_version"), config.getValue("App", "launch_token"), &ticketError)) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "Startup Restriction"), QCoreApplication::translate("MainApp", "Invalid or missing one-time launch ticket: %1\nPlease use %2.") .arg(ticketError, launcherExecutable)); return -1; } QString appDir = QApplication::applicationDirPath(); const QString installRoot = config.installRoot(); DeviceIdentityHelper identity(appDir); if (!identity.verifyLocal(config.getValue("App", "app_id"), config.getValue("App", "channel"))) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "License Error"), QCoreApplication::translate("MainApp", "Local license invalid: %1").arg(identity.errorString())); return -1; } PolicyHelper policy(appDir); if (!policy.loadPolicy("config/version_policy.dat") || !policy.isValid()) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "Policy Error"), QCoreApplication::translate("MainApp", "Local policy invalid: %1").arg(policy.errorString())); return -1; } if (policy.isExpired()) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "Policy Error"), QCoreApplication::translate("MainApp", "Policy expired. The application cannot start.")); return -1; } const QString currentVersion = config.getValue("App", "current_version"); if (!policy.isApplicable(config.getValue("App", "app_id"), config.getValue("App", "channel"), currentVersion) || !policy.allowRun() || !policy.isVersionAllowed(currentVersion)) { QMessageBox::critical( nullptr, QCoreApplication::translate("MainApp", "Policy Error"), QCoreApplication::translate( "MainApp", "The signed policy does not allow this installed version to run.")); return -1; } LocalStateHelper state(appDir); if (!state.loadState()) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "State Error"), QCoreApplication::translate("MainApp", "Cannot load local state: %1").arg(state.errorString())); return -1; } if (state.isPolicySeqRolledBack(policy.policySeq())) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "Policy Error"), QCoreApplication::translate("MainApp", "A policy sequence rollback was detected, so startup was blocked.")); return -1; } if (state.isSystemTimeRewound()) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "Policy Error"), QCoreApplication::translate("MainApp", "The system clock appears to have moved backward, so startup was blocked.")); return -1; } IntegrityHelper integrity(installRoot); if (!integrity.verifyInstalledVersion( config.getValue("App", "app_id"), config.getValue("App", "channel"), currentVersion)) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "Integrity Check Failed"), QCoreApplication::translate("MainApp", "Application files failed signed manifest verification:\n%1") .arg(integrity.errorString())); return -1; } MainWindow w; w.show(); state.updateAfterSuccessfulRun(ConfigHelper::instance().getValue("App", "current_version"), policy.policySeq()); if (!state.saveState()) { QMessageBox::critical(nullptr, QCoreApplication::translate("MainApp", "State Error"), QCoreApplication::translate("MainApp", "Cannot save local state: %1").arg(state.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, QCoreApplication::translate("MainApp", "Startup Error"), QCoreApplication::translate("MainApp", "Cannot write the update health confirmation file.")); return -1; } } qDebug() << "Main program MainApp is running normally"; return a.exec(); }