mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Services/AM: Add InstallCIA function for frontends
This commit is contained in:
		
							parent
							
								
									1f2aa29dee
								
							
						
					
					
						commit
						56e906f1e3
					
				
					 2 changed files with 56 additions and 0 deletions
				
			
		|  | @ -283,6 +283,49 @@ bool CIAFile::Close() const { | ||||||
| 
 | 
 | ||||||
| void CIAFile::Flush() const {} | void CIAFile::Flush() const {} | ||||||
| 
 | 
 | ||||||
|  | bool InstallCIA(const std::string& path, std::function<ProgressCallback>&& update_callback) { | ||||||
|  |     LOG_INFO(Service_AM, "Installing %s...", path.c_str()); | ||||||
|  | 
 | ||||||
|  |     if (!FileUtil::Exists(path)) { | ||||||
|  |         LOG_ERROR(Service_AM, "File %s does not exist!", path.c_str()); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     FileSys::CIAContainer container; | ||||||
|  |     if (container.Load(path) == Loader::ResultStatus::Success) { | ||||||
|  |         Service::AM::CIAFile installFile( | ||||||
|  |             Service::AM::GetTitleMediaType(container.GetTitleMetadata().GetTitleID())); | ||||||
|  | 
 | ||||||
|  |         FileUtil::IOFile file(path, "rb"); | ||||||
|  |         if (!file.IsOpen()) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         std::array<u8, 0x10000> buffer; | ||||||
|  |         size_t total_bytes_read = 0; | ||||||
|  |         while (total_bytes_read != file.GetSize()) { | ||||||
|  |             size_t bytes_read = file.ReadBytes(buffer.data(), buffer.size()); | ||||||
|  |             auto result = installFile.Write(static_cast<u64>(total_bytes_read), bytes_read, true, | ||||||
|  |                                             static_cast<u8*>(buffer.data())); | ||||||
|  | 
 | ||||||
|  |             if (update_callback) | ||||||
|  |                 update_callback(total_bytes_read, file.GetSize()); | ||||||
|  |             if (result.Failed()) { | ||||||
|  |                 LOG_ERROR(Service_AM, "CIA file installation aborted with error code %08x", | ||||||
|  |                           result.Code()); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |             total_bytes_read += bytes_read; | ||||||
|  |         } | ||||||
|  |         installFile.Close(); | ||||||
|  | 
 | ||||||
|  |         LOG_INFO(Service_AM, "Installed %s successfully.", path.c_str()); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LOG_ERROR(Service_AM, "CIA file %s is invalid!", path.c_str()); | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Service::FS::MediaType GetTitleMediaType(u64 titleId) { | Service::FS::MediaType GetTitleMediaType(u64 titleId) { | ||||||
|     u16 platform = static_cast<u16>(titleId >> 48); |     u16 platform = static_cast<u16>(titleId >> 48); | ||||||
|     u16 category = static_cast<u16>((titleId >> 32) & 0xFFFF); |     u16 category = static_cast<u16>((titleId >> 32) & 0xFFFF); | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <functional> | ||||||
| #include <string> | #include <string> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "core/file_sys/cia_container.h" | #include "core/file_sys/cia_container.h" | ||||||
|  | @ -41,6 +42,9 @@ enum class CIAInstallState : u32 { | ||||||
|     ContentWritten, |     ContentWritten, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // Progress callback for InstallCIA, recieves bytes written and total bytes
 | ||||||
|  | using ProgressCallback = void(size_t, size_t); | ||||||
|  | 
 | ||||||
| // A file handled returned for CIAs to be written into and subsequently installed.
 | // A file handled returned for CIAs to be written into and subsequently installed.
 | ||||||
| class CIAFile final : public FileSys::FileBackend { | class CIAFile final : public FileSys::FileBackend { | ||||||
| public: | public: | ||||||
|  | @ -73,6 +77,15 @@ private: | ||||||
|     Service::FS::MediaType media_type; |     Service::FS::MediaType media_type; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Installs a CIA file from a specified file path. | ||||||
|  |  * @param path file path of the CIA file to install | ||||||
|  |  * @param update_callback callback function called during filesystem write | ||||||
|  |  * @returns bool whether the install was successful | ||||||
|  |  */ | ||||||
|  | bool InstallCIA(const std::string& path, | ||||||
|  |                 std::function<ProgressCallback>&& update_callback = nullptr); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Get the mediatype for an installed title |  * Get the mediatype for an installed title | ||||||
|  * @param titleId the installed title ID |  * @param titleId the installed title ID | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue