diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 42f56612c1..deaa13dbdc 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -4,7 +4,6 @@ #include "Crypto/sha1.h" #include -#include #include #include #include @@ -1823,20 +1822,6 @@ bool fs::remove_all(const std::string& path, bool remove_root) return true; } -std::string fs::resolve_path(std::string_view path) -{ - std::error_code ec{}; - const auto result = std::filesystem::weakly_canonical(std::filesystem::u8path(path), ec); - - if (ec) - { - g_tls_error = error::inval; - return {}; - } - - return result.string(); -} - u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment) { u64 result = 0; diff --git a/Utilities/File.h b/Utilities/File.h index 790d7bdcc8..8e019d8cc5 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -645,9 +645,6 @@ namespace fs std::string m_dest{}; // Destination file path }; - // Get real path for comparisons - std::string resolve_path(std::string_view path); - // Delete directory and all its contents recursively bool remove_all(const std::string& path, bool remove_root = true); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index f3adf24b3a..e67abdb023 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -554,7 +554,7 @@ void Emulator::SetForceBoot(bool force_boot) game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool is_disc_patch) { - const std::string resolved_path = fs::resolve_path(m_path); + const std::string resolved_path = GetCallbacks().resolve_path(m_path); if (!IsStopped()) { @@ -931,7 +931,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool break; } - if (fs::file sfb_file{parent_dir + "/PS3_DISC.SFB"}; sfb_file && !sfb_file.stat().is_directory && sfb_file.size() >= 4 && sfb_file.read() == ".SFB"_u32) + if (fs::file sfb_file{parent_dir + "/PS3_DISC.SFB"}; sfb_file && sfb_file.size() >= 4 && sfb_file.read() == ".SFB"_u32) { main_dir_name = std::string_view{search_dir}.substr(search_dir.find_last_of(fs::delim) + 1); @@ -1213,7 +1213,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool // Check game updates const std::string hdd0_boot = hdd0_game + m_title_id + "/USRDIR/EBOOT.BIN"; - if (disc.empty() && !bdvd_dir.empty() && fs::resolve_path(m_path) != fs::resolve_path(hdd0_boot) && fs::is_file(hdd0_boot)) + if (disc.empty() && !bdvd_dir.empty() && GetCallbacks().resolve_path(m_path) != GetCallbacks().resolve_path(hdd0_boot) && fs::is_file(hdd0_boot)) { // Booting game update sys_log.success("Updates found at /dev_hdd0/game/%s/", m_title_id); @@ -1333,7 +1333,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool return fmt::merge(result, "/"); }; - const std::string resolved_hdd0 = fs::resolve_path(hdd0_game) + '/'; + const std::string resolved_hdd0 = GetCallbacks().resolve_path(hdd0_game) + '/'; if (from_hdd0_game && m_cat == "DG") { @@ -1357,7 +1357,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool else if (from_dev_flash) { // Firmware executables - argv[0] = "/dev_flash" + resolved_path.substr(fs::resolve_path(g_cfg_vfs.get_dev_flash()).size()); + argv[0] = "/dev_flash" + resolved_path.substr(GetCallbacks().resolve_path(g_cfg_vfs.get_dev_flash()).size()); m_dir = fs::get_parent_dir(argv[0]) + '/'; } else if (g_cfg.vfs.host_root) @@ -1975,9 +1975,9 @@ std::set Emulator::GetGameDirs() const bool Emulator::IsPathInsideDir(std::string_view path, std::string_view dir) const { - const std::string dir_path = fs::resolve_path(dir); + const std::string dir_path = GetCallbacks().resolve_path(dir); - return !dir_path.empty() && (fs::resolve_path(path) + '/').starts_with(dir_path + '/'); + return !dir_path.empty() && (GetCallbacks().resolve_path(path) + '/').starts_with(dir_path + '/'); }; const std::string& Emulator::GetFakeCat() const diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 2534a34480..f0159f9786 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -81,6 +81,7 @@ struct EmuCallbacks std::function get_localized_string; std::function get_localized_u32string; std::function play_sound; + std::string(*resolve_path)(std::string_view) = nullptr; // Resolve path using Qt }; class Emulator final diff --git a/rpcs3/Emu/VFS.cpp b/rpcs3/Emu/VFS.cpp index 65333fa916..966214a31e 100644 --- a/rpcs3/Emu/VFS.cpp +++ b/rpcs3/Emu/VFS.cpp @@ -42,6 +42,8 @@ bool vfs::mount(std::string_view vpath, std::string_view path) // TODO: scan roots of mounted devices for undeleted vfs::host::unlink remnants, and try to delete them (_WIN32 only) + std::lock_guard lock(table.mutex); + if (vpath.empty()) { // Empty relative path, should set relative path base; unsupported @@ -49,23 +51,8 @@ bool vfs::mount(std::string_view vpath, std::string_view path) return false; } - std::string final_path = fs::resolve_path(path); - - if (final_path.empty()) - { - vfs_log.error("Cannot mount path \"%s\" due to invalid host path \"%s\" (%s)", vpath, path, fs::g_tls_error); - return false; - } - - if (!final_path.ends_with(fs::delim[0]) && !final_path.ends_with(fs::delim[1]) && (path.ends_with(fs::delim[0]) || path.ends_with(fs::delim[1]))) - { - final_path += '/'; - } - const std::string_view vpath_backup = vpath; - std::lock_guard lock(table.mutex); - for (std::vector list{&table.root};;) { // Skip one or more '/' @@ -81,8 +68,8 @@ bool vfs::mount(std::string_view vpath, std::string_view path) if (pos == umax) { // Mounting completed - list.back()->path = std::move(final_path); - vfs_log.notice("Mounted path \"%s\" to \"%s\"", vpath_backup, list.back()->path); + list.back()->path = path; + vfs_log.notice("Mounted path \"%s\" to \"%s\"", vpath_backup, path); return true; } @@ -756,7 +743,7 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2 { // Lock mount point, close file descriptors, retry const auto from0 = std::string_view(from).substr(0, from.find_last_not_of(fs::delim) + 1); - const auto escaped_from = fs::resolve_path(from); + const auto escaped_from = Emu.GetCallbacks().resolve_path(from); std::lock_guard lock(mp->mutex); @@ -767,7 +754,7 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2 idm::select([&](u32 /*id*/, lv2_file& file) { - if (check_path(fs::resolve_path(file.real_path))) + if (check_path(Emu.GetCallbacks().resolve_path(file.real_path))) { ensure(file.mp == mp); @@ -809,7 +796,7 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2 idm::select([&](u32 /*id*/, lv2_file& file) { - const auto escaped_real = fs::resolve_path(file.real_path); + const auto escaped_real = Emu.GetCallbacks().resolve_path(file.real_path); if (check_path(escaped_real)) { diff --git a/rpcs3/main_application.cpp b/rpcs3/main_application.cpp index 8d4d110c96..ff61055cb2 100644 --- a/rpcs3/main_application.cpp +++ b/rpcs3/main_application.cpp @@ -26,6 +26,8 @@ #include "Emu/Audio/FAudio/FAudioBackend.h" #endif +#include // This shouldn't be outside rpcs3qt... + LOG_CHANNEL(sys_log, "SYS"); /** Emu.Init() wrapper for user management */ @@ -121,5 +123,10 @@ EmuCallbacks main_application::CreateCallbacks() return result; }; + callbacks.resolve_path = [](std::string_view sv) + { + return QFileInfo(QString::fromUtf8(sv.data(), static_cast(sv.size()))).canonicalFilePath().toStdString(); + }; + return callbacks; }