[VFS] Fixed allow_game_relative_writes to write invalid cached entries

This PR fixes https://github.com/xenia-canary/xenia-canary/issues/123 a bug where files would not write to the host if they were deleted from the host filesystem during runtime.
This commit is contained in:
Adrian 2023-02-04 17:18:24 +00:00 committed by Radosław Gliński
parent 333d7c2767
commit 321dd75e05
3 changed files with 21 additions and 3 deletions

View File

@ -103,9 +103,10 @@ bool HostPathEntry::DeleteEntryInternal(Entry* entry) {
auto removed = std::filesystem::remove_all(full_path, ec);
return removed >= 1 && removed != static_cast<std::uintmax_t>(-1);
} else {
// Delete file.
// Delete file only if it exists.
return !std::filesystem::is_directory(full_path) &&
std::filesystem::remove(full_path, ec);
(!std::filesystem::exists(full_path) ||
std::filesystem::remove(full_path, ec));
}
}

View File

@ -30,7 +30,7 @@ class HostPathEntry : public Entry {
const std::filesystem::path& full_path,
xe::filesystem::FileInfo file_info);
const std::filesystem::path& host_path() { return host_path_; }
const std::filesystem::path& host_path() const { return host_path_; }
X_STATUS Open(uint32_t desired_access, File** out_file) override;

View File

@ -11,6 +11,7 @@
#include "xenia/kernel/xam/content_manager.h"
#include "xenia/vfs/devices/stfs_container_device.h"
#include "devices/host_path_entry.h"
#include "xenia/base/literals.h"
#include "xenia/base/logging.h"
#include "xenia/base/string.h"
@ -221,6 +222,22 @@ X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry,
if (entry->attributes() & kFileAttributeDirectory && is_non_directory) {
return X_STATUS_FILE_IS_A_DIRECTORY;
}
// If the entry does not exist on the host then remove the cached entry
if (parent_entry) {
const xe::vfs::HostPathEntry* host_Path =
dynamic_cast<const xe::vfs::HostPathEntry*>(parent_entry);
if (host_Path) {
auto const file_path = host_Path->host_path() / entry->name();
if (!std::filesystem::exists(file_path)) {
// Remove cached entry
entry->Delete();
entry = nullptr;
}
}
}
}
// Check if exists (if we need it to), or that it doesn't (if it shouldn't).