diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 6445f473d1..c1a40627be 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -862,7 +862,9 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr path) const std::string_view vpath = path.get_ptr(); const std::string local_path = vfs::get(vpath); - if (vpath.find_first_not_of('/') == -1) + const std::size_t dev_start = vpath.find_first_not_of('/'); + + if (dev_start == -1) { return {CELL_EISDIR, path}; } @@ -877,7 +879,10 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr path) return {CELL_EISDIR, path}; } - if (!vfs::host::unlink(local_path)) + // Size of "/dev_hdd0"-alike substring + const std::size_t dev_size = vpath.find_first_of('/', dev_start); + + if (!vfs::host::unlink(local_path, vfs::get(vpath.substr(0, dev_size)))) { switch (auto error = fs::g_tls_error) { diff --git a/rpcs3/Emu/VFS.cpp b/rpcs3/Emu/VFS.cpp index 3140984e11..bb68a7a357 100644 --- a/rpcs3/Emu/VFS.cpp +++ b/rpcs3/Emu/VFS.cpp @@ -33,6 +33,8 @@ bool vfs::mount(std::string_view vpath, std::string_view path) const auto table = g_fxo->get(); + // 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()) @@ -566,13 +568,13 @@ bool vfs::host::rename(const std::string& from, const std::string& to, bool over return true; } -bool vfs::host::unlink(const std::string& path) +bool vfs::host::unlink(const std::string& path, const std::string& dev_root) { #ifdef _WIN32 if (path.size() < 2 || reinterpret_cast(path.front()) != "//"_u16) { // Rename to special dummy name which will be ignored by VFS (but opened file handles can still read or write it) - const std::string dummy = fmt::format(u8"%s/$%s%s", fs::get_parent_dir(path), fmt::base57(std::hash()(path)), fmt::base57(__rdtsc())); + const std::string dummy = fmt::format(u8"%s/$%s%s", dev_root, fmt::base57(std::hash()(path)), fmt::base57(__rdtsc())); if (!fs::rename(path, dummy, true)) { diff --git a/rpcs3/Emu/VFS.h b/rpcs3/Emu/VFS.h index e3e12ede1b..72e551c15f 100644 --- a/rpcs3/Emu/VFS.h +++ b/rpcs3/Emu/VFS.h @@ -25,6 +25,6 @@ namespace vfs bool rename(const std::string& from, const std::string& to, bool overwrite); // Delete file without deleting its contents, emulated with MoveFileEx on Windows - bool unlink(const std::string&); + bool unlink(const std::string& path, const std::string& dev_root); } }