From 3a1899d143b6b50da6c1ed4fcc03390ef210df75 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:07:29 -0400 Subject: bis_factory: Add accessors for BIS partitions --- src/core/file_sys/bis_factory.cpp | 41 +++++++++++++++++++++++++++++++++++++++ src/core/file_sys/bis_factory.h | 20 +++++++++++++++++++ 2 files changed, 61 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index e29f70b3a..70a04f6a0 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -39,4 +39,45 @@ VirtualDir BISFactory::GetModificationDumpRoot(u64 title_id) const { return GetOrCreateDirectoryRelative(dump_root, fmt::format("/{:016X}", title_id)); } +VirtualDir BISFactory::OpenPartition(BisPartitionId id) const { + switch (id) { + case BisPartitionId::CalibrationFile: + return GetOrCreateDirectoryRelative(nand_root, "/prodinfof"); + case BisPartitionId::SafeMode: + return GetOrCreateDirectoryRelative(nand_root, "/safe"); + case BisPartitionId::System: + return GetOrCreateDirectoryRelative(nand_root, "/system"); + case BisPartitionId::User: + return GetOrCreateDirectoryRelative(nand_root, "/user"); + default: + return nullptr; + } +} + +VirtualFile BISFactory::OpenPartitionStorage(BisPartitionId id) const { + Core::Crypto::KeyManager keys; + Core::Crypto::PartitionDataManager pdm{ + Core::System::GetInstance().GetFilesystem()->OpenDirectory( + FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), Mode::Read)}; + keys.PopulateFromPartitionData(pdm); + + switch (id) { + case BisPartitionId::CalibrationBinary: + return pdm.GetDecryptedProdInfo(); + case BisPartitionId::BootConfigAndPackage2Part1: + case BisPartitionId::BootConfigAndPackage2Part2: + case BisPartitionId::BootConfigAndPackage2Part3: + case BisPartitionId::BootConfigAndPackage2Part4: + case BisPartitionId::BootConfigAndPackage2Part5: + case BisPartitionId::BootConfigAndPackage2Part6: { + const auto new_id = static_cast(id) - + static_cast(BisPartitionId::BootConfigAndPackage2Part1) + + static_cast(Core::Crypto::Package2Type::NormalMain); + return pdm.GetPackage2Raw(static_cast(new_id)); + } + default: + return nullptr; + } +} + } // namespace FileSys diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h index 453c11ad2..f8413d4ef 100644 --- a/src/core/file_sys/bis_factory.h +++ b/src/core/file_sys/bis_factory.h @@ -10,6 +10,23 @@ namespace FileSys { +enum class BisPartitionId : u32 { + UserDataRoot = 20, + CalibrationBinary = 27, + CalibrationFile = 28, + BootConfigAndPackage2Part1 = 21, + BootConfigAndPackage2Part2 = 22, + BootConfigAndPackage2Part3 = 23, + BootConfigAndPackage2Part4 = 24, + BootConfigAndPackage2Part5 = 25, + BootConfigAndPackage2Part6 = 26, + SafeMode = 29, + System = 31, + SystemProperEncryption = 32, + SystemProperPartition = 33, + User = 30, +}; + class RegisteredCache; /// File system interface to the Built-In Storage @@ -26,6 +43,9 @@ public: VirtualDir GetModificationLoadRoot(u64 title_id) const; VirtualDir GetModificationDumpRoot(u64 title_id) const; + VirtualDir OpenPartition(BisPartitionId id) const; + VirtualFile OpenPartitionStorage(BisPartitionId id) const; + private: VirtualDir nand_root; VirtualDir load_root; -- cgit v1.2.3 From 4dae5a52a832cc3c4679aba80fd8b15c56ded93a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:08:39 -0400 Subject: bis_factory: Add accessors for BIS content directories --- src/core/file_sys/bis_factory.cpp | 8 ++++++++ src/core/file_sys/bis_factory.h | 3 +++ 2 files changed, 11 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 70a04f6a0..be737b9ad 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -18,6 +18,14 @@ BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_, VirtualDir BISFactory::~BISFactory() = default; +VirtualDir BISFactory::GetSystemNANDContentDirectory() const { + return GetOrCreateDirectoryRelative(nand_root, "/system/Contents"); +} + +VirtualDir BISFactory::GetUserNANDContentDirectory() const { + return GetOrCreateDirectoryRelative(nand_root, "/user/Contents"); +} + RegisteredCache* BISFactory::GetSystemNANDContents() const { return sysnand_cache.get(); } diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h index f8413d4ef..bfebceeaf 100644 --- a/src/core/file_sys/bis_factory.h +++ b/src/core/file_sys/bis_factory.h @@ -37,6 +37,9 @@ public: explicit BISFactory(VirtualDir nand_root, VirtualDir load_root, VirtualDir dump_root); ~BISFactory(); + VirtualDir GetSystemNANDContentDirectory() const; + VirtualDir GetUserNANDContentDirectory() const; + RegisteredCache* GetSystemNANDContents() const; RegisteredCache* GetUserNANDContents() const; -- cgit v1.2.3 From 9bee8852829bfb99025397186d9d1b2e7dec9c30 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:09:25 -0400 Subject: bis_factory: Add accessor for NAND Image Directory --- src/core/file_sys/bis_factory.cpp | 4 ++++ src/core/file_sys/bis_factory.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index be737b9ad..b8967853f 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -88,4 +88,8 @@ VirtualFile BISFactory::OpenPartitionStorage(BisPartitionId id) const { } } +VirtualDir BISFactory::GetImageDirectory() const { + return GetOrCreateDirectoryRelative(nand_root, "/user/Album"); +} + } // namespace FileSys diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h index bfebceeaf..38dcd28dc 100644 --- a/src/core/file_sys/bis_factory.h +++ b/src/core/file_sys/bis_factory.h @@ -49,6 +49,8 @@ public: VirtualDir OpenPartition(BisPartitionId id) const; VirtualFile OpenPartitionStorage(BisPartitionId id) const; + VirtualDir GetImageDirectory() const; + private: VirtualDir nand_root; VirtualDir load_root; -- cgit v1.2.3 From b71bda45ae26695665bba45e7a3f84ae5a13d2b3 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:10:38 -0400 Subject: bis_factory: Add accessors for BIS placeholder caches --- src/core/file_sys/bis_factory.cpp | 14 +++++++++++++- src/core/file_sys/bis_factory.h | 7 +++++++ 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index b8967853f..cbeb2f73a 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -14,7 +14,11 @@ BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_, VirtualDir sysnand_cache(std::make_unique( GetOrCreateDirectoryRelative(nand_root, "/system/Contents/registered"))), usrnand_cache(std::make_unique( - GetOrCreateDirectoryRelative(nand_root, "/user/Contents/registered"))) {} + GetOrCreateDirectoryRelative(nand_root, "/user/Contents/registered"))), + sysnand_placeholder(std::make_unique( + GetOrCreateDirectoryRelative(nand_root, "/system/Contents/placehld"))), + usrnand_placeholder(std::make_unique( + GetOrCreateDirectoryRelative(nand_root, "/user/Contents/placehld"))) {} BISFactory::~BISFactory() = default; @@ -34,6 +38,14 @@ RegisteredCache* BISFactory::GetUserNANDContents() const { return usrnand_cache.get(); } +PlaceholderCache* BISFactory::GetSystemNANDPlaceholder() const { + return sysnand_placeholder.get(); +} + +PlaceholderCache* BISFactory::GetUserNANDPlaceholder() const { + return usrnand_placeholder.get(); +} + VirtualDir BISFactory::GetModificationLoadRoot(u64 title_id) const { // LayeredFS doesn't work on updates and title id-less homebrew if (title_id == 0 || (title_id & 0x800) > 0) diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h index 38dcd28dc..6229cd5a9 100644 --- a/src/core/file_sys/bis_factory.h +++ b/src/core/file_sys/bis_factory.h @@ -28,6 +28,7 @@ enum class BisPartitionId : u32 { }; class RegisteredCache; +class PlaceholderCache; /// File system interface to the Built-In Storage /// This is currently missing accessors to BIS partitions, but seemed like a good place for the NAND @@ -43,6 +44,9 @@ public: RegisteredCache* GetSystemNANDContents() const; RegisteredCache* GetUserNANDContents() const; + PlaceholderCache* GetSystemNANDPlaceholder() const; + PlaceholderCache* GetUserNANDPlaceholder() const; + VirtualDir GetModificationLoadRoot(u64 title_id) const; VirtualDir GetModificationDumpRoot(u64 title_id) const; @@ -58,6 +62,9 @@ private: std::unique_ptr sysnand_cache; std::unique_ptr usrnand_cache; + + std::unique_ptr sysnand_placeholder; + std::unique_ptr usrnand_placeholder; }; } // namespace FileSys -- cgit v1.2.3 From 256a50ad15a1666a40c8aeff9759664f9e7a85a9 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:11:50 -0400 Subject: bis_factory: Fix mod loader edge-case with homebrew title IDs Fixes a bug where homebrew that has a title ID with the update bit set can cause issues with the PatchManager --- src/core/file_sys/bis_factory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index cbeb2f73a..6cd0a98eb 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -48,7 +48,7 @@ PlaceholderCache* BISFactory::GetUserNANDPlaceholder() const { VirtualDir BISFactory::GetModificationLoadRoot(u64 title_id) const { // LayeredFS doesn't work on updates and title id-less homebrew - if (title_id == 0 || (title_id & 0x800) > 0) + if (title_id == 0 || (title_id & 0xFFF) == 0x800) return nullptr; return GetOrCreateDirectoryRelative(load_root, fmt::format("/{:016X}", title_id)); } -- cgit v1.2.3 From 8500ca797f430226c86edf694db6a96ee14a8333 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:21:51 -0400 Subject: registered_cache: Implement PlaceholderCache to manage placeholder and installing content --- src/core/file_sys/registered_cache.cpp | 150 +++++++++++++++++++++++++++++++++ src/core/file_sys/registered_cache.h | 25 ++++++ 2 files changed, 175 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 3725b10f7..93a20ab94 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -127,6 +127,156 @@ std::vector ContentProvider::ListEntries() const { return ListEntriesFilter(std::nullopt, std::nullopt, std::nullopt); } +PlaceholderCache::PlaceholderCache(VirtualDir dir_) : dir(std::move(dir_)) {} + +bool PlaceholderCache::Create(const NcaID& id, u64 size) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + + if (dir->GetFileRelative(path) != nullptr) { + return false; + } + + Core::Crypto::SHA256Hash hash{}; + mbedtls_sha256(id.data(), id.size(), hash.data(), 0); + const auto dirname = fmt::format("000000{:02X}", hash[0]); + + const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname); + + if (dir2 == nullptr) + return false; + + const auto file = dir2->CreateFile(fmt::format("{}.nca", Common::HexArrayToString(id, false))); + + if (file == nullptr) + return false; + + return file->Resize(size); +} + +bool PlaceholderCache::Delete(const NcaID& id) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + + if (dir->GetFileRelative(path) == nullptr) { + return false; + } + + Core::Crypto::SHA256Hash hash{}; + mbedtls_sha256(id.data(), id.size(), hash.data(), 0); + const auto dirname = fmt::format("000000{:02X}", hash[0]); + + const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname); + + const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexArrayToString(id, false))); + + return res; +} + +bool PlaceholderCache::Exists(const NcaID& id) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + + return dir->GetFileRelative(path) != nullptr; +} + +bool PlaceholderCache::Write(const NcaID& id, u64 offset, const std::vector& data) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + const auto file = dir->GetFileRelative(path); + + if (file == nullptr) + return false; + + return file->WriteBytes(data, offset) == data.size(); +} + +bool PlaceholderCache::Register(RegisteredCache* cache, const NcaID& placeholder, + const NcaID& install) const { + const auto path = GetRelativePathFromNcaID(placeholder, false, true, false); + const auto file = dir->GetFileRelative(path); + + if (file == nullptr) + return false; + + const auto res = cache->RawInstallNCA(NCA{file}, &VfsRawCopy, false, install); + + if (res != InstallResult::Success) + return false; + + return Delete(placeholder); +} + +bool PlaceholderCache::CleanAll() const { + return dir->GetParentDirectory()->CleanSubdirectoryRecursive(dir->GetName()); +} + +std::optional> PlaceholderCache::GetRightsID(const NcaID& id) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + const auto file = dir->GetFileRelative(path); + + if (file == nullptr) + return std::nullopt; + + NCA nca{file}; + + if (nca.GetStatus() != Loader::ResultStatus::Success && + nca.GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { + return std::nullopt; + } + + const auto rights_id = nca.GetRightsId(); + if (rights_id == NcaID{}) + return std::nullopt; + + return rights_id; +} + +u64 PlaceholderCache::Size(const NcaID& id) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + const auto file = dir->GetFileRelative(path); + + if (file == nullptr) + return 0; + + return file->GetSize(); +} + +bool PlaceholderCache::SetSize(const NcaID& id, u64 new_size) const { + const auto path = GetRelativePathFromNcaID(id, false, true, false); + const auto file = dir->GetFileRelative(path); + + if (file == nullptr) + return false; + + return file->Resize(new_size); +} + +std::vector PlaceholderCache::List() const { + std::vector out; + for (const auto& sdir : dir->GetSubdirectories()) { + for (const auto& file : sdir->GetFiles()) { + const auto name = file->GetName(); + if (name.length() == 36 && name[32] == '.' && name[33] == 'n' && name[34] == 'c' && + name[35] == 'a') { + out.push_back(Common::HexStringToArray<0x10>(name.substr(0, 32))); + } + } + } + return out; +} + +NcaID PlaceholderCache::Generate() { + std::random_device device; + std::mt19937 gen(device()); + std::uniform_int_distribution distribution(1, std::numeric_limits::max()); + + NcaID out{}; + + const auto v1 = distribution(gen); + const auto v2 = distribution(gen); + std::memcpy(out.data(), &v1, sizeof(u64)); + std::memcpy(out.data() + sizeof(u64), &v2, sizeof(u64)); + + return out; +} + VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const { const auto file = dir->GetFileRelative(path); diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index 4398d63e1..d1eec240e 100644 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -25,6 +25,8 @@ enum class NCAContentType : u8; enum class TitleType : u8; struct ContentRecord; +struct MetaRecord; +class RegisteredCache; using NcaID = std::array; using ContentProviderParsingFunction = std::function; @@ -89,6 +91,27 @@ protected: Core::Crypto::KeyManager keys; }; +class PlaceholderCache { +public: + explicit PlaceholderCache(VirtualDir dir); + + bool Create(const NcaID& id, u64 size) const; + bool Delete(const NcaID& id) const; + bool Exists(const NcaID& id) const; + bool Write(const NcaID& id, u64 offset, const std::vector& data) const; + bool Register(RegisteredCache* cache, const NcaID& placeholder, const NcaID& install) const; + bool CleanAll() const; + std::optional> GetRightsID(const NcaID& id) const; + u64 Size(const NcaID& id) const; + bool SetSize(const NcaID& id, u64 new_size) const; + std::vector List() const; + + static NcaID Generate(); + +private: + VirtualDir dir; +}; + /* * A class that catalogues NCAs in the registered directory structure. * Nintendo's registered format follows this structure: @@ -103,6 +126,8 @@ protected: * when 4GB splitting can be ignored.) */ class RegisteredCache : public ContentProvider { + friend class PlaceholderCache; + 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 -- cgit v1.2.3 From 9d9fc8a675ffa35998830a0a5670dd1ca288112f Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:24:44 -0400 Subject: registered_cache: Process *.cnmt.nca files Needed to use the RegisteredCache/PlaceholderCache on gamecards. --- src/core/file_sys/registered_cache.cpp | 39 ++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 93a20ab94..afa87be9c 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -48,19 +48,22 @@ static bool FollowsTwoDigitDirFormat(std::string_view name) { static bool FollowsNcaIdFormat(std::string_view name) { static const std::regex nca_id_regex("[0-9A-F]{32}\\.nca", std::regex_constants::ECMAScript | std::regex_constants::icase); - return name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex); + static const std::regex nca_id_cnmt_regex( + "[0-9A-F]{32}\\.cnmt.nca", std::regex_constants::ECMAScript | std::regex_constants::icase); + return (name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex)) || + (name.size() == 41 && std::regex_match(name.begin(), name.end(), nca_id_cnmt_regex)); } static std::string GetRelativePathFromNcaID(const std::array& nca_id, bool second_hex_upper, - bool within_two_digit) { - if (!within_two_digit) { - return fmt::format("/{}.nca", Common::HexToString(nca_id, second_hex_upper)); - } + bool within_two_digit, bool cnmt_suffix) { + if (!within_two_digit) + return fmt::format(cnmt_suffix ? "{}.cnmt.nca" : "/{}.nca", + Common::HexArrayToString(nca_id, second_hex_upper)); Core::Crypto::SHA256Hash hash{}; mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); - return fmt::format("/000000{:02X}/{}.nca", hash[0], - Common::HexToString(nca_id, second_hex_upper)); + return fmt::format(cnmt_suffix ? "/000000{:02X}/{}.cnmt.nca" : "/000000{:02X}/{}.nca", hash[0], + Common::HexArrayToString(nca_id, second_hex_upper)); } static std::string GetCNMTName(TitleType type, u64 title_id) { @@ -319,14 +322,18 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir, VirtualFile RegisteredCache::GetFileAtID(NcaID id) const { VirtualFile file; - // Try all four modes of file storage: - // (bit 1 = uppercase/lower, bit 0 = within a two-digit dir) - // 00: /000000**/{:032X}.nca - // 01: /{:032X}.nca - // 10: /000000**/{:032x}.nca - // 11: /{:032x}.nca - for (u8 i = 0; i < 4; ++i) { - const auto path = GetRelativePathFromNcaID(id, (i & 0b10) == 0, (i & 0b01) == 0); + // Try all five relevant modes of file storage: + // (bit 2 = uppercase/lower, bit 1 = within a two-digit dir, bit 0 = .cnmt suffix) + // 000: /000000**/{:032X}.nca + // 010: /{:032X}.nca + // 100: /000000**/{:032x}.nca + // 110: /{:032x}.nca + // 111: /{:032x}.cnmt.nca + for (u8 i = 0; i < 8; ++i) { + if ((i % 2) == 1 && i != 7) + continue; + const auto path = + GetRelativePathFromNcaID(id, (i & 0b100) == 0, (i & 0b010) == 0, (i & 0b001) == 0b001); file = OpenFileOrDirectoryConcat(dir, path); if (file != nullptr) return file; @@ -622,7 +629,7 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti memcpy(id.data(), hash.data(), 16); } - std::string path = GetRelativePathFromNcaID(id, false, true); + std::string path = GetRelativePathFromNcaID(id, false, true, false); if (GetFileAtID(id) != nullptr && !overwrite_if_exists) { LOG_WARNING(Loader, "Attempting to overwrite existing NCA. Skipping..."); -- cgit v1.2.3 From 06db4d94fde745c39326fe5564b93348610a5674 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:28:32 -0400 Subject: patch_manager: Add error checking to load dir to prevent crashes Prevents a crash if the load dir would be nullptr, instead logs an error and returns appropriately. --- src/core/file_sys/patch_manager.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index a8f80e2c6..0a4f0ea74 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -187,6 +187,11 @@ std::vector PatchManager::PatchNSO(const std::vector& nso, const std::st LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id); const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (load_dir == nullptr) { + LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); + return nso; + } + auto patch_dirs = load_dir->GetSubdirectories(); std::sort(patch_dirs.begin(), patch_dirs.end(), [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); @@ -225,6 +230,11 @@ bool PatchManager::HasNSOPatch(const std::array& build_id_) const { LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id); const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (load_dir == nullptr) { + LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); + return false; + } + auto patch_dirs = load_dir->GetSubdirectories(); std::sort(patch_dirs.begin(), patch_dirs.end(), [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); @@ -259,6 +269,11 @@ static std::optional ReadCheatFileFromFolder(const Core::System& syst std::vector PatchManager::CreateCheatList(const Core::System& system, const std::array& build_id_) const { const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (load_dir == nullptr) { + LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); + return {}; + } + auto patch_dirs = load_dir->GetSubdirectories(); std::sort(patch_dirs.begin(), patch_dirs.end(), [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); -- cgit v1.2.3 From 62d772eaedbdd983574d2bfd0022fff58b55ca73 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:29:15 -0400 Subject: patch_manager: Add short-circuit edge-case to GetPatchVersionNames If title ID is 0, there are no add ons, prevents wasting time looking for them. --- src/core/file_sys/patch_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 0a4f0ea74..e3ebaca03 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -408,6 +408,8 @@ static bool IsDirValidAndNonEmpty(const VirtualDir& dir) { std::map> PatchManager::GetPatchVersionNames( VirtualFile update_raw) const { + if (title_id == 0) + return {}; std::map> out; const auto& installed = Core::System::GetInstance().GetContentProvider(); const auto& disabled = Settings::values.disabled_addons[title_id]; -- cgit v1.2.3 From 49c44e3faebe5912b71532a118f3bcd71bf73b4d Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:30:49 -0400 Subject: savedata_factory: Implement savedata creation and don't create dir on open Matches hardware behavior and eliminates some nasty behavior we were doing that wasn't hw-accurate at all. --- src/core/file_sys/savedata_factory.cpp | 65 ++++++++++++++++++++-------------- src/core/file_sys/savedata_factory.h | 1 + 2 files changed, 40 insertions(+), 26 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 7974b031d..c63815332 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -15,22 +15,8 @@ namespace FileSys { constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; -std::string SaveDataDescriptor::DebugInfo() const { - return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, " - "rank={}, index={}]", - static_cast(type), title_id, user_id[1], user_id[0], save_id, - static_cast(rank), index); -} - -SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) { - // Delete all temporary storages - // On hardware, it is expected that temporary storage be empty at first use. - dir->DeleteSubdirectoryRecursive("temp"); -} - -SaveDataFactory::~SaveDataFactory() = default; - -ResultVal SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataDescriptor& meta) { +namespace { +void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { if (meta.zero_1 != 0) { LOG_WARNING(Service_FS, @@ -65,23 +51,50 @@ ResultVal SaveDataFactory::Open(SaveDataSpaceId space, const SaveDat "non-zero ({:016X}{:016X})", meta.user_id[1], meta.user_id[0]); } +} +} // Anonymous namespace - std::string save_directory = - GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); +std::string SaveDataDescriptor::DebugInfo() const { + return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, " + "save_id={:016X}, " + "rank={}, index={}]", + static_cast(type), title_id, user_id[1], user_id[0], save_id, + static_cast(rank), index); +} - // TODO(DarkLordZach): Try to not create when opening, there are dedicated create save methods. - // But, user_ids don't match so this works for now. +SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) { + // Delete all temporary storages + // On hardware, it is expected that temporary storage be empty at first use. + dir->DeleteSubdirectoryRecursive("temp"); +} - auto out = dir->GetDirectoryRelative(save_directory); +SaveDataFactory::~SaveDataFactory() = default; + +ResultVal SaveDataFactory::Create(SaveDataSpaceId space, + const SaveDataDescriptor& meta) { + PrintSaveDataDescriptorWarnings(meta); + + const auto save_directory = + GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); + + auto out = dir->CreateDirectoryRelative(save_directory); + // Return an error if the save data doesn't actually exist. if (out == nullptr) { - // TODO(bunnei): This is a work-around to always create a save data directory if it does not - // already exist. This is a hack, as we do not understand yet how this works on hardware. - // Without a save data directory, many games will assert on boot. This should not have any - // bad side-effects. - out = dir->CreateDirectoryRelative(save_directory); + // TODO(DarkLordZach): Find out correct error code. + return ResultCode(-1); } + return MakeResult(std::move(out)); +} + +ResultVal SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataDescriptor& meta) { + + const auto save_directory = + GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); + + auto out = dir->GetDirectoryRelative(save_directory); + // Return an error if the save data doesn't actually exist. if (out == nullptr) { // TODO(Subv): Find out correct error code. diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index b73654571..738038ee0 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h @@ -64,6 +64,7 @@ public: explicit SaveDataFactory(VirtualDir dir); ~SaveDataFactory(); + ResultVal Create(SaveDataSpaceId space, const SaveDataDescriptor& meta); ResultVal Open(SaveDataSpaceId space, const SaveDataDescriptor& meta); VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; -- cgit v1.2.3 From 02b36b0eb564f60b751398f5e7e89e75e05c1c20 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:31:41 -0400 Subject: sdmc_factory: Add accessor for content directory --- src/core/file_sys/sdmc_factory.cpp | 4 ++++ src/core/file_sys/sdmc_factory.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index bd3a57058..e5668d70e 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -22,6 +22,10 @@ ResultVal SDMCFactory::Open() { return MakeResult(dir); } +VirtualDir SDMCFactory::GetSDMCContentDirectory() const { + return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents"); +} + RegisteredCache* SDMCFactory::GetSDMCContents() const { return contents.get(); } diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 42794ba5b..a98e44f85 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h @@ -19,6 +19,9 @@ public: ~SDMCFactory(); ResultVal Open(); + + VirtualDir GetSDMCContentDirectory() const; + RegisteredCache* GetSDMCContents() const; private: -- cgit v1.2.3 From 0084cceb203544e306d7089bc81d81e20e1ddafa Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:32:19 -0400 Subject: sdmc_factory: Add accessor for SDMC PlaceholderCache --- src/core/file_sys/sdmc_factory.cpp | 8 +++++++- src/core/file_sys/sdmc_factory.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index e5668d70e..d63d960ce 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -14,7 +14,9 @@ SDMCFactory::SDMCFactory(VirtualDir dir_) GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"), [](const VirtualFile& file, const NcaID& id) { return NAX{file, id}.GetDecrypted(); - })) {} + })), + placeholder(std::make_unique( + GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/placehld"))) {} SDMCFactory::~SDMCFactory() = default; @@ -30,4 +32,8 @@ RegisteredCache* SDMCFactory::GetSDMCContents() const { return contents.get(); } +PlaceholderCache* SDMCFactory::GetSDMCPlaceholder() const { + return placeholder.get(); +} + } // namespace FileSys diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index a98e44f85..2ef5909a6 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h @@ -11,6 +11,7 @@ namespace FileSys { class RegisteredCache; +class PlaceholderCache; /// File system interface to the SDCard archive class SDMCFactory { @@ -23,11 +24,13 @@ public: VirtualDir GetSDMCContentDirectory() const; RegisteredCache* GetSDMCContents() const; + PlaceholderCache* GetSDMCPlaceholder() const; private: VirtualDir dir; std::unique_ptr contents; + std::unique_ptr placeholder; }; } // namespace FileSys -- cgit v1.2.3 From 08c0783d345550c673763328d102095345940dcc Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:32:49 -0400 Subject: sdmc_factory: Add accessor for SDMC Album directory --- src/core/file_sys/sdmc_factory.cpp | 4 ++++ src/core/file_sys/sdmc_factory.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index d63d960ce..a5f1dcc5c 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -36,4 +36,8 @@ PlaceholderCache* SDMCFactory::GetSDMCPlaceholder() const { return placeholder.get(); } +VirtualDir SDMCFactory::GetImageDirectory() const { + return GetOrCreateDirectoryRelative(dir, "/Nintendo/Album"); +} + } // namespace FileSys diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 2ef5909a6..abe6cc41c 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h @@ -26,6 +26,8 @@ public: RegisteredCache* GetSDMCContents() const; PlaceholderCache* GetSDMCPlaceholder() const; + VirtualDir GetImageDirectory() const; + private: VirtualDir dir; -- cgit v1.2.3 From 0a8e54068191c911806c7b825e4050afd65a794c Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:35:42 -0400 Subject: submisson_package: Fix edge case with improperly sized filenames Prevents a crash if the filename is less than 9 characters long. --- src/core/file_sys/submission_package.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 730221fd6..ef3084681 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -248,7 +248,8 @@ void NSP::InitializeExeFSAndRomFS(const std::vector& files) { void NSP::ReadNCAs(const std::vector& files) { for (const auto& outer_file : files) { - if (outer_file->GetName().substr(outer_file->GetName().size() - 9) != ".cnmt.nca") { + if (outer_file->GetName().size() < 9 || + outer_file->GetName().substr(outer_file->GetName().size() - 9) != ".cnmt.nca") { continue; } -- cgit v1.2.3 From e47b57a90fb2123a2c4d98f4f990b61976c0ea1f Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 16 Apr 2019 14:27:34 -0400 Subject: bis_factory: Add getters for NAND partition sizes --- src/core/file_sys/bis_factory.cpp | 32 ++++++++++++++++++++++++++++++++ src/core/file_sys/bis_factory.h | 6 ++++++ 2 files changed, 38 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 6cd0a98eb..8f758d6d9 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -3,8 +3,12 @@ // Refer to the license.txt file included. #include +#include "common/file_util.h" +#include "core/core.h" #include "core/file_sys/bis_factory.h" +#include "core/file_sys/mode.h" #include "core/file_sys/registered_cache.h" +#include "core/settings.h" namespace FileSys { @@ -104,4 +108,32 @@ VirtualDir BISFactory::GetImageDirectory() const { return GetOrCreateDirectoryRelative(nand_root, "/user/Album"); } +u64 BISFactory::GetSystemNANDFreeSpace() const { + const auto sys_dir = GetOrCreateDirectoryRelative(nand_root, "/system"); + if (sys_dir == nullptr) + return 0; + + return GetSystemNANDTotalSpace() - sys_dir->GetSize(); +} + +u64 BISFactory::GetSystemNANDTotalSpace() const { + return static_cast(Settings::values.nand_system_size); +} + +u64 BISFactory::GetUserNANDFreeSpace() const { + const auto usr_dir = GetOrCreateDirectoryRelative(nand_root, "/user"); + if (usr_dir == nullptr) + return 0; + + return GetUserNANDTotalSpace() - usr_dir->GetSize(); +} + +u64 BISFactory::GetUserNANDTotalSpace() const { + return static_cast(Settings::values.nand_user_size); +} + +u64 BISFactory::GetFullNANDTotalSpace() const { + return static_cast(Settings::values.nand_total_size); +} + } // namespace FileSys diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h index 6229cd5a9..bdfe728c9 100644 --- a/src/core/file_sys/bis_factory.h +++ b/src/core/file_sys/bis_factory.h @@ -55,6 +55,12 @@ public: VirtualDir GetImageDirectory() const; + u64 GetSystemNANDFreeSpace() const; + u64 GetSystemNANDTotalSpace() const; + u64 GetUserNANDFreeSpace() const; + u64 GetUserNANDTotalSpace() const; + u64 GetFullNANDTotalSpace() const; + private: VirtualDir nand_root; VirtualDir load_root; -- cgit v1.2.3 From 721a92775d2da30843fc5e1d9887e55dafa0bc3a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 16 Apr 2019 14:28:20 -0400 Subject: sdmc_factory: Add SD Card size getters --- src/core/file_sys/sdmc_factory.cpp | 9 +++++++++ src/core/file_sys/sdmc_factory.h | 3 +++ 2 files changed, 12 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index a5f1dcc5c..743e2e63a 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -6,6 +6,7 @@ #include "core/file_sys/registered_cache.h" #include "core/file_sys/sdmc_factory.h" #include "core/file_sys/xts_archive.h" +#include "core/settings.h" namespace FileSys { @@ -40,4 +41,12 @@ VirtualDir SDMCFactory::GetImageDirectory() const { return GetOrCreateDirectoryRelative(dir, "/Nintendo/Album"); } +u64 SDMCFactory::GetSDMCFreeSpace() const { + return GetSDMCTotalSpace() - dir->GetSize(); +} + +u64 SDMCFactory::GetSDMCTotalSpace() const { + return static_cast(Settings::values.sdmc_size); +} + } // namespace FileSys diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index abe6cc41c..164fd9435 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h @@ -28,6 +28,9 @@ public: VirtualDir GetImageDirectory() const; + u64 GetSDMCFreeSpace() const; + u64 GetSDMCTotalSpace() const; + private: VirtualDir dir; -- cgit v1.2.3 From e018a48460ca35403e53f319eb5f89135475d81a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 10:23:13 -0400 Subject: content_archive: Add accessors for Rights ID and SDK Version --- src/core/file_sys/content_archive.cpp | 8 ++++++++ src/core/file_sys/content_archive.h | 2 ++ 2 files changed, 10 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index ce5c69b41..ea5c92f61 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -528,6 +528,14 @@ u64 NCA::GetTitleId() const { return header.title_id; } +std::array NCA::GetRightsId() const { + return header.rights_id; +} + +u32 NCA::GetSDKVersion() const { + return header.sdk_version; +} + bool NCA::IsUpdate() const { return is_update; } diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 15b9e6624..e249079b5 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -112,6 +112,8 @@ public: NCAContentType GetType() const; u64 GetTitleId() const; + std::array GetRightsId() const; + u32 GetSDKVersion() const; bool IsUpdate() const; VirtualFile GetRomFS() const; -- cgit v1.2.3 From 77f9ecd32b075fb8986103de5e446fa330210526 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:12:49 -0400 Subject: card_image: Add functions to query gamecard update partition Includes version and meta title ID, used by fsp-srv/IDeviceOperator --- src/core/file_sys/card_image.cpp | 20 ++++++++++++++++++++ src/core/file_sys/card_image.h | 4 ++++ 2 files changed, 24 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 626ed0042..9fb6e0178 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -175,6 +175,26 @@ VirtualDir XCI::GetParentDirectory() const { return file->GetContainingDirectory(); } +VirtualDir XCI::ConcatenatedPseudoDirectory() { + const auto out = std::make_shared(); + for (const auto& part_id : {XCIPartition::Normal, XCIPartition::Logo, XCIPartition::Secure}) { + const auto& part = GetPartition(part_id); + if (part == nullptr) + continue; + + for (const auto& file : part->GetFiles()) + out->AddFile(file); + } + + return out; +} + +std::array XCI::GetCertificate() const { + std::array out; + file->Read(out.data(), out.size(), GAMECARD_CERTIFICATE_OFFSET); + return out; +} + Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { const auto partition_index = static_cast(part); const auto& partition = partitions[partition_index]; diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index a350496f7..5a83acc1c 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -91,6 +91,8 @@ public: VirtualDir GetLogoPartition() const; u64 GetProgramTitleID() const; + u32 GetSystemUpdateVersion(); + u64 GetSystemUpdateTitleID() const; bool HasProgramNCA() const; VirtualFile GetProgramNCAFile() const; @@ -120,6 +122,8 @@ private: std::shared_ptr program; std::vector> ncas; + u64 update_normal_partition_end; + Core::Crypto::KeyManager keys; }; } // namespace FileSys -- cgit v1.2.3 From ccaafaccfc924c6ac910775e546537c297ce2636 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 10 Apr 2019 12:13:27 -0400 Subject: card_image: Add accessors for gamecard certificate Used by fsp-srv/IDeviceOperator --- src/core/file_sys/card_image.cpp | 4 ++++ src/core/file_sys/card_image.h | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 9fb6e0178..db54113a0 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -12,12 +12,16 @@ #include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/partition_filesystem.h" +#include "core/file_sys/romfs.h" #include "core/file_sys/submission_package.h" +#include "core/file_sys/vfs_concat.h" #include "core/file_sys/vfs_offset.h" +#include "core/file_sys/vfs_vector.h" #include "core/loader/loader.h" namespace FileSys { +constexpr u64 GAMECARD_CERTIFICATE_OFFSET = 0x7000; constexpr std::array partition_names{ "update", "normal", diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index 5a83acc1c..3e6b92ff3 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -108,6 +108,11 @@ public: VirtualDir GetParentDirectory() const override; + // Creates a directory that contains all the NCAs in the gamecard + VirtualDir ConcatenatedPseudoDirectory(); + + std::array GetCertificate() const; + private: Loader::ResultStatus AddNCAFromPartition(XCIPartition part); -- cgit v1.2.3 From c6ff4a6f4d05eb380616be57e4088003e7aedfcb Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 22 Apr 2019 17:56:56 -0400 Subject: yuzu: Port old usages of Filesystem namespace to FilesystemController --- src/core/file_sys/patch_manager.cpp | 24 ++++++++++++++++-------- src/core/file_sys/registered_cache.cpp | 1 + src/core/file_sys/romfs_factory.cpp | 11 ++++++++--- 3 files changed, 25 insertions(+), 11 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index e3ebaca03..c1dd0c6d7 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -63,7 +63,8 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { if (Settings::values.dump_exefs) { LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id); - const auto dump_dir = Service::FileSystem::GetModificationDumpRoot(title_id); + const auto dump_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id); if (dump_dir != nullptr) { const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs"); VfsRawCopyD(exefs, exefs_dir); @@ -88,7 +89,8 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { } // LayeredExeFS - const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + const auto load_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); if (load_dir != nullptr && load_dir->GetSize() > 0) { auto patch_dirs = load_dir->GetSubdirectories(); std::sort( @@ -174,7 +176,8 @@ std::vector PatchManager::PatchNSO(const std::vector& nso, const std::st if (Settings::values.dump_nso) { LOG_INFO(Loader, "Dumping NSO for name={}, build_id={}, title_id={:016X}", name, build_id, title_id); - const auto dump_dir = Service::FileSystem::GetModificationDumpRoot(title_id); + const auto dump_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id); if (dump_dir != nullptr) { const auto nso_dir = GetOrCreateDirectoryRelative(dump_dir, "/nso"); const auto file = nso_dir->CreateFile(fmt::format("{}-{}.nso", name, build_id)); @@ -186,7 +189,8 @@ std::vector PatchManager::PatchNSO(const std::vector& nso, const std::st LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id); - const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + const auto load_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); if (load_dir == nullptr) { LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); return nso; @@ -229,7 +233,8 @@ bool PatchManager::HasNSOPatch(const std::array& build_id_) const { LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id); - const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + const auto load_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); if (load_dir == nullptr) { LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); return false; @@ -268,7 +273,8 @@ static std::optional ReadCheatFileFromFolder(const Core::System& syst std::vector PatchManager::CreateCheatList(const Core::System& system, const std::array& build_id_) const { - const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + const auto load_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); if (load_dir == nullptr) { LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); return {}; @@ -299,7 +305,8 @@ std::vector PatchManager::CreateCheatList(const Core::System& system, } static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { - const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + const auto load_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || load_dir == nullptr || load_dir->GetSize() <= 0) { return; @@ -440,7 +447,8 @@ std::map> PatchManager::GetPatchVersionNam } // General Mods (LayeredFS and IPS) - const auto mod_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + const auto mod_dir = + Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); if (mod_dir != nullptr && mod_dir->GetSize() > 0) { for (const auto& mod : mod_dir->GetSubdirectories()) { std::string types; diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index afa87be9c..d1ef1e72d 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include "common/assert.h" diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index b2ccb2926..c3ee4a158 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -7,6 +7,7 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/file_sys/card_image.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/patch_manager.h" @@ -51,13 +52,17 @@ ResultVal RomFSFactory::Open(u64 title_id, StorageId storage, Conte res = Core::System::GetInstance().GetContentProvider().GetEntry(title_id, type); break; case StorageId::NandSystem: - res = Service::FileSystem::GetSystemNANDContents()->GetEntry(title_id, type); + res = + Core::System::GetInstance().GetFileSystemController().GetSystemNANDContents()->GetEntry( + title_id, type); break; case StorageId::NandUser: - res = Service::FileSystem::GetUserNANDContents()->GetEntry(title_id, type); + res = Core::System::GetInstance().GetFileSystemController().GetUserNANDContents()->GetEntry( + title_id, type); break; case StorageId::SdCard: - res = Service::FileSystem::GetSDMCContents()->GetEntry(title_id, type); + res = Core::System::GetInstance().GetFileSystemController().GetSDMCContents()->GetEntry( + title_id, type); break; default: UNIMPLEMENTED_MSG("Unimplemented storage_id={:02X}", static_cast(storage)); -- cgit v1.2.3 From a49169e81906d230fd6bfc7546acc6f763f4c321 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 23 Apr 2019 14:38:18 -0400 Subject: filesystem: Add const qualification to various accessors --- src/core/file_sys/romfs_factory.cpp | 5 +++-- src/core/file_sys/romfs_factory.h | 4 ++-- src/core/file_sys/savedata_factory.cpp | 7 ++++--- src/core/file_sys/savedata_factory.h | 7 ++++--- src/core/file_sys/sdmc_factory.cpp | 2 +- src/core/file_sys/sdmc_factory.h | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index c3ee4a158..84cd4684c 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -35,7 +35,7 @@ void RomFSFactory::SetPackedUpdate(VirtualFile update_raw) { this->update_raw = std::move(update_raw); } -ResultVal RomFSFactory::OpenCurrentProcess() { +ResultVal RomFSFactory::OpenCurrentProcess() const { if (!updatable) return MakeResult(file); @@ -44,7 +44,8 @@ ResultVal RomFSFactory::OpenCurrentProcess() { patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw)); } -ResultVal RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) { +ResultVal RomFSFactory::Open(u64 title_id, StorageId storage, + ContentRecordType type) const { std::shared_ptr res; switch (storage) { diff --git a/src/core/file_sys/romfs_factory.h b/src/core/file_sys/romfs_factory.h index 7724c0b23..da63a313a 100644 --- a/src/core/file_sys/romfs_factory.h +++ b/src/core/file_sys/romfs_factory.h @@ -33,8 +33,8 @@ public: ~RomFSFactory(); void SetPackedUpdate(VirtualFile update_raw); - ResultVal OpenCurrentProcess(); - ResultVal Open(u64 title_id, StorageId storage, ContentRecordType type); + ResultVal OpenCurrentProcess() const; + ResultVal Open(u64 title_id, StorageId storage, ContentRecordType type) const; private: VirtualFile file; diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index c63815332..f77cc02ac 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -71,7 +71,7 @@ SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save SaveDataFactory::~SaveDataFactory() = default; ResultVal SaveDataFactory::Create(SaveDataSpaceId space, - const SaveDataDescriptor& meta) { + const SaveDataDescriptor& meta) const { PrintSaveDataDescriptorWarnings(meta); const auto save_directory = @@ -88,7 +88,8 @@ ResultVal SaveDataFactory::Create(SaveDataSpaceId space, return MakeResult(std::move(out)); } -ResultVal SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataDescriptor& meta) { +ResultVal SaveDataFactory::Open(SaveDataSpaceId space, + const SaveDataDescriptor& meta) const { const auto save_directory = GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); @@ -165,7 +166,7 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, } void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, - SaveDataSize new_value) { + SaveDataSize new_value) const { const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0); const auto dir = GetOrCreateDirectoryRelative(this->dir, path); diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index 738038ee0..991e57aa1 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h @@ -64,8 +64,8 @@ public: explicit SaveDataFactory(VirtualDir dir); ~SaveDataFactory(); - ResultVal Create(SaveDataSpaceId space, const SaveDataDescriptor& meta); - ResultVal Open(SaveDataSpaceId space, const SaveDataDescriptor& meta); + ResultVal Create(SaveDataSpaceId space, const SaveDataDescriptor& meta) const; + ResultVal Open(SaveDataSpaceId space, const SaveDataDescriptor& meta) const; VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; @@ -74,7 +74,8 @@ public: u128 user_id, u64 save_id); SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; - void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, SaveDataSize new_value); + void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, + SaveDataSize new_value) const; private: VirtualDir dir; diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index 743e2e63a..5113a1ca6 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -21,7 +21,7 @@ SDMCFactory::SDMCFactory(VirtualDir dir_) SDMCFactory::~SDMCFactory() = default; -ResultVal SDMCFactory::Open() { +ResultVal SDMCFactory::Open() const { return MakeResult(dir); } diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 164fd9435..42dc4e08a 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h @@ -19,7 +19,7 @@ public: explicit SDMCFactory(VirtualDir dir); ~SDMCFactory(); - ResultVal Open(); + ResultVal Open() const; VirtualDir GetSDMCContentDirectory() const; -- cgit v1.2.3 From 038bcec11153cefd713ddb06eddcc42b0a936df2 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 21 Sep 2019 18:43:11 -0400 Subject: configure_debug: Move reporting option to logging --- src/core/file_sys/registered_cache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index d1ef1e72d..ac3fbd849 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -59,12 +59,12 @@ static std::string GetRelativePathFromNcaID(const std::array& nca_id, bo bool within_two_digit, bool cnmt_suffix) { if (!within_two_digit) return fmt::format(cnmt_suffix ? "{}.cnmt.nca" : "/{}.nca", - Common::HexArrayToString(nca_id, second_hex_upper)); + Common::HexToString(nca_id, second_hex_upper)); Core::Crypto::SHA256Hash hash{}; mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); return fmt::format(cnmt_suffix ? "/000000{:02X}/{}.cnmt.nca" : "/000000{:02X}/{}.nca", hash[0], - Common::HexArrayToString(nca_id, second_hex_upper)); + Common::HexToString(nca_id, second_hex_upper)); } static std::string GetCNMTName(TitleType type, u64 title_id) { @@ -149,7 +149,7 @@ bool PlaceholderCache::Create(const NcaID& id, u64 size) const { if (dir2 == nullptr) return false; - const auto file = dir2->CreateFile(fmt::format("{}.nca", Common::HexArrayToString(id, false))); + const auto file = dir2->CreateFile(fmt::format("{}.nca", Common::HexToString(id, false))); if (file == nullptr) return false; @@ -170,7 +170,7 @@ bool PlaceholderCache::Delete(const NcaID& id) const { const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname); - const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexArrayToString(id, false))); + const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexToString(id, false))); return res; } -- cgit v1.2.3