Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"
This reverts commit 15b7df8ef1.
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_meta_database.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_storage.hpp>
|
||||
#include <stratosphere/ncm/ncm_i_content_manager.hpp>
|
||||
#include <stratosphere/fs/fs_content_storage_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
/* Management. */
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
|
||||
void InitializeWithObject(sf::SharedPointer<IContentManager> manager_object);
|
||||
|
||||
/* Service API. */
|
||||
Result CreateContentStorage(StorageId storage_id);
|
||||
Result CreateContentMetaDatabase(StorageId storage_id);
|
||||
|
||||
Result VerifyContentStorage(StorageId storage_id);
|
||||
Result VerifyContentMetaDatabase(StorageId storage_id);
|
||||
|
||||
Result OpenContentStorage(ContentStorage *out, StorageId storage_id);
|
||||
Result OpenContentMetaDatabase(ContentMetaDatabase *out, StorageId storage_id);
|
||||
|
||||
Result CleanupContentMetaDatabase(StorageId storage_id);
|
||||
|
||||
Result ActivateContentStorage(StorageId storage_id);
|
||||
Result InactivateContentStorage(StorageId storage_id);
|
||||
|
||||
Result ActivateContentMetaDatabase(StorageId storage_id);
|
||||
Result InactivateContentMetaDatabase(StorageId storage_id);
|
||||
|
||||
Result InvalidateRightsIdCache();
|
||||
|
||||
Result ActivateFsContentStorage(fs::ContentStorageId fs_content_storage_id);
|
||||
|
||||
/* Deprecated API. */
|
||||
Result CloseContentStorageForcibly(StorageId storage_id);
|
||||
Result CloseContentMetaDatabaseForcibly(StorageId storage_id);
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class AutoBuffer {
|
||||
NON_COPYABLE(AutoBuffer);
|
||||
private:
|
||||
u8 *m_buffer;
|
||||
size_t m_size;
|
||||
public:
|
||||
AutoBuffer() : m_buffer(nullptr), m_size(0) { /* ... */ }
|
||||
|
||||
~AutoBuffer() {
|
||||
this->Reset();
|
||||
}
|
||||
|
||||
AutoBuffer(AutoBuffer &&rhs) {
|
||||
m_buffer = rhs.m_buffer;
|
||||
m_size = rhs.m_size;
|
||||
rhs.m_buffer = nullptr;
|
||||
rhs.m_size = 0;
|
||||
}
|
||||
|
||||
AutoBuffer &operator=(AutoBuffer &&rhs) {
|
||||
AutoBuffer(std::move(rhs)).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Swap(AutoBuffer &rhs) {
|
||||
std::swap(m_buffer, rhs.m_buffer);
|
||||
std::swap(m_size, rhs.m_size);
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
if (m_buffer != nullptr) {
|
||||
delete[] m_buffer;
|
||||
m_buffer = nullptr;
|
||||
m_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
u8 *Get() const {
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
size_t GetSize() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
Result Initialize(size_t size) {
|
||||
/* Check that we're not already initialized. */
|
||||
AMS_ABORT_UNLESS(m_buffer == nullptr);
|
||||
|
||||
/* Allocate a buffer. */
|
||||
m_buffer = new (std::nothrow) u8[size];
|
||||
R_UNLESS(m_buffer != nullptr, ncm::ResultAllocationFailed());
|
||||
|
||||
m_size = size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Initialize(const void *buf, size_t size) {
|
||||
/* Create a new buffer of the right size. */
|
||||
R_TRY(this->Initialize(size));
|
||||
|
||||
/* Copy the input data in. */
|
||||
std::memcpy(m_buffer, buf, size);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
template<class Key, class Value, size_t N>
|
||||
using BoundedMap = util::BoundedMap<Key, Value, N>;
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct ContentId {
|
||||
util::Uuid uuid;
|
||||
|
||||
bool operator==(const ContentId &other) const {
|
||||
return this->uuid == other.uuid;
|
||||
}
|
||||
|
||||
bool operator!=(const ContentId &other) const {
|
||||
return this->uuid != other.uuid;
|
||||
}
|
||||
|
||||
bool operator==(const util::Uuid &other) const {
|
||||
return this->uuid == other;
|
||||
}
|
||||
|
||||
bool operator!=(const util::Uuid &other) const {
|
||||
return this->uuid != other;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(alignof(ContentId) == 1);
|
||||
|
||||
constexpr inline ContentId InvalidContentId = { util::InvalidUuid };
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/fs/fs_rights_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_info_data.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
constexpr inline size_t ContentIdStringLength = 2 * sizeof(ContentId);
|
||||
constexpr inline size_t RightsIdStringLength = 2 * sizeof(fs::RightsId);
|
||||
constexpr inline size_t TicketFileStringLength = RightsIdStringLength + 4;
|
||||
constexpr inline size_t CertFileStringLength = RightsIdStringLength + 5;
|
||||
|
||||
struct ContentIdString {
|
||||
char data[ContentIdStringLength + 1];
|
||||
};
|
||||
|
||||
ContentIdString GetContentIdString(ContentId id);
|
||||
|
||||
void GetStringFromContentId(char *dst, size_t dst_size, ContentId id);
|
||||
void GetStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
||||
|
||||
void GetTicketFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
||||
void GetCertificateFileStringFromRightsId(char *dst, size_t dst_size, fs::RightsId id);
|
||||
|
||||
util::optional<ContentId> GetContentIdFromString(const char *str, size_t len);
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/fs/fs_content_attributes.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_type.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct ContentInfo {
|
||||
static constexpr fs::ContentAttributes DefaultContentAttributes = fs::ContentAttributes_None;
|
||||
|
||||
ContentId content_id;
|
||||
u32 size_low;
|
||||
u8 size_high;
|
||||
u8 content_attributes;
|
||||
ContentType content_type;
|
||||
u8 id_offset;
|
||||
|
||||
constexpr const ContentId &GetId() const {
|
||||
return this->content_id;
|
||||
}
|
||||
|
||||
constexpr u64 GetSize() const {
|
||||
return (static_cast<u64>(this->size_high) << 32) | static_cast<u64>(this->size_low);
|
||||
}
|
||||
|
||||
constexpr fs::ContentAttributes GetContentAttributes() const {
|
||||
return static_cast<fs::ContentAttributes>(this->content_attributes & 0xF);
|
||||
}
|
||||
|
||||
constexpr ContentType GetType() const {
|
||||
return this->content_type;
|
||||
}
|
||||
|
||||
constexpr u8 GetIdOffset() const {
|
||||
return this->id_offset;
|
||||
}
|
||||
|
||||
static constexpr ContentInfo Make(ContentId id, u64 size, fs::ContentAttributes attr, ContentType type, u8 id_ofs = 0) {
|
||||
const u32 size_low = size & 0xFFFFFFFFu;
|
||||
const u8 size_high = static_cast<u8>(size >> 32);
|
||||
return {
|
||||
.content_id = id,
|
||||
.size_low = size_low,
|
||||
.size_high = size_high,
|
||||
.content_attributes = attr,
|
||||
.content_type = type,
|
||||
.id_offset = id_ofs,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(util::is_pod<ContentInfo>::value));
|
||||
static_assert(sizeof(ContentInfo) == 0x18);
|
||||
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_info.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_storage.hpp>
|
||||
#include <stratosphere/ncm/ncm_storage_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_key.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct Digest {
|
||||
u8 data[crypto::Sha256Generator::HashSize];
|
||||
};
|
||||
|
||||
enum class InstallState : u8 {
|
||||
NotPrepared,
|
||||
Prepared,
|
||||
Installed,
|
||||
AlreadyExists,
|
||||
};
|
||||
|
||||
struct PackagedContentInfo {
|
||||
Digest digest;
|
||||
ContentInfo info;
|
||||
|
||||
constexpr const ContentId &GetId() const {
|
||||
return this->info.GetId();
|
||||
}
|
||||
|
||||
constexpr fs::ContentAttributes GetContentAttributes() const {
|
||||
return this->info.GetContentAttributes();
|
||||
}
|
||||
|
||||
constexpr ContentType GetType() const {
|
||||
return this->info.GetType();
|
||||
}
|
||||
|
||||
constexpr u8 GetIdOffset() const {
|
||||
return this->info.GetIdOffset();
|
||||
}
|
||||
};
|
||||
|
||||
struct InstallContentInfo {
|
||||
Digest digest;
|
||||
crypto::Sha256Context context;
|
||||
u8 buffered_data[crypto::Sha256Generator::BlockSize];
|
||||
u64 buffered_data_size;
|
||||
ContentInfo info;
|
||||
PlaceHolderId placeholder_id;
|
||||
ContentMetaType meta_type;
|
||||
InstallState install_state;
|
||||
bool verify_digest;
|
||||
StorageId storage_id;
|
||||
bool is_temporary;
|
||||
bool is_sha256_calculated;
|
||||
s64 written;
|
||||
|
||||
constexpr const ContentId &GetId() const {
|
||||
return this->info.GetId();
|
||||
}
|
||||
|
||||
constexpr u64 GetSize() const {
|
||||
return this->info.GetSize();
|
||||
}
|
||||
|
||||
constexpr fs::ContentAttributes GetContentAttributes() const {
|
||||
return this->info.GetContentAttributes();
|
||||
}
|
||||
|
||||
constexpr ContentType GetType() const {
|
||||
return this->info.GetType();
|
||||
}
|
||||
|
||||
constexpr u8 GetIdOffset() const {
|
||||
return this->info.GetIdOffset();
|
||||
}
|
||||
|
||||
constexpr const PlaceHolderId &GetPlaceHolderId() const {
|
||||
return this->placeholder_id;
|
||||
}
|
||||
|
||||
constexpr ContentMetaType GetContentMetaType() const {
|
||||
return this->meta_type;
|
||||
}
|
||||
|
||||
constexpr InstallState GetInstallState() const {
|
||||
return this->install_state;
|
||||
}
|
||||
|
||||
constexpr StorageId GetStorageId() const {
|
||||
return this->storage_id;
|
||||
}
|
||||
|
||||
constexpr s64 GetSizeWritten() const {
|
||||
return this->written;
|
||||
}
|
||||
|
||||
static constexpr InstallContentInfo Make(const ContentInfo &info, ContentMetaType meta_type) {
|
||||
return {
|
||||
.info = info,
|
||||
.meta_type = meta_type,
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr InstallContentInfo Make(const PackagedContentInfo &info, ContentMetaType meta_type) {
|
||||
return {
|
||||
.digest = info.digest,
|
||||
.info = info.info,
|
||||
.meta_type = meta_type,
|
||||
.verify_digest = true,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(InstallContentInfo) == 0xC8);
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_key.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
constexpr inline s64 MaxClusterSize = 256_KB;
|
||||
|
||||
s64 CalculateRequiredSize(s64 file_size, s64 cluster_size = MaxClusterSize);
|
||||
s64 CalculateRequiredSizeForExtension(s64 file_size, s64 cluster_size = MaxClusterSize);
|
||||
|
||||
class ContentMetaDatabase;
|
||||
|
||||
Result EstimateRequiredSize(s64 *out_size, const ContentMetaKey &key, ContentMetaDatabase *db);
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_meta.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_database.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_storage.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class ContentMetaDatabaseBuilder {
|
||||
private:
|
||||
ContentMetaDatabase *m_db;
|
||||
private:
|
||||
Result BuildFromPackageContentMeta(void *buf, size_t size, const ContentInfo &meta_info);
|
||||
public:
|
||||
explicit ContentMetaDatabaseBuilder(ContentMetaDatabase *d) : m_db(d) { /* ... */ }
|
||||
|
||||
Result BuildFromStorage(ContentStorage *storage);
|
||||
Result BuildFromPackage(const char *package_root_path);
|
||||
|
||||
Result Cleanup();
|
||||
};
|
||||
|
||||
Result ListApplicationPackage(s32 *out_count, ApplicationId *out_ids, s32 max_out_ids, const char *package_root_path);
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct ContentManagerConfig {
|
||||
bool build_system_database;
|
||||
bool import_database_from_system_on_sd;
|
||||
bool enable_integrated_system_content;
|
||||
|
||||
bool HasAnyConfig() const {
|
||||
return this->ShouldBuildDatabase() || this->import_database_from_system_on_sd || this->enable_integrated_system_content;
|
||||
}
|
||||
|
||||
bool ShouldBuildDatabase() const {
|
||||
return hos::GetVersion() < hos::Version_4_0_0 || this->build_system_database;
|
||||
}
|
||||
|
||||
bool ShouldImportDatabaseFromSignedSystemPartitionOnSd() const {
|
||||
return this->import_database_from_system_on_sd;
|
||||
}
|
||||
|
||||
bool IsIntegratedSystemContentEnabled() const {
|
||||
return this->enable_integrated_system_content;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/os.hpp>
|
||||
#include <stratosphere/fs/fs_mount.hpp>
|
||||
#include <stratosphere/fs/fs_bis.hpp>
|
||||
#include <stratosphere/fs/fs_content_storage.hpp>
|
||||
#include <stratosphere/fs/fs_system_save_data.hpp>
|
||||
#include <stratosphere/ncm/ncm_i_content_manager.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_manager_config.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_database.hpp>
|
||||
#include <stratosphere/ncm/ncm_bounded_map.hpp>
|
||||
#include <stratosphere/ncm/ncm_rights_id_cache.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_management_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_registered_host_content.hpp>
|
||||
#include <stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp>
|
||||
#include <stratosphere/ncm/ncm_integrated_content_storage_impl.hpp>
|
||||
#include <stratosphere/kvdb/kvdb_memory_key_value_store.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class ContentMetaMemoryResource : public MemoryResource {
|
||||
private:
|
||||
mem::StandardAllocator m_allocator;
|
||||
size_t m_peak_total_alloc_size;
|
||||
size_t m_peak_alloc_size;
|
||||
public:
|
||||
explicit ContentMetaMemoryResource(void *heap, size_t heap_size) : m_allocator(heap, heap_size), m_peak_total_alloc_size(0), m_peak_alloc_size(0) { /* ... */ }
|
||||
|
||||
mem::StandardAllocator *GetAllocator() { return std::addressof(m_allocator); }
|
||||
size_t GetPeakTotalAllocationSize() const { return m_peak_total_alloc_size; }
|
||||
size_t GetPeakAllocationSize() const { return m_peak_alloc_size; }
|
||||
private:
|
||||
virtual void *AllocateImpl(size_t size, size_t alignment) override {
|
||||
void *mem = m_allocator.Allocate(size, alignment);
|
||||
m_peak_total_alloc_size = std::max(m_allocator.Hash().allocated_size, m_peak_total_alloc_size);
|
||||
m_peak_alloc_size = std::max(size, m_peak_alloc_size);
|
||||
return mem;
|
||||
}
|
||||
|
||||
virtual void DeallocateImpl(void *buffer, size_t size, size_t alignment) override {
|
||||
AMS_UNUSED(size, alignment);
|
||||
return m_allocator.Free(buffer);
|
||||
}
|
||||
|
||||
virtual bool IsEqualImpl(const MemoryResource &resource) const override {
|
||||
return this == std::addressof(resource);
|
||||
}
|
||||
};
|
||||
|
||||
struct SystemSaveDataInfo {
|
||||
u64 id;
|
||||
u64 size;
|
||||
u64 journal_size;
|
||||
u32 flags;
|
||||
fs::SaveDataSpaceId space_id;
|
||||
};
|
||||
static_assert(util::is_pod<SystemSaveDataInfo>::value);
|
||||
|
||||
struct IntegratedContentStorageImpl;
|
||||
|
||||
class ContentManagerImpl {
|
||||
private:
|
||||
constexpr static size_t MaxContentStorageRoots = 8;
|
||||
constexpr static size_t MaxIntegratedContentStorageRoots = 8;
|
||||
constexpr static size_t MaxContentMetaDatabaseRoots = 8;
|
||||
constexpr static size_t MaxIntegratedContentMetaDatabaseRoots = 8;
|
||||
constexpr static size_t MaxConfigs = 8;
|
||||
constexpr static size_t MaxIntegratedConfigs = 8;
|
||||
private:
|
||||
struct ContentStorageConfig {
|
||||
fs::ContentStorageId content_storage_id;
|
||||
bool skip_verify_and_create;
|
||||
bool skip_activate;
|
||||
};
|
||||
|
||||
struct IntegratedContentStorageConfig {
|
||||
ncm::StorageId storage_id;
|
||||
fs::ContentStorageId content_storage_ids[MaxContentStorageRoots];
|
||||
int num_content_storage_ids;
|
||||
bool is_integrated;
|
||||
};
|
||||
private:
|
||||
struct ContentStorageRoot {
|
||||
NON_COPYABLE(ContentStorageRoot);
|
||||
NON_MOVEABLE(ContentStorageRoot);
|
||||
|
||||
char mount_name[fs::MountNameLengthMax + 1];
|
||||
char path[128];
|
||||
StorageId storage_id;
|
||||
util::optional<ContentStorageConfig> config;
|
||||
sf::SharedPointer<IContentStorage> content_storage;
|
||||
|
||||
ContentStorageRoot() : mount_name(), path(), storage_id(), config(util::nullopt), content_storage() { /* ... */ }
|
||||
};
|
||||
|
||||
struct IntegratedContentStorageRoot {
|
||||
NON_COPYABLE(IntegratedContentStorageRoot);
|
||||
NON_MOVEABLE(IntegratedContentStorageRoot);
|
||||
|
||||
const IntegratedContentStorageConfig *m_config;
|
||||
ContentStorageRoot *m_roots;
|
||||
int m_num_roots;
|
||||
sf::EmplacedRef<IContentStorage, IntegratedContentStorageImpl> m_integrated_content_storage;
|
||||
|
||||
IntegratedContentStorageRoot() : m_config(), m_roots(), m_num_roots(), m_integrated_content_storage() { /* ... */ }
|
||||
|
||||
Result Create();
|
||||
Result Verify();
|
||||
Result Open(sf::Out<sf::SharedPointer<IContentStorage>> out, RightsIdCache &rights_id_cache, RegisteredHostContent ®istered_host_content);
|
||||
Result Activate(RightsIdCache &rights_id_cache, RegisteredHostContent ®istered_host_content);
|
||||
Result Inactivate(RegisteredHostContent ®istered_host_content);
|
||||
|
||||
Result Activate(ContentStorageRoot &root, RightsIdCache &rights_id_cache, RegisteredHostContent ®istered_host_content);
|
||||
|
||||
Result Activate(RightsIdCache &rights_id_cache, RegisteredHostContent ®istered_host_content, fs::ContentStorageId content_storage_id);
|
||||
|
||||
ContentStorageRoot *GetRoot(fs::ContentStorageId storage_id) {
|
||||
for (auto i = 0; i < m_num_roots; ++i) {
|
||||
if (auto &root = m_roots[i]; root.config.has_value() && root.config->content_storage_id == storage_id) {
|
||||
return std::addressof(root);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct ContentMetaDatabaseRoot {
|
||||
NON_COPYABLE(ContentMetaDatabaseRoot);
|
||||
NON_MOVEABLE(ContentMetaDatabaseRoot);
|
||||
|
||||
char mount_name[fs::MountNameLengthMax + 1];
|
||||
char path[128];
|
||||
StorageId storage_id;
|
||||
util::optional<ContentStorageConfig> storage_config;
|
||||
util::optional<SystemSaveDataInfo> save_data_info;
|
||||
util::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
|
||||
sf::SharedPointer<IContentMetaDatabase> content_meta_database;
|
||||
ContentMetaMemoryResource *memory_resource;
|
||||
u32 max_content_metas;
|
||||
|
||||
ContentMetaDatabaseRoot() : mount_name(), path(), storage_id(), storage_config(util::nullopt), save_data_info(util::nullopt), kvs(util::nullopt), content_meta_database(), memory_resource(), max_content_metas() { /* ... */ }
|
||||
};
|
||||
|
||||
struct IntegratedContentMetaDatabaseRoot {
|
||||
NON_COPYABLE(IntegratedContentMetaDatabaseRoot);
|
||||
NON_MOVEABLE(IntegratedContentMetaDatabaseRoot);
|
||||
|
||||
const IntegratedContentStorageConfig *m_config;
|
||||
ContentMetaDatabaseRoot *m_roots;
|
||||
int m_num_roots;
|
||||
sf::EmplacedRef<IContentMetaDatabase, IntegratedContentMetaDatabaseImpl> m_integrated_content_meta_database;
|
||||
|
||||
IntegratedContentMetaDatabaseRoot() : m_config(), m_roots(), m_num_roots(), m_integrated_content_meta_database() { /* ... */ }
|
||||
|
||||
Result Create();
|
||||
Result Verify();
|
||||
Result Open(sf::Out<sf::SharedPointer<IContentMetaDatabase>> out);
|
||||
Result Cleanup();
|
||||
Result Activate();
|
||||
Result Inactivate();
|
||||
|
||||
Result Activate(ContentMetaDatabaseRoot &root);
|
||||
|
||||
Result Activate(fs::ContentStorageId content_storage_id);
|
||||
|
||||
ContentMetaDatabaseRoot *GetRoot(fs::ContentStorageId storage_id) {
|
||||
for (auto i = 0; i < m_num_roots; ++i) {
|
||||
if (auto &root = m_roots[i]; root.storage_config.has_value() && root.storage_config->content_storage_id == storage_id) {
|
||||
return std::addressof(root);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
private:
|
||||
os::SdkRecursiveMutex m_mutex{};
|
||||
bool m_initialized{false};
|
||||
IntegratedContentStorageRoot m_integrated_content_storage_roots[MaxIntegratedContentStorageRoots]{};
|
||||
ContentStorageRoot m_content_storage_roots[MaxContentStorageRoots]{};
|
||||
IntegratedContentMetaDatabaseRoot m_integrated_content_meta_database_roots[MaxIntegratedContentMetaDatabaseRoots]{};
|
||||
ContentMetaDatabaseRoot m_content_meta_database_roots[MaxContentMetaDatabaseRoots]{};
|
||||
IntegratedContentStorageConfig m_integrated_configs[MaxIntegratedConfigs]{};
|
||||
ContentStorageConfig m_configs[MaxConfigs]{};
|
||||
u32 m_num_integrated_content_storage_entries{0};
|
||||
u32 m_num_content_storage_entries{0};
|
||||
u32 m_num_integrated_content_meta_entries{0};
|
||||
u32 m_num_content_meta_entries{0};
|
||||
u32 m_num_integrated_configs{0};
|
||||
u32 m_num_configs{0};
|
||||
RightsIdCache m_rights_id_cache{};
|
||||
RegisteredHostContent m_registered_host_content{};
|
||||
public:
|
||||
ContentManagerImpl() = default;
|
||||
~ContentManagerImpl();
|
||||
public:
|
||||
Result Initialize(const ContentManagerConfig &config);
|
||||
private:
|
||||
Result Initialize(const ContentManagerConfig &manager_config, const IntegratedContentStorageConfig *integrated_configs, size_t num_integrated_configs, const ContentStorageConfig *configs, size_t num_configs, const ncm::StorageId *activated_storages, size_t num_activated_storages);
|
||||
Result InitializeStorageBuiltInSystem(const ContentManagerConfig &manager_config);
|
||||
Result InitializeStorage(ncm::StorageId storage_id);
|
||||
|
||||
const ContentStorageConfig &GetContentStorageConfig(fs::ContentStorageId content_storage_id) {
|
||||
for (size_t i = 0; i < m_num_configs; ++i) {
|
||||
if (m_configs[i].content_storage_id == content_storage_id) {
|
||||
return m_configs[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: Nintendo accesses out of bounds memory here. Should we explicitly abort? This is guaranteed by data to never happen. */
|
||||
AMS_ASSUME(false);
|
||||
}
|
||||
private:
|
||||
/* Helpers. */
|
||||
Result GetIntegratedContentStorageConfig(IntegratedContentStorageConfig **out, fs::ContentStorageId content_storage_id);
|
||||
Result GetIntegratedContentStorageRoot(IntegratedContentStorageRoot **out, StorageId id);
|
||||
Result GetIntegratedContentMetaDatabaseRoot(IntegratedContentMetaDatabaseRoot **out, StorageId id);
|
||||
|
||||
Result InitializeContentStorageRoot(ContentStorageRoot *out, StorageId storage_id, util::optional<ContentStorageConfig> config);
|
||||
Result InitializeContentMetaDatabaseRoot(ContentMetaDatabaseRoot *out, StorageId storage_id, util::optional<ContentStorageConfig> storage_config);
|
||||
|
||||
Result InitializeIntegratedContentStorageRoot(IntegratedContentStorageRoot *out, const IntegratedContentStorageConfig *config, size_t root_idx, size_t root_count);
|
||||
Result InitializeIntegratedContentMetaDatabaseRoot(IntegratedContentMetaDatabaseRoot *out, const IntegratedContentStorageConfig *config, size_t root_idx, size_t root_count);
|
||||
|
||||
Result BuildContentMetaDatabase(StorageId storage_id);
|
||||
Result BuildContentMetaDatabaseImpl(StorageId storage_id);
|
||||
Result ImportContentMetaDatabase(StorageId storage_id, bool from_signed_partition);
|
||||
Result ImportContentMetaDatabaseImpl(ContentMetaDatabaseRoot *root, const char *import_mount_name);
|
||||
private:
|
||||
/* Helpers for unofficial functionality. */
|
||||
bool IsNeedRebuildSystemContentMetaDatabase();
|
||||
public:
|
||||
/* Actual commands. */
|
||||
Result CreateContentStorage(StorageId storage_id);
|
||||
Result CreateContentMetaDatabase(StorageId storage_id);
|
||||
Result VerifyContentStorage(StorageId storage_id);
|
||||
Result VerifyContentMetaDatabase(StorageId storage_id);
|
||||
Result OpenContentStorage(sf::Out<sf::SharedPointer<IContentStorage>> out, StorageId storage_id);
|
||||
Result OpenContentMetaDatabase(sf::Out<sf::SharedPointer<IContentMetaDatabase>> out, StorageId storage_id);
|
||||
Result CloseContentStorageForcibly(StorageId storage_id);
|
||||
Result CloseContentMetaDatabaseForcibly(StorageId storage_id);
|
||||
Result CleanupContentMetaDatabase(StorageId storage_id);
|
||||
Result ActivateContentStorage(StorageId storage_id);
|
||||
Result InactivateContentStorage(StorageId storage_id);
|
||||
Result ActivateContentMetaDatabase(StorageId storage_id);
|
||||
Result InactivateContentMetaDatabase(StorageId storage_id);
|
||||
Result InvalidateRightsIdCache();
|
||||
Result GetMemoryReport(sf::Out<MemoryReport> out);
|
||||
Result ActivateFsContentStorage(fs::ContentStorageId fs_content_storage_id);
|
||||
};
|
||||
static_assert(IsIContentManager<ContentManagerImpl>);
|
||||
|
||||
}
|
||||
@@ -1,399 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_meta_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_key.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_platform.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_info.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_info_data.hpp>
|
||||
#include <stratosphere/ncm/ncm_firmware_variation.hpp>
|
||||
#include <stratosphere/ncm/ncm_storage_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum ContentMetaAttribute : u8 {
|
||||
ContentMetaAttribute_None = (0 << 0),
|
||||
ContentMetaAttribute_IncludesExFatDriver = (1 << 0),
|
||||
ContentMetaAttribute_Rebootless = (1 << 1),
|
||||
ContentMetaAttribute_Compacted = (1 << 2),
|
||||
};
|
||||
|
||||
struct ContentMetaInfo {
|
||||
u64 id;
|
||||
u32 version;
|
||||
ContentMetaType type;
|
||||
u8 attributes;
|
||||
u8 padding[2];
|
||||
|
||||
static constexpr ContentMetaInfo Make(u64 id, u32 version, ContentMetaType type, u8 attributes) {
|
||||
return {
|
||||
.id = id,
|
||||
.version = version,
|
||||
.type = type,
|
||||
.attributes = attributes,
|
||||
};
|
||||
}
|
||||
|
||||
constexpr ContentMetaKey ToKey() const {
|
||||
return ContentMetaKey::Make(this->id, this->version, this->type);
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(ContentMetaInfo) == 0x10);
|
||||
|
||||
struct ContentMetaHeader {
|
||||
u16 extended_header_size;
|
||||
u16 content_count;
|
||||
u16 content_meta_count;
|
||||
u8 attributes;
|
||||
ContentMetaPlatform platform;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ContentMetaHeader) == 0x8);
|
||||
|
||||
struct PackagedContentMetaHeader {
|
||||
u64 id;
|
||||
u32 version;
|
||||
ContentMetaType type;
|
||||
ContentMetaPlatform platform;
|
||||
u16 extended_header_size;
|
||||
u16 content_count;
|
||||
u16 content_meta_count;
|
||||
u8 attributes;
|
||||
u8 storage_id;
|
||||
ContentInstallType install_type;
|
||||
bool committed;
|
||||
u32 required_download_system_version;
|
||||
u8 reserved_1C[4];
|
||||
};
|
||||
static_assert(sizeof(PackagedContentMetaHeader) == 0x20);
|
||||
static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_1C) == 0x1C);
|
||||
|
||||
using InstallContentMetaHeader = PackagedContentMetaHeader;
|
||||
|
||||
struct ApplicationMetaExtendedHeader {
|
||||
PatchId patch_id;
|
||||
u32 required_system_version;
|
||||
u32 required_application_version;
|
||||
};
|
||||
|
||||
struct PatchMetaExtendedHeader {
|
||||
ApplicationId application_id;
|
||||
u32 required_system_version;
|
||||
u32 extended_data_size;
|
||||
u8 reserved[0x8];
|
||||
};
|
||||
|
||||
struct AddOnContentMetaExtendedHeader {
|
||||
ApplicationId application_id;
|
||||
u32 required_application_version;
|
||||
u8 content_accessibilities;
|
||||
u8 padding[3];
|
||||
DataPatchId data_patch_id;
|
||||
};
|
||||
|
||||
struct LegacyAddOnContentMetaExtendedHeader {
|
||||
ApplicationId application_id;
|
||||
u32 required_application_version;
|
||||
u32 padding;
|
||||
};
|
||||
|
||||
struct DeltaMetaExtendedHeader {
|
||||
ApplicationId application_id;
|
||||
u32 extended_data_size;
|
||||
u32 padding;
|
||||
};
|
||||
|
||||
struct SystemUpdateMetaExtendedHeader {
|
||||
u32 extended_data_size;
|
||||
};
|
||||
|
||||
template<typename ContentMetaHeaderType, typename ContentInfoType>
|
||||
class ContentMetaAccessor {
|
||||
public:
|
||||
using HeaderType = ContentMetaHeaderType;
|
||||
using InfoType = ContentInfoType;
|
||||
private:
|
||||
void *m_data;
|
||||
const size_t m_size;
|
||||
bool m_is_header_valid;
|
||||
private:
|
||||
static size_t GetExtendedHeaderSize(ContentMetaType type) {
|
||||
switch (type) {
|
||||
case ContentMetaType::Application: return sizeof(ApplicationMetaExtendedHeader);
|
||||
case ContentMetaType::Patch: return sizeof(PatchMetaExtendedHeader);
|
||||
case ContentMetaType::AddOnContent: return sizeof(AddOnContentMetaExtendedHeader);
|
||||
case ContentMetaType::Delta: return sizeof(DeltaMetaExtendedHeader);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
constexpr ContentMetaAccessor(const void *d, size_t sz) : m_data(const_cast<void *>(d)), m_size(sz), m_is_header_valid(true) { /* ... */ }
|
||||
constexpr ContentMetaAccessor(void *d, size_t sz) : m_data(d), m_size(sz), m_is_header_valid(false) { /* ... */ }
|
||||
|
||||
template<class NewHeaderType, class NewInfoType>
|
||||
static constexpr size_t CalculateSizeImpl(size_t ext_header_size, size_t content_count, size_t content_meta_count, size_t extended_data_size, bool has_digest) {
|
||||
return sizeof(NewHeaderType) + ext_header_size + content_count * sizeof(NewInfoType) + content_meta_count * sizeof(ContentMetaInfo) + extended_data_size + (has_digest ? sizeof(Digest) : 0);
|
||||
}
|
||||
|
||||
static constexpr size_t CalculateSize(ContentMetaType type, size_t content_count, size_t content_meta_count, size_t extended_data_size, bool has_digest = false) {
|
||||
return CalculateSizeImpl<ContentMetaHeaderType, ContentInfoType>(GetExtendedHeaderSize(type), content_count, content_meta_count, extended_data_size, has_digest);
|
||||
}
|
||||
|
||||
uintptr_t GetExtendedHeaderAddress() const {
|
||||
return reinterpret_cast<uintptr_t>(m_data) + sizeof(HeaderType);
|
||||
}
|
||||
|
||||
uintptr_t GetContentInfoStartAddress() const {
|
||||
return this->GetExtendedHeaderAddress() + this->GetExtendedHeaderSize();
|
||||
}
|
||||
|
||||
uintptr_t GetContentInfoAddress(size_t i) const {
|
||||
return this->GetContentInfoStartAddress() + i * sizeof(InfoType);
|
||||
}
|
||||
|
||||
uintptr_t GetContentMetaInfoStartAddress() const {
|
||||
return this->GetContentInfoAddress(this->GetContentCount());
|
||||
}
|
||||
|
||||
uintptr_t GetContentMetaInfoAddress(size_t i) const {
|
||||
return this->GetContentMetaInfoStartAddress() + i * sizeof(ContentMetaInfo);
|
||||
}
|
||||
|
||||
uintptr_t GetExtendedDataAddress() const {
|
||||
return this->GetContentMetaInfoAddress(this->GetContentMetaCount());
|
||||
}
|
||||
|
||||
uintptr_t GetDigestAddress() const {
|
||||
return this->GetExtendedDataAddress() + this->GetExtendedDataSize();
|
||||
}
|
||||
|
||||
InfoType *GetWritableContentInfo(size_t i) const {
|
||||
AMS_ABORT_UNLESS(i < this->GetContentCount());
|
||||
|
||||
return reinterpret_cast<InfoType *>(this->GetContentInfoAddress(i));
|
||||
}
|
||||
|
||||
InfoType *GetWritableContentInfo(ContentType type) const {
|
||||
InfoType *found = nullptr;
|
||||
for (size_t i = 0; i < this->GetContentCount(); i++) {
|
||||
/* We want to find the info with the lowest id offset and the correct type. */
|
||||
InfoType *info = this->GetWritableContentInfo(i);
|
||||
if (info->GetType() == type && (found == nullptr || info->GetIdOffset() < found->GetIdOffset())) {
|
||||
found = info;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
InfoType *GetWritableContentInfo(ContentType type, u8 id_ofs) const {
|
||||
for (size_t i = 0; i < this->GetContentCount(); i++) {
|
||||
/* We want to find the info with the correct id offset and the correct type. */
|
||||
if (InfoType *info = this->GetWritableContentInfo(i); info->GetType() == type && info->GetIdOffset() == id_ofs) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
s64 CalculateContentRequiredSize() const {
|
||||
s64 required_size = 0;
|
||||
for (size_t i = 0; i < this->GetContentCount(); i++) {
|
||||
required_size += CalculateRequiredSize(this->GetContentInfo(i)->info.GetSize());
|
||||
}
|
||||
return required_size;
|
||||
}
|
||||
|
||||
void SetStorageId(StorageId storage_id) {
|
||||
this->GetWritableHeader()->storage_id = static_cast<u8>(storage_id);
|
||||
}
|
||||
|
||||
public:
|
||||
const void *GetData() const {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
size_t GetSize() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
HeaderType *GetWritableHeader() const {
|
||||
AMS_ABORT_UNLESS(m_is_header_valid);
|
||||
return reinterpret_cast<HeaderType *>(m_data);
|
||||
}
|
||||
|
||||
const HeaderType *GetHeader() const {
|
||||
AMS_ABORT_UNLESS(m_is_header_valid);
|
||||
return static_cast<const HeaderType *>(m_data);
|
||||
}
|
||||
|
||||
ContentMetaKey GetKey() const {
|
||||
auto header = this->GetHeader();
|
||||
return ContentMetaKey::Make(header->id, header->version, header->type, header->install_type);
|
||||
}
|
||||
|
||||
size_t GetExtendedHeaderSize() const {
|
||||
return this->GetHeader()->extended_header_size;
|
||||
}
|
||||
|
||||
template<typename ExtendedHeaderType>
|
||||
const ExtendedHeaderType *GetExtendedHeader() const {
|
||||
return reinterpret_cast<const ExtendedHeaderType *>(this->GetExtendedHeaderAddress());
|
||||
}
|
||||
|
||||
size_t GetContentCount() const {
|
||||
return this->GetHeader()->content_count;
|
||||
}
|
||||
|
||||
const InfoType *GetContentInfo(size_t i) const {
|
||||
AMS_ABORT_UNLESS(i < this->GetContentCount());
|
||||
|
||||
return this->GetWritableContentInfo(i);
|
||||
}
|
||||
|
||||
const InfoType *GetContentInfo(ContentType type) const {
|
||||
return this->GetWritableContentInfo(type);
|
||||
}
|
||||
|
||||
const InfoType *GetContentInfo(ContentType type, u8 id_ofs) const {
|
||||
return this->GetWritableContentInfo(type, id_ofs);
|
||||
}
|
||||
|
||||
size_t GetContentMetaCount() const {
|
||||
return this->GetHeader()->content_meta_count;
|
||||
}
|
||||
|
||||
const ContentMetaInfo *GetContentMetaInfo(size_t i) const {
|
||||
AMS_ABORT_UNLESS(i < this->GetContentMetaCount());
|
||||
|
||||
return reinterpret_cast<const ContentMetaInfo *>(this->GetContentMetaInfoAddress(i));
|
||||
}
|
||||
|
||||
size_t GetExtendedDataSize() const {
|
||||
switch (this->GetHeader()->type) {
|
||||
case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->extended_data_size;
|
||||
case ContentMetaType::Delta: return this->GetExtendedHeader<DeltaMetaExtendedHeader>()->extended_data_size;
|
||||
case ContentMetaType::SystemUpdate: return this->GetExtendedHeaderSize() == 0 ? 0 : this->GetExtendedHeader<SystemUpdateMetaExtendedHeader>()->extended_data_size;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const void *GetExtendedData() const {
|
||||
return reinterpret_cast<const void *>(this->GetExtendedDataAddress());
|
||||
}
|
||||
|
||||
const Digest *GetDigest() const {
|
||||
return reinterpret_cast<Digest *>(this->GetDigestAddress());
|
||||
}
|
||||
|
||||
bool HasContent(const ContentId &id) const {
|
||||
for (size_t i = 0; i < this->GetContentCount(); i++) {
|
||||
if (id == this->GetContentInfo(i)->GetId()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
StorageId GetStorageId() const {
|
||||
return static_cast<StorageId>(this->GetHeader()->storage_id);
|
||||
}
|
||||
|
||||
util::optional<ApplicationId> GetApplicationId(const ContentMetaKey &key) const {
|
||||
switch (key.type) {
|
||||
case ContentMetaType::Application: return ApplicationId{ key.id };
|
||||
case ContentMetaType::Patch: return this->GetExtendedHeader<PatchMetaExtendedHeader>()->application_id;
|
||||
case ContentMetaType::AddOnContent: return this->GetExtendedHeader<AddOnContentMetaExtendedHeader>()->application_id;
|
||||
case ContentMetaType::Delta: return this->GetExtendedHeader<DeltaMetaExtendedHeader>()->application_id;
|
||||
default: return util::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
util::optional<ApplicationId> GetApplicationId() const {
|
||||
return this->GetApplicationId(this->GetKey());
|
||||
}
|
||||
};
|
||||
|
||||
class ContentMetaReader : public ContentMetaAccessor<ContentMetaHeader, ContentInfo> {
|
||||
public:
|
||||
constexpr ContentMetaReader(const void *data, size_t size) : ContentMetaAccessor(data, size) { /* ... */ }
|
||||
|
||||
using ContentMetaAccessor::CalculateSize;
|
||||
};
|
||||
|
||||
class PackagedContentMetaReader : public ContentMetaAccessor<PackagedContentMetaHeader, PackagedContentInfo> {
|
||||
public:
|
||||
constexpr PackagedContentMetaReader(const void *data, size_t size) : ContentMetaAccessor(data, size) { /* ... */ }
|
||||
|
||||
size_t CalculateConvertInstallContentMetaSize() const;
|
||||
void ConvertToInstallContentMeta(void *dst, size_t size, const InstallContentInfo &meta);
|
||||
|
||||
size_t CalculateConvertContentMetaSize() const;
|
||||
void ConvertToContentMeta(void *dst, size_t size, const ContentInfo &meta);
|
||||
|
||||
size_t CalculateConvertFragmentOnlyInstallContentMetaSize(s32 fragment_count) const {
|
||||
return CalculateSizeImpl<InstallContentMetaHeader, InstallContentInfo>(this->GetExtendedHeaderSize(), fragment_count + 1, 0, 0, false);
|
||||
}
|
||||
|
||||
Result CalculateConvertFragmentOnlyInstallContentMetaSize(size_t *out_size, u32 source_version) const;
|
||||
Result ConvertToFragmentOnlyInstallContentMeta(void *dst, size_t size, const InstallContentInfo &content_info, u32 source_version);
|
||||
|
||||
size_t CountDeltaFragments() const;
|
||||
|
||||
static constexpr size_t CalculateSize(ContentMetaType type, size_t content_count, size_t content_meta_count, size_t extended_data_size) {
|
||||
return ContentMetaAccessor::CalculateSize(type, content_count, content_meta_count, extended_data_size, true);
|
||||
}
|
||||
|
||||
size_t GetExtendedDataOffset() const {
|
||||
return this->GetExtendedDataAddress() - reinterpret_cast<uintptr_t>(this->GetData());
|
||||
}
|
||||
};
|
||||
|
||||
class InstallContentMetaReader : public ContentMetaAccessor<InstallContentMetaHeader, InstallContentInfo> {
|
||||
public:
|
||||
constexpr InstallContentMetaReader(const void *data, size_t size) : ContentMetaAccessor(data, size) { /* ... */ }
|
||||
|
||||
using ContentMetaAccessor::CalculateSize;
|
||||
using ContentMetaAccessor::CalculateContentRequiredSize;
|
||||
using ContentMetaAccessor::GetStorageId;
|
||||
|
||||
size_t CalculateConvertSize() const;
|
||||
|
||||
void ConvertToContentMeta(void *dst, size_t size) const;
|
||||
};
|
||||
|
||||
class InstallContentMetaWriter : public ContentMetaAccessor<InstallContentMetaHeader, InstallContentInfo> {
|
||||
public:
|
||||
InstallContentMetaWriter(const void *data, size_t size) : ContentMetaAccessor(data, size) { /* ... */ }
|
||||
|
||||
using ContentMetaAccessor::CalculateSize;
|
||||
using ContentMetaAccessor::CalculateContentRequiredSize;
|
||||
using ContentMetaAccessor::GetWritableContentInfo;
|
||||
using ContentMetaAccessor::SetStorageId;
|
||||
};
|
||||
|
||||
class PatchMetaExtendedDataAccessor;
|
||||
struct PatchDeltaHeader;
|
||||
class AutoBuffer;
|
||||
|
||||
class MetaConverter {
|
||||
public:
|
||||
static Result CountContentExceptForMeta(s32 *out, PatchMetaExtendedDataAccessor *accessor, const PatchDeltaHeader &header, s32 delta_index);
|
||||
static Result FindDeltaIndex(s32 *out, PatchMetaExtendedDataAccessor *accessor, u32 source_version, u32 destination_version);
|
||||
static Result GetFragmentOnlyInstallContentMeta(AutoBuffer *out, const InstallContentInfo &content_info, const PackagedContentMetaReader &reader, PatchMetaExtendedDataAccessor *accessor, u32 source_version);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_i_content_meta_database.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class ContentMetaDatabase {
|
||||
NON_COPYABLE(ContentMetaDatabase);
|
||||
public:
|
||||
struct ListCount {
|
||||
s32 written;
|
||||
s32 total;
|
||||
};
|
||||
private:
|
||||
sf::SharedPointer<IContentMetaDatabase> m_interface;
|
||||
public:
|
||||
ContentMetaDatabase() : m_interface(nullptr) { /* ... */ }
|
||||
explicit ContentMetaDatabase(sf::SharedPointer<IContentMetaDatabase> intf) : m_interface(intf) { /* ... */ }
|
||||
|
||||
ContentMetaDatabase(ContentMetaDatabase &&rhs) {
|
||||
m_interface = std::move(rhs.m_interface);
|
||||
}
|
||||
|
||||
ContentMetaDatabase &operator=(ContentMetaDatabase &&rhs) {
|
||||
ContentMetaDatabase(std::move(rhs)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(ContentMetaDatabase &rhs) {
|
||||
std::swap(m_interface, rhs.m_interface);
|
||||
}
|
||||
public:
|
||||
Result Set(const ContentMetaKey &key, const void *buf, size_t size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Set(key, sf::InBuffer(buf, size)));
|
||||
}
|
||||
|
||||
Result Get(size_t *out_size, void *dst, size_t dst_size, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
u64 size;
|
||||
R_TRY(m_interface->Get(std::addressof(size), key, sf::OutBuffer(dst, dst_size)));
|
||||
|
||||
*out_size = size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
#define AMS_NCM_DEFINE_GETTERS(Kind, IdType) \
|
||||
Result Get##Kind(ContentId *out, IdType##Id id, u32 version) { \
|
||||
R_RETURN(m_interface->GetContentIdByType(out, ContentMetaKey::MakeUnknownType(id.value, version), ContentType::Kind)); \
|
||||
} \
|
||||
\
|
||||
Result Get##Kind(ContentInfo *out, IdType##Id id, u32 version) { \
|
||||
R_RETURN(m_interface->GetContentInfoByType(out, ContentMetaKey::MakeUnknownType(id.value, version), ContentType::Kind)); \
|
||||
} \
|
||||
\
|
||||
Result GetLatest##Kind(ContentId *out, IdType##Id id) { \
|
||||
ContentMetaKey latest_key; \
|
||||
R_TRY(m_interface->GetLatestContentMetaKey(std::addressof(latest_key), id.value)); \
|
||||
R_RETURN(m_interface->GetContentIdByType(out, latest_key, ContentType::Kind)); \
|
||||
} \
|
||||
\
|
||||
Result GetLatest##Kind(ContentInfo *out, IdType##Id id) { \
|
||||
ContentMetaKey latest_key; \
|
||||
R_TRY(m_interface->GetLatestContentMetaKey(std::addressof(latest_key), id.value)); \
|
||||
R_RETURN(m_interface->GetContentInfoByType(out, latest_key, ContentType::Kind)); \
|
||||
}
|
||||
|
||||
AMS_NCM_DEFINE_GETTERS(Program, Program)
|
||||
AMS_NCM_DEFINE_GETTERS(Data, Data)
|
||||
AMS_NCM_DEFINE_GETTERS(Control, Application)
|
||||
AMS_NCM_DEFINE_GETTERS(HtmlDocument, Application)
|
||||
AMS_NCM_DEFINE_GETTERS(LegalInformation, Application)
|
||||
|
||||
#undef AMS_NCM_DEFINE_GETTERS
|
||||
|
||||
Result Remove(const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Remove(key));
|
||||
}
|
||||
|
||||
Result Remove(SystemProgramId id, u32 version) {
|
||||
R_RETURN(this->Remove(ContentMetaKey::Make(id, version)));
|
||||
}
|
||||
|
||||
Result Remove(SystemDataId id, u32 version) {
|
||||
R_RETURN(this->Remove(ContentMetaKey::Make(id, version)));
|
||||
}
|
||||
|
||||
Result Remove(ApplicationId id, u32 version) {
|
||||
R_RETURN(this->Remove(ContentMetaKey::Make(id, version)));
|
||||
}
|
||||
|
||||
Result GetContentIdByType(ContentId *out_content_id, const ContentMetaKey &key, ContentType type) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentIdByType(out_content_id, key, type));
|
||||
}
|
||||
|
||||
Result GetContentIdByTypeAndIdOffset(ContentId *out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentIdByTypeAndIdOffset(out_content_id, key, type, id_offset));
|
||||
}
|
||||
|
||||
ListCount ListApplication(ApplicationContentMetaKey *dst, size_t dst_size) {
|
||||
ListCount lc = {};
|
||||
R_ABORT_UNLESS(m_interface->ListApplication(std::addressof(lc.total), std::addressof(lc.written), sf::OutArray<ApplicationContentMetaKey>(dst, dst_size), ContentMetaType::Unknown));
|
||||
return lc;
|
||||
}
|
||||
|
||||
ListCount ListContentMeta(ContentMetaKey *dst, size_t dst_size, ContentMetaType type = ContentMetaType::Unknown, ApplicationId app_id = InvalidApplicationId, u64 min = std::numeric_limits<u64>::min(), u64 max = std::numeric_limits<u64>::max(), ContentInstallType install_type = ContentInstallType::Full) {
|
||||
ListCount lc = {};
|
||||
R_ABORT_UNLESS(m_interface->List(std::addressof(lc.total), std::addressof(lc.written), sf::OutArray<ContentMetaKey>(dst, dst_size), type, app_id, min, max, install_type));
|
||||
return lc;
|
||||
}
|
||||
|
||||
Result GetLatest(ContentMetaKey *out_key, u64 id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetLatestContentMetaKey(out_key, id));
|
||||
}
|
||||
|
||||
Result ListContentInfo(s32 *out_count, ContentInfo *dst, size_t dst_size, const ContentMetaKey &key, s32 offset) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->ListContentInfo(out_count, sf::OutArray<ContentInfo>(dst, dst_size), key, offset));
|
||||
}
|
||||
|
||||
Result ListContentMetaInfo(s32 *out_count, ContentMetaInfo *dst, size_t dst_size, const ContentMetaKey &key, s32 offset) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->ListContentMetaInfo(out_count, sf::OutArray<ContentMetaInfo>(dst, dst_size), key, offset));
|
||||
}
|
||||
|
||||
Result Has(bool *out, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Has(out, key));
|
||||
}
|
||||
|
||||
Result HasAll(bool *out, const ContentMetaKey *keys, size_t num_keys) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->HasAll(out, sf::InArray<ContentMetaKey>(keys, num_keys)));
|
||||
}
|
||||
|
||||
Result HasContent(bool *out, const ContentMetaKey &key, const ContentId &content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->HasContent(out, key, content_id));
|
||||
}
|
||||
|
||||
Result GetSize(size_t *out_size, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
u64 size;
|
||||
R_TRY(m_interface->GetSize(std::addressof(size), key));
|
||||
|
||||
*out_size = size;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetRequiredSystemVersion(u32 *out_version, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetRequiredSystemVersion(out_version, key));
|
||||
}
|
||||
|
||||
Result GetPatchId(PatchId *out_patch_id, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
static_assert(sizeof(*out_patch_id) == sizeof(u64));
|
||||
R_RETURN(m_interface->GetPatchContentMetaId(reinterpret_cast<u64 *>(out_patch_id), key));
|
||||
}
|
||||
|
||||
Result GetDataPatchId(DataPatchId *out_patch_id, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
static_assert(sizeof(*out_patch_id) == sizeof(u64));
|
||||
R_RETURN(m_interface->GetPatchContentMetaId(reinterpret_cast<u64 *>(out_patch_id), key));
|
||||
}
|
||||
|
||||
Result DisableForcibly() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->DisableForcibly());
|
||||
}
|
||||
|
||||
Result LookupOrphanContent(bool *out_orphaned, ContentId *content_list, size_t count) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->LookupOrphanContent(sf::OutArray<bool>(out_orphaned, count), sf::InArray<ContentId>(content_list, count)));
|
||||
}
|
||||
|
||||
Result Commit() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Commit());
|
||||
}
|
||||
|
||||
Result GetAttributes(u8 *out_attributes, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetAttributes(out_attributes, key));
|
||||
}
|
||||
|
||||
Result GetRequiredApplicationVersion(u32 *out_version, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetRequiredApplicationVersion(out_version, key));
|
||||
}
|
||||
|
||||
Result GetContentAccessibilities(u8 *out_accessibilities, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentAccessibilities(out_accessibilities, key));
|
||||
}
|
||||
|
||||
Result GetContentInfoByType(ContentInfo *out_content_info, const ContentMetaKey &key, ContentType type) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentInfoByType(out_content_info, key, type));
|
||||
}
|
||||
|
||||
Result GetContentInfoByTypeAndIdOffset(ContentInfo *out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentInfoByTypeAndIdOffset(out_content_info, key, type, id_offset));
|
||||
}
|
||||
|
||||
Result GetPlatform(ContentMetaPlatform *out, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetPlatform(out, key));
|
||||
}
|
||||
|
||||
Result HasAttributes(u8 *out, u8 attr_mask) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->HasAttributes(out, attr_mask));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,857 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_info.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta.hpp>
|
||||
#include <stratosphere/ncm/ncm_firmware_variation.hpp>
|
||||
#include <stratosphere/ncm/ncm_mapped_memory.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class UpdateType : u8 {
|
||||
ApplyAsDelta = 0,
|
||||
Overwrite = 1,
|
||||
Create = 2,
|
||||
};
|
||||
|
||||
struct FragmentIndicator {
|
||||
u16 content_info_index;
|
||||
u16 fragment_index;
|
||||
};
|
||||
|
||||
struct FragmentSet {
|
||||
ContentId source_content_id;
|
||||
ContentId destination_content_id;
|
||||
u32 source_size_low;
|
||||
u16 source_size_high;
|
||||
u16 destination_size_high;
|
||||
u32 destination_size_low;
|
||||
u16 fragment_count;
|
||||
ContentType target_content_type;
|
||||
UpdateType update_type;
|
||||
u8 reserved[4];
|
||||
|
||||
constexpr s64 GetSourceSize() const {
|
||||
return (static_cast<s64>(this->source_size_high) << 32) + this->source_size_low;
|
||||
}
|
||||
|
||||
constexpr s64 GetDestinationSize() const {
|
||||
return (static_cast<s64>(this->destination_size_high) << 32) + this->destination_size_low;
|
||||
}
|
||||
|
||||
constexpr void SetSourceSize(s64 size) {
|
||||
this->source_size_low = size & 0xFFFFFFFFll;
|
||||
this->source_size_high = static_cast<u16>(size >> 32);
|
||||
}
|
||||
|
||||
constexpr void SetDestinationSize(s64 size) {
|
||||
this->destination_size_low = size & 0xFFFFFFFFll;
|
||||
this->destination_size_high = static_cast<u16>(size >> 32);
|
||||
}
|
||||
};
|
||||
|
||||
struct SystemUpdateMetaExtendedDataHeader {
|
||||
u32 version;
|
||||
u32 firmware_variation_count;
|
||||
};
|
||||
|
||||
struct DeltaMetaExtendedDataHeader {
|
||||
PatchId source_id;
|
||||
PatchId destination_id;
|
||||
u32 source_version;
|
||||
u32 destination_version;
|
||||
u16 fragment_set_count;
|
||||
u8 reserved[6];
|
||||
};
|
||||
|
||||
struct PatchMetaExtendedDataHeader {
|
||||
u32 history_count;
|
||||
u32 delta_history_count;
|
||||
u32 delta_count;
|
||||
u32 fragment_set_count;
|
||||
u32 history_content_total_count;
|
||||
u32 delta_content_total_count;
|
||||
u8 reserved[4];
|
||||
};
|
||||
|
||||
struct PatchHistoryHeader {
|
||||
ContentMetaKey key;
|
||||
Digest digest;
|
||||
u16 content_count;
|
||||
u8 reserved[2];
|
||||
};
|
||||
|
||||
struct PatchDeltaHistory {
|
||||
PatchId source_id;
|
||||
PatchId destination_id;
|
||||
u32 source_version;
|
||||
u32 destination_version;
|
||||
u64 download_size;
|
||||
u8 reserved[4];
|
||||
};
|
||||
|
||||
struct PatchDeltaHeader {
|
||||
DeltaMetaExtendedDataHeader delta;
|
||||
u16 content_count;
|
||||
u8 reserved[4];
|
||||
};
|
||||
|
||||
template<typename MemberTypePointer, typename DataTypePointer>
|
||||
class PatchMetaExtendedDataReaderWriterBase {
|
||||
private:
|
||||
MemberTypePointer m_data;
|
||||
const size_t m_size;
|
||||
public:
|
||||
PatchMetaExtendedDataReaderWriterBase(MemberTypePointer d, size_t sz) : m_data(d), m_size(sz) { /* ... */ }
|
||||
protected:
|
||||
s32 CountFragmentSet(s32 delta_index) const {
|
||||
auto delta_header = this->GetPatchDeltaHeader(0);
|
||||
s32 count = 0;
|
||||
for (s32 i = 0; i < delta_index; i++) {
|
||||
count += delta_header[i].delta.fragment_set_count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
s32 CountHistoryContent(s32 history_index) const {
|
||||
auto history_header = this->GetPatchHistoryHeader(0);
|
||||
s32 count = 0;
|
||||
for (s32 i = 0; i < history_index; i++) {
|
||||
count += history_header[i].content_count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
s32 CountDeltaContent(s32 delta_index) const {
|
||||
auto delta_header = this->GetPatchDeltaHeader(0);
|
||||
s32 count = 0;
|
||||
for (s32 i = 0; i < delta_index; i++) {
|
||||
count += delta_header[i].content_count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
s32 CountFragment(s32 index) const {
|
||||
auto fragment_set = this->GetFragmentSet(0, 0);
|
||||
s32 count = 0;
|
||||
for (s32 i = 0; i < index; i++) {
|
||||
count += fragment_set[i].fragment_count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
DataTypePointer GetHeaderAddress() const {
|
||||
return reinterpret_cast<DataTypePointer>(m_data);
|
||||
}
|
||||
|
||||
DataTypePointer GetPatchHistoryHeaderAddress(s32 index) const {
|
||||
auto header = this->GetHeader();
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(index) < header->history_count);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * index;
|
||||
}
|
||||
|
||||
DataTypePointer GetPatchDeltaHistoryAddress(s32 index) const {
|
||||
auto header = this->GetHeader();
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(index) < header->delta_history_count);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * header->history_count
|
||||
+ sizeof(PatchDeltaHistory) * index;
|
||||
}
|
||||
|
||||
DataTypePointer GetPatchDeltaHeaderAddress(s32 index) const {
|
||||
auto header = this->GetHeader();
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(index) < header->delta_count);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * header->history_count
|
||||
+ sizeof(PatchDeltaHistory) * header->delta_history_count
|
||||
+ sizeof(PatchDeltaHeader) * index;
|
||||
}
|
||||
|
||||
DataTypePointer GetFragmentSetAddress(s32 delta_index, s32 fragment_set_index) const {
|
||||
auto header = this->GetHeader();
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(delta_index) < header->delta_count);
|
||||
|
||||
auto delta_header = this->GetPatchDeltaHeader(delta_index);
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(fragment_set_index) < delta_header->delta.fragment_set_count);
|
||||
|
||||
auto previous_fragment_set_count = this->CountFragmentSet(delta_index);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * header->history_count
|
||||
+ sizeof(PatchDeltaHistory) * header->delta_history_count
|
||||
+ sizeof(PatchDeltaHeader) * header->delta_count
|
||||
+ sizeof(FragmentSet) * (previous_fragment_set_count + fragment_set_index);
|
||||
}
|
||||
|
||||
DataTypePointer GetPatchHistoryContentInfoAddress(s32 history_index, s32 content_index) const {
|
||||
auto header = this->GetHeader();
|
||||
auto history_header = this->GetPatchHistoryHeader(history_index);
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(content_index) < history_header->content_count);
|
||||
|
||||
auto prev_history_count = this->CountHistoryContent(history_index);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * header->history_count
|
||||
+ sizeof(PatchDeltaHistory) * header->delta_history_count
|
||||
+ sizeof(PatchDeltaHeader) * header->delta_count
|
||||
+ sizeof(FragmentSet) * header->fragment_set_count
|
||||
+ sizeof(ContentInfo) * (prev_history_count + content_index);
|
||||
}
|
||||
|
||||
DataTypePointer GetPatchDeltaPackagedContentInfoAddress(s32 delta_index, s32 content_index) const {
|
||||
auto header = this->GetHeader();
|
||||
auto delta_header = this->GetPatchDeltaHeader(delta_index);
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(content_index) < delta_header->content_count);
|
||||
|
||||
auto content_count = this->CountDeltaContent(delta_index);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * header->history_count
|
||||
+ sizeof(PatchDeltaHistory) * header->delta_history_count
|
||||
+ sizeof(PatchDeltaHeader) * header->delta_count
|
||||
+ sizeof(FragmentSet) * header->fragment_set_count
|
||||
+ sizeof(ContentInfo) * header->history_content_total_count
|
||||
+ sizeof(PackagedContentInfo) * (content_count + content_index);
|
||||
}
|
||||
|
||||
DataTypePointer GetFragmentIndicatorAddress(s32 delta_index, s32 fragment_set_index, s32 index) const {
|
||||
auto header = this->GetHeader();
|
||||
auto fragment_set = this->GetFragmentSet(delta_index, fragment_set_index);
|
||||
AMS_ABORT_UNLESS(static_cast<u16>(index) < fragment_set->fragment_count);
|
||||
|
||||
auto fragment_set_count = this->CountFragmentSet(delta_index);
|
||||
auto fragment_count = this->CountFragment(fragment_set_count + fragment_set_index);
|
||||
|
||||
return this->GetHeaderAddress()
|
||||
+ sizeof(PatchMetaExtendedDataHeader)
|
||||
+ sizeof(PatchHistoryHeader) * header->history_count
|
||||
+ sizeof(PatchDeltaHistory) * header->delta_history_count
|
||||
+ sizeof(PatchDeltaHeader) * header->delta_count
|
||||
+ sizeof(FragmentSet) * header->fragment_set_count
|
||||
+ sizeof(ContentInfo) * header->history_content_total_count
|
||||
+ sizeof(PackagedContentInfo) * header->delta_content_total_count
|
||||
+ sizeof(FragmentIndicator) * (fragment_count + index);
|
||||
}
|
||||
public:
|
||||
const PatchMetaExtendedDataHeader *GetHeader() const {
|
||||
return reinterpret_cast<const PatchMetaExtendedDataHeader *>(this->GetHeaderAddress());
|
||||
}
|
||||
|
||||
const PatchHistoryHeader *GetPatchHistoryHeader(s32 index) const {
|
||||
return reinterpret_cast<const PatchHistoryHeader *>(this->GetPatchHistoryHeaderAddress(index));
|
||||
}
|
||||
|
||||
const PatchDeltaHistory *GetPatchDeltaHistory(s32 index) const {
|
||||
return reinterpret_cast<const PatchDeltaHistory *>(this->GetPatchDeltaHistoryAddress(index));
|
||||
}
|
||||
|
||||
const ContentInfo *GetPatchHistoryContentInfo(s32 history_index, s32 content_index) const {
|
||||
return reinterpret_cast<const ContentInfo *>(this->GetPatchHistoryContentInfoAddress(history_index, content_index));
|
||||
}
|
||||
|
||||
const PatchDeltaHeader *GetPatchDeltaHeader(s32 index) const {
|
||||
return reinterpret_cast<const PatchDeltaHeader *>(this->GetPatchDeltaHeaderAddress(index));
|
||||
}
|
||||
|
||||
const PackagedContentInfo *GetPatchDeltaPackagedContentInfo(s32 delta_index, s32 content_index) const {
|
||||
return reinterpret_cast<const PackagedContentInfo *>(this->GetPatchDeltaPackagedContentInfoAddress(delta_index, content_index));
|
||||
}
|
||||
|
||||
const FragmentSet *GetFragmentSet(s32 delta_index, s32 fragment_set_index) const {
|
||||
return reinterpret_cast<const FragmentSet *>(this->GetFragmentSetAddress(delta_index, fragment_set_index));
|
||||
}
|
||||
|
||||
const FragmentIndicator *GetFragmentIndicator(s32 delta_index, s32 fragment_set_index, s32 index) const {
|
||||
return reinterpret_cast<const FragmentIndicator *>(this->GetFragmentIndicatorAddress(delta_index, fragment_set_index, index));
|
||||
}
|
||||
|
||||
const FragmentIndicator *FindFragmentIndicator(s32 delta_index, s32 fragment_set_index, s32 fragment_index) const {
|
||||
auto fragment_set = this->GetFragmentSet(delta_index, fragment_set_index);
|
||||
auto fragment = this->GetFragmentIndicator(delta_index, fragment_set_index, 0);
|
||||
for (s32 i = 0; i < fragment_set->fragment_count; i++) {
|
||||
if (fragment[i].fragment_index == fragment_index) {
|
||||
return std::addressof(fragment[i]);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class PatchMetaExtendedDataReader : public PatchMetaExtendedDataReaderWriterBase<const void *, const u8 *> {
|
||||
public:
|
||||
PatchMetaExtendedDataReader(const void *data, size_t size) : PatchMetaExtendedDataReaderWriterBase(data, size) { /* ... */ }
|
||||
};
|
||||
|
||||
class SystemUpdateMetaExtendedDataReaderWriterBase {
|
||||
private:
|
||||
void *m_data;
|
||||
const size_t m_size;
|
||||
bool m_is_header_valid;
|
||||
protected:
|
||||
constexpr SystemUpdateMetaExtendedDataReaderWriterBase(const void *d, size_t sz) : m_data(const_cast<void *>(d)), m_size(sz), m_is_header_valid(true) { /* ... */ }
|
||||
constexpr SystemUpdateMetaExtendedDataReaderWriterBase(void *d, size_t sz) : m_data(d), m_size(sz), m_is_header_valid(false) { /* ... */ }
|
||||
|
||||
uintptr_t GetHeaderAddress() const {
|
||||
return reinterpret_cast<uintptr_t>(m_data);
|
||||
}
|
||||
|
||||
uintptr_t GetFirmwareVariationIdStartAddress() const {
|
||||
return this->GetHeaderAddress() + sizeof(SystemUpdateMetaExtendedDataHeader);
|
||||
}
|
||||
|
||||
uintptr_t GetFirmwareVariationIdAddress(size_t i) const {
|
||||
return this->GetFirmwareVariationIdStartAddress() + i * sizeof(FirmwareVariationId);
|
||||
}
|
||||
|
||||
uintptr_t GetFirmwareVariationInfoStartAddress() const {
|
||||
return this->GetFirmwareVariationIdAddress(this->GetFirmwareVariationCount());
|
||||
}
|
||||
|
||||
uintptr_t GetFirmwareVariationInfoAddress(size_t i) const {
|
||||
return this->GetFirmwareVariationInfoStartAddress() + i * sizeof(FirmwareVariationInfo);
|
||||
}
|
||||
|
||||
uintptr_t GetContentMetaInfoStartAddress() const {
|
||||
return this->GetFirmwareVariationInfoAddress(this->GetFirmwareVariationCount());
|
||||
}
|
||||
|
||||
uintptr_t GetContentMetaInfoAddress(size_t i) const {
|
||||
return this->GetContentMetaInfoStartAddress() + i * sizeof(ContentMetaInfo);
|
||||
}
|
||||
public:
|
||||
const SystemUpdateMetaExtendedDataHeader *GetHeader() const {
|
||||
AMS_ABORT_UNLESS(m_is_header_valid);
|
||||
return reinterpret_cast<const SystemUpdateMetaExtendedDataHeader *>(this->GetHeaderAddress());
|
||||
}
|
||||
|
||||
size_t GetFirmwareVariationCount() const {
|
||||
return this->GetHeader()->firmware_variation_count;
|
||||
}
|
||||
|
||||
const FirmwareVariationId *GetFirmwareVariationId(size_t i) const {
|
||||
AMS_ABORT_UNLESS(i < this->GetFirmwareVariationCount());
|
||||
|
||||
return reinterpret_cast<FirmwareVariationId *>(this->GetFirmwareVariationIdAddress(i));
|
||||
}
|
||||
|
||||
const FirmwareVariationInfo *GetFirmwareVariationInfo(size_t i) const {
|
||||
AMS_ABORT_UNLESS(i < this->GetFirmwareVariationCount());
|
||||
|
||||
return reinterpret_cast<FirmwareVariationInfo *>(this->GetFirmwareVariationInfoAddress(i));
|
||||
}
|
||||
|
||||
void GetContentMetaInfoList(Span<const ContentMetaInfo> *out_list, size_t i) const {
|
||||
size_t preceding_content_meta_count = 0;
|
||||
|
||||
/* Count the number of preceding content metas. */
|
||||
for (size_t j = 0; j < i; j++) {
|
||||
preceding_content_meta_count += this->GetFirmwareVariationInfo(j)->content_meta_count;
|
||||
}
|
||||
|
||||
/* Output the list. */
|
||||
*out_list = Span<const ContentMetaInfo>(reinterpret_cast<const ContentMetaInfo *>(this->GetContentMetaInfoAddress(preceding_content_meta_count)), this->GetFirmwareVariationInfo(i)->content_meta_count);
|
||||
}
|
||||
};
|
||||
|
||||
class SystemUpdateMetaExtendedDataReader : public SystemUpdateMetaExtendedDataReaderWriterBase {
|
||||
public:
|
||||
constexpr SystemUpdateMetaExtendedDataReader(const void *data, size_t size) : SystemUpdateMetaExtendedDataReaderWriterBase(data, size) { /* ... */ }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ReadableStructPin;
|
||||
|
||||
class AccessorBase {
|
||||
public:
|
||||
template<typename T>
|
||||
class PinBase {
|
||||
private:
|
||||
AccessorBase *m_accessor;
|
||||
u64 m_pin_id;
|
||||
T *m_data;
|
||||
size_t m_size;
|
||||
public:
|
||||
PinBase() : m_accessor(nullptr), m_data(nullptr), m_size(0) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
PinBase(const PinBase &) = delete;
|
||||
PinBase &operator=(const PinBase &) = delete;
|
||||
|
||||
PinBase(PinBase &&rhs) : m_accessor(rhs.m_accessor), m_pin_id(rhs.m_pin_id), m_data(rhs.m_data), m_size(rhs.m_size) {
|
||||
rhs.m_accessor = nullptr;
|
||||
}
|
||||
|
||||
PinBase &operator=(PinBase &&rhs) {
|
||||
m_accessor = rhs.m_accessor;
|
||||
m_pin_id = rhs.m_pin_id;
|
||||
m_data = rhs.m_data;
|
||||
m_size = rhs.m_size;
|
||||
rhs.m_accessor = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~PinBase() {
|
||||
this->Reset();
|
||||
}
|
||||
public:
|
||||
void Reset() {
|
||||
if (m_accessor != nullptr) {
|
||||
m_accessor->ReleasePin(m_pin_id);
|
||||
m_accessor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset(AccessorBase *accessor, u64 pin_id, void *data, size_t size) {
|
||||
AMS_ASSERT(data != nullptr || size == 0);
|
||||
|
||||
this->Reset();
|
||||
|
||||
m_accessor = accessor;
|
||||
m_pin_id = pin_id;
|
||||
m_data = reinterpret_cast<T *>(data);
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
T *GetData() const {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
size_t GetDataSize() const {
|
||||
return m_size;
|
||||
}
|
||||
};
|
||||
private:
|
||||
IMapper *m_mapper;
|
||||
public:
|
||||
AccessorBase(IMapper *mapper) : m_mapper(mapper) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result AcquireReadableStructPin(ReadableStructPin<T> *out, size_t offset) {
|
||||
/* Acquire mapped memory for the pin. */
|
||||
MappedMemory memory = {};
|
||||
R_TRY(m_mapper->GetMappedMemory(std::addressof(memory), offset, sizeof(T)));
|
||||
|
||||
/* Mark the memory as in use. */
|
||||
R_RETURN(m_mapper->MarkUsing(memory.id));
|
||||
|
||||
/* Setup the pin. */
|
||||
out->Reset(this, memory.id, memory.GetBuffer(offset, sizeof(T)), sizeof(T));
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ReleasePin(u64 id) {
|
||||
R_RETURN(m_mapper->UnmarkUsing(id));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result ReadStruct(T *out, size_t offset) {
|
||||
/* Acquire mapped memory for the pin. */
|
||||
MappedMemory memory = {};
|
||||
R_TRY(m_mapper->GetMappedMemory(std::addressof(memory), offset, sizeof(T)));
|
||||
|
||||
/* Mark the memory as in use. */
|
||||
R_RETURN(m_mapper->MarkUsing(memory.id));
|
||||
ON_SCOPE_EXIT { this->ReleasePin(memory.id); };
|
||||
|
||||
/* Copy out the struct. */
|
||||
*out = *reinterpret_cast<const T *>(memory.GetBuffer(offset, sizeof(T)));
|
||||
R_SUCCEED();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ReadableStructPin final : public AccessorBase::PinBase<const u8> {
|
||||
public:
|
||||
using PinBase::PinBase;
|
||||
using PinBase::operator=;
|
||||
|
||||
const T *Get() const {
|
||||
return reinterpret_cast<const T *>(this->GetData());
|
||||
}
|
||||
|
||||
size_t GetSize() const {
|
||||
return this->GetDataSize();
|
||||
}
|
||||
|
||||
const T &operator*() const { return *this->Get(); }
|
||||
const T *operator->() const { return this->Get(); }
|
||||
};
|
||||
|
||||
class PatchMetaExtendedDataAccessor : public AccessorBase {
|
||||
private:
|
||||
struct CachedCount {
|
||||
s32 index;
|
||||
s32 count;
|
||||
};
|
||||
private:
|
||||
util::optional<CachedCount> m_cached_history_content_count = util::nullopt;
|
||||
util::optional<CachedCount> m_cached_delta_content_count = util::nullopt;
|
||||
util::optional<CachedCount> m_cached_fragment_set_count = util::nullopt;
|
||||
util::optional<CachedCount> m_cached_fragment_indicator_count = util::nullopt;
|
||||
util::optional<PatchMetaExtendedDataHeader> m_header = util::nullopt;
|
||||
public:
|
||||
using AccessorBase::AccessorBase;
|
||||
public:
|
||||
Result GetHeader(ReadableStructPin<PatchMetaExtendedDataHeader> *out) { R_RETURN(this->AcquireReadableStructPin(out, 0)); }
|
||||
Result GetHeader(PatchMetaExtendedDataHeader *out) { R_RETURN(this->template ReadStruct<PatchMetaExtendedDataHeader>(out, 0)); }
|
||||
|
||||
Result GetHistoryHeader(ReadableStructPin<PatchHistoryHeader> *out, s32 index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= index && static_cast<u32>(index) < m_header->history_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the header. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * index;
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetPatchDeltaHistory(ReadableStructPin<PatchDeltaHistory> *out, s32 index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= index && static_cast<u32>(index) < m_header->delta_history_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the history. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * index;
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetPatchDeltaHeader(ReadableStructPin<PatchDeltaHeader> *out, s32 index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= index && static_cast<u32>(index) < m_header->delta_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the header. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * index;
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetFragmentSet(ReadableStructPin<FragmentSet> *out, s32 delta_index, s32 fragment_set_index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= delta_index && static_cast<u32>(delta_index) < m_header->delta_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the previous fragment set count. */
|
||||
s32 previous_fragment_set_count = 0;
|
||||
R_TRY(this->CountFragmentSet(std::addressof(previous_fragment_set_count), delta_index));
|
||||
|
||||
/* Get the set. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * m_header->delta_count + sizeof(FragmentSet) * (previous_fragment_set_count + fragment_set_index);
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetFragmentSetDirectly(ReadableStructPin<FragmentSet> *out, s32 fragment_set_direct_index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= fragment_set_direct_index && static_cast<u32>(fragment_set_direct_index) < m_header->fragment_set_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the set. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * m_header->delta_count + sizeof(FragmentSet) * (fragment_set_direct_index);
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetPatchHistoryContentInfo(ReadableStructPin<ContentInfo> *out, s32 history_index, s32 content_index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= history_index && static_cast<u32>(history_index) < m_header->history_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Determine the true history content index. */
|
||||
s32 prev_history_count = 0;
|
||||
R_TRY(this->CountHistoryContentInfo(std::addressof(prev_history_count), history_index));
|
||||
|
||||
/* Adjust and check the content index. */
|
||||
content_index += prev_history_count;
|
||||
R_UNLESS(0 <= content_index && static_cast<u32>(content_index) < m_header->history_content_total_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the info. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * m_header->delta_count + sizeof(FragmentSet) * m_header->fragment_set_count + sizeof(ContentInfo) * content_index;
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetPatchDeltaContentInfo(ReadableStructPin<PackagedContentInfo> *out, s32 delta_index, s32 content_index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= delta_index && static_cast<u32>(delta_index) < m_header->delta_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Determine the true delta content index. */
|
||||
s32 prev_delta_count = 0;
|
||||
R_TRY(this->CountDeltaContentInfo(std::addressof(prev_delta_count), delta_index));
|
||||
|
||||
/* Adjust and check the content index. */
|
||||
content_index += prev_delta_count;
|
||||
R_UNLESS(0 <= content_index && static_cast<u32>(content_index) < m_header->delta_content_total_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the info. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * m_header->delta_count + sizeof(FragmentSet) * m_header->fragment_set_count + sizeof(ContentInfo) * m_header->history_content_total_count + sizeof(PackagedContentInfo) * content_index;
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result GetFragmentIndicator(ReadableStructPin<FragmentIndicator> *out, s32 delta_index, s32 fragment_set_index, s32 index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= delta_index && static_cast<u32>(delta_index) < m_header->delta_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the previous fragment set count. */
|
||||
s32 previous_fragment_set_count = 0;
|
||||
R_TRY(this->CountFragmentSet(std::addressof(previous_fragment_set_count), delta_index));
|
||||
|
||||
/* Get the previous fragment indicator count. */
|
||||
s32 previous_fragment_count = 0;
|
||||
R_TRY(this->CountFragmentIndicator(std::addressof(previous_fragment_count), previous_fragment_count + fragment_set_index));
|
||||
|
||||
/* Get the info. */
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * m_header->delta_count + sizeof(FragmentSet) * m_header->fragment_set_count + sizeof(ContentInfo) * m_header->history_content_total_count + sizeof(PackagedContentInfo) * m_header->delta_content_total_count + sizeof(FragmentIndicator) * (previous_fragment_count + index);
|
||||
R_RETURN(this->AcquireReadableStructPin(out, offset));
|
||||
}
|
||||
|
||||
Result FindFragmentIndicator(ReadableStructPin<FragmentIndicator> *out, s32 delta_index, s32 fragment_set_index, s32 fragment_index) {
|
||||
/* Ensure we have our header. */
|
||||
R_TRY(this->EnsureHeader());
|
||||
|
||||
/* Check that the index is valid. */
|
||||
R_UNLESS(0 <= delta_index && static_cast<u32>(delta_index) < m_header->delta_count, ncm::ResultInvalidOffset());
|
||||
|
||||
/* Get the fragment count. */
|
||||
s32 fragment_count = 0;
|
||||
{
|
||||
ReadableStructPin<FragmentSet> set;
|
||||
R_TRY(this->GetFragmentSet(std::addressof(set), delta_index, fragment_set_index));
|
||||
|
||||
fragment_count = set->fragment_count;
|
||||
}
|
||||
|
||||
/* Get the previous fragment set count. */
|
||||
s32 previous_fragment_set_count = 0;
|
||||
R_TRY(this->CountFragmentSet(std::addressof(previous_fragment_set_count), delta_index));
|
||||
|
||||
/* Get the previous fragment indicator count. */
|
||||
s32 previous_fragment_count = 0;
|
||||
R_TRY(this->CountFragmentIndicator(std::addressof(previous_fragment_count), previous_fragment_count + fragment_set_index));
|
||||
|
||||
/* Look for a correct indicator. */
|
||||
for (auto i = 0; i < fragment_count; ++i) {
|
||||
/* Get the current info. */
|
||||
ReadableStructPin<FragmentIndicator> indicator;
|
||||
const size_t offset = sizeof(PatchHistoryHeader) + sizeof(PatchHistoryHeader) * m_header->history_count + sizeof(PatchDeltaHistory) * m_header->delta_history_count + sizeof(PatchDeltaHeader) * m_header->delta_count + sizeof(FragmentSet) * m_header->fragment_set_count + sizeof(ContentInfo) * m_header->history_content_total_count + sizeof(PackagedContentInfo) * m_header->delta_content_total_count + sizeof(FragmentIndicator) * (previous_fragment_count + i);
|
||||
R_TRY(this->AcquireReadableStructPin(std::addressof(indicator), offset));
|
||||
|
||||
/* If it matches, return it. */
|
||||
if (indicator->fragment_index == fragment_index) {
|
||||
*out = std::move(indicator);
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
/* We didn't find an indicator. */
|
||||
R_THROW(ncm::ResultFragmentIndicatorNotFound());
|
||||
}
|
||||
|
||||
Result GetHistoryHeader(PatchHistoryHeader *out, s32 index) {
|
||||
/* Get the pin. */
|
||||
ReadableStructPin<PatchHistoryHeader> pin;
|
||||
R_TRY(this->GetHistoryHeader(std::addressof(pin), index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetPatchDeltaHistory(PatchDeltaHistory *out, s32 index) {
|
||||
/* Get the pin. */
|
||||
ReadableStructPin<PatchDeltaHistory> pin;
|
||||
R_TRY(this->GetPatchDeltaHistory(std::addressof(pin), index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetPatchDeltaHeader(PatchDeltaHeader *out, s32 index) {
|
||||
/* Get the pin. */
|
||||
ReadableStructPin<PatchDeltaHeader> pin;
|
||||
R_TRY(this->GetPatchDeltaHeader(std::addressof(pin), index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetFragmentSet(FragmentSet *out, s32 delta_index, s32 fragment_set_index) {
|
||||
/* Get the pin. */
|
||||
ReadableStructPin<FragmentSet> pin;
|
||||
R_TRY(this->GetFragmentSet(std::addressof(pin), delta_index, fragment_set_index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetPatchHistoryContentInfo(ContentInfo *out, s32 history_index, s32 content_index) {
|
||||
/* Get the header. */
|
||||
ReadableStructPin<ContentInfo> pin;
|
||||
R_TRY(this->GetPatchHistoryContentInfo(std::addressof(pin), history_index, content_index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetPatchDeltaContentInfo(PackagedContentInfo *out, s32 delta_index, s32 content_index) {
|
||||
/* Get the header. */
|
||||
ReadableStructPin<PackagedContentInfo> pin;
|
||||
R_TRY(this->GetPatchDeltaContentInfo(std::addressof(pin), delta_index, content_index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetFragmentIndicator(FragmentIndicator *out, s32 delta_index, s32 fragment_set_index, s32 index) {
|
||||
/* Get the header. */
|
||||
ReadableStructPin<FragmentIndicator> pin;
|
||||
R_TRY(this->GetFragmentIndicator(std::addressof(pin), delta_index, fragment_set_index, index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FindFragmentIndicator(FragmentIndicator *out, s32 delta_index, s32 fragment_set_index, s32 fragment_index) {
|
||||
/* Get the header. */
|
||||
ReadableStructPin<FragmentIndicator> pin;
|
||||
R_TRY(this->FindFragmentIndicator(std::addressof(pin), delta_index, fragment_set_index, fragment_index));
|
||||
|
||||
/* Copy it out. */
|
||||
*out = *pin;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result CountHistoryContentInfo(s32 *out, s32 index) {
|
||||
R_RETURN(this->CountImpl(out, index, m_cached_history_content_count, [&](s32 *out, s32 i) -> Result {
|
||||
/* Get the history header. */
|
||||
ReadableStructPin<ncm::PatchHistoryHeader> header;
|
||||
R_TRY(this->GetHistoryHeader(std::addressof(header), i));
|
||||
|
||||
/* Set the content count. */
|
||||
*out = header->content_count;
|
||||
R_SUCCEED();
|
||||
}));
|
||||
}
|
||||
|
||||
Result CountDeltaContentInfo(s32 *out, s32 index) {
|
||||
R_RETURN(this->CountImpl(out, index, m_cached_delta_content_count, [&](s32 *out, s32 i) -> Result {
|
||||
/* Get the history header. */
|
||||
ReadableStructPin<ncm::PatchDeltaHeader> header;
|
||||
R_TRY(this->GetPatchDeltaHeader(std::addressof(header), i));
|
||||
|
||||
/* Set the content count. */
|
||||
*out = header->content_count;
|
||||
R_SUCCEED();
|
||||
}));
|
||||
}
|
||||
|
||||
Result CountFragmentSet(s32 *out, s32 index) {
|
||||
R_RETURN(this->CountImpl(out, index, m_cached_fragment_set_count, [&](s32 *out, s32 i) -> Result {
|
||||
/* Get the history header. */
|
||||
ReadableStructPin<ncm::PatchDeltaHeader> header;
|
||||
R_TRY(this->GetPatchDeltaHeader(std::addressof(header), i));
|
||||
|
||||
/* Set the fragment set count. */
|
||||
*out = header->delta.fragment_set_count;
|
||||
R_SUCCEED();
|
||||
}));
|
||||
}
|
||||
|
||||
Result CountFragmentIndicator(s32 *out, s32 index) {
|
||||
R_RETURN(this->CountImpl(out, index, m_cached_fragment_indicator_count, [&](s32 *out, s32 i) -> Result {
|
||||
/* Get the history header. */
|
||||
ReadableStructPin<ncm::FragmentSet> set;
|
||||
R_TRY(this->GetFragmentSetDirectly(std::addressof(set), i));
|
||||
|
||||
/* Set the indicator count. */
|
||||
*out = set->fragment_count;
|
||||
R_SUCCEED();
|
||||
}));
|
||||
}
|
||||
private:
|
||||
Result CountImpl(s32 *out, s32 index, util::optional<CachedCount> &cache, auto get_count_impl) const {
|
||||
/* Ensure the value is cached. */
|
||||
if (!(cache.has_value() && cache->index == index)) {
|
||||
/* Determine the count. */
|
||||
CachedCount calc = { .index = index, .count = 0 };
|
||||
for (auto i = 0; i < index; ++i) {
|
||||
s32 cur_count = 0;
|
||||
R_TRY(get_count_impl(std::addressof(cur_count), i));
|
||||
|
||||
calc.count += cur_count;
|
||||
}
|
||||
|
||||
/* Cache the count. */
|
||||
cache = calc;
|
||||
}
|
||||
|
||||
/* Set the output count. */
|
||||
*out = cache->count;
|
||||
R_SUCCEED();
|
||||
}
|
||||
private:
|
||||
Result EnsureHeader() {
|
||||
/* If we have our header, we're good. */
|
||||
R_SUCCEED_IF(m_header.has_value());
|
||||
|
||||
/* Get our header. */
|
||||
PatchMetaExtendedDataHeader header{};
|
||||
R_TRY(this->GetHeader(std::addressof(header)));
|
||||
|
||||
/* Set our header. */
|
||||
m_header.emplace(header);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_data_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_program_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct ApplicationId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const ApplicationId &) const = default;
|
||||
constexpr inline bool operator!=(const ApplicationId &) const = default;
|
||||
|
||||
static const ApplicationId Start;
|
||||
static const ApplicationId End;
|
||||
};
|
||||
|
||||
constexpr inline const ApplicationId InvalidApplicationId = {};
|
||||
|
||||
inline constexpr const ApplicationId ApplicationId::Start = { 0x0100000000010000ul };
|
||||
inline constexpr const ApplicationId ApplicationId::End = { 0x01FFFFFFFFFFFFFFul };
|
||||
|
||||
inline constexpr bool IsApplicationId(const ProgramId &program_id) {
|
||||
return ApplicationId::Start <= program_id && program_id <= ApplicationId::End;
|
||||
}
|
||||
|
||||
inline constexpr bool IsApplicationId(const ApplicationId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct ApplicationGroupId {
|
||||
u64 value;
|
||||
};
|
||||
|
||||
struct PatchId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const PatchId &) const = default;
|
||||
constexpr inline bool operator!=(const PatchId &) const = default;
|
||||
};
|
||||
|
||||
struct PatchGroupId {
|
||||
u64 value;
|
||||
};
|
||||
|
||||
struct AddOnContentId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator DataId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const AddOnContentId &) const = default;
|
||||
constexpr inline bool operator!=(const AddOnContentId &) const = default;
|
||||
};
|
||||
|
||||
struct DeltaId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const DeltaId &) const = default;
|
||||
constexpr inline bool operator!=(const DeltaId &) const = default;
|
||||
};
|
||||
|
||||
struct DataPatchId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator DataId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const DataPatchId &) const = default;
|
||||
constexpr inline bool operator!=(const DataPatchId &) const = default;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_type.hpp>
|
||||
#include <stratosphere/ncm/ncm_system_content_meta_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class ContentInstallType : u8 {
|
||||
Full = 0,
|
||||
FragmentOnly = 1,
|
||||
Unknown = 7,
|
||||
};
|
||||
|
||||
struct ContentMetaKey {
|
||||
u64 id;
|
||||
u32 version;
|
||||
ContentMetaType type;
|
||||
ContentInstallType install_type;
|
||||
u8 padding[2];
|
||||
|
||||
bool operator<(const ContentMetaKey &rhs) const {
|
||||
return std::tie(this->id, this->version, this->type, this->install_type) < std::tie(rhs.id, rhs.version, rhs.type, rhs.install_type);
|
||||
}
|
||||
|
||||
constexpr bool operator==(const ContentMetaKey &rhs) const {
|
||||
return std::tie(this->id, this->version, this->type, this->install_type) == std::tie(rhs.id, rhs.version, rhs.type, rhs.install_type);
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const ContentMetaKey &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey MakeUnknownType(u64 id, u32 version) {
|
||||
return { .id = id, .version = version, .type = ContentMetaType::Unknown };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(u64 id, u32 version, ContentMetaType type) {
|
||||
return { .id = id, .version = version, .type = type };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(u64 id, u32 version, ContentMetaType type, ContentInstallType install_type) {
|
||||
return { .id = id, .version = version, .type = type, .install_type = install_type };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(SystemProgramId id, u32 version) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::SystemProgram };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(SystemDataId id, u32 version) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::SystemData };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(SystemUpdateId id, u32 version) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::SystemUpdate };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(ApplicationId id, u32 version) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::Application };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(PatchId id, u32 version) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::Patch };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(PatchId id, u32 version, ContentInstallType install_type) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::Patch, .install_type = install_type };
|
||||
}
|
||||
|
||||
static constexpr ContentMetaKey Make(DeltaId id, u32 version) {
|
||||
return { .id = id.value, .version = version, .type = ContentMetaType::Delta };
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(ContentMetaKey) == 0x10);
|
||||
|
||||
struct ApplicationContentMetaKey {
|
||||
ContentMetaKey key;
|
||||
ncm::ApplicationId application_id;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ApplicationContentMetaKey) == 0x18);
|
||||
|
||||
struct StorageContentMetaKey {
|
||||
ContentMetaKey key;
|
||||
StorageId storage_id;
|
||||
u8 reserved[7];
|
||||
|
||||
constexpr bool operator==(StorageContentMetaKey &rhs) const {
|
||||
return this->key == rhs.key && this->storage_id == rhs.storage_id;
|
||||
}
|
||||
|
||||
constexpr bool operator<(StorageContentMetaKey &rhs) const {
|
||||
return this->key == rhs.key ? this->storage_id < rhs.storage_id : this->key < rhs.key;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(StorageContentMetaKey) == 0x18);
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class ContentMetaPlatform : u8 {
|
||||
Nx = 0x0,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class ContentMetaType : u8 {
|
||||
Unknown = 0x0,
|
||||
SystemProgram = 0x1,
|
||||
SystemData = 0x2,
|
||||
SystemUpdate = 0x3,
|
||||
BootImagePackage = 0x4,
|
||||
BootImagePackageSafe = 0x5,
|
||||
Application = 0x80,
|
||||
Patch = 0x81,
|
||||
AddOnContent = 0x82,
|
||||
Delta = 0x83,
|
||||
DataPatch = 0x84,
|
||||
};
|
||||
|
||||
const char *GetContentMetaTypeString(ContentMetaType type);
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_auto_buffer.hpp>
|
||||
#include <stratosphere/ncm/ncm_storage_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_storage.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_key.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_database.hpp>
|
||||
#include <stratosphere/ncm/ncm_firmware_variation.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
using MountContentMetaFunction = Result (*)(const char *mount_name, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
bool IsContentMetaFileName(const char *name);
|
||||
|
||||
Result ReadContentMetaPathAlongWithExtendedDataAndDigest(AutoBuffer *out, const char *path, fs::ContentAttributes attr);
|
||||
Result ReadContentMetaPathAlongWithExtendedDataAndDigestSuppressingFsAbort(AutoBuffer *out, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
Result ReadContentMetaPathWithoutExtendedDataOrDigest(AutoBuffer *out, const char *path, fs::ContentAttributes attr);
|
||||
Result ReadContentMetaPathWithoutExtendedDataOrDigestSuppressingFsAbort(AutoBuffer *out, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
using ReadContentMetaPathFunction = Result (*)(AutoBuffer *out, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
Result TryReadContentMetaPath(fs::ContentAttributes *out_attr, AutoBuffer *out, const char *path, ReadContentMetaPathFunction func);
|
||||
Result TryReadContentMetaPath(AutoBuffer *out, const char *path, ReadContentMetaPathFunction func);
|
||||
|
||||
Result ReadVariationContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const Path &path, fs::ContentAttributes attr, FirmwareVariationId firmware_variation_id);
|
||||
|
||||
void SetMountContentMetaFunction(MountContentMetaFunction func);
|
||||
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_i_content_storage.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class ContentStorage {
|
||||
NON_COPYABLE(ContentStorage);
|
||||
private:
|
||||
sf::SharedPointer<IContentStorage> m_interface;
|
||||
public:
|
||||
ContentStorage() : m_interface(nullptr) { /* ... */ }
|
||||
explicit ContentStorage(sf::SharedPointer<IContentStorage> intf) : m_interface(intf) { /* ... */ }
|
||||
|
||||
ContentStorage(ContentStorage &&rhs) {
|
||||
m_interface = std::move(rhs.m_interface);
|
||||
}
|
||||
|
||||
ContentStorage &operator=(ContentStorage &&rhs) {
|
||||
ContentStorage(std::move(rhs)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(ContentStorage &rhs) {
|
||||
std::swap(m_interface, rhs.m_interface);
|
||||
}
|
||||
public:
|
||||
PlaceHolderId GeneratePlaceHolderId() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
|
||||
PlaceHolderId id;
|
||||
R_ABORT_UNLESS(m_interface->GeneratePlaceHolderId(std::addressof(id)));
|
||||
return id;
|
||||
}
|
||||
|
||||
Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->CreatePlaceHolder(placeholder_id, content_id, size));
|
||||
}
|
||||
|
||||
Result DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->DeletePlaceHolder(placeholder_id));
|
||||
}
|
||||
|
||||
Result HasPlaceHolder(bool *out, PlaceHolderId placeholder_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->HasPlaceHolder(out, placeholder_id));
|
||||
}
|
||||
|
||||
Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const void *buf, size_t size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->WritePlaceHolder(placeholder_id, offset, sf::InBuffer(buf, size)));
|
||||
}
|
||||
|
||||
Result Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Register(placeholder_id, content_id));
|
||||
}
|
||||
|
||||
Result Delete(ContentId content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Delete(content_id));
|
||||
}
|
||||
|
||||
Result Has(bool *out, ContentId content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->Has(out, content_id));
|
||||
}
|
||||
|
||||
void GetPath(Path *out, ContentId content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_ABORT_UNLESS(m_interface->GetPath(out, content_id));
|
||||
}
|
||||
|
||||
void GetPlaceHolderPath(Path *out, PlaceHolderId placeholder_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_ABORT_UNLESS(m_interface->GetPlaceHolderPath(out, placeholder_id));
|
||||
}
|
||||
|
||||
Result CleanupAllPlaceHolder() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->CleanupAllPlaceHolder());
|
||||
}
|
||||
|
||||
Result ListPlaceHolder(s32 *out_count, PlaceHolderId *out_list, size_t out_list_size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->ListPlaceHolder(out_count, sf::OutArray<PlaceHolderId>(out_list, out_list_size)));
|
||||
}
|
||||
|
||||
Result GetContentCount(s32 *out_count) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentCount(out_count));
|
||||
}
|
||||
|
||||
Result ListContentId(s32 *out_count, ContentId *out_list, size_t out_list_size, s32 offset) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->ListContentId(out_count, sf::OutArray<ContentId>(out_list, out_list_size), offset));
|
||||
}
|
||||
|
||||
Result GetSize(s64 *out_size, ContentId content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetSizeFromContentId(out_size, content_id));
|
||||
}
|
||||
|
||||
Result GetSize(s64 *out_size, PlaceHolderId placeholder_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetSizeFromPlaceHolderId(out_size, placeholder_id));
|
||||
}
|
||||
|
||||
Result DisableForcibly() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->DisableForcibly());
|
||||
}
|
||||
|
||||
Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->RevertToPlaceHolder(placeholder_id, old_content_id, new_content_id));
|
||||
}
|
||||
|
||||
Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->SetPlaceHolderSize(placeholder_id, size));
|
||||
}
|
||||
|
||||
Result ReadContentIdFile(void *dst, size_t size, ContentId content_id, s64 offset) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->ReadContentIdFile(sf::OutBuffer(dst, size), content_id, offset));
|
||||
}
|
||||
|
||||
Result GetRightsId(ncm::RightsId *out_rights_id, PlaceHolderId placeholder_id, fs::ContentAttributes attr) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
|
||||
const auto vers = hos::GetVersion();
|
||||
if (vers >= hos::Version_16_0_0) {
|
||||
R_RETURN(m_interface->GetRightsIdFromPlaceHolderId(out_rights_id, placeholder_id, attr));
|
||||
} else if (vers >= hos::Version_3_0_0) {
|
||||
R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdDeprecated2(out_rights_id, placeholder_id));
|
||||
} else {
|
||||
AMS_ABORT_UNLESS(vers >= hos::Version_2_0_0);
|
||||
*out_rights_id = {};
|
||||
R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdDeprecated(std::addressof(out_rights_id->id), placeholder_id));
|
||||
}
|
||||
}
|
||||
|
||||
Result GetRightsId(ncm::RightsId *out_rights_id, ContentId content_id, fs::ContentAttributes attr) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
|
||||
const auto vers = hos::GetVersion();
|
||||
if (vers >= hos::Version_16_0_0) {
|
||||
R_RETURN(m_interface->GetRightsIdFromContentId(out_rights_id, content_id, attr));
|
||||
} else if (vers >= hos::Version_3_0_0) {
|
||||
R_RETURN(m_interface->GetRightsIdFromContentIdDeprecated2(out_rights_id, content_id));
|
||||
} else {
|
||||
AMS_ABORT_UNLESS(vers >= hos::Version_2_0_0);
|
||||
*out_rights_id = {};
|
||||
R_RETURN(m_interface->GetRightsIdFromContentIdDeprecated(std::addressof(out_rights_id->id), content_id));
|
||||
}
|
||||
}
|
||||
|
||||
Result WriteContentForDebug(ContentId content_id, s64 offset, const void *buf, size_t size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->WriteContentForDebug(content_id, offset, sf::InBuffer(buf, size)));
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(s64 *out_size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetFreeSpaceSize(out_size));
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(s64 *out_size) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetTotalSpaceSize(out_size));
|
||||
}
|
||||
|
||||
Result FlushPlaceHolder() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->FlushPlaceHolder());
|
||||
}
|
||||
|
||||
Result RepairInvalidFileAttribute() {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->RepairInvalidFileAttribute());
|
||||
}
|
||||
|
||||
Result GetRightsIdFromPlaceHolderIdWithCache(ncm::RightsId *out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
|
||||
const auto vers = hos::GetVersion();
|
||||
if (vers >= hos::Version_16_0_0) {
|
||||
R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdWithCache(out_rights_id, placeholder_id, cache_content_id, attr));
|
||||
} else {
|
||||
R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdWithCacheDeprecated(out_rights_id, cache_content_id, placeholder_id));
|
||||
}
|
||||
}
|
||||
|
||||
Result GetProgramId(ncm::ProgramId *out, ContentId content_id, fs::ContentAttributes attr) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetProgramId(out, content_id, attr));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class ContentType : u8 {
|
||||
Meta = 0,
|
||||
Program = 1,
|
||||
Data = 2,
|
||||
Control = 3,
|
||||
HtmlDocument = 4,
|
||||
LegalInformation = 5,
|
||||
DeltaFragment = 6,
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct DataId {
|
||||
u64 value;
|
||||
|
||||
static const DataId Invalid;
|
||||
|
||||
constexpr inline auto operator<=>(const DataId &) const = default;
|
||||
};
|
||||
|
||||
inline constexpr const DataId DataId::Invalid = {};
|
||||
inline constexpr const DataId InvalidDataId = DataId::Invalid;
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct FirmwareVariationInfo {
|
||||
bool refer_to_base;
|
||||
u8 _0x1[3];
|
||||
u32 content_meta_count;
|
||||
u8 reserved[0x18];
|
||||
};
|
||||
|
||||
struct FirmwareVariationId {
|
||||
u32 value;
|
||||
};
|
||||
|
||||
constexpr inline bool operator==(const FirmwareVariationId &lhs, const FirmwareVariationId &rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
constexpr inline bool operator!=(const FirmwareVariationId &lhs, const FirmwareVariationId &rhs) {
|
||||
return lhs.value != rhs.value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_i_content_storage.hpp>
|
||||
#include <stratosphere/ncm/ncm_i_content_meta_database.hpp>
|
||||
#include <stratosphere/ncm/ncm_memory_report.hpp>
|
||||
#include <stratosphere/fs/fs_content_storage_id.hpp>
|
||||
|
||||
#define AMS_NCM_I_CONTENT_MANAGER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, CreateContentStorage, (ncm::StorageId storage_id), (storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreateContentMetaDatabase, (ncm::StorageId storage_id), (storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, VerifyContentStorage, (ncm::StorageId storage_id), (storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, VerifyContentMetaDatabase, (ncm::StorageId storage_id), (storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, OpenContentStorage, (sf::Out<sf::SharedPointer<ncm::IContentStorage>> out, ncm::StorageId storage_id), (out, storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, OpenContentMetaDatabase, (sf::Out<sf::SharedPointer<ncm::IContentMetaDatabase>> out, ncm::StorageId storage_id), (out, storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, CloseContentStorageForcibly, (ncm::StorageId storage_id), (storage_id), hos::Version_1_0_0, hos::Version_1_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, CloseContentMetaDatabaseForcibly, (ncm::StorageId storage_id), (storage_id), hos::Version_1_0_0, hos::Version_1_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, CleanupContentMetaDatabase, (ncm::StorageId storage_id), (storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, ActivateContentStorage, (ncm::StorageId storage_id), (storage_id), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, InactivateContentStorage, (ncm::StorageId storage_id), (storage_id), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, ActivateContentMetaDatabase, (ncm::StorageId storage_id), (storage_id), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, InactivateContentMetaDatabase, (ncm::StorageId storage_id), (storage_id), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 13, Result, InvalidateRightsIdCache, (), (), hos::Version_9_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 14, Result, GetMemoryReport, (sf::Out<ncm::MemoryReport> out), (out), hos::Version_10_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 15, Result, ActivateFsContentStorage, (fs::ContentStorageId fs_storage_id), (fs_storage_id)) /* Technically min 16.0.0, but used. */
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentManager, AMS_NCM_I_CONTENT_MANAGER_INTERFACE_INFO, 0xFDB4FFE1);
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/sf.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta.hpp>
|
||||
|
||||
#define AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, Set, (const ncm::ContentMetaKey &key, const sf::InBuffer &value), (key, value)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, Get, (sf::Out<u64> out_size, const ncm::ContentMetaKey &key, const sf::OutBuffer &out_value), (out_size, key, out_value)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, Remove, (const ncm::ContentMetaKey &key), (key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetContentIdByType, (sf::Out<ncm::ContentId> out_content_id, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_id, key, type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, ListContentInfo, (sf::Out<s32> out_entries_written, const sf::OutArray<ncm::ContentInfo> &out_info, const ncm::ContentMetaKey &key, s32 offset), (out_entries_written, out_info, key, offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, List, (sf::Out<s32> out_entries_total, sf::Out<s32> out_entries_written, const sf::OutArray<ncm::ContentMetaKey> &out_info, ncm::ContentMetaType meta_type, ncm::ApplicationId application_id, u64 min, u64 max, ncm::ContentInstallType install_type), (out_entries_total, out_entries_written, out_info, meta_type, application_id, min, max, install_type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, GetLatestContentMetaKey, (sf::Out<ncm::ContentMetaKey> out_key, u64 id), (out_key, id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, ListApplication, (sf::Out<s32> out_entries_total, sf::Out<s32> out_entries_written, const sf::OutArray<ncm::ApplicationContentMetaKey> &out_keys, ncm::ContentMetaType meta_type), (out_entries_total, out_entries_written, out_keys, meta_type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, Has, (sf::Out<bool> out, const ncm::ContentMetaKey &key), (out, key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, HasAll, (sf::Out<bool> out, const sf::InArray<ncm::ContentMetaKey> &keys), (out, keys)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, GetSize, (sf::Out<u64> out_size, const ncm::ContentMetaKey &key), (out_size, key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, GetRequiredSystemVersion, (sf::Out<u32> out_version, const ncm::ContentMetaKey &key), (out_version, key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, GetPatchContentMetaId, (sf::Out<u64> out_patch_id, const ncm::ContentMetaKey &key), (out_patch_id, key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 13, Result, DisableForcibly, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 14, Result, LookupOrphanContent, (const sf::OutArray<bool> &out_orphaned, const sf::InArray<ncm::ContentId> &content_ids), (out_orphaned, content_ids)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 15, Result, Commit, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 16, Result, HasContent, (sf::Out<bool> out, const ncm::ContentMetaKey &key, const ncm::ContentId &content_id), (out, key, content_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 17, Result, ListContentMetaInfo, (sf::Out<s32> out_entries_written, const sf::OutArray<ncm::ContentMetaInfo> &out_meta_info, const ncm::ContentMetaKey &key, s32 offset), (out_entries_written, out_meta_info, key, offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 18, Result, GetAttributes, (sf::Out<u8> out_attributes, const ncm::ContentMetaKey &key), (out_attributes, key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 19, Result, GetRequiredApplicationVersion, (sf::Out<u32> out_version, const ncm::ContentMetaKey &key), (out_version, key), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, GetContentIdByTypeAndIdOffset, (sf::Out<ncm::ContentId> out_content_id, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_id, key, type, id_offset), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, GetCount, (sf::Out<u32> out_count), (out_count), hos::Version_10_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 22, Result, GetOwnerApplicationId, (sf::Out<ncm::ApplicationId> out_id, const ncm::ContentMetaKey &key), (out_id, key), hos::Version_10_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out<u8> out_accessibilities, const ncm::ContentMetaKey &key), (out_accessibilities, key), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 24, Result, GetContentInfoByType, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_info, key, type), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out<ncm::ContentMetaPlatform> out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 27, Result, HasAttributes, (sf::Out<u8> out, u8 attr_mask), (out, attr_mask), hos::Version_20_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC)
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/sf.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_placeholder_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_path.hpp>
|
||||
#include <stratosphere/ncm/ncm_rights_id.hpp>
|
||||
|
||||
#define AMS_NCM_I_CONTENT_STORAGE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, GeneratePlaceHolderId, (sf::Out<ncm::PlaceHolderId> out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreatePlaceHolder_AtmosphereAlignmentFix, (ncm::ContentId content_id, ncm::PlaceHolderId placeholder_id, s64 size), (content_id, placeholder_id, size), hos::Version_Min, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, CreatePlaceHolder, (ncm::PlaceHolderId placeholder_id, ncm::ContentId content_id, s64 size), (placeholder_id, content_id, size), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, DeletePlaceHolder, (ncm::PlaceHolderId placeholder_id), (placeholder_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, HasPlaceHolder, (sf::Out<bool> out, ncm::PlaceHolderId placeholder_id), (out, placeholder_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, WritePlaceHolder, (ncm::PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data), (placeholder_id, offset, data)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, Register_AtmosphereAlignmentFix, (ncm::ContentId content_id, ncm::PlaceHolderId placeholder_id), (content_id, placeholder_id), hos::Version_Min, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, Register, (ncm::PlaceHolderId placeholder_id, ncm::ContentId content_id), (placeholder_id, content_id), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, Delete, (ncm::ContentId content_id), (content_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, Has, (sf::Out<bool> out, ncm::ContentId content_id), (out, content_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, GetPath, (sf::Out<ncm::Path> out, ncm::ContentId content_id), (out, content_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 9, Result, GetPlaceHolderPath, (sf::Out<ncm::Path> out, ncm::PlaceHolderId placeholder_id), (out, placeholder_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, CleanupAllPlaceHolder, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 11, Result, ListPlaceHolder, (sf::Out<s32> out_count, const sf::OutArray<ncm::PlaceHolderId> &out_buf), (out_count, out_buf)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, GetContentCount, (sf::Out<s32> out_count), (out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 13, Result, ListContentId, (sf::Out<s32> out_count, const sf::OutArray<ncm::ContentId> &out_buf, s32 start_offset), (out_count, out_buf, start_offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 14, Result, GetSizeFromContentId, (sf::Out<s64> out_size, ncm::ContentId content_id), (out_size, content_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 15, Result, DisableForcibly, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 16, Result, RevertToPlaceHolder_AtmosphereAlignmentFix, (ncm::ContentId old_content_id, ncm::ContentId new_content_id, ncm::PlaceHolderId placeholder_id), (old_content_id, new_content_id, placeholder_id), hos::Version_2_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 16, Result, RevertToPlaceHolder, (ncm::PlaceHolderId placeholder_id, ncm::ContentId old_content_id, ncm::ContentId new_content_id), (placeholder_id, old_content_id, new_content_id), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 17, Result, SetPlaceHolderSize, (ncm::PlaceHolderId placeholder_id, s64 size), (placeholder_id, size), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 18, Result, ReadContentIdFile, (const sf::OutBuffer &buf, ncm::ContentId content_id, s64 offset), (buf, content_id, offset), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 19, Result, GetRightsIdFromPlaceHolderIdDeprecated, (sf::Out<ams::fs::RightsId> out_rights_id, ncm::PlaceHolderId placeholder_id), (out_rights_id, placeholder_id), hos::Version_2_0_0, hos::Version_2_3_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 19, Result, GetRightsIdFromPlaceHolderIdDeprecated2, (sf::Out<ncm::RightsId> out_rights_id, ncm::PlaceHolderId placeholder_id), (out_rights_id, placeholder_id), hos::Version_3_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 19, Result, GetRightsIdFromPlaceHolderId, (sf::Out<ncm::RightsId> out_rights_id, ncm::PlaceHolderId placeholder_id, fs::ContentAttributes attr), (out_rights_id, placeholder_id, attr), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, GetRightsIdFromContentIdDeprecated, (sf::Out<ams::fs::RightsId> out_rights_id, ncm::ContentId content_id), (out_rights_id, content_id), hos::Version_2_0_0, hos::Version_2_3_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, GetRightsIdFromContentIdDeprecated2, (sf::Out<ncm::RightsId> out_rights_id, ncm::ContentId content_id), (out_rights_id, content_id), hos::Version_3_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 20, Result, GetRightsIdFromContentId, (sf::Out<ncm::RightsId> out_rights_id, ncm::ContentId content_id, fs::ContentAttributes attr), (out_rights_id, content_id, attr), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, WriteContentForDebug, (ncm::ContentId content_id, s64 offset, const sf::InBuffer &data), (content_id, offset, data), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 22, Result, GetFreeSpaceSize, (sf::Out<s64> out_size), (out_size), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 23, Result, GetTotalSpaceSize, (sf::Out<s64> out_size), (out_size), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 24, Result, FlushPlaceHolder, (), (), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 25, Result, GetSizeFromPlaceHolderId, (sf::Out<s64> out, ncm::PlaceHolderId placeholder_id), (out, placeholder_id), hos::Version_4_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 26, Result, RepairInvalidFileAttribute, (), (), hos::Version_4_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCacheDeprecated, (sf::Out<ncm::RightsId> out_rights_id, ncm::ContentId cache_content_id, ncm::PlaceHolderId placeholder_id), (out_rights_id, cache_content_id, placeholder_id), hos::Version_8_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCache, (sf::Out<ncm::RightsId> out_rights_id, ncm::PlaceHolderId placeholder_id, ncm::ContentId cache_content_id, fs::ContentAttributes attr), (out_rights_id, placeholder_id, cache_content_id, attr), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 28, Result, RegisterPath, (const ncm::ContentId &content_id, const ncm::Path &path), (content_id, path), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 30, Result, GetProgramId, (sf::Out<ncm::ProgramId> out, ncm::ContentId content_id, fs::ContentAttributes attr), (out, content_id, attr), hos::Version_17_0_0)
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentStorage, AMS_NCM_I_CONTENT_STORAGE_INTERFACE_INFO, 0xFEAE3DD1)
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_data_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_program_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_system_content_meta_id.hpp>
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class InstallProgressState : u8 {
|
||||
NotPrepared = 0,
|
||||
DataPrepared = 1,
|
||||
Prepared = 2,
|
||||
Downloaded = 3,
|
||||
Committed = 4,
|
||||
Fatal = 5,
|
||||
};
|
||||
|
||||
struct InstallProgress {
|
||||
InstallProgressState state;
|
||||
u8 pad[3];
|
||||
util::TypedStorage<Result> last_result;
|
||||
s64 installed_size;
|
||||
s64 total_size;
|
||||
|
||||
Result GetLastResult() const {
|
||||
return util::GetReference(last_result);
|
||||
}
|
||||
|
||||
void SetLastResult(Result result) {
|
||||
*util::GetPointer(last_result) = result;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_install_task_data.hpp>
|
||||
#include <stratosphere/ncm/ncm_install_task_occupied_size.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class ListContentMetaKeyFilter : u8 {
|
||||
All = 0,
|
||||
Committed = 1,
|
||||
NotCommitted = 2,
|
||||
};
|
||||
|
||||
enum InstallConfig {
|
||||
InstallConfig_None = (0 << 0),
|
||||
InstallConfig_SystemUpdate = (1 << 2),
|
||||
InstallConfig_RequiresExFatDriver = (1 << 3),
|
||||
InstallConfig_IgnoreTicket = (1 << 4),
|
||||
};
|
||||
|
||||
struct InstallThroughput {
|
||||
s64 installed;
|
||||
TimeSpan elapsed_time;
|
||||
};
|
||||
|
||||
struct InstallContentMetaInfo {
|
||||
ContentId content_id;
|
||||
s64 content_size;
|
||||
ContentMetaKey key;
|
||||
bool verify_digest;
|
||||
bool has_key;
|
||||
Digest digest;
|
||||
|
||||
static constexpr InstallContentMetaInfo MakeVerifiable(const ContentId &cid, s64 sz, const ContentMetaKey &ky, const Digest &d) {
|
||||
return {
|
||||
.content_id = cid,
|
||||
.content_size = sz,
|
||||
.key = ky,
|
||||
.verify_digest = true,
|
||||
.has_key = true,
|
||||
.digest = d,
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr InstallContentMetaInfo MakeUnverifiable(const ContentId &cid, s64 sz, const ContentMetaKey &ky) {
|
||||
return {
|
||||
.content_id = cid,
|
||||
.content_size = sz,
|
||||
.key = ky,
|
||||
.verify_digest = false,
|
||||
.has_key = true,
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr InstallContentMetaInfo MakeUnverifiable(const ContentId &cid, s64 sz) {
|
||||
return {
|
||||
.content_id = cid,
|
||||
.content_size = sz,
|
||||
.verify_digest = false,
|
||||
.has_key = false,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(InstallContentMetaInfo) == 0x50);
|
||||
|
||||
class InstallTaskBase {
|
||||
NON_COPYABLE(InstallTaskBase);
|
||||
NON_MOVEABLE(InstallTaskBase);
|
||||
private:
|
||||
crypto::Sha256Generator m_sha256_generator{};
|
||||
StorageId m_install_storage{};
|
||||
InstallTaskDataBase *m_data{};
|
||||
InstallProgress m_progress{};
|
||||
os::SdkMutex m_progress_mutex{};
|
||||
u32 m_config{};
|
||||
os::SdkMutex m_cancel_mutex{};
|
||||
bool m_cancel_requested{};
|
||||
InstallThroughput m_throughput{};
|
||||
TimeSpan m_throughput_start_time{};
|
||||
os::SdkMutex m_throughput_mutex{};
|
||||
FirmwareVariationId m_firmware_variation_id{};
|
||||
private:
|
||||
ALWAYS_INLINE Result SetLastResultOnFailure(Result result) {
|
||||
if (R_FAILED(result)) {
|
||||
this->SetLastResult(result);
|
||||
}
|
||||
R_RETURN(result);
|
||||
}
|
||||
public:
|
||||
InstallTaskBase() : m_data(), m_progress(), m_progress_mutex(), m_cancel_mutex(), m_cancel_requested(), m_throughput_mutex() { /* ... */ }
|
||||
virtual ~InstallTaskBase() { /* ... */ };
|
||||
public:
|
||||
virtual void Cancel();
|
||||
virtual void ResetCancel();
|
||||
|
||||
Result Prepare();
|
||||
Result GetPreparedPlaceHolderPath(Path *out_path, u64 id, ContentMetaType meta_type, ContentType type);
|
||||
Result CalculateRequiredSize(s64 *out_size);
|
||||
Result Cleanup();
|
||||
Result ListContentMetaKey(s32 *out_keys_written, StorageContentMetaKey *out_keys, s32 out_keys_count, s32 offset, ListContentMetaKeyFilter filter);
|
||||
Result ListContentMetaKey(s32 *out_keys_written, StorageContentMetaKey *out_keys, s32 out_keys_count, s32 offset) { R_RETURN(this->ListContentMetaKey(out_keys_written, out_keys, out_keys_count, offset, ListContentMetaKeyFilter::All)); }
|
||||
Result ListApplicationContentMetaKey(s32 *out_keys_written, ApplicationContentMetaKey *out_keys, s32 out_keys_count, s32 offset);
|
||||
Result Execute();
|
||||
Result PrepareAndExecute();
|
||||
Result Commit(const StorageContentMetaKey *keys, s32 num_keys);
|
||||
Result Commit() { R_RETURN(this->Commit(nullptr, 0)); }
|
||||
virtual InstallProgress GetProgress();
|
||||
void ResetLastResult();
|
||||
Result IncludesExFatDriver(bool *out);
|
||||
InstallThroughput GetThroughput();
|
||||
Result CalculateContentsSize(s64 *out_size, const ContentMetaKey &key, StorageId storage_id);
|
||||
Result ListOccupiedSize(s32 *out_written, InstallTaskOccupiedSize *out_list, s32 out_list_size, s32 offset);
|
||||
|
||||
Result FindMaxRequiredApplicationVersion(u32 *out);
|
||||
Result FindMaxRequiredSystemVersion(u32 *out);
|
||||
protected:
|
||||
Result Initialize(StorageId install_storage, InstallTaskDataBase *data, u32 config);
|
||||
|
||||
Result PrepareContentMeta(const InstallContentMetaInfo &meta_info, util::optional<ContentMetaKey> key, util::optional<u32> source_version);
|
||||
Result PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer);
|
||||
Result WritePlaceHolderBuffer(InstallContentInfo *content_info, const void *data, size_t data_size);
|
||||
void PrepareAgain();
|
||||
|
||||
Result CountInstallContentMetaData(s32 *out_count);
|
||||
Result GetInstallContentMetaData(InstallContentMeta *out_content_meta, s32 index);
|
||||
Result DeleteInstallContentMetaData(const ContentMetaKey *keys, s32 num_keys);
|
||||
virtual Result GetInstallContentMetaInfo(InstallContentMetaInfo *out_info, const ContentMetaKey &key) = 0;
|
||||
|
||||
virtual Result PrepareDependency();
|
||||
Result PrepareSystemUpdateDependency();
|
||||
virtual Result PrepareContentMetaIfLatest(const ContentMetaKey &key); /* NOTE: This is not virtual in Nintendo's code. We do so to facilitate downgrades. */
|
||||
u32 GetConfig() const { return m_config; }
|
||||
Result WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, util::optional<bool> is_temporary);
|
||||
|
||||
StorageId GetInstallStorage() const { return m_install_storage; }
|
||||
|
||||
virtual Result OnPrepareComplete() { R_SUCCEED(); }
|
||||
|
||||
Result GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out);
|
||||
|
||||
Result CanContinue();
|
||||
private:
|
||||
bool IsCancelRequested();
|
||||
Result PrepareImpl();
|
||||
Result ExecuteImpl();
|
||||
Result CommitImpl(const StorageContentMetaKey *keys, s32 num_keys);
|
||||
Result CleanupOne(const InstallContentMeta &content_meta);
|
||||
|
||||
Result VerifyAllNotCommitted(const StorageContentMetaKey *keys, s32 num_keys);
|
||||
|
||||
virtual Result PrepareInstallContentMetaData() = 0;
|
||||
virtual Result GetLatestVersion(util::optional<u32> *out_version, u64 id) { AMS_UNUSED(out_version, id); R_THROW(ncm::ResultContentMetaNotFound()); }
|
||||
|
||||
virtual Result OnExecuteComplete() { R_SUCCEED(); }
|
||||
|
||||
Result WritePlaceHolder(const ContentMetaKey &key, InstallContentInfo *content_info);
|
||||
virtual Result OnWritePlaceHolder(const ContentMetaKey &key, InstallContentInfo *content_info) = 0;
|
||||
|
||||
bool IsNecessaryInstallTicket(const fs::RightsId &rights_id);
|
||||
virtual Result InstallTicket(const fs::RightsId &rights_id, ContentMetaType meta_type) = 0;
|
||||
|
||||
Result IsNewerThanInstalled(bool *out, const ContentMetaKey &key);
|
||||
Result PreparePlaceHolder();
|
||||
|
||||
void SetProgressState(InstallProgressState state);
|
||||
void IncrementProgress(s64 size);
|
||||
void SetTotalSize(s64 size);
|
||||
void SetLastResult(Result last_result);
|
||||
void CleanupProgress();
|
||||
|
||||
void ResetThroughputMeasurement();
|
||||
void StartThroughputMeasurement();
|
||||
void UpdateThroughputMeasurement(s64 throughput);
|
||||
|
||||
Result GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, util::optional<u32> source_version);
|
||||
|
||||
InstallContentInfo MakeInstallContentInfoFrom(const InstallContentMetaInfo &info, const PlaceHolderId &placeholder_id, util::optional<bool> is_temporary);
|
||||
|
||||
Result ReadContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const ContentMetaKey &key, fs::ContentAttributes attr);
|
||||
Result ListRightsIdsByInstallContentMeta(s32 *out_count, Span<RightsId> out_span, const InstallContentMeta &content_meta, s32 offset);
|
||||
public:
|
||||
virtual Result CheckInstallable() { R_SUCCEED(); }
|
||||
|
||||
void SetFirmwareVariationId(FirmwareVariationId id) { m_firmware_variation_id = id; }
|
||||
Result ListRightsIds(s32 *out_count, Span<RightsId> out_span, const ContentMetaKey &key, s32 offset);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_meta.hpp>
|
||||
#include <stratosphere/ncm/ncm_install_progress.hpp>
|
||||
#include <stratosphere/ncm/ncm_system_update_task_apply_info.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct InstallContentMeta {
|
||||
std::unique_ptr<char[]> data;
|
||||
size_t size;
|
||||
|
||||
InstallContentMetaReader GetReader() const {
|
||||
return InstallContentMetaReader(this->data.get(), this->size);
|
||||
}
|
||||
|
||||
InstallContentMetaWriter GetWriter() const {
|
||||
return InstallContentMetaWriter(this->data.get(), this->size);
|
||||
}
|
||||
};
|
||||
|
||||
class InstallTaskDataBase {
|
||||
public:
|
||||
Result Get(InstallContentMeta *out, s32 index);
|
||||
Result Update(const InstallContentMeta &content_meta, s32 index);
|
||||
Result Has(bool *out, u64 id);
|
||||
public:
|
||||
virtual Result GetProgress(InstallProgress *out_progress) = 0;
|
||||
virtual Result GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out_info) = 0;
|
||||
virtual Result SetState(InstallProgressState state) = 0;
|
||||
virtual Result SetLastResult(Result result) = 0;
|
||||
virtual Result SetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo info) = 0;
|
||||
virtual Result Push(const void *data, size_t data_size) = 0;
|
||||
virtual Result Count(s32 *out) = 0;
|
||||
virtual Result Delete(const ContentMetaKey *keys, s32 num_keys) = 0;
|
||||
virtual Result Cleanup() = 0;
|
||||
private:
|
||||
virtual Result GetSize(size_t *out_size, s32 index) = 0;
|
||||
virtual Result Get(s32 index, void *out, size_t out_size) = 0;
|
||||
virtual Result Update(s32 index, const void *data, size_t data_size) = 0;
|
||||
};
|
||||
|
||||
class MemoryInstallTaskData : public InstallTaskDataBase {
|
||||
private:
|
||||
struct DataHolder : public InstallContentMeta, public util::IntrusiveListBaseNode<DataHolder>{};
|
||||
using DataList = util::IntrusiveListBaseTraits<DataHolder>::ListType;
|
||||
private:
|
||||
DataList m_data_list;
|
||||
InstallProgressState m_state;
|
||||
Result m_last_result;
|
||||
SystemUpdateTaskApplyInfo m_system_update_task_apply_info;
|
||||
public:
|
||||
MemoryInstallTaskData() : m_data_list(), m_state(InstallProgressState::NotPrepared), m_last_result(ResultSuccess()), m_system_update_task_apply_info() { /* ... */ };
|
||||
~MemoryInstallTaskData() {
|
||||
this->Cleanup();
|
||||
}
|
||||
public:
|
||||
virtual Result GetProgress(InstallProgress *out_progress) override;
|
||||
virtual Result GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out_info) override;
|
||||
virtual Result SetState(InstallProgressState state) override;
|
||||
virtual Result SetLastResult(Result result) override;
|
||||
virtual Result SetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo info) override;
|
||||
virtual Result Push(const void *data, size_t data_size) override;
|
||||
virtual Result Count(s32 *out) override;
|
||||
virtual Result Delete(const ContentMetaKey *keys, s32 num_keys) override;
|
||||
virtual Result Cleanup() override;
|
||||
private:
|
||||
virtual Result GetSize(size_t *out_size, s32 index) override;
|
||||
virtual Result Get(s32 index, void *out, size_t out_size) override;
|
||||
virtual Result Update(s32 index, const void *data, size_t data_size) override;
|
||||
};
|
||||
|
||||
class FileInstallTaskData : public InstallTaskDataBase {
|
||||
private:
|
||||
struct Header {
|
||||
u32 max_entries;
|
||||
u32 count;
|
||||
s64 last_data_offset;
|
||||
Result last_result;
|
||||
InstallProgressState progress_state;
|
||||
SystemUpdateTaskApplyInfo system_update_task_apply_info;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Header) == 0x18);
|
||||
|
||||
struct EntryInfo {
|
||||
s64 offset;
|
||||
s64 size;
|
||||
};
|
||||
|
||||
static_assert(sizeof(EntryInfo) == 0x10);
|
||||
private:
|
||||
Header m_header{};
|
||||
char m_path[64]{};
|
||||
private:
|
||||
static constexpr Header MakeInitialHeader(s32 max_entries) {
|
||||
return {
|
||||
.max_entries = static_cast<u32>(max_entries),
|
||||
.count = 0,
|
||||
.last_data_offset = GetEntryInfoOffset(max_entries),
|
||||
.last_result = ResultSuccess(),
|
||||
.progress_state = InstallProgressState::NotPrepared,
|
||||
.system_update_task_apply_info = SystemUpdateTaskApplyInfo::Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
static constexpr s64 GetEntryInfoOffset(s32 index) {
|
||||
return index * sizeof(EntryInfo) + sizeof(Header);
|
||||
}
|
||||
public:
|
||||
static Result Create(const char *path, s32 max_entries);
|
||||
Result Initialize(const char *path);
|
||||
public:
|
||||
virtual Result GetProgress(InstallProgress *out_progress) override;
|
||||
virtual Result GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out_info) override;
|
||||
virtual Result SetState(InstallProgressState state) override;
|
||||
virtual Result SetLastResult(Result result) override;
|
||||
virtual Result SetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo info) override;
|
||||
virtual Result Push(const void *data, size_t data_size) override;
|
||||
virtual Result Count(s32 *out) override;
|
||||
virtual Result Delete(const ContentMetaKey *keys, s32 num_keys) override;
|
||||
virtual Result Cleanup() override;
|
||||
private:
|
||||
virtual Result GetSize(size_t *out_size, s32 index) override;
|
||||
virtual Result Get(s32 index, void *out, size_t out_size) override;
|
||||
virtual Result Update(s32 index, const void *data, size_t data_size) override;
|
||||
|
||||
Result GetEntryInfo(EntryInfo *out_entry_info, s32 index);
|
||||
|
||||
Result Write(const void *data, size_t size, s64 offset);
|
||||
Result Read(void *out, size_t out_size, s64 offset);
|
||||
Result WriteHeader();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_meta_key.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct InstallTaskOccupiedSize {
|
||||
ContentMetaKey key;
|
||||
s64 size;
|
||||
StorageId storage_id;
|
||||
u8 reserved[7];
|
||||
};
|
||||
|
||||
static_assert(sizeof(InstallTaskOccupiedSize) == 0x20);
|
||||
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.hpp>
|
||||
#include <stratosphere/ncm/ncm_i_content_meta_database.hpp>
|
||||
#include <stratosphere/ncm/ncm_integrated_list.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class IntegratedContentMetaDatabaseImpl {
|
||||
NON_COPYABLE(IntegratedContentMetaDatabaseImpl);
|
||||
NON_MOVEABLE(IntegratedContentMetaDatabaseImpl);
|
||||
private:
|
||||
using ListType = ncm::IntegratedList<ncm::IContentMetaDatabase, 2>;
|
||||
using DataType = ListType::ListData;
|
||||
private:
|
||||
os::SdkRecursiveMutex m_mutex;
|
||||
ListType m_list;
|
||||
bool m_disabled;
|
||||
public:
|
||||
IntegratedContentMetaDatabaseImpl() : m_mutex(), m_list(), m_disabled(false) { /* ... */ }
|
||||
|
||||
void Add(sf::SharedPointer<ncm::IContentMetaDatabase> p, u8 id) {
|
||||
DataType data = {std::move(p), id};
|
||||
m_list.Add(data);
|
||||
}
|
||||
private:
|
||||
/* Helpers. */
|
||||
Result EnsureEnabled() const {
|
||||
R_UNLESS(!m_disabled, ncm::ResultInvalidContentMetaDatabase());
|
||||
R_SUCCEED();
|
||||
}
|
||||
public:
|
||||
/* Actual commands. */
|
||||
Result Set(const ContentMetaKey &key, const sf::InBuffer &value);
|
||||
Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, const sf::OutBuffer &out_value);
|
||||
Result Remove(const ContentMetaKey &key);
|
||||
Result GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type);
|
||||
Result ListContentInfo(sf::Out<s32> out_entries_written, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset);
|
||||
Result List(sf::Out<s32> out_entries_total, sf::Out<s32> out_entries_written, const sf::OutArray<ContentMetaKey> &out_info, ContentMetaType meta_type, ApplicationId application_id, u64 min, u64 max, ContentInstallType install_type);
|
||||
Result GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id);
|
||||
Result ListApplication(sf::Out<s32> out_entries_total, sf::Out<s32> out_entries_written, const sf::OutArray<ApplicationContentMetaKey> &out_keys, ContentMetaType meta_type);
|
||||
Result Has(sf::Out<bool> out, const ContentMetaKey &key);
|
||||
Result HasAll(sf::Out<bool> out, const sf::InArray<ContentMetaKey> &keys);
|
||||
Result GetSize(sf::Out<u64> out_size, const ContentMetaKey &key);
|
||||
Result GetRequiredSystemVersion(sf::Out<u32> out_version, const ContentMetaKey &key);
|
||||
Result GetPatchContentMetaId(sf::Out<u64> out_patch_id, const ContentMetaKey &key);
|
||||
Result DisableForcibly();
|
||||
Result LookupOrphanContent(const sf::OutArray<bool> &out_orphaned, const sf::InArray<ContentId> &content_ids);
|
||||
Result Commit();
|
||||
Result HasContent(sf::Out<bool> out, const ContentMetaKey &key, const ContentId &content_id);
|
||||
Result ListContentMetaInfo(sf::Out<s32> out_entries_written, const sf::OutArray<ContentMetaInfo> &out_meta_info, const ContentMetaKey &key, s32 offset);
|
||||
Result GetAttributes(sf::Out<u8> out_attributes, const ContentMetaKey &key);
|
||||
Result GetRequiredApplicationVersion(sf::Out<u32> out_version, const ContentMetaKey &key);
|
||||
Result GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset);
|
||||
Result GetCount(sf::Out<u32> out_count);
|
||||
Result GetOwnerApplicationId(sf::Out<ApplicationId> out_id, const ContentMetaKey &key);
|
||||
Result GetContentAccessibilities(sf::Out<u8> out_accessibilities, const ContentMetaKey &key);
|
||||
Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type);
|
||||
Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset);
|
||||
Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key);
|
||||
Result HasAttributes(sf::Out<u8> out, u8 attr_mask);
|
||||
};
|
||||
static_assert(ncm::IsIContentMetaDatabase<IntegratedContentMetaDatabaseImpl>);
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.hpp>
|
||||
#include <stratosphere/ncm/ncm_i_content_storage.hpp>
|
||||
#include <stratosphere/ncm/ncm_integrated_list.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class IntegratedContentStorageImpl {
|
||||
NON_COPYABLE(IntegratedContentStorageImpl);
|
||||
NON_MOVEABLE(IntegratedContentStorageImpl);
|
||||
private:
|
||||
using ListType = ncm::IntegratedList<ncm::IContentStorage, 2>;
|
||||
using DataType = ListType::ListData;
|
||||
private:
|
||||
os::SdkRecursiveMutex m_mutex;
|
||||
ListType m_list;
|
||||
bool m_disabled;
|
||||
public:
|
||||
IntegratedContentStorageImpl() : m_mutex(), m_list(), m_disabled(false) { /* ... */ }
|
||||
|
||||
void Add(sf::SharedPointer<ncm::IContentStorage> p, u8 id) {
|
||||
DataType data = {std::move(p), id};
|
||||
m_list.Add(data);
|
||||
}
|
||||
private:
|
||||
/* Helpers. */
|
||||
Result EnsureEnabled() const {
|
||||
R_UNLESS(!m_disabled, ncm::ResultInvalidContentStorage());
|
||||
R_SUCCEED();
|
||||
}
|
||||
public:
|
||||
/* Actual commands. */
|
||||
Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out);
|
||||
Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size);
|
||||
Result DeletePlaceHolder(PlaceHolderId placeholder_id);
|
||||
Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id);
|
||||
Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data);
|
||||
Result Register(PlaceHolderId placeholder_id, ContentId content_id);
|
||||
Result Delete(ContentId content_id);
|
||||
Result Has(sf::Out<bool> out, ContentId content_id);
|
||||
Result GetPath(sf::Out<Path> out, ContentId content_id);
|
||||
Result GetPlaceHolderPath(sf::Out<Path> out, PlaceHolderId placeholder_id);
|
||||
Result CleanupAllPlaceHolder();
|
||||
Result ListPlaceHolder(sf::Out<s32> out_count, const sf::OutArray<PlaceHolderId> &out_buf);
|
||||
Result GetContentCount(sf::Out<s32> out_count);
|
||||
Result ListContentId(sf::Out<s32> out_count, const sf::OutArray<ContentId> &out_buf, s32 start_offset);
|
||||
Result GetSizeFromContentId(sf::Out<s64> out_size, ContentId content_id);
|
||||
Result DisableForcibly();
|
||||
Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id);
|
||||
Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size);
|
||||
Result ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset);
|
||||
Result GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id);
|
||||
Result GetRightsIdFromPlaceHolderIdDeprecated2(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id);
|
||||
Result GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, fs::ContentAttributes attr);
|
||||
Result GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id);
|
||||
Result GetRightsIdFromContentIdDeprecated2(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id);
|
||||
Result GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id, fs::ContentAttributes attr);
|
||||
Result WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data);
|
||||
Result GetFreeSpaceSize(sf::Out<s64> out_size);
|
||||
Result GetTotalSpaceSize(sf::Out<s64> out_size);
|
||||
Result FlushPlaceHolder();
|
||||
Result GetSizeFromPlaceHolderId(sf::Out<s64> out, PlaceHolderId placeholder_id);
|
||||
Result RepairInvalidFileAttribute();
|
||||
Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr);
|
||||
Result RegisterPath(const ContentId &content_id, const Path &path);
|
||||
Result ClearRegisteredPath();
|
||||
Result GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr);
|
||||
|
||||
/* 16.0.0 Alignment change hacks. */
|
||||
Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); }
|
||||
Result Register_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id) { R_RETURN(this->Register(placeholder_id, content_id)); }
|
||||
Result RevertToPlaceHolder_AtmosphereAlignmentFix(ncm::ContentId old_content_id, ncm::ContentId new_content_id, ncm::PlaceHolderId placeholder_id) { R_RETURN(this->RevertToPlaceHolder(placeholder_id, old_content_id, new_content_id)); }
|
||||
Result GetRightsIdFromPlaceHolderIdWithCacheDeprecated(sf::Out<ncm::RightsId> out_rights_id, ContentId cache_content_id, PlaceHolderId placeholder_id) { R_RETURN(this->GetRightsIdFromPlaceHolderIdWithCache(out_rights_id, placeholder_id, cache_content_id, fs::ContentAttributes_None)); }
|
||||
};
|
||||
static_assert(ncm::IsIContentStorage<IntegratedContentStorageImpl>);
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/sf/sf_shared_object.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
template<typename T, size_t N>
|
||||
class IntegratedList {
|
||||
static_assert(N <= std::numeric_limits<u8>::max());
|
||||
public:
|
||||
struct ListData {
|
||||
sf::SharedPointer<T> interface;
|
||||
u8 id;
|
||||
};
|
||||
private:
|
||||
size_t m_count;
|
||||
sf::SharedPointer<T> m_interfaces[N];
|
||||
u8 m_ids[N];
|
||||
public:
|
||||
IntegratedList() : m_count(0), m_interfaces(), m_ids() { /* ... */ }
|
||||
|
||||
void Add(ListData &data) {
|
||||
/* Find place to insert into the list. */
|
||||
const size_t pos = std::distance(std::begin(m_ids), std::lower_bound(std::begin(m_ids), std::end(m_ids), data.id));
|
||||
|
||||
/* If we need to, move stuff to make space. */
|
||||
if (m_ids[pos] > data.id) {
|
||||
AMS_ABORT_UNLESS(m_count < N);
|
||||
|
||||
for (size_t i = m_count; i > pos; --i) {
|
||||
m_ids[i] = std::move(m_ids[i - 1]);
|
||||
m_interfaces[i] = std::move(m_interfaces[i - 1]);
|
||||
}
|
||||
|
||||
/* If we're inserting somewhere in the middle, increment count. */
|
||||
m_count++;
|
||||
} else if (m_ids[pos] < data.id) {
|
||||
/* If we're inserting at the end, increment count. */
|
||||
AMS_ABORT_UNLESS(m_count < N);
|
||||
m_count++;
|
||||
}
|
||||
|
||||
/* Set at position. */
|
||||
m_interfaces[pos] = data.interface;
|
||||
m_ids[pos] = data.id;
|
||||
}
|
||||
|
||||
ListData Get(size_t idx) {
|
||||
AMS_ABORT_UNLESS(idx < m_count);
|
||||
|
||||
return { m_interfaces[idx], m_ids[idx] };
|
||||
}
|
||||
|
||||
Result TryEach(auto callback) {
|
||||
Result result = ResultSuccess();
|
||||
for (size_t i = 0; i < m_count; ++i) {
|
||||
result = callback(this->Get(i));
|
||||
if (R_SUCCEEDED(result)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
R_RETURN(result);
|
||||
}
|
||||
|
||||
Result ForAll(auto callback) {
|
||||
for (size_t i = 0; i < m_count; ++i) {
|
||||
R_TRY(callback(this->Get(i)));
|
||||
}
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
size_t GetCount() const { return m_count; }
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_content_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_placeholder_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_path_string.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
using MakeContentPathFunction = void (*)(PathString *out, ContentId content_id, const char *root_path);
|
||||
using MakePlaceHolderPathFunction = void (*)(PathString *out, PlaceHolderId placeholder_id,const char *root_path);
|
||||
|
||||
void MakeFlatContentFilePath(PathString *out, ContentId content_id, const char *root_path);
|
||||
void MakeSha256HierarchicalContentFilePath_ForFat4KCluster(PathString *out, ContentId content_id, const char *root_path);
|
||||
void MakeSha256HierarchicalContentFilePath_ForFat16KCluster(PathString *out, ContentId content_id, const char *root_path);
|
||||
void MakeSha256HierarchicalContentFilePath_ForFat32KCluster(PathString *out, ContentId content_id, const char *root_path);
|
||||
|
||||
size_t GetHierarchicalContentDirectoryDepth(MakeContentPathFunction func);
|
||||
|
||||
void MakeFlatPlaceHolderFilePath(PathString *out, PlaceHolderId placeholder_id, const char *root_path);
|
||||
void MakeSha256HierarchicalPlaceHolderFilePath_ForFat16KCluster(PathString *out, PlaceHolderId placeholder_id, const char *root_pathroot);
|
||||
|
||||
size_t GetHierarchicalPlaceHolderDirectoryDepth(MakePlaceHolderPathFunction func);
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct MappedMemory {
|
||||
u64 id;
|
||||
size_t offset;
|
||||
u8 *buffer;
|
||||
size_t buffer_size;
|
||||
|
||||
bool IsIncluded(size_t o, size_t sz) const {
|
||||
return this->offset <= o && sz <= this->buffer_size && (o + sz) <= (this->offset + this->buffer_size);
|
||||
}
|
||||
|
||||
u8 *GetBuffer(size_t o, size_t sz) const {
|
||||
AMS_ASSERT(this->buffer != nullptr);
|
||||
AMS_ASSERT(this->IsIncluded(o, sz));
|
||||
AMS_UNUSED(sz);
|
||||
|
||||
return this->buffer + (o - this->offset);
|
||||
}
|
||||
};
|
||||
static_assert(util::is_pod<MappedMemory>::value);
|
||||
|
||||
class IMapper {
|
||||
public:
|
||||
virtual ~IMapper() { /* ... */ }
|
||||
public:
|
||||
virtual Result GetMappedMemory(MappedMemory *out, size_t offset, size_t size) = 0;
|
||||
virtual Result MarkUsing(u64 id) = 0;
|
||||
virtual Result UnmarkUsing(u64 id) = 0;
|
||||
virtual Result MarkDirty(u64 id) = 0;
|
||||
protected:
|
||||
virtual Result MapImpl(MappedMemory *out, Span<u8> data, size_t offset, size_t size) = 0;
|
||||
virtual Result UnmapImpl(MappedMemory *mem) = 0;
|
||||
virtual bool IsAccessibleSizeUpdatable() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
constexpr inline s32 SystemMaxContentMetaCount = 0x800;
|
||||
constexpr inline s32 GameCardMaxContentMetaCount = 0x800;
|
||||
constexpr inline s32 HostMaxContentMetaCount = 0x800;
|
||||
constexpr inline s32 UserMaxContentMetaCount = 0x2000;
|
||||
constexpr inline s32 SdCardMaxContentMetaCount = 0x2000;
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/os.hpp>
|
||||
#include <stratosphere/lmem/lmem_common.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct MemoryResourceState {
|
||||
size_t peak_total_alloc_size;
|
||||
size_t peak_alloc_size;
|
||||
size_t allocatable_size;
|
||||
size_t total_free_size;
|
||||
};
|
||||
|
||||
static_assert(sizeof(MemoryResourceState) == 0x20);
|
||||
|
||||
struct MemoryReport {
|
||||
MemoryResourceState system_content_meta_resource_state;
|
||||
MemoryResourceState sd_and_user_content_meta_resource_state;
|
||||
MemoryResourceState gamecard_content_meta_resource_state;
|
||||
MemoryResourceState heap_resource_state;
|
||||
};
|
||||
|
||||
static_assert(sizeof(MemoryReport) == 0x80);
|
||||
|
||||
class HeapState {
|
||||
private:
|
||||
os::SdkMutex m_mutex;
|
||||
lmem::HeapHandle m_heap_handle;
|
||||
size_t m_total_alloc_size;
|
||||
size_t m_peak_total_alloc_size;
|
||||
size_t m_peak_alloc_size;
|
||||
public:
|
||||
constexpr HeapState() : m_mutex(), m_heap_handle(nullptr), m_total_alloc_size(0), m_peak_total_alloc_size(0), m_peak_alloc_size(0) { /* ... */ }
|
||||
|
||||
void Initialize(lmem::HeapHandle heap_handle);
|
||||
void Allocate(size_t size);
|
||||
void Free(size_t size);
|
||||
void GetMemoryResourceState(MemoryResourceState *out);
|
||||
};
|
||||
|
||||
HeapState &GetHeapState();
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_package_install_task_base.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class PackageInstallTask : public PackageInstallTaskBase {
|
||||
private:
|
||||
MemoryInstallTaskData m_data{};
|
||||
public:
|
||||
Result Initialize(const char *package_root, 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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 m_package_root;
|
||||
void *m_buffer{};
|
||||
size_t m_buffer_size{};
|
||||
public:
|
||||
PackageInstallTaskBase() : m_package_root() { /* ... */ }
|
||||
|
||||
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 m_package_root.Get();
|
||||
}
|
||||
private:
|
||||
virtual Result OnWritePlaceHolder(const ContentMetaKey &key, InstallContentInfo *content_info) override;
|
||||
virtual Result InstallTicket(const fs::RightsId &rights_id, ContentMetaType meta_type) override;
|
||||
|
||||
void CreateContentMetaPath(PackagePath *out_path, ContentId content_id);
|
||||
void CreateContentPath(PackagePath *out_path, ContentId content_id);
|
||||
void CreateTicketPath(PackagePath *out_path, fs::RightsId id);
|
||||
void CreateCertificatePath(PackagePath *out_path, fs::RightsId id);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_package_system_update_task.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class PackageSystemDowngradeTask : public PackageSystemUpdateTask {
|
||||
public:
|
||||
Result Commit();
|
||||
protected:
|
||||
virtual Result PrepareContentMetaIfLatest(const ContentMetaKey &key) override;
|
||||
private:
|
||||
Result PreCommit();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_package_install_task_base.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class PackageSystemUpdateTask : public PackageInstallTaskBase {
|
||||
private:
|
||||
using PackagePath = kvdb::BoundedString<0x100>;
|
||||
private:
|
||||
PackagePath m_context_path{};
|
||||
FileInstallTaskData m_data{};
|
||||
ContentMetaDatabase m_package_db{};
|
||||
bool m_gamecard_content_meta_database_active{};
|
||||
public:
|
||||
~PackageSystemUpdateTask();
|
||||
|
||||
void Inactivate();
|
||||
Result Initialize(const char *package_root, const char *context_path, void *buffer, size_t buffer_size, bool requires_exfat_driver, FirmwareVariationId firmware_variation_id);
|
||||
util::optional<ContentMetaKey> GetSystemUpdateMetaKey();
|
||||
protected:
|
||||
virtual Result PrepareInstallContentMetaData() override;
|
||||
virtual Result GetInstallContentMetaInfo(InstallContentMetaInfo *out, const ContentMetaKey &key) override;
|
||||
InstallTaskDataBase &GetInstallData() { return m_data; } /* Atmosphere extension. */
|
||||
private:
|
||||
virtual Result PrepareDependency() override;
|
||||
|
||||
Result GetContentInfoOfContentMeta(ContentInfo *out, const ContentMetaKey &key);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/fs/fs_directory.hpp>
|
||||
#include <stratosphere/sf/sf_buffer_tags.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct alignas(4) Path : ams::sf::LargeData {
|
||||
char str[fs::EntryNameLengthMax];
|
||||
|
||||
static constexpr Path Encode(const char *p) {
|
||||
Path path = {};
|
||||
/* Copy C string to path, terminating when a null byte is found. */
|
||||
for (size_t i = 0; i < sizeof(path) - 1; i++) {
|
||||
path.str[i] = p[i];
|
||||
if (p[i] == '\x00') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/fs/fs_directory.hpp>
|
||||
#include <stratosphere/kvdb/kvdb_bounded_string.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
using PathString = kvdb::BoundedString<fs::EntryNameLengthMax>;
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct PlaceHolderId {
|
||||
util::Uuid uuid;
|
||||
|
||||
bool operator==(const PlaceHolderId &other) const {
|
||||
return this->uuid == other.uuid;
|
||||
}
|
||||
|
||||
bool operator!=(const PlaceHolderId &other) const {
|
||||
return this->uuid != other.uuid;
|
||||
}
|
||||
|
||||
bool operator==(const util::Uuid &other) const {
|
||||
return this->uuid == other;
|
||||
}
|
||||
|
||||
bool operator!=(const util::Uuid &other) const {
|
||||
return this->uuid != other;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(alignof(PlaceHolderId) == 1);
|
||||
|
||||
constexpr inline PlaceHolderId InvalidPlaceHolderId = { util::InvalidUuid };
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct ProgramId {
|
||||
u64 value;
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
inline explicit operator svc::ProgramId() const {
|
||||
static_assert(sizeof(value) == sizeof(svc::ProgramId));
|
||||
return { this->value };
|
||||
}
|
||||
#endif
|
||||
|
||||
constexpr inline auto operator<=>(const ProgramId &) const = default;
|
||||
};
|
||||
|
||||
inline constexpr const ProgramId InvalidProgramId = {};
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_program_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_storage_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct ProgramLocation {
|
||||
ProgramId program_id;
|
||||
u8 storage_id;
|
||||
|
||||
static constexpr ProgramLocation Make(ProgramId program_id, StorageId storage_id) {
|
||||
return { .program_id = program_id, .storage_id = static_cast<u8>(storage_id), };
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ProgramLocation) == 0x10 && util::is_pod<ProgramLocation>::value);
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/os.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_path.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class RegisteredHostContent {
|
||||
NON_COPYABLE(RegisteredHostContent);
|
||||
NON_MOVEABLE(RegisteredHostContent);
|
||||
private:
|
||||
class RegisteredPath;
|
||||
private:
|
||||
using RegisteredPathList = ams::util::IntrusiveListBaseTraits<RegisteredPath>::ListType;
|
||||
private:
|
||||
os::SdkMutex m_mutex;
|
||||
RegisteredPathList m_path_list;
|
||||
public:
|
||||
RegisteredHostContent() : m_mutex(), m_path_list() { /* ... */ }
|
||||
~RegisteredHostContent();
|
||||
|
||||
Result RegisterPath(const ncm::ContentId &content_id, const ncm::Path &path);
|
||||
Result GetPath(Path *out, const ncm::ContentId &content_id);
|
||||
void ClearPaths();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
#include <stratosphere/fs/fs_rights_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct RightsId {
|
||||
fs::RightsId id;
|
||||
u8 key_generation;
|
||||
u8 reserved[7];
|
||||
};
|
||||
static_assert(sizeof(RightsId) == 0x18);
|
||||
static_assert(util::is_pod<RightsId>::value);
|
||||
|
||||
inline bool operator==(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::tie(lhs.id, lhs.key_generation) == std::tie(rhs.id, rhs.key_generation);
|
||||
}
|
||||
|
||||
inline bool operator!=(const RightsId &lhs, const RightsId &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const RightsId &lhs, const RightsId &rhs) {
|
||||
return std::tie(lhs.id, lhs.key_generation) < std::tie(rhs.id, rhs.key_generation);
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/os.hpp>
|
||||
#include <stratosphere/ncm/ncm_rights_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class RightsIdCache {
|
||||
NON_COPYABLE(RightsIdCache);
|
||||
NON_MOVEABLE(RightsIdCache);
|
||||
private:
|
||||
static constexpr size_t MaxEntries = 0x80;
|
||||
private:
|
||||
struct Entry {
|
||||
public:
|
||||
util::Uuid uuid;
|
||||
ncm::RightsId rights_id;
|
||||
u64 last_accessed;
|
||||
};
|
||||
private:
|
||||
Entry m_entries[MaxEntries];
|
||||
u64 m_counter;
|
||||
os::SdkMutex m_mutex;
|
||||
public:
|
||||
RightsIdCache() : m_entries(), m_counter(2), m_mutex() {
|
||||
this->Invalidate();
|
||||
}
|
||||
|
||||
void Invalidate() {
|
||||
m_counter = 2;
|
||||
for (size_t i = 0; i < MaxEntries; i++) {
|
||||
m_entries[i].last_accessed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Store(ContentId content_id, ncm::RightsId rights_id) {
|
||||
std::scoped_lock lk(m_mutex);
|
||||
Entry *eviction_candidate = std::addressof(m_entries[0]);
|
||||
|
||||
/* Find a suitable existing entry to store our new one at. */
|
||||
for (size_t i = 1; i < MaxEntries; i++) {
|
||||
Entry *entry = std::addressof(m_entries[i]);
|
||||
|
||||
/* Change eviction candidates if the uuid already matches ours, or if the uuid doesn't already match and the last_accessed count is lower */
|
||||
if (content_id == entry->uuid || (content_id != eviction_candidate->uuid && entry->last_accessed < eviction_candidate->last_accessed)) {
|
||||
eviction_candidate = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the cache. */
|
||||
eviction_candidate->uuid = content_id.uuid;
|
||||
eviction_candidate->rights_id = rights_id;
|
||||
eviction_candidate->last_accessed = m_counter++;
|
||||
}
|
||||
|
||||
bool Find(ncm::RightsId *out_rights_id, ContentId content_id) {
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
/* Attempt to locate the content id in the cache. */
|
||||
for (size_t i = 0; i < MaxEntries; i++) {
|
||||
Entry *entry = std::addressof(m_entries[i]);
|
||||
|
||||
if (entry->last_accessed != 1 && content_id == entry->uuid) {
|
||||
entry->last_accessed = m_counter;
|
||||
m_counter++;
|
||||
*out_rights_id = entry->rights_id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class StorageId : u8 {
|
||||
None = 0,
|
||||
Host = 1,
|
||||
GameCard = 2,
|
||||
BuiltInSystem = 3,
|
||||
BuiltInUser = 4,
|
||||
SdCard = 5,
|
||||
Any = 6,
|
||||
|
||||
/* Aliases. */
|
||||
Card = GameCard,
|
||||
BuildInSystem = BuiltInSystem,
|
||||
BuildInUser = BuiltInUser,
|
||||
};
|
||||
|
||||
constexpr inline bool IsUniqueStorage(StorageId id) {
|
||||
return id != StorageId::None && id != StorageId::Any;
|
||||
}
|
||||
|
||||
constexpr inline bool IsInstallableStorage(StorageId id) {
|
||||
return id == StorageId::BuiltInSystem || id == StorageId::BuiltInUser || id == StorageId::SdCard || id == StorageId::Any;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_storage_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class StorageList {
|
||||
public:
|
||||
static constexpr s32 MaxCount = 10;
|
||||
private:
|
||||
StorageId m_ids[MaxCount];
|
||||
s32 m_count;
|
||||
public:
|
||||
constexpr StorageList() : m_ids(), m_count() { /* ... */ }
|
||||
|
||||
void Push(StorageId storage_id) {
|
||||
AMS_ABORT_UNLESS(m_count < MaxCount);
|
||||
|
||||
for (s32 i = 0; i < MaxCount; i++) {
|
||||
if (m_ids[i] == storage_id) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_ids[m_count++] = storage_id;
|
||||
}
|
||||
|
||||
s32 Count() const {
|
||||
return m_count;
|
||||
}
|
||||
|
||||
StorageId operator[](s32 i) const {
|
||||
AMS_ABORT_UNLESS(i < m_count);
|
||||
return m_ids[i];
|
||||
}
|
||||
};
|
||||
|
||||
constexpr StorageList GetStorageList(StorageId storage_id) {
|
||||
StorageList list;
|
||||
switch (storage_id) {
|
||||
case StorageId::BuiltInSystem:
|
||||
case StorageId::BuiltInUser:
|
||||
case StorageId::SdCard:
|
||||
list.Push(storage_id);
|
||||
break;
|
||||
case StorageId::Any:
|
||||
list.Push(StorageId::SdCard);
|
||||
list.Push(StorageId::BuiltInUser);
|
||||
break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
Result SelectDownloadableStorage(StorageId *out_storage_id, StorageId storage_id, s64 required_size);
|
||||
Result SelectPatchStorage(StorageId *out_storage_id, StorageId storage_id, PatchId patch_id);
|
||||
const char *GetStorageIdString(StorageId storage_id);
|
||||
const char *GetStorageIdStringForPlayReport(StorageId storage_id);
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/fs/common/fs_file_storage.hpp>
|
||||
#include <stratosphere/ncm/ncm_package_install_task.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class SubmissionPackageInstallTask : public PackageInstallTask {
|
||||
private:
|
||||
class Impl;
|
||||
private:
|
||||
std::unique_ptr<Impl> m_impl;
|
||||
public:
|
||||
SubmissionPackageInstallTask();
|
||||
virtual ~SubmissionPackageInstallTask() override;
|
||||
|
||||
Result Initialize(fs::FileHandle handle, StorageId storage_id, void *buffer, size_t buffer_size, bool ignore_ticket = false);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,588 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/ncm/ncm_data_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_program_id.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
struct SystemProgramId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
static const SystemProgramId Start;
|
||||
|
||||
static const SystemProgramId Fs;
|
||||
static const SystemProgramId Loader;
|
||||
static const SystemProgramId Ncm;
|
||||
static const SystemProgramId Pm;
|
||||
static const SystemProgramId Sm;
|
||||
static const SystemProgramId Boot;
|
||||
static const SystemProgramId Usb;
|
||||
static const SystemProgramId Tma;
|
||||
static const SystemProgramId Boot2;
|
||||
static const SystemProgramId Settings;
|
||||
static const SystemProgramId Bus;
|
||||
static const SystemProgramId Bluetooth;
|
||||
static const SystemProgramId Bcat;
|
||||
static const SystemProgramId Dmnt;
|
||||
static const SystemProgramId Friends;
|
||||
static const SystemProgramId Nifm;
|
||||
static const SystemProgramId Ptm;
|
||||
static const SystemProgramId Shell;
|
||||
static const SystemProgramId BsdSockets;
|
||||
static const SystemProgramId Hid;
|
||||
static const SystemProgramId Audio;
|
||||
static const SystemProgramId LogManager;
|
||||
static const SystemProgramId Wlan;
|
||||
static const SystemProgramId Cs;
|
||||
static const SystemProgramId Ldn;
|
||||
static const SystemProgramId NvServices;
|
||||
static const SystemProgramId Pcv;
|
||||
static const SystemProgramId Ppc;
|
||||
static const SystemProgramId NvnFlinger;
|
||||
static const SystemProgramId Pcie;
|
||||
static const SystemProgramId Account;
|
||||
static const SystemProgramId Ns;
|
||||
static const SystemProgramId Nfc;
|
||||
static const SystemProgramId Psc;
|
||||
static const SystemProgramId CapSrv;
|
||||
static const SystemProgramId Am;
|
||||
static const SystemProgramId Ssl;
|
||||
static const SystemProgramId Nim;
|
||||
static const SystemProgramId Cec;
|
||||
static const SystemProgramId Tspm;
|
||||
static const SystemProgramId Spl;
|
||||
static const SystemProgramId Lbl;
|
||||
static const SystemProgramId Btm;
|
||||
static const SystemProgramId Erpt;
|
||||
static const SystemProgramId Time;
|
||||
static const SystemProgramId Vi;
|
||||
static const SystemProgramId Pctl;
|
||||
static const SystemProgramId Npns;
|
||||
static const SystemProgramId Eupld;
|
||||
static const SystemProgramId Arp;
|
||||
static const SystemProgramId Glue;
|
||||
static const SystemProgramId Eclct;
|
||||
static const SystemProgramId Es;
|
||||
static const SystemProgramId Fatal;
|
||||
static const SystemProgramId Grc;
|
||||
static const SystemProgramId Creport;
|
||||
static const SystemProgramId Ro;
|
||||
static const SystemProgramId Profiler;
|
||||
static const SystemProgramId Sdb;
|
||||
static const SystemProgramId Migration;
|
||||
static const SystemProgramId Jit;
|
||||
static const SystemProgramId JpegDec;
|
||||
static const SystemProgramId SafeMode;
|
||||
static const SystemProgramId Olsc;
|
||||
static const SystemProgramId Dt;
|
||||
static const SystemProgramId Nd;
|
||||
static const SystemProgramId Ngct;
|
||||
static const SystemProgramId Pgl;
|
||||
static const SystemProgramId Omm;
|
||||
static const SystemProgramId Eth;
|
||||
static const SystemProgramId Ngc;
|
||||
|
||||
static const SystemProgramId End;
|
||||
|
||||
static const SystemProgramId Manu;
|
||||
static const SystemProgramId Htc;
|
||||
static const SystemProgramId DmntGen2;
|
||||
static const SystemProgramId DevServer;
|
||||
};
|
||||
|
||||
struct AtmosphereProgramId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator SystemProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return static_cast<SystemProgramId>(*this);
|
||||
}
|
||||
|
||||
static const AtmosphereProgramId Mitm;
|
||||
static const AtmosphereProgramId AtmosphereLogManager;
|
||||
static const AtmosphereProgramId AtmosphereMemlet;
|
||||
};
|
||||
|
||||
inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul };
|
||||
inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereLogManager = { 0x0100000000000420ul };
|
||||
inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereMemlet = { 0x0100000000000421ul };
|
||||
|
||||
inline constexpr bool IsAtmosphereProgramId(const ProgramId &program_id) {
|
||||
return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager || program_id == AtmosphereProgramId::AtmosphereMemlet;
|
||||
}
|
||||
|
||||
inline constexpr bool IsSystemProgramId(const AtmosphereProgramId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline constexpr const SystemProgramId SystemProgramId::Start = { 0x0100000000000000ul };
|
||||
|
||||
inline constexpr const SystemProgramId SystemProgramId::Fs = { 0x0100000000000000ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Loader = { 0x0100000000000001ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ncm = { 0x0100000000000002ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Pm = { 0x0100000000000003ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Sm = { 0x0100000000000004ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Boot = { 0x0100000000000005ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Usb = { 0x0100000000000006ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Tma = { 0x0100000000000007ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Boot2 = { 0x0100000000000008ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Settings = { 0x0100000000000009ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Bus = { 0x010000000000000Aul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Bluetooth = { 0x010000000000000Bul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Bcat = { 0x010000000000000Cul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Dmnt = { 0x010000000000000Dul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Friends = { 0x010000000000000Eul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Nifm = { 0x010000000000000Ful };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ptm = { 0x0100000000000010ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Shell = { 0x0100000000000011ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::BsdSockets = { 0x0100000000000012ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Hid = { 0x0100000000000013ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Audio = { 0x0100000000000014ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::LogManager = { 0x0100000000000015ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Wlan = { 0x0100000000000016ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Cs = { 0x0100000000000017ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ldn = { 0x0100000000000018ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::NvServices = { 0x0100000000000019ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Pcv = { 0x010000000000001Aul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ppc = { 0x010000000000001Bul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::NvnFlinger = { 0x010000000000001Cul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Pcie = { 0x010000000000001Dul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Account = { 0x010000000000001Eul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ns = { 0x010000000000001Ful };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Nfc = { 0x0100000000000020ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Psc = { 0x0100000000000021ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::CapSrv = { 0x0100000000000022ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Am = { 0x0100000000000023ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ssl = { 0x0100000000000024ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Nim = { 0x0100000000000025ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Cec = { 0x0100000000000026ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Tspm = { 0x0100000000000027ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Spl = { 0x0100000000000028ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Lbl = { 0x0100000000000029ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Btm = { 0x010000000000002Aul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Erpt = { 0x010000000000002Bul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Time = { 0x010000000000002Cul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Vi = { 0x010000000000002Dul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Pctl = { 0x010000000000002Eul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Npns = { 0x010000000000002Ful };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Eupld = { 0x0100000000000030ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Arp = { 0x0100000000000031ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Glue = { 0x0100000000000031ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Eclct = { 0x0100000000000032ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Es = { 0x0100000000000033ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Fatal = { 0x0100000000000034ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Grc = { 0x0100000000000035ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Creport = { 0x0100000000000036ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ro = { 0x0100000000000037ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Profiler = { 0x0100000000000038ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Sdb = { 0x0100000000000039ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Migration = { 0x010000000000003Aul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Jit = { 0x010000000000003Bul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::JpegDec = { 0x010000000000003Cul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::SafeMode = { 0x010000000000003Dul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Olsc = { 0x010000000000003Eul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Dt = { 0x010000000000003Ful };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Nd = { 0x0100000000000040ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ngct = { 0x0100000000000041ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Pgl = { 0x0100000000000042ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Omm = { 0x0100000000000045ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Eth = { 0x0100000000000046ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Ngc = { 0x0100000000000050ul };
|
||||
|
||||
inline constexpr const SystemProgramId SystemProgramId::End = { 0x01000000000007FFul };
|
||||
|
||||
inline constexpr const SystemProgramId SystemProgramId::Manu = { 0x010000000000B14Aul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::Htc = { 0x010000000000B240ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::DmntGen2 = { 0x010000000000D609ul };
|
||||
inline constexpr const SystemProgramId SystemProgramId::DevServer = { 0x010000000000D623ul };
|
||||
|
||||
inline constexpr bool IsSystemProgramId(const ProgramId &program_id) {
|
||||
return (SystemProgramId::Start <= program_id && program_id <= SystemProgramId::End) || IsAtmosphereProgramId(program_id);
|
||||
}
|
||||
|
||||
inline constexpr bool IsSystemProgramId(const SystemProgramId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct SystemDataId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator DataId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const SystemDataId &) const = default;
|
||||
constexpr inline bool operator!=(const SystemDataId &) const = default;
|
||||
|
||||
static const SystemDataId Start;
|
||||
|
||||
static const SystemDataId CertStore;
|
||||
static const SystemDataId ErrorMessage;
|
||||
static const SystemDataId MiiModel;
|
||||
static const SystemDataId BrowserDll;
|
||||
static const SystemDataId Help;
|
||||
static const SystemDataId SharedFont;
|
||||
static const SystemDataId NgWord;
|
||||
static const SystemDataId SsidList;
|
||||
static const SystemDataId Dictionary;
|
||||
static const SystemDataId SystemVersion;
|
||||
static const SystemDataId AvatarImage;
|
||||
static const SystemDataId LocalNews;
|
||||
static const SystemDataId Eula;
|
||||
static const SystemDataId UrlBlackList;
|
||||
static const SystemDataId TimeZoneBinar;
|
||||
static const SystemDataId CertStoreCruiser;
|
||||
static const SystemDataId FontNintendoExtension;
|
||||
static const SystemDataId FontStandard;
|
||||
static const SystemDataId FontKorean;
|
||||
static const SystemDataId FontChineseTraditional;
|
||||
static const SystemDataId FontChineseSimple;
|
||||
static const SystemDataId FontBfcpx;
|
||||
static const SystemDataId SystemUpdate;
|
||||
|
||||
static const SystemDataId FirmwareDebugSettings;
|
||||
static const SystemDataId BootImagePackage;
|
||||
static const SystemDataId BootImagePackageSafe;
|
||||
static const SystemDataId BootImagePackageExFat;
|
||||
static const SystemDataId BootImagePackageExFatSafe;
|
||||
static const SystemDataId FatalMessage;
|
||||
static const SystemDataId ControllerIcon;
|
||||
static const SystemDataId PlatformConfigIcosa;
|
||||
static const SystemDataId PlatformConfigCopper;
|
||||
static const SystemDataId PlatformConfigHoag;
|
||||
static const SystemDataId ControllerFirmware;
|
||||
static const SystemDataId NgWord2;
|
||||
static const SystemDataId PlatformConfigIcosaMariko;
|
||||
static const SystemDataId ApplicationBlackList;
|
||||
static const SystemDataId RebootlessSystemUpdateVersion;
|
||||
static const SystemDataId ContentActionTable;
|
||||
|
||||
static const SystemDataId PlatformConfigCalcio;
|
||||
|
||||
static const SystemDataId PlatformConfigAula;
|
||||
|
||||
static const SystemDataId End;
|
||||
};
|
||||
|
||||
inline constexpr const SystemDataId SystemDataId::Start = { 0x0100000000000800ul };
|
||||
inline constexpr const SystemDataId SystemDataId::CertStore = { 0x0100000000000800ul };
|
||||
inline constexpr const SystemDataId SystemDataId::ErrorMessage = { 0x0100000000000801ul };
|
||||
inline constexpr const SystemDataId SystemDataId::MiiModel = { 0x0100000000000802ul };
|
||||
inline constexpr const SystemDataId SystemDataId::BrowserDll = { 0x0100000000000803ul };
|
||||
inline constexpr const SystemDataId SystemDataId::Help = { 0x0100000000000804ul };
|
||||
inline constexpr const SystemDataId SystemDataId::SharedFont = { 0x0100000000000805ul };
|
||||
inline constexpr const SystemDataId SystemDataId::NgWord = { 0x0100000000000806ul };
|
||||
inline constexpr const SystemDataId SystemDataId::SsidList = { 0x0100000000000807ul };
|
||||
inline constexpr const SystemDataId SystemDataId::Dictionary = { 0x0100000000000808ul };
|
||||
inline constexpr const SystemDataId SystemDataId::SystemVersion = { 0x0100000000000809ul };
|
||||
inline constexpr const SystemDataId SystemDataId::AvatarImage = { 0x010000000000080Aul };
|
||||
inline constexpr const SystemDataId SystemDataId::LocalNews = { 0x010000000000080Bul };
|
||||
inline constexpr const SystemDataId SystemDataId::Eula = { 0x010000000000080Cul };
|
||||
inline constexpr const SystemDataId SystemDataId::UrlBlackList = { 0x010000000000080Dul };
|
||||
inline constexpr const SystemDataId SystemDataId::TimeZoneBinar = { 0x010000000000080Eul };
|
||||
inline constexpr const SystemDataId SystemDataId::CertStoreCruiser = { 0x010000000000080Ful };
|
||||
inline constexpr const SystemDataId SystemDataId::FontNintendoExtension = { 0x0100000000000810ul };
|
||||
inline constexpr const SystemDataId SystemDataId::FontStandard = { 0x0100000000000811ul };
|
||||
inline constexpr const SystemDataId SystemDataId::FontKorean = { 0x0100000000000812ul };
|
||||
inline constexpr const SystemDataId SystemDataId::FontChineseTraditional = { 0x0100000000000813ul };
|
||||
inline constexpr const SystemDataId SystemDataId::FontChineseSimple = { 0x0100000000000814ul };
|
||||
inline constexpr const SystemDataId SystemDataId::FontBfcpx = { 0x0100000000000815ul };
|
||||
inline constexpr const SystemDataId SystemDataId::SystemUpdate = { 0x0100000000000816ul };
|
||||
|
||||
inline constexpr const SystemDataId SystemDataId::FirmwareDebugSettings = { 0x0100000000000818ul };
|
||||
inline constexpr const SystemDataId SystemDataId::BootImagePackage = { 0x0100000000000819ul };
|
||||
inline constexpr const SystemDataId SystemDataId::BootImagePackageSafe = { 0x010000000000081Aul };
|
||||
inline constexpr const SystemDataId SystemDataId::BootImagePackageExFat = { 0x010000000000081Bul };
|
||||
inline constexpr const SystemDataId SystemDataId::BootImagePackageExFatSafe = { 0x010000000000081Cul };
|
||||
inline constexpr const SystemDataId SystemDataId::FatalMessage = { 0x010000000000081Dul };
|
||||
inline constexpr const SystemDataId SystemDataId::ControllerIcon = { 0x010000000000081Eul };
|
||||
inline constexpr const SystemDataId SystemDataId::PlatformConfigIcosa = { 0x010000000000081Ful };
|
||||
inline constexpr const SystemDataId SystemDataId::PlatformConfigCopper = { 0x0100000000000820ul };
|
||||
inline constexpr const SystemDataId SystemDataId::PlatformConfigHoag = { 0x0100000000000821ul };
|
||||
inline constexpr const SystemDataId SystemDataId::ControllerFirmware = { 0x0100000000000822ul };
|
||||
inline constexpr const SystemDataId SystemDataId::NgWord2 = { 0x0100000000000823ul };
|
||||
inline constexpr const SystemDataId SystemDataId::PlatformConfigIcosaMariko = { 0x0100000000000824ul };
|
||||
inline constexpr const SystemDataId SystemDataId::ApplicationBlackList = { 0x0100000000000825ul };
|
||||
inline constexpr const SystemDataId SystemDataId::RebootlessSystemUpdateVersion = { 0x0100000000000826ul };
|
||||
inline constexpr const SystemDataId SystemDataId::ContentActionTable = { 0x0100000000000827ul };
|
||||
|
||||
inline constexpr const SystemDataId SystemDataId::PlatformConfigCalcio = { 0x0100000000000829ul };
|
||||
|
||||
inline constexpr const SystemDataId SystemDataId::PlatformConfigAula = { 0x0100000000000831ul };
|
||||
|
||||
inline constexpr const SystemDataId SystemDataId::End = { 0x0100000000000FFFul };
|
||||
|
||||
inline constexpr bool IsSystemDataId(const DataId &data_id) {
|
||||
return SystemDataId::Start <= data_id && data_id <= SystemDataId::End;
|
||||
}
|
||||
|
||||
inline constexpr bool IsSystemDataId(const SystemDataId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct SystemUpdateId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator DataId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const SystemUpdateId &) const = default;
|
||||
constexpr inline bool operator!=(const SystemUpdateId &) const = default;
|
||||
};
|
||||
|
||||
struct SystemAppletId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const SystemAppletId &) const = default;
|
||||
constexpr inline bool operator!=(const SystemAppletId &) const = default;
|
||||
|
||||
static const SystemAppletId Start;
|
||||
|
||||
static const SystemAppletId Qlaunch;
|
||||
static const SystemAppletId Auth;
|
||||
static const SystemAppletId Cabinet;
|
||||
static const SystemAppletId Controller;
|
||||
static const SystemAppletId DataErase;
|
||||
static const SystemAppletId Error;
|
||||
static const SystemAppletId NetConnect;
|
||||
static const SystemAppletId PlayerSelect;
|
||||
static const SystemAppletId Swkbd;
|
||||
static const SystemAppletId MiiEdit;
|
||||
static const SystemAppletId Web;
|
||||
static const SystemAppletId Shop;
|
||||
static const SystemAppletId OverlayDisp;
|
||||
static const SystemAppletId PhotoViewer;
|
||||
static const SystemAppletId Set;
|
||||
static const SystemAppletId OfflineWeb;
|
||||
static const SystemAppletId LoginShare;
|
||||
static const SystemAppletId WifiWebAuth;
|
||||
static const SystemAppletId Starter;
|
||||
static const SystemAppletId MyPage;
|
||||
static const SystemAppletId PlayReport;
|
||||
static const SystemAppletId MaintenanceMenu;
|
||||
|
||||
static const SystemAppletId Gift;
|
||||
static const SystemAppletId DummyShop;
|
||||
static const SystemAppletId UserMigration;
|
||||
static const SystemAppletId Encounter;
|
||||
|
||||
static const SystemAppletId Story;
|
||||
|
||||
static const SystemAppletId End;
|
||||
};
|
||||
|
||||
inline constexpr const SystemAppletId SystemAppletId::Start = { 0x0100000000001000ul };
|
||||
|
||||
inline constexpr const SystemAppletId SystemAppletId::Qlaunch = { 0x0100000000001000ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Auth = { 0x0100000000001001ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Cabinet = { 0x0100000000001002ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Controller = { 0x0100000000001003ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::DataErase = { 0x0100000000001004ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Error = { 0x0100000000001005ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::NetConnect = { 0x0100000000001006ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::PlayerSelect = { 0x0100000000001007ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Swkbd = { 0x0100000000001008ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::MiiEdit = { 0x0100000000001009ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Web = { 0x010000000000100Aul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Shop = { 0x010000000000100Bul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::OverlayDisp = { 0x010000000000100Cul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::PhotoViewer = { 0x010000000000100Dul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Set = { 0x010000000000100Eul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::OfflineWeb = { 0x010000000000100Ful };
|
||||
inline constexpr const SystemAppletId SystemAppletId::LoginShare = { 0x0100000000001010ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::WifiWebAuth = { 0x0100000000001011ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Starter = { 0x0100000000001012ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::MyPage = { 0x0100000000001013ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::PlayReport = { 0x0100000000001014ul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::MaintenanceMenu = { 0x0100000000001015ul };
|
||||
|
||||
inline constexpr const SystemAppletId SystemAppletId::Gift = { 0x010000000000101Aul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::DummyShop = { 0x010000000000101Bul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::UserMigration = { 0x010000000000101Cul };
|
||||
inline constexpr const SystemAppletId SystemAppletId::Encounter = { 0x010000000000101Dul };
|
||||
|
||||
inline constexpr const SystemAppletId SystemAppletId::Story = { 0x0100000000001020ul };
|
||||
|
||||
inline constexpr const SystemAppletId SystemAppletId::End = { 0x0100000000001FFFul };
|
||||
|
||||
inline constexpr bool IsSystemAppletId(const ProgramId &program_id) {
|
||||
return SystemAppletId::Start <= program_id && program_id <= SystemAppletId::End;
|
||||
}
|
||||
|
||||
inline constexpr bool IsSystemAppletId(const SystemAppletId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct SystemDebugAppletId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const SystemDebugAppletId &) const = default;
|
||||
constexpr inline bool operator!=(const SystemDebugAppletId &) const = default;
|
||||
|
||||
static const SystemDebugAppletId Start;
|
||||
|
||||
static const SystemDebugAppletId SnapShotDumper;
|
||||
|
||||
static const SystemDebugAppletId End;
|
||||
};
|
||||
|
||||
inline constexpr const SystemDebugAppletId SystemDebugAppletId::Start = { 0x0100000000002000ul };
|
||||
|
||||
inline constexpr const SystemDebugAppletId SystemDebugAppletId::SnapShotDumper = { 0x0100000000002071ul };
|
||||
|
||||
inline constexpr const SystemDebugAppletId SystemDebugAppletId::End = { 0x0100000000002FFFul };
|
||||
|
||||
inline constexpr bool IsSystemDebugAppletId(const ProgramId &program_id) {
|
||||
return SystemDebugAppletId::Start <= program_id && program_id <= SystemDebugAppletId::End;
|
||||
}
|
||||
|
||||
inline constexpr bool IsSystemDebugAppletId(const SystemDebugAppletId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LibraryAppletId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator SystemAppletId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return static_cast<SystemAppletId>(*this);
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const LibraryAppletId &) const = default;
|
||||
constexpr inline bool operator!=(const LibraryAppletId &) const = default;
|
||||
|
||||
static const LibraryAppletId Auth;
|
||||
static const LibraryAppletId Controller;
|
||||
static const LibraryAppletId Error;
|
||||
static const LibraryAppletId PlayerSelect;
|
||||
static const LibraryAppletId Swkbd;
|
||||
static const LibraryAppletId Web;
|
||||
static const LibraryAppletId Shop;
|
||||
static const LibraryAppletId PhotoViewer;
|
||||
static const LibraryAppletId OfflineWeb;
|
||||
static const LibraryAppletId LoginShare;
|
||||
static const LibraryAppletId WifiWebAuth;
|
||||
static const LibraryAppletId MyPage;
|
||||
|
||||
};
|
||||
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::Auth = { SystemAppletId::Auth.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::Controller = { SystemAppletId::Controller.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::Error = { SystemAppletId::Error.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::PlayerSelect = { SystemAppletId::PlayerSelect.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::Swkbd = { SystemAppletId::Swkbd.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::Web = { SystemAppletId::Web.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::Shop = { SystemAppletId::Shop.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::PhotoViewer = { SystemAppletId::PhotoViewer.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::OfflineWeb = { SystemAppletId::OfflineWeb.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::LoginShare = { SystemAppletId::LoginShare.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::WifiWebAuth = { SystemAppletId::WifiWebAuth.value };
|
||||
inline constexpr const LibraryAppletId LibraryAppletId::MyPage = { SystemAppletId::MyPage.value };
|
||||
|
||||
inline constexpr bool IsLibraryAppletId(const ProgramId &id) {
|
||||
return id == LibraryAppletId::Auth ||
|
||||
id == LibraryAppletId::Controller ||
|
||||
id == LibraryAppletId::Error ||
|
||||
id == LibraryAppletId::PlayerSelect ||
|
||||
id == LibraryAppletId::Swkbd ||
|
||||
id == LibraryAppletId::Web ||
|
||||
id == LibraryAppletId::Shop ||
|
||||
id == LibraryAppletId::PhotoViewer ||
|
||||
id == LibraryAppletId::OfflineWeb ||
|
||||
id == LibraryAppletId::LoginShare ||
|
||||
id == LibraryAppletId::WifiWebAuth ||
|
||||
id == LibraryAppletId::MyPage;
|
||||
}
|
||||
|
||||
inline constexpr bool IsLibraryAppletId(const LibraryAppletId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct WebAppletId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator LibraryAppletId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr operator SystemAppletId() const {
|
||||
return static_cast<LibraryAppletId>(*this);
|
||||
}
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return static_cast<SystemAppletId>(*this);
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const WebAppletId &) const = default;
|
||||
constexpr inline bool operator!=(const WebAppletId &) const = default;
|
||||
|
||||
static const WebAppletId Web;
|
||||
static const WebAppletId Shop;
|
||||
static const WebAppletId OfflineWeb;
|
||||
static const WebAppletId LoginShare;
|
||||
static const WebAppletId WifiWebAuth;
|
||||
};
|
||||
|
||||
inline constexpr const WebAppletId WebAppletId::Web = { LibraryAppletId::Web.value };
|
||||
inline constexpr const WebAppletId WebAppletId::Shop = { LibraryAppletId::Shop.value };
|
||||
inline constexpr const WebAppletId WebAppletId::OfflineWeb = { LibraryAppletId::OfflineWeb.value };
|
||||
inline constexpr const WebAppletId WebAppletId::LoginShare = { LibraryAppletId::LoginShare.value };
|
||||
inline constexpr const WebAppletId WebAppletId::WifiWebAuth = { LibraryAppletId::WifiWebAuth.value };
|
||||
|
||||
inline constexpr bool IsWebAppletId(const ProgramId &id) {
|
||||
return id == WebAppletId::Web ||
|
||||
id == WebAppletId::Shop ||
|
||||
id == WebAppletId::OfflineWeb ||
|
||||
id == WebAppletId::LoginShare ||
|
||||
id == WebAppletId::WifiWebAuth;
|
||||
}
|
||||
|
||||
inline constexpr bool IsWebAppletId(const WebAppletId &) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct SystemApplicationId {
|
||||
u64 value;
|
||||
|
||||
constexpr operator ProgramId() const {
|
||||
return { this->value };
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const SystemApplicationId &) const = default;
|
||||
constexpr inline bool operator!=(const SystemApplicationId &) const = default;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <vapours.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class SystemUpdateTaskApplyInfo : u8 {
|
||||
Unknown = 0,
|
||||
RequireReboot = 1,
|
||||
RequireNoReboot = 2,
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user