summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/file_sys/card_image.cpp114
-rw-r--r--src/core/file_sys/card_image.h23
-rw-r--r--src/core/file_sys/partition_filesystem.cpp11
-rw-r--r--src/core/file_sys/partition_filesystem.h6
4 files changed, 128 insertions, 26 deletions
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
index db54113a0..07d0c8d5d 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
32XCI::XCI(VirtualFile file_) 32XCI::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)] = std::move(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,34 +98,114 @@ Loader::ResultStatus XCI::GetProgramNCAStatus() const {
104 return program_nca_status; 98 return program_nca_status;
105} 99}
106 100
107VirtualDir XCI::GetPartition(XCIPartition partition) const { 101VirtualDir 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
110std::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
111std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { 122std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const {
112 return secure_partition; 123 return secure_partition;
113} 124}
114 125
115VirtualDir XCI::GetSecurePartition() const { 126VirtualDir XCI::GetSecurePartition() {
116 return GetPartition(XCIPartition::Secure); 127 return GetPartition(XCIPartition::Secure);
117} 128}
118 129
119VirtualDir XCI::GetNormalPartition() const { 130VirtualDir XCI::GetNormalPartition() {
120 return GetPartition(XCIPartition::Normal); 131 return GetPartition(XCIPartition::Normal);
121} 132}
122 133
123VirtualDir XCI::GetUpdatePartition() const { 134VirtualDir XCI::GetUpdatePartition() {
124 return GetPartition(XCIPartition::Update); 135 return GetPartition(XCIPartition::Update);
125} 136}
126 137
127VirtualDir XCI::GetLogoPartition() const { 138VirtualDir XCI::GetLogoPartition() {
128 return GetPartition(XCIPartition::Logo); 139 return GetPartition(XCIPartition::Logo);
129} 140}
130 141
142VirtualFile XCI::GetPartitionRaw(XCIPartition partition) const {
143 return partitions_raw[static_cast<std::size_t>(partition)];
144}
145
146VirtualFile XCI::GetSecurePartitionRaw() const {
147 return GetPartitionRaw(XCIPartition::Secure);
148}
149
150VirtualFile XCI::GetStoragePartition0() const {
151 return std::make_shared<OffsetVfsFile>(file, update_normal_partition_end, 0, "partition0");
152}
153
154VirtualFile XCI::GetStoragePartition1() const {
155 return std::make_shared<OffsetVfsFile>(file, file->GetSize() - update_normal_partition_end,
156 update_normal_partition_end, "partition1");
157}
158
159VirtualFile XCI::GetNormalPartitionRaw() const {
160 return GetPartitionRaw(XCIPartition::Normal);
161}
162
163VirtualFile XCI::GetUpdatePartitionRaw() const {
164 return GetPartitionRaw(XCIPartition::Update);
165}
166
167VirtualFile XCI::GetLogoPartitionRaw() const {
168 return GetPartitionRaw(XCIPartition::Logo);
169}
170
131u64 XCI::GetProgramTitleID() const { 171u64 XCI::GetProgramTitleID() const {
132 return secure_partition->GetProgramTitleID(); 172 return secure_partition->GetProgramTitleID();
133} 173}
134 174
175u32 XCI::GetSystemUpdateVersion() {
176 const auto update = GetPartition(XCIPartition::Update);
177 if (update == nullptr)
178 return 0;
179
180 for (const auto& file : update->GetFiles()) {
181 NCA nca{file, nullptr, 0, keys};
182
183 if (nca.GetStatus() != Loader::ResultStatus::Success)
184 continue;
185
186 if (nca.GetType() == NCAContentType::Meta && nca.GetTitleId() == 0x0100000000000816) {
187 const auto dir = nca.GetSubdirectories()[0];
188 const auto cnmt = dir->GetFile("SystemUpdate_0100000000000816.cnmt");
189 if (cnmt == nullptr)
190 continue;
191
192 CNMT cnmt_data{cnmt};
193
194 const auto metas = cnmt_data.GetMetaRecords();
195 if (metas.empty())
196 continue;
197
198 return metas[0].title_version;
199 }
200 }
201
202 return 0;
203}
204
205u64 XCI::GetSystemUpdateTitleID() const {
206 return 0x0100000000000816;
207}
208
135bool XCI::HasProgramNCA() const { 209bool XCI::HasProgramNCA() const {
136 return program != nullptr; 210 return program != nullptr;
137} 211}
@@ -201,7 +275,7 @@ std::array<u8, 0x200> XCI::GetCertificate() const {
201 275
202Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { 276Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
203 const auto partition_index = static_cast<std::size_t>(part); 277 const auto partition_index = static_cast<std::size_t>(part);
204 const auto& partition = partitions[partition_index]; 278 const auto partition = GetPartition(part);
205 279
206 if (partition == nullptr) { 280 if (partition == nullptr) {
207 return Loader::ResultStatus::ErrorXCIMissingPartition; 281 return Loader::ResultStatus::ErrorXCIMissingPartition;
@@ -232,7 +306,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
232 return Loader::ResultStatus::Success; 306 return Loader::ResultStatus::Success;
233} 307}
234 308
235u8 XCI::GetFormatVersion() const { 309u8 XCI::GetFormatVersion() {
236 return GetLogoPartition() == nullptr ? 0x1 : 0x2; 310 return GetLogoPartition() == nullptr ? 0x1 : 0x2;
237} 311}
238} // namespace FileSys 312} // namespace FileSys
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h
index 3e6b92ff3..c2ee0ea99 100644
--- a/src/core/file_sys/card_image.h
+++ b/src/core/file_sys/card_image.h
@@ -81,14 +81,24 @@ 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
95 VirtualFile GetPartitionRaw(XCIPartition partition) const;
96 VirtualFile GetSecurePartitionRaw() const;
97 VirtualFile GetStoragePartition0() const;
98 VirtualFile GetStoragePartition1() const;
99 VirtualFile GetNormalPartitionRaw() const;
100 VirtualFile GetUpdatePartitionRaw() const;
101 VirtualFile GetLogoPartitionRaw() const;
92 102
93 u64 GetProgramTitleID() const; 103 u64 GetProgramTitleID() const;
94 u32 GetSystemUpdateVersion(); 104 u32 GetSystemUpdateVersion();
@@ -123,6 +133,7 @@ private:
123 Loader::ResultStatus program_nca_status; 133 Loader::ResultStatus program_nca_status;
124 134
125 std::vector<VirtualDir> partitions; 135 std::vector<VirtualDir> partitions;
136 std::vector<VirtualFile> partitions_raw;
126 std::shared_ptr<NSP> secure_partition; 137 std::shared_ptr<NSP> secure_partition;
127 std::shared_ptr<NCA> program; 138 std::shared_ptr<NCA> program;
128 std::vector<std::shared_ptr<NCA>> ncas; 139 std::vector<std::shared_ptr<NCA>> ncas;
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp
index a5259a593..846986736 100644
--- a/src/core/file_sys/partition_filesystem.cpp
+++ b/src/core/file_sys/partition_filesystem.cpp
@@ -65,6 +65,9 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
65 std::string name( 65 std::string name(
66 reinterpret_cast<const char*>(&file_data[strtab_offset + entry.strtab_offset])); 66 reinterpret_cast<const char*>(&file_data[strtab_offset + entry.strtab_offset]));
67 67
68 offsets.insert_or_assign(name, content_offset + entry.offset);
69 sizes.insert_or_assign(name, entry.size);
70
68 pfs_files.emplace_back(std::make_shared<OffsetVfsFile>( 71 pfs_files.emplace_back(std::make_shared<OffsetVfsFile>(
69 file, entry.size, content_offset + entry.offset, std::move(name))); 72 file, entry.size, content_offset + entry.offset, std::move(name)));
70 } 73 }
@@ -78,6 +81,14 @@ Loader::ResultStatus PartitionFilesystem::GetStatus() const {
78 return status; 81 return status;
79} 82}
80 83
84std::map<std::string, u64> PartitionFilesystem::GetFileOffsets() const {
85 return offsets;
86}
87
88std::map<std::string, u64> PartitionFilesystem::GetFileSizes() const {
89 return sizes;
90}
91
81std::vector<std::shared_ptr<VfsFile>> PartitionFilesystem::GetFiles() const { 92std::vector<std::shared_ptr<VfsFile>> PartitionFilesystem::GetFiles() const {
82 return pfs_files; 93 return pfs_files;
83} 94}
diff --git a/src/core/file_sys/partition_filesystem.h b/src/core/file_sys/partition_filesystem.h
index 248fdfdeb..279193b19 100644
--- a/src/core/file_sys/partition_filesystem.h
+++ b/src/core/file_sys/partition_filesystem.h
@@ -29,6 +29,9 @@ public:
29 29
30 Loader::ResultStatus GetStatus() const; 30 Loader::ResultStatus GetStatus() const;
31 31
32 std::map<std::string, u64> GetFileOffsets() const;
33 std::map<std::string, u64> GetFileSizes() const;
34
32 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; 35 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
33 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; 36 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
34 std::string GetName() const override; 37 std::string GetName() const override;
@@ -80,6 +83,9 @@ private:
80 bool is_hfs = false; 83 bool is_hfs = false;
81 std::size_t content_offset = 0; 84 std::size_t content_offset = 0;
82 85
86 std::map<std::string, u64> offsets;
87 std::map<std::string, u64> sizes;
88
83 std::vector<VirtualFile> pfs_files; 89 std::vector<VirtualFile> pfs_files;
84}; 90};
85 91