summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-28 22:37:42 -0400
committerGravatar Zach Hilman2018-09-04 16:24:02 -0400
commita6e75cd45b75a202eed1a68692e33e7732789dd2 (patch)
tree48af4f9227030e247474334067515a5cdd0f5283 /src/core/file_sys
parentbktr: Fix missing includes and optimize style (diff)
downloadyuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.gz
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.xz
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.zip
bktr: Implement IVFC offset shifting
Fixes base game read errors
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/content_archive.cpp13
-rw-r--r--src/core/file_sys/content_archive.h7
-rw-r--r--src/core/file_sys/nca_patch.cpp2
-rw-r--r--src/core/file_sys/romfs_factory.cpp5
-rw-r--r--src/core/file_sys/romfs_factory.h1
5 files changed, 20 insertions, 8 deletions
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index f0d376bf5..26e1daf55 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -215,7 +215,7 @@ VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting
215 } 215 }
216} 216}
217 217
218NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_) 218NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_offset)
219 : file(std::move(file_)), 219 : file(std::move(file_)),
220 bktr_base_romfs(bktr_base_romfs_ ? std::move(bktr_base_romfs_) : nullptr) { 220 bktr_base_romfs(bktr_base_romfs_ ? std::move(bktr_base_romfs_) : nullptr) {
221 status = Loader::ResultStatus::Success; 221 status = Loader::ResultStatus::Success;
@@ -292,6 +292,7 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
292 is_update = std::find_if(sections.begin(), sections.end(), [](const NCASectionHeader& header) { 292 is_update = std::find_if(sections.begin(), sections.end(), [](const NCASectionHeader& header) {
293 return header.raw.header.crypto_type == NCASectionCryptoType::BKTR; 293 return header.raw.header.crypto_type == NCASectionCryptoType::BKTR;
294 }) != sections.end(); 294 }) != sections.end();
295 ivfc_offset = 0;
295 296
296 for (std::ptrdiff_t i = 0; i < number_sections; ++i) { 297 for (std::ptrdiff_t i = 0; i < number_sections; ++i) {
297 auto section = sections[i]; 298 auto section = sections[i];
@@ -299,8 +300,8 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
299 if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) { 300 if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) {
300 const size_t base_offset = 301 const size_t base_offset =
301 header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER; 302 header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER;
302 const size_t romfs_offset = 303 ivfc_offset = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
303 base_offset + section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset; 304 const size_t romfs_offset = base_offset + ivfc_offset;
304 const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size; 305 const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size;
305 auto raw = std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset); 306 auto raw = std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset);
306 auto dec = Decrypt(section, raw, romfs_offset); 307 auto dec = Decrypt(section, raw, romfs_offset);
@@ -414,7 +415,7 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
414 bktr_base_romfs, std::make_shared<OffsetVfsFile>(file, romfs_size, base_offset), 415 bktr_base_romfs, std::make_shared<OffsetVfsFile>(file, romfs_size, base_offset),
415 relocation_block, relocation_buckets, subsection_block, subsection_buckets, 416 relocation_block, relocation_buckets, subsection_block, subsection_buckets,
416 encrypted, encrypted ? key.get() : Core::Crypto::Key128{}, base_offset, 417 encrypted, encrypted ? key.get() : Core::Crypto::Key128{}, base_offset,
417 romfs_offset - base_offset, section.raw.section_ctr); 418 bktr_base_ivfc_offset, section.raw.section_ctr);
418 419
419 // BKTR applies to entire IVFC, so make an offset version to level 6 420 // BKTR applies to entire IVFC, so make an offset version to level 6
420 421
@@ -511,6 +512,10 @@ VirtualFile NCA::GetBaseFile() const {
511 return file; 512 return file;
512} 513}
513 514
515u64 NCA::GetBaseIVFCOffset() const {
516 return ivfc_offset;
517}
518
514bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { 519bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
515 return false; 520 return false;
516} 521}
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h
index 104226f3a..00eca52da 100644
--- a/src/core/file_sys/content_archive.h
+++ b/src/core/file_sys/content_archive.h
@@ -79,7 +79,8 @@ bool IsValidNCA(const NCAHeader& header);
79// After construction, use GetStatus to determine if the file is valid and ready to be used. 79// After construction, use GetStatus to determine if the file is valid and ready to be used.
80class NCA : public ReadOnlyVfsDirectory { 80class NCA : public ReadOnlyVfsDirectory {
81public: 81public:
82 explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr); 82 explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr,
83 u64 bktr_base_ivfc_offset = 0);
83 Loader::ResultStatus GetStatus() const; 84 Loader::ResultStatus GetStatus() const;
84 85
85 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; 86 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
@@ -96,6 +97,9 @@ public:
96 97
97 VirtualFile GetBaseFile() const; 98 VirtualFile GetBaseFile() const;
98 99
100 // Returns the base ivfc offset used in BKTR patching.
101 u64 GetBaseIVFCOffset() const;
102
99protected: 103protected:
100 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; 104 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
101 105
@@ -112,6 +116,7 @@ private:
112 VirtualDir exefs = nullptr; 116 VirtualDir exefs = nullptr;
113 VirtualFile file; 117 VirtualFile file;
114 VirtualFile bktr_base_romfs; 118 VirtualFile bktr_base_romfs;
119 u64 ivfc_offset;
115 120
116 NCAHeader header{}; 121 NCAHeader header{};
117 bool has_rights_id{}; 122 bool has_rights_id{};
diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp
index 22fbba573..e293af452 100644
--- a/src/core/file_sys/nca_patch.cpp
+++ b/src/core/file_sys/nca_patch.cpp
@@ -51,7 +51,7 @@ size_t BKTR::Read(u8* data, size_t length, size_t offset) const {
51 51
52 if (!bktr_read) { 52 if (!bktr_read) {
53 ASSERT_MSG(section_offset > ivfc_offset, "Offset calculation negative."); 53 ASSERT_MSG(section_offset > ivfc_offset, "Offset calculation negative.");
54 return base_romfs->Read(data, length, section_offset); 54 return base_romfs->Read(data, length, section_offset - ivfc_offset);
55 } 55 }
56 56
57 if (!encrypted) { 57 if (!encrypted) {
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp
index fc9cf1eca..33ec62491 100644
--- a/src/core/file_sys/romfs_factory.cpp
+++ b/src/core/file_sys/romfs_factory.cpp
@@ -24,14 +24,15 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) {
24 } 24 }
25 25
26 updatable = app_loader.IsRomFSUpdatable(); 26 updatable = app_loader.IsRomFSUpdatable();
27 ivfc_offset = app_loader.ReadRomFSIVFCOffset();
27} 28}
28 29
29ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() { 30ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
30 if (!updatable) 31 if (!updatable)
31 return MakeResult<VirtualFile>(file); 32 return MakeResult<VirtualFile>(file);
32 33
33 const PatchManager patch_manager(Core::CurrentProcess()->process_id); 34 const PatchManager patch_manager(Core::CurrentProcess()->program_id);
34 return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file)); 35 return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset));
35} 36}
36 37
37ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) { 38ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) {
diff --git a/src/core/file_sys/romfs_factory.h b/src/core/file_sys/romfs_factory.h
index 168db1c46..26b8f46cc 100644
--- a/src/core/file_sys/romfs_factory.h
+++ b/src/core/file_sys/romfs_factory.h
@@ -37,6 +37,7 @@ public:
37private: 37private:
38 VirtualFile file; 38 VirtualFile file;
39 bool updatable; 39 bool updatable;
40 u64 ivfc_offset;
40}; 41};
41 42
42} // namespace FileSys 43} // namespace FileSys