diff options
| author | 2023-08-21 16:09:22 -0400 | |
|---|---|---|
| committer | 2023-08-21 16:09:22 -0400 | |
| commit | 9d6ac28999330ff5118ee60eeb0468e88ebbbcd0 (patch) | |
| tree | 883f7b3185e58e530ec41bb08315c4f7c2fb8b81 | |
| parent | Merge pull request #11342 from liamwhite/skyline-4 (diff) | |
| parent | file_sys/card_image: support dumps with prepended key area (diff) | |
| download | yuzu-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
| -rw-r--r-- | src/core/file_sys/card_image.cpp | 48 | ||||
| -rw-r--r-- | src/core/file_sys/card_image.h | 1 |
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 | ||
| 315 | Loader::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 | |||
| 319 | u8 XCI::GetFormatVersion() { | 353 | u8 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 | ||
| 129 | private: | 129 | private: |
| 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{}; |