re-do how protected files work, by default everything is writeable, aside from fs.
the design in now opt-out rather than opt-in. for fs, it is still opt-in. this is because the risk of a user deciding to delete a file / folder in the filebrowser menu. this can now be toggled in the the advanced options menu within filebrowser.
This commit is contained in:
@@ -171,39 +171,39 @@ static_assert(FsPath::TestFrom(FsPath{"abc"}));
|
|||||||
|
|
||||||
FsPath AppendPath(const fs::FsPath& root_path, const fs::FsPath& file_path);
|
FsPath AppendPath(const fs::FsPath& root_path, const fs::FsPath& file_path);
|
||||||
|
|
||||||
Result CreateFile(FsFileSystem* fs, const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = false);
|
Result CreateFile(FsFileSystem* fs, const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = true);
|
||||||
Result CreateDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = false);
|
Result CreateDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = true);
|
||||||
Result CreateDirectoryRecursively(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = false);
|
Result CreateDirectoryRecursively(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = true);
|
||||||
Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = false);
|
Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = true);
|
||||||
Result DeleteFile(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = false);
|
Result DeleteFile(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = true);
|
||||||
Result DeleteDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = false);
|
Result DeleteDirectory(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = true);
|
||||||
Result DeleteDirectoryRecursively(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = false);
|
Result DeleteDirectoryRecursively(FsFileSystem* fs, const FsPath& path, bool ignore_read_only = true);
|
||||||
Result RenameFile(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only = false);
|
Result RenameFile(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only = true);
|
||||||
Result RenameDirectory(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only = false);
|
Result RenameDirectory(FsFileSystem* fs, const FsPath& src, const FsPath& dst, bool ignore_read_only = true);
|
||||||
Result GetEntryType(FsFileSystem* fs, const FsPath& path, FsDirEntryType* out);
|
Result GetEntryType(FsFileSystem* fs, const FsPath& path, FsDirEntryType* out);
|
||||||
Result GetFileTimeStampRaw(FsFileSystem* fs, const FsPath& path, FsTimeStampRaw *out);
|
Result GetFileTimeStampRaw(FsFileSystem* fs, const FsPath& path, FsTimeStampRaw *out);
|
||||||
bool FileExists(FsFileSystem* fs, const FsPath& path);
|
bool FileExists(FsFileSystem* fs, const FsPath& path);
|
||||||
bool DirExists(FsFileSystem* fs, const FsPath& path);
|
bool DirExists(FsFileSystem* fs, const FsPath& path);
|
||||||
Result read_entire_file(FsFileSystem* fs, const FsPath& path, std::vector<u8>& out);
|
Result read_entire_file(FsFileSystem* fs, const FsPath& path, std::vector<u8>& out);
|
||||||
Result write_entire_file(FsFileSystem* fs, const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = false);
|
Result write_entire_file(FsFileSystem* fs, const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = true);
|
||||||
Result copy_entire_file(FsFileSystem* fs, const FsPath& dst, const FsPath& src, bool ignore_read_only = false);
|
Result copy_entire_file(FsFileSystem* fs, const FsPath& dst, const FsPath& src, bool ignore_read_only = true);
|
||||||
|
|
||||||
Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = false);
|
Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = true);
|
||||||
Result CreateDirectory(const FsPath& path, bool ignore_read_only = false);
|
Result CreateDirectory(const FsPath& path, bool ignore_read_only = true);
|
||||||
Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only = false);
|
Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only = true);
|
||||||
Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only = false);
|
Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only = true);
|
||||||
Result DeleteFile(const FsPath& path, bool ignore_read_only = false);
|
Result DeleteFile(const FsPath& path, bool ignore_read_only = true);
|
||||||
Result DeleteDirectory(const FsPath& path, bool ignore_read_only = false);
|
Result DeleteDirectory(const FsPath& path, bool ignore_read_only = true);
|
||||||
Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only = false);
|
Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only = true);
|
||||||
Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only = false);
|
Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only = true);
|
||||||
Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only = false);
|
Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only = true);
|
||||||
Result GetEntryType(const FsPath& path, FsDirEntryType* out);
|
Result GetEntryType(const FsPath& path, FsDirEntryType* out);
|
||||||
Result GetFileTimeStampRaw(const FsPath& path, FsTimeStampRaw *out);
|
Result GetFileTimeStampRaw(const FsPath& path, FsTimeStampRaw *out);
|
||||||
bool FileExists(const FsPath& path);
|
bool FileExists(const FsPath& path);
|
||||||
bool DirExists(const FsPath& path);
|
bool DirExists(const FsPath& path);
|
||||||
Result read_entire_file(const FsPath& path, std::vector<u8>& out);
|
Result read_entire_file(const FsPath& path, std::vector<u8>& out);
|
||||||
Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = false);
|
Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = true);
|
||||||
Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only = false);
|
Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only = true);
|
||||||
|
|
||||||
struct Fs {
|
struct Fs {
|
||||||
static constexpr inline u32 FsModule = 505;
|
static constexpr inline u32 FsModule = 505;
|
||||||
@@ -222,51 +222,64 @@ struct Fs {
|
|||||||
static constexpr inline Result ResultUnknownStdioError = MAKERESULT(FsModule, 13);
|
static constexpr inline Result ResultUnknownStdioError = MAKERESULT(FsModule, 13);
|
||||||
static constexpr inline Result ResultReadOnly = MAKERESULT(FsModule, 14);
|
static constexpr inline Result ResultReadOnly = MAKERESULT(FsModule, 14);
|
||||||
|
|
||||||
virtual Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = false) = 0;
|
Fs(bool ignore_read_only = true) : m_ignore_read_only{ignore_read_only} {}
|
||||||
virtual Result CreateDirectory(const FsPath& path, bool ignore_read_only = false) = 0;
|
virtual ~Fs() = default;
|
||||||
virtual Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only = false) = 0;
|
|
||||||
virtual Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only = false) = 0;
|
virtual Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0) = 0;
|
||||||
virtual Result DeleteFile(const FsPath& path, bool ignore_read_only = false) = 0;
|
virtual Result CreateDirectory(const FsPath& path) = 0;
|
||||||
virtual Result DeleteDirectory(const FsPath& path, bool ignore_read_only = false) = 0;
|
virtual Result CreateDirectoryRecursively(const FsPath& path) = 0;
|
||||||
virtual Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only = false) = 0;
|
virtual Result CreateDirectoryRecursivelyWithPath(const FsPath& path) = 0;
|
||||||
virtual Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only = false) = 0;
|
virtual Result DeleteFile(const FsPath& path) = 0;
|
||||||
virtual Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only = false) = 0;
|
virtual Result DeleteDirectory(const FsPath& path) = 0;
|
||||||
|
virtual Result DeleteDirectoryRecursively(const FsPath& path) = 0;
|
||||||
|
virtual Result RenameFile(const FsPath& src, const FsPath& dst) = 0;
|
||||||
|
virtual Result RenameDirectory(const FsPath& src, const FsPath& dst) = 0;
|
||||||
virtual Result GetEntryType(const FsPath& path, FsDirEntryType* out) = 0;
|
virtual Result GetEntryType(const FsPath& path, FsDirEntryType* out) = 0;
|
||||||
virtual Result GetFileTimeStampRaw(const FsPath& path, FsTimeStampRaw *out) = 0;
|
virtual Result GetFileTimeStampRaw(const FsPath& path, FsTimeStampRaw *out) = 0;
|
||||||
virtual bool FileExists(const FsPath& path) = 0;
|
virtual bool FileExists(const FsPath& path) = 0;
|
||||||
virtual bool DirExists(const FsPath& path) = 0;
|
virtual bool DirExists(const FsPath& path) = 0;
|
||||||
virtual Result read_entire_file(const FsPath& path, std::vector<u8>& out) = 0;
|
virtual Result read_entire_file(const FsPath& path, std::vector<u8>& out) = 0;
|
||||||
virtual Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = false) = 0;
|
virtual Result write_entire_file(const FsPath& path, const std::vector<u8>& in) = 0;
|
||||||
virtual Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only = false) = 0;
|
virtual Result copy_entire_file(const FsPath& dst, const FsPath& src) = 0;
|
||||||
|
|
||||||
|
void SetIgnoreReadOnly(bool enable) {
|
||||||
|
m_ignore_read_only = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_ignore_read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FsStdio : Fs {
|
struct FsStdio : Fs {
|
||||||
Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = false) override {
|
FsStdio(bool ignore_read_only = true) : Fs{ignore_read_only} {}
|
||||||
return fs::CreateFile(path, size, option, ignore_read_only);
|
virtual ~FsStdio() = default;
|
||||||
|
|
||||||
|
Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0) override {
|
||||||
|
return fs::CreateFile(path, size, option, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result CreateDirectory(const FsPath& path, bool ignore_read_only = false) override {
|
Result CreateDirectory(const FsPath& path) override {
|
||||||
return fs::CreateDirectory(path, ignore_read_only);
|
return fs::CreateDirectory(path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only = false) override {
|
Result CreateDirectoryRecursively(const FsPath& path) override {
|
||||||
return fs::CreateDirectoryRecursively(path, ignore_read_only);
|
return fs::CreateDirectoryRecursively(path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only = false) override {
|
Result CreateDirectoryRecursivelyWithPath(const FsPath& path) override {
|
||||||
return fs::CreateDirectoryRecursivelyWithPath(path, ignore_read_only);
|
return fs::CreateDirectoryRecursivelyWithPath(path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result DeleteFile(const FsPath& path, bool ignore_read_only = false) override {
|
Result DeleteFile(const FsPath& path) override {
|
||||||
return fs::DeleteFile(path, ignore_read_only);
|
return fs::DeleteFile(path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result DeleteDirectory(const FsPath& path, bool ignore_read_only = false) override {
|
Result DeleteDirectory(const FsPath& path) override {
|
||||||
return fs::DeleteDirectory(path, ignore_read_only);
|
return fs::DeleteDirectory(path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only = false) override {
|
Result DeleteDirectoryRecursively(const FsPath& path) override {
|
||||||
return fs::DeleteDirectoryRecursively(path, ignore_read_only);
|
return fs::DeleteDirectoryRecursively(path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only = false) override {
|
Result RenameFile(const FsPath& src, const FsPath& dst) override {
|
||||||
return fs::RenameFile(src, dst, ignore_read_only);
|
return fs::RenameFile(src, dst, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only = false) override {
|
Result RenameDirectory(const FsPath& src, const FsPath& dst) override {
|
||||||
return fs::RenameDirectory(src, dst, ignore_read_only);
|
return fs::RenameDirectory(src, dst, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result GetEntryType(const FsPath& path, FsDirEntryType* out) override {
|
Result GetEntryType(const FsPath& path, FsDirEntryType* out) override {
|
||||||
return fs::GetEntryType(path, out);
|
return fs::GetEntryType(path, out);
|
||||||
@@ -283,17 +296,17 @@ struct FsStdio : Fs {
|
|||||||
Result read_entire_file(const FsPath& path, std::vector<u8>& out) override {
|
Result read_entire_file(const FsPath& path, std::vector<u8>& out) override {
|
||||||
return fs::read_entire_file(path, out);
|
return fs::read_entire_file(path, out);
|
||||||
}
|
}
|
||||||
Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = false) override {
|
Result write_entire_file(const FsPath& path, const std::vector<u8>& in) override {
|
||||||
return fs::write_entire_file(path, in, ignore_read_only);
|
return fs::write_entire_file(path, in, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only = false) override {
|
Result copy_entire_file(const FsPath& dst, const FsPath& src) override {
|
||||||
return fs::copy_entire_file(dst, src, ignore_read_only);
|
return fs::copy_entire_file(dst, src, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FsNative : Fs {
|
struct FsNative : Fs {
|
||||||
FsNative() = default;
|
explicit FsNative(bool ignore_read_only = true) : Fs{ignore_read_only} {}
|
||||||
FsNative(FsFileSystem* fs, bool own) : m_fs{*fs}, m_own{own} {}
|
explicit FsNative(FsFileSystem* fs, bool own, bool ignore_read_only = true) : Fs{ignore_read_only}, m_fs{*fs}, m_own{own} {}
|
||||||
|
|
||||||
virtual ~FsNative() {
|
virtual ~FsNative() {
|
||||||
if (m_own) {
|
if (m_own) {
|
||||||
@@ -355,32 +368,32 @@ struct FsNative : Fs {
|
|||||||
return m_open_result;
|
return m_open_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0, bool ignore_read_only = false) override {
|
Result CreateFile(const FsPath& path, u64 size = 0, u32 option = 0) override {
|
||||||
return fs::CreateFile(&m_fs, path, size, option, ignore_read_only);
|
return fs::CreateFile(&m_fs, path, size, option, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result CreateDirectory(const FsPath& path, bool ignore_read_only = false) override {
|
Result CreateDirectory(const FsPath& path) override {
|
||||||
return fs::CreateDirectory(&m_fs, path, ignore_read_only);
|
return fs::CreateDirectory(&m_fs, path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result CreateDirectoryRecursively(const FsPath& path, bool ignore_read_only = false) override {
|
Result CreateDirectoryRecursively(const FsPath& path) override {
|
||||||
return fs::CreateDirectoryRecursively(&m_fs, path, ignore_read_only);
|
return fs::CreateDirectoryRecursively(&m_fs, path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result CreateDirectoryRecursivelyWithPath(const FsPath& path, bool ignore_read_only = false) override {
|
Result CreateDirectoryRecursivelyWithPath(const FsPath& path) override {
|
||||||
return fs::CreateDirectoryRecursivelyWithPath(&m_fs, path, ignore_read_only);
|
return fs::CreateDirectoryRecursivelyWithPath(&m_fs, path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result DeleteFile(const FsPath& path, bool ignore_read_only = false) override {
|
Result DeleteFile(const FsPath& path) override {
|
||||||
return fs::DeleteFile(&m_fs, path, ignore_read_only);
|
return fs::DeleteFile(&m_fs, path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result DeleteDirectory(const FsPath& path, bool ignore_read_only = false) override {
|
Result DeleteDirectory(const FsPath& path) override {
|
||||||
return fs::DeleteDirectory(&m_fs, path, ignore_read_only);
|
return fs::DeleteDirectory(&m_fs, path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result DeleteDirectoryRecursively(const FsPath& path, bool ignore_read_only = false) override {
|
Result DeleteDirectoryRecursively(const FsPath& path) override {
|
||||||
return fs::DeleteDirectoryRecursively(&m_fs, path, ignore_read_only);
|
return fs::DeleteDirectoryRecursively(&m_fs, path, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result RenameFile(const FsPath& src, const FsPath& dst, bool ignore_read_only = false) override {
|
Result RenameFile(const FsPath& src, const FsPath& dst) override {
|
||||||
return fs::RenameFile(&m_fs, src, dst, ignore_read_only);
|
return fs::RenameFile(&m_fs, src, dst, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result RenameDirectory(const FsPath& src, const FsPath& dst, bool ignore_read_only = false) override {
|
Result RenameDirectory(const FsPath& src, const FsPath& dst) override {
|
||||||
return fs::RenameDirectory(&m_fs, src, dst, ignore_read_only);
|
return fs::RenameDirectory(&m_fs, src, dst, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result GetEntryType(const FsPath& path, FsDirEntryType* out) override {
|
Result GetEntryType(const FsPath& path, FsDirEntryType* out) override {
|
||||||
return fs::GetEntryType(&m_fs, path, out);
|
return fs::GetEntryType(&m_fs, path, out);
|
||||||
@@ -397,11 +410,11 @@ struct FsNative : Fs {
|
|||||||
Result read_entire_file(const FsPath& path, std::vector<u8>& out) override {
|
Result read_entire_file(const FsPath& path, std::vector<u8>& out) override {
|
||||||
return fs::read_entire_file(&m_fs, path, out);
|
return fs::read_entire_file(&m_fs, path, out);
|
||||||
}
|
}
|
||||||
Result write_entire_file(const FsPath& path, const std::vector<u8>& in, bool ignore_read_only = false) override {
|
Result write_entire_file(const FsPath& path, const std::vector<u8>& in) override {
|
||||||
return fs::write_entire_file(&m_fs, path, in, ignore_read_only);
|
return fs::write_entire_file(&m_fs, path, in, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
Result copy_entire_file(const FsPath& dst, const FsPath& src, bool ignore_read_only = false) override {
|
Result copy_entire_file(const FsPath& dst, const FsPath& src) override {
|
||||||
return fs::copy_entire_file(&m_fs, dst, src, ignore_read_only);
|
return fs::copy_entire_file(&m_fs, dst, src, m_ignore_read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
FsFileSystem m_fs{};
|
FsFileSystem m_fs{};
|
||||||
@@ -417,43 +430,28 @@ struct FsNativeSd final : FsNative {
|
|||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
struct FsNativeSd final : FsNative {
|
struct FsNativeSd final : FsNative {
|
||||||
FsNativeSd() : FsNative{fsdevGetDeviceFileSystem("sdmc:"), false} {
|
FsNativeSd(bool ignore_read_only = true) : FsNative{fsdevGetDeviceFileSystem("sdmc:"), false, ignore_read_only} {
|
||||||
m_open_result = 0;
|
m_open_result = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct FsNativeBis final : FsNative {
|
struct FsNativeBis final : FsNative {
|
||||||
FsNativeBis(FsBisPartitionId id, const FsPath& string) {
|
FsNativeBis(FsBisPartitionId id, const FsPath& string, bool ignore_read_only = true) : FsNative{ignore_read_only} {
|
||||||
m_open_result = fsOpenBisFileSystem(&m_fs, id, string);
|
m_open_result = fsOpenBisFileSystem(&m_fs, id, string);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FsNativeImage final : FsNative {
|
struct FsNativeImage final : FsNative {
|
||||||
FsNativeImage(FsImageDirectoryId id) {
|
FsNativeImage(FsImageDirectoryId id, bool ignore_read_only = true) : FsNative{ignore_read_only} {
|
||||||
m_open_result = fsOpenImageDirectoryFileSystem(&m_fs, id);
|
m_open_result = fsOpenImageDirectoryFileSystem(&m_fs, id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FsNativeContentStorage final : FsNative {
|
struct FsNativeContentStorage final : FsNative {
|
||||||
FsNativeContentStorage(FsContentStorageId id) {
|
FsNativeContentStorage(FsContentStorageId id, bool ignore_read_only = true) : FsNative{ignore_read_only} {
|
||||||
m_open_result = fsOpenContentStorageFileSystem(&m_fs, id);
|
m_open_result = fsOpenContentStorageFileSystem(&m_fs, id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// auto file_exists(const FsPath& path) -> bool;
|
|
||||||
// auto create_file(const FsPath& path, u64 size = 0) -> Result;
|
|
||||||
// auto delete_file(const FsPath& path) -> Result;
|
|
||||||
// auto create_directory(const FsPath& path) -> Result;
|
|
||||||
// auto create_directory_recursively(const FsPath& path) -> Result;
|
|
||||||
// auto delete_directory(const FsPath& path) -> Result;
|
|
||||||
// auto delete_directory_recursively(const FsPath& path) -> Result;
|
|
||||||
// auto rename_file(const FsPath& src, const FsPath& dst) -> Result;
|
|
||||||
// auto rename_directory(const FsPath& src, const FsPath& dst) -> Result;
|
|
||||||
|
|
||||||
// auto read_entire_file(const FsPath& path, std::vector<u8>& out) -> Result;
|
|
||||||
// auto write_entire_file(const FsPath& path, const std::vector<u8>& in) -> Result;
|
|
||||||
// // single threaded one shot copy, only use for very small files!
|
|
||||||
// auto copy_entire_file(const FsPath& dst, const FsPath& src) -> Result;
|
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
|
|||||||
@@ -256,10 +256,7 @@ private:
|
|||||||
option::OptionBool m_show_hidden{INI_SECTION, "show_hidden", false};
|
option::OptionBool m_show_hidden{INI_SECTION, "show_hidden", false};
|
||||||
option::OptionBool m_folders_first{INI_SECTION, "folders_first", true};
|
option::OptionBool m_folders_first{INI_SECTION, "folders_first", true};
|
||||||
option::OptionBool m_hidden_last{INI_SECTION, "hidden_last", false};
|
option::OptionBool m_hidden_last{INI_SECTION, "hidden_last", false};
|
||||||
|
option::OptionBool m_ignore_read_only{INI_SECTION, "ignore_read_only", false};
|
||||||
option::OptionBool m_search_show_files{INI_SECTION, "search_show_files", true};
|
|
||||||
option::OptionBool m_search_show_folders{INI_SECTION, "search_show_folders", true};
|
|
||||||
option::OptionBool m_search_recursive{INI_SECTION, "search_recursive", false};
|
|
||||||
|
|
||||||
bool m_loaded_assoc_entries{};
|
bool m_loaded_assoc_entries{};
|
||||||
bool m_is_update_folder{};
|
bool m_is_update_folder{};
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ void App::SetReplaceHbmenuEnable(bool enable) {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) {
|
if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) {
|
||||||
if (std::strcmp(sphaira_nacp.display_version, hbmenu_nacp.display_version) < 0) {
|
if (std::strcmp(sphaira_nacp.display_version, hbmenu_nacp.display_version) < 0) {
|
||||||
if (R_FAILED(rc = fs.copy_entire_file(sphaira_path, "/hbmenu.nro", true))) {
|
if (R_FAILED(rc = fs.copy_entire_file(sphaira_path, "/hbmenu.nro"))) {
|
||||||
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path, rc, R_MODULE(rc), R_DESCRIPTION(rc));
|
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path, rc, R_MODULE(rc), R_DESCRIPTION(rc));
|
||||||
} else {
|
} else {
|
||||||
log_write("success with updating hbmenu!\n");
|
log_write("success with updating hbmenu!\n");
|
||||||
@@ -530,13 +530,13 @@ void App::SetReplaceHbmenuEnable(bool enable) {
|
|||||||
// sphaira doesn't yet exist, create a new file.
|
// sphaira doesn't yet exist, create a new file.
|
||||||
sphaira_path = "/switch/sphaira/sphaira.nro";
|
sphaira_path = "/switch/sphaira/sphaira.nro";
|
||||||
fs.CreateDirectoryRecursively("/switch/sphaira/");
|
fs.CreateDirectoryRecursively("/switch/sphaira/");
|
||||||
fs.copy_entire_file(sphaira_path, "/hbmenu.nro", true);
|
fs.copy_entire_file(sphaira_path, "/hbmenu.nro");
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should never fail, if it does, well then the sd card is fucked.
|
// this should never fail, if it does, well then the sd card is fucked.
|
||||||
if (R_FAILED(rc = fs.copy_entire_file("/hbmenu.nro", "/switch/hbmenu.nro", true))) {
|
if (R_FAILED(rc = fs.copy_entire_file("/hbmenu.nro", "/switch/hbmenu.nro"))) {
|
||||||
// try and restore sphaira in a last ditch effort.
|
// try and restore sphaira in a last ditch effort.
|
||||||
if (R_FAILED(rc = fs.copy_entire_file("/hbmenu.nro", sphaira_path, true))) {
|
if (R_FAILED(rc = fs.copy_entire_file("/hbmenu.nro", sphaira_path))) {
|
||||||
App::Push(std::make_shared<ui::ErrorBox>(rc,
|
App::Push(std::make_shared<ui::ErrorBox>(rc,
|
||||||
"Failed to restore hbmenu, please re-download hbmenu"_i18n
|
"Failed to restore hbmenu, please re-download hbmenu"_i18n
|
||||||
));
|
));
|
||||||
@@ -550,7 +550,7 @@ void App::SetReplaceHbmenuEnable(bool enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't need this any more.
|
// don't need this any more.
|
||||||
fs.DeleteFile("/switch/hbmenu.nro", true);
|
fs.DeleteFile("/switch/hbmenu.nro");
|
||||||
|
|
||||||
// if we were hbmenu, exit now (as romfs is gone).
|
// if we were hbmenu, exit now (as romfs is gone).
|
||||||
if (IsHbmenu()) {
|
if (IsHbmenu()) {
|
||||||
@@ -1260,14 +1260,14 @@ App::~App() {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc = nro_get_nacp("/hbmenu.nro", hbmenu_nacp)) && std::strcmp(hbmenu_nacp.lang[0].name, "sphaira")) {
|
if (R_SUCCEEDED(rc = nro_get_nacp("/hbmenu.nro", hbmenu_nacp)) && std::strcmp(hbmenu_nacp.lang[0].name, "sphaira")) {
|
||||||
log_write("backing up hbmenu.nro\n");
|
log_write("backing up hbmenu.nro\n");
|
||||||
if (R_FAILED(rc = fs.copy_entire_file("/switch/hbmenu.nro", "/hbmenu.nro", true))) {
|
if (R_FAILED(rc = fs.copy_entire_file("/switch/hbmenu.nro", "/hbmenu.nro"))) {
|
||||||
log_write("failed to backup hbmenu.nro\n");
|
log_write("failed to backup hbmenu.nro\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_write("not backing up\n");
|
log_write("not backing up\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc = fs.copy_entire_file("/hbmenu.nro", GetExePath(), true))) {
|
if (R_FAILED(rc = fs.copy_entire_file("/hbmenu.nro", GetExePath()))) {
|
||||||
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", GetExePath(), rc, R_MODULE(rc), R_DESCRIPTION(rc));
|
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", GetExePath(), rc, R_MODULE(rc), R_DESCRIPTION(rc));
|
||||||
} else {
|
} else {
|
||||||
log_write("success with copying over root file!\n");
|
log_write("success with copying over root file!\n");
|
||||||
@@ -1292,7 +1292,7 @@ App::~App() {
|
|||||||
// found sphaira, now lets get compare version
|
// found sphaira, now lets get compare version
|
||||||
if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) {
|
if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) {
|
||||||
if (std::strcmp(hbmenu_nacp.display_version, sphaira_nacp.display_version) < 0) {
|
if (std::strcmp(hbmenu_nacp.display_version, sphaira_nacp.display_version) < 0) {
|
||||||
if (R_FAILED(rc = fs.copy_entire_file(GetExePath(), sphaira_path, true))) {
|
if (R_FAILED(rc = fs.copy_entire_file(GetExePath(), sphaira_path))) {
|
||||||
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path, rc, R_MODULE(rc), R_DESCRIPTION(rc));
|
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path, rc, R_MODULE(rc), R_DESCRIPTION(rc));
|
||||||
} else {
|
} else {
|
||||||
log_write("success with updating hbmenu!\n");
|
log_write("success with updating hbmenu!\n");
|
||||||
|
|||||||
@@ -454,9 +454,9 @@ auto DownloadInternal(CURL* curl, const Api& e) -> ApiResult {
|
|||||||
|
|
||||||
if (has_file) {
|
if (has_file) {
|
||||||
GetDownloadTempPath(tmp_buf);
|
GetDownloadTempPath(tmp_buf);
|
||||||
fs.CreateDirectoryRecursivelyWithPath(tmp_buf, true);
|
fs.CreateDirectoryRecursivelyWithPath(tmp_buf);
|
||||||
|
|
||||||
if (auto rc = fs.CreateFile(tmp_buf, 0, 0, true); R_FAILED(rc) && rc != FsError_PathAlreadyExists) {
|
if (auto rc = fs.CreateFile(tmp_buf, 0, 0); R_FAILED(rc) && rc != FsError_PathAlreadyExists) {
|
||||||
log_write("failed to create file: %s\n", tmp_buf);
|
log_write("failed to create file: %s\n", tmp_buf);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -537,7 +537,7 @@ auto DownloadInternal(CURL* curl, const Api& e) -> ApiResult {
|
|||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||||
|
|
||||||
if (has_file) {
|
if (has_file) {
|
||||||
ON_SCOPE_EXIT( fs.DeleteFile(tmp_buf, true) );
|
ON_SCOPE_EXIT( fs.DeleteFile(tmp_buf) );
|
||||||
if (res == CURLE_OK && chunk.offset) {
|
if (res == CURLE_OK && chunk.offset) {
|
||||||
fsFileWrite(&chunk.f, chunk.file_offset, chunk.data.data(), chunk.offset, FsWriteOption_None);
|
fsFileWrite(&chunk.f, chunk.file_offset, chunk.data.data(), chunk.offset, FsWriteOption_None);
|
||||||
}
|
}
|
||||||
@@ -553,9 +553,9 @@ auto DownloadInternal(CURL* curl, const Api& e) -> ApiResult {
|
|||||||
g_cache.set(e.m_path, header_out);
|
g_cache.set(e.m_path, header_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.DeleteFile(e.m_path, true);
|
fs.DeleteFile(e.m_path);
|
||||||
fs.CreateDirectoryRecursivelyWithPath(e.m_path, true);
|
fs.CreateDirectoryRecursivelyWithPath(e.m_path);
|
||||||
if (R_FAILED(fs.RenameFile(tmp_buf, e.m_path, true))) {
|
if (R_FAILED(fs.RenameFile(tmp_buf, e.m_path))) {
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,10 +248,10 @@ Result read_entire_file(FsFileSystem* _fs, const FsPath& path, std::vector<u8>&
|
|||||||
Result write_entire_file(FsFileSystem* _fs, const FsPath& path, const std::vector<u8>& in, bool ignore_read_only) {
|
Result write_entire_file(FsFileSystem* _fs, const FsPath& path, const std::vector<u8>& in, bool ignore_read_only) {
|
||||||
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
R_UNLESS(ignore_read_only || !is_read_only(path), Fs::ResultReadOnly);
|
||||||
|
|
||||||
FsNative fs{_fs, false};
|
FsNative fs{_fs, false, ignore_read_only};
|
||||||
R_TRY(fs.GetFsOpenResult());
|
R_TRY(fs.GetFsOpenResult());
|
||||||
|
|
||||||
if (auto rc = fs.CreateFile(path, in.size(), 0, ignore_read_only); R_FAILED(rc) && rc != FsError_PathAlreadyExists) {
|
if (auto rc = fs.CreateFile(path, in.size(), 0); R_FAILED(rc) && rc != FsError_PathAlreadyExists) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -522,10 +522,10 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create directories
|
// create directories
|
||||||
fs.CreateDirectoryRecursivelyWithPath(output, true);
|
fs.CreateDirectoryRecursivelyWithPath(output);
|
||||||
|
|
||||||
Result rc;
|
Result rc;
|
||||||
if (R_FAILED(rc = fs.CreateFile(output, info.uncompressed_size, 0, true)) && rc != FsError_PathAlreadyExists) {
|
if (R_FAILED(rc = fs.CreateFile(output, info.uncompressed_size, 0)) && rc != FsError_PathAlreadyExists) {
|
||||||
log_write("failed to create file: %s 0x%04X\n", output, rc);
|
log_write("failed to create file: %s 0x%04X\n", output, rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -614,7 +614,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> bool {
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
const auto safe_buf = fs::AppendPath("/", old_entry.path);
|
const auto safe_buf = fs::AppendPath("/", old_entry.path);
|
||||||
// std::strcat(safe_buf, old_entry.path);
|
// std::strcat(safe_buf, old_entry.path);
|
||||||
if (R_FAILED(fs.DeleteFile(safe_buf, true))) {
|
if (R_FAILED(fs.DeleteFile(safe_buf))) {
|
||||||
log_write("failed to delete: %s\n", safe_buf);
|
log_write("failed to delete: %s\n", safe_buf);
|
||||||
} else {
|
} else {
|
||||||
log_write("deleted file: %s\n", safe_buf);
|
log_write("deleted file: %s\n", safe_buf);
|
||||||
|
|||||||
@@ -533,11 +533,16 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i1
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options->Add(std::make_shared<SidebarEntryBool>("Ignore read only"_i18n, m_ignore_read_only.Get(), [this](bool& v_out){
|
||||||
|
m_ignore_read_only.Set(v_out);
|
||||||
|
m_fs->SetIgnoreReadOnly(v_out);
|
||||||
|
}, "Yes"_i18n, "No"_i18n));
|
||||||
}));
|
}));
|
||||||
}})
|
}})
|
||||||
);
|
);
|
||||||
|
|
||||||
m_fs = std::make_unique<fs::FsNativeSd>();
|
m_fs = std::make_unique<fs::FsNativeSd>(m_ignore_read_only.Get());
|
||||||
fs::FsPath buf;
|
fs::FsPath buf;
|
||||||
ini_gets("paths", "last_path", "/", buf, sizeof(buf), App::CONFIG_PATH);
|
ini_gets("paths", "last_path", "/", buf, sizeof(buf), App::CONFIG_PATH);
|
||||||
m_path = buf;
|
m_path = buf;
|
||||||
|
|||||||
@@ -154,17 +154,17 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry
|
|||||||
|
|
||||||
Result rc;
|
Result rc;
|
||||||
if (file_path[strlen(file_path) -1] == '/') {
|
if (file_path[strlen(file_path) -1] == '/') {
|
||||||
if (R_FAILED(rc = fs.CreateDirectoryRecursively(file_path, true)) && rc != FsError_PathAlreadyExists) {
|
if (R_FAILED(rc = fs.CreateDirectoryRecursively(file_path)) && rc != FsError_PathAlreadyExists) {
|
||||||
log_write("failed to create folder: %s 0x%04X\n", file_path, rc);
|
log_write("failed to create folder: %s 0x%04X\n", file_path, rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (R_FAILED(rc = fs.CreateDirectoryRecursivelyWithPath(file_path, true)) && rc != FsError_PathAlreadyExists) {
|
if (R_FAILED(rc = fs.CreateDirectoryRecursivelyWithPath(file_path)) && rc != FsError_PathAlreadyExists) {
|
||||||
log_write("failed to create folder: %s 0x%04X\n", file_path, rc);
|
log_write("failed to create folder: %s 0x%04X\n", file_path, rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0, true)) && rc != FsError_PathAlreadyExists) {
|
if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0)) && rc != FsError_PathAlreadyExists) {
|
||||||
log_write("failed to create file: %s 0x%04X\n", file_path, rc);
|
log_write("failed to create file: %s 0x%04X\n", file_path, rc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -201,9 +201,9 @@ auto DownloadApp(ProgressBox* pbox, const GhApiAsset& gh_asset, const AssetEntry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs.CreateDirectoryRecursivelyWithPath(root_path, true);
|
fs.CreateDirectoryRecursivelyWithPath(root_path);
|
||||||
fs.DeleteFile(root_path);
|
fs.DeleteFile(root_path);
|
||||||
if (R_FAILED(fs.RenameFile(temp_file, root_path, true))) {
|
if (R_FAILED(fs.RenameFile(temp_file, root_path))) {
|
||||||
log_write("failed to rename file: %s -> %s\n", temp_file.s, root_path.s);
|
log_write("failed to rename file: %s -> %s\n", temp_file.s, root_path.s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user