summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2018-10-23 19:26:57 -0400
committerGravatar GitHub2018-10-23 19:26:57 -0400
commit5edb2403c2030162bbb602dfd8289c738acff0e3 (patch)
treefafcdebf8f3305deff1f8a2ebaa0ef14218bb41c /src/core
parentMerge pull request #1542 from lioncash/project (diff)
parentqt: Add support for dumping a DLC Data RomFS (diff)
downloadyuzu-5edb2403c2030162bbb602dfd8289c738acff0e3.tar.gz
yuzu-5edb2403c2030162bbb602dfd8289c738acff0e3.tar.xz
yuzu-5edb2403c2030162bbb602dfd8289c738acff0e3.zip
Merge pull request #1515 from DarkLordZach/dlc-lfs
patch_manager: Add support for LayeredFS on DLC RomFS
Diffstat (limited to 'src/core')
-rw-r--r--src/core/file_sys/patch_manager.cpp5
-rw-r--r--src/core/file_sys/registered_cache.cpp15
-rw-r--r--src/core/file_sys/registered_cache.h8
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp6
4 files changed, 29 insertions, 5 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 0117cb0bf..1f4928562 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -168,7 +168,8 @@ bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const {
168 168
169static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { 169static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) {
170 const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); 170 const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id);
171 if (type != ContentRecordType::Program || load_dir == nullptr || load_dir->GetSize() <= 0) { 171 if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
172 load_dir == nullptr || load_dir->GetSize() <= 0) {
172 return; 173 return;
173 } 174 }
174 175
@@ -218,7 +219,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
218 title_id, static_cast<u8>(type)) 219 title_id, static_cast<u8>(type))
219 .c_str(); 220 .c_str();
220 221
221 if (type == ContentRecordType::Program) 222 if (type == ContentRecordType::Program || type == ContentRecordType::Data)
222 LOG_INFO(Loader, log_string); 223 LOG_INFO(Loader, log_string);
223 else 224 else
224 LOG_DEBUG(Loader, log_string); 225 LOG_DEBUG(Loader, log_string);
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 1febb398e..29b100414 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <regex> 6#include <regex>
6#include <mbedtls/sha256.h> 7#include <mbedtls/sha256.h>
7#include "common/assert.h" 8#include "common/assert.h"
@@ -30,6 +31,14 @@ bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs)
30 return (lhs.title_id < rhs.title_id) || (lhs.title_id == rhs.title_id && lhs.type < rhs.type); 31 return (lhs.title_id < rhs.title_id) || (lhs.title_id == rhs.title_id && lhs.type < rhs.type);
31} 32}
32 33
34bool operator==(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs) {
35 return std::tie(lhs.title_id, lhs.type) == std::tie(rhs.title_id, rhs.type);
36}
37
38bool operator!=(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs) {
39 return !operator==(lhs, rhs);
40}
41
33static bool FollowsTwoDigitDirFormat(std::string_view name) { 42static bool FollowsTwoDigitDirFormat(std::string_view name) {
34 static const std::regex two_digit_regex("000000[0-9A-F]{2}", std::regex_constants::ECMAScript | 43 static const std::regex two_digit_regex("000000[0-9A-F]{2}", std::regex_constants::ECMAScript |
35 std::regex_constants::icase); 44 std::regex_constants::icase);
@@ -593,6 +602,9 @@ std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntries() const {
593 }, 602 },
594 [](const CNMT& c, const ContentRecord& r) { return true; }); 603 [](const CNMT& c, const ContentRecord& r) { return true; });
595 } 604 }
605
606 std::sort(out.begin(), out.end());
607 out.erase(std::unique(out.begin(), out.end()), out.end());
596 return out; 608 return out;
597} 609}
598 610
@@ -616,6 +628,9 @@ std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter(
616 return true; 628 return true;
617 }); 629 });
618 } 630 }
631
632 std::sort(out.begin(), out.end());
633 out.erase(std::unique(out.begin(), out.end()), out.end());
619 return out; 634 return out;
620} 635}
621} // namespace FileSys 636} // namespace FileSys
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index 5ddacba47..5beceffb3 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -50,6 +50,10 @@ constexpr u64 GetUpdateTitleID(u64 base_title_id) {
50// boost flat_map requires operator< for O(log(n)) lookups. 50// boost flat_map requires operator< for O(log(n)) lookups.
51bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs); 51bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs);
52 52
53// std unique requires operator== to identify duplicates.
54bool operator==(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs);
55bool operator!=(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs);
56
53/* 57/*
54 * A class that catalogues NCAs in the registered directory structure. 58 * A class that catalogues NCAs in the registered directory structure.
55 * Nintendo's registered format follows this structure: 59 * Nintendo's registered format follows this structure:
@@ -60,8 +64,8 @@ bool operator<(const RegisteredCacheEntry& lhs, const RegisteredCacheEntry& rhs)
60 * | 00 64 * | 00
61 * | 01 <- Actual content split along 4GB boundaries. (optional) 65 * | 01 <- Actual content split along 4GB boundaries. (optional)
62 * 66 *
63 * (This impl also supports substituting the nca dir for an nca file, as that's more convenient when 67 * (This impl also supports substituting the nca dir for an nca file, as that's more convenient
64 * 4GB splitting can be ignored.) 68 * when 4GB splitting can be ignored.)
65 */ 69 */
66class RegisteredCache { 70class RegisteredCache {
67 friend class RegisteredCacheUnion; 71 friend class RegisteredCacheUnion;
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index d5dced429..c87721c39 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -17,6 +17,7 @@
17#include "core/file_sys/errors.h" 17#include "core/file_sys/errors.h"
18#include "core/file_sys/mode.h" 18#include "core/file_sys/mode.h"
19#include "core/file_sys/nca_metadata.h" 19#include "core/file_sys/nca_metadata.h"
20#include "core/file_sys/patch_manager.h"
20#include "core/file_sys/savedata_factory.h" 21#include "core/file_sys/savedata_factory.h"
21#include "core/file_sys/vfs.h" 22#include "core/file_sys/vfs.h"
22#include "core/hle/ipc_helpers.h" 23#include "core/hle/ipc_helpers.h"
@@ -630,6 +631,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
630 static_cast<u8>(storage_id), unknown, title_id); 631 static_cast<u8>(storage_id), unknown, title_id);
631 632
632 auto data = OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data); 633 auto data = OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data);
634
633 if (data.Failed()) { 635 if (data.Failed()) {
634 // TODO(DarkLordZach): Find the right error code to use here 636 // TODO(DarkLordZach): Find the right error code to use here
635 LOG_ERROR(Service_FS, 637 LOG_ERROR(Service_FS,
@@ -640,7 +642,9 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
640 return; 642 return;
641 } 643 }
642 644
643 IStorage storage(std::move(data.Unwrap())); 645 FileSys::PatchManager pm{title_id};
646
647 IStorage storage(pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data));
644 648
645 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 649 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
646 rb.Push(RESULT_SUCCESS); 650 rb.Push(RESULT_SUCCESS);