From 4dd8a831bd5ea32108db837754289ab42a2fa6ca Mon Sep 17 00:00:00 2001 From: wwylele Date: Fri, 14 Oct 2016 15:29:09 +0800 Subject: FileSys: make Archive interfaces return error code and make the mode parameter a reference since it is a BitField union --- src/core/file_sys/disk_archive.cpp | 50 +++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 14 deletions(-) (limited to 'src/core/file_sys/disk_archive.cpp') diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 2f05af361..ce6b9360b 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -16,7 +16,7 @@ namespace FileSys { ResultVal> DiskArchive::OpenFile(const Path& path, - const Mode mode) const { + const Mode& mode) const { LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); auto file = std::make_unique(*this, path, mode); ResultCode result = file->Open(); @@ -43,16 +43,28 @@ ResultCode DiskArchive::DeleteFile(const Path& path) const { ErrorLevel::Status); } -bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { - return FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString()); +ResultCode DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { + if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) + return RESULT_SUCCESS; + + // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't + // exist or similar. Verify. + return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description + ErrorSummary::NothingHappened, ErrorLevel::Status); } -bool DiskArchive::DeleteDirectory(const Path& path) const { - return FileUtil::DeleteDir(mount_point + path.AsString()); +ResultCode DiskArchive::DeleteDirectory(const Path& path) const { + if (FileUtil::DeleteDir(mount_point + path.AsString())) + return RESULT_SUCCESS; + return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description + ErrorSummary::Canceled, ErrorLevel::Status); } -bool DiskArchive::DeleteDirectoryRecursively(const Path& path) const { - return FileUtil::DeleteDirRecursively(mount_point + path.AsString()); +ResultCode DiskArchive::DeleteDirectoryRecursively(const Path& path) const { + if (FileUtil::DeleteDirRecursively(mount_point + path.AsString())) + return RESULT_SUCCESS; + return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description + ErrorSummary::Canceled, ErrorLevel::Status); } ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const { @@ -81,20 +93,30 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const { ErrorLevel::Info); } -bool DiskArchive::CreateDirectory(const Path& path) const { - return FileUtil::CreateDir(mount_point + path.AsString()); +ResultCode DiskArchive::CreateDirectory(const Path& path) const { + if (FileUtil::CreateDir(mount_point + path.AsString())) + return RESULT_SUCCESS; + return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description + ErrorSummary::Canceled, ErrorLevel::Status); } -bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { - return FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString()); +ResultCode DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { + if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) + return RESULT_SUCCESS; + + // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't + // exist or similar. Verify. + return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description + ErrorSummary::NothingHappened, ErrorLevel::Status); } -std::unique_ptr DiskArchive::OpenDirectory(const Path& path) const { +ResultVal> DiskArchive::OpenDirectory(const Path& path) const { LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); auto directory = std::make_unique(*this, path); if (!directory->Open()) - return nullptr; - return std::move(directory); + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Permanent); + return MakeResult>(std::move(directory)); } u64 DiskArchive::GetFreeBytes() const { -- cgit v1.2.3 From 0e754875d175bfec393a3f4c4f6ad73f45ed361f Mon Sep 17 00:00:00 2001 From: wwylele Date: Sun, 16 Oct 2016 23:09:36 +0800 Subject: FileSys: remove Open from DirectoryBackend Open should not be an interface exposed by Directory because it is the Archive thats implement the methed to open the directory. The service API of 3DS also implies this - Open is not a function of directory service, but is of FS main service --- src/core/file_sys/disk_archive.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'src/core/file_sys/disk_archive.cpp') diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index ce6b9360b..fef6e68a2 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -112,10 +112,11 @@ ResultCode DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_p ResultVal> DiskArchive::OpenDirectory(const Path& path) const { LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); - auto directory = std::make_unique(*this, path); - if (!directory->Open()) + auto full_path = mount_point + path.AsString(); + if (!FileUtil::IsDirectory(full_path)) return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); + auto directory = std::make_unique(full_path); return MakeResult>(std::move(directory)); } @@ -211,21 +212,11 @@ bool DiskFile::Close() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) : directory() { - // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass - // the root directory we set while opening the archive. - // For example, opening /../../usr/bin can give the emulated program your installed programs. - this->path = archive.mount_point + path.AsString(); -} - -bool DiskDirectory::Open() { - if (!FileUtil::IsDirectory(path)) - return false; +DiskDirectory::DiskDirectory(const std::string& path) : directory() { unsigned size = FileUtil::ScanDirectoryTree(path, directory); directory.size = size; directory.isDirectory = true; children_iterator = directory.children.begin(); - return true; } u32 DiskDirectory::Read(const u32 count, Entry* entries) { -- cgit v1.2.3 From 9a0405858a5602a5e1e112b131ecdd8ca27e6d10 Mon Sep 17 00:00:00 2001 From: wwylele Date: Mon, 17 Oct 2016 10:10:23 +0800 Subject: FileSys: remove Open from FileBackend Same as directory, file shouldn't expose Open either. --- src/core/file_sys/disk_archive.cpp | 92 +++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 52 deletions(-) (limited to 'src/core/file_sys/disk_archive.cpp') diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index fef6e68a2..43d199434 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -18,11 +18,46 @@ namespace FileSys { ResultVal> DiskArchive::OpenFile(const Path& path, const Mode& mode) const { LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); - auto file = std::make_unique(*this, path, mode); - ResultCode result = file->Open(); - if (result.IsError()) - return result; - return MakeResult>(std::move(file)); + + auto full_path = mount_point + path.AsString(); + if (FileUtil::IsDirectory(full_path)) + return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, + ErrorLevel::Status); + + // Specifying only the Create flag is invalid + if (mode.create_flag && !mode.read_flag && !mode.write_flag) { + return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, + ErrorSummary::Canceled, ErrorLevel::Status); + } + + if (!FileUtil::Exists(full_path)) { + if (!mode.create_flag) { + LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", + full_path.c_str()); + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, + ErrorSummary::NotFound, ErrorLevel::Status); + } else { + // Create the file + FileUtil::CreateEmptyFile(full_path); + } + } + + std::string mode_string = ""; + if (mode.write_flag) + mode_string += "r+"; // Files opened with Write access can be read from + else if (mode.read_flag) + mode_string += "r"; + + // Open the file in binary mode, to avoid problems with CR/LF on Windows systems + mode_string += "b"; + + FileUtil::IOFile file(full_path, mode_string.c_str()); + if (!file.IsOpen()) + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Status); + + auto disk_file = std::make_unique(std::move(file), mode); + return MakeResult>(std::move(disk_file)); } ResultCode DiskArchive::DeleteFile(const Path& path) const { @@ -127,53 +162,6 @@ u64 DiskArchive::GetFreeBytes() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode) { - // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass - // the root directory we set while opening the archive. - // For example, opening /../../etc/passwd can give the emulated program your users list. - this->path = archive.mount_point + path.AsString(); - this->mode.hex = mode.hex; -} - -ResultCode DiskFile::Open() { - if (FileUtil::IsDirectory(path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, - ErrorLevel::Status); - - // Specifying only the Create flag is invalid - if (mode.create_flag && !mode.read_flag && !mode.write_flag) { - return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, - ErrorSummary::Canceled, ErrorLevel::Status); - } - - if (!FileUtil::Exists(path)) { - if (!mode.create_flag) { - LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", - path.c_str()); - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Status); - } else { - // Create the file - FileUtil::CreateEmptyFile(path); - } - } - - std::string mode_string = ""; - if (mode.write_flag) - mode_string += "r+"; // Files opened with Write access can be read from - else if (mode.read_flag) - mode_string += "r"; - - // Open the file in binary mode, to avoid problems with CR/LF on Windows systems - mode_string += "b"; - - file = std::make_unique(path, mode_string.c_str()); - if (file->IsOpen()) - return RESULT_SUCCESS; - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, - ErrorLevel::Status); -} - ResultVal DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const { if (!mode.read_flag && !mode.write_flag) return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, -- cgit v1.2.3 From 0647f866498412f22999966cc97b122db2ef9318 Mon Sep 17 00:00:00 2001 From: wwylele Date: Thu, 20 Oct 2016 11:45:01 +0800 Subject: FileSys: w->rw permission lift only happens in SDMC archive --- src/core/file_sys/disk_archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/file_sys/disk_archive.cpp') diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 43d199434..0e51fd1a6 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -163,7 +163,7 @@ u64 DiskArchive::GetFreeBytes() const { //////////////////////////////////////////////////////////////////////////////////////////////////// ResultVal DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const { - if (!mode.read_flag && !mode.write_flag) + if (!mode.read_flag) return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); -- cgit v1.2.3 From f775a3781bde276707b27ec220f4c7ca18062767 Mon Sep 17 00:00:00 2001 From: wwylele Date: Wed, 19 Oct 2016 21:42:47 +0800 Subject: FileSys: remove unused DiskArchive All "subclasses" of DiskArchive are splitted out. This class is useless --- src/core/file_sys/disk_archive.cpp | 147 ------------------------------------- 1 file changed, 147 deletions(-) (limited to 'src/core/file_sys/disk_archive.cpp') diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 0e51fd1a6..a243d9a13 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -15,153 +15,6 @@ namespace FileSys { -ResultVal> DiskArchive::OpenFile(const Path& path, - const Mode& mode) const { - LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); - - auto full_path = mount_point + path.AsString(); - if (FileUtil::IsDirectory(full_path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, - ErrorLevel::Status); - - // Specifying only the Create flag is invalid - if (mode.create_flag && !mode.read_flag && !mode.write_flag) { - return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, - ErrorSummary::Canceled, ErrorLevel::Status); - } - - if (!FileUtil::Exists(full_path)) { - if (!mode.create_flag) { - LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", - full_path.c_str()); - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Status); - } else { - // Create the file - FileUtil::CreateEmptyFile(full_path); - } - } - - std::string mode_string = ""; - if (mode.write_flag) - mode_string += "r+"; // Files opened with Write access can be read from - else if (mode.read_flag) - mode_string += "r"; - - // Open the file in binary mode, to avoid problems with CR/LF on Windows systems - mode_string += "b"; - - FileUtil::IOFile file(full_path, mode_string.c_str()); - if (!file.IsOpen()) - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, - ErrorLevel::Status); - - auto disk_file = std::make_unique(std::move(file), mode); - return MakeResult>(std::move(disk_file)); -} - -ResultCode DiskArchive::DeleteFile(const Path& path) const { - std::string file_path = mount_point + path.AsString(); - - if (FileUtil::IsDirectory(file_path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, - ErrorLevel::Status); - - if (!FileUtil::Exists(file_path)) - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, - ErrorLevel::Status); - - if (FileUtil::Delete(file_path)) - return RESULT_SUCCESS; - - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, - ErrorLevel::Status); -} - -ResultCode DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { - if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) - return RESULT_SUCCESS; - - // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't - // exist or similar. Verify. - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description - ErrorSummary::NothingHappened, ErrorLevel::Status); -} - -ResultCode DiskArchive::DeleteDirectory(const Path& path) const { - if (FileUtil::DeleteDir(mount_point + path.AsString())) - return RESULT_SUCCESS; - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description - ErrorSummary::Canceled, ErrorLevel::Status); -} - -ResultCode DiskArchive::DeleteDirectoryRecursively(const Path& path) const { - if (FileUtil::DeleteDirRecursively(mount_point + path.AsString())) - return RESULT_SUCCESS; - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description - ErrorSummary::Canceled, ErrorLevel::Status); -} - -ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const { - std::string full_path = mount_point + path.AsString(); - - if (FileUtil::IsDirectory(full_path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, - ErrorLevel::Status); - - if (FileUtil::Exists(full_path)) - return ResultCode(ErrorDescription::FS_AlreadyExists, ErrorModule::FS, - ErrorSummary::NothingHappened, ErrorLevel::Status); - - if (size == 0) { - FileUtil::CreateEmptyFile(full_path); - return RESULT_SUCCESS; - } - - FileUtil::IOFile file(full_path, "wb"); - // Creates a sparse file (or a normal file on filesystems without the concept of sparse files) - // We do this by seeking to the right size, then writing a single null byte. - if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1) - return RESULT_SUCCESS; - - return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource, - ErrorLevel::Info); -} - -ResultCode DiskArchive::CreateDirectory(const Path& path) const { - if (FileUtil::CreateDir(mount_point + path.AsString())) - return RESULT_SUCCESS; - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description - ErrorSummary::Canceled, ErrorLevel::Status); -} - -ResultCode DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { - if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) - return RESULT_SUCCESS; - - // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't - // exist or similar. Verify. - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description - ErrorSummary::NothingHappened, ErrorLevel::Status); -} - -ResultVal> DiskArchive::OpenDirectory(const Path& path) const { - LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); - auto full_path = mount_point + path.AsString(); - if (!FileUtil::IsDirectory(full_path)) - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, - ErrorLevel::Permanent); - auto directory = std::make_unique(full_path); - return MakeResult>(std::move(directory)); -} - -u64 DiskArchive::GetFreeBytes() const { - // TODO: Stubbed to return 1GiB - return 1024 * 1024 * 1024; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - ResultVal DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const { if (!mode.read_flag) return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, -- cgit v1.2.3