summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar liamwhite2023-08-21 16:09:22 -0400
committerGravatar GitHub2023-08-21 16:09:22 -0400
commit9d6ac28999330ff5118ee60eeb0468e88ebbbcd0 (patch)
tree883f7b3185e58e530ec41bb08315c4f7c2fb8b81
parentMerge pull request #11342 from liamwhite/skyline-4 (diff)
parentfile_sys/card_image: support dumps with prepended key area (diff)
downloadyuzu-9d6ac28999330ff5118ee60eeb0468e88ebbbcd0.tar.gz
yuzu-9d6ac28999330ff5118ee60eeb0468e88ebbbcd0.tar.xz
yuzu-9d6ac28999330ff5118ee60eeb0468e88ebbbcd0.zip
Merge pull request #11309 from liamwhite/full-xci
file_sys/card_image: support dumps with prepended key area
Diffstat (limited to '')
-rw-r--r--src/core/file_sys/card_image.cpp48
-rw-r--r--src/core/file_sys/card_image.h1
2 files changed, 42 insertions, 7 deletions
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
index 3b2588c84..8b9a4fc5a 100644
--- a/src/core/file_sys/card_image.cpp
+++ b/src/core/file_sys/card_image.cpp
@@ -31,13 +31,9 @@ XCI::XCI(VirtualFile file_, u64 program_id, size_t program_index)
31 : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, 31 : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA},
32 partitions(partition_names.size()), 32 partitions(partition_names.size()),
33 partitions_raw(partition_names.size()), keys{Core::Crypto::KeyManager::Instance()} { 33 partitions_raw(partition_names.size()), keys{Core::Crypto::KeyManager::Instance()} {
34 if (file->ReadObject(&header) != sizeof(GamecardHeader)) { 34 const auto header_status = TryReadHeader();
35 status = Loader::ResultStatus::ErrorBadXCIHeader; 35 if (header_status != Loader::ResultStatus::Success) {
36 return; 36 status = header_status;
37 }
38
39 if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) {
40 status = Loader::ResultStatus::ErrorBadXCIHeader;
41 return; 37 return;
42 } 38 }
43 39
@@ -316,6 +312,44 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
316 return Loader::ResultStatus::Success; 312 return Loader::ResultStatus::Success;
317} 313}
318 314
315Loader::ResultStatus XCI::TryReadHeader() {
316 constexpr size_t CardInitialDataRegionSize = 0x1000;
317
318 // Define the function we'll use to determine if we read a valid header.
319 const auto ReadCardHeader = [&]() {
320 // Ensure we can read the entire header. If we can't, we can't read the card image.
321 if (file->ReadObject(&header) != sizeof(GamecardHeader)) {
322 return Loader::ResultStatus::ErrorBadXCIHeader;
323 }
324
325 // Ensure the header magic matches. If it doesn't, this isn't a card image header.
326 if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) {
327 return Loader::ResultStatus::ErrorBadXCIHeader;
328 }
329
330 // We read a card image header.
331 return Loader::ResultStatus::Success;
332 };
333
334 // Try to read the header directly.
335 if (ReadCardHeader() == Loader::ResultStatus::Success) {
336 return Loader::ResultStatus::Success;
337 }
338
339 // Get the size of the file.
340 const size_t card_image_size = file->GetSize();
341
342 // If we are large enough to have a key area, offset past the key area and retry.
343 if (card_image_size >= CardInitialDataRegionSize) {
344 file = std::make_shared<OffsetVfsFile>(file, card_image_size - CardInitialDataRegionSize,
345 CardInitialDataRegionSize);
346 return ReadCardHeader();
347 }
348
349 // We had no header and aren't large enough to have a key area, so this can't be parsed.
350 return Loader::ResultStatus::ErrorBadXCIHeader;
351}
352
319u8 XCI::GetFormatVersion() { 353u8 XCI::GetFormatVersion() {
320 return GetLogoPartition() == nullptr ? 0x1 : 0x2; 354 return GetLogoPartition() == nullptr ? 0x1 : 0x2;
321} 355}
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h
index 1283f8216..9886123e7 100644
--- a/src/core/file_sys/card_image.h
+++ b/src/core/file_sys/card_image.h
@@ -128,6 +128,7 @@ public:
128 128
129private: 129private:
130 Loader::ResultStatus AddNCAFromPartition(XCIPartition part); 130 Loader::ResultStatus AddNCAFromPartition(XCIPartition part);
131 Loader::ResultStatus TryReadHeader();
131 132
132 VirtualFile file; 133 VirtualFile file;
133 GamecardHeader header{}; 134 GamecardHeader header{};