From b93da4401074b63c4dd87ddf4bfaf59cc92cf504 Mon Sep 17 00:00:00 2001 From: condut Date: Fri, 10 Jul 2015 00:55:23 +0300 Subject: [PATCH 1/4] . (Will git move this to the right place?) --- src/core/file_sys/archive_romfs.cpp | 7 +++---- src/core/file_sys/archive_romfs.h | 4 +++- src/core/file_sys/archive_savedatacheck.cpp | 11 ++++------- src/core/file_sys/ivfc_archive.cpp | 13 ++++++------- src/core/file_sys/ivfc_archive.h | 14 ++++++++++---- src/core/loader/loader.cpp | 2 +- src/core/loader/loader.h | 7 +++++-- src/core/loader/ncch.cpp | 14 +++++++++----- src/core/loader/ncch.h | 7 +++++-- 9 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index d4a12ed10..99af0ffcc 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -16,16 +16,15 @@ namespace FileSys { -ArchiveFactory_RomFS::ArchiveFactory_RomFS(const Loader::AppLoader& app_loader) - : romfs_data(std::make_shared>()) { +ArchiveFactory_RomFS::ArchiveFactory_RomFS(const Loader::AppLoader& app_loader) { // Load the RomFS from the app - if (Loader::ResultStatus::Success != app_loader.ReadRomFS(*romfs_data)) { + if (Loader::ResultStatus::Success != app_loader.ReadRomFS (m_romfs_file, m_offset, m_size)) { LOG_ERROR(Service_FS, "Unable to read RomFS!"); } } ResultVal> ArchiveFactory_RomFS::Open(const Path& path) { - auto archive = Common::make_unique(romfs_data); + auto archive = Common::make_unique(m_romfs_file, m_offset, m_size); return MakeResult>(std::move(archive)); } diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 409bc670a..ea6490330 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -27,7 +27,9 @@ public: ResultCode Format(const Path& path) override; private: - std::shared_ptr> romfs_data; + std::shared_ptr m_romfs_file; + u64 m_offset; + u64 m_size; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index e7e4fbf1d..00cd1bfad 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -31,17 +31,14 @@ ResultVal> ArchiveFactory_SaveDataCheck::Open(co auto vec = path.AsBinary(); const u32* data = reinterpret_cast(vec.data()); std::string file_path = GetSaveDataCheckPath(mount_point, data[1], data[0]); - FileUtil::IOFile file(file_path, "rb"); + auto file = std::make_shared(file_path, "rb"); - if (!file.IsOpen()) { + if (!file->IsOpen()) { return ResultCode(-1); // TODO(Subv): Find the right error code } - auto size = file.GetSize(); - auto raw_data = std::make_shared>(size); - file.ReadBytes(raw_data->data(), size); - file.Close(); + auto size = file->GetSize(); - auto archive = Common::make_unique(std::move(raw_data)); + auto archive = Common::make_unique(file, 0, size); return MakeResult>(std::move(archive)); } diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 2d2509d16..131285bc9 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -16,15 +16,12 @@ namespace FileSys { -IVFCArchive::IVFCArchive(std::shared_ptr> data) : data(data) { -} - std::string IVFCArchive::GetName() const { return "IVFC"; } std::unique_ptr IVFCArchive::OpenFile(const Path& path, const Mode mode) const { - return Common::make_unique(data); + return Common::make_unique(m_romfs_file, m_offset, m_size); } bool IVFCArchive::DeleteFile(const Path& path) const { @@ -66,8 +63,10 @@ std::unique_ptr IVFCArchive::OpenDirectory(const Path& path) c size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); - memcpy(buffer, data->data() + offset, length); - return length; + m_romfs_file->Seek(m_offset + offset, SEEK_SET); + u32 read_length = (u32) std::min((u64) length, m_size - offset); + + return m_romfs_file->ReadBytes(buffer, read_length); } size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { @@ -76,7 +75,7 @@ size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, cons } size_t IVFCFile::GetSize() const { - return sizeof(u8) * data->size(); + return sizeof(u8) * m_size; } bool IVFCFile::SetSize(const u64 size) const { diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 10415798d..f51766114 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -26,7 +26,8 @@ namespace FileSys { */ class IVFCArchive : public ArchiveBackend { public: - IVFCArchive(std::shared_ptr> data); + IVFCArchive(std::shared_ptr romfs_file, u64 offset, u64 size) + : m_romfs_file(romfs_file), m_offset(offset), m_size(size) {} std::string GetName() const override; @@ -40,12 +41,15 @@ public: std::unique_ptr OpenDirectory(const Path& path) const override; protected: - std::shared_ptr> data; + std::shared_ptr m_romfs_file; + u64 m_offset; + u64 m_size; }; class IVFCFile : public FileBackend { public: - IVFCFile(std::shared_ptr> data) : data(data) {} + IVFCFile(std::shared_ptr romfs_file, u64 offset, u64 size) + : m_romfs_file(romfs_file), m_offset(offset), m_size(size) {} bool Open() override { return true; } size_t Read(const u64 offset, const u32 length, u8* buffer) const override; @@ -56,7 +60,9 @@ public: void Flush() const override { } private: - std::shared_ptr> data; + std::shared_ptr m_romfs_file; + u64 m_offset; + u64 m_size; }; class IVFCDirectory : public DirectoryBackend { diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 8b14edf00..7030eb6d2 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -122,7 +122,7 @@ ResultStatus LoadFile(const std::string& filename) { case FileType::CXI: case FileType::CCI: { - AppLoader_NCCH app_loader(std::move(file)); + AppLoader_NCCH app_loader(std::move(file), filename); // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 87e16fb98..e439a86e0 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -93,10 +93,13 @@ public: /** * Get the RomFS of the application - * @param buffer Reference to buffer to store data + * Since the RomFS is huge, we return a file reference instead of copying to a buffer + * @param romfs_file The file containing the RomFS + * @param offset The offset the romfs begins on + * @param size The size of the romfs * @return ResultStatus result of function */ - virtual ResultStatus ReadRomFS(std::vector& buffer) const { + virtual ResultStatus ReadRomFS(std::shared_ptr& romfs_file, u64& offset, u64& size) const { return ResultStatus::ErrorNotImplemented; } diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 08993c4fa..8795b2c3b 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -275,7 +275,7 @@ ResultStatus AppLoader_NCCH::ReadLogo(std::vector& buffer) const { return LoadSectionExeFS("logo", buffer); } -ResultStatus AppLoader_NCCH::ReadRomFS(std::vector& buffer) const { +ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr& romfs_file, u64& offset, u64& size) const { if (!file->IsOpen()) return ResultStatus::Error; @@ -287,12 +287,16 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::vector& buffer) const { LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); - buffer.resize(romfs_size); - - file->Seek(romfs_offset, SEEK_SET); - if (file->ReadBytes(&buffer[0], romfs_size) != romfs_size) + if (file->GetSize () < romfs_offset + romfs_size) return ResultStatus::Error; + // We reopen the file, to avoid reuse of the file offset + romfs_file.reset(new FileUtil::IOFile(filepath, "rb")); + offset = romfs_offset; + size = romfs_size; + + if (!romfs_file->IsOpen()) + return ResultStatus::Error; return ResultStatus::Success; } LOG_DEBUG(Loader, "NCCH has no RomFS"); diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 29e39d2c0..0fe41390a 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -163,7 +163,8 @@ namespace Loader { /// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) class AppLoader_NCCH final : public AppLoader { public: - AppLoader_NCCH(std::unique_ptr&& file) : AppLoader(std::move(file)) { } + AppLoader_NCCH(std::unique_ptr&& file, std::string filepath) + : AppLoader(std::move(file)), filepath(filepath) { } /** * Returns the type of the file @@ -211,7 +212,7 @@ public: * @param buffer Reference to buffer to store data * @return ResultStatus result of function */ - ResultStatus ReadRomFS(std::vector& buffer) const override; + ResultStatus ReadRomFS(std::shared_ptr& romfs_file, u64& offset, u64& size) const override; private: @@ -244,6 +245,8 @@ private: NCCH_Header ncch_header; ExeFs_Header exefs_header; ExHeader_Header exheader_header; + + std::string filepath; }; } // namespace Loader From 2815f9668c98eafce504b4223ab9c48b6651903e Mon Sep 17 00:00:00 2001 From: condut Date: Fri, 10 Jul 2015 01:02:27 +0300 Subject: [PATCH 2/4] . --- src/core/file_sys/archive_romfs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 99af0ffcc..7ec9fa73d 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -18,7 +18,7 @@ namespace FileSys { ArchiveFactory_RomFS::ArchiveFactory_RomFS(const Loader::AppLoader& app_loader) { // Load the RomFS from the app - if (Loader::ResultStatus::Success != app_loader.ReadRomFS (m_romfs_file, m_offset, m_size)) { + if (Loader::ResultStatus::Success != app_loader.ReadRomFS(m_romfs_file, m_offset, m_size)) { LOG_ERROR(Service_FS, "Unable to read RomFS!"); } } From 3c06e9b8c8e7ecaaa9f0074ea388c7c8dc6277e7 Mon Sep 17 00:00:00 2001 From: condut Date: Fri, 10 Jul 2015 02:33:18 +0300 Subject: [PATCH 3/4] Update per PR comments. --- src/core/file_sys/archive_romfs.cpp | 4 ++-- src/core/file_sys/archive_romfs.h | 6 +++--- src/core/file_sys/ivfc_archive.cpp | 10 +++++----- src/core/file_sys/ivfc_archive.h | 20 ++++++++++---------- src/core/loader/loader.h | 2 +- src/core/loader/ncch.cpp | 7 ++++--- src/core/loader/ncch.h | 2 +- 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 7ec9fa73d..8e8ef5250 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -18,13 +18,13 @@ namespace FileSys { ArchiveFactory_RomFS::ArchiveFactory_RomFS(const Loader::AppLoader& app_loader) { // Load the RomFS from the app - if (Loader::ResultStatus::Success != app_loader.ReadRomFS(m_romfs_file, m_offset, m_size)) { + if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { LOG_ERROR(Service_FS, "Unable to read RomFS!"); } } ResultVal> ArchiveFactory_RomFS::Open(const Path& path) { - auto archive = Common::make_unique(m_romfs_file, m_offset, m_size); + auto archive = Common::make_unique(romfs_file, data_offset, data_size); return MakeResult>(std::move(archive)); } diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index ea6490330..01cef4733 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -27,9 +27,9 @@ public: ResultCode Format(const Path& path) override; private: - std::shared_ptr m_romfs_file; - u64 m_offset; - u64 m_size; + std::shared_ptr romfs_file; + u64 data_offset; + u64 data_size; }; } // namespace FileSys diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 131285bc9..c1cba699e 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -21,7 +21,7 @@ std::string IVFCArchive::GetName() const { } std::unique_ptr IVFCArchive::OpenFile(const Path& path, const Mode mode) const { - return Common::make_unique(m_romfs_file, m_offset, m_size); + return Common::make_unique(romfs_file, data_offset, data_size); } bool IVFCArchive::DeleteFile(const Path& path) const { @@ -63,10 +63,10 @@ std::unique_ptr IVFCArchive::OpenDirectory(const Path& path) c size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); - m_romfs_file->Seek(m_offset + offset, SEEK_SET); - u32 read_length = (u32) std::min((u64) length, m_size - offset); + romfs_file->Seek(data_offset + offset, SEEK_SET); + u32 read_length = (u32)std::min((u64)length, data_size - offset); - return m_romfs_file->ReadBytes(buffer, read_length); + return romfs_file->ReadBytes(buffer, read_length); } size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { @@ -75,7 +75,7 @@ size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, cons } size_t IVFCFile::GetSize() const { - return sizeof(u8) * m_size; + return sizeof(u8) * data_size; } bool IVFCFile::SetSize(const u64 size) const { diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index f51766114..15a59407d 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -26,8 +26,8 @@ namespace FileSys { */ class IVFCArchive : public ArchiveBackend { public: - IVFCArchive(std::shared_ptr romfs_file, u64 offset, u64 size) - : m_romfs_file(romfs_file), m_offset(offset), m_size(size) {} + IVFCArchive(std::shared_ptr file, u64 offset, u64 size) + : romfs_file(file), data_offset(offset), data_size(size) {} std::string GetName() const override; @@ -41,15 +41,15 @@ public: std::unique_ptr OpenDirectory(const Path& path) const override; protected: - std::shared_ptr m_romfs_file; - u64 m_offset; - u64 m_size; + std::shared_ptr romfs_file; + u64 data_offset; + u64 data_size; }; class IVFCFile : public FileBackend { public: - IVFCFile(std::shared_ptr romfs_file, u64 offset, u64 size) - : m_romfs_file(romfs_file), m_offset(offset), m_size(size) {} + IVFCFile(std::shared_ptr file, u64 offset, u64 size) + : romfs_file(file), data_offset(offset), data_size(size) {} bool Open() override { return true; } size_t Read(const u64 offset, const u32 length, u8* buffer) const override; @@ -60,9 +60,9 @@ public: void Flush() const override { } private: - std::shared_ptr m_romfs_file; - u64 m_offset; - u64 m_size; + std::shared_ptr romfs_file; + u64 data_offset; + u64 data_size; }; class IVFCDirectory : public DirectoryBackend { diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index e439a86e0..08c3f59ee 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -93,7 +93,7 @@ public: /** * Get the RomFS of the application - * Since the RomFS is huge, we return a file reference instead of copying to a buffer + * Since the RomFS can be huge, we return a file reference instead of copying to a buffer * @param romfs_file The file containing the RomFS * @param offset The offset the romfs begins on * @param size The size of the romfs diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 8737041e0..5593cbf01 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -289,13 +289,14 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr& romfs_ if (file->GetSize () < romfs_offset + romfs_size) return ResultStatus::Error; - // We reopen the file, to avoid reuse of the file offset + // We reopen the file, to allow its position to be independent from file's romfs_file.reset(new FileUtil::IOFile(filepath, "rb")); + if (!romfs_file->IsOpen()) + return ResultStatus::Error; + offset = romfs_offset; size = romfs_size; - if (!romfs_file->IsOpen()) - return ResultStatus::Error; return ResultStatus::Success; } LOG_DEBUG(Loader, "NCCH has no RomFS"); diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 0fe41390a..d180e77ed 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -163,7 +163,7 @@ namespace Loader { /// Loads an NCCH file (e.g. from a CCI, or the first NCCH in a CXI) class AppLoader_NCCH final : public AppLoader { public: - AppLoader_NCCH(std::unique_ptr&& file, std::string filepath) + AppLoader_NCCH(std::unique_ptr&& file, const std::string& filepath) : AppLoader(std::move(file)), filepath(filepath) { } /** From f0d5e614e04013ea2f5aa3fa564d25d2722b2481 Mon Sep 17 00:00:00 2001 From: condut Date: Sat, 11 Jul 2015 06:20:02 +0300 Subject: [PATCH 4/4] Update per request --- src/core/file_sys/ivfc_archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index c1cba699e..612f6cbb6 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -75,7 +75,7 @@ size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, cons } size_t IVFCFile::GetSize() const { - return sizeof(u8) * data_size; + return data_size; // TODO: return value will overflow on 32-bit machines } bool IVFCFile::SetSize(const u64 size) const {