diff --git a/Common/File/AndroidStorage.h b/Common/File/AndroidStorage.h index cb40db0e9f..7e585c0161 100644 --- a/Common/File/AndroidStorage.h +++ b/Common/File/AndroidStorage.h @@ -47,7 +47,10 @@ StorageError Android_CreateDirectory(const std::string &parentTreeUri, const std StorageError Android_CreateFile(const std::string &parentTreeUri, const std::string &fileName); StorageError Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri); StorageError Android_CopyFile(const std::string &fileUri, const std::string &destParentUri); + +// WARNING: This is very powerful, it will delete directories recursively! StorageError Android_RemoveFile(const std::string &fileUri); + StorageError Android_RenameFileTo(const std::string &fileUri, const std::string &newName); bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *info); bool Android_FileExists(const std::string &fileUri); @@ -65,6 +68,8 @@ void Android_RegisterStorageCallbacks(JNIEnv * env, jobject obj); // Stub out the Android Storage wrappers, so that we can avoid ifdefs everywhere. +// See comments for the corresponding functions above. + inline bool Android_IsContentUri(std::string_view uri) { return false; } inline int Android_OpenContentUriFd(std::string_view uri, const Android_OpenContentUriMode mode) { return -1; } inline StorageError Android_CreateDirectory(const std::string &parentTreeUri, const std::string &dirName) { return StorageError::UNKNOWN; } diff --git a/Common/File/FileUtil.cpp b/Common/File/FileUtil.cpp index 19da5f04bb..2959056aed 100644 --- a/Common/File/FileUtil.cpp +++ b/Common/File/FileUtil.cpp @@ -902,6 +902,7 @@ bool CreateEmptyFile(const Path &filename) { } // Deletes an empty directory, returns true on success +// WARNING: On Android with content URIs, it will delete recursively! bool DeleteDir(const Path &path) { switch (path.Type()) { case PathType::NATIVE: @@ -937,18 +938,20 @@ bool DeleteDir(const Path &path) { } // Deletes the given directory and anything under it. Returns true on success. -bool DeleteDirRecursively(const Path &directory) { - switch (directory.Type()) { - case PathType::CONTENT_URI: +bool DeleteDirRecursively(const Path &path) { + switch (path.Type()) { case PathType::NATIVE: - break; // OK + break; + case PathType::CONTENT_URI: + // We make use of the dangerous auto-recursive property of Android_RemoveFile. + return Android_RemoveFile(path.ToString()) == StorageError::SUCCESS; default: ERROR_LOG(COMMON, "DeleteDirRecursively: Path type not supported"); return false; } std::vector files; - GetFilesInDir(directory, &files, nullptr, GETFILES_GETHIDDEN); + GetFilesInDir(path, &files, nullptr, GETFILES_GETHIDDEN); for (const auto &file : files) { if (file.isDirectory) { DeleteDirRecursively(file.fullName); @@ -956,7 +959,7 @@ bool DeleteDirRecursively(const Path &directory) { Delete(file.fullName); } } - return DeleteDir(directory); + return DeleteDir(path); } bool OpenFileInEditor(const Path &fileName) {