summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-04-10 12:24:44 -0400
committerGravatar Zach Hilman2019-09-21 16:43:10 -0400
commit9d9fc8a675ffa35998830a0a5670dd1ca288112f (patch)
treea6d014316eb92ea2209c73df5c5b6fbfe56d9f72 /src
parentregistered_cache: Implement PlaceholderCache to manage placeholder and instal... (diff)
downloadyuzu-9d9fc8a675ffa35998830a0a5670dd1ca288112f.tar.gz
yuzu-9d9fc8a675ffa35998830a0a5670dd1ca288112f.tar.xz
yuzu-9d9fc8a675ffa35998830a0a5670dd1ca288112f.zip
registered_cache: Process *.cnmt.nca files
Needed to use the RegisteredCache/PlaceholderCache on gamecards.
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/registered_cache.cpp39
1 files changed, 23 insertions, 16 deletions
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) {
48static bool FollowsNcaIdFormat(std::string_view name) { 48static bool FollowsNcaIdFormat(std::string_view name) {
49 static const std::regex nca_id_regex("[0-9A-F]{32}\\.nca", std::regex_constants::ECMAScript | 49 static const std::regex nca_id_regex("[0-9A-F]{32}\\.nca", std::regex_constants::ECMAScript |
50 std::regex_constants::icase); 50 std::regex_constants::icase);
51 return name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex); 51 static const std::regex nca_id_cnmt_regex(
52 "[0-9A-F]{32}\\.cnmt.nca", std::regex_constants::ECMAScript | std::regex_constants::icase);
53 return (name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex)) ||
54 (name.size() == 41 && std::regex_match(name.begin(), name.end(), nca_id_cnmt_regex));
52} 55}
53 56
54static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bool second_hex_upper, 57static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bool second_hex_upper,
55 bool within_two_digit) { 58 bool within_two_digit, bool cnmt_suffix) {
56 if (!within_two_digit) { 59 if (!within_two_digit)
57 return fmt::format("/{}.nca", Common::HexToString(nca_id, second_hex_upper)); 60 return fmt::format(cnmt_suffix ? "{}.cnmt.nca" : "/{}.nca",
58 } 61 Common::HexArrayToString(nca_id, second_hex_upper));
59 62
60 Core::Crypto::SHA256Hash hash{}; 63 Core::Crypto::SHA256Hash hash{};
61 mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); 64 mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
62 return fmt::format("/000000{:02X}/{}.nca", hash[0], 65 return fmt::format(cnmt_suffix ? "/000000{:02X}/{}.cnmt.nca" : "/000000{:02X}/{}.nca", hash[0],
63 Common::HexToString(nca_id, second_hex_upper)); 66 Common::HexArrayToString(nca_id, second_hex_upper));
64} 67}
65 68
66static std::string GetCNMTName(TitleType type, u64 title_id) { 69static std::string GetCNMTName(TitleType type, u64 title_id) {
@@ -319,14 +322,18 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir,
319 322
320VirtualFile RegisteredCache::GetFileAtID(NcaID id) const { 323VirtualFile RegisteredCache::GetFileAtID(NcaID id) const {
321 VirtualFile file; 324 VirtualFile file;
322 // Try all four modes of file storage: 325 // Try all five relevant modes of file storage:
323 // (bit 1 = uppercase/lower, bit 0 = within a two-digit dir) 326 // (bit 2 = uppercase/lower, bit 1 = within a two-digit dir, bit 0 = .cnmt suffix)
324 // 00: /000000**/{:032X}.nca 327 // 000: /000000**/{:032X}.nca
325 // 01: /{:032X}.nca 328 // 010: /{:032X}.nca
326 // 10: /000000**/{:032x}.nca 329 // 100: /000000**/{:032x}.nca
327 // 11: /{:032x}.nca 330 // 110: /{:032x}.nca
328 for (u8 i = 0; i < 4; ++i) { 331 // 111: /{:032x}.cnmt.nca
329 const auto path = GetRelativePathFromNcaID(id, (i & 0b10) == 0, (i & 0b01) == 0); 332 for (u8 i = 0; i < 8; ++i) {
333 if ((i % 2) == 1 && i != 7)
334 continue;
335 const auto path =
336 GetRelativePathFromNcaID(id, (i & 0b100) == 0, (i & 0b010) == 0, (i & 0b001) == 0b001);
330 file = OpenFileOrDirectoryConcat(dir, path); 337 file = OpenFileOrDirectoryConcat(dir, path);
331 if (file != nullptr) 338 if (file != nullptr)
332 return file; 339 return file;
@@ -622,7 +629,7 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti
622 memcpy(id.data(), hash.data(), 16); 629 memcpy(id.data(), hash.data(), 16);
623 } 630 }
624 631
625 std::string path = GetRelativePathFromNcaID(id, false, true); 632 std::string path = GetRelativePathFromNcaID(id, false, true, false);
626 633
627 if (GetFileAtID(id) != nullptr && !overwrite_if_exists) { 634 if (GetFileAtID(id) != nullptr && !overwrite_if_exists) {
628 LOG_WARNING(Loader, "Attempting to overwrite existing NCA. Skipping..."); 635 LOG_WARNING(Loader, "Attempting to overwrite existing NCA. Skipping...");