From 8cf1132b2e1f4a09176801cc2d97b646b3d2bf88 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Mon, 1 Oct 2018 08:41:40 +0800 Subject: [PATCH] ncch_container: choose the first id as extdata id when extended save data access is used --- src/core/file_sys/ncch_container.cpp | 20 +++++++++++++++++++- src/core/file_sys/ncch_container.h | 18 ++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/core/file_sys/ncch_container.cpp b/src/core/file_sys/ncch_container.cpp index e817a004f..fbda4ba80 100644 --- a/src/core/file_sys/ncch_container.cpp +++ b/src/core/file_sys/ncch_container.cpp @@ -585,7 +585,25 @@ Loader::ResultStatus NCCHContainer::ReadExtdataId(u64& extdata_id) { return Loader::ResultStatus::ErrorNotUsed; if (exheader_header.arm11_system_local_caps.storage_info.other_attributes >> 1) { - // Extdata id is not present when using extended savedata access + // Using extended save data access + // There would be multiple possible extdata IDs in this case. The best we can do for now is + // guessing that the first one would be the main save. + const std::array extdata_ids{{ + exheader_header.arm11_system_local_caps.storage_info.extdata_id0.Value(), + exheader_header.arm11_system_local_caps.storage_info.extdata_id1.Value(), + exheader_header.arm11_system_local_caps.storage_info.extdata_id2.Value(), + exheader_header.arm11_system_local_caps.storage_info.extdata_id3.Value(), + exheader_header.arm11_system_local_caps.storage_info.extdata_id4.Value(), + exheader_header.arm11_system_local_caps.storage_info.extdata_id5.Value(), + }}; + for (u64 id : extdata_ids) { + if (id) { + // Found a non-zero ID, use it + extdata_id = id; + return Loader::ResultStatus::Success; + } + } + return Loader::ResultStatus::ErrorNotUsed; } diff --git a/src/core/file_sys/ncch_container.h b/src/core/file_sys/ncch_container.h index bee740e3b..79f87a6ef 100644 --- a/src/core/file_sys/ncch_container.h +++ b/src/core/file_sys/ncch_container.h @@ -125,9 +125,23 @@ struct ExHeader_SystemInfo { }; struct ExHeader_StorageInfo { - u64_le ext_save_data_id; + union { + u64_le ext_save_data_id; + // When using extended savedata access + // Prefer the ID specified in the most significant bits + BitField<40, 20, u64_le> extdata_id3; + BitField<20, 20, u64_le> extdata_id4; + BitField<0, 20, u64_le> extdata_id5; + }; u8 system_save_data_id[8]; - u8 reserved[8]; + union { + u64_le storage_accessible_unique_ids; + // When using extended savedata access + // Prefer the ID specified in the most significant bits + BitField<40, 20, u64_le> extdata_id0; + BitField<20, 20, u64_le> extdata_id1; + BitField<0, 20, u64_le> extdata_id2; + }; u8 access_info[7]; u8 other_attributes; };