From a7d9fe993a3e0e4d939752d2e447cc2b5fdb80f0 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 30 Nov 2018 14:44:13 -0500 Subject: service/fsp_srv: Implement CleanDirectoryRecursively This is the same behavior-wise as DeleteDirectoryRecursively, with the only difference being that it doesn't delete the top level directory in the hierarchy, so given: root_dir/ - some_dir/ - File.txt - OtherFile.txt The end result is just: root_dir/ --- src/core/hle/service/filesystem/filesystem.cpp | 12 ++++++++++++ src/core/hle/service/filesystem/filesystem.h | 12 ++++++++++++ src/core/hle/service/filesystem/fsp_srv.cpp | 12 +++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 2aa77f68d..3bdff4036 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -113,6 +113,18 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str return RESULT_SUCCESS; } +ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const { + const std::string sanitized_path(FileUtil::SanitizePath(path)); + auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(sanitized_path)); + + if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) { + // TODO(DarkLordZach): Find a better error code for this + return ResultCode(-1); + } + + return RESULT_SUCCESS; +} + ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, const std::string& dest_path_) const { std::string src_path(FileUtil::SanitizePath(src_path_)); diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 0a6cb6635..278cf90ab 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -113,6 +113,18 @@ public: */ ResultCode DeleteDirectoryRecursively(const std::string& path) const; + /** + * Cleans the specified directory. This is similar to DeleteDirectoryRecursively, + * in that it deletes all the contents of the specified directory, however, this + * function does *not* delete the directory itself. It only deletes everything + * within it. + * + * @param path Path relative to the archive. + * + * @return Result of the operation. + */ + ResultCode CleanDirectoryRecursively(const std::string& path) const; + /** * Rename a File specified by its path * @param src_path Source path relative to the archive diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 99d9ebc39..694ec40ec 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -291,7 +291,7 @@ public: {10, &IFileSystem::Commit, "Commit"}, {11, nullptr, "GetFreeSpaceSize"}, {12, nullptr, "GetTotalSpaceSize"}, - {13, nullptr, "CleanDirectoryRecursively"}, + {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, {14, nullptr, "GetFileTimeStampRaw"}, {15, nullptr, "QueryEntry"}, }; @@ -361,6 +361,16 @@ public: rb.Push(backend.DeleteDirectoryRecursively(name)); } + void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. Directory: {}", name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.CleanDirectoryRecursively(name)); + } + void RenameFile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; -- cgit v1.2.3