From 95b34f8081e26cfe75d63a853d1626fdd5b636e6 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 28 Dec 2015 10:17:06 -0500 Subject: [PATCH] HLE/FS: Return the proper error codes when opening files. --- src/core/file_sys/archive_backend.h | 4 +-- src/core/file_sys/disk_archive.cpp | 44 +++++++++++++++++++---------- src/core/file_sys/disk_archive.h | 4 +-- src/core/file_sys/file_backend.h | 4 +-- src/core/file_sys/ivfc_archive.cpp | 4 +-- src/core/file_sys/ivfc_archive.h | 4 +-- src/core/hle/service/fs/archive.cpp | 7 +++-- 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index c5da9bd6f..60108b4b0 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -76,9 +76,9 @@ public: * Open a file specified by its path, using the specified mode * @param path Path relative to the archive * @param mode Mode to open the file with - * @return Opened file, or nullptr + * @return Opened file, or error code */ - virtual std::unique_ptr OpenFile(const Path& path, const Mode mode) const = 0; + virtual ResultVal> OpenFile(const Path& path, const Mode mode) const = 0; /** * Delete a file specified by its path diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 2dca895fd..8e4ea01c5 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -17,12 +17,13 @@ namespace FileSys { -std::unique_ptr DiskArchive::OpenFile(const Path& path, const Mode mode) const { +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 = Common::make_unique(*this, path, mode); - if (!file->Open()) - return nullptr; - return std::move(file); + ResultCode result = file->Open(); + if (result.IsError()) + return result; + return MakeResult>(std::move(file)); } ResultCode DiskArchive::DeleteFile(const Path& path) const { @@ -103,25 +104,38 @@ DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode this->mode.hex = mode.hex; } -bool DiskFile::Open() { - if (!mode.create_flag && !FileUtil::Exists(path)) { - LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str()); - return false; +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); } - std::string mode_string; - if (mode.create_flag) - mode_string = "w+"; - else if (mode.write_flag) - mode_string = "r+"; // Files opened with Write access can be read from + 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"; + mode_string += "r"; // Open the file in binary mode, to avoid problems with CR/LF on Windows systems mode_string += "b"; file = Common::make_unique(path, mode_string.c_str()); - return file->IsOpen(); + 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 { diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 96d86ad21..b4cc2f702 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -33,7 +33,7 @@ public: virtual std::string GetName() const override { return "DiskArchive: " + mount_point; } - std::unique_ptr OpenFile(const Path& path, const Mode mode) const override; + ResultVal> OpenFile(const Path& path, const Mode mode) const override; ResultCode DeleteFile(const Path& path) const override; bool RenameFile(const Path& src_path, const Path& dest_path) const override; bool DeleteDirectory(const Path& path) const override; @@ -54,7 +54,7 @@ class DiskFile : public FileBackend { public: DiskFile(const DiskArchive& archive, const Path& path, const Mode mode); - bool Open() override; + ResultCode Open() override; ResultVal Read(u64 offset, size_t length, u8* buffer) const override; ResultVal Write(u64 offset, size_t length, bool flush, const u8* buffer) const override; u64 GetSize() const override; diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index 21864a73c..9137bbbad 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -21,9 +21,9 @@ public: /** * Open the file - * @return true if the file opened correctly + * @return Result of the file operation */ - virtual bool Open() = 0; + virtual ResultCode Open() = 0; /** * Read data from the file diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index e7b37e09d..a8e9a72ef 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -20,8 +20,8 @@ std::string IVFCArchive::GetName() const { return "IVFC"; } -std::unique_ptr IVFCArchive::OpenFile(const Path& path, const Mode mode) const { - return Common::make_unique(romfs_file, data_offset, data_size); +ResultVal> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { + return MakeResult>(Common::make_unique(romfs_file, data_offset, data_size)); } ResultCode IVFCArchive::DeleteFile(const Path& path) const { diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index acc7e60f5..19d32dcca 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -34,7 +34,7 @@ public: std::string GetName() const override; - std::unique_ptr OpenFile(const Path& path, const Mode mode) const override; + ResultVal> OpenFile(const Path& path, const Mode mode) const override; ResultCode DeleteFile(const Path& path) const override; bool RenameFile(const Path& src_path, const Path& dest_path) const override; bool DeleteDirectory(const Path& path) const override; @@ -55,7 +55,7 @@ public: IVFCFile(std::shared_ptr file, u64 offset, u64 size) : romfs_file(file), data_offset(offset), data_size(size) {} - bool Open() override { return true; } + ResultCode Open() override { return RESULT_SUCCESS; } ResultVal Read(u64 offset, size_t length, u8* buffer) const override; ResultVal Write(u64 offset, size_t length, bool flush, const u8* buffer) const override; u64 GetSize() const override; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 0c56777cf..2ce5f0fe7 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -307,13 +307,14 @@ ResultVal> OpenFileFromArchive(ArchiveHandle archive_han if (archive == nullptr) return ERR_INVALID_HANDLE; - std::unique_ptr backend = archive->OpenFile(path, mode); - if (backend == nullptr) { + auto backend = archive->OpenFile(path, mode); + if (backend.Failed()) { + return backend.Code(); return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); } - auto file = Kernel::SharedPtr(new File(std::move(backend), path)); + auto file = Kernel::SharedPtr(new File(backend.MoveFrom(), path)); return MakeResult>(std::move(file)); }