From a91983b11c9aab00065e258ab94b1b99a1f62201 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 9 Aug 2018 20:52:27 -0400 Subject: file_sys: Add RegisteredCache Manages NAND NCA get and install. --- src/core/file_sys/registered_cache.h | 108 +++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/core/file_sys/registered_cache.h (limited to 'src/core/file_sys/registered_cache.h') diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h new file mode 100644 index 000000000..ba2e3403f --- /dev/null +++ b/src/core/file_sys/registered_cache.h @@ -0,0 +1,108 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include +#include +#include "common/common_funcs.h" +#include "content_archive.h" +#include "core/file_sys/vfs.h" +#include "nca_metadata.h" + +namespace FileSys { +class XCI; +class CNMT; + +using NcaID = std::array; +using RegisteredCacheParsingFunction = std::function; + +struct RegisteredCacheEntry { + u64 title_id; + ContentRecordType type; + + std::string DebugInfo() const; +}; + +// boost flat_map requires operator< for O(log(n)) lookups. +bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); + +/* + * A class that catalogues NCAs in the registered directory structure. + * Nintendo's registered format follows this structure: + * + * Root + * | 000000XX <- XX is the ____ two digits of the NcaID + * | .nca <- hash is the NcaID (first half of SHA256 over entire file) (folder) + * | 00 + * | 01 <- Actual content split along 4GB boundaries. (optional) + * + * (This impl also supports substituting the nca dir for an nca file, as that's more convenient when + * 4GB splitting can be ignored.) + */ +class RegisteredCache { +public: + // Parsing function defines the conversion from raw file to NCA. If there are other steps + // besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom + // parsing function. + RegisteredCache(VirtualDir dir, + RegisteredCacheParsingFunction parsing_function = + [](const VirtualFile& file, const NcaID& id) { return file; }); + + void Refresh(); + + bool HasEntry(u64 title_id, ContentRecordType type) const; + bool HasEntry(RegisteredCacheEntry entry) const; + + VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const; + VirtualFile GetEntryRaw(RegisteredCacheEntry entry) const; + + std::shared_ptr GetEntry(u64 title_id, ContentRecordType type) const; + std::shared_ptr GetEntry(RegisteredCacheEntry entry) const; + + std::vector ListEntries() const; + // If a parameter is not boost::none, it will be filtered for from all entries. + std::vector ListEntriesFilter( + boost::optional title_type = boost::none, + boost::optional record_type = boost::none, + boost::optional title_id = boost::none) const; + + // Raw copies all the ncas from the xci to the csache. Does some quick checks to make sure there + // is a meta NCA and all of them are accessible. + bool InstallEntry(std::shared_ptr xci); + + // Due to the fact that we must use Meta-type NCAs to determine the existance of files, this + // poses quite a challenge. Instead of creating a new meta NCA for this file, yuzu will create a + // dir inside the NAND called 'yuzu_meta' and store the raw CNMT there. + // TODO(DarkLordZach): Author real meta-type NCAs and install those. + bool InstallEntry(std::shared_ptr nca, TitleType type); + +private: + template + void IterateAllMetadata(std::vector& out, + std::function proc, + std::function filter) const; + void AccumulateFiles(std::vector& ids) const; + void ProcessFiles(const std::vector& ids); + void AccumulateYuzuMeta(); + boost::optional GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const; + VirtualFile GetFileAtID(NcaID id) const; + VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const; + bool RawInstallNCA(std::shared_ptr nca, boost::optional override_id = boost::none); + bool RawInstallYuzuMeta(const CNMT& cnmt); + + VirtualDir dir; + RegisteredCacheParsingFunction parser; + // maps tid -> NcaID of meta + boost::container::flat_map meta_id; + // maps tid -> meta + boost::container::flat_map meta; + // maps tid -> meta for CNMT in yuzu_meta + boost::container::flat_map yuzu_meta; +}; + +} // namespace FileSys -- cgit v1.2.3