Implement the NCM sysmodule (closes #91)

* Implement NCM

* Modernize ncm_main

* Remove unnecessary smExit

* Give access to svcCallSecureMonitor

* Stack size bump

* Fix incorrect setup for NandUser's content storage entry

* Fix a potential data abort when flushing the placeholder accessor cache

* Fix HasFile and HasDirectory

* Use r+b, not w+b

* Misc fixes

* errno begone

* Fixed more stdio error handling

* More main fixes

* Various command improvements

* Make dispatch tables great again

* Fix logic inversion

* Fixed content path generation

* Bump heap size, fix CleanupAllPlaceHolder

* Various fixes. Note: This contains debug stuff which will be removed later. I was getting tired of having to cherrypick tiny changes

* Fixed placeholder/content deletion

* Fixed incorrect content manager destruction

* Prevent automatic placeholder creation on open

* Fixed List implementation. Also lots of debug logging.

* Removed debug code

* Added a scope guard for WritePlaceHolder

* Manually prevent placeholder/content appending

* Revert "Removed debug code"

This reverts commit d6ff261fcc.

* Always cache placeholder file. Switch to ftell for preventing appending

* Universally use EnsureEnabled

* Abstract away file writing logic

* Misc cleanup

* Refactor placeholder cacheing

* Remove debug code (again)

* Revert "Remove debug code (again)"

This reverts commit 168447d80e.

* Misc changes

* Fixed file modes

* Fixed ContentId/PlaceHolderId alignment

* Improved type safety

* Fixed reinitialization

* Fixed doubleup on path creation

* Remove debug code

* Fixed 1.0.0 booting

* Correct amount of add on content

* Correct main thread stack size

* lr: Introducing registered data

* Reorder stratosphere Makefile

* Move results to libstrat

* lr: Cleanup lr_redirection

* lr: lr_manager tweaks

* lr: Imrpoved path handling and adjust ResolveAddOnContentPath order

* lr: Organise types

* Add eof newlines

* lr: Eliminate unnecessary vars

* lr: Unnecessary vars 2 electric boogaloo

* lr: Various helpers

* lr: RegisteredLocationResolver helpers

* ncm: Move ncm_types to libstrat

* ncm: Misc cleanup

* Implement NCM

* Modernize ncm_main

* Remove unnecessary smExit

* Give access to svcCallSecureMonitor

* Stack size bump

* Fix incorrect setup for NandUser's content storage entry

* Fix a potential data abort when flushing the placeholder accessor cache

* Fix HasFile and HasDirectory

* Use r+b, not w+b

* Misc fixes

* errno begone

* Fixed more stdio error handling

* More main fixes

* Various command improvements

* Make dispatch tables great again

* Fix logic inversion

* Fixed content path generation

* Bump heap size, fix CleanupAllPlaceHolder

* Various fixes. Note: This contains debug stuff which will be removed later. I was getting tired of having to cherrypick tiny changes

* Fixed placeholder/content deletion

* Fixed incorrect content manager destruction

* Prevent automatic placeholder creation on open

* Fixed List implementation. Also lots of debug logging.

* Removed debug code

* Added a scope guard for WritePlaceHolder

* Manually prevent placeholder/content appending

* Revert "Removed debug code"

This reverts commit d6ff261fcc.

* Always cache placeholder file. Switch to ftell for preventing appending

* Universally use EnsureEnabled

* Abstract away file writing logic

* Misc cleanup

* Refactor placeholder cacheing

* Remove debug code (again)

* Revert "Remove debug code (again)"

This reverts commit 168447d80e.

* Misc changes

* Fixed file modes

* Fixed ContentId/PlaceHolderId alignment

* Improved type safety

* Fixed reinitialization

* Fixed doubleup on path creation

* Remove debug code

* Fixed 1.0.0 booting

* Correct amount of add on content

* Correct main thread stack size

* lr: Introducing registered data

* Reorder stratosphere Makefile

* Move results to libstrat

* lr: Cleanup lr_redirection

* lr: lr_manager tweaks

* lr: Imrpoved path handling and adjust ResolveAddOnContentPath order

* lr: Organise types

* Add eof newlines

* lr: Eliminate unnecessary vars

* lr: Unnecessary vars 2 electric boogaloo

* lr: Various helpers

* lr: RegisteredLocationResolver helpers

* ncm: Move ncm_types to libstrat

* ncm: Misc cleanup

* Updated AddOnContentLocationResolver and RegisteredLocationResolver to 9.0.0

* Finished updating lr to 9.0.0

* Updated NCM to 9.0.0

* Fix libstrat includes

* Fixed application launching

* title_id_2 -> owner_tid

* Updated to new-ipc

* Change to using pure virtuals

* Title Id -> Program Id

* Fixed compilation against master

* std::scoped_lock<> -> std::scoped_lock

* Adopted R_UNLESS and R_CONVERT

* Prefix namespace to Results

* Adopt std::numeric_limits

* Fixed incorrect error handling in ReadFile

* Adopted AMS_ABORT_UNLESS

* Adopt util::GenerateUuid()

* Syntax improvements

* ncm_types: Address review

* Address more review comments

* Updated copyrights

* Address more feedback

* More feedback addressed

* More changes

* Move dispatch tables out of interface files

* Addressed remaining comments

* lr: move into libstratosphere

* ncm: Fix logic inversion

* lr: Add comments

* lr: Remove whitespace

* ncm: Start addressing feedback

* ncm: Cleanup InitializeContentManager

* lr: support client-side usage

* lr_service -> lr_api

* ncm: Begin refactoring content manager

* ncm: More content manager improvements

* ncm: Content manager mount improvements

* ldr: use lr bindings

* lr bindings usage: minor fixes

* ncm/lr: Pointer placement

* ncm: placeholder accessor cleanup

* ncm: minor fixes

* ncm: refactor rights cache

* ncm: content meta database cleanup

* ncm: move content meta database impl out of interface file

* ncm: Use const ContentMetaKey &

* ncm: fix other non-const ContentMetaKey references

* ncm: content meta database cleanup

* ncm: content storage fixes for 2.0.0

* ncm: add missing end of file newlines

* ncm: implement ContentMetaReader

* ncm: client-side api

* ncm: trim trailing spaces

* ncm: FS_MAX_PATH-1 -> fs::EntryNameLengthMax

* ncm: Use PathString and Path

* fs: implement accessor wrappers for ncm

* fs: implement user fs wrappers

* fs: add MountSdCard

* ncm: move to content manager impl

* ncm: fix up main

* kvdb: use fs::

* fs: Add wrappers needed for ncm

* ncm: use fs bindings, other refactoring

* ncm: minor fixes

* fsa: fix ReadFile without size output

* fs: add substorage, rom path tool

* ncm: fix dangling fsdev usage

* fs: fix bug in Commit

* fs: fixed incorrect mode check

* fs: implement Mount(System)Data

* ncm: don't delete hos

* results: add R_SUCCEED_IF

* ams-except-ncm: use R_SUCCEED_IF

* ncm: added comments

* ncm: fix api definitions

* ncm: use R_SUCCEED_IF

* pm: think of the savings

* ncm: employ kernel strats

* ncm: Nintendo has 5 MiB of heap. Give ourselves 4 to be safe, pending analysis

* ncm: refactor IDs, split types header into many headers

* ams.mitm: use fs bindings instead of stdio

* fs: SystemData uses SystemDataId

* ncm: improve meta-db accuracy

* ncm: inline getlatestkey

* fs: improve UnsupportedOperation results

* fs: modernize mount utils

* ams: misc fixes for merge-errors

* fs: improve unsupportedoperation results

* git subrepo pull emummc

subrepo:
  subdir:   "emummc"
  merged:   "d12dd546"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "d12dd546"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"

* util: add boundedmap

* ncm: minor style fixes

* ncm: don't unmount if mounting fails

* lr: bug fixes

* ncm: implement ncm.for-initialize + ncm.for-safemode

* lr: ncm::ProgramId::Invalid -> ncm::InvalidProgramId

* ncm: fix open directory mode on 1.0.0

* ncm: fix fs use, implement more of < 4.0.0 for-initialize/safemode

* ncm: implement packagedcontent -> content for building metadb

* ncm: fix save data flag management

* ncm: address some review suggestions (thanks @leoetlino!)

* updater: use fs bindings

* fs: implement MountCode

* fs: prefer make_unique to operator new

* ncm: implement remaining ContentMetaDatabaseBuilder functionality

Co-authored-by: Michael Scire <SciresM@gmail.com>
This commit is contained in:
Adubbz
2020-03-08 19:06:23 +11:00
committed by GitHub
parent f9403201f0
commit c7026b9094
254 changed files with 16876 additions and 1274 deletions

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/ncm/ncm_content_meta_database.hpp>
#include <stratosphere/ncm/ncm_content_storage.hpp>
#include <stratosphere/ncm/ncm_i_content_manager.hpp>
namespace ams::ncm {
/* Management. */
void Initialize();
void Finalize();
void InitializeWithObject(std::shared_ptr<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();
/* Deprecated API. */
Result CloseContentStorageForcibly(StorageId storage_id);
Result CloseContentMetaDatabaseForcibly(StorageId storage_id);
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2018-2020 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 *buffer;
size_t size;
public:
AutoBuffer() : buffer(nullptr), size(0) { /* ... */ }
~AutoBuffer() {
this->Reset();
}
AutoBuffer(AutoBuffer &&rhs) {
this->buffer = rhs.buffer;
this->size = rhs.size;
rhs.buffer = nullptr;
rhs.size = 0;
}
AutoBuffer& operator=(AutoBuffer &&rhs) {
AutoBuffer(std::move(rhs)).Swap(*this);
return *this;
}
void Swap(AutoBuffer &rhs) {
std::swap(this->buffer, rhs.buffer);
std::swap(this->size, rhs.size);
}
void Reset() {
if (this->buffer != nullptr) {
std::free(this->buffer);
this->buffer = nullptr;
this->size = 0;
}
}
u8 *Get() const {
return this->buffer;
}
size_t GetSize() const {
return this->size;
}
Result Initialize(size_t size) {
/* Check that we're not already initialized. */
AMS_ABORT_UNLESS(this->buffer == nullptr);
/* Allocate a buffer. */
this->buffer = static_cast<u8 *>(std::malloc(size));
R_UNLESS(this->buffer != nullptr, ResultAllocationFailed());
this->size = size;
return ResultSuccess();
}
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(this->buffer, buf, size);
return ResultSuccess();
}
};
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
template<class Key, class Value, size_t N>
using BoundedMap = util::BoundedMap<Key, Value, N>;
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
struct alignas(4) 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) == 4);
constexpr inline ContentId InvalidContentId = { util::InvalidUuid };
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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);
std::optional<ContentId> GetContentIdFromString(const char *str, size_t len);
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/ncm/ncm_content_id.hpp>
#include <stratosphere/ncm/ncm_content_type.hpp>
namespace ams::ncm {
struct ContentInfo {
ContentId content_id;
u32 size_low;
u16 size_high;
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 ContentType GetType() const {
return this->content_type;
}
constexpr u8 GetIdOffset() const {
return this->id_offset;
}
static constexpr ContentInfo Make(ContentId id, u64 size, ContentType type, u8 id_ofs = 0) {
const u32 size_low = size & 0xFFFFFFFFu;
const u16 size_high = static_cast<u16>(size >> 32);
return {
.content_id = id,
.size_low = size_low,
.size_high = size_high,
.content_type = type,
.id_offset = id_ofs,
};
}
};
static_assert(sizeof(std::is_pod<ContentInfo>::value));
static_assert(sizeof(ContentInfo) == 0x18);
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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];
};
struct PackagedContentInfo {
Digest digest;
ContentInfo info;
constexpr const ContentId &GetId() const {
return this->info.GetId();
}
constexpr const ContentType GetType() const {
return this->info.GetType();
}
constexpr const u8 GetIdOffset() const {
return this->info.GetIdOffset();
}
};
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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 *db;
private:
Result BuildFromPackageContentMeta(void *buf, size_t size, const ContentInfo &meta_info);
public:
explicit ContentMetaDatabaseBuilder(ContentMetaDatabase *d) : 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);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
struct ContentManagerConfig {
bool build_system_database;
bool import_database_from_system_on_sd;
bool HasAnyConfig() const {
return this->ShouldBuildDatabase() || this->import_database_from_system_on_sd;
}
bool ShouldBuildDatabase() const {
return hos::GetVersion() < hos::Version_400 || this->build_system_database;
}
bool ShouldImportDatabaseFromSignedSystemPartitionOnSd() const {
return this->import_database_from_system_on_sd;
}
};
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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/kvdb/kvdb_memory_key_value_store.hpp>
namespace ams::ncm {
struct SystemSaveDataInfo {
u64 id;
u64 size;
u64 journal_size;
u32 flags;
fs::SaveDataSpaceId space_id;
};
static_assert(std::is_pod<SystemSaveDataInfo>::value);
class ContentManagerImpl final : public IContentManager {
private:
constexpr static size_t MaxContentStorageRoots = 8;
constexpr static size_t MaxContentMetaDatabaseRoots = 8;
private:
struct ContentStorageRoot {
NON_COPYABLE(ContentStorageRoot);
NON_MOVEABLE(ContentStorageRoot);
char mount_name[fs::MountNameLengthMax + 1];
char path[128];
StorageId storage_id;
fs::ContentStorageId content_storage_id;
std::shared_ptr<IContentStorage> content_storage;
ContentStorageRoot() { /* ... */ }
};
struct ContentMetaDatabaseRoot {
NON_COPYABLE(ContentMetaDatabaseRoot);
NON_MOVEABLE(ContentMetaDatabaseRoot);
char mount_name[fs::MountNameLengthMax + 1];
char path[128];
StorageId storage_id;
SystemSaveDataInfo info;
std::shared_ptr<IContentMetaDatabase> content_meta_database;
std::optional<kvdb::MemoryKeyValueStore<ContentMetaKey>> kvs;
u32 max_content_metas;
ContentMetaDatabaseRoot() { /* ... */ }
};
private:
os::RecursiveMutex mutex;
bool initialized;
ContentStorageRoot content_storage_roots[MaxContentStorageRoots];
ContentMetaDatabaseRoot content_meta_database_roots[MaxContentMetaDatabaseRoots];
u32 num_content_storage_entries;
u32 num_content_meta_entries;
RightsIdCache rights_id_cache;
public:
ContentManagerImpl() : initialized(false) { /* ... */ };
~ContentManagerImpl();
public:
Result Initialize(const ContentManagerConfig &config);
private:
/* Helpers. */
Result GetContentStorageRoot(ContentStorageRoot **out, StorageId id);
Result GetContentMetaDatabaseRoot(ContentMetaDatabaseRoot **out, StorageId id);
Result InitializeContentStorageRoot(ContentStorageRoot *out, StorageId storage_id, fs::ContentStorageId content_storage_id);
Result InitializeGameCardContentStorageRoot(ContentStorageRoot *out);
Result InitializeContentMetaDatabaseRoot(ContentMetaDatabaseRoot *out, StorageId storage_id, const SystemSaveDataInfo &info, size_t max_content_metas);
Result InitializeGameCardContentMetaDatabaseRoot(ContentMetaDatabaseRoot *out, size_t max_content_metas);
Result BuildContentMetaDatabase(StorageId storage_id);
Result ImportContentMetaDatabase(StorageId storage_id, bool from_signed_partition);
Result ImportContentMetaDatabaseImpl(StorageId storage_id, const char *import_mount_name, const char *path);
Result EnsureAndMountSystemSaveData(const char *mount, const SystemSaveDataInfo &info) const;
public:
/* Actual commands. */
virtual Result CreateContentStorage(StorageId storage_id) override;
virtual Result CreateContentMetaDatabase(StorageId storage_id) override;
virtual Result VerifyContentStorage(StorageId storage_id) override;
virtual Result VerifyContentMetaDatabase(StorageId storage_id) override;
virtual Result OpenContentStorage(sf::Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id) override;
virtual Result OpenContentMetaDatabase(sf::Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id) override;
virtual Result CloseContentStorageForcibly(StorageId storage_id) override;
virtual Result CloseContentMetaDatabaseForcibly(StorageId storage_id) override;
virtual Result CleanupContentMetaDatabase(StorageId storage_id) override;
virtual Result ActivateContentStorage(StorageId storage_id) override;
virtual Result InactivateContentStorage(StorageId storage_id) override;
virtual Result ActivateContentMetaDatabase(StorageId storage_id) override;
virtual Result InactivateContentMetaDatabase(StorageId storage_id) override;
virtual Result InvalidateRightsIdCache() override;
};
}

View File

@@ -0,0 +1,315 @@
/*
* Copyright (c) 2018-2020 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_info.hpp>
#include <stratosphere/ncm/ncm_content_info_data.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),
};
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() {
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;
StorageId storage_id;
};
static_assert(sizeof(ContentMetaHeader) == 0x8);
struct PackagedContentMetaHeader {
u64 id;
u32 version;
ContentMetaType type;
u8 reserved_0D;
u16 extended_header_size;
u16 content_count;
u16 content_meta_count;
u8 attributes;
u8 storage_id;
ContentInstallType install_type;
u8 reserved_17;
u32 required_download_system_version;
u8 reserved_1C[4];
};
static_assert(sizeof(PackagedContentMetaHeader) == 0x20);
static_assert(OFFSETOF(PackagedContentMetaHeader, reserved_0D) == 0x0D);
static_assert(OFFSETOF(PackagedContentMetaHeader, reserved_17) == 0x17);
static_assert(OFFSETOF(PackagedContentMetaHeader, reserved_1C) == 0x1C);
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;
u32 padding;
};
struct DeltaMetaExtendedHeader {
ApplicationId application_id;
u32 extended_data_size;
u32 padding;
};
template<typename ContentMetaHeaderType, typename ContentInfoType>
class ContentMetaAccessor {
public:
using HeaderType = ContentMetaHeaderType;
using InfoType = ContentInfoType;
private:
void *data;
const size_t size;
bool 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) : data(const_cast<void *>(d)), size(sz), is_header_valid(true) { /* ... */ }
constexpr ContentMetaAccessor(void *d, size_t sz) : data(d), size(sz), 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>(this->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;
}
public:
const void *GetData() const {
return this->data;
}
size_t GetSize() const {
return this->size;
}
const HeaderType *GetHeader() const {
AMS_ABORT_UNLESS(this->is_header_valid);
return static_cast<const HeaderType *>(this->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;
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;
}
std::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 std::nullopt;
}
}
std::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 CalculateConvertContentMetaSize() const;
void ConvertToContentMeta(void *dst, size_t size, const ContentInfo &meta);
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);
}
};
}

View File

@@ -0,0 +1,194 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/ncm/ncm_i_content_meta_database.hpp>
namespace ams::ncm {
class ContentMetaDatabase {
NON_COPYABLE(ContentMetaDatabase);
public:
struct ListCount {
s32 written;
s32 total;
};
private:
std::shared_ptr<IContentMetaDatabase> interface;
public:
ContentMetaDatabase() { /* ... */ }
explicit ContentMetaDatabase(std::shared_ptr<IContentMetaDatabase> intf) : interface(std::move(intf)) { /* ... */ }
ContentMetaDatabase(ContentMetaDatabase &&rhs) {
this->interface = std::move(rhs.interface);
}
ContentMetaDatabase &operator=(ContentMetaDatabase &&rhs) {
ContentMetaDatabase(std::move(rhs)).Swap(*this);
return *this;
}
void Swap(ContentMetaDatabase &rhs) {
std::swap(this->interface, rhs.interface);
}
public:
Result Set(const ContentMetaKey &key, const void *buf, size_t size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->Set(key, sf::InBuffer(buf, size));
}
Result Get(size_t *out_size, void *dst, size_t dst_size, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
u64 size;
R_TRY(this->interface->Get(std::addressof(size), key, sf::OutBuffer(dst, dst_size)));
*out_size = size;
return ResultSuccess();
}
#define AMS_NCM_DEFINE_GETTERS(Kind, IdType) \
Result Get##Kind(ContentId *out, IdType##Id id, u32 version) { \
return this->interface->GetContentIdByType(out, ContentMetaKey::MakeUnknownType(id.value, version), ContentType::Kind); \
} \
\
Result GetLatest##Kind(ContentId *out, IdType##Id id) { \
ContentMetaKey latest_key; \
R_TRY(this->interface->GetLatestContentMetaKey(std::addressof(latest_key), id.value)); \
return this->interface->GetContentIdByType(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(this->interface != nullptr);
return this->interface->Remove(key);
}
Result Remove(SystemProgramId id, u32 version) {
return this->Remove(ContentMetaKey::Make(id, version));
}
Result Remove(SystemDataId id, u32 version) {
return this->Remove(ContentMetaKey::Make(id, version));
}
Result Remove(ApplicationId id, u32 version) {
return this->Remove(ContentMetaKey::Make(id, version));
}
Result GetContentIdByType(ContentId *out_content_id, const ContentMetaKey &key, ContentType type) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetContentIdByType(out_content_id, key, type);
}
Result GetContentIdByTypeAndIdOffset(ContentId *out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetContentIdByTypeAndIdOffset(out_content_id, key, type, id_offset);
}
ListCount ListApplication(ApplicationContentMetaKey *dst, size_t dst_size) {
ListCount lc = {};
R_ABORT_UNLESS(this->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(this->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(this->interface != nullptr);
return this->interface->GetLatestContentMetaKey(out_key, id);
}
Result ListContentInfo(s32 *out_count, ContentInfo *dst, size_t dst_size, const ContentMetaKey &key, s32 offset) {
AMS_ASSERT(this->interface != nullptr);
return this->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(this->interface != nullptr);
return this->interface->ListContentMetaInfo(out_count, sf::OutArray<ContentMetaInfo>(dst, dst_size), key, offset);
}
Result Has(bool *out, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->Has(out, key);
}
Result HasAll(bool *out, const ContentMetaKey *keys, size_t num_keys) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->HasAll(out, sf::InArray<ContentMetaKey>(keys, num_keys));
}
Result HasContent(bool *out, const ContentMetaKey &key, const ContentId &content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->HasContent(out, key, content_id);
}
Result GetSize(size_t *out_size, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
u64 size;
R_TRY(this->interface->GetSize(std::addressof(size), key));
*out_size = size;
return ResultSuccess();
}
Result GetRequiredSystemVersion(u32 *out_version, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetRequiredSystemVersion(out_version, key);
}
Result GetPatchId(PatchId *out_patch_id, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetPatchId(out_patch_id, key);
}
Result DisableForcibly() {
AMS_ASSERT(this->interface != nullptr);
return this->interface->DisableForcibly();
}
Result LookupOrphanContent(bool *out_orphaned, ContentId *content_list, size_t count) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->LookupOrphanContent(sf::OutArray<bool>(out_orphaned, count), sf::InArray<ContentId>(content_list, count));
}
Result Commit() {
AMS_ASSERT(this->interface != nullptr);
return this->interface->Commit();
}
Result GetAttributes(u8 *out_attributes, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetAttributes(out_attributes, key);
}
Result GetRequiredApplicationVersion(u32 *out_version, const ContentMetaKey &key) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetRequiredApplicationVersion(out_version, key);
}
};
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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 };
}
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 &id) {
return true;
}
struct ApplicationGroupId {
u64 value;
};
struct PatchId {
u64 value;
constexpr operator ProgramId() const {
return { this->value };
}
};
struct PatchGroupId {
u64 value;
};
struct AddOnContentId {
u64 value;
constexpr operator DataId() const {
return { this->value };
}
};
struct DeltaId {
u64 value;
constexpr operator ProgramId() const {
return { this->value };
}
};
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <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);
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <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,
};
const char *GetContentMetaTypeString(ContentMetaType type);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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>
namespace ams::ncm {
Result ReadContentMetaPath(AutoBuffer *out, const char *path);
}

View File

@@ -0,0 +1,200 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/ncm/ncm_i_content_storage.hpp>
namespace ams::ncm {
class ContentStorage {
NON_COPYABLE(ContentStorage);
private:
std::shared_ptr<IContentStorage> interface;
public:
ContentStorage() { /* ... */ }
explicit ContentStorage(std::shared_ptr<IContentStorage> intf) : interface(std::move(intf)) { /* ... */ }
ContentStorage(ContentStorage &&rhs) {
this->interface = std::move(rhs.interface);
}
ContentStorage &operator=(ContentStorage &&rhs) {
ContentStorage(std::move(rhs)).Swap(*this);
return *this;
}
void Swap(ContentStorage &rhs) {
std::swap(this->interface, rhs.interface);
}
public:
PlaceHolderId GeneratePlaceHolderId() {
AMS_ASSERT(this->interface != nullptr);
PlaceHolderId id;
R_ABORT_UNLESS(this->interface->GeneratePlaceHolderId(std::addressof(id)));
return id;
}
Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->CreatePlaceHolder(placeholder_id, content_id, size);
}
Result DeletePlaceHolder(PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->DeletePlaceHolder(placeholder_id);
}
Result HasPlaceHolder(bool *out, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->HasPlaceHolder(out, placeholder_id);
}
Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const void *buf, size_t size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->WritePlaceHolder(placeholder_id, offset, sf::InBuffer(buf, size));
}
Result Register(PlaceHolderId placeholder_id, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->Register(placeholder_id, content_id);
}
Result Delete(ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->Delete(content_id);
}
Result Has(bool *out, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->Has(out, content_id);
}
void GetPath(Path *out, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
R_ABORT_UNLESS(this->interface->GetPath(out, content_id));
}
void GetPlaceHolderPath(Path *out, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr);
R_ABORT_UNLESS(this->interface->GetPlaceHolderPath(out, placeholder_id));
}
Result CleanupAllPlaceHolder() {
AMS_ASSERT(this->interface != nullptr);
return this->interface->CleanupAllPlaceHolder();
}
Result ListPlaceHolder(s32 *out_count, PlaceHolderId *out_list, size_t out_list_size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->ListPlaceHolder(out_count, sf::OutArray<PlaceHolderId>(out_list, out_list_size));
}
Result GetContentCount(s32 *out_count) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetContentCount(out_count);
}
Result ListContentId(s32 *out_count, ContentId *out_list, size_t out_list_size, s32 offset) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->ListContentId(out_count, sf::OutArray<ContentId>(out_list, out_list_size), offset);
}
Result GetSize(s64 *out_size, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetSizeFromContentId(out_size, content_id);
}
Result GetSize(s64 *out_size, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetSizeFromPlaceHolderId(out_size, placeholder_id);
}
Result DisableForcibly() {
AMS_ASSERT(this->interface != nullptr);
return this->interface->DisableForcibly();
}
Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->RevertToPlaceHolder(placeholder_id, old_content_id, new_content_id);
}
Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->SetPlaceHolderSize(placeholder_id, size);
}
Result ReadContentIdFile(void *dst, size_t size, ContentId content_id, s64 offset) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->ReadContentIdFile(sf::OutBuffer(dst, size), content_id, offset);
}
Result GetRightsId(ams::fs::RightsId *out_rights_id, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() < hos::Version_300);
return this->interface->GetRightsIdFromPlaceHolderIdDeprecated(out_rights_id, placeholder_id);
}
Result GetRightsId(ncm::RightsId *out_rights_id, PlaceHolderId placeholder_id) {
AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() >= hos::Version_300);
return this->interface->GetRightsIdFromPlaceHolderId(out_rights_id, placeholder_id);
}
Result GetRightsId(ams::fs::RightsId *out_rights_id, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() < hos::Version_300);
return this->interface->GetRightsIdFromContentIdDeprecated(out_rights_id, content_id);
}
Result GetRightsId(ncm::RightsId *out_rights_id, ContentId content_id) {
AMS_ASSERT(this->interface != nullptr);
AMS_ABORT_UNLESS(hos::GetVersion() >= hos::Version_300);
return this->interface->GetRightsIdFromContentId(out_rights_id, content_id);
}
Result WriteContentForDebug(ContentId content_id, s64 offset, const void *buf, size_t size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->WriteContentForDebug(content_id, offset, sf::InBuffer(buf, size));
}
Result GetFreeSpaceSize(s64 *out_size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetFreeSpaceSize(out_size);
}
Result GetTotalSpaceSize(s64 *out_size) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetTotalSpaceSize(out_size);
}
Result FlushPlaceHolder() {
AMS_ASSERT(this->interface != nullptr);
return this->interface->FlushPlaceHolder();
}
Result RepairInvalidFileAttribute() {
AMS_ASSERT(this->interface != nullptr);
return this->interface->RepairInvalidFileAttribute();
}
Result GetRightsIdFromPlaceHolderIdWithCache(ncm::RightsId *out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id) {
AMS_ASSERT(this->interface != nullptr);
return this->interface->GetRightsIdFromPlaceHolderIdWithCache(out_rights_id, placeholder_id, cache_content_id);
}
};
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
enum class ContentType : u8 {
Meta = 0,
Program = 1,
Data = 2,
Control = 3,
HtmlDocument = 4,
LegalInformation = 5,
DeltaFragment = 6,
};
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
struct DataId {
u64 value;
static const DataId Invalid;
};
inline constexpr bool operator==(const DataId &lhs, const DataId &rhs) {
return lhs.value == rhs.value;
}
inline constexpr bool operator!=(const DataId &lhs, const DataId &rhs) {
return lhs.value != rhs.value;
}
inline constexpr bool operator<(const DataId &lhs, const DataId &rhs) {
return lhs.value < rhs.value;
}
inline constexpr bool operator<=(const DataId &lhs, const DataId &rhs) {
return lhs.value <= rhs.value;
}
inline constexpr bool operator>(const DataId &lhs, const DataId &rhs) {
return lhs.value > rhs.value;
}
inline constexpr bool operator>=(const DataId &lhs, const DataId &rhs) {
return lhs.value >= rhs.value;
}
inline constexpr const DataId DataId::Invalid = {};
inline constexpr const DataId InvalidDataId = DataId::Invalid;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/ncm/ncm_i_content_storage.hpp>
#include <stratosphere/ncm/ncm_i_content_meta_database.hpp>
namespace ams::ncm {
class IContentManager : public sf::IServiceObject {
protected:
enum class CommandId {
CreateContentStorage = 0,
CreateContentMetaDatabase = 1,
VerifyContentStorage = 2,
VerifyContentMetaDatabase = 3,
OpenContentStorage = 4,
OpenContentMetaDatabase = 5,
CloseContentStorageForcibly = 6,
CloseContentMetaDatabaseForcibly = 7,
CleanupContentMetaDatabase = 8,
ActivateContentStorage = 9,
InactivateContentStorage = 10,
ActivateContentMetaDatabase = 11,
InactivateContentMetaDatabase = 12,
InvalidateRightsIdCache = 13,
};
public:
virtual Result CreateContentStorage(StorageId storage_id) = 0;
virtual Result CreateContentMetaDatabase(StorageId storage_id) = 0;
virtual Result VerifyContentStorage(StorageId storage_id) = 0;
virtual Result VerifyContentMetaDatabase(StorageId storage_id) = 0;
virtual Result OpenContentStorage(sf::Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id) = 0;
virtual Result OpenContentMetaDatabase(sf::Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id) = 0;
virtual Result CloseContentStorageForcibly(StorageId storage_id) = 0;
virtual Result CloseContentMetaDatabaseForcibly(StorageId storage_id) = 0;
virtual Result CleanupContentMetaDatabase(StorageId storage_id) = 0;
virtual Result ActivateContentStorage(StorageId storage_id) = 0;
virtual Result InactivateContentStorage(StorageId storage_id) = 0;
virtual Result ActivateContentMetaDatabase(StorageId storage_id) = 0;
virtual Result InactivateContentMetaDatabase(StorageId storage_id) = 0;
virtual Result InvalidateRightsIdCache() = 0;
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(CreateContentStorage),
MAKE_SERVICE_COMMAND_META(CreateContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(VerifyContentStorage),
MAKE_SERVICE_COMMAND_META(VerifyContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(OpenContentStorage),
MAKE_SERVICE_COMMAND_META(OpenContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(CloseContentStorageForcibly, hos::Version_100, hos::Version_100),
MAKE_SERVICE_COMMAND_META(CloseContentMetaDatabaseForcibly, hos::Version_100, hos::Version_100),
MAKE_SERVICE_COMMAND_META(CleanupContentMetaDatabase),
MAKE_SERVICE_COMMAND_META(ActivateContentStorage, hos::Version_200),
MAKE_SERVICE_COMMAND_META(InactivateContentStorage, hos::Version_200),
MAKE_SERVICE_COMMAND_META(ActivateContentMetaDatabase, hos::Version_200),
MAKE_SERVICE_COMMAND_META(InactivateContentMetaDatabase, hos::Version_200),
MAKE_SERVICE_COMMAND_META(InvalidateRightsIdCache, hos::Version_900),
};
};
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/sf.hpp>
#include <stratosphere/ncm/ncm_content_meta.hpp>
namespace ams::ncm {
class IContentMetaDatabase : public sf::IServiceObject {
protected:
enum class CommandId {
Set = 0,
Get = 1,
Remove = 2,
GetContentIdByType = 3,
ListContentInfo = 4,
List = 5,
GetLatestContentMetaKey = 6,
ListApplication = 7,
Has = 8,
HasAll = 9,
GetSize = 10,
GetRequiredSystemVersion = 11,
GetPatchId = 12,
DisableForcibly = 13,
LookupOrphanContent = 14,
Commit = 15,
HasContent = 16,
ListContentMetaInfo = 17,
GetAttributes = 18,
GetRequiredApplicationVersion = 19,
GetContentIdByTypeAndIdOffset = 20,
};
public:
/* Actual commands. */
virtual Result Set(const ContentMetaKey &key, sf::InBuffer value) = 0;
virtual Result Get(sf::Out<u64> out_size, const ContentMetaKey &key, sf::OutBuffer out_value) = 0;
virtual Result Remove(const ContentMetaKey &key) = 0;
virtual Result GetContentIdByType(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type) = 0;
virtual Result ListContentInfo(sf::Out<s32> out_entries_written, const sf::OutArray<ContentInfo> &out_info, const ContentMetaKey &key, s32 offset) = 0;
virtual 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) = 0;
virtual Result GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, u64 id) = 0;
virtual Result ListApplication(sf::Out<s32> out_entries_total, sf::Out<s32> out_entries_written, const sf::OutArray<ApplicationContentMetaKey> &out_keys, ContentMetaType meta_type) = 0;
virtual Result Has(sf::Out<bool> out, const ContentMetaKey &key) = 0;
virtual Result HasAll(sf::Out<bool> out, const sf::InArray<ContentMetaKey> &keys) = 0;
virtual Result GetSize(sf::Out<u64> out_size, const ContentMetaKey &key) = 0;
virtual Result GetRequiredSystemVersion(sf::Out<u32> out_version, const ContentMetaKey &key) = 0;
virtual Result GetPatchId(sf::Out<PatchId> out_patch_id, const ContentMetaKey &key) = 0;
virtual Result DisableForcibly() = 0;
virtual Result LookupOrphanContent(const sf::OutArray<bool> &out_orphaned, const sf::InArray<ContentId> &content_ids) = 0;
virtual Result Commit() = 0;
virtual Result HasContent(sf::Out<bool> out, const ContentMetaKey &key, const ContentId &content_id) = 0;
virtual Result ListContentMetaInfo(sf::Out<s32> out_entries_written, const sf::OutArray<ContentMetaInfo> &out_meta_info, const ContentMetaKey &key, s32 offset) = 0;
virtual Result GetAttributes(sf::Out<u8> out_attributes, const ContentMetaKey &key) = 0;
virtual Result GetRequiredApplicationVersion(sf::Out<u32> out_version, const ContentMetaKey &key) = 0;
virtual Result GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0;
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(Set),
MAKE_SERVICE_COMMAND_META(Get),
MAKE_SERVICE_COMMAND_META(Remove),
MAKE_SERVICE_COMMAND_META(GetContentIdByType),
MAKE_SERVICE_COMMAND_META(ListContentInfo),
MAKE_SERVICE_COMMAND_META(List),
MAKE_SERVICE_COMMAND_META(GetLatestContentMetaKey),
MAKE_SERVICE_COMMAND_META(ListApplication),
MAKE_SERVICE_COMMAND_META(Has),
MAKE_SERVICE_COMMAND_META(HasAll),
MAKE_SERVICE_COMMAND_META(GetSize),
MAKE_SERVICE_COMMAND_META(GetRequiredSystemVersion),
MAKE_SERVICE_COMMAND_META(GetPatchId),
MAKE_SERVICE_COMMAND_META(DisableForcibly),
MAKE_SERVICE_COMMAND_META(LookupOrphanContent),
MAKE_SERVICE_COMMAND_META(Commit),
MAKE_SERVICE_COMMAND_META(HasContent),
MAKE_SERVICE_COMMAND_META(ListContentMetaInfo),
MAKE_SERVICE_COMMAND_META(GetAttributes),
MAKE_SERVICE_COMMAND_META(GetRequiredApplicationVersion, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetContentIdByTypeAndIdOffset, hos::Version_500),
};
};
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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>
namespace ams::ncm {
class IContentStorage : public sf::IServiceObject {
NON_COPYABLE(IContentStorage);
NON_MOVEABLE(IContentStorage);
protected:
enum class CommandId {
GeneratePlaceHolderId = 0,
CreatePlaceHolder = 1,
DeletePlaceHolder = 2,
HasPlaceHolder = 3,
WritePlaceHolder = 4,
Register = 5,
Delete = 6,
Has = 7,
GetPath = 8,
GetPlaceHolderPath = 9,
CleanupAllPlaceHolder = 10,
ListPlaceHolder = 11,
GetContentCount = 12,
ListContentId = 13,
GetSizeFromContentId = 14,
DisableForcibly = 15,
RevertToPlaceHolder = 16,
SetPlaceHolderSize = 17,
ReadContentIdFile = 18,
GetRightsIdFromPlaceHolderIdDeprecated = 19,
GetRightsIdFromPlaceHolderId = 19,
GetRightsIdFromContentIdDeprecated = 20,
GetRightsIdFromContentId = 20,
WriteContentForDebug = 21,
GetFreeSpaceSize = 22,
GetTotalSpaceSize = 23,
FlushPlaceHolder = 24,
GetSizeFromPlaceHolderId = 25,
RepairInvalidFileAttribute = 26,
GetRightsIdFromPlaceHolderIdWithCache = 27,
};
public:
IContentStorage() { /* ... */ }
public:
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) = 0;
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) = 0;
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) = 0;
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) = 0;
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, sf::InBuffer data) = 0;
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) = 0;
virtual Result Delete(ContentId content_id) = 0;
virtual Result Has(sf::Out<bool> out, ContentId content_id) = 0;
virtual Result GetPath(sf::Out<Path> out, ContentId content_id) = 0;
virtual Result GetPlaceHolderPath(sf::Out<Path> out, PlaceHolderId placeholder_id) = 0;
virtual Result CleanupAllPlaceHolder() = 0;
virtual Result ListPlaceHolder(sf::Out<s32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) = 0;
virtual Result GetContentCount(sf::Out<s32> out_count) = 0;
virtual Result ListContentId(sf::Out<s32> out_count, const sf::OutArray<ContentId> &out_buf, s32 start_offset) = 0;
virtual Result GetSizeFromContentId(sf::Out<s64> out_size, ContentId content_id) = 0;
virtual Result DisableForcibly() = 0;
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) = 0;
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) = 0;
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, s64 offset) = 0;
virtual Result GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id) = 0;
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) = 0;
virtual Result GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id) = 0;
virtual Result GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) = 0;
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, sf::InBuffer data) = 0;
virtual Result GetFreeSpaceSize(sf::Out<s64> out_size) = 0;
virtual Result GetTotalSpaceSize(sf::Out<s64> out_size) = 0;
virtual Result FlushPlaceHolder() = 0;
virtual Result GetSizeFromPlaceHolderId(sf::Out<s64> out, PlaceHolderId placeholder_id) = 0;
virtual Result RepairInvalidFileAttribute() = 0;
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id) = 0;
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(GeneratePlaceHolderId),
MAKE_SERVICE_COMMAND_META(CreatePlaceHolder),
MAKE_SERVICE_COMMAND_META(DeletePlaceHolder),
MAKE_SERVICE_COMMAND_META(HasPlaceHolder),
MAKE_SERVICE_COMMAND_META(WritePlaceHolder),
MAKE_SERVICE_COMMAND_META(Register),
MAKE_SERVICE_COMMAND_META(Delete),
MAKE_SERVICE_COMMAND_META(Has),
MAKE_SERVICE_COMMAND_META(GetPath),
MAKE_SERVICE_COMMAND_META(GetPlaceHolderPath),
MAKE_SERVICE_COMMAND_META(CleanupAllPlaceHolder),
MAKE_SERVICE_COMMAND_META(ListPlaceHolder),
MAKE_SERVICE_COMMAND_META(GeneratePlaceHolderId),
MAKE_SERVICE_COMMAND_META(GetContentCount),
MAKE_SERVICE_COMMAND_META(ListContentId),
MAKE_SERVICE_COMMAND_META(GetSizeFromContentId),
MAKE_SERVICE_COMMAND_META(DisableForcibly),
MAKE_SERVICE_COMMAND_META(RevertToPlaceHolder, hos::Version_200),
MAKE_SERVICE_COMMAND_META(SetPlaceHolderSize, hos::Version_200),
MAKE_SERVICE_COMMAND_META(ReadContentIdFile, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdDeprecated, hos::Version_200, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderId, hos::Version_300),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentIdDeprecated, hos::Version_200, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentId, hos::Version_300),
MAKE_SERVICE_COMMAND_META(WriteContentForDebug, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetFreeSpaceSize, hos::Version_200),
MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize, hos::Version_200),
MAKE_SERVICE_COMMAND_META(FlushPlaceHolder, hos::Version_300),
MAKE_SERVICE_COMMAND_META(GetSizeFromPlaceHolderId, hos::Version_400),
MAKE_SERVICE_COMMAND_META(RepairInvalidFileAttribute, hos::Version_400),
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdWithCache, hos::Version_800),
};
};
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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>

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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);
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <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;
}
};
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/fs/fs_directory.hpp>
#include <stratosphere/kvdb/kvdb_bounded_string.hpp>
namespace ams::ncm {
using PathString = kvdb::BoundedString<fs::EntryNameLengthMax>;
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
struct alignas(8) 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) == 8);
constexpr inline PlaceHolderId InvalidPlaceHolderId = { util::InvalidUuid };
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
struct ProgramId {
u64 value;
static const ProgramId Invalid;
inline explicit operator svc::ProgramId() const {
static_assert(sizeof(value) == sizeof(svc::ProgramId));
return { this->value };
}
};
inline constexpr bool operator==(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value == rhs.value;
}
inline constexpr bool operator!=(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value != rhs.value;
}
inline constexpr bool operator<(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value < rhs.value;
}
inline constexpr bool operator<=(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value <= rhs.value;
}
inline constexpr bool operator>(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value > rhs.value;
}
inline constexpr bool operator>=(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value >= rhs.value;
}
inline constexpr const ProgramId ProgramId::Invalid = {};
inline constexpr const ProgramId InvalidProgramId = ProgramId::Invalid;
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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 && std::is_pod<ProgramLocation>::value);
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <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(std::is_pod<RightsId>::value);
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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 entries[MaxEntries];
u64 counter;
os::Mutex mutex;
public:
RightsIdCache() {
this->Invalidate();
}
void Invalidate() {
this->counter = 2;
for (size_t i = 0; i < MaxEntries; i++) {
this->entries[i].last_accessed = 1;
}
}
void Store(ContentId content_id, ncm::RightsId rights_id) {
std::scoped_lock lk(this->mutex);
Entry *eviction_candidate = &this->entries[0];
/* Find a suitable existing entry to store our new one at. */
for (size_t i = 1; i < MaxEntries; i++) {
Entry *entry = &this->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 = this->counter++;
}
bool Find(ncm::RightsId *out_rights_id, ContentId content_id) {
std::scoped_lock lk(this->mutex);
/* Attempt to locate the content id in the cache. */
for (size_t i = 0; i < MaxEntries; i++) {
Entry *entry = &this->entries[i];
if (entry->last_accessed != 1 && content_id == entry->uuid) {
entry->last_accessed = this->counter;
this->counter++;
*out_rights_id = entry->rights_id;
return true;
}
}
return false;
}
};
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::ncm {
enum class StorageId : u8 {
None = 0,
Host = 1,
GameCard = 2,
BuiltInSystem = 3,
BuiltInUser = 4,
SdCard = 5,
Any = 6,
};
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;
}
}

View File

@@ -0,0 +1,509 @@
/*
* Copyright (c) 2019-2020 Adubbz, Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/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 End;
};
struct AtmosphereProgramId {
u64 value;
constexpr operator SystemProgramId() const {
return { this->value };
}
constexpr operator ProgramId() const {
return static_cast<SystemProgramId>(*this);
}
static const AtmosphereProgramId Mitm;
};
inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul };
inline constexpr bool IsAtmosphereProgramId(const ProgramId &program_id) {
return program_id == AtmosphereProgramId::Mitm;
}
inline constexpr bool IsSystemProgramId(const AtmosphereProgramId &program_id) {
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::End = { 0x01000000000007FFul };
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 &program_id) {
return true;
}
struct SystemDataId {
u64 value;
constexpr operator DataId() const {
return { this->value };
}
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 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::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 &data_id) {
return true;
}
struct SystemUpdateId {
u64 value;
constexpr operator DataId() const {
return { this->value };
}
};
struct SystemAppletId {
u64 value;
constexpr operator ProgramId() const {
return { this->value };
}
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 &program_id) {
return true;
}
struct LibraryAppletId {
u64 value;
constexpr operator SystemAppletId() const {
return { this->value };
}
constexpr operator ProgramId() const {
return static_cast<SystemAppletId>(*this);
}
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 &id) {
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);
}
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 &id) {
return true;
}
struct SystemApplicationId {
u64 value;
constexpr operator ProgramId() const {
return { this->value };
}
};
}

View File

@@ -1,447 +0,0 @@
/*
* Copyright (c) 2018-2020 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 {
/* Storage IDs. */
enum class StorageId : u8 {
#define DEFINE_ENUM_MEMBER(nm) nm = NcmStorageId_##nm
DEFINE_ENUM_MEMBER(None),
DEFINE_ENUM_MEMBER(Host),
DEFINE_ENUM_MEMBER(GameCard),
DEFINE_ENUM_MEMBER(BuiltInSystem),
DEFINE_ENUM_MEMBER(BuiltInUser),
DEFINE_ENUM_MEMBER(SdCard),
DEFINE_ENUM_MEMBER(Any),
#undef DEFINE_ENUM_MEMBER
};
/* Program IDs (Formerly: Title IDs). */
struct ProgramId {
svc::ProgramId value;
inline explicit operator svc::ProgramId() const {
return this->value;
}
/* Invalid Program ID. */
static const ProgramId Invalid;
/* System Modules. */
static const ProgramId SystemStart;
static const ProgramId Fs;
static const ProgramId Loader;
static const ProgramId Ncm;
static const ProgramId Pm;
static const ProgramId Sm;
static const ProgramId Boot;
static const ProgramId Usb;
static const ProgramId Tma;
static const ProgramId Boot2;
static const ProgramId Settings;
static const ProgramId Bus;
static const ProgramId Bluetooth;
static const ProgramId Bcat;
static const ProgramId Dmnt;
static const ProgramId Friends;
static const ProgramId Nifm;
static const ProgramId Ptm;
static const ProgramId Shell;
static const ProgramId BsdSockets;
static const ProgramId Hid;
static const ProgramId Audio;
static const ProgramId LogManager;
static const ProgramId Wlan;
static const ProgramId Cs;
static const ProgramId Ldn;
static const ProgramId NvServices;
static const ProgramId Pcv;
static const ProgramId Ppc;
static const ProgramId NvnFlinger;
static const ProgramId Pcie;
static const ProgramId Account;
static const ProgramId Ns;
static const ProgramId Nfc;
static const ProgramId Psc;
static const ProgramId CapSrv;
static const ProgramId Am;
static const ProgramId Ssl;
static const ProgramId Nim;
static const ProgramId Cec;
static const ProgramId Tspm;
static const ProgramId Spl;
static const ProgramId Lbl;
static const ProgramId Btm;
static const ProgramId Erpt;
static const ProgramId Time;
static const ProgramId Vi;
static const ProgramId Pctl;
static const ProgramId Npns;
static const ProgramId Eupld;
static const ProgramId Arp;
static const ProgramId Glue;
static const ProgramId Eclct;
static const ProgramId Es;
static const ProgramId Fatal;
static const ProgramId Grc;
static const ProgramId Creport;
static const ProgramId Ro;
static const ProgramId Profiler;
static const ProgramId Sdb;
static const ProgramId Migration;
static const ProgramId Jit;
static const ProgramId JpegDec;
static const ProgramId SafeMode;
static const ProgramId Olsc;
static const ProgramId Dt;
static const ProgramId Nd;
static const ProgramId Ngct;
static const ProgramId SystemEnd;
/* System Data Archives. */
static const ProgramId ArchiveStart;
static const ProgramId ArchiveCertStore;
static const ProgramId ArchiveErrorMessage;
static const ProgramId ArchiveMiiModel;
static const ProgramId ArchiveBrowserDll;
static const ProgramId ArchiveHelp;
static const ProgramId ArchiveSharedFont;
static const ProgramId ArchiveNgWord;
static const ProgramId ArchiveSsidList;
static const ProgramId ArchiveDictionary;
static const ProgramId ArchiveSystemVersion;
static const ProgramId ArchiveAvatarImage;
static const ProgramId ArchiveLocalNews;
static const ProgramId ArchiveEula;
static const ProgramId ArchiveUrlBlackList;
static const ProgramId ArchiveTimeZoneBinar;
static const ProgramId ArchiveCertStoreCruiser;
static const ProgramId ArchiveFontNintendoExtension;
static const ProgramId ArchiveFontStandard;
static const ProgramId ArchiveFontKorean;
static const ProgramId ArchiveFontChineseTraditional;
static const ProgramId ArchiveFontChineseSimple;
static const ProgramId ArchiveFontBfcpx;
static const ProgramId ArchiveSystemUpdate;
static const ProgramId ArchiveFirmwareDebugSettings;
static const ProgramId ArchiveBootImagePackage;
static const ProgramId ArchiveBootImagePackageSafe;
static const ProgramId ArchiveBootImagePackageExFat;
static const ProgramId ArchiveBootImagePackageExFatSafe;
static const ProgramId ArchiveFatalMessage;
static const ProgramId ArchiveControllerIcon;
static const ProgramId ArchivePlatformConfigIcosa;
static const ProgramId ArchivePlatformConfigCopper;
static const ProgramId ArchivePlatformConfigHoag;
static const ProgramId ArchiveControllerFirmware;
static const ProgramId ArchiveNgWord2;
static const ProgramId ArchivePlatformConfigIcosaMariko;
static const ProgramId ArchiveApplicationBlackList;
static const ProgramId ArchiveRebootlessSystemUpdateVersion;
static const ProgramId ArchiveContentActionTable;
static const ProgramId ArchiveEnd;
/* System Applets. */
static const ProgramId AppletStart;
static const ProgramId AppletQlaunch;
static const ProgramId AppletAuth;
static const ProgramId AppletCabinet;
static const ProgramId AppletController;
static const ProgramId AppletDataErase;
static const ProgramId AppletError;
static const ProgramId AppletNetConnect;
static const ProgramId AppletPlayerSelect;
static const ProgramId AppletSwkbd;
static const ProgramId AppletMiiEdit;
static const ProgramId AppletWeb;
static const ProgramId AppletShop;
static const ProgramId AppletOverlayDisp;
static const ProgramId AppletPhotoViewer;
static const ProgramId AppletSet;
static const ProgramId AppletOfflineWeb;
static const ProgramId AppletLoginShare;
static const ProgramId AppletWifiWebAuth;
static const ProgramId AppletStarter;
static const ProgramId AppletMyPage;
static const ProgramId AppletPlayReport;
static const ProgramId AppletMaintenanceMenu;
static const ProgramId AppletGift;
static const ProgramId AppletDummyShop;
static const ProgramId AppletUserMigration;
static const ProgramId AppletEncounter;
static const ProgramId AppletStory;
static const ProgramId AppletEnd;
/* Debug Applets. */
/* Debug Modules. */
/* Factory Setup. */
/* Applications. */
static const ProgramId ApplicationStart;
static const ProgramId ApplicationEnd;
/* Atmosphere Extensions. */
static const ProgramId AtmosphereMitm;
};
/* Invalid Program ID. */
inline constexpr const ProgramId ProgramId::Invalid = {};
inline constexpr const ProgramId InvalidProgramId = ProgramId::Invalid;
/* System Modules. */
inline constexpr const ProgramId ProgramId::SystemStart = { 0x0100000000000000ul };
inline constexpr const ProgramId ProgramId::Fs = { 0x0100000000000000ul };
inline constexpr const ProgramId ProgramId::Loader = { 0x0100000000000001ul };
inline constexpr const ProgramId ProgramId::Ncm = { 0x0100000000000002ul };
inline constexpr const ProgramId ProgramId::Pm = { 0x0100000000000003ul };
inline constexpr const ProgramId ProgramId::Sm = { 0x0100000000000004ul };
inline constexpr const ProgramId ProgramId::Boot = { 0x0100000000000005ul };
inline constexpr const ProgramId ProgramId::Usb = { 0x0100000000000006ul };
inline constexpr const ProgramId ProgramId::Tma = { 0x0100000000000007ul };
inline constexpr const ProgramId ProgramId::Boot2 = { 0x0100000000000008ul };
inline constexpr const ProgramId ProgramId::Settings = { 0x0100000000000009ul };
inline constexpr const ProgramId ProgramId::Bus = { 0x010000000000000Aul };
inline constexpr const ProgramId ProgramId::Bluetooth = { 0x010000000000000Bul };
inline constexpr const ProgramId ProgramId::Bcat = { 0x010000000000000Cul };
inline constexpr const ProgramId ProgramId::Dmnt = { 0x010000000000000Dul };
inline constexpr const ProgramId ProgramId::Friends = { 0x010000000000000Eul };
inline constexpr const ProgramId ProgramId::Nifm = { 0x010000000000000Ful };
inline constexpr const ProgramId ProgramId::Ptm = { 0x0100000000000010ul };
inline constexpr const ProgramId ProgramId::Shell = { 0x0100000000000011ul };
inline constexpr const ProgramId ProgramId::BsdSockets = { 0x0100000000000012ul };
inline constexpr const ProgramId ProgramId::Hid = { 0x0100000000000013ul };
inline constexpr const ProgramId ProgramId::Audio = { 0x0100000000000014ul };
inline constexpr const ProgramId ProgramId::LogManager = { 0x0100000000000015ul };
inline constexpr const ProgramId ProgramId::Wlan = { 0x0100000000000016ul };
inline constexpr const ProgramId ProgramId::Cs = { 0x0100000000000017ul };
inline constexpr const ProgramId ProgramId::Ldn = { 0x0100000000000018ul };
inline constexpr const ProgramId ProgramId::NvServices = { 0x0100000000000019ul };
inline constexpr const ProgramId ProgramId::Pcv = { 0x010000000000001Aul };
inline constexpr const ProgramId ProgramId::Ppc = { 0x010000000000001Bul };
inline constexpr const ProgramId ProgramId::NvnFlinger = { 0x010000000000001Cul };
inline constexpr const ProgramId ProgramId::Pcie = { 0x010000000000001Dul };
inline constexpr const ProgramId ProgramId::Account = { 0x010000000000001Eul };
inline constexpr const ProgramId ProgramId::Ns = { 0x010000000000001Ful };
inline constexpr const ProgramId ProgramId::Nfc = { 0x0100000000000020ul };
inline constexpr const ProgramId ProgramId::Psc = { 0x0100000000000021ul };
inline constexpr const ProgramId ProgramId::CapSrv = { 0x0100000000000022ul };
inline constexpr const ProgramId ProgramId::Am = { 0x0100000000000023ul };
inline constexpr const ProgramId ProgramId::Ssl = { 0x0100000000000024ul };
inline constexpr const ProgramId ProgramId::Nim = { 0x0100000000000025ul };
inline constexpr const ProgramId ProgramId::Cec = { 0x0100000000000026ul };
inline constexpr const ProgramId ProgramId::Tspm = { 0x0100000000000027ul };
inline constexpr const ProgramId ProgramId::Spl = { 0x0100000000000028ul };
inline constexpr const ProgramId ProgramId::Lbl = { 0x0100000000000029ul };
inline constexpr const ProgramId ProgramId::Btm = { 0x010000000000002Aul };
inline constexpr const ProgramId ProgramId::Erpt = { 0x010000000000002Bul };
inline constexpr const ProgramId ProgramId::Time = { 0x010000000000002Cul };
inline constexpr const ProgramId ProgramId::Vi = { 0x010000000000002Dul };
inline constexpr const ProgramId ProgramId::Pctl = { 0x010000000000002Eul };
inline constexpr const ProgramId ProgramId::Npns = { 0x010000000000002Ful };
inline constexpr const ProgramId ProgramId::Eupld = { 0x0100000000000030ul };
inline constexpr const ProgramId ProgramId::Arp = { 0x0100000000000031ul };
inline constexpr const ProgramId ProgramId::Glue = { 0x0100000000000031ul };
inline constexpr const ProgramId ProgramId::Eclct = { 0x0100000000000032ul };
inline constexpr const ProgramId ProgramId::Es = { 0x0100000000000033ul };
inline constexpr const ProgramId ProgramId::Fatal = { 0x0100000000000034ul };
inline constexpr const ProgramId ProgramId::Grc = { 0x0100000000000035ul };
inline constexpr const ProgramId ProgramId::Creport = { 0x0100000000000036ul };
inline constexpr const ProgramId ProgramId::Ro = { 0x0100000000000037ul };
inline constexpr const ProgramId ProgramId::Profiler = { 0x0100000000000038ul };
inline constexpr const ProgramId ProgramId::Sdb = { 0x0100000000000039ul };
inline constexpr const ProgramId ProgramId::Migration = { 0x010000000000003Aul };
inline constexpr const ProgramId ProgramId::Jit = { 0x010000000000003Bul };
inline constexpr const ProgramId ProgramId::JpegDec = { 0x010000000000003Cul };
inline constexpr const ProgramId ProgramId::SafeMode = { 0x010000000000003Dul };
inline constexpr const ProgramId ProgramId::Olsc = { 0x010000000000003Eul };
inline constexpr const ProgramId ProgramId::Dt = { 0x010000000000003Ful };
inline constexpr const ProgramId ProgramId::Nd = { 0x0100000000000040ul };
inline constexpr const ProgramId ProgramId::Ngct = { 0x0100000000000041ul };
inline constexpr const ProgramId ProgramId::SystemEnd = { 0x01000000000007FFul };
/* System Data Archives. */
inline constexpr const ProgramId ProgramId::ArchiveStart = { 0x0100000000000800ul };
inline constexpr const ProgramId ProgramId::ArchiveCertStore = { 0x0100000000000800ul };
inline constexpr const ProgramId ProgramId::ArchiveErrorMessage = { 0x0100000000000801ul };
inline constexpr const ProgramId ProgramId::ArchiveMiiModel = { 0x0100000000000802ul };
inline constexpr const ProgramId ProgramId::ArchiveBrowserDll = { 0x0100000000000803ul };
inline constexpr const ProgramId ProgramId::ArchiveHelp = { 0x0100000000000804ul };
inline constexpr const ProgramId ProgramId::ArchiveSharedFont = { 0x0100000000000805ul };
inline constexpr const ProgramId ProgramId::ArchiveNgWord = { 0x0100000000000806ul };
inline constexpr const ProgramId ProgramId::ArchiveSsidList = { 0x0100000000000807ul };
inline constexpr const ProgramId ProgramId::ArchiveDictionary = { 0x0100000000000808ul };
inline constexpr const ProgramId ProgramId::ArchiveSystemVersion = { 0x0100000000000809ul };
inline constexpr const ProgramId ProgramId::ArchiveAvatarImage = { 0x010000000000080Aul };
inline constexpr const ProgramId ProgramId::ArchiveLocalNews = { 0x010000000000080Bul };
inline constexpr const ProgramId ProgramId::ArchiveEula = { 0x010000000000080Cul };
inline constexpr const ProgramId ProgramId::ArchiveUrlBlackList = { 0x010000000000080Dul };
inline constexpr const ProgramId ProgramId::ArchiveTimeZoneBinar = { 0x010000000000080Eul };
inline constexpr const ProgramId ProgramId::ArchiveCertStoreCruiser = { 0x010000000000080Ful };
inline constexpr const ProgramId ProgramId::ArchiveFontNintendoExtension = { 0x0100000000000810ul };
inline constexpr const ProgramId ProgramId::ArchiveFontStandard = { 0x0100000000000811ul };
inline constexpr const ProgramId ProgramId::ArchiveFontKorean = { 0x0100000000000812ul };
inline constexpr const ProgramId ProgramId::ArchiveFontChineseTraditional = { 0x0100000000000813ul };
inline constexpr const ProgramId ProgramId::ArchiveFontChineseSimple = { 0x0100000000000814ul };
inline constexpr const ProgramId ProgramId::ArchiveFontBfcpx = { 0x0100000000000815ul };
inline constexpr const ProgramId ProgramId::ArchiveSystemUpdate = { 0x0100000000000816ul };
inline constexpr const ProgramId ProgramId::ArchiveFirmwareDebugSettings = { 0x0100000000000818ul };
inline constexpr const ProgramId ProgramId::ArchiveBootImagePackage = { 0x0100000000000819ul };
inline constexpr const ProgramId ProgramId::ArchiveBootImagePackageSafe = { 0x010000000000081Aul };
inline constexpr const ProgramId ProgramId::ArchiveBootImagePackageExFat = { 0x010000000000081Bul };
inline constexpr const ProgramId ProgramId::ArchiveBootImagePackageExFatSafe = { 0x010000000000081Cul };
inline constexpr const ProgramId ProgramId::ArchiveFatalMessage = { 0x010000000000081Dul };
inline constexpr const ProgramId ProgramId::ArchiveControllerIcon = { 0x010000000000081Eul };
inline constexpr const ProgramId ProgramId::ArchivePlatformConfigIcosa = { 0x010000000000081Ful };
inline constexpr const ProgramId ProgramId::ArchivePlatformConfigCopper = { 0x0100000000000820ul };
inline constexpr const ProgramId ProgramId::ArchivePlatformConfigHoag = { 0x0100000000000821ul };
inline constexpr const ProgramId ProgramId::ArchiveControllerFirmware = { 0x0100000000000822ul };
inline constexpr const ProgramId ProgramId::ArchiveNgWord2 = { 0x0100000000000823ul };
inline constexpr const ProgramId ProgramId::ArchivePlatformConfigIcosaMariko = { 0x0100000000000824ul };
inline constexpr const ProgramId ProgramId::ArchiveApplicationBlackList = { 0x0100000000000825ul };
inline constexpr const ProgramId ProgramId::ArchiveRebootlessSystemUpdateVersion = { 0x0100000000000826ul };
inline constexpr const ProgramId ProgramId::ArchiveContentActionTable = { 0x0100000000000827ul };
inline constexpr const ProgramId ProgramId::ArchiveEnd = { 0x0100000000000FFFul };
/* System Applets. */
inline constexpr const ProgramId ProgramId::AppletStart = { 0x0100000000001000ul };
inline constexpr const ProgramId ProgramId::AppletQlaunch = { 0x0100000000001000ul };
inline constexpr const ProgramId ProgramId::AppletAuth = { 0x0100000000001001ul };
inline constexpr const ProgramId ProgramId::AppletCabinet = { 0x0100000000001002ul };
inline constexpr const ProgramId ProgramId::AppletController = { 0x0100000000001003ul };
inline constexpr const ProgramId ProgramId::AppletDataErase = { 0x0100000000001004ul };
inline constexpr const ProgramId ProgramId::AppletError = { 0x0100000000001005ul };
inline constexpr const ProgramId ProgramId::AppletNetConnect = { 0x0100000000001006ul };
inline constexpr const ProgramId ProgramId::AppletPlayerSelect = { 0x0100000000001007ul };
inline constexpr const ProgramId ProgramId::AppletSwkbd = { 0x0100000000001008ul };
inline constexpr const ProgramId ProgramId::AppletMiiEdit = { 0x0100000000001009ul };
inline constexpr const ProgramId ProgramId::AppletWeb = { 0x010000000000100Aul };
inline constexpr const ProgramId ProgramId::AppletShop = { 0x010000000000100Bul };
inline constexpr const ProgramId ProgramId::AppletOverlayDisp = { 0x010000000000100Cul };
inline constexpr const ProgramId ProgramId::AppletPhotoViewer = { 0x010000000000100Dul };
inline constexpr const ProgramId ProgramId::AppletSet = { 0x010000000000100Eul };
inline constexpr const ProgramId ProgramId::AppletOfflineWeb = { 0x010000000000100Ful };
inline constexpr const ProgramId ProgramId::AppletLoginShare = { 0x0100000000001010ul };
inline constexpr const ProgramId ProgramId::AppletWifiWebAuth = { 0x0100000000001011ul };
inline constexpr const ProgramId ProgramId::AppletStarter = { 0x0100000000001012ul };
inline constexpr const ProgramId ProgramId::AppletMyPage = { 0x0100000000001013ul };
inline constexpr const ProgramId ProgramId::AppletPlayReport = { 0x0100000000001014ul };
inline constexpr const ProgramId ProgramId::AppletMaintenanceMenu = { 0x0100000000001015ul };
inline constexpr const ProgramId ProgramId::AppletGift = { 0x010000000000101Aul };
inline constexpr const ProgramId ProgramId::AppletDummyShop = { 0x010000000000101Bul };
inline constexpr const ProgramId ProgramId::AppletUserMigration = { 0x010000000000101Cul };
inline constexpr const ProgramId ProgramId::AppletEncounter = { 0x010000000000101Dul };
inline constexpr const ProgramId ProgramId::AppletStory = { 0x0100000000001020ul };
inline constexpr const ProgramId ProgramId::AppletEnd = { 0x0100000000001FFFul };
/* Debug Applets. */
/* Debug Modules. */
/* Factory Setup. */
/* Applications. */
inline constexpr const ProgramId ProgramId::ApplicationStart = { 0x0100000000010000ul };
inline constexpr const ProgramId ProgramId::ApplicationEnd = { 0x01FFFFFFFFFFFFFFul };
/* Atmosphere Extensions. */
inline constexpr const ProgramId ProgramId::AtmosphereMitm = { 0x010041544D530000ul };
inline constexpr bool operator==(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value == rhs.value;
}
inline constexpr bool operator!=(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value != rhs.value;
}
inline constexpr bool operator<(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value < rhs.value;
}
inline constexpr bool operator<=(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value <= rhs.value;
}
inline constexpr bool operator>(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value > rhs.value;
}
inline constexpr bool operator>=(const ProgramId &lhs, const ProgramId &rhs) {
return lhs.value >= rhs.value;
}
inline constexpr bool IsSystemProgramId(const ProgramId &program_id) {
return ProgramId::SystemStart <= program_id && program_id <= ProgramId::SystemEnd;
}
inline constexpr bool IsArchiveProgramId(const ProgramId &program_id) {
return ProgramId::ArchiveStart <= program_id && program_id <= ProgramId::ArchiveEnd;
}
inline constexpr bool IsAppletProgramId(const ProgramId &program_id) {
return ProgramId::AppletStart <= program_id && program_id <= ProgramId::AppletEnd;
}
inline constexpr bool IsApplicationProgramId(const ProgramId &program_id) {
return ProgramId::ApplicationStart <= program_id && program_id <= ProgramId::ApplicationEnd;
}
inline constexpr bool IsWebAppletProgramId(const ProgramId &program_id) {
return program_id == ProgramId::AppletWeb ||
program_id == ProgramId::AppletShop ||
program_id == ProgramId::AppletOfflineWeb ||
program_id == ProgramId::AppletLoginShare ||
program_id == ProgramId::AppletWifiWebAuth;
}
static_assert(sizeof(ProgramId) == sizeof(u64) && std::is_pod<ProgramId>::value, "ProgramId definition!");
/* Program Location. */
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 && std::is_pod<ProgramLocation>::value, "ProgramLocation definition!");
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");
}