diff --git a/src/duckstation-qt/autoupdaterwindow.cpp b/src/duckstation-qt/autoupdaterwindow.cpp index 0d71fced5..357e60cac 100644 --- a/src/duckstation-qt/autoupdaterwindow.cpp +++ b/src/duckstation-qt/autoupdaterwindow.cpp @@ -679,6 +679,13 @@ bool AutoUpdaterWindow::processUpdate(const std::vector& update_data) const std::string update_zip_path = Path::Combine(EmuFolders::DataRoot, UPDATER_ARCHIVE_NAME); const std::string updater_path = Path::Combine(EmuFolders::DataRoot, UPDATER_EXECUTABLE); + const std::string program_path = QDir::toNativeSeparators(QCoreApplication::applicationFilePath()).toStdString(); + if (program_path.empty()) + { + reportError("Failed to get current application path"); + return false; + } + Error error; if ((FileSystem::FileExists(update_zip_path.c_str()) && !FileSystem::DeleteFile(update_zip_path.c_str(), &error))) { @@ -693,16 +700,18 @@ bool AutoUpdaterWindow::processUpdate(const std::vector& update_data) } Error updater_extract_error; - if (!extractUpdater(update_zip_path.c_str(), updater_path.c_str(), &updater_extract_error)) + if (!extractUpdater(update_zip_path.c_str(), updater_path.c_str(), Path::GetFileName(program_path), + &updater_extract_error)) { reportError(fmt::format("Extracting updater failed: {}", updater_extract_error.GetDescription())); return false; } - return doUpdate(application_dir, update_zip_path, updater_path); + return doUpdate(application_dir, update_zip_path, updater_path, program_path); } -bool AutoUpdaterWindow::extractUpdater(const std::string& zip_path, const std::string& destination_path, Error* error) +bool AutoUpdaterWindow::extractUpdater(const std::string& zip_path, const std::string& destination_path, + const std::string_view check_for_file, Error* error) { unzFile zf = MinizipHelpers::OpenUnzFile(zip_path.c_str()); if (!zf) @@ -711,6 +720,33 @@ bool AutoUpdaterWindow::extractUpdater(const std::string& zip_path, const std::s return false; } + // check the the expected program name is inside the updater zip. if it's not, we're going to launch the old binary + // with a partially updated installation + if (unzLocateFile(zf, std::string(check_for_file).c_str(), 0) != UNZ_OK) + { +#ifdef CPU_ARCH_X64 + const QString expected_executable = QStringLiteral("duckstation-qt-x64-ReleaseLTCG.exe"); +#else + const QString expected_executable = QStringLiteral("duckstation-qt-ARM64-ReleaseLTCG.exe"); +#endif + + if (QtUtils::MessageBoxIcon( + this, QMessageBox::Warning, tr("Updater Warning"), + tr("

Inconsistent Application State

The update zip is missing the current executable:

%1

This is usually a result of manually renaming the " + "file. Continuing to install this update may result in a broken installation if the renamed " + "executable is used. The DuckStation executable should be named:

%2

Do you want to continue anyway?

") + .arg(QString::fromStdString(std::string(check_for_file))) + .arg(expected_executable), + QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton) == QMessageBox::No) + { + Error::SetStringFmt(error, "Update zip is missing expected file: {}", check_for_file); + unzClose(zf); + return false; + } + } + if (unzLocateFile(zf, UPDATER_EXECUTABLE, 0) != UNZ_OK || unzOpenCurrentFile(zf) != UNZ_OK) { Error::SetString(error, "Failed to locate updater.exe"); @@ -759,15 +795,8 @@ bool AutoUpdaterWindow::extractUpdater(const std::string& zip_path, const std::s } bool AutoUpdaterWindow::doUpdate(const std::string& application_dir, const std::string& zip_path, - const std::string& updater_path) + const std::string& updater_path, const std::string& program_path) { - const std::string program_path = QDir::toNativeSeparators(QCoreApplication::applicationFilePath()).toStdString(); - if (program_path.empty()) - { - reportError("Failed to get current application path"); - return false; - } - const std::wstring wupdater_path = StringUtil::UTF8StringToWideString(updater_path); const std::wstring wapplication_dir = StringUtil::UTF8StringToWideString(application_dir); const std::wstring arguments = StringUtil::UTF8StringToWideString(fmt::format( diff --git a/src/duckstation-qt/autoupdaterwindow.h b/src/duckstation-qt/autoupdaterwindow.h index 77e79c36b..00124836b 100644 --- a/src/duckstation-qt/autoupdaterwindow.h +++ b/src/duckstation-qt/autoupdaterwindow.h @@ -70,8 +70,10 @@ private: #ifdef _WIN32 bool doesUpdaterNeedElevation(const std::string& application_dir) const; - bool doUpdate(const std::string& application_dir, const std::string& zip_path, const std::string& updater_path); - bool extractUpdater(const std::string& zip_path, const std::string& destination_path, Error* error); + bool doUpdate(const std::string& application_dir, const std::string& zip_path, const std::string& updater_path, + const std::string& program_path); + bool extractUpdater(const std::string& zip_path, const std::string& destination_path, + const std::string_view check_for_file, Error* error); #endif Ui::AutoUpdaterWindow m_ui;