// Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include #include #include #include #include "core/file_sys/archive_backend.h" #include "core/file_sys/file_backend.h" #include "core/hle/result.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace namespace Service::FS { enum class MediaType : u32; } // namespace Service::FS namespace FileSys { enum class NCCHFilePathType : u32 { RomFS = 0, Code = 1, ExeFS = 2, }; enum class NCCHFileOpenType : u32 { NCCHData = 0, SaveData = 1, }; /// Helper function to generate a Path for NCCH archives Path MakeNCCHArchivePath(u64 tid, Service::FS::MediaType media_type); /// Helper function to generate a Path for NCCH files Path MakeNCCHFilePath(NCCHFileOpenType open_type, u32 content_index, NCCHFilePathType filepath_type, std::array& exefs_filepath); /// Archive backend for NCCH Archives (RomFS, ExeFS) class NCCHArchive : public ArchiveBackend { public: explicit NCCHArchive(u64 title_id, Service::FS::MediaType media_type) : title_id(title_id), media_type(media_type) {} std::string GetName() const override { return "NCCHArchive"; } ResultVal> OpenFile(const Path& path, const Mode& mode) const override; ResultCode DeleteFile(const Path& path) const override; ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; ResultCode DeleteDirectory(const Path& path) const override; ResultCode DeleteDirectoryRecursively(const Path& path) const override; ResultCode CreateFile(const Path& path, u64 size) const override; ResultCode CreateDirectory(const Path& path) const override; ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override; ResultVal> OpenDirectory(const Path& path) const override; u64 GetFreeBytes() const override; protected: u64 title_id; Service::FS::MediaType media_type; private: NCCHArchive() = default; // NOTE: If the public ctor has behaviour, need to replace this with // *_construct_data template void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object(*this); ar& title_id; ar& media_type; } friend class boost::serialization::access; }; // File backend for NCCH files class NCCHFile : public FileBackend { public: explicit NCCHFile(std::vector buffer, std::unique_ptr delay_generator_); ResultVal Read(u64 offset, std::size_t length, u8* buffer) const override; ResultVal Write(u64 offset, std::size_t length, bool flush, const u8* buffer) override; u64 GetSize() const override; bool SetSize(u64 size) const override; bool Close() const override { return false; } void Flush() const override {} private: NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with // *_construct_data std::vector file_buffer; // TODO: Replace with file ref for serialization }; /// File system interface to the NCCH archive class ArchiveFactory_NCCH final : public ArchiveFactory { public: explicit ArchiveFactory_NCCH(); std::string GetName() const override { return "NCCH"; } ResultVal> Open(const Path& path, u64 program_id) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, u64 program_id) override; ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: template void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH)