diff options
| author | 2018-08-11 19:25:30 -0400 | |
|---|---|---|
| committer | 2018-08-11 19:25:30 -0400 | |
| commit | bc286c169fb8b07d21e082e05152cfd6bc611b33 (patch) | |
| tree | 512bc4cca3adbe98a16cae454377c2ec2638b5e3 /src/core/file_sys | |
| parent | Merge pull request #1018 from Subv/ssy_sync (diff) | |
| parent | game_list: Reorder error checks (diff) | |
| download | yuzu-bc286c169fb8b07d21e082e05152cfd6bc611b33.tar.gz yuzu-bc286c169fb8b07d21e082e05152cfd6bc611b33.tar.xz yuzu-bc286c169fb8b07d21e082e05152cfd6bc611b33.zip | |
Merge pull request #970 from DarkLordZach/loader-errors
loader: Add more descriptive errors
Diffstat (limited to 'src/core/file_sys')
| -rw-r--r-- | src/core/file_sys/card_image.cpp | 19 | ||||
| -rw-r--r-- | src/core/file_sys/content_archive.cpp | 86 | ||||
| -rw-r--r-- | src/core/file_sys/content_archive.h | 5 | ||||
| -rw-r--r-- | src/core/file_sys/partition_filesystem.cpp | 8 | ||||
| -rw-r--r-- | src/core/file_sys/program_metadata.cpp | 12 |
5 files changed, 95 insertions, 35 deletions
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index e897d9913..a4823353e 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp | |||
| @@ -12,14 +12,16 @@ | |||
| 12 | 12 | ||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure", "logo"}; | ||
| 16 | |||
| 15 | XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { | 17 | XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { |
| 16 | if (file->ReadObject(&header) != sizeof(GamecardHeader)) { | 18 | if (file->ReadObject(&header) != sizeof(GamecardHeader)) { |
| 17 | status = Loader::ResultStatus::ErrorInvalidFormat; | 19 | status = Loader::ResultStatus::ErrorBadXCIHeader; |
| 18 | return; | 20 | return; |
| 19 | } | 21 | } |
| 20 | 22 | ||
| 21 | if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) { | 23 | if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) { |
| 22 | status = Loader::ResultStatus::ErrorInvalidFormat; | 24 | status = Loader::ResultStatus::ErrorBadXCIHeader; |
| 23 | return; | 25 | return; |
| 24 | } | 26 | } |
| 25 | 27 | ||
| @@ -31,9 +33,6 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { | |||
| 31 | return; | 33 | return; |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | static constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure", | ||
| 35 | "logo"}; | ||
| 36 | |||
| 37 | for (XCIPartition partition : | 36 | for (XCIPartition partition : |
| 38 | {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { | 37 | {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { |
| 39 | auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]); | 38 | auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]); |
| @@ -130,15 +129,21 @@ bool XCI::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { | |||
| 130 | 129 | ||
| 131 | Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | 130 | Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { |
| 132 | if (partitions[static_cast<size_t>(part)] == nullptr) { | 131 | if (partitions[static_cast<size_t>(part)] == nullptr) { |
| 133 | return Loader::ResultStatus::ErrorInvalidFormat; | 132 | return Loader::ResultStatus::ErrorXCIMissingPartition; |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) { | 135 | for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) { |
| 137 | if (file->GetExtension() != "nca") | 136 | if (file->GetExtension() != "nca") |
| 138 | continue; | 137 | continue; |
| 139 | auto nca = std::make_shared<NCA>(file); | 138 | auto nca = std::make_shared<NCA>(file); |
| 140 | if (nca->GetStatus() == Loader::ResultStatus::Success) | 139 | if (nca->GetStatus() == Loader::ResultStatus::Success) { |
| 141 | ncas.push_back(std::move(nca)); | 140 | ncas.push_back(std::move(nca)); |
| 141 | } else { | ||
| 142 | const u16 error_id = static_cast<u16>(nca->GetStatus()); | ||
| 143 | LOG_CRITICAL(Loader, "Could not load NCA {}/{}, failed with error code {:04X} ({})", | ||
| 144 | partition_names[static_cast<size_t>(part)], nca->GetName(), error_id, | ||
| 145 | Loader::GetMessageForResultStatus(nca->GetStatus())); | ||
| 146 | } | ||
| 142 | } | 147 | } |
| 143 | 148 | ||
| 144 | return Loader::ResultStatus::Success; | 149 | return Loader::ResultStatus::Success; |
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index d3007d981..47afcad9b 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -113,17 +113,27 @@ boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType ty | |||
| 113 | return out; | 113 | return out; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() const { | 116 | boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() { |
| 117 | const auto master_key_id = GetCryptoRevision(); | 117 | const auto master_key_id = GetCryptoRevision(); |
| 118 | 118 | ||
| 119 | u128 rights_id{}; | 119 | u128 rights_id{}; |
| 120 | memcpy(rights_id.data(), header.rights_id.data(), 16); | 120 | memcpy(rights_id.data(), header.rights_id.data(), 16); |
| 121 | if (rights_id == u128{}) | 121 | if (rights_id == u128{}) { |
| 122 | status = Loader::ResultStatus::ErrorInvalidRightsID; | ||
| 122 | return boost::none; | 123 | return boost::none; |
| 124 | } | ||
| 123 | 125 | ||
| 124 | auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]); | 126 | auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]); |
| 125 | if (titlekey == Core::Crypto::Key128{}) | 127 | if (titlekey == Core::Crypto::Key128{}) { |
| 128 | status = Loader::ResultStatus::ErrorMissingTitlekey; | ||
| 129 | return boost::none; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) { | ||
| 133 | status = Loader::ResultStatus::ErrorMissingTitlekek; | ||
| 126 | return boost::none; | 134 | return boost::none; |
| 135 | } | ||
| 136 | |||
| 127 | Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( | 137 | Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( |
| 128 | keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id), Core::Crypto::Mode::ECB); | 138 | keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id), Core::Crypto::Mode::ECB); |
| 129 | cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt); | 139 | cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt); |
| @@ -131,7 +141,7 @@ boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() const { | |||
| 131 | return titlekey; | 141 | return titlekey; |
| 132 | } | 142 | } |
| 133 | 143 | ||
| 134 | VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting_offset) const { | 144 | VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting_offset) { |
| 135 | if (!encrypted) | 145 | if (!encrypted) |
| 136 | return in; | 146 | return in; |
| 137 | 147 | ||
| @@ -143,15 +153,22 @@ VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting | |||
| 143 | LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset); | 153 | LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset); |
| 144 | { | 154 | { |
| 145 | boost::optional<Core::Crypto::Key128> key = boost::none; | 155 | boost::optional<Core::Crypto::Key128> key = boost::none; |
| 146 | if (std::find_if_not(header.rights_id.begin(), header.rights_id.end(), | 156 | if (has_rights_id) { |
| 147 | [](char c) { return c == 0; }) == header.rights_id.end()) { | 157 | status = Loader::ResultStatus::Success; |
| 148 | key = GetKeyAreaKey(NCASectionCryptoType::CTR); | ||
| 149 | } else { | ||
| 150 | key = GetTitlekey(); | 158 | key = GetTitlekey(); |
| 159 | if (key == boost::none) { | ||
| 160 | if (status == Loader::ResultStatus::Success) | ||
| 161 | status = Loader::ResultStatus::ErrorMissingTitlekey; | ||
| 162 | return nullptr; | ||
| 163 | } | ||
| 164 | } else { | ||
| 165 | key = GetKeyAreaKey(NCASectionCryptoType::CTR); | ||
| 166 | if (key == boost::none) { | ||
| 167 | status = Loader::ResultStatus::ErrorMissingKeyAreaKey; | ||
| 168 | return nullptr; | ||
| 169 | } | ||
| 151 | } | 170 | } |
| 152 | 171 | ||
| 153 | if (key == boost::none) | ||
| 154 | return nullptr; | ||
| 155 | auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>( | 172 | auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>( |
| 156 | std::move(in), key.value(), starting_offset); | 173 | std::move(in), key.value(), starting_offset); |
| 157 | std::vector<u8> iv(16); | 174 | std::vector<u8> iv(16); |
| @@ -170,16 +187,31 @@ VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting | |||
| 170 | } | 187 | } |
| 171 | 188 | ||
| 172 | NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | 189 | NCA::NCA(VirtualFile file_) : file(std::move(file_)) { |
| 190 | status = Loader::ResultStatus::Success; | ||
| 191 | |||
| 173 | if (file == nullptr) { | 192 | if (file == nullptr) { |
| 174 | status = Loader::ResultStatus::ErrorInvalidFormat; | 193 | status = Loader::ResultStatus::ErrorNullFile; |
| 175 | return; | 194 | return; |
| 176 | } | 195 | } |
| 177 | if (sizeof(NCAHeader) != file->ReadObject(&header)) | 196 | |
| 197 | if (sizeof(NCAHeader) != file->ReadObject(&header)) { | ||
| 178 | LOG_ERROR(Loader, "File reader errored out during header read."); | 198 | LOG_ERROR(Loader, "File reader errored out during header read."); |
| 199 | status = Loader::ResultStatus::ErrorBadNCAHeader; | ||
| 200 | return; | ||
| 201 | } | ||
| 179 | 202 | ||
| 180 | encrypted = false; | 203 | encrypted = false; |
| 181 | 204 | ||
| 182 | if (!IsValidNCA(header)) { | 205 | if (!IsValidNCA(header)) { |
| 206 | if (header.magic == Common::MakeMagic('N', 'C', 'A', '2')) { | ||
| 207 | status = Loader::ResultStatus::ErrorNCA2; | ||
| 208 | return; | ||
| 209 | } | ||
| 210 | if (header.magic == Common::MakeMagic('N', 'C', 'A', '0')) { | ||
| 211 | status = Loader::ResultStatus::ErrorNCA0; | ||
| 212 | return; | ||
| 213 | } | ||
| 214 | |||
| 183 | NCAHeader dec_header{}; | 215 | NCAHeader dec_header{}; |
| 184 | Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( | 216 | Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( |
| 185 | keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); | 217 | keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); |
| @@ -189,14 +221,26 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | |||
| 189 | header = dec_header; | 221 | header = dec_header; |
| 190 | encrypted = true; | 222 | encrypted = true; |
| 191 | } else { | 223 | } else { |
| 224 | if (dec_header.magic == Common::MakeMagic('N', 'C', 'A', '2')) { | ||
| 225 | status = Loader::ResultStatus::ErrorNCA2; | ||
| 226 | return; | ||
| 227 | } | ||
| 228 | if (dec_header.magic == Common::MakeMagic('N', 'C', 'A', '0')) { | ||
| 229 | status = Loader::ResultStatus::ErrorNCA0; | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | |||
| 192 | if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) | 233 | if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) |
| 193 | status = Loader::ResultStatus::ErrorMissingKeys; | 234 | status = Loader::ResultStatus::ErrorMissingHeaderKey; |
| 194 | else | 235 | else |
| 195 | status = Loader::ResultStatus::ErrorDecrypting; | 236 | status = Loader::ResultStatus::ErrorIncorrectHeaderKey; |
| 196 | return; | 237 | return; |
| 197 | } | 238 | } |
| 198 | } | 239 | } |
| 199 | 240 | ||
| 241 | has_rights_id = std::find_if_not(header.rights_id.begin(), header.rights_id.end(), | ||
| 242 | [](char c) { return c == '\0'; }) != header.rights_id.end(); | ||
| 243 | |||
| 200 | const std::ptrdiff_t number_sections = | 244 | const std::ptrdiff_t number_sections = |
| 201 | std::count_if(std::begin(header.section_tables), std::end(header.section_tables), | 245 | std::count_if(std::begin(header.section_tables), std::end(header.section_tables), |
| 202 | [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); | 246 | [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); |
| @@ -229,7 +273,12 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | |||
| 229 | files.push_back(std::move(dec)); | 273 | files.push_back(std::move(dec)); |
| 230 | romfs = files.back(); | 274 | romfs = files.back(); |
| 231 | } else { | 275 | } else { |
| 232 | status = Loader::ResultStatus::ErrorMissingKeys; | 276 | if (status != Loader::ResultStatus::Success) |
| 277 | return; | ||
| 278 | if (has_rights_id) | ||
| 279 | status = Loader::ResultStatus::ErrorIncorrectTitlekeyOrTitlekek; | ||
| 280 | else | ||
| 281 | status = Loader::ResultStatus::ErrorIncorrectKeyAreaKey; | ||
| 233 | return; | 282 | return; |
| 234 | } | 283 | } |
| 235 | } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { | 284 | } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { |
| @@ -249,7 +298,12 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | |||
| 249 | exefs = dirs.back(); | 298 | exefs = dirs.back(); |
| 250 | } | 299 | } |
| 251 | } else { | 300 | } else { |
| 252 | status = Loader::ResultStatus::ErrorMissingKeys; | 301 | if (status != Loader::ResultStatus::Success) |
| 302 | return; | ||
| 303 | if (has_rights_id) | ||
| 304 | status = Loader::ResultStatus::ErrorIncorrectTitlekeyOrTitlekek; | ||
| 305 | else | ||
| 306 | status = Loader::ResultStatus::ErrorIncorrectKeyAreaKey; | ||
| 253 | return; | 307 | return; |
| 254 | } | 308 | } |
| 255 | } | 309 | } |
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 5cfd5031a..b82e65ad5 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h | |||
| @@ -98,8 +98,8 @@ protected: | |||
| 98 | private: | 98 | private: |
| 99 | u8 GetCryptoRevision() const; | 99 | u8 GetCryptoRevision() const; |
| 100 | boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const; | 100 | boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const; |
| 101 | boost::optional<Core::Crypto::Key128> GetTitlekey() const; | 101 | boost::optional<Core::Crypto::Key128> GetTitlekey(); |
| 102 | VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset) const; | 102 | VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset); |
| 103 | 103 | ||
| 104 | std::vector<VirtualDir> dirs; | 104 | std::vector<VirtualDir> dirs; |
| 105 | std::vector<VirtualFile> files; | 105 | std::vector<VirtualFile> files; |
| @@ -109,6 +109,7 @@ private: | |||
| 109 | VirtualFile file; | 109 | VirtualFile file; |
| 110 | 110 | ||
| 111 | NCAHeader header{}; | 111 | NCAHeader header{}; |
| 112 | bool has_rights_id{}; | ||
| 112 | 113 | ||
| 113 | Loader::ResultStatus status{}; | 114 | Loader::ResultStatus status{}; |
| 114 | 115 | ||
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 47e032b19..c377edc9c 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp | |||
| @@ -24,19 +24,19 @@ bool PartitionFilesystem::Header::HasValidMagicValue() const { | |||
| 24 | PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) { | 24 | PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) { |
| 25 | // At least be as large as the header | 25 | // At least be as large as the header |
| 26 | if (file->GetSize() < sizeof(Header)) { | 26 | if (file->GetSize() < sizeof(Header)) { |
| 27 | status = Loader::ResultStatus::Error; | 27 | status = Loader::ResultStatus::ErrorBadPFSHeader; |
| 28 | return; | 28 | return; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | // For cartridges, HFSs can get very large, so we need to calculate the size up to | 31 | // For cartridges, HFSs can get very large, so we need to calculate the size up to |
| 32 | // the actual content itself instead of just blindly reading in the entire file. | 32 | // the actual content itself instead of just blindly reading in the entire file. |
| 33 | if (sizeof(Header) != file->ReadObject(&pfs_header)) { | 33 | if (sizeof(Header) != file->ReadObject(&pfs_header)) { |
| 34 | status = Loader::ResultStatus::Error; | 34 | status = Loader::ResultStatus::ErrorBadPFSHeader; |
| 35 | return; | 35 | return; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | if (!pfs_header.HasValidMagicValue()) { | 38 | if (!pfs_header.HasValidMagicValue()) { |
| 39 | status = Loader::ResultStatus::ErrorInvalidFormat; | 39 | status = Loader::ResultStatus::ErrorBadPFSHeader; |
| 40 | return; | 40 | return; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| @@ -51,7 +51,7 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) { | |||
| 51 | const size_t total_size = file_data.size(); | 51 | const size_t total_size = file_data.size(); |
| 52 | 52 | ||
| 53 | if (total_size != metadata_size) { | 53 | if (total_size != metadata_size) { |
| 54 | status = Loader::ResultStatus::Error; | 54 | status = Loader::ResultStatus::ErrorIncorrectPFSFileSize; |
| 55 | return; | 55 | return; |
| 56 | } | 56 | } |
| 57 | 57 | ||
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 63d4b6e4f..279f987d4 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp | |||
| @@ -12,26 +12,26 @@ namespace FileSys { | |||
| 12 | Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { | 12 | Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { |
| 13 | size_t total_size = static_cast<size_t>(file->GetSize()); | 13 | size_t total_size = static_cast<size_t>(file->GetSize()); |
| 14 | if (total_size < sizeof(Header)) | 14 | if (total_size < sizeof(Header)) |
| 15 | return Loader::ResultStatus::Error; | 15 | return Loader::ResultStatus::ErrorBadNPDMHeader; |
| 16 | 16 | ||
| 17 | // TODO(DarkLordZach): Use ReadObject when Header/AcidHeader becomes trivially copyable. | 17 | // TODO(DarkLordZach): Use ReadObject when Header/AcidHeader becomes trivially copyable. |
| 18 | std::vector<u8> npdm_header_data = file->ReadBytes(sizeof(Header)); | 18 | std::vector<u8> npdm_header_data = file->ReadBytes(sizeof(Header)); |
| 19 | if (sizeof(Header) != npdm_header_data.size()) | 19 | if (sizeof(Header) != npdm_header_data.size()) |
| 20 | return Loader::ResultStatus::Error; | 20 | return Loader::ResultStatus::ErrorBadNPDMHeader; |
| 21 | std::memcpy(&npdm_header, npdm_header_data.data(), sizeof(Header)); | 21 | std::memcpy(&npdm_header, npdm_header_data.data(), sizeof(Header)); |
| 22 | 22 | ||
| 23 | std::vector<u8> acid_header_data = file->ReadBytes(sizeof(AcidHeader), npdm_header.acid_offset); | 23 | std::vector<u8> acid_header_data = file->ReadBytes(sizeof(AcidHeader), npdm_header.acid_offset); |
| 24 | if (sizeof(AcidHeader) != acid_header_data.size()) | 24 | if (sizeof(AcidHeader) != acid_header_data.size()) |
| 25 | return Loader::ResultStatus::Error; | 25 | return Loader::ResultStatus::ErrorBadACIDHeader; |
| 26 | std::memcpy(&acid_header, acid_header_data.data(), sizeof(AcidHeader)); | 26 | std::memcpy(&acid_header, acid_header_data.data(), sizeof(AcidHeader)); |
| 27 | 27 | ||
| 28 | if (sizeof(AciHeader) != file->ReadObject(&aci_header, npdm_header.aci_offset)) | 28 | if (sizeof(AciHeader) != file->ReadObject(&aci_header, npdm_header.aci_offset)) |
| 29 | return Loader::ResultStatus::Error; | 29 | return Loader::ResultStatus::ErrorBadACIHeader; |
| 30 | 30 | ||
| 31 | if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) | 31 | if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) |
| 32 | return Loader::ResultStatus::Error; | 32 | return Loader::ResultStatus::ErrorBadFileAccessControl; |
| 33 | if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) | 33 | if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) |
| 34 | return Loader::ResultStatus::Error; | 34 | return Loader::ResultStatus::ErrorBadFileAccessHeader; |
| 35 | 35 | ||
| 36 | return Loader::ResultStatus::Success; | 36 | return Loader::ResultStatus::Success; |
| 37 | } | 37 | } |