summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/vfs.cpp26
-rw-r--r--src/core/file_sys/vfs.h15
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp12
-rw-r--r--src/core/hle/service/filesystem/filesystem.h12
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp12
5 files changed, 72 insertions, 5 deletions
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index 7b584de7f..a4a3236f4 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -384,6 +384,28 @@ bool VfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
384 return success; 384 return success;
385} 385}
386 386
387bool VfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
388 auto dir = GetSubdirectory(name);
389 if (dir == nullptr) {
390 return false;
391 }
392
393 bool success = true;
394 for (const auto& file : dir->GetFiles()) {
395 if (!dir->DeleteFile(file->GetName())) {
396 success = false;
397 }
398 }
399
400 for (const auto& sdir : dir->GetSubdirectories()) {
401 if (!dir->DeleteSubdirectoryRecursive(sdir->GetName())) {
402 success = false;
403 }
404 }
405
406 return success;
407}
408
387bool VfsDirectory::Copy(std::string_view src, std::string_view dest) { 409bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
388 const auto f1 = GetFile(src); 410 const auto f1 = GetFile(src);
389 auto f2 = CreateFile(dest); 411 auto f2 = CreateFile(dest);
@@ -435,6 +457,10 @@ bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) {
435 return false; 457 return false;
436} 458}
437 459
460bool ReadOnlyVfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
461 return false;
462}
463
438bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) { 464bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
439 return false; 465 return false;
440} 466}
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h
index 002f99d4e..6e1db36f1 100644
--- a/src/core/file_sys/vfs.h
+++ b/src/core/file_sys/vfs.h
@@ -245,12 +245,18 @@ public:
245 // any failure. 245 // any failure.
246 virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path); 246 virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
247 247
248 // Deletes the subdirectory with name and returns true on success. 248 // Deletes the subdirectory with the given name and returns true on success.
249 virtual bool DeleteSubdirectory(std::string_view name) = 0; 249 virtual bool DeleteSubdirectory(std::string_view name) = 0;
250 // Deletes all subdirectories and files of subdirectory with name recirsively and then deletes 250
251 // the subdirectory. Returns true on success. 251 // Deletes all subdirectories and files within the provided directory and then deletes
252 // the directory itself. Returns true on success.
252 virtual bool DeleteSubdirectoryRecursive(std::string_view name); 253 virtual bool DeleteSubdirectoryRecursive(std::string_view name);
253 // Returnes whether or not the file with name name was deleted successfully. 254
255 // Deletes all subdirectories and files within the provided directory.
256 // Unlike DeleteSubdirectoryRecursive, this does not delete the provided directory.
257 virtual bool CleanSubdirectoryRecursive(std::string_view name);
258
259 // Returns whether or not the file with name name was deleted successfully.
254 virtual bool DeleteFile(std::string_view name) = 0; 260 virtual bool DeleteFile(std::string_view name) = 0;
255 261
256 // Returns whether or not this directory was renamed to name. 262 // Returns whether or not this directory was renamed to name.
@@ -277,6 +283,7 @@ public:
277 std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override; 283 std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
278 std::shared_ptr<VfsFile> CreateFile(std::string_view name) override; 284 std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
279 bool DeleteSubdirectory(std::string_view name) override; 285 bool DeleteSubdirectory(std::string_view name) override;
286 bool CleanSubdirectoryRecursive(std::string_view name) override;
280 bool DeleteFile(std::string_view name) override; 287 bool DeleteFile(std::string_view name) override;
281 bool Rename(std::string_view name) override; 288 bool Rename(std::string_view name) override;
282}; 289};
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
113 return RESULT_SUCCESS; 113 return RESULT_SUCCESS;
114} 114}
115 115
116ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const {
117 const std::string sanitized_path(FileUtil::SanitizePath(path));
118 auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(sanitized_path));
119
120 if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) {
121 // TODO(DarkLordZach): Find a better error code for this
122 return ResultCode(-1);
123 }
124
125 return RESULT_SUCCESS;
126}
127
116ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, 128ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
117 const std::string& dest_path_) const { 129 const std::string& dest_path_) const {
118 std::string src_path(FileUtil::SanitizePath(src_path_)); 130 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
@@ -114,6 +114,18 @@ public:
114 ResultCode DeleteDirectoryRecursively(const std::string& path) const; 114 ResultCode DeleteDirectoryRecursively(const std::string& path) const;
115 115
116 /** 116 /**
117 * Cleans the specified directory. This is similar to DeleteDirectoryRecursively,
118 * in that it deletes all the contents of the specified directory, however, this
119 * function does *not* delete the directory itself. It only deletes everything
120 * within it.
121 *
122 * @param path Path relative to the archive.
123 *
124 * @return Result of the operation.
125 */
126 ResultCode CleanDirectoryRecursively(const std::string& path) const;
127
128 /**
117 * Rename a File specified by its path 129 * Rename a File specified by its path
118 * @param src_path Source path relative to the archive 130 * @param src_path Source path relative to the archive
119 * @param dest_path Destination path relative to the archive 131 * @param dest_path Destination 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:
291 {10, &IFileSystem::Commit, "Commit"}, 291 {10, &IFileSystem::Commit, "Commit"},
292 {11, nullptr, "GetFreeSpaceSize"}, 292 {11, nullptr, "GetFreeSpaceSize"},
293 {12, nullptr, "GetTotalSpaceSize"}, 293 {12, nullptr, "GetTotalSpaceSize"},
294 {13, nullptr, "CleanDirectoryRecursively"}, 294 {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
295 {14, nullptr, "GetFileTimeStampRaw"}, 295 {14, nullptr, "GetFileTimeStampRaw"},
296 {15, nullptr, "QueryEntry"}, 296 {15, nullptr, "QueryEntry"},
297 }; 297 };
@@ -361,6 +361,16 @@ public:
361 rb.Push(backend.DeleteDirectoryRecursively(name)); 361 rb.Push(backend.DeleteDirectoryRecursively(name));
362 } 362 }
363 363
364 void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) {
365 const auto file_buffer = ctx.ReadBuffer();
366 const std::string name = Common::StringFromBuffer(file_buffer);
367
368 LOG_DEBUG(Service_FS, "called. Directory: {}", name);
369
370 IPC::ResponseBuilder rb{ctx, 2};
371 rb.Push(backend.CleanDirectoryRecursively(name));
372 }
373
364 void RenameFile(Kernel::HLERequestContext& ctx) { 374 void RenameFile(Kernel::HLERequestContext& ctx) {
365 IPC::RequestParser rp{ctx}; 375 IPC::RequestParser rp{ctx};
366 376