diff options
| author | 2019-09-22 21:50:29 -0400 | |
|---|---|---|
| committer | 2019-09-22 21:50:29 -0400 | |
| commit | 3952c73aee27d6d1401e0280c4f3432dd0ddecf5 (patch) | |
| tree | 9d9ee433f2bf67dbed18aeae0c85e90ea7bd0bab | |
| parent | pfs: Provide accessors for file sizes and offsets (diff) | |
| download | yuzu-3952c73aee27d6d1401e0280c4f3432dd0ddecf5.tar.gz yuzu-3952c73aee27d6d1401e0280c4f3432dd0ddecf5.tar.xz yuzu-3952c73aee27d6d1401e0280c4f3432dd0ddecf5.zip | |
card_image: Lazily load partitions in XCI
| -rw-r--r-- | src/core/file_sys/card_image.cpp | 51 | ||||
| -rw-r--r-- | src/core/file_sys/card_image.h | 16 |
2 files changed, 41 insertions, 26 deletions
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{ | |||
| 31 | 31 | ||
| 32 | XCI::XCI(VirtualFile file_) | 32 | XCI::XCI(VirtualFile file_) |
| 33 | : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, | 33 | : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, |
| 34 | partitions(partition_names.size()) { | 34 | partitions(partition_names.size()), partitions_raw(partition_names.size()) { |
| 35 | if (file->ReadObject(&header) != sizeof(GamecardHeader)) { | 35 | if (file->ReadObject(&header) != sizeof(GamecardHeader)) { |
| 36 | status = Loader::ResultStatus::ErrorBadXCIHeader; | 36 | status = Loader::ResultStatus::ErrorBadXCIHeader; |
| 37 | return; | 37 | return; |
| @@ -42,8 +42,10 @@ XCI::XCI(VirtualFile file_) | |||
| 42 | return; | 42 | return; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | PartitionFilesystem main_hfs( | 45 | PartitionFilesystem main_hfs(std::make_shared<OffsetVfsFile>( |
| 46 | std::make_shared<OffsetVfsFile>(file, header.hfs_size, header.hfs_offset)); | 46 | file, file->GetSize() - header.hfs_offset, header.hfs_offset)); |
| 47 | |||
| 48 | update_normal_partition_end = main_hfs.GetFileOffsets()["secure"]; | ||
| 47 | 49 | ||
| 48 | if (main_hfs.GetStatus() != Loader::ResultStatus::Success) { | 50 | if (main_hfs.GetStatus() != Loader::ResultStatus::Success) { |
| 49 | status = main_hfs.GetStatus(); | 51 | status = main_hfs.GetStatus(); |
| @@ -55,9 +57,7 @@ XCI::XCI(VirtualFile file_) | |||
| 55 | const auto partition_idx = static_cast<std::size_t>(partition); | 57 | const auto partition_idx = static_cast<std::size_t>(partition); |
| 56 | auto raw = main_hfs.GetFile(partition_names[partition_idx]); | 58 | auto raw = main_hfs.GetFile(partition_names[partition_idx]); |
| 57 | 59 | ||
| 58 | if (raw != nullptr) { | 60 | partitions_raw[static_cast<std::size_t>(partition)] = raw; |
| 59 | partitions[partition_idx] = std::make_shared<PartitionFilesystem>(std::move(raw)); | ||
| 60 | } | ||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | secure_partition = std::make_shared<NSP>( | 63 | secure_partition = std::make_shared<NSP>( |
| @@ -71,13 +71,7 @@ XCI::XCI(VirtualFile file_) | |||
| 71 | program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; | 71 | program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | auto result = AddNCAFromPartition(XCIPartition::Update); | 74 | auto result = AddNCAFromPartition(XCIPartition::Normal); |
| 75 | if (result != Loader::ResultStatus::Success) { | ||
| 76 | status = result; | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | result = AddNCAFromPartition(XCIPartition::Normal); | ||
| 81 | if (result != Loader::ResultStatus::Success) { | 75 | if (result != Loader::ResultStatus::Success) { |
| 82 | status = result; | 76 | status = result; |
| 83 | return; | 77 | return; |
| @@ -104,27 +98,44 @@ Loader::ResultStatus XCI::GetProgramNCAStatus() const { | |||
| 104 | return program_nca_status; | 98 | return program_nca_status; |
| 105 | } | 99 | } |
| 106 | 100 | ||
| 107 | VirtualDir XCI::GetPartition(XCIPartition partition) const { | 101 | VirtualDir XCI::GetPartition(XCIPartition partition) { |
| 102 | const auto id = static_cast<std::size_t>(partition); | ||
| 103 | if (partitions[id] == nullptr && partitions_raw[id] != nullptr) { | ||
| 104 | partitions[id] = std::make_shared<PartitionFilesystem>(partitions_raw[id]); | ||
| 105 | } | ||
| 106 | |||
| 108 | return partitions[static_cast<std::size_t>(partition)]; | 107 | return partitions[static_cast<std::size_t>(partition)]; |
| 109 | } | 108 | } |
| 110 | 109 | ||
| 110 | std::vector<VirtualDir> XCI::GetPartitions() { | ||
| 111 | std::vector<VirtualDir> out; | ||
| 112 | for (const auto& id : | ||
| 113 | {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { | ||
| 114 | const auto part = GetPartition(id); | ||
| 115 | if (part != nullptr) { | ||
| 116 | out.push_back(part); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | return out; | ||
| 120 | } | ||
| 121 | |||
| 111 | std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { | 122 | std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { |
| 112 | return secure_partition; | 123 | return secure_partition; |
| 113 | } | 124 | } |
| 114 | 125 | ||
| 115 | VirtualDir XCI::GetSecurePartition() const { | 126 | VirtualDir XCI::GetSecurePartition() { |
| 116 | return GetPartition(XCIPartition::Secure); | 127 | return GetPartition(XCIPartition::Secure); |
| 117 | } | 128 | } |
| 118 | 129 | ||
| 119 | VirtualDir XCI::GetNormalPartition() const { | 130 | VirtualDir XCI::GetNormalPartition() { |
| 120 | return GetPartition(XCIPartition::Normal); | 131 | return GetPartition(XCIPartition::Normal); |
| 121 | } | 132 | } |
| 122 | 133 | ||
| 123 | VirtualDir XCI::GetUpdatePartition() const { | 134 | VirtualDir XCI::GetUpdatePartition() { |
| 124 | return GetPartition(XCIPartition::Update); | 135 | return GetPartition(XCIPartition::Update); |
| 125 | } | 136 | } |
| 126 | 137 | ||
| 127 | VirtualDir XCI::GetLogoPartition() const { | 138 | VirtualDir XCI::GetLogoPartition() { |
| 128 | return GetPartition(XCIPartition::Logo); | 139 | return GetPartition(XCIPartition::Logo); |
| 129 | } | 140 | } |
| 130 | 141 | ||
| @@ -201,7 +212,7 @@ std::array<u8, 0x200> XCI::GetCertificate() const { | |||
| 201 | 212 | ||
| 202 | Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | 213 | Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { |
| 203 | const auto partition_index = static_cast<std::size_t>(part); | 214 | const auto partition_index = static_cast<std::size_t>(part); |
| 204 | const auto& partition = partitions[partition_index]; | 215 | const auto partition = GetPartition(part); |
| 205 | 216 | ||
| 206 | if (partition == nullptr) { | 217 | if (partition == nullptr) { |
| 207 | return Loader::ResultStatus::ErrorXCIMissingPartition; | 218 | return Loader::ResultStatus::ErrorXCIMissingPartition; |
| @@ -232,7 +243,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | |||
| 232 | return Loader::ResultStatus::Success; | 243 | return Loader::ResultStatus::Success; |
| 233 | } | 244 | } |
| 234 | 245 | ||
| 235 | u8 XCI::GetFormatVersion() const { | 246 | u8 XCI::GetFormatVersion() { |
| 236 | return GetLogoPartition() == nullptr ? 0x1 : 0x2; | 247 | return GetLogoPartition() == nullptr ? 0x1 : 0x2; |
| 237 | } | 248 | } |
| 238 | } // namespace FileSys | 249 | } // 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: | |||
| 81 | Loader::ResultStatus GetStatus() const; | 81 | Loader::ResultStatus GetStatus() const; |
| 82 | Loader::ResultStatus GetProgramNCAStatus() const; | 82 | Loader::ResultStatus GetProgramNCAStatus() const; |
| 83 | 83 | ||
| 84 | u8 GetFormatVersion() const; | 84 | u8 GetFormatVersion(); |
| 85 | |||
| 86 | VirtualDir GetPartition(XCIPartition partition); | ||
| 87 | std::vector<VirtualDir> GetPartitions(); | ||
| 85 | 88 | ||
| 86 | VirtualDir GetPartition(XCIPartition partition) const; | ||
| 87 | std::shared_ptr<NSP> GetSecurePartitionNSP() const; | 89 | std::shared_ptr<NSP> GetSecurePartitionNSP() const; |
| 88 | VirtualDir GetSecurePartition() const; | 90 | VirtualDir GetSecurePartition(); |
| 89 | VirtualDir GetNormalPartition() const; | 91 | VirtualDir GetNormalPartition(); |
| 90 | VirtualDir GetUpdatePartition() const; | 92 | VirtualDir GetUpdatePartition(); |
| 91 | VirtualDir GetLogoPartition() const; | 93 | VirtualDir GetLogoPartition(); |
| 94 | |||
| 92 | 95 | ||
| 93 | u64 GetProgramTitleID() const; | 96 | u64 GetProgramTitleID() const; |
| 94 | u32 GetSystemUpdateVersion(); | 97 | u32 GetSystemUpdateVersion(); |
| @@ -123,6 +126,7 @@ private: | |||
| 123 | Loader::ResultStatus program_nca_status; | 126 | Loader::ResultStatus program_nca_status; |
| 124 | 127 | ||
| 125 | std::vector<VirtualDir> partitions; | 128 | std::vector<VirtualDir> partitions; |
| 129 | std::vector<VirtualFile> partitions_raw; | ||
| 126 | std::shared_ptr<NSP> secure_partition; | 130 | std::shared_ptr<NSP> secure_partition; |
| 127 | std::shared_ptr<NCA> program; | 131 | std::shared_ptr<NCA> program; |
| 128 | std::vector<std::shared_ptr<NCA>> ncas; | 132 | std::vector<std::shared_ptr<NCA>> ncas; |