diff --git a/libraries/libstratosphere/include/stratosphere/ncm.hpp b/libraries/libstratosphere/include/stratosphere/ncm.hpp index 78b5a4d6e..cb9ee8c3e 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm.hpp @@ -29,8 +29,9 @@ #include #include #include -#include #include #include +#include +#include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_install_task_base.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_install_task_base.hpp index cabc7c569..3beb56f87 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_install_task_base.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_install_task_base.hpp @@ -26,6 +26,7 @@ namespace ams::ncm { }; enum InstallConfig { + InstallConfig_None = (0 << 0), InstallConfig_SystemUpdate = (1 << 2), InstallConfig_RequiresExFatDriver = (1 << 3), InstallConfig_IgnoreTicket = (1 << 4), diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task.hpp new file mode 100644 index 000000000..a7b90602d --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task.hpp @@ -0,0 +1,36 @@ +/* + * 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 . + */ +#pragma once +#include + +namespace ams::ncm { + + class PackageInstallTask : public PackageInstallTaskBase { + private: + MemoryInstallTaskData data; + public: + PackageInstallTask() { /* ... */ } + virtual ~PackageInstallTask() override { /* ... */ } + + Result Initialize(const char *package_path, StorageId storage_id, void *buffer, size_t buffer_size, bool ignore_ticket); + protected: + bool IsContentMetaContentName(const char *name); + virtual Result PrepareInstallContentMetaData() override; + private: + virtual Result GetInstallContentMetaInfo(InstallContentMetaInfo *out_info, const ContentMetaKey &key) override; + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task_base.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task_base.hpp index 72580ae30..892921eb9 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task_base.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_package_install_task_base.hpp @@ -29,7 +29,7 @@ namespace ams::ncm { public: PackageInstallTaskBase() : package_root() { /* ... */ } - Result Initialize(const char *package_path, void *buffer, size_t buffer_size, StorageId storage_id, InstallTaskDataBase *data, u32 config); + Result Initialize(const char *package_root_path, void *buffer, size_t buffer_size, StorageId storage_id, InstallTaskDataBase *data, u32 config); protected: const char *GetPackageRootPath() { return this->package_root.Get(); diff --git a/libraries/libstratosphere/source/ncm/ncm_package_install_task.cpp b/libraries/libstratosphere/source/ncm/ncm_package_install_task.cpp new file mode 100644 index 000000000..a59ad9d8c --- /dev/null +++ b/libraries/libstratosphere/source/ncm/ncm_package_install_task.cpp @@ -0,0 +1,62 @@ +/* + * 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 . + */ +#include +#include "ncm_fs_utils.hpp" + +namespace ams::ncm { + + bool PackageInstallTask::IsContentMetaContentName(const char *name) { + return impl::PathView(name).HasSuffix(".cnmt"); + } + + Result PackageInstallTask::Initialize(const char *package_root_path, StorageId storage_id, void *buffer, size_t buffer_size, bool ignore_ticket) { + return PackageInstallTaskBase::Initialize(package_root_path, buffer, buffer_size, storage_id, std::addressof(this->data), ignore_ticket ? InstallConfig_IgnoreTicket : InstallConfig_None); + } + + Result PackageInstallTask::GetInstallContentMetaInfo(InstallContentMetaInfo *out_info, const ContentMetaKey &key) { + return ncm::ResultContentNotFound(); + } + + Result PackageInstallTask::PrepareInstallContentMetaData() { + /* Open the directory. */ + fs::DirectoryHandle dir; + R_TRY(fs::OpenDirectory(std::addressof(dir), this->GetPackageRootPath(), fs::OpenDirectoryMode_File)); + ON_SCOPE_EXIT { fs::CloseDirectory(dir); }; + + while (true) { + /* Read the current entry. */ + s64 count; + fs::DirectoryEntry entry; + R_TRY(fs::ReadDirectory(std::addressof(count), std::addressof(entry), dir, 1)); + + /* No more entries remain, we are done. */ + if (count == 0) { + break; + } + + /* Check if this entry is content meta. */ + if (this->IsContentMetaContentName(entry.name)) { + /* Prepare content meta if id is valid. */ + std::optional id = GetContentIdFromString(entry.name, strnlen(entry.name, fs::EntryNameLengthMax + 1)); + R_UNLESS(id, ncm::ResultInvalidPackageFormat()); + R_TRY(this->PrepareContentMeta(InstallContentMetaInfo::MakeUnverifiable(*id, entry.file_size, ContentMetaKey::MakeUnknownType(0, 0)), std::nullopt, std::nullopt)); + } + } + + return ResultSuccess(); + } + +} diff --git a/libraries/libstratosphere/source/ncm/ncm_package_install_task_base.cpp b/libraries/libstratosphere/source/ncm/ncm_package_install_task_base.cpp index 4ef586e2b..7fe4d93bc 100644 --- a/libraries/libstratosphere/source/ncm/ncm_package_install_task_base.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_package_install_task_base.cpp @@ -17,9 +17,9 @@ namespace ams::ncm { - Result PackageInstallTaskBase::Initialize(const char *package_path, void *buffer, size_t buffer_size, StorageId storage_id, InstallTaskDataBase *data, u32 config) { + Result PackageInstallTaskBase::Initialize(const char *package_root_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->package_root.Set(package_root_path); this->buffer = buffer; this->buffer_size = buffer_size; return ResultSuccess();