mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-25 11:56:42 +08:00 
			
		
		
		
	card_image: Lazily load partitions in XCI
This commit is contained in:
		
							parent
							
								
									3895f7e456
								
							
						
					
					
						commit
						3952c73aee
					
				| @ -31,7 +31,7 @@ constexpr std::array partition_names{ | |||||||
| 
 | 
 | ||||||
| XCI::XCI(VirtualFile file_) | XCI::XCI(VirtualFile file_) | ||||||
|     : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, |     : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, | ||||||
|       partitions(partition_names.size()) { |       partitions(partition_names.size()), partitions_raw(partition_names.size()) { | ||||||
|     if (file->ReadObject(&header) != sizeof(GamecardHeader)) { |     if (file->ReadObject(&header) != sizeof(GamecardHeader)) { | ||||||
|         status = Loader::ResultStatus::ErrorBadXCIHeader; |         status = Loader::ResultStatus::ErrorBadXCIHeader; | ||||||
|         return; |         return; | ||||||
| @ -42,8 +42,10 @@ XCI::XCI(VirtualFile file_) | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     PartitionFilesystem main_hfs( |     PartitionFilesystem main_hfs(std::make_shared<OffsetVfsFile>( | ||||||
|         std::make_shared<OffsetVfsFile>(file, header.hfs_size, header.hfs_offset)); |         file, file->GetSize() - header.hfs_offset, header.hfs_offset)); | ||||||
|  | 
 | ||||||
|  |     update_normal_partition_end = main_hfs.GetFileOffsets()["secure"]; | ||||||
| 
 | 
 | ||||||
|     if (main_hfs.GetStatus() != Loader::ResultStatus::Success) { |     if (main_hfs.GetStatus() != Loader::ResultStatus::Success) { | ||||||
|         status = main_hfs.GetStatus(); |         status = main_hfs.GetStatus(); | ||||||
| @ -55,9 +57,7 @@ XCI::XCI(VirtualFile file_) | |||||||
|         const auto partition_idx = static_cast<std::size_t>(partition); |         const auto partition_idx = static_cast<std::size_t>(partition); | ||||||
|         auto raw = main_hfs.GetFile(partition_names[partition_idx]); |         auto raw = main_hfs.GetFile(partition_names[partition_idx]); | ||||||
| 
 | 
 | ||||||
|         if (raw != nullptr) { |         partitions_raw[static_cast<std::size_t>(partition)] = raw; | ||||||
|             partitions[partition_idx] = std::make_shared<PartitionFilesystem>(std::move(raw)); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     secure_partition = std::make_shared<NSP>( |     secure_partition = std::make_shared<NSP>( | ||||||
| @ -71,13 +71,7 @@ XCI::XCI(VirtualFile file_) | |||||||
|         program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; |         program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto result = AddNCAFromPartition(XCIPartition::Update); |     auto result = AddNCAFromPartition(XCIPartition::Normal); | ||||||
|     if (result != Loader::ResultStatus::Success) { |  | ||||||
|         status = result; |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     result = AddNCAFromPartition(XCIPartition::Normal); |  | ||||||
|     if (result != Loader::ResultStatus::Success) { |     if (result != Loader::ResultStatus::Success) { | ||||||
|         status = result; |         status = result; | ||||||
|         return; |         return; | ||||||
| @ -104,27 +98,44 @@ Loader::ResultStatus XCI::GetProgramNCAStatus() const { | |||||||
|     return program_nca_status; |     return program_nca_status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VirtualDir XCI::GetPartition(XCIPartition partition) const { | VirtualDir XCI::GetPartition(XCIPartition partition) { | ||||||
|  |     const auto id = static_cast<std::size_t>(partition); | ||||||
|  |     if (partitions[id] == nullptr && partitions_raw[id] != nullptr) { | ||||||
|  |         partitions[id] = std::make_shared<PartitionFilesystem>(partitions_raw[id]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return partitions[static_cast<std::size_t>(partition)]; |     return partitions[static_cast<std::size_t>(partition)]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::vector<VirtualDir> XCI::GetPartitions() { | ||||||
|  |     std::vector<VirtualDir> out; | ||||||
|  |     for (const auto& id : | ||||||
|  |          {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { | ||||||
|  |         const auto part = GetPartition(id); | ||||||
|  |         if (part != nullptr) { | ||||||
|  |             out.push_back(part); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { | std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { | ||||||
|     return secure_partition; |     return secure_partition; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VirtualDir XCI::GetSecurePartition() const { | VirtualDir XCI::GetSecurePartition() { | ||||||
|     return GetPartition(XCIPartition::Secure); |     return GetPartition(XCIPartition::Secure); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VirtualDir XCI::GetNormalPartition() const { | VirtualDir XCI::GetNormalPartition() { | ||||||
|     return GetPartition(XCIPartition::Normal); |     return GetPartition(XCIPartition::Normal); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VirtualDir XCI::GetUpdatePartition() const { | VirtualDir XCI::GetUpdatePartition() { | ||||||
|     return GetPartition(XCIPartition::Update); |     return GetPartition(XCIPartition::Update); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| VirtualDir XCI::GetLogoPartition() const { | VirtualDir XCI::GetLogoPartition() { | ||||||
|     return GetPartition(XCIPartition::Logo); |     return GetPartition(XCIPartition::Logo); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -201,7 +212,7 @@ std::array<u8, 0x200> XCI::GetCertificate() const { | |||||||
| 
 | 
 | ||||||
| Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | ||||||
|     const auto partition_index = static_cast<std::size_t>(part); |     const auto partition_index = static_cast<std::size_t>(part); | ||||||
|     const auto& partition = partitions[partition_index]; |     const auto partition = GetPartition(part); | ||||||
| 
 | 
 | ||||||
|     if (partition == nullptr) { |     if (partition == nullptr) { | ||||||
|         return Loader::ResultStatus::ErrorXCIMissingPartition; |         return Loader::ResultStatus::ErrorXCIMissingPartition; | ||||||
| @ -232,7 +243,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | |||||||
|     return Loader::ResultStatus::Success; |     return Loader::ResultStatus::Success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u8 XCI::GetFormatVersion() const { | u8 XCI::GetFormatVersion() { | ||||||
|     return GetLogoPartition() == nullptr ? 0x1 : 0x2; |     return GetLogoPartition() == nullptr ? 0x1 : 0x2; | ||||||
| } | } | ||||||
| } // namespace FileSys
 | } // namespace FileSys
 | ||||||
|  | |||||||
| @ -81,14 +81,17 @@ public: | |||||||
|     Loader::ResultStatus GetStatus() const; |     Loader::ResultStatus GetStatus() const; | ||||||
|     Loader::ResultStatus GetProgramNCAStatus() const; |     Loader::ResultStatus GetProgramNCAStatus() const; | ||||||
| 
 | 
 | ||||||
|     u8 GetFormatVersion() const; |     u8 GetFormatVersion(); | ||||||
|  | 
 | ||||||
|  |     VirtualDir GetPartition(XCIPartition partition); | ||||||
|  |     std::vector<VirtualDir> GetPartitions(); | ||||||
| 
 | 
 | ||||||
|     VirtualDir GetPartition(XCIPartition partition) const; |  | ||||||
|     std::shared_ptr<NSP> GetSecurePartitionNSP() const; |     std::shared_ptr<NSP> GetSecurePartitionNSP() const; | ||||||
|     VirtualDir GetSecurePartition() const; |     VirtualDir GetSecurePartition(); | ||||||
|     VirtualDir GetNormalPartition() const; |     VirtualDir GetNormalPartition(); | ||||||
|     VirtualDir GetUpdatePartition() const; |     VirtualDir GetUpdatePartition(); | ||||||
|     VirtualDir GetLogoPartition() const; |     VirtualDir GetLogoPartition(); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     u64 GetProgramTitleID() const; |     u64 GetProgramTitleID() const; | ||||||
|     u32 GetSystemUpdateVersion(); |     u32 GetSystemUpdateVersion(); | ||||||
| @ -123,6 +126,7 @@ private: | |||||||
|     Loader::ResultStatus program_nca_status; |     Loader::ResultStatus program_nca_status; | ||||||
| 
 | 
 | ||||||
|     std::vector<VirtualDir> partitions; |     std::vector<VirtualDir> partitions; | ||||||
|  |     std::vector<VirtualFile> partitions_raw; | ||||||
|     std::shared_ptr<NSP> secure_partition; |     std::shared_ptr<NSP> secure_partition; | ||||||
|     std::shared_ptr<NCA> program; |     std::shared_ptr<NCA> program; | ||||||
|     std::vector<std::shared_ptr<NCA>> ncas; |     std::vector<std::shared_ptr<NCA>> ncas; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user