diff options
author | lat9nq <22451773+lat9nq@users.noreply.github.com> | 2021-06-10 22:25:25 +0200 |
---|---|---|
committer | lat9nq <lat9nq@gmail.com> | 2022-02-13 08:20:56 +0100 |
commit | bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495 (patch) | |
tree | 30c36b49f63918ccf8b3c78e077bec4d769b3b6a | |
parent | Merge pull request #7887 from lat9nq/stub-is-usb-full-key (diff) | |
download | yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.tar yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.tar.gz yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.tar.bz2 yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.tar.lz yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.tar.xz yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.tar.zst yuzu-bfb7cbc2922655e8a7a9e6f8bb80a186d4d75495.zip |
-rw-r--r-- | src/core/file_sys/program_metadata.cpp | 52 | ||||
-rw-r--r-- | src/core/file_sys/program_metadata.h | 14 |
2 files changed, 51 insertions, 15 deletions
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 4e46c24cf..484d4baea 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -34,11 +34,55 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { return Loader::ResultStatus::ErrorBadACIHeader; } - if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) { + // Load acid_file_access per-component instead of the entire struct, since this struct does not + // reflect the layout of the real data. + std::size_t current_offset = acid_header.fac_offset; + if (sizeof(FileAccessControl::version) != file->ReadBytes(&acid_file_access.version, + sizeof(FileAccessControl::version), + current_offset)) { + return Loader::ResultStatus::ErrorBadFileAccessControl; + } + if (sizeof(FileAccessControl::permissions) != + file->ReadBytes(&acid_file_access.permissions, sizeof(FileAccessControl::permissions), + current_offset += sizeof(FileAccessControl::version) + 3)) { + return Loader::ResultStatus::ErrorBadFileAccessControl; + } + if (sizeof(FileAccessControl::unknown) != + file->ReadBytes(&acid_file_access.unknown, sizeof(FileAccessControl::unknown), + current_offset + sizeof(FileAccessControl::permissions))) { return Loader::ResultStatus::ErrorBadFileAccessControl; } - if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) { + // Load aci_file_access per-component instead of the entire struct, same as acid_file_access + current_offset = aci_header.fah_offset; + if (sizeof(FileAccessHeader::version) != file->ReadBytes(&aci_file_access.version, + sizeof(FileAccessHeader::version), + current_offset)) { + return Loader::ResultStatus::ErrorBadFileAccessHeader; + } + if (sizeof(FileAccessHeader::permissions) != + file->ReadBytes(&aci_file_access.permissions, sizeof(FileAccessHeader::permissions), + current_offset += sizeof(FileAccessHeader::version) + 3)) { + return Loader::ResultStatus::ErrorBadFileAccessHeader; + } + if (sizeof(FileAccessHeader::unk_offset) != + file->ReadBytes(&aci_file_access.unk_offset, sizeof(FileAccessHeader::unk_offset), + current_offset += sizeof(FileAccessHeader::permissions))) { + return Loader::ResultStatus::ErrorBadFileAccessHeader; + } + if (sizeof(FileAccessHeader::unk_size) != + file->ReadBytes(&aci_file_access.unk_size, sizeof(FileAccessHeader::unk_size), + current_offset += sizeof(FileAccessHeader::unk_offset))) { + return Loader::ResultStatus::ErrorBadFileAccessHeader; + } + if (sizeof(FileAccessHeader::unk_offset_2) != + file->ReadBytes(&aci_file_access.unk_offset_2, sizeof(FileAccessHeader::unk_offset_2), + current_offset += sizeof(FileAccessHeader::unk_size))) { + return Loader::ResultStatus::ErrorBadFileAccessHeader; + } + if (sizeof(FileAccessHeader::unk_size_2) != + file->ReadBytes(&aci_file_access.unk_size_2, sizeof(FileAccessHeader::unk_size_2), + current_offset + sizeof(FileAccessHeader::unk_offset_2))) { return Loader::ResultStatus::ErrorBadFileAccessHeader; } @@ -153,9 +197,7 @@ void ProgramMetadata::Print() const { LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO"); LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min); LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max); - u64_le permissions_l; // local copy to fix alignment error - std::memcpy(&permissions_l, &acid_file_access.permissions, sizeof(permissions_l)); - LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", permissions_l); + LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions); // Begin ACI0 printing (actual perms, unsigned) LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data()); diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index 1eee916be..c89a1c445 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h @@ -143,20 +143,18 @@ private: static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong"); -#pragma pack(push, 1) - + // FileAccessControl and FileAccessHeader need loaded per-component: this layout does not + // reflect the real layout to avoid reference binding to misaligned addresses struct FileAccessControl { u8 version; - INSERT_PADDING_BYTES(3); + // 3 padding bytes u64_le permissions; std::array<u8, 0x20> unknown; }; - static_assert(sizeof(FileAccessControl) == 0x2C, "FS access control structure size is wrong"); - struct FileAccessHeader { u8 version; - INSERT_PADDING_BYTES(3); + // 3 padding bytes u64_le permissions; u32_le unk_offset; u32_le unk_size; @@ -164,10 +162,6 @@ private: u32_le unk_size_2; }; - static_assert(sizeof(FileAccessHeader) == 0x1C, "FS access header structure size is wrong"); - -#pragma pack(pop) - Header npdm_header; AciHeader aci_header; AcidHeader acid_header; |