mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-17 14:22:13 +02:00
ncm client: implement PackageInstallTaskBase
This commit is contained in:
parent
cce292e524
commit
27de9ea37b
@ -28,7 +28,8 @@
|
|||||||
#include <stratosphere/ncm/ncm_content_manager_impl.hpp>
|
#include <stratosphere/ncm/ncm_content_manager_impl.hpp>
|
||||||
#include <stratosphere/ncm/ncm_content_meta_utils.hpp>
|
#include <stratosphere/ncm/ncm_content_meta_utils.hpp>
|
||||||
#include <stratosphere/ncm/ncm_firmware_variation.hpp>
|
#include <stratosphere/ncm/ncm_firmware_variation.hpp>
|
||||||
#include <stratosphere/ncm/ncm_install_task.hpp>
|
#include <stratosphere/ncm/ncm_install_task_base.hpp>
|
||||||
|
#include <stratosphere/ncm/ncm_package_install_task_base.hpp>
|
||||||
#include <stratosphere/ncm/ncm_install_task_data.hpp>
|
#include <stratosphere/ncm/ncm_install_task_data.hpp>
|
||||||
#include <stratosphere/ncm/ncm_install_task_occupied_size.hpp>
|
#include <stratosphere/ncm/ncm_install_task_occupied_size.hpp>
|
||||||
#include <stratosphere/ncm/ncm_storage_id_utils.hpp>
|
#include <stratosphere/ncm/ncm_storage_id_utils.hpp>
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere/kvdb/kvdb_bounded_string.hpp>
|
||||||
|
#include <stratosphere/ncm/ncm_install_task_base.hpp>
|
||||||
|
|
||||||
|
namespace ams::ncm {
|
||||||
|
|
||||||
|
class PackageInstallTaskBase : public InstallTaskBase {
|
||||||
|
private:
|
||||||
|
using PackagePath = kvdb::BoundedString<256>;
|
||||||
|
private:
|
||||||
|
PackagePath package_root;
|
||||||
|
void *buffer;
|
||||||
|
size_t buffer_size;
|
||||||
|
public:
|
||||||
|
Result Initialize(const char *package_path, void *buffer, size_t buffer_size, StorageId storage_id, InstallTaskDataBase *data, u32 config);
|
||||||
|
protected:
|
||||||
|
const char *GetPackageRootPath() {
|
||||||
|
return this->package_root.Get();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void CreateContentMetaPath(PackagePath *out_path, ContentId content_id);
|
||||||
|
void CreateContentPath(PackagePath *out_path, ContentId content_id);
|
||||||
|
Result InstallTicket(const fs::RightsId &rights_id, ContentMetaType meta_type);
|
||||||
|
void CreateTicketPath(PackagePath *out_path, fs::RightsId id);
|
||||||
|
void CreateCertificatePath(PackagePath *out_path, fs::RightsId id);
|
||||||
|
private:
|
||||||
|
virtual Result OnWritePlaceHolder(const ContentMetaKey &key, InstallContentInfo *content_info) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -48,7 +48,6 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ContentIdString GetContentIdString(ContentId id) {
|
ContentIdString GetContentIdString(ContentId id) {
|
||||||
ContentIdString str;
|
ContentIdString str;
|
||||||
GetStringFromContentId(str.data, sizeof(str), id);
|
GetStringFromContentId(str.data, sizeof(str), id);
|
||||||
@ -60,6 +59,25 @@ namespace ams::ncm {
|
|||||||
GetStringFromBytes(dst, std::addressof(id), sizeof(id));
|
GetStringFromBytes(dst, std::addressof(id), sizeof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id) {
|
||||||
|
AMS_ABORT_UNLESS(dst_size > RightsIdStringLength);
|
||||||
|
GetStringFromBytes(dst, std::addressof(id), sizeof(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetTicketFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id) {
|
||||||
|
AMS_ABORT_UNLESS(dst_size > TicketFileStringLength);
|
||||||
|
ContentIdString str;
|
||||||
|
GetStringFromRightsId(str.data, sizeof(str), id);
|
||||||
|
std::snprintf(dst, dst_size, "%s.tik", str.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id) {
|
||||||
|
AMS_ABORT_UNLESS(dst_size > CertFileStringLength);
|
||||||
|
ContentIdString str;
|
||||||
|
GetStringFromRightsId(str.data, sizeof(str), id);
|
||||||
|
std::snprintf(dst, dst_size, "%s.cert", str.data);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len) {
|
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len) {
|
||||||
if (len < ContentIdStringLength) {
|
if (len < ContentIdStringLength) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::ncm {
|
||||||
|
|
||||||
|
Result PackageInstallTaskBase::Initialize(const char *package_path, void *buffer, size_t buffer_size, StorageId storage_id, InstallTaskDataBase *data, u32 config) {
|
||||||
|
R_TRY(InstallTaskBase::Initialize(storage_id, data, config));
|
||||||
|
this->package_root.Set(package_path);
|
||||||
|
this->buffer = buffer;
|
||||||
|
this->buffer_size = buffer_size;
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result PackageInstallTaskBase::OnWritePlaceHolder(const ContentMetaKey &key, InstallContentInfo *content_info) {
|
||||||
|
PackagePath path;
|
||||||
|
if (content_info->GetType() == ContentType::Meta) {
|
||||||
|
this->CreateContentMetaPath(std::addressof(path), content_info->GetId());
|
||||||
|
} else {
|
||||||
|
this->CreateContentPath(std::addressof(path), content_info->GetId());
|
||||||
|
}
|
||||||
|
/* Open the file. */
|
||||||
|
fs::FileHandle file;
|
||||||
|
R_TRY(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read));
|
||||||
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
/* Continuously write the file to the placeholder until there is nothing left to write. */
|
||||||
|
while (true) {
|
||||||
|
/* Read as much of the remainder of the file as possible. */
|
||||||
|
size_t size_read;
|
||||||
|
R_TRY(fs::ReadFile(std::addressof(size_read), file, content_info->written, this->buffer, this->buffer_size));
|
||||||
|
|
||||||
|
/* There is nothing left to read. */
|
||||||
|
if (size_read == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the placeholder. */
|
||||||
|
R_TRY(this->WritePlaceHolderBuffer(content_info, this->buffer, size_read));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackageInstallTaskBase::CreateContentMetaPath(PackagePath *out_path, ContentId content_id) {
|
||||||
|
char str[ContentIdStringLength + 1] = {};
|
||||||
|
GetStringFromContentId(str, sizeof(str), content_id);
|
||||||
|
out_path->SetFormat("%s%s%s", this->package_root.Get(), str, ".cnmt.nca");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackageInstallTaskBase::CreateContentPath(PackagePath *out_path, ContentId content_id) {
|
||||||
|
char str[ContentIdStringLength + 1] = {};
|
||||||
|
GetStringFromContentId(str, sizeof(str), content_id);
|
||||||
|
out_path->SetFormat("%s%s%s", this->package_root.Get(), str, ".nca");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result PackageInstallTaskBase::InstallTicket(const fs::RightsId &rights_id, ContentMetaType meta_type) {
|
||||||
|
/* TODO: Read ticket from file. */
|
||||||
|
/* TODO: Read certificate from file. */
|
||||||
|
/* TODO: es::ImportTicket() */
|
||||||
|
/* TODO: How should es be handled without undesired effects? */
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackageInstallTaskBase::CreateTicketPath(PackagePath *out_path, fs::RightsId id) {
|
||||||
|
char str[RightsIdStringLength + 1] = {};
|
||||||
|
GetStringFromRightsId(str, sizeof(str), id);
|
||||||
|
out_path->SetFormat("%s%s%s", this->package_root.Get(), str, ".tik");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackageInstallTaskBase::CreateCertificatePath(PackagePath *out_path, fs::RightsId id) {
|
||||||
|
char str[RightsIdStringLength + 1] = {};
|
||||||
|
GetStringFromRightsId(str, sizeof(str), id);
|
||||||
|
out_path->SetFormat("%s%s%s", this->package_root.Get(), str, ".cert");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user