From 3895f7e4562a02ee07cac6908787802bddf2c092 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 22 Sep 2019 21:44:36 -0400 Subject: pfs: Provide accessors for file sizes and offsets --- src/core/file_sys/partition_filesystem.cpp | 11 +++++++++++ src/core/file_sys/partition_filesystem.h | 6 ++++++ 2 files changed, 17 insertions(+) (limited to 'src/core') diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index a5259a593..932409d79 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp @@ -65,6 +65,9 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr file) { std::string name( reinterpret_cast(&file_data[strtab_offset + entry.strtab_offset])); + offsets[name] = content_offset + entry.offset; + sizes[name] = entry.size; + pfs_files.emplace_back(std::make_shared( file, entry.size, content_offset + entry.offset, std::move(name))); } @@ -78,6 +81,14 @@ Loader::ResultStatus PartitionFilesystem::GetStatus() const { return status; } +std::map PartitionFilesystem::GetFileOffsets() const { + return offsets; +} + +std::map PartitionFilesystem::GetFileSizes() const { + return sizes; +} + std::vector> PartitionFilesystem::GetFiles() const { return pfs_files; } diff --git a/src/core/file_sys/partition_filesystem.h b/src/core/file_sys/partition_filesystem.h index 248fdfdeb..279193b19 100644 --- a/src/core/file_sys/partition_filesystem.h +++ b/src/core/file_sys/partition_filesystem.h @@ -29,6 +29,9 @@ public: Loader::ResultStatus GetStatus() const; + std::map GetFileOffsets() const; + std::map GetFileSizes() const; + std::vector> GetFiles() const override; std::vector> GetSubdirectories() const override; std::string GetName() const override; @@ -80,6 +83,9 @@ private: bool is_hfs = false; std::size_t content_offset = 0; + std::map offsets; + std::map sizes; + std::vector pfs_files; }; -- cgit v1.2.3 From 3952c73aee27d6d1401e0280c4f3432dd0ddecf5 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 22 Sep 2019 21:50:29 -0400 Subject: card_image: Lazily load partitions in XCI --- src/core/file_sys/card_image.cpp | 51 ++++++++++++++++++++++++---------------- src/core/file_sys/card_image.h | 16 ++++++++----- 2 files changed, 41 insertions(+), 26 deletions(-) (limited to 'src/core') diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index db54113a0..c79f0885e 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -31,7 +31,7 @@ constexpr std::array partition_names{ XCI::XCI(VirtualFile file_) : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, - partitions(partition_names.size()) { + partitions(partition_names.size()), partitions_raw(partition_names.size()) { if (file->ReadObject(&header) != sizeof(GamecardHeader)) { status = Loader::ResultStatus::ErrorBadXCIHeader; return; @@ -42,8 +42,10 @@ XCI::XCI(VirtualFile file_) return; } - PartitionFilesystem main_hfs( - std::make_shared(file, header.hfs_size, header.hfs_offset)); + PartitionFilesystem main_hfs(std::make_shared( + file, file->GetSize() - header.hfs_offset, header.hfs_offset)); + + update_normal_partition_end = main_hfs.GetFileOffsets()["secure"]; if (main_hfs.GetStatus() != Loader::ResultStatus::Success) { status = main_hfs.GetStatus(); @@ -55,9 +57,7 @@ XCI::XCI(VirtualFile file_) const auto partition_idx = static_cast(partition); auto raw = main_hfs.GetFile(partition_names[partition_idx]); - if (raw != nullptr) { - partitions[partition_idx] = std::make_shared(std::move(raw)); - } + partitions_raw[static_cast(partition)] = raw; } secure_partition = std::make_shared( @@ -71,13 +71,7 @@ XCI::XCI(VirtualFile file_) program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; } - auto result = AddNCAFromPartition(XCIPartition::Update); - if (result != Loader::ResultStatus::Success) { - status = result; - return; - } - - result = AddNCAFromPartition(XCIPartition::Normal); + auto result = AddNCAFromPartition(XCIPartition::Normal); if (result != Loader::ResultStatus::Success) { status = result; return; @@ -104,27 +98,44 @@ Loader::ResultStatus XCI::GetProgramNCAStatus() const { return program_nca_status; } -VirtualDir XCI::GetPartition(XCIPartition partition) const { +VirtualDir XCI::GetPartition(XCIPartition partition) { + const auto id = static_cast(partition); + if (partitions[id] == nullptr && partitions_raw[id] != nullptr) { + partitions[id] = std::make_shared(partitions_raw[id]); + } + return partitions[static_cast(partition)]; } +std::vector XCI::GetPartitions() { + std::vector out; + for (const auto& id : + {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { + const auto part = GetPartition(id); + if (part != nullptr) { + out.push_back(part); + } + } + return out; +} + std::shared_ptr XCI::GetSecurePartitionNSP() const { return secure_partition; } -VirtualDir XCI::GetSecurePartition() const { +VirtualDir XCI::GetSecurePartition() { return GetPartition(XCIPartition::Secure); } -VirtualDir XCI::GetNormalPartition() const { +VirtualDir XCI::GetNormalPartition() { return GetPartition(XCIPartition::Normal); } -VirtualDir XCI::GetUpdatePartition() const { +VirtualDir XCI::GetUpdatePartition() { return GetPartition(XCIPartition::Update); } -VirtualDir XCI::GetLogoPartition() const { +VirtualDir XCI::GetLogoPartition() { return GetPartition(XCIPartition::Logo); } @@ -201,7 +212,7 @@ std::array XCI::GetCertificate() const { Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { const auto partition_index = static_cast(part); - const auto& partition = partitions[partition_index]; + const auto partition = GetPartition(part); if (partition == nullptr) { return Loader::ResultStatus::ErrorXCIMissingPartition; @@ -232,7 +243,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { return Loader::ResultStatus::Success; } -u8 XCI::GetFormatVersion() const { +u8 XCI::GetFormatVersion() { return GetLogoPartition() == nullptr ? 0x1 : 0x2; } } // namespace FileSys diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index 3e6b92ff3..ea2ad7741 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -81,14 +81,17 @@ public: Loader::ResultStatus GetStatus() const; Loader::ResultStatus GetProgramNCAStatus() const; - u8 GetFormatVersion() const; + u8 GetFormatVersion(); + + VirtualDir GetPartition(XCIPartition partition); + std::vector GetPartitions(); - VirtualDir GetPartition(XCIPartition partition) const; std::shared_ptr GetSecurePartitionNSP() const; - VirtualDir GetSecurePartition() const; - VirtualDir GetNormalPartition() const; - VirtualDir GetUpdatePartition() const; - VirtualDir GetLogoPartition() const; + VirtualDir GetSecurePartition(); + VirtualDir GetNormalPartition(); + VirtualDir GetUpdatePartition(); + VirtualDir GetLogoPartition(); + u64 GetProgramTitleID() const; u32 GetSystemUpdateVersion(); @@ -123,6 +126,7 @@ private: Loader::ResultStatus program_nca_status; std::vector partitions; + std::vector partitions_raw; std::shared_ptr secure_partition; std::shared_ptr program; std::vector> ncas; -- cgit v1.2.3 From c4f3400bead6b666b803e3990a4aba625a2dfe70 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 22 Sep 2019 21:51:46 -0400 Subject: card_image: Add accessors for raw partitions in XCI --- src/core/file_sys/card_image.cpp | 29 +++++++++++++++++++++++++++++ src/core/file_sys/card_image.h | 7 +++++++ 2 files changed, 36 insertions(+) (limited to 'src/core') diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index c79f0885e..a6a68b748 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -139,6 +139,35 @@ VirtualDir XCI::GetLogoPartition() { return GetPartition(XCIPartition::Logo); } +VirtualFile XCI::GetPartitionRaw(XCIPartition partition) const { + return partitions_raw[static_cast(partition)]; +} + +VirtualFile XCI::GetSecurePartitionRaw() const { + return GetPartitionRaw(XCIPartition::Secure); +} + +VirtualFile XCI::GetStoragePartition0() const { + return std::make_shared(file, update_normal_partition_end, 0, "partition0"); +} + +VirtualFile XCI::GetStoragePartition1() const { + return std::make_shared(file, file->GetSize() - update_normal_partition_end, + update_normal_partition_end, "partition1"); +} + +VirtualFile XCI::GetNormalPartitionRaw() const { + return GetPartitionRaw(XCIPartition::Normal); +} + +VirtualFile XCI::GetUpdatePartitionRaw() const { + return GetPartitionRaw(XCIPartition::Update); +} + +VirtualFile XCI::GetLogoPartitionRaw() const { + return GetPartitionRaw(XCIPartition::Logo); +} + u64 XCI::GetProgramTitleID() const { return secure_partition->GetProgramTitleID(); } diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index ea2ad7741..c2ee0ea99 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -92,6 +92,13 @@ public: VirtualDir GetUpdatePartition(); VirtualDir GetLogoPartition(); + VirtualFile GetPartitionRaw(XCIPartition partition) const; + VirtualFile GetSecurePartitionRaw() const; + VirtualFile GetStoragePartition0() const; + VirtualFile GetStoragePartition1() const; + VirtualFile GetNormalPartitionRaw() const; + VirtualFile GetUpdatePartitionRaw() const; + VirtualFile GetLogoPartitionRaw() const; u64 GetProgramTitleID() const; u32 GetSystemUpdateVersion(); -- cgit v1.2.3 From e0b9ee9b941f3fb47a5b219d27c37081f379d05a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 13 Oct 2019 14:18:09 -0400 Subject: card_image: Implement system update commands in XCI --- src/core/file_sys/card_image.cpp | 36 +++++++++++++++++++++++++++++- src/core/file_sys/partition_filesystem.cpp | 4 ++-- 2 files changed, 37 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index a6a68b748..07d0c8d5d 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -57,7 +57,7 @@ XCI::XCI(VirtualFile file_) const auto partition_idx = static_cast(partition); auto raw = main_hfs.GetFile(partition_names[partition_idx]); - partitions_raw[static_cast(partition)] = raw; + partitions_raw[static_cast(partition)] = std::move(raw); } secure_partition = std::make_shared( @@ -172,6 +172,40 @@ u64 XCI::GetProgramTitleID() const { return secure_partition->GetProgramTitleID(); } +u32 XCI::GetSystemUpdateVersion() { + const auto update = GetPartition(XCIPartition::Update); + if (update == nullptr) + return 0; + + for (const auto& file : update->GetFiles()) { + NCA nca{file, nullptr, 0, keys}; + + if (nca.GetStatus() != Loader::ResultStatus::Success) + continue; + + if (nca.GetType() == NCAContentType::Meta && nca.GetTitleId() == 0x0100000000000816) { + const auto dir = nca.GetSubdirectories()[0]; + const auto cnmt = dir->GetFile("SystemUpdate_0100000000000816.cnmt"); + if (cnmt == nullptr) + continue; + + CNMT cnmt_data{cnmt}; + + const auto metas = cnmt_data.GetMetaRecords(); + if (metas.empty()) + continue; + + return metas[0].title_version; + } + } + + return 0; +} + +u64 XCI::GetSystemUpdateTitleID() const { + return 0x0100000000000816; +} + bool XCI::HasProgramNCA() const { return program != nullptr; } diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 932409d79..846986736 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp @@ -65,8 +65,8 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr file) { std::string name( reinterpret_cast(&file_data[strtab_offset + entry.strtab_offset])); - offsets[name] = content_offset + entry.offset; - sizes[name] = entry.size; + offsets.insert_or_assign(name, content_offset + entry.offset); + sizes.insert_or_assign(name, entry.size); pfs_files.emplace_back(std::make_shared( file, entry.size, content_offset + entry.offset, std::move(name))); -- cgit v1.2.3