Services/AM: Add InstallCIA function for frontends
This commit is contained in:
parent
1f2aa29dee
commit
56e906f1e3
@ -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…
Reference in New Issue
Block a user