registered_cache.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <functional>
  7. #include <map>
  8. #include <memory>
  9. #include <string>
  10. #include <vector>
  11. #include <boost/container/flat_map.hpp>
  12. #include "common/common_funcs.h"
  13. #include "common/common_types.h"
  14. #include "content_archive.h"
  15. #include "core/file_sys/nca_metadata.h"
  16. #include "core/file_sys/vfs.h"
  17. namespace FileSys {
  18. class XCI;
  19. class CNMT;
  20. using NcaID = std::array<u8, 0x10>;
  21. using RegisteredCacheParsingFunction = std::function<VirtualFile(const VirtualFile&, const NcaID&)>;
  22. struct RegisteredCacheEntry {
  23. u64 title_id;
  24. ContentRecordType type;
  25. std::string DebugInfo() const;
  26. };
  27. // boost flat_map requires operator< for O(log(n)) lookups.
  28. bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs);
  29. /*
  30. * A class that catalogues NCAs in the registered directory structure.
  31. * Nintendo's registered format follows this structure:
  32. *
  33. * Root
  34. * | 000000XX <- XX is the ____ two digits of the NcaID
  35. * | <hash>.nca <- hash is the NcaID (first half of SHA256 over entire file) (folder)
  36. * | 00
  37. * | 01 <- Actual content split along 4GB boundaries. (optional)
  38. *
  39. * (This impl also supports substituting the nca dir for an nca file, as that's more convenient when
  40. * 4GB splitting can be ignored.)
  41. */
  42. class RegisteredCache {
  43. public:
  44. // Parsing function defines the conversion from raw file to NCA. If there are other steps
  45. // besides creating the NCA from the file (e.g. NAX0 on SD Card), that should go in a custom
  46. // parsing function.
  47. explicit RegisteredCache(VirtualDir dir,
  48. RegisteredCacheParsingFunction parsing_function =
  49. [](const VirtualFile& file, const NcaID& id) { return file; });
  50. void Refresh();
  51. bool HasEntry(u64 title_id, ContentRecordType type) const;
  52. bool HasEntry(RegisteredCacheEntry entry) const;
  53. VirtualFile GetEntryRaw(u64 title_id, ContentRecordType type) const;
  54. VirtualFile GetEntryRaw(RegisteredCacheEntry entry) const;
  55. std::shared_ptr<NCA> GetEntry(u64 title_id, ContentRecordType type) const;
  56. std::shared_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
  57. std::vector<RegisteredCacheEntry> ListEntries() const;
  58. // If a parameter is not boost::none, it will be filtered for from all entries.
  59. std::vector<RegisteredCacheEntry> ListEntriesFilter(
  60. boost::optional<TitleType> title_type = boost::none,
  61. boost::optional<ContentRecordType> record_type = boost::none,
  62. boost::optional<u64> title_id = boost::none) const;
  63. // Raw copies all the ncas from the xci to the csache. Does some quick checks to make sure there
  64. // is a meta NCA and all of them are accessible.
  65. bool InstallEntry(std::shared_ptr<XCI> xci);
  66. // Due to the fact that we must use Meta-type NCAs to determine the existance of files, this
  67. // poses quite a challenge. Instead of creating a new meta NCA for this file, yuzu will create a
  68. // dir inside the NAND called 'yuzu_meta' and store the raw CNMT there.
  69. // TODO(DarkLordZach): Author real meta-type NCAs and install those.
  70. bool InstallEntry(std::shared_ptr<NCA> nca, TitleType type);
  71. private:
  72. template <typename T>
  73. void IterateAllMetadata(std::vector<T>& out,
  74. std::function<T(const CNMT&, const ContentRecord&)> proc,
  75. std::function<bool(const CNMT&, const ContentRecord&)> filter) const;
  76. std::vector<NcaID> AccumulateFiles() const;
  77. void ProcessFiles(const std::vector<NcaID>& ids);
  78. void AccumulateYuzuMeta();
  79. boost::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
  80. VirtualFile GetFileAtID(NcaID id) const;
  81. VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const;
  82. bool RawInstallNCA(std::shared_ptr<NCA> nca, boost::optional<NcaID> override_id = boost::none);
  83. bool RawInstallYuzuMeta(const CNMT& cnmt);
  84. VirtualDir dir;
  85. RegisteredCacheParsingFunction parser;
  86. // maps tid -> NcaID of meta
  87. boost::container::flat_map<u64, NcaID> meta_id;
  88. // maps tid -> meta
  89. boost::container::flat_map<u64, CNMT> meta;
  90. // maps tid -> meta for CNMT in yuzu_meta
  91. boost::container::flat_map<u64, CNMT> yuzu_meta;
  92. };
  93. } // namespace FileSys