From 29528f6ea08bff48595401c45225aaaf968a673b Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 17 Jul 2018 17:29:58 -0400 Subject: [PATCH] Fix delete bug and documentate --- src/core/file_sys/vfs.h | 12 ++++++++++++ src/core/file_sys/vfs_real.cpp | 10 ++++++++++ src/core/file_sys/vfs_real.h | 4 ++++ src/core/hle/service/filesystem/filesystem.cpp | 8 +++----- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index 255166afc6..a5213e0cc7 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h @@ -173,9 +173,21 @@ struct VfsDirectory : NonCopyable { // operation failed. virtual std::shared_ptr CreateFile(const std::string& name) = 0; + // Creates a new file at the path relative to this directory. Also creates directories if + // they do not exist and is supported by this implementation. Returns nullptr on any failure. virtual std::shared_ptr CreateFileRelative(const std::string& path); + + // Creates a new file at the path relative to root of this directory. Also creates directories + // if they do not exist and is supported by this implementation. Returns nullptr on any failure. virtual std::shared_ptr CreateFileAbsolute(const std::string& path); + + // Creates a new directory at the path relative to this directory. Also creates directories if + // they do not exist and is supported by this implementation. Returns nullptr on any failure. virtual std::shared_ptr CreateDirectoryRelative(const std::string& path); + + // Creates a new directory at the path relative to root of this directory. Also creates + // directories if they do not exist and is supported by this implementation. Returns nullptr on + // any failure. virtual std::shared_ptr CreateDirectoryAbsolute(const std::string& path); // Deletes the subdirectory with name and returns true on success. diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 8b95e8c729..87ebf71097 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -76,6 +76,10 @@ bool RealVfsFile::Rename(const std::string& name) { return out; } +bool RealVfsFile::Close() { + return backing.Close(); +} + RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_) : path(FileUtil::RemoveTrailingSlash(path_)), parent_path(FileUtil::GetParentPath(path)), path_components(FileUtil::SplitPathComponents(path)), @@ -146,6 +150,12 @@ bool RealVfsDirectory::DeleteSubdirectory(const std::string& name) { } bool RealVfsDirectory::DeleteFile(const std::string& name) { + auto file = GetFile(name); + if (file == nullptr) + return false; + files.erase(std::find(files.begin(), files.end(), file)); + auto real_file = dynamic_cast(file.get()); + real_file->Close(); return FileUtil::Delete(path + DIR_SEP + name); } diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index 93d8295e82..5b765a5525 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h @@ -12,6 +12,8 @@ namespace FileSys { // An implmentation of VfsFile that represents a file on the user's computer. struct RealVfsFile : public VfsFile { + friend struct RealVfsDirectory; + RealVfsFile(const std::string& name, Mode perms = Mode::Read); std::string GetName() const override; @@ -25,6 +27,8 @@ struct RealVfsFile : public VfsFile { bool Rename(const std::string& name) override; private: + bool Close(); + FileUtil::IOFile backing; std::string path; std::string parent_path; diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 0b94b45396..d9e57cd52c 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -2,16 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma optimize("", 0) - #include "common/assert.h" #include "common/file_util.h" #include "core/core.h" #include "core/file_sys/errors.h" -#include "core/file_sys/filesystem.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/sdmc_factory.h" -#include "core/file_sys/errors.h" #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_offset.h" #include "core/file_sys/vfs_real.h" @@ -53,9 +49,11 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 s ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const { auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path)); if (path == "/" || path == "\\") { - backing->DeleteSubdirectory(""); + // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but... return RESULT_SUCCESS; } + if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr) + return FileSys::ERROR_PATH_NOT_FOUND; if (!backing->DeleteFile(FileUtil::GetFilename(path))) return ResultCode(-1); return RESULT_SUCCESS;