From 9c5ed01130da77fa102ad39b6cb7aab8af805a63 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 16 Mar 2022 23:56:43 +0100 Subject: [PATCH] Add rpcs3 location checks to main Don't allow running RPCS3 from temp dirs. Abort if the folder has no write permissions. --- rpcs3/main.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index 911332482d..bb654c6f53 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "rpcs3qt/gui_application.h" #include "rpcs3qt/fatal_error_dialog.h" @@ -97,7 +98,7 @@ LOG_CHANNEL(q_debug, "QDEBUG"); buf = std::string(_text); // Always print thread id - fmt::append(buf, "\nThread id = %s.", std::this_thread::get_id()); + fmt::append(buf, "\n\nThread id = %s.", std::this_thread::get_id()); } std::string_view text = buf.empty() ? _text : buf; @@ -258,6 +259,7 @@ constexpr auto arg_installpkg = "installpkg"; constexpr auto arg_commit_db = "get-commit-db"; constexpr auto arg_timer = "high-res-timer"; constexpr auto arg_verbose_curl = "verbose-curl"; +constexpr auto arg_any_location = "allow-any-location"; int find_arg(std::string arg, int& argc, char* argv[]) { @@ -591,6 +593,7 @@ int main(int argc, char** argv) parser.addOption(QCommandLineOption(arg_commit_db, "Update commits.lst cache. Optional arguments: ")); parser.addOption(QCommandLineOption(arg_timer, "Enable high resolution timer for better performance (windows)", "enabled", "1")); parser.addOption(QCommandLineOption(arg_verbose_curl, "Enable verbose curl logging.")); + parser.addOption(QCommandLineOption(arg_any_location, "Allow RPCS3 to be run from any location. Dangerous")); parser.process(app->arguments()); // Don't start up the full rpcs3 gui if we just want the version or help. @@ -901,6 +904,42 @@ int main(int argc, char** argv) report_fatal_error("RPCS3 initialization failed!"); } + // Check if the current location is actually useable + if (!parser.isSet(arg_any_location)) + { + const std::string emu_dir = rpcs3::utils::get_emu_dir(); + + // Check temporary directories + for (const QString& path : QStandardPaths::standardLocations(QStandardPaths::StandardLocation::TempLocation)) + { + if (Emu.IsPathInsideDir(emu_dir, path.toStdString())) + { + report_fatal_error(fmt::format( + "RPCS3 should never be run from a temporary location!\n" + "Please install RPCS3 in a persistent location.\n" + "Current location:\n%s", emu_dir)); + return 1; + } + } + + // Check if the directory is writable + fs::stat_t info{}; + if (!fs::stat(emu_dir, info)) + { + report_fatal_error(fmt::format("Unable to query folder stats. Error: %s\nCurrent location:\n%s", fs::g_tls_error, emu_dir)); + return 1; + } + + if (!info.is_writable) + { + report_fatal_error(fmt::format( + "The RPCS3 folder has no write permissions!\n" + "Please make sure that the current user has write permissions.\n" + "Current location:\n%s", emu_dir)); + return 1; + } + } + #ifdef _WIN32 // Create dummy permanent low resolution timer to workaround messing with system timer resolution QTimer* dummy_timer = new QTimer(app.data());