mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +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 {}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
    u16 platform = static_cast<u16>(titleId >> 48);
 | 
			
		||||
    u16 category = static_cast<u16>((titleId >> 32) & 0xFFFF);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/file_sys/cia_container.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +42,9 @@ enum class CIAInstallState : u32 {
 | 
			
		|||
    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.
 | 
			
		||||
class CIAFile final : public FileSys::FileBackend {
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +77,15 @@ private:
 | 
			
		|||
    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
 | 
			
		||||
 * @param titleId the installed title ID
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue