summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/file_sys/card_image.cpp51
-rw-r--r--src/core/file_sys/card_image.h16
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
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)] = 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
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
@@ -201,7 +212,7 @@ std::array<u8, 0x200> XCI::GetCertificate() const {
201 212
202Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { 213Loader::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
235u8 XCI::GetFormatVersion() const { 246u8 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;