mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-22 12:34:47 +00:00
ncm client: implement PackageInstallTaskBase
This commit is contained in:
parent
cce292e524
commit
27de9ea37b
6 changed files with 156 additions and 2 deletions
|
@ -28,7 +28,8 @@
|
|||
#include <stratosphere/ncm/ncm_content_manager_impl.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_utils.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_occupied_size.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 str;
|
||||
GetStringFromContentId(str.data, sizeof(str), id);
|
||||
|
@ -60,6 +59,25 @@ namespace ams::ncm {
|
|||
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) {
|
||||
if (len < ContentIdStringLength) {
|
||||
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…
Add table
Reference in a new issue