summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/program_metadata.cpp52
-rw-r--r--src/core/file_sys/program_metadata.h14
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) {
34 return Loader::ResultStatus::ErrorBadACIHeader; 34 return Loader::ResultStatus::ErrorBadACIHeader;
35 } 35 }
36 36
37 if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) { 37 // Load acid_file_access per-component instead of the entire struct, since this struct does not
38 // reflect the layout of the real data.
39 std::size_t current_offset = acid_header.fac_offset;
40 if (sizeof(FileAccessControl::version) != file->ReadBytes(&acid_file_access.version,
41 sizeof(FileAccessControl::version),
42 current_offset)) {
43 return Loader::ResultStatus::ErrorBadFileAccessControl;
44 }
45 if (sizeof(FileAccessControl::permissions) !=
46 file->ReadBytes(&acid_file_access.permissions, sizeof(FileAccessControl::permissions),
47 current_offset += sizeof(FileAccessControl::version) + 3)) {
48 return Loader::ResultStatus::ErrorBadFileAccessControl;
49 }
50 if (sizeof(FileAccessControl::unknown) !=
51 file->ReadBytes(&acid_file_access.unknown, sizeof(FileAccessControl::unknown),
52 current_offset + sizeof(FileAccessControl::permissions))) {
38 return Loader::ResultStatus::ErrorBadFileAccessControl; 53 return Loader::ResultStatus::ErrorBadFileAccessControl;
39 } 54 }
40 55
41 if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) { 56 // Load aci_file_access per-component instead of the entire struct, same as acid_file_access
57 current_offset = aci_header.fah_offset;
58 if (sizeof(FileAccessHeader::version) != file->ReadBytes(&aci_file_access.version,
59 sizeof(FileAccessHeader::version),
60 current_offset)) {
61 return Loader::ResultStatus::ErrorBadFileAccessHeader;
62 }
63 if (sizeof(FileAccessHeader::permissions) !=
64 file->ReadBytes(&aci_file_access.permissions, sizeof(FileAccessHeader::permissions),
65 current_offset += sizeof(FileAccessHeader::version) + 3)) {
66 return Loader::ResultStatus::ErrorBadFileAccessHeader;
67 }
68 if (sizeof(FileAccessHeader::unk_offset) !=
69 file->ReadBytes(&aci_file_access.unk_offset, sizeof(FileAccessHeader::unk_offset),
70 current_offset += sizeof(FileAccessHeader::permissions))) {
71 return Loader::ResultStatus::ErrorBadFileAccessHeader;
72 }
73 if (sizeof(FileAccessHeader::unk_size) !=
74 file->ReadBytes(&aci_file_access.unk_size, sizeof(FileAccessHeader::unk_size),
75 current_offset += sizeof(FileAccessHeader::unk_offset))) {
76 return Loader::ResultStatus::ErrorBadFileAccessHeader;
77 }
78 if (sizeof(FileAccessHeader::unk_offset_2) !=
79 file->ReadBytes(&aci_file_access.unk_offset_2, sizeof(FileAccessHeader::unk_offset_2),
80 current_offset += sizeof(FileAccessHeader::unk_size))) {
81 return Loader::ResultStatus::ErrorBadFileAccessHeader;
82 }
83 if (sizeof(FileAccessHeader::unk_size_2) !=
84 file->ReadBytes(&aci_file_access.unk_size_2, sizeof(FileAccessHeader::unk_size_2),
85 current_offset + sizeof(FileAccessHeader::unk_offset_2))) {
42 return Loader::ResultStatus::ErrorBadFileAccessHeader; 86 return Loader::ResultStatus::ErrorBadFileAccessHeader;
43 } 87 }
44 88
@@ -153,9 +197,7 @@ void ProgramMetadata::Print() const {
153 LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO"); 197 LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
154 LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min); 198 LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
155 LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max); 199 LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
156 u64_le permissions_l; // local copy to fix alignment error 200 LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
157 std::memcpy(&permissions_l, &acid_file_access.permissions, sizeof(permissions_l));
158 LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", permissions_l);
159 201
160 // Begin ACI0 printing (actual perms, unsigned) 202 // Begin ACI0 printing (actual perms, unsigned)
161 LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data()); 203 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:
143 143
144 static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong"); 144 static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong");
145 145
146#pragma pack(push, 1) 146 // FileAccessControl and FileAccessHeader need loaded per-component: this layout does not
147 147 // reflect the real layout to avoid reference binding to misaligned addresses
148 struct FileAccessControl { 148 struct FileAccessControl {
149 u8 version; 149 u8 version;
150 INSERT_PADDING_BYTES(3); 150 // 3 padding bytes
151 u64_le permissions; 151 u64_le permissions;
152 std::array<u8, 0x20> unknown; 152 std::array<u8, 0x20> unknown;
153 }; 153 };
154 154
155 static_assert(sizeof(FileAccessControl) == 0x2C, "FS access control structure size is wrong");
156
157 struct FileAccessHeader { 155 struct FileAccessHeader {
158 u8 version; 156 u8 version;
159 INSERT_PADDING_BYTES(3); 157 // 3 padding bytes
160 u64_le permissions; 158 u64_le permissions;
161 u32_le unk_offset; 159 u32_le unk_offset;
162 u32_le unk_size; 160 u32_le unk_size;
@@ -164,10 +162,6 @@ private:
164 u32_le unk_size_2; 162 u32_le unk_size_2;
165 }; 163 };
166 164
167 static_assert(sizeof(FileAccessHeader) == 0x1C, "FS access header structure size is wrong");
168
169#pragma pack(pop)
170
171 Header npdm_header; 165 Header npdm_header;
172 AciHeader aci_header; 166 AciHeader aci_header;
173 AcidHeader acid_header; 167 AcidHeader acid_header;