summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZach Hilman <zachhilman@gmail.com>2018-08-29 04:37:42 +0200
committerZach Hilman <zachhilman@gmail.com>2018-09-04 22:24:02 +0200
commita6e75cd45b75a202eed1a68692e33e7732789dd2 (patch)
tree48af4f9227030e247474334067515a5cdd0f5283
parentbktr: Fix missing includes and optimize style (diff)
downloadyuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.gz
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.bz2
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.lz
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.xz
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.tar.zst
yuzu-a6e75cd45b75a202eed1a68692e33e7732789dd2.zip
-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
-rw-r--r--src/core/loader/loader.h9
-rw-r--r--src/core/loader/nca.cpp6
-rw-r--r--src/core/loader/nca.h1
8 files changed, 36 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
}
}
-NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
+NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_offset)
: file(std::move(file_)),
bktr_base_romfs(bktr_base_romfs_ ? std::move(bktr_base_romfs_) : nullptr) {
status = Loader::ResultStatus::Success;
@@ -292,6 +292,7 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
is_update = std::find_if(sections.begin(), sections.end(), [](const NCASectionHeader& header) {
return header.raw.header.crypto_type == NCASectionCryptoType::BKTR;
}) != sections.end();
+ ivfc_offset = 0;
for (std::ptrdiff_t i = 0; i < number_sections; ++i) {
auto section = sections[i];
@@ -299,8 +300,8 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) {
const size_t base_offset =
header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER;
- const size_t romfs_offset =
- base_offset + section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
+ ivfc_offset = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
+ const size_t romfs_offset = base_offset + ivfc_offset;
const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size;
auto raw = std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset);
auto dec = Decrypt(section, raw, romfs_offset);
@@ -414,7 +415,7 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_)
bktr_base_romfs, std::make_shared<OffsetVfsFile>(file, romfs_size, base_offset),
relocation_block, relocation_buckets, subsection_block, subsection_buckets,
encrypted, encrypted ? key.get() : Core::Crypto::Key128{}, base_offset,
- romfs_offset - base_offset, section.raw.section_ctr);
+ bktr_base_ivfc_offset, section.raw.section_ctr);
// BKTR applies to entire IVFC, so make an offset version to level 6
@@ -511,6 +512,10 @@ VirtualFile NCA::GetBaseFile() const {
return file;
}
+u64 NCA::GetBaseIVFCOffset() const {
+ return ivfc_offset;
+}
+
bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
return false;
}
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);
// After construction, use GetStatus to determine if the file is valid and ready to be used.
class NCA : public ReadOnlyVfsDirectory {
public:
- explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr);
+ explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr,
+ u64 bktr_base_ivfc_offset = 0);
Loader::ResultStatus GetStatus() const;
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
@@ -96,6 +97,9 @@ public:
VirtualFile GetBaseFile() const;
+ // Returns the base ivfc offset used in BKTR patching.
+ u64 GetBaseIVFCOffset() const;
+
protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
@@ -112,6 +116,7 @@ private:
VirtualDir exefs = nullptr;
VirtualFile file;
VirtualFile bktr_base_romfs;
+ u64 ivfc_offset;
NCAHeader header{};
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 {
if (!bktr_read) {
ASSERT_MSG(section_offset > ivfc_offset, "Offset calculation negative.");
- return base_romfs->Read(data, length, section_offset);
+ return base_romfs->Read(data, length, section_offset - ivfc_offset);
}
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) {
}
updatable = app_loader.IsRomFSUpdatable();
+ ivfc_offset = app_loader.ReadRomFSIVFCOffset();
}
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
if (!updatable)
return MakeResult<VirtualFile>(file);
- const PatchManager patch_manager(Core::CurrentProcess()->process_id);
- return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file));
+ const PatchManager patch_manager(Core::CurrentProcess()->program_id);
+ return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset));
}
ResultVal<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:
private:
VirtualFile file;
bool updatable;
+ u64 ivfc_offset;
};
} // namespace FileSys
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 225c05127..843c4bb91 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -215,6 +215,15 @@ public:
}
/**
+ * Gets the difference between the start of the IVFC header and the start of level 6 (RomFS)
+ * data. Needed for bktr patching.
+ * @return IVFC offset for romfs.
+ */
+ virtual u64 ReadRomFSIVFCOffset() const {
+ return 0;
+ }
+
+ /**
* Get the title of the application
* @param title Reference to store the application title into
* @return ResultStatus result of function
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index 6b1c27b47..6aaffae59 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -71,6 +71,12 @@ ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
return ResultStatus::Success;
}
+u64 AppLoader_NCA::ReadRomFSIVFCOffset() const {
+ if (nca == nullptr)
+ return 0;
+ return nca->GetBaseIVFCOffset();
+}
+
ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
if (nca == nullptr || nca->GetStatus() != ResultStatus::Success)
return ResultStatus::ErrorNotInitialized;
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index 326f84857..10be197c4 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -37,6 +37,7 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
+ u64 ReadRomFSIVFCOffset() const override;
ResultStatus ReadProgramId(u64& out_program_id) override;
private: