mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-12 20:32:17 +02:00
Updated to new-ipc
This commit is contained in:
parent
97bc709ceb
commit
1020e24b9c
@ -25,3 +25,4 @@
|
|||||||
#include "util/util_intrusive_red_black_tree.hpp"
|
#include "util/util_intrusive_red_black_tree.hpp"
|
||||||
#include "util/util_compression.hpp"
|
#include "util/util_compression.hpp"
|
||||||
#include "util/util_ini.hpp"
|
#include "util/util_ini.hpp"
|
||||||
|
#include "util/util_uuid.hpp"
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
namespace sts::util {
|
namespace ams::util {
|
||||||
|
|
||||||
struct Uuid {
|
struct Uuid {
|
||||||
u8 uuid[0x10];
|
u8 uuid[0x10];
|
@ -15,35 +15,44 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstring>
|
#include <atmosphere/common.hpp>
|
||||||
#include <switch.h>
|
#include "../fs/fs_directory.hpp"
|
||||||
|
#include "../sf/sf_buffer_tags.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
constexpr size_t MaxPathLen = 0x300;
|
struct alignas(4) Path : ams::sf::LargeData {
|
||||||
|
char str[fs::EntryNameLengthMax];
|
||||||
|
|
||||||
struct Path {
|
static constexpr Path Encode(const char *p) {
|
||||||
char path[MaxPathLen];
|
Path path = {};
|
||||||
|
for (size_t i = 0; i < sizeof(path) - 1; i++) {
|
||||||
Path() {
|
path.str[i] = p[i];
|
||||||
path[0] = '\0';
|
if (p[i] == '\x00') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
Path(const char* path) {
|
constexpr inline size_t GetLength() const {
|
||||||
strncpy(this->path, path, MaxPathLen-1);
|
size_t len = 0;
|
||||||
this->EnsureNullTerminated();
|
for (size_t i = 0; i < sizeof(this->str) - 1 && this->str[i] != '\x00'; i++) {
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
Path& operator=(const Path& other) {
|
constexpr inline bool IsValid() const {
|
||||||
/* N appears to always memcpy paths, so we will too. */
|
for (size_t i = 0; i < sizeof(this->str); i++) {
|
||||||
std::memcpy(this->path, other.path, MaxPathLen);
|
if (this->str[i] == '\x00') {
|
||||||
this->EnsureNullTerminated();
|
return true;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void EnsureNullTerminated() {
|
return false;
|
||||||
path[MaxPathLen-1] = '\0';
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::is_pod<Path>::value && sizeof(Path) == fs::EntryNameLengthMax);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
namespace ams::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
using Path = lr::Path;
|
|
||||||
|
|
||||||
enum class ContentMetaType : u8 {
|
enum class ContentMetaType : u8 {
|
||||||
Unknown = 0x0,
|
Unknown = 0x0,
|
||||||
SystemProgram = 0x1,
|
SystemProgram = 0x1,
|
||||||
@ -545,7 +543,7 @@ namespace ams::ncm {
|
|||||||
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");
|
static_assert(sizeof(ProgramLocation) == sizeof(::NcmProgramLocation) && alignof(ProgramLocation) == alignof(::NcmProgramLocation), "ProgramLocation Libnx Compatibility");
|
||||||
|
|
||||||
struct ContentMetaKey {
|
struct ContentMetaKey {
|
||||||
TitleId id;
|
ProgramId id;
|
||||||
u32 version;
|
u32 version;
|
||||||
ContentMetaType type;
|
ContentMetaType type;
|
||||||
ContentInstallType install_type;
|
ContentInstallType install_type;
|
||||||
@ -584,11 +582,11 @@ namespace ams::ncm {
|
|||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr ContentMetaKey Make(TitleId title_id, u32 version, ContentMetaType type) {
|
static constexpr ContentMetaKey Make(ProgramId title_id, u32 version, ContentMetaType type) {
|
||||||
return { .id = title_id, .version = version, .type = type };
|
return { .id = title_id, .version = version, .type = type };
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr ContentMetaKey Make(TitleId title_id, u32 version, ContentMetaType type, ContentInstallType install_type) {
|
static constexpr ContentMetaKey Make(ProgramId title_id, u32 version, ContentMetaType type, ContentInstallType install_type) {
|
||||||
return { .id = title_id, .version = version, .type = type, .install_type = install_type };
|
return { .id = title_id, .version = version, .type = type, .install_type = install_type };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -600,7 +598,7 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
struct ApplicationContentMetaKey {
|
struct ApplicationContentMetaKey {
|
||||||
ContentMetaKey key;
|
ContentMetaKey key;
|
||||||
TitleId application_title_id;
|
ProgramId application_title_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(ApplicationContentMetaKey) == 0x18, "ApplicationContentMetaKey definition!");
|
static_assert(sizeof(ApplicationContentMetaKey) == 0x18, "ApplicationContentMetaKey definition!");
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
#include "lr_manager.hpp"
|
#include "lr_manager.hpp"
|
||||||
#include "ncm_bounded_map.hpp"
|
#include "ncm_bounded_map.hpp"
|
||||||
|
|
||||||
namespace sts::lr::impl {
|
namespace ams::lr::impl {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
ncm::impl::BoundedMap<ncm::StorageId, std::shared_ptr<ILocationResolver>, 5> g_location_resolvers;
|
ncm::impl::BoundedMap<ncm::StorageId, std::shared_ptr<ILocationResolver>, 5> g_location_resolvers;
|
||||||
std::shared_ptr<RegisteredLocationResolverInterface> g_registered_location_resolver = nullptr;
|
std::shared_ptr<RegisteredLocationResolverInterface> g_registered_location_resolver = nullptr;
|
||||||
std::shared_ptr<AddOnContentLocationResolverInterface> g_add_on_content_location_resolver = nullptr;
|
std::shared_ptr<AddOnContentLocationResolverInterface> g_add_on_content_location_resolver = nullptr;
|
||||||
HosMutex g_mutex;
|
os::Mutex g_mutex;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenLocationResolver(Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id) {
|
Result OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id) {
|
||||||
std::scoped_lock lk(g_mutex);
|
std::scoped_lock lk(g_mutex);
|
||||||
auto resolver = g_location_resolvers.Find(storage_id);
|
auto resolver = g_location_resolvers.Find(storage_id);
|
||||||
|
|
||||||
@ -45,19 +45,21 @@ namespace sts::lr::impl {
|
|||||||
resolver = g_location_resolvers.Find(storage_id);
|
resolver = g_location_resolvers.Find(storage_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(*resolver);
|
std::shared_ptr<ILocationResolver> new_intf = *resolver;
|
||||||
return ResultSuccess;
|
out.SetValue(std::move(new_intf));
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenRegisteredLocationResolver(Out<std::shared_ptr<RegisteredLocationResolverInterface>> out) {
|
Result OpenRegisteredLocationResolver(sf::Out<std::shared_ptr<RegisteredLocationResolverInterface>> out) {
|
||||||
std::scoped_lock lk(g_mutex);
|
std::scoped_lock lk(g_mutex);
|
||||||
|
|
||||||
if (!g_registered_location_resolver) {
|
if (!g_registered_location_resolver) {
|
||||||
g_registered_location_resolver = std::make_shared<RegisteredLocationResolverInterface>();
|
g_registered_location_resolver = std::make_shared<RegisteredLocationResolverInterface>();
|
||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(g_registered_location_resolver);
|
std::shared_ptr<RegisteredLocationResolverInterface> new_intf = g_registered_location_resolver;
|
||||||
return ResultSuccess;
|
out.SetValue(std::move(new_intf));
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RefreshLocationResolver(ncm::StorageId storage_id) {
|
Result RefreshLocationResolver(ncm::StorageId storage_id) {
|
||||||
@ -65,25 +67,26 @@ namespace sts::lr::impl {
|
|||||||
auto resolver = g_location_resolvers.Find(storage_id);
|
auto resolver = g_location_resolvers.Find(storage_id);
|
||||||
|
|
||||||
if (!resolver) {
|
if (!resolver) {
|
||||||
return ResultLrUnknownStorageId;
|
return ResultUnknownStorageId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storage_id != ncm::StorageId::Host) {
|
if (storage_id != ncm::StorageId::Host) {
|
||||||
(*resolver)->Refresh();
|
(*resolver)->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenAddOnContentLocationResolver(Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out) {
|
Result OpenAddOnContentLocationResolver(sf::Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out) {
|
||||||
std::scoped_lock lk(g_mutex);
|
std::scoped_lock lk(g_mutex);
|
||||||
|
|
||||||
if (!g_add_on_content_location_resolver) {
|
if (!g_add_on_content_location_resolver) {
|
||||||
g_add_on_content_location_resolver = std::make_shared<AddOnContentLocationResolverInterface>();
|
g_add_on_content_location_resolver = std::make_shared<AddOnContentLocationResolverInterface>();
|
||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(g_add_on_content_location_resolver);
|
std::shared_ptr<AddOnContentLocationResolverInterface> new_intf = g_add_on_content_location_resolver;
|
||||||
return ResultSuccess;
|
out.SetValue(std::move(new_intf));
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,12 @@
|
|||||||
#include "../lr_ilocationresolver.hpp"
|
#include "../lr_ilocationresolver.hpp"
|
||||||
#include "../lr_registeredlocationresolver.hpp"
|
#include "../lr_registeredlocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr::impl {
|
namespace ams::lr::impl {
|
||||||
|
|
||||||
/* Location Resolver API. */
|
/* Location Resolver API. */
|
||||||
Result OpenLocationResolver(Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id);
|
Result OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id);
|
||||||
Result OpenRegisteredLocationResolver(Out<std::shared_ptr<RegisteredLocationResolverInterface>> out);
|
Result OpenRegisteredLocationResolver(sf::Out<std::shared_ptr<RegisteredLocationResolverInterface>> out);
|
||||||
Result RefreshLocationResolver(ncm::StorageId storage_id);
|
Result RefreshLocationResolver(ncm::StorageId storage_id);
|
||||||
Result OpenAddOnContentLocationResolver(Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out);
|
Result OpenAddOnContentLocationResolver(sf::Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,25 +16,25 @@
|
|||||||
|
|
||||||
#include "lr_redirection.hpp"
|
#include "lr_redirection.hpp"
|
||||||
|
|
||||||
namespace sts::lr::impl {
|
namespace ams::lr::impl {
|
||||||
|
|
||||||
class LocationRedirection : public util::IntrusiveListBaseNode<LocationRedirection> {
|
class LocationRedirection : public util::IntrusiveListBaseNode<LocationRedirection> {
|
||||||
NON_COPYABLE(LocationRedirection);
|
NON_COPYABLE(LocationRedirection);
|
||||||
NON_MOVEABLE(LocationRedirection);
|
NON_MOVEABLE(LocationRedirection);
|
||||||
private:
|
private:
|
||||||
ncm::TitleId title_id;
|
ncm::ProgramId title_id;
|
||||||
ncm::TitleId owner_tid;
|
ncm::ProgramId owner_tid;
|
||||||
Path path;
|
Path path;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
public:
|
public:
|
||||||
LocationRedirection(ncm::TitleId title_id, ncm::TitleId owner_tid, const Path& path, u32 flags) :
|
LocationRedirection(ncm::ProgramId title_id, ncm::ProgramId owner_tid, const Path& path, u32 flags) :
|
||||||
title_id(title_id), owner_tid(owner_tid), path(path), flags(flags) { /* ... */ }
|
title_id(title_id), owner_tid(owner_tid), path(path), flags(flags) { /* ... */ }
|
||||||
|
|
||||||
ncm::TitleId GetTitleId() const {
|
ncm::ProgramId GetTitleId() const {
|
||||||
return this->title_id;
|
return this->title_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
ncm::TitleId GetOwnerTitleId() const {
|
ncm::ProgramId GetOwnerTitleId() const {
|
||||||
return this->owner_tid;
|
return this->owner_tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ namespace sts::lr::impl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool LocationRedirector::FindRedirection(Path *out, ncm::TitleId title_id) {
|
bool LocationRedirector::FindRedirection(Path *out, ncm::ProgramId title_id) {
|
||||||
if (this->redirection_list.empty()) {
|
if (this->redirection_list.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -65,16 +65,16 @@ namespace sts::lr::impl {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::SetRedirection(ncm::TitleId title_id, const Path &path, u32 flags) {
|
void LocationRedirector::SetRedirection(ncm::ProgramId title_id, const Path &path, u32 flags) {
|
||||||
this->SetRedirection(title_id, path, flags);
|
this->SetRedirection(title_id, path, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::SetRedirection(ncm::TitleId title_id, ncm::TitleId owner_tid, const Path &path, u32 flags) {
|
void LocationRedirector::SetRedirection(ncm::ProgramId title_id, ncm::ProgramId owner_tid, const Path &path, u32 flags) {
|
||||||
this->EraseRedirection(title_id);
|
this->EraseRedirection(title_id);
|
||||||
this->redirection_list.push_back(*(new LocationRedirection(title_id, owner_tid, path, flags)));
|
this->redirection_list.push_back(*(new LocationRedirection(title_id, owner_tid, path, flags)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::SetRedirectionFlags(ncm::TitleId title_id, u32 flags) {
|
void LocationRedirector::SetRedirectionFlags(ncm::ProgramId title_id, u32 flags) {
|
||||||
for (auto &redirection : this->redirection_list) {
|
for (auto &redirection : this->redirection_list) {
|
||||||
if (redirection.GetTitleId() == title_id) {
|
if (redirection.GetTitleId() == title_id) {
|
||||||
redirection.SetFlags(flags);
|
redirection.SetFlags(flags);
|
||||||
@ -83,7 +83,7 @@ namespace sts::lr::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::EraseRedirection(ncm::TitleId title_id) {
|
void LocationRedirector::EraseRedirection(ncm::ProgramId title_id) {
|
||||||
for (auto &redirection : this->redirection_list) {
|
for (auto &redirection : this->redirection_list) {
|
||||||
if (redirection.GetTitleId() == title_id) {
|
if (redirection.GetTitleId() == title_id) {
|
||||||
this->redirection_list.erase(this->redirection_list.iterator_to(redirection));
|
this->redirection_list.erase(this->redirection_list.iterator_to(redirection));
|
||||||
@ -105,11 +105,11 @@ namespace sts::lr::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::ClearRedirections(const ncm::TitleId* excluding_tids, size_t num_tids) {
|
void LocationRedirector::ClearRedirections(const ncm::ProgramId* excluding_tids, size_t num_tids) {
|
||||||
for (auto it = this->redirection_list.begin(); it != this->redirection_list.end();) {
|
for (auto it = this->redirection_list.begin(); it != this->redirection_list.end();) {
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
for (size_t i = 0; i < num_tids; i++) {
|
for (size_t i = 0; i < num_tids; i++) {
|
||||||
ncm::TitleId tid = excluding_tids[i];
|
ncm::ProgramId tid = excluding_tids[i];
|
||||||
|
|
||||||
if (it->GetOwnerTitleId() == tid) {
|
if (it->GetOwnerTitleId() == tid) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::lr::impl {
|
namespace ams::lr::impl {
|
||||||
|
|
||||||
enum RedirectionFlags {
|
enum RedirectionFlags {
|
||||||
RedirectionFlags_None = (0 << 0),
|
RedirectionFlags_None = (0 << 0),
|
||||||
@ -31,17 +31,17 @@ namespace sts::lr::impl {
|
|||||||
NON_COPYABLE(LocationRedirector);
|
NON_COPYABLE(LocationRedirector);
|
||||||
NON_MOVEABLE(LocationRedirector);
|
NON_MOVEABLE(LocationRedirector);
|
||||||
private:
|
private:
|
||||||
sts::util::IntrusiveListBaseTraits<LocationRedirection>::ListType redirection_list;
|
ams::util::IntrusiveListBaseTraits<LocationRedirection>::ListType redirection_list;
|
||||||
public:
|
public:
|
||||||
LocationRedirector() { /* ... */ }
|
LocationRedirector() { /* ... */ }
|
||||||
|
|
||||||
bool FindRedirection(Path *out, ncm::TitleId title_id);
|
bool FindRedirection(Path *out, ncm::ProgramId title_id);
|
||||||
void SetRedirection(ncm::TitleId title_id, const Path &path, u32 flags = RedirectionFlags_None);
|
void SetRedirection(ncm::ProgramId title_id, const Path &path, u32 flags = RedirectionFlags_None);
|
||||||
void SetRedirection(ncm::TitleId title_id, ncm::TitleId owner_tid, const Path &path, u32 flags = RedirectionFlags_None);
|
void SetRedirection(ncm::ProgramId title_id, ncm::ProgramId owner_tid, const Path &path, u32 flags = RedirectionFlags_None);
|
||||||
void SetRedirectionFlags(ncm::TitleId title_id, u32 flags);
|
void SetRedirectionFlags(ncm::ProgramId title_id, u32 flags);
|
||||||
void EraseRedirection(ncm::TitleId title_id);
|
void EraseRedirection(ncm::ProgramId title_id);
|
||||||
void ClearRedirections(u32 flags = RedirectionFlags_None);
|
void ClearRedirections(u32 flags = RedirectionFlags_None);
|
||||||
void ClearRedirections(const ncm::TitleId* excluding_tids, size_t num_tids);
|
void ClearRedirections(const ncm::ProgramId* excluding_tids, size_t num_tids);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::lr::impl {
|
namespace ams::lr::impl {
|
||||||
|
|
||||||
template<typename Key, typename Value, size_t NumEntries>
|
template<typename Key, typename Value, size_t NumEntries>
|
||||||
class RegisteredData {
|
class RegisteredData {
|
||||||
@ -27,7 +27,7 @@ namespace sts::lr::impl {
|
|||||||
private:
|
private:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
Value value;
|
Value value;
|
||||||
ncm::TitleId owner_tid;
|
ncm::ProgramId owner_tid;
|
||||||
Key key;
|
Key key;
|
||||||
bool is_valid;
|
bool is_valid;
|
||||||
};
|
};
|
||||||
@ -39,7 +39,7 @@ namespace sts::lr::impl {
|
|||||||
this->Clear();
|
this->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Register(const Key &key, const Value &value, const ncm::TitleId owner_tid) {
|
bool Register(const Key &key, const Value &value, const ncm::ProgramId owner_tid) {
|
||||||
/* Try to find an existing value. */
|
/* Try to find an existing value. */
|
||||||
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
|
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
|
||||||
Entry& entry = this->entries[i];
|
Entry& entry = this->entries[i];
|
||||||
@ -72,7 +72,7 @@ namespace sts::lr::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterOwnerTitle(ncm::TitleId owner_tid) {
|
void UnregisterOwnerTitle(ncm::ProgramId owner_tid) {
|
||||||
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
|
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
|
||||||
Entry& entry = this->entries[i];
|
Entry& entry = this->entries[i];
|
||||||
if (entry.owner_tid == owner_tid) {
|
if (entry.owner_tid == owner_tid) {
|
||||||
@ -99,13 +99,13 @@ namespace sts::lr::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearExcluding(const ncm::TitleId* tids, size_t num_tids) {
|
void ClearExcluding(const ncm::ProgramId* tids, size_t num_tids) {
|
||||||
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
|
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
|
||||||
Entry& entry = this->entries[i];
|
Entry& entry = this->entries[i];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (size_t j = 0; j < num_tids; j++) {
|
for (size_t j = 0; j < num_tids; j++) {
|
||||||
ncm::TitleId tid = tids[j];
|
ncm::ProgramId tid = tids[j];
|
||||||
|
|
||||||
if (entry.owner_tid == tid) {
|
if (entry.owner_tid == tid) {
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace ams::ncm::impl {
|
||||||
|
|
||||||
template<class Key, class Value, size_t N>
|
template<class Key, class Value, size_t N>
|
||||||
class BoundedMap {
|
class BoundedMap {
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "ncm_content_manager.hpp"
|
#include "ncm_content_manager.hpp"
|
||||||
#include "ncm_rights_cache.hpp"
|
#include "ncm_rights_cache.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace ams::ncm::impl {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace sts::ncm::impl {
|
|||||||
std::shared_ptr<IContentStorage> content_storage;
|
std::shared_ptr<IContentStorage> content_storage;
|
||||||
|
|
||||||
inline ContentStorageEntry() : storage_id(StorageId::None),
|
inline ContentStorageEntry() : storage_id(StorageId::None),
|
||||||
content_storage_id(FS_CONTENTSTORAGEID_NandSystem), content_storage(nullptr) {
|
content_storage_id(FsContentStorageId_System), content_storage(nullptr) {
|
||||||
mount_point[0] = '\0';
|
mount_point[0] = '\0';
|
||||||
root_path[0] = '\0';
|
root_path[0] = '\0';
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ namespace sts::ncm::impl {
|
|||||||
strcpy(this->mount_point, mount_name.name);
|
strcpy(this->mount_point, mount_name.name);
|
||||||
this->mount_point[0] = '#';
|
this->mount_point[0] = '#';
|
||||||
snprintf(this->meta_path, 0x80, "%s:/meta", this->mount_point);
|
snprintf(this->meta_path, 0x80, "%s:/meta", this->mount_point);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InitializeGameCard(size_t max_content_metas) {
|
Result InitializeGameCard(size_t max_content_metas) {
|
||||||
@ -103,14 +103,14 @@ namespace sts::ncm::impl {
|
|||||||
this->max_content_metas = max_content_metas;
|
this->max_content_metas = max_content_metas;
|
||||||
this->content_meta_database = nullptr;
|
this->content_meta_database = nullptr;
|
||||||
this->kvs.reset();
|
this->kvs.reset();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr size_t MaxContentStorageEntries = 8;
|
constexpr size_t MaxContentStorageEntries = 8;
|
||||||
constexpr size_t MaxContentMetaDBEntries = 8;
|
constexpr size_t MaxContentMetaDBEntries = 8;
|
||||||
|
|
||||||
HosMutex g_mutex;
|
os::Mutex g_mutex;
|
||||||
bool g_initialized = false;
|
bool g_initialized = false;
|
||||||
ContentStorageEntry g_content_storage_entries[MaxContentStorageEntries];
|
ContentStorageEntry g_content_storage_entries[MaxContentStorageEntries];
|
||||||
ContentMetaDBEntry g_content_meta_entries[MaxContentMetaDBEntries];
|
ContentMetaDBEntry g_content_meta_entries[MaxContentMetaDBEntries];
|
||||||
@ -145,11 +145,11 @@ namespace sts::ncm::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result InitializeContentManager() {
|
Result InitializeContentManager() {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
/* Already initialized. */
|
/* Already initialized. */
|
||||||
if (g_initialized) {
|
if (g_initialized) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cur_storage_index = g_num_content_storage_entries;
|
size_t cur_storage_index = g_num_content_storage_entries;
|
||||||
@ -168,46 +168,46 @@ namespace sts::ncm::impl {
|
|||||||
auto storage_entry = &g_content_storage_entries[cur_storage_index];
|
auto storage_entry = &g_content_storage_entries[cur_storage_index];
|
||||||
|
|
||||||
/* First, setup the NandSystem storage entry. */
|
/* First, setup the NandSystem storage entry. */
|
||||||
storage_entry->Initialize(StorageId::NandSystem, FS_CONTENTSTORAGEID_NandSystem);
|
storage_entry->Initialize(StorageId::BuiltInSystem, FsContentStorageId_System);
|
||||||
|
|
||||||
if (R_FAILED(VerifyContentStorage(StorageId::NandSystem))) {
|
if (R_FAILED(VerifyContentStorage(StorageId::BuiltInSystem))) {
|
||||||
R_TRY(CreateContentStorage(StorageId::NandSystem));
|
R_TRY(CreateContentStorage(StorageId::BuiltInSystem));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(ActivateContentStorage(StorageId::NandSystem));
|
R_TRY(ActivateContentStorage(StorageId::BuiltInSystem));
|
||||||
|
|
||||||
/* Next, the NandSystem content meta entry. */
|
/* Next, the NandSystem content meta entry. */
|
||||||
SaveDataMeta nand_system_save_meta;
|
SaveDataMeta nand_system_save_meta;
|
||||||
nand_system_save_meta.id = 0x8000000000000120;
|
nand_system_save_meta.id = 0x8000000000000120;
|
||||||
nand_system_save_meta.size = 0x6c000;
|
nand_system_save_meta.size = 0x6c000;
|
||||||
nand_system_save_meta.journal_size = 0x6c000;
|
nand_system_save_meta.journal_size = 0x6c000;
|
||||||
nand_system_save_meta.flags = FsSaveDataFlags_SurviveFactoryReset| FsSaveDataFlags_SurviveFactoryResetForRefurbishment;
|
nand_system_save_meta.flags = FsSaveDataFlags_KeepAfterResettingSystemSaveData | FsSaveDataFlags_KeepAfterRefurbishment;
|
||||||
nand_system_save_meta.space_id = FsSaveDataSpaceId_NandSystem;
|
nand_system_save_meta.space_id = FsSaveDataSpaceId_System;
|
||||||
|
|
||||||
size_t cur_meta_index = g_num_content_meta_entries;
|
size_t cur_meta_index = g_num_content_meta_entries;
|
||||||
g_num_content_meta_entries++;
|
g_num_content_meta_entries++;
|
||||||
auto content_meta_entry = &g_content_meta_entries[cur_meta_index];
|
auto content_meta_entry = &g_content_meta_entries[cur_meta_index];
|
||||||
|
|
||||||
R_TRY(content_meta_entry->Initialize(StorageId::NandSystem, nand_system_save_meta, 0x800));
|
R_TRY(content_meta_entry->Initialize(StorageId::BuiltInSystem, nand_system_save_meta, 0x800));
|
||||||
|
|
||||||
if (R_FAILED(VerifyContentMetaDatabase(StorageId::NandSystem))) {
|
if (R_FAILED(VerifyContentMetaDatabase(StorageId::BuiltInSystem))) {
|
||||||
R_TRY(CreateContentMetaDatabase(StorageId::NandSystem));
|
R_TRY(CreateContentMetaDatabase(StorageId::BuiltInSystem));
|
||||||
|
|
||||||
/* TODO: N supports a number of unused modes here, we don't bother implementing them currently. */
|
/* TODO: N supports a number of unused modes here, we don't bother implementing them currently. */
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 current_flags = 0;
|
u32 current_flags = 0;
|
||||||
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200 && R_SUCCEEDED(fs::GetSaveDataFlags(¤t_flags, 0x8000000000000120)) && current_flags != (FsSaveDataFlags_SurviveFactoryReset | FsSaveDataFlags_SurviveFactoryResetForRefurbishment)) {
|
if (hos::GetVersion() >= hos::Version_200 && R_SUCCEEDED(fs::GetSaveDataFlags(¤t_flags, 0x8000000000000120)) && current_flags != (FsSaveDataFlags_KeepAfterResettingSystemSaveData | FsSaveDataFlags_KeepAfterRefurbishment)) {
|
||||||
fs::SetSaveDataFlags(0x8000000000000120, FsSaveDataSpaceId_NandSystem, FsSaveDataFlags_SurviveFactoryReset | FsSaveDataFlags_SurviveFactoryResetForRefurbishment);
|
fs::SetSaveDataFlags(0x8000000000000120, FsSaveDataSpaceId_System, FsSaveDataFlags_KeepAfterResettingSystemSaveData | FsSaveDataFlags_KeepAfterRefurbishment);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(ActivateContentMetaDatabase(StorageId::NandSystem));
|
R_TRY(ActivateContentMetaDatabase(StorageId::BuiltInSystem));
|
||||||
|
|
||||||
/* Now for NandUser's content storage entry. */
|
/* Now for NandUser's content storage entry. */
|
||||||
cur_storage_index = g_num_content_storage_entries;
|
cur_storage_index = g_num_content_storage_entries;
|
||||||
g_num_content_storage_entries++;
|
g_num_content_storage_entries++;
|
||||||
storage_entry = &g_content_storage_entries[cur_storage_index];
|
storage_entry = &g_content_storage_entries[cur_storage_index];
|
||||||
storage_entry->Initialize(StorageId::NandUser, FS_CONTENTSTORAGEID_NandUser);
|
storage_entry->Initialize(StorageId::BuiltInUser, FsContentStorageId_User);
|
||||||
|
|
||||||
/* And NandUser's content meta entry. */
|
/* And NandUser's content meta entry. */
|
||||||
SaveDataMeta nand_user_save_meta;
|
SaveDataMeta nand_user_save_meta;
|
||||||
@ -215,13 +215,13 @@ namespace sts::ncm::impl {
|
|||||||
nand_user_save_meta.size = 0x29e000;
|
nand_user_save_meta.size = 0x29e000;
|
||||||
nand_user_save_meta.journal_size = 0x29e000;
|
nand_user_save_meta.journal_size = 0x29e000;
|
||||||
nand_user_save_meta.flags = 0;
|
nand_user_save_meta.flags = 0;
|
||||||
nand_user_save_meta.space_id = FsSaveDataSpaceId_NandSystem;
|
nand_user_save_meta.space_id = FsSaveDataSpaceId_System;
|
||||||
|
|
||||||
cur_meta_index = g_num_content_meta_entries;
|
cur_meta_index = g_num_content_meta_entries;
|
||||||
g_num_content_meta_entries++;
|
g_num_content_meta_entries++;
|
||||||
content_meta_entry = &g_content_meta_entries[cur_meta_index];
|
content_meta_entry = &g_content_meta_entries[cur_meta_index];
|
||||||
|
|
||||||
R_TRY(content_meta_entry->Initialize(StorageId::NandUser, nand_user_save_meta, 0x2000));
|
R_TRY(content_meta_entry->Initialize(StorageId::BuiltInUser, nand_user_save_meta, 0x2000));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Beyond this point N no longer appears to bother
|
Beyond this point N no longer appears to bother
|
||||||
@ -229,7 +229,7 @@ namespace sts::ncm::impl {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Next SdCard's content storage entry. */
|
/* Next SdCard's content storage entry. */
|
||||||
g_content_storage_entries[2].Initialize(StorageId::SdCard, FS_CONTENTSTORAGEID_SdCard);
|
g_content_storage_entries[2].Initialize(StorageId::SdCard, FsContentStorageId_SdCard);
|
||||||
|
|
||||||
/* And SdCard's content meta entry. */
|
/* And SdCard's content meta entry. */
|
||||||
SaveDataMeta sd_card_save_meta;
|
SaveDataMeta sd_card_save_meta;
|
||||||
@ -237,26 +237,26 @@ namespace sts::ncm::impl {
|
|||||||
sd_card_save_meta.size = 0xa08000;
|
sd_card_save_meta.size = 0xa08000;
|
||||||
sd_card_save_meta.journal_size = 0xa08000;
|
sd_card_save_meta.journal_size = 0xa08000;
|
||||||
sd_card_save_meta.flags = 0;
|
sd_card_save_meta.flags = 0;
|
||||||
sd_card_save_meta.space_id = FsSaveDataSpaceId_SdCard;
|
sd_card_save_meta.space_id = FsSaveDataSpaceId_SdSystem;
|
||||||
|
|
||||||
content_meta_entry = &g_content_meta_entries[2];
|
content_meta_entry = &g_content_meta_entries[2];
|
||||||
R_TRY(content_meta_entry->Initialize(StorageId::SdCard, sd_card_save_meta, 0x2000));
|
R_TRY(content_meta_entry->Initialize(StorageId::SdCard, sd_card_save_meta, 0x2000));
|
||||||
|
|
||||||
/* GameCard's content storage entry. */
|
/* GameCard's content storage entry. */
|
||||||
/* N doesn't set a content storage id for game cards, so we'll just use 0 (NandSystem). */
|
/* N doesn't set a content storage id for game cards, so we'll just use 0 (NandSystem). */
|
||||||
g_content_storage_entries[3].Initialize(StorageId::GameCard, FS_CONTENTSTORAGEID_NandSystem);
|
g_content_storage_entries[3].Initialize(StorageId::GameCard, FsContentStorageId_System);
|
||||||
|
|
||||||
/* Lasty, GameCard's content meta entry. */
|
/* Lasty, GameCard's content meta entry. */
|
||||||
content_meta_entry = &g_content_meta_entries[3];
|
content_meta_entry = &g_content_meta_entries[3];
|
||||||
R_TRY(content_meta_entry->InitializeGameCard(0x800));
|
R_TRY(content_meta_entry->InitializeGameCard(0x800));
|
||||||
|
|
||||||
g_initialized = true;
|
g_initialized = true;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinalizeContentManager() {
|
void FinalizeContentManager() {
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
for (size_t i = 0; i < MaxContentStorageEntries; i++) {
|
for (size_t i = 0; i < MaxContentStorageEntries; i++) {
|
||||||
ContentStorageEntry* entry = &g_content_storage_entries[i];
|
ContentStorageEntry* entry = &g_content_storage_entries[i];
|
||||||
@ -281,16 +281,16 @@ namespace sts::ncm::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result CreateContentStorage(StorageId storage_id) {
|
Result CreateContentStorage(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fs::MountContentStorage(entry->mount_point, entry->content_storage_id));
|
R_TRY(fs::MountContentStorage(entry->mount_point, entry->content_storage_id));
|
||||||
@ -302,20 +302,20 @@ namespace sts::ncm::impl {
|
|||||||
R_TRY(fs::EnsureDirectoryRecursively(entry->root_path));
|
R_TRY(fs::EnsureDirectoryRecursively(entry->root_path));
|
||||||
R_TRY(fs::EnsureContentAndPlaceHolderRoot(entry->root_path));
|
R_TRY(fs::EnsureContentAndPlaceHolderRoot(entry->root_path));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result VerifyContentStorage(StorageId storage_id) {
|
Result VerifyContentStorage(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
MountName mount_name = fs::CreateUniqueMountName();
|
MountName mount_name = fs::CreateUniqueMountName();
|
||||||
@ -330,99 +330,99 @@ namespace sts::ncm::impl {
|
|||||||
|
|
||||||
R_TRY(fs::CheckContentStorageDirectoriesExist(mount_root));
|
R_TRY(fs::CheckContentStorageDirectoriesExist(mount_root));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenContentStorage(std::shared_ptr<IContentStorage>* out, StorageId storage_id) {
|
Result OpenContentStorage(std::shared_ptr<IContentStorage>* out, StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto content_storage = entry->content_storage;
|
auto content_storage = entry->content_storage;
|
||||||
|
|
||||||
if (!content_storage) {
|
if (!content_storage) {
|
||||||
/* 1.0.0 activates content storages as soon as they are opened. */
|
/* 1.0.0 activates content storages as soon as they are opened. */
|
||||||
if (GetRuntimeFirmwareVersion() == FirmwareVersion_100) {
|
if (hos::GetVersion() == hos::Version_100) {
|
||||||
R_TRY(ActivateContentStorage(storage_id));
|
R_TRY(ActivateContentStorage(storage_id));
|
||||||
content_storage = entry->content_storage;
|
content_storage = entry->content_storage;
|
||||||
} else {
|
} else {
|
||||||
switch (storage_id) {
|
switch (storage_id) {
|
||||||
case StorageId::GameCard:
|
case StorageId::GameCard:
|
||||||
return ResultNcmGameCardContentStorageNotActive;
|
return ResultGameCardContentStorageNotActive();
|
||||||
|
|
||||||
case StorageId::NandSystem:
|
case StorageId::BuiltInSystem:
|
||||||
return ResultNcmNandSystemContentStorageNotActive;
|
return ResultNandSystemContentStorageNotActive();
|
||||||
|
|
||||||
case StorageId::NandUser:
|
case StorageId::BuiltInUser:
|
||||||
return ResultNcmNandUserContentStorageNotActive;
|
return ResultNandUserContentStorageNotActive();
|
||||||
|
|
||||||
case StorageId::SdCard:
|
case StorageId::SdCard:
|
||||||
return ResultNcmSdCardContentStorageNotActive;
|
return ResultSdCardContentStorageNotActive();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ResultNcmUnknownContentStorageNotActive;
|
return ResultUnknownContentStorageNotActive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = std::move(content_storage);
|
*out = std::move(content_storage);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CloseContentStorageForcibly(StorageId storage_id) {
|
Result CloseContentStorageForcibly(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None) {
|
if (storage_id == StorageId::None) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry->content_storage) {
|
if (!entry->content_storage) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* N doesn't bother checking the result of this */
|
/* N doesn't bother checking the result of this */
|
||||||
entry->content_storage->DisableForcibly();
|
entry->content_storage->DisableForcibly();
|
||||||
fs::Unmount(entry->mount_point);
|
fs::Unmount(entry->mount_point);
|
||||||
entry->content_storage = nullptr;
|
entry->content_storage = nullptr;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ActivateContentStorage(StorageId storage_id) {
|
Result ActivateContentStorage(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Already activated. */
|
/* Already activated. */
|
||||||
if (entry->content_storage != nullptr) {
|
if (entry->content_storage != nullptr) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storage_id == StorageId::GameCard) {
|
if (storage_id == StorageId::GameCard) {
|
||||||
FsGameCardHandle gc_hnd;
|
FsGameCardHandle gc_hnd;
|
||||||
R_TRY(fs::GetGameCardHandle(&gc_hnd));
|
R_TRY(fs::GetGameCardHandle(&gc_hnd));
|
||||||
R_TRY(fs::MountGameCardPartition(entry->mount_point, gc_hnd, FsGameCardPartiton_Secure));
|
R_TRY(fs::MountGameCardPartition(entry->mount_point, gc_hnd, FsGameCardPartition_Secure));
|
||||||
auto mount_guard = SCOPE_GUARD { fs::Unmount(entry->mount_point); };
|
auto mount_guard = SCOPE_GUARD { fs::Unmount(entry->mount_point); };
|
||||||
auto content_storage = std::make_shared<ReadOnlyContentStorageInterface>();
|
auto content_storage = std::make_shared<ReadOnlyContentStorageInterface>();
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ namespace sts::ncm::impl {
|
|||||||
auto content_storage = std::make_shared<ContentStorageInterface>();
|
auto content_storage = std::make_shared<ContentStorageInterface>();
|
||||||
|
|
||||||
switch (storage_id) {
|
switch (storage_id) {
|
||||||
case StorageId::NandSystem:
|
case StorageId::BuiltInSystem:
|
||||||
content_path_func = path::MakeContentPathFlat;
|
content_path_func = path::MakeContentPathFlat;
|
||||||
placeholder_path_func = path::MakePlaceHolderPathFlat;
|
placeholder_path_func = path::MakePlaceHolderPathFlat;
|
||||||
break;
|
break;
|
||||||
@ -456,51 +456,51 @@ namespace sts::ncm::impl {
|
|||||||
mount_guard.Cancel();
|
mount_guard.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InactivateContentStorage(StorageId storage_id) {
|
Result InactivateContentStorage(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
ContentStorageEntry* entry = FindContentStorageEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Already inactivated. */
|
/* Already inactivated. */
|
||||||
if (entry->content_storage == nullptr) {
|
if (entry->content_storage == nullptr) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->content_storage->DisableForcibly();
|
entry->content_storage->DisableForcibly();
|
||||||
entry->content_storage = nullptr;
|
entry->content_storage = nullptr;
|
||||||
fs::Unmount(entry->mount_point);
|
fs::Unmount(entry->mount_point);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateContentMetaDatabase(StorageId storage_id) {
|
Result CreateContentMetaDatabase(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || storage_id == StorageId::GameCard || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || storage_id == StorageId::GameCard || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* N doesn't bother checking the result of this. */
|
/* N doesn't bother checking the result of this. */
|
||||||
fsDisableAutoSaveDataCreation();
|
fsDisableAutoSaveDataCreation();
|
||||||
|
|
||||||
R_TRY_CATCH(fs::MountSystemSaveData(entry->mount_point, entry->save_meta.space_id, entry->save_meta.id)) {
|
R_TRY_CATCH(fs::MountSystemSaveData(entry->mount_point, entry->save_meta.space_id, entry->save_meta.id)) {
|
||||||
R_CATCH(ResultFsTargetNotFound) {
|
R_CATCH(ams::fs::ResultTargetNotFound) {
|
||||||
R_TRY(fsCreate_SystemSaveData(entry->save_meta.space_id, entry->save_meta.id, entry->save_meta.size, entry->save_meta.journal_size, entry->save_meta.flags));
|
R_TRY(fsCreate_SystemSaveData(entry->save_meta.space_id, entry->save_meta.id, entry->save_meta.size, entry->save_meta.journal_size, entry->save_meta.flags));
|
||||||
R_TRY(fs::MountSystemSaveData(entry->mount_point, entry->save_meta.space_id, entry->save_meta.id));
|
R_TRY(fs::MountSystemSaveData(entry->mount_point, entry->save_meta.space_id, entry->save_meta.id));
|
||||||
}
|
}
|
||||||
@ -513,24 +513,24 @@ namespace sts::ncm::impl {
|
|||||||
R_TRY(fs::EnsureDirectoryRecursively(entry->meta_path));
|
R_TRY(fs::EnsureDirectoryRecursively(entry->meta_path));
|
||||||
R_TRY(fsdevCommitDevice(entry->mount_point));
|
R_TRY(fsdevCommitDevice(entry->mount_point));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result VerifyContentMetaDatabase(StorageId storage_id) {
|
Result VerifyContentMetaDatabase(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::GameCard) {
|
if (storage_id == StorageId::GameCard) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mounted_save_data = false;
|
bool mounted_save_data = false;
|
||||||
@ -549,73 +549,73 @@ namespace sts::ncm::impl {
|
|||||||
bool has_meta_path = false;
|
bool has_meta_path = false;
|
||||||
R_TRY(fs::HasDirectory(&has_meta_path, entry->meta_path));
|
R_TRY(fs::HasDirectory(&has_meta_path, entry->meta_path));
|
||||||
if (!has_meta_path) {
|
if (!has_meta_path) {
|
||||||
return ResultNcmInvalidContentMetaDatabase;
|
return ResultInvalidContentMetaDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenContentMetaDatabase(std::shared_ptr<IContentMetaDatabase>* out, StorageId storage_id) {
|
Result OpenContentMetaDatabase(std::shared_ptr<IContentMetaDatabase>* out, StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IContentMetaDatabase> content_meta_db = entry->content_meta_database;
|
std::shared_ptr<IContentMetaDatabase> content_meta_db = entry->content_meta_database;
|
||||||
|
|
||||||
if (!content_meta_db) {
|
if (!content_meta_db) {
|
||||||
/* 1.0.0 activates content meta dbs as soon as they are opened. */
|
/* 1.0.0 activates content meta dbs as soon as they are opened. */
|
||||||
if (GetRuntimeFirmwareVersion() == FirmwareVersion_100) {
|
if (hos::GetVersion() == hos::Version_100) {
|
||||||
R_TRY(ActivateContentMetaDatabase(storage_id));
|
R_TRY(ActivateContentMetaDatabase(storage_id));
|
||||||
content_meta_db = entry->content_meta_database;
|
content_meta_db = entry->content_meta_database;
|
||||||
} else {
|
} else {
|
||||||
switch (storage_id) {
|
switch (storage_id) {
|
||||||
case StorageId::GameCard:
|
case StorageId::GameCard:
|
||||||
return ResultNcmGameCardContentMetaDatabaseNotActive;
|
return ResultGameCardContentMetaDatabaseNotActive();
|
||||||
|
|
||||||
case StorageId::NandSystem:
|
case StorageId::BuiltInSystem:
|
||||||
return ResultNcmNandSystemContentMetaDatabaseNotActive;
|
return ResultNandSystemContentMetaDatabaseNotActive();
|
||||||
|
|
||||||
case StorageId::NandUser:
|
case StorageId::BuiltInUser:
|
||||||
return ResultNcmNandUserContentMetaDatabaseNotActive;
|
return ResultNandUserContentMetaDatabaseNotActive();
|
||||||
|
|
||||||
case StorageId::SdCard:
|
case StorageId::SdCard:
|
||||||
return ResultNcmSdCardContentMetaDatabaseNotActive;
|
return ResultSdCardContentMetaDatabaseNotActive();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ResultNcmUnknownContentMetaDatabaseNotActive;
|
return ResultUnknownContentMetaDatabaseNotActive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = std::move(content_meta_db);
|
*out = std::move(content_meta_db);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CloseContentMetaDatabaseForcibly(StorageId storage_id) {
|
Result CloseContentMetaDatabaseForcibly(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None) {
|
if (storage_id == StorageId::None) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IContentMetaDatabase> content_meta_db = entry->content_meta_database;
|
std::shared_ptr<IContentMetaDatabase> content_meta_db = entry->content_meta_database;
|
||||||
|
|
||||||
if (!content_meta_db) {
|
if (!content_meta_db) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* N doesn't bother checking the result of this */
|
/* N doesn't bother checking the result of this */
|
||||||
@ -627,38 +627,38 @@ namespace sts::ncm::impl {
|
|||||||
|
|
||||||
entry->content_meta_database = nullptr;
|
entry->content_meta_database = nullptr;
|
||||||
entry->kvs.reset();
|
entry->kvs.reset();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CleanupContentMetaDatabase(StorageId storage_id) {
|
Result CleanupContentMetaDatabase(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fsDeleteSaveDataFileSystemBySaveDataSpaceId(entry->save_meta.space_id, entry->save_meta.id));
|
R_TRY(fsDeleteSaveDataFileSystemBySaveDataSpaceId(entry->save_meta.space_id, entry->save_meta.id));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ActivateContentMetaDatabase(StorageId storage_id) {
|
Result ActivateContentMetaDatabase(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
/* Already activated. */
|
/* Already activated. */
|
||||||
if (entry->content_meta_database != nullptr) {
|
if (entry->content_meta_database != nullptr) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a brand new kvs. N doesn't quite do this, but we will for cleanliness. */
|
/* Make a brand new kvs. N doesn't quite do this, but we will for cleanliness. */
|
||||||
@ -680,21 +680,21 @@ namespace sts::ncm::impl {
|
|||||||
entry->content_meta_database = std::move(content_meta_database);
|
entry->content_meta_database = std::move(content_meta_database);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InactivateContentMetaDatabase(StorageId storage_id) {
|
Result InactivateContentMetaDatabase(StorageId storage_id) {
|
||||||
std::scoped_lock<HosMutex> lk(g_mutex);
|
std::scoped_lock<os::Mutex> lk(g_mutex);
|
||||||
|
|
||||||
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
if (storage_id == StorageId::None || static_cast<u8>(storage_id) == 6) {
|
||||||
return ResultNcmUnknownStorage;
|
return ResultUnknownStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
ContentMetaDBEntry* entry = FindContentMetaDBEntry(storage_id);
|
||||||
|
|
||||||
/* Already inactivated. */
|
/* Already inactivated. */
|
||||||
if (entry->content_meta_database == nullptr) {
|
if (entry->content_meta_database == nullptr) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->content_meta_database->DisableForcibly();
|
entry->content_meta_database->DisableForcibly();
|
||||||
@ -706,12 +706,12 @@ namespace sts::ncm::impl {
|
|||||||
fs::Unmount(entry->mount_point);
|
fs::Unmount(entry->mount_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InvalidateRightsIdCache() {
|
Result InvalidateRightsIdCache() {
|
||||||
g_rights_id_cache.Invalidate();
|
g_rights_id_cache.Invalidate();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "../ncm_icontentmetadatabase.hpp"
|
#include "../ncm_icontentmetadatabase.hpp"
|
||||||
#include "../ncm_icontentstorage.hpp"
|
#include "../ncm_icontentstorage.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace ams::ncm::impl {
|
||||||
|
|
||||||
/* Initialization/Finalization. */
|
/* Initialization/Finalization. */
|
||||||
Result InitializeContentManager();
|
Result InitializeContentManager();
|
||||||
|
@ -20,20 +20,20 @@
|
|||||||
#include "../ncm_make_path.hpp"
|
#include "../ncm_make_path.hpp"
|
||||||
#include "../ncm_path_utils.hpp"
|
#include "../ncm_path_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace ams::ncm::impl {
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Open(FILE** out_handle, PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::Open(FILE** out_handle, PlaceHolderId placeholder_id) {
|
||||||
if (this->LoadFromCache(out_handle, placeholder_id)) {
|
if (this->LoadFromCache(out_handle, placeholder_id)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
this->MakePath(placeholder_path, placeholder_id);
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
|
|
||||||
FILE* f = nullptr;
|
FILE* f = nullptr;
|
||||||
R_TRY(fs::OpenFile(&f, placeholder_path, FS_OPEN_WRITE));
|
R_TRY(fs::OpenFile(&f, placeholder_path, FsOpenMode_Write));
|
||||||
|
|
||||||
*out_handle = f;
|
*out_handle = f;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlaceHolderAccessor::LoadFromCache(FILE** out_handle, PlaceHolderId placeholder_id) {
|
bool PlaceHolderAccessor::LoadFromCache(FILE** out_handle, PlaceHolderId placeholder_id) {
|
||||||
@ -126,13 +126,13 @@ namespace sts::ncm::impl {
|
|||||||
this->EnsureRecursively(placeholder_id);
|
this->EnsureRecursively(placeholder_id);
|
||||||
this->GetPath(placeholder_path, placeholder_id);
|
this->GetPath(placeholder_path, placeholder_id);
|
||||||
|
|
||||||
R_TRY_CATCH(fsdevCreateFile(placeholder_path, size, FS_CREATE_BIG_FILE)) {
|
R_TRY_CATCH(fsdevCreateFile(placeholder_path, size, FsCreateOption_BigFile)) {
|
||||||
R_CATCH(ResultFsPathAlreadyExists) {
|
R_CATCH(ams::fs::ResultPathAlreadyExists) {
|
||||||
return ResultNcmPlaceHolderAlreadyExists;
|
return ResultPlaceHolderAlreadyExists();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Delete(PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::Delete(PlaceHolderId placeholder_id) {
|
||||||
@ -142,21 +142,21 @@ namespace sts::ncm::impl {
|
|||||||
|
|
||||||
if (std::remove(placeholder_path) != 0) {
|
if (std::remove(placeholder_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmPlaceHolderNotFound;
|
return ResultPlaceHolderNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Write(PlaceHolderId placeholder_id, size_t offset, const void* buffer, size_t size) {
|
Result PlaceHolderAccessor::Write(PlaceHolderId placeholder_id, size_t offset, const void* buffer, size_t size) {
|
||||||
FILE* f = nullptr;
|
FILE* f = nullptr;
|
||||||
|
|
||||||
R_TRY_CATCH(this->Open(&f, placeholder_id)) {
|
R_TRY_CATCH(this->Open(&f, placeholder_id)) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmPlaceHolderNotFound;
|
return ResultPlaceHolderNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ namespace sts::ncm::impl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
R_TRY(fs::WriteFile(f, offset, buffer, size, !this->delay_flush));
|
R_TRY(fs::WriteFile(f, offset, buffer, size, !this->delay_flush));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::SetSize(PlaceHolderId placeholder_id, size_t size) {
|
Result PlaceHolderAccessor::SetSize(PlaceHolderId placeholder_id, size_t size) {
|
||||||
@ -173,13 +173,13 @@ namespace sts::ncm::impl {
|
|||||||
this->MakePath(placeholder_path, placeholder_id);
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
if (truncate(placeholder_path, size) == -1) {
|
if (truncate(placeholder_path, size) == -1) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmPlaceHolderNotFound;
|
return ResultPlaceHolderNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::GetSize(bool* found_in_cache, size_t* out_size, PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::GetSize(bool* found_in_cache, size_t* out_size, PlaceHolderId placeholder_id) {
|
||||||
@ -191,14 +191,14 @@ namespace sts::ncm::impl {
|
|||||||
|
|
||||||
if (placeholder_id == InvalidPlaceHolderId) {
|
if (placeholder_id == InvalidPlaceHolderId) {
|
||||||
*found_in_cache = false;
|
*found_in_cache = false;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
CacheEntry* cache_entry = this->FindInCache(placeholder_id);
|
CacheEntry* cache_entry = this->FindInCache(placeholder_id);
|
||||||
|
|
||||||
if (cache_entry == nullptr) {
|
if (cache_entry == nullptr) {
|
||||||
*found_in_cache = false;
|
*found_in_cache = false;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_entry->id = InvalidPlaceHolderId;
|
cache_entry->id = InvalidPlaceHolderId;
|
||||||
@ -217,14 +217,14 @@ namespace sts::ncm::impl {
|
|||||||
|
|
||||||
*found_in_cache = true;
|
*found_in_cache = true;
|
||||||
*out_size = size;
|
*out_size = size;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::EnsureRecursively(PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::EnsureRecursively(PlaceHolderId placeholder_id) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
this->MakePath(placeholder_path, placeholder_id);
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
R_TRY(fs::EnsureParentDirectoryRecursively(placeholder_path));
|
R_TRY(fs::EnsureParentDirectoryRecursively(placeholder_path));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaceHolderAccessor::InvalidateAll() {
|
void PlaceHolderAccessor::InvalidateAll() {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "../ncm_path_utils.hpp"
|
#include "../ncm_path_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace ams::ncm::impl {
|
||||||
|
|
||||||
class PlaceHolderAccessor {
|
class PlaceHolderAccessor {
|
||||||
private:
|
private:
|
||||||
@ -36,7 +36,7 @@ namespace sts::ncm::impl {
|
|||||||
std::array<CacheEntry, MaxCaches> caches;
|
std::array<CacheEntry, MaxCaches> caches;
|
||||||
char* root_path;
|
char* root_path;
|
||||||
u64 cur_counter;
|
u64 cur_counter;
|
||||||
HosMutex cache_mutex;
|
os::Mutex cache_mutex;
|
||||||
MakePlaceHolderPathFunc make_placeholder_path_func;
|
MakePlaceHolderPathFunc make_placeholder_path_func;
|
||||||
bool delay_flush;
|
bool delay_flush;
|
||||||
private:
|
private:
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace ams::ncm::impl {
|
||||||
|
|
||||||
class RightsIdCache {
|
class RightsIdCache {
|
||||||
public:
|
public:
|
||||||
@ -34,7 +34,7 @@ namespace sts::ncm::impl {
|
|||||||
|
|
||||||
Entry entries[MaxEntries];
|
Entry entries[MaxEntries];
|
||||||
u64 counter;
|
u64 counter;
|
||||||
HosMutex mutex;
|
os::Mutex mutex;
|
||||||
|
|
||||||
RightsIdCache() {
|
RightsIdCache() {
|
||||||
this->Invalidate();
|
this->Invalidate();
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
#include "impl/ncm_content_manager.hpp"
|
#include "impl/ncm_content_manager.hpp"
|
||||||
#include "lr_addoncontentlocationresolver.hpp"
|
#include "lr_addoncontentlocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
Result AddOnContentLocationResolverInterface::ResolveAddOnContentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result AddOnContentLocationResolverInterface::ResolveAddOnContentPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
ncm::StorageId storage_id = ncm::StorageId::None;
|
ncm::StorageId storage_id = ncm::StorageId::None;
|
||||||
|
|
||||||
if (!this->registered_storages.Find(&storage_id, tid)) {
|
if (!this->registered_storages.Find(&storage_id, tid)) {
|
||||||
return ResultLrAddOnContentNotFound;
|
return ResultAddOnContentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ncm::IContentMetaDatabase> content_meta_database;
|
std::shared_ptr<ncm::IContentMetaDatabase> content_meta_database;
|
||||||
@ -34,45 +34,45 @@ namespace sts::lr {
|
|||||||
|
|
||||||
std::shared_ptr<ncm::IContentStorage> content_storage;
|
std::shared_ptr<ncm::IContentStorage> content_storage;
|
||||||
R_TRY(ncm::impl::OpenContentStorage(&content_storage, storage_id));
|
R_TRY(ncm::impl::OpenContentStorage(&content_storage, storage_id));
|
||||||
R_ASSERT(content_storage->GetPath(out.pointer, data_content_id));
|
R_ASSERT(content_storage->GetPath(out.GetPointer(), data_content_id));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::TitleId tid) {
|
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::ProgramId tid) {
|
||||||
if (!this->registered_storages.Register(tid, storage_id, ncm::TitleId::Invalid)) {
|
if (!this->registered_storages.Register(tid, storage_id, ncm::ProgramId::Invalid)) {
|
||||||
return ResultLrTooManyRegisteredPaths;
|
return ResultTooManyRegisteredPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::TitleId tid, ncm::TitleId application_tid) {
|
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::ProgramId tid, ncm::ProgramId application_tid) {
|
||||||
if (!this->registered_storages.Register(tid, storage_id, application_tid)) {
|
if (!this->registered_storages.Register(tid, storage_id, application_tid)) {
|
||||||
return ResultLrTooManyRegisteredPaths;
|
return ResultTooManyRegisteredPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddOnContentLocationResolverInterface::UnregisterAllAddOnContentPath() {
|
Result AddOnContentLocationResolverInterface::UnregisterAllAddOnContentPath() {
|
||||||
this->registered_storages.Clear();
|
this->registered_storages.Clear();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddOnContentLocationResolverInterface::RefreshApplicationAddOnContent(InBuffer<ncm::TitleId> tids) {
|
Result AddOnContentLocationResolverInterface::RefreshApplicationAddOnContent(const sf::InArray<ncm::ProgramId> &tids) {
|
||||||
if (tids.num_elements == 0) {
|
if (tids.GetSize() == 0) {
|
||||||
this->registered_storages.Clear();
|
this->registered_storages.Clear();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->registered_storages.ClearExcluding(tids.buffer, tids.num_elements);
|
this->registered_storages.ClearExcluding(tids.GetPointer(), tids.GetSize());
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddOnContentLocationResolverInterface::UnregisterApplicationAddOnContent(ncm::TitleId tid) {
|
Result AddOnContentLocationResolverInterface::UnregisterApplicationAddOnContent(ncm::ProgramId tid) {
|
||||||
this->registered_storages.UnregisterOwnerTitle(tid);
|
this->registered_storages.UnregisterOwnerTitle(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "impl/lr_registered_data.hpp"
|
#include "impl/lr_registered_data.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class AddOnContentLocationResolverInterface : public IServiceObject {
|
class AddOnContentLocationResolverInterface : public sf::IServiceObject {
|
||||||
protected:
|
protected:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
ResolveAddOnContentPath = 0,
|
ResolveAddOnContentPath = 0,
|
||||||
@ -33,24 +33,24 @@ namespace sts::lr {
|
|||||||
UnregisterApplicationAddOnContent = 4,
|
UnregisterApplicationAddOnContent = 4,
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
impl::RegisteredStorages<ncm::TitleId, 0x800> registered_storages;
|
impl::RegisteredStorages<ncm::ProgramId, 0x800> registered_storages;
|
||||||
public:
|
public:
|
||||||
AddOnContentLocationResolverInterface() : registered_storages(GetRuntimeFirmwareVersion() < FirmwareVersion_900 ? 0x800 : 0x2) { /* ... */ }
|
AddOnContentLocationResolverInterface() : registered_storages(hos::GetVersion() < hos::Version_900 ? 0x800 : 0x2) { /* ... */ }
|
||||||
|
|
||||||
virtual Result ResolveAddOnContentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveAddOnContentPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::TitleId tid);
|
virtual Result RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::ProgramId tid);
|
||||||
virtual Result RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::TitleId tid, ncm::TitleId application_tid);
|
virtual Result RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::ProgramId tid, ncm::ProgramId application_tid);
|
||||||
virtual Result UnregisterAllAddOnContentPath();
|
virtual Result UnregisterAllAddOnContentPath();
|
||||||
virtual Result RefreshApplicationAddOnContent(InBuffer<ncm::TitleId> tids);
|
virtual Result RefreshApplicationAddOnContent(const sf::InArray<ncm::ProgramId> &tids);
|
||||||
virtual Result UnregisterApplicationAddOnContent(ncm::TitleId tid);
|
virtual Result UnregisterApplicationAddOnContent(ncm::ProgramId tid);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, ResolveAddOnContentPath, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(ResolveAddOnContentPath, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RegisterAddOnContentStorageDeprecated, FirmwareVersion_200, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RegisterAddOnContentStorageDeprecated, hos::Version_200, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RegisterAddOnContentStorage, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RegisterAddOnContentStorage, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, UnregisterAllAddOnContentPath, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(UnregisterAllAddOnContentPath, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RefreshApplicationAddOnContent, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RefreshApplicationAddOnContent, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, UnregisterApplicationAddOnContent, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(UnregisterApplicationAddOnContent, hos::Version_900),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "impl/ncm_content_manager.hpp"
|
#include "impl/ncm_content_manager.hpp"
|
||||||
#include "lr_contentlocationresolver.hpp"
|
#include "lr_contentlocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
ContentLocationResolverInterface::~ContentLocationResolverInterface() {
|
ContentLocationResolverInterface::~ContentLocationResolverInterface() {
|
||||||
this->ClearRedirections();
|
this->ClearRedirections();
|
||||||
@ -27,88 +27,88 @@ namespace sts::lr {
|
|||||||
R_ASSERT(this->content_storage->GetPath(out, content_id));
|
R_ASSERT(this->content_storage->GetPath(out, content_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->program_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->program_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
ncm::ContentId program_content_id;
|
ncm::ContentId program_content_id;
|
||||||
|
|
||||||
R_TRY_CATCH(this->content_meta_database->GetLatestProgram(&program_content_id, tid)) {
|
R_TRY_CATCH(this->content_meta_database->GetLatestProgram(&program_content_id, tid)) {
|
||||||
R_CATCH(ResultNcmContentMetaNotFound) {
|
R_CATCH(ncm::ResultContentMetaNotFound) {
|
||||||
return ResultLrProgramNotFound;
|
return ResultProgramNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
this->GetContentStoragePath(out.pointer, program_content_id);
|
this->GetContentStoragePath(out.GetPointer(), program_content_id);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectProgramPath(const Path &path, ncm::ProgramId tid) {
|
||||||
this->program_redirector.SetRedirection(tid, *path.pointer);
|
this->program_redirector.SetRedirection(tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ResolveApplicationControlPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->app_control_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->app_control_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrControlNotFound;
|
return ResultControlNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ResolveApplicationHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->html_docs_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->html_docs_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrHtmlDocumentNotFound;
|
return ResultHtmlDocumentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ResolveDataPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::ResolveDataPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
ncm::ContentId data_content_id;
|
ncm::ContentId data_content_id;
|
||||||
|
|
||||||
R_TRY(this->content_meta_database->GetLatestData(&data_content_id, tid));
|
R_TRY(this->content_meta_database->GetLatestData(&data_content_id, tid));
|
||||||
this->GetContentStoragePath(out.pointer, data_content_id);
|
this->GetContentStoragePath(out.GetPointer(), data_content_id);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationControlPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->app_control_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->app_control_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationControlPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationControlPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->app_control_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->app_control_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->html_docs_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->html_docs_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->html_docs_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->html_docs_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ResolveApplicationLegalInformationPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->legal_info_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->legal_info_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrLegalInformationNotFound;
|
return ResultLegalInformationNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationLegalInformationPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->legal_info_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->legal_info_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationLegalInformationPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->legal_info_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->legal_info_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::Refresh() {
|
Result ContentLocationResolverInterface::Refresh() {
|
||||||
@ -121,81 +121,81 @@ namespace sts::lr {
|
|||||||
this->content_storage = std::move(content_storage);
|
this->content_storage = std::move(content_storage);
|
||||||
this->ClearRedirections();
|
this->ClearRedirections();
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->program_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->program_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->program_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->program_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ClearApplicationRedirectionDeprecated() {
|
Result ContentLocationResolverInterface::ClearApplicationRedirectionDeprecated() {
|
||||||
this->ClearRedirections(impl::RedirectionFlags_Application);
|
this->ClearRedirections(impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ClearApplicationRedirection(InBuffer<ncm::TitleId> excluding_tids) {
|
Result ContentLocationResolverInterface::ClearApplicationRedirection(const sf::InArray<ncm::ProgramId> &excluding_tids) {
|
||||||
this->ClearRedirections(excluding_tids.buffer, excluding_tids.num_elements);
|
this->ClearRedirections(excluding_tids.GetPointer(), excluding_tids.GetSize());
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::EraseProgramRedirection(ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::EraseProgramRedirection(ncm::ProgramId tid) {
|
||||||
this->program_redirector.EraseRedirection(tid);
|
this->program_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::EraseApplicationControlRedirection(ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::EraseApplicationControlRedirection(ncm::ProgramId tid) {
|
||||||
this->app_control_redirector.EraseRedirection(tid);
|
this->app_control_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::EraseApplicationHtmlDocumentRedirection(ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::EraseApplicationHtmlDocumentRedirection(ncm::ProgramId tid) {
|
||||||
this->html_docs_redirector.EraseRedirection(tid);
|
this->html_docs_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::EraseApplicationLegalInformationRedirection(ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::EraseApplicationLegalInformationRedirection(ncm::ProgramId tid) {
|
||||||
this->legal_info_redirector.EraseRedirection(tid);
|
this->legal_info_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::ResolveProgramPathForDebug(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->debug_program_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->debug_program_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY_CATCH(this->ResolveProgramPath(out.pointer, tid)) {
|
R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), tid)) {
|
||||||
R_CATCH(ResultLrProgramNotFound) {
|
R_CATCH(ResultProgramNotFound) {
|
||||||
return ResultLrDebugProgramNotFound;
|
return ResultDebugProgramNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectProgramPathForDebug(const Path &path, ncm::ProgramId tid) {
|
||||||
this->debug_program_redirector.SetRedirection(tid, *path.pointer);
|
this->debug_program_redirector.SetRedirection(tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationProgramPathForDebugDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->debug_program_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->debug_program_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::RedirectApplicationProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result ContentLocationResolverInterface::RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->debug_program_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->debug_program_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverInterface::EraseProgramRedirectionForDebug(ncm::TitleId tid) {
|
Result ContentLocationResolverInterface::EraseProgramRedirectionForDebug(ncm::ProgramId tid) {
|
||||||
this->debug_program_redirector.EraseRedirection(tid);
|
this->debug_program_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "ncm_icontentmetadatabase.hpp"
|
#include "ncm_icontentmetadatabase.hpp"
|
||||||
#include "ncm_icontentstorage.hpp"
|
#include "ncm_icontentstorage.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class ContentLocationResolverInterface : public ILocationResolver {
|
class ContentLocationResolverInterface : public ILocationResolver {
|
||||||
private:
|
private:
|
||||||
@ -37,32 +37,32 @@ namespace sts::lr {
|
|||||||
private:
|
private:
|
||||||
void GetContentStoragePath(Path* out, ncm::ContentId content_id);
|
void GetContentStoragePath(Path* out, ncm::ContentId content_id);
|
||||||
public:
|
public:
|
||||||
virtual Result ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveApplicationControlPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveApplicationHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveDataPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveDataPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationControlPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationControlPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationControlPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result RedirectApplicationHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result ResolveApplicationLegalInformationPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationLegalInformationPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationLegalInformationPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result Refresh() override;
|
virtual Result Refresh() override;
|
||||||
virtual Result RedirectApplicationProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result ClearApplicationRedirectionDeprecated() override;
|
virtual Result ClearApplicationRedirectionDeprecated() override;
|
||||||
virtual Result ClearApplicationRedirection(InBuffer<ncm::TitleId> excluding_tids) override;
|
virtual Result ClearApplicationRedirection(const sf::InArray<ncm::ProgramId> &excluding_tids) override;
|
||||||
virtual Result EraseProgramRedirection(ncm::TitleId tid) override;
|
virtual Result EraseProgramRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result EraseApplicationControlRedirection(ncm::TitleId tid) override;
|
virtual Result EraseApplicationControlRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result EraseApplicationHtmlDocumentRedirection(ncm::TitleId tid) override;
|
virtual Result EraseApplicationHtmlDocumentRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result EraseApplicationLegalInformationRedirection(ncm::TitleId tid) override;
|
virtual Result EraseApplicationLegalInformationRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveProgramPathForDebug(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectProgramPathForDebug(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationProgramPathForDebugDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result EraseProgramRedirectionForDebug(ncm::TitleId tid) override;
|
virtual Result EraseProgramRedirectionForDebug(ncm::ProgramId tid) override;
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveProgramPath),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveProgramPath),
|
||||||
@ -70,27 +70,27 @@ namespace sts::lr {
|
|||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveApplicationControlPath),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveApplicationControlPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveApplicationHtmlDocumentPath),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveApplicationHtmlDocumentPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveDataPath),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveDataPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationControlPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationControlPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationControlPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationControlPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationHtmlDocumentPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationHtmlDocumentPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationHtmlDocumentPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationHtmlDocumentPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveApplicationLegalInformationPath),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveApplicationLegalInformationPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationLegalInformationPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationLegalInformationPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationLegalInformationPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationLegalInformationPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, Refresh),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, Refresh),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPathDeprecated, FirmwareVersion_500, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPathDeprecated, hos::Version_500, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ClearApplicationRedirectionDeprecated, FirmwareVersion_500, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ClearApplicationRedirectionDeprecated, hos::Version_500, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ClearApplicationRedirection, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ClearApplicationRedirection, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseProgramRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseProgramRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseApplicationControlRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseApplicationControlRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseApplicationHtmlDocumentRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseApplicationHtmlDocumentRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseApplicationLegalInformationRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseApplicationLegalInformationRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveProgramPathForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, ResolveProgramPathForDebug, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectProgramPathForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectProgramPathForDebug, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPathForDebugDeprecated, FirmwareVersion_700, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPathForDebugDeprecated, hos::Version_700, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPathForDebug, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, RedirectApplicationProgramPathForDebug, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseProgramRedirectionForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(ContentLocationResolverInterface, EraseProgramRedirectionForDebug, hos::Version_700),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019 Adubbz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lr_ilocationresolver.hpp"
|
|
||||||
|
|
||||||
namespace sts::lr {
|
|
||||||
|
|
||||||
Result ILocationResolver::ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ResolveApplicationControlPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ResolveApplicationHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ResolveDataPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationControlPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationControlPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ResolveApplicationLegalInformationPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationLegalInformationPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationLegalInformationPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::Refresh() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ClearApplicationRedirectionDeprecated() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ClearApplicationRedirection(InBuffer<ncm::TitleId> excluding_tids) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::EraseProgramRedirection(ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::EraseApplicationControlRedirection(ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::EraseApplicationHtmlDocumentRedirection(ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::EraseApplicationLegalInformationRedirection(ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::ResolveProgramPathForDebug(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationProgramPathForDebugDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::RedirectApplicationProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ILocationResolver::EraseProgramRedirectionForDebug(ncm::TitleId tid) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
#include "impl/lr_redirection.hpp"
|
#include "impl/lr_redirection.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class ILocationResolver : public IServiceObject {
|
class ILocationResolver : public sf::IServiceObject {
|
||||||
protected:
|
protected:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
ResolveProgramPath = 0,
|
ResolveProgramPath = 0,
|
||||||
@ -59,7 +59,7 @@ namespace sts::lr {
|
|||||||
impl::LocationRedirector html_docs_redirector;
|
impl::LocationRedirector html_docs_redirector;
|
||||||
impl::LocationRedirector legal_info_redirector;
|
impl::LocationRedirector legal_info_redirector;
|
||||||
protected:
|
protected:
|
||||||
bool GetRedirectedPath(Path* out, impl::LocationRedirector* redirector, ncm::TitleId tid) {
|
bool GetRedirectedPath(Path* out, impl::LocationRedirector* redirector, ncm::ProgramId tid) {
|
||||||
return redirector->FindRedirection(out, tid);
|
return redirector->FindRedirection(out, tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ namespace sts::lr {
|
|||||||
this->legal_info_redirector.ClearRedirections(flags);
|
this->legal_info_redirector.ClearRedirections(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearRedirections(const ncm::TitleId* excluding_tids, size_t num_tids) {
|
void ClearRedirections(const ncm::ProgramId* excluding_tids, size_t num_tids) {
|
||||||
this->program_redirector.ClearRedirections(excluding_tids, num_tids);
|
this->program_redirector.ClearRedirections(excluding_tids, num_tids);
|
||||||
this->debug_program_redirector.ClearRedirections(excluding_tids, num_tids);
|
this->debug_program_redirector.ClearRedirections(excluding_tids, num_tids);
|
||||||
this->app_control_redirector.ClearRedirections(excluding_tids, num_tids);
|
this->app_control_redirector.ClearRedirections(excluding_tids, num_tids);
|
||||||
@ -79,60 +79,60 @@ namespace sts::lr {
|
|||||||
this->legal_info_redirector.ClearRedirections(excluding_tids, num_tids);
|
this->legal_info_redirector.ClearRedirections(excluding_tids, num_tids);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual Result ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result ResolveApplicationControlPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result ResolveApplicationHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result ResolveDataPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveDataPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationControlPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationControlPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
virtual Result RedirectApplicationControlPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
virtual Result RedirectApplicationHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
virtual Result RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
virtual Result ResolveApplicationLegalInformationPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationLegalInformationPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationLegalInformationPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
virtual Result RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
virtual Result Refresh();
|
virtual Result Refresh();
|
||||||
virtual Result RedirectApplicationProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
virtual Result RedirectApplicationProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
virtual Result ClearApplicationRedirectionDeprecated();
|
virtual Result ClearApplicationRedirectionDeprecated();
|
||||||
virtual Result ClearApplicationRedirection(InBuffer<ncm::TitleId> excluding_tids);
|
virtual Result ClearApplicationRedirection(const sf::InArray<ncm::ProgramId> &excluding_tids);
|
||||||
virtual Result EraseProgramRedirection(ncm::TitleId tid);
|
virtual Result EraseProgramRedirection(ncm::ProgramId tid);
|
||||||
virtual Result EraseApplicationControlRedirection(ncm::TitleId tid);
|
virtual Result EraseApplicationControlRedirection(ncm::ProgramId tid);
|
||||||
virtual Result EraseApplicationHtmlDocumentRedirection(ncm::TitleId tid);
|
virtual Result EraseApplicationHtmlDocumentRedirection(ncm::ProgramId tid);
|
||||||
virtual Result EraseApplicationLegalInformationRedirection(ncm::TitleId tid);
|
virtual Result EraseApplicationLegalInformationRedirection(ncm::ProgramId tid);
|
||||||
virtual Result ResolveProgramPathForDebug(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
virtual Result ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
virtual Result RedirectProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectProgramPathForDebug(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationProgramPathForDebugDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
virtual Result RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
virtual Result RedirectApplicationProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
virtual Result RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
virtual Result EraseProgramRedirectionForDebug(ncm::TitleId tid);
|
virtual Result EraseProgramRedirectionForDebug(ncm::ProgramId tid);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ResolveProgramPath),
|
MAKE_SERVICE_COMMAND_META(ResolveProgramPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectProgramPath),
|
MAKE_SERVICE_COMMAND_META(RedirectProgramPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ResolveApplicationControlPath),
|
MAKE_SERVICE_COMMAND_META(ResolveApplicationControlPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ResolveApplicationHtmlDocumentPath),
|
MAKE_SERVICE_COMMAND_META(ResolveApplicationHtmlDocumentPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ResolveDataPath),
|
MAKE_SERVICE_COMMAND_META(ResolveDataPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationControlPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationControlPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationHtmlDocumentPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationHtmlDocumentPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ResolveApplicationLegalInformationPath),
|
MAKE_SERVICE_COMMAND_META(ResolveApplicationLegalInformationPath),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationLegalInformationPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationLegalInformationPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, Refresh),
|
MAKE_SERVICE_COMMAND_META(Refresh),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationProgramPathDeprecated, FirmwareVersion_500, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathDeprecated, hos::Version_500, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationProgramPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ClearApplicationRedirectionDeprecated, FirmwareVersion_500, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ClearApplicationRedirectionDeprecated, hos::Version_500, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ClearApplicationRedirection, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ClearApplicationRedirection, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, EraseProgramRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseProgramRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, EraseApplicationControlRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseApplicationControlRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, EraseApplicationHtmlDocumentRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseApplicationHtmlDocumentRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, EraseApplicationLegalInformationRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseApplicationLegalInformationRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, ResolveProgramPathForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(ResolveProgramPathForDebug, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectProgramPathForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(RedirectProgramPathForDebug, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationProgramPathForDebugDeprecated, FirmwareVersion_700, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebugDeprecated, hos::Version_700, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, RedirectApplicationProgramPathForDebug, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebug, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(ILocationResolver, EraseProgramRedirectionForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(EraseProgramRedirectionForDebug, hos::Version_700),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,13 +18,13 @@
|
|||||||
#include "impl/lr_manager.hpp"
|
#include "impl/lr_manager.hpp"
|
||||||
#include "lr_manager_service.hpp"
|
#include "lr_manager_service.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
Result LocationResolverManagerService::OpenLocationResolver(Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id) {
|
Result LocationResolverManagerService::OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id) {
|
||||||
return impl::OpenLocationResolver(out, storage_id);
|
return impl::OpenLocationResolver(out, storage_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LocationResolverManagerService::OpenRegisteredLocationResolver(Out<std::shared_ptr<RegisteredLocationResolverInterface>> out) {
|
Result LocationResolverManagerService::OpenRegisteredLocationResolver(sf::Out<std::shared_ptr<RegisteredLocationResolverInterface>> out) {
|
||||||
return impl::OpenRegisteredLocationResolver(out);
|
return impl::OpenRegisteredLocationResolver(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ namespace sts::lr {
|
|||||||
return impl::RefreshLocationResolver(storage_id);
|
return impl::RefreshLocationResolver(storage_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LocationResolverManagerService::OpenAddOnContentLocationResolver(Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out) {
|
Result LocationResolverManagerService::OpenAddOnContentLocationResolver(sf::Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out) {
|
||||||
return impl::OpenAddOnContentLocationResolver(out);
|
return impl::OpenAddOnContentLocationResolver(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
#include "lr_ilocationresolver.hpp"
|
#include "lr_ilocationresolver.hpp"
|
||||||
#include "lr_registeredlocationresolver.hpp"
|
#include "lr_registeredlocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class LocationResolverManagerService final : public IServiceObject {
|
class LocationResolverManagerService final : public sf::IServiceObject {
|
||||||
protected:
|
protected:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
OpenLocationResolver = 0,
|
OpenLocationResolver = 0,
|
||||||
@ -34,16 +34,16 @@ namespace sts::lr {
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result OpenLocationResolver(Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id);
|
virtual Result OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolver>> out, ncm::StorageId storage_id);
|
||||||
virtual Result OpenRegisteredLocationResolver(Out<std::shared_ptr<RegisteredLocationResolverInterface>> out);
|
virtual Result OpenRegisteredLocationResolver(sf::Out<std::shared_ptr<RegisteredLocationResolverInterface>> out);
|
||||||
virtual Result RefreshLocationResolver(ncm::StorageId storage_id);
|
virtual Result RefreshLocationResolver(ncm::StorageId storage_id);
|
||||||
virtual Result OpenAddOnContentLocationResolver(Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out);
|
virtual Result OpenAddOnContentLocationResolver(sf::Out<std::shared_ptr<AddOnContentLocationResolverInterface>> out);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(LocationResolverManagerService, OpenLocationResolver),
|
MAKE_SERVICE_COMMAND_META(OpenLocationResolver),
|
||||||
MAKE_SERVICE_COMMAND_META(LocationResolverManagerService, OpenRegisteredLocationResolver),
|
MAKE_SERVICE_COMMAND_META(OpenRegisteredLocationResolver),
|
||||||
MAKE_SERVICE_COMMAND_META(LocationResolverManagerService, RefreshLocationResolver),
|
MAKE_SERVICE_COMMAND_META(RefreshLocationResolver),
|
||||||
MAKE_SERVICE_COMMAND_META(LocationResolverManagerService, OpenAddOnContentLocationResolver, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(OpenAddOnContentLocationResolver, hos::Version_200),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "impl/ncm_content_manager.hpp"
|
#include "impl/ncm_content_manager.hpp"
|
||||||
#include "lr_redirectonlylocationresolver.hpp"
|
#include "lr_redirectonlylocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
RedirectOnlyLocationResolverInterface::~RedirectOnlyLocationResolverInterface() {
|
RedirectOnlyLocationResolverInterface::~RedirectOnlyLocationResolverInterface() {
|
||||||
this->program_redirector.ClearRedirections();
|
this->program_redirector.ClearRedirections();
|
||||||
@ -27,75 +27,75 @@ namespace sts::lr {
|
|||||||
this->legal_info_redirector.ClearRedirections();
|
this->legal_info_redirector.ClearRedirections();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->program_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->program_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrProgramNotFound;
|
return ResultProgramNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectProgramPath(const Path &path, ncm::ProgramId tid) {
|
||||||
this->program_redirector.SetRedirection(tid, *path.pointer);
|
this->program_redirector.SetRedirection(tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ResolveApplicationControlPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->app_control_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->app_control_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrControlNotFound;
|
return ResultControlNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ResolveApplicationHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->html_docs_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->html_docs_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrHtmlDocumentNotFound;
|
return ResultHtmlDocumentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ResolveDataPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::ResolveDataPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
return ResultLrDataNotFound;
|
return ResultDataNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationControlPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->app_control_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->app_control_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationControlPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationControlPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->app_control_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->app_control_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->html_docs_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->html_docs_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->html_docs_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->html_docs_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ResolveApplicationLegalInformationPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->legal_info_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->legal_info_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultLrLegalInformationNotFound;
|
return ResultLegalInformationNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationLegalInformationPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->legal_info_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->legal_info_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationLegalInformationPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->legal_info_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->legal_info_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::Refresh() {
|
Result RedirectOnlyLocationResolverInterface::Refresh() {
|
||||||
@ -104,17 +104,17 @@ namespace sts::lr {
|
|||||||
this->app_control_redirector.ClearRedirections();
|
this->app_control_redirector.ClearRedirections();
|
||||||
this->html_docs_redirector.ClearRedirections();
|
this->html_docs_redirector.ClearRedirections();
|
||||||
this->legal_info_redirector.ClearRedirections();
|
this->legal_info_redirector.ClearRedirections();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->program_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->program_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->program_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->program_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ClearApplicationRedirectionDeprecated() {
|
Result RedirectOnlyLocationResolverInterface::ClearApplicationRedirectionDeprecated() {
|
||||||
@ -123,66 +123,66 @@ namespace sts::lr {
|
|||||||
this->app_control_redirector.ClearRedirections(impl::RedirectionFlags_Application);
|
this->app_control_redirector.ClearRedirections(impl::RedirectionFlags_Application);
|
||||||
this->html_docs_redirector.ClearRedirections(impl::RedirectionFlags_Application);
|
this->html_docs_redirector.ClearRedirections(impl::RedirectionFlags_Application);
|
||||||
this->legal_info_redirector.ClearRedirections(impl::RedirectionFlags_Application);
|
this->legal_info_redirector.ClearRedirections(impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ClearApplicationRedirection(InBuffer<ncm::TitleId> excluding_tids) {
|
Result RedirectOnlyLocationResolverInterface::ClearApplicationRedirection(const sf::InArray<ncm::ProgramId> &excluding_tids) {
|
||||||
this->ClearRedirections(excluding_tids.buffer, excluding_tids.num_elements);
|
this->ClearRedirections(excluding_tids.GetPointer(), excluding_tids.GetSize());
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::EraseProgramRedirection(ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::EraseProgramRedirection(ncm::ProgramId tid) {
|
||||||
this->program_redirector.EraseRedirection(tid);
|
this->program_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::EraseApplicationControlRedirection(ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::EraseApplicationControlRedirection(ncm::ProgramId tid) {
|
||||||
this->app_control_redirector.EraseRedirection(tid);
|
this->app_control_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::EraseApplicationHtmlDocumentRedirection(ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::EraseApplicationHtmlDocumentRedirection(ncm::ProgramId tid) {
|
||||||
this->html_docs_redirector.EraseRedirection(tid);
|
this->html_docs_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::EraseApplicationLegalInformationRedirection(ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::EraseApplicationLegalInformationRedirection(ncm::ProgramId tid) {
|
||||||
this->legal_info_redirector.EraseRedirection(tid);
|
this->legal_info_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::ResolveProgramPathForDebug(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (this->GetRedirectedPath(out.pointer, &this->debug_program_redirector, tid)) {
|
if (this->GetRedirectedPath(out.GetPointer(), &this->debug_program_redirector, tid)) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY_CATCH(this->ResolveProgramPath(out.pointer, tid)) {
|
R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), tid)) {
|
||||||
R_CATCH(ResultLrProgramNotFound) {
|
R_CATCH(ResultProgramNotFound) {
|
||||||
return ResultLrDebugProgramNotFound;
|
return ResultDebugProgramNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectProgramPathForDebug(const Path &path, ncm::ProgramId tid) {
|
||||||
this->debug_program_redirector.SetRedirection(tid, *path.pointer);
|
this->debug_program_redirector.SetRedirection(tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPathForDebugDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->debug_program_redirector.SetRedirection(tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->debug_program_redirector.SetRedirection(tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RedirectOnlyLocationResolverInterface::RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->debug_program_redirector.SetRedirection(tid, owner_tid, *path.pointer, impl::RedirectionFlags_Application);
|
this->debug_program_redirector.SetRedirection(tid, owner_tid, path, impl::RedirectionFlags_Application);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverInterface::EraseProgramRedirectionForDebug(ncm::TitleId tid) {
|
Result RedirectOnlyLocationResolverInterface::EraseProgramRedirectionForDebug(ncm::ProgramId tid) {
|
||||||
this->debug_program_redirector.EraseRedirection(tid);
|
this->debug_program_redirector.EraseRedirection(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,66 +20,66 @@
|
|||||||
|
|
||||||
#include "lr_contentlocationresolver.hpp"
|
#include "lr_contentlocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class RedirectOnlyLocationResolverInterface : public ILocationResolver {
|
class RedirectOnlyLocationResolverInterface : public ILocationResolver {
|
||||||
public:
|
public:
|
||||||
~RedirectOnlyLocationResolverInterface();
|
~RedirectOnlyLocationResolverInterface();
|
||||||
public:
|
public:
|
||||||
virtual Result ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveApplicationControlPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveApplicationHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveDataPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveDataPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationControlPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationControlPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationControlPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result RedirectApplicationHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result ResolveApplicationLegalInformationPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationLegalInformationPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationLegalInformationPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result Refresh() override;
|
virtual Result Refresh() override;
|
||||||
virtual Result RedirectApplicationProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result ClearApplicationRedirectionDeprecated() override;
|
virtual Result ClearApplicationRedirectionDeprecated() override;
|
||||||
virtual Result ClearApplicationRedirection(InBuffer<ncm::TitleId> excluding_tids) override;
|
virtual Result ClearApplicationRedirection(const sf::InArray<ncm::ProgramId> &excluding_tids) override;
|
||||||
virtual Result EraseProgramRedirection(ncm::TitleId tid) override;
|
virtual Result EraseProgramRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result EraseApplicationControlRedirection(ncm::TitleId tid) override;
|
virtual Result EraseApplicationControlRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result EraseApplicationHtmlDocumentRedirection(ncm::TitleId tid) override;
|
virtual Result EraseApplicationHtmlDocumentRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result EraseApplicationLegalInformationRedirection(ncm::TitleId tid) override;
|
virtual Result EraseApplicationLegalInformationRedirection(ncm::ProgramId tid) override;
|
||||||
virtual Result ResolveProgramPathForDebug(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) override;
|
virtual Result ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectProgramPathForDebug(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationProgramPathForDebugDeprecated(InPointer<const Path> path, ncm::TitleId tid) override;
|
virtual Result RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId tid) override;
|
||||||
virtual Result RedirectApplicationProgramPathForDebug(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) override;
|
virtual Result RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) override;
|
||||||
virtual Result EraseProgramRedirectionForDebug(ncm::TitleId tid) override;
|
virtual Result EraseProgramRedirectionForDebug(ncm::ProgramId tid) override;
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ResolveProgramPath),
|
MAKE_SERVICE_COMMAND_META(ResolveProgramPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectProgramPath),
|
MAKE_SERVICE_COMMAND_META(RedirectProgramPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ResolveApplicationControlPath),
|
MAKE_SERVICE_COMMAND_META(ResolveApplicationControlPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ResolveApplicationHtmlDocumentPath),
|
MAKE_SERVICE_COMMAND_META(ResolveApplicationHtmlDocumentPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ResolveDataPath),
|
MAKE_SERVICE_COMMAND_META(ResolveDataPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationControlPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationControlPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationControlPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationHtmlDocumentPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationHtmlDocumentPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationHtmlDocumentPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ResolveApplicationLegalInformationPath),
|
MAKE_SERVICE_COMMAND_META(ResolveApplicationLegalInformationPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationLegalInformationPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationLegalInformationPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationLegalInformationPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, Refresh),
|
MAKE_SERVICE_COMMAND_META(Refresh),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationProgramPathDeprecated, FirmwareVersion_500, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathDeprecated, hos::Version_500, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationProgramPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ClearApplicationRedirectionDeprecated, FirmwareVersion_500, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(ClearApplicationRedirectionDeprecated, hos::Version_500, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ClearApplicationRedirection, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(ClearApplicationRedirection, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, EraseProgramRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseProgramRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, EraseApplicationControlRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseApplicationControlRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, EraseApplicationHtmlDocumentRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseApplicationHtmlDocumentRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, EraseApplicationLegalInformationRedirection, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(EraseApplicationLegalInformationRedirection, hos::Version_500),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, ResolveProgramPathForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(ResolveProgramPathForDebug, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectProgramPathForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(RedirectProgramPathForDebug, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationProgramPathForDebugDeprecated, FirmwareVersion_700, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebugDeprecated, hos::Version_700, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, RedirectApplicationProgramPathForDebug, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectApplicationProgramPathForDebug, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RedirectOnlyLocationResolverInterface, EraseProgramRedirectionForDebug, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(EraseProgramRedirectionForDebug, hos::Version_700),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include "lr_registeredlocationresolver.hpp"
|
#include "lr_registeredlocationresolver.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
RegisteredLocationResolverInterface::~RegisteredLocationResolverInterface() {
|
RegisteredLocationResolverInterface::~RegisteredLocationResolverInterface() {
|
||||||
/* Ensure entries are deallocated */
|
/* Ensure entries are deallocated */
|
||||||
@ -28,14 +28,14 @@ namespace sts::lr {
|
|||||||
this->program_redirector.ClearRedirections();
|
this->program_redirector.ClearRedirections();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisteredLocationResolverInterface::RegisterPath(const Path& path, impl::RegisteredLocations<ncm::TitleId, RegisteredLocationResolverInterface::MaxRegisteredLocations>* locations, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
void RegisteredLocationResolverInterface::RegisterPath(const Path& path, impl::RegisteredLocations<ncm::ProgramId, RegisteredLocationResolverInterface::MaxRegisteredLocations>* locations, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
if (!locations->Register(tid, path, owner_tid)) {
|
if (!locations->Register(tid, path, owner_tid)) {
|
||||||
locations->Clear();
|
locations->Clear();
|
||||||
locations->Register(tid, path, owner_tid);
|
locations->Register(tid, path, owner_tid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegisteredLocationResolverInterface::ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::TitleId, RegisteredLocationResolverInterface::MaxRegisteredLocations>* locations, ncm::TitleId tid) {
|
bool RegisteredLocationResolverInterface::ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::ProgramId, RegisteredLocationResolverInterface::MaxRegisteredLocations>* locations, ncm::ProgramId tid) {
|
||||||
if (!redirector->FindRedirection(out, tid)) {
|
if (!redirector->FindRedirection(out, tid)) {
|
||||||
if (!locations->Find(out, tid)) {
|
if (!locations->Find(out, tid)) {
|
||||||
return false;
|
return false;
|
||||||
@ -44,10 +44,10 @@ namespace sts::lr {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RefreshImpl(const ncm::TitleId* excluding_tids, size_t num_tids) {
|
Result RegisteredLocationResolverInterface::RefreshImpl(const ncm::ProgramId* excluding_tids, size_t num_tids) {
|
||||||
if (GetRuntimeFirmwareVersion() < FirmwareVersion_900) {
|
if (hos::GetVersion() < hos::Version_900) {
|
||||||
this->ClearRedirections();
|
this->ClearRedirections();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_tids == 0) {
|
if (num_tids == 0) {
|
||||||
@ -59,81 +59,81 @@ namespace sts::lr {
|
|||||||
|
|
||||||
this->program_redirector.ClearRedirections(excluding_tids, num_tids);
|
this->program_redirector.ClearRedirections(excluding_tids, num_tids);
|
||||||
this->html_docs_redirector.ClearRedirections(excluding_tids, num_tids);
|
this->html_docs_redirector.ClearRedirections(excluding_tids, num_tids);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (!this->ResolvePath(out.pointer, &this->program_redirector, &this->registered_program_locations, tid)) {
|
if (!this->ResolvePath(out.GetPointer(), &this->program_redirector, &this->registered_program_locations, tid)) {
|
||||||
return ResultLrProgramNotFound;
|
return ResultProgramNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RegisterProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::RegisterProgramPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->RegisterPath(*path.pointer, &this->registered_program_locations, tid, ncm::TitleId::Invalid);
|
this->RegisterPath(path, &this->registered_program_locations, tid, ncm::ProgramId::Invalid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RegisterProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RegisteredLocationResolverInterface::RegisterProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->RegisterPath(*path.pointer, &this->registered_program_locations, tid, owner_tid);
|
this->RegisterPath(path, &this->registered_program_locations, tid, owner_tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::UnregisterProgramPath(ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::UnregisterProgramPath(ncm::ProgramId tid) {
|
||||||
this->registered_program_locations.Unregister(tid);
|
this->registered_program_locations.Unregister(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RedirectProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::RedirectProgramPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->program_redirector.SetRedirection(tid, *path.pointer);
|
this->program_redirector.SetRedirection(tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RegisteredLocationResolverInterface::RedirectProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->program_redirector.SetRedirection(tid, owner_tid, *path.pointer);
|
this->program_redirector.SetRedirection(tid, owner_tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::ResolveHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::ResolveHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid) {
|
||||||
if (!this->ResolvePath(out.pointer, &this->html_docs_redirector, &this->registered_html_docs_locations, tid)) {
|
if (!this->ResolvePath(out.GetPointer(), &this->html_docs_redirector, &this->registered_html_docs_locations, tid)) {
|
||||||
return ResultLrHtmlDocumentNotFound;
|
return ResultHtmlDocumentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->RegisterPath(*path.pointer, &this->registered_html_docs_locations, tid, ncm::TitleId::Invalid);
|
this->RegisterPath(path, &this->registered_html_docs_locations, tid, ncm::ProgramId::Invalid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->RegisterPath(*path.pointer, &this->registered_html_docs_locations, tid, owner_tid);
|
this->RegisterPath(path, &this->registered_html_docs_locations, tid, owner_tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::UnregisterHtmlDocumentPath(ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::UnregisterHtmlDocumentPath(ncm::ProgramId tid) {
|
||||||
this->registered_html_docs_locations.Unregister(tid);
|
this->registered_html_docs_locations.Unregister(tid);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
|
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid) {
|
||||||
this->html_docs_redirector.SetRedirection(tid, *path.pointer);
|
this->html_docs_redirector.SetRedirection(tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid) {
|
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid) {
|
||||||
this->html_docs_redirector.SetRedirection(tid, owner_tid, *path.pointer);
|
this->html_docs_redirector.SetRedirection(tid, owner_tid, path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::Refresh() {
|
Result RegisteredLocationResolverInterface::Refresh() {
|
||||||
return this->RefreshImpl(nullptr, 0);
|
return this->RefreshImpl(nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverInterface::RefreshExcluding(InBuffer<ncm::TitleId> tids) {
|
Result RegisteredLocationResolverInterface::RefreshExcluding(const sf::InArray<ncm::ProgramId> &tids) {
|
||||||
return this->RefreshImpl(tids.buffer, tids.num_elements);
|
return this->RefreshImpl(tids.GetPointer(), tids.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include "impl/lr_redirection.hpp"
|
#include "impl/lr_redirection.hpp"
|
||||||
#include "impl/lr_registered_data.hpp"
|
#include "impl/lr_registered_data.hpp"
|
||||||
|
|
||||||
namespace sts::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class RegisteredLocationResolverInterface final : public IServiceObject {
|
class RegisteredLocationResolverInterface final : public sf::IServiceObject {
|
||||||
private:
|
private:
|
||||||
static constexpr size_t MaxRegisteredLocations = 0x20;
|
static constexpr size_t MaxRegisteredLocations = 0x20;
|
||||||
protected:
|
protected:
|
||||||
@ -45,48 +45,48 @@ namespace sts::lr {
|
|||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
impl::LocationRedirector program_redirector;
|
impl::LocationRedirector program_redirector;
|
||||||
impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations> registered_program_locations;
|
impl::RegisteredLocations<ncm::ProgramId, MaxRegisteredLocations> registered_program_locations;
|
||||||
impl::LocationRedirector html_docs_redirector;
|
impl::LocationRedirector html_docs_redirector;
|
||||||
impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations> registered_html_docs_locations;
|
impl::RegisteredLocations<ncm::ProgramId, MaxRegisteredLocations> registered_html_docs_locations;
|
||||||
private:
|
private:
|
||||||
void ClearRedirections(u32 flags = impl::RedirectionFlags_None);
|
void ClearRedirections(u32 flags = impl::RedirectionFlags_None);
|
||||||
void RegisterPath(const Path& path, impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations>* locations, ncm::TitleId tid, ncm::TitleId owner_tid);
|
void RegisterPath(const Path& path, impl::RegisteredLocations<ncm::ProgramId, MaxRegisteredLocations>* locations, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
bool ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations>* locations, ncm::TitleId tid);
|
bool ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::ProgramId, MaxRegisteredLocations>* locations, ncm::ProgramId tid);
|
||||||
Result RefreshImpl(const ncm::TitleId* excluding_tids, size_t num_tids);
|
Result RefreshImpl(const ncm::ProgramId* excluding_tids, size_t num_tids);
|
||||||
public:
|
public:
|
||||||
RegisteredLocationResolverInterface() : registered_program_locations(GetRuntimeFirmwareVersion() < FirmwareVersion_900 ? 0x10 : MaxRegisteredLocations), registered_html_docs_locations(GetRuntimeFirmwareVersion() < FirmwareVersion_900 ? 0x10 : MaxRegisteredLocations) { /* ... */ }
|
RegisteredLocationResolverInterface() : registered_program_locations(hos::GetVersion() < hos::Version_900 ? 0x10 : MaxRegisteredLocations), registered_html_docs_locations(hos::GetVersion() < hos::Version_900 ? 0x10 : MaxRegisteredLocations) { /* ... */ }
|
||||||
~RegisteredLocationResolverInterface();
|
~RegisteredLocationResolverInterface();
|
||||||
|
|
||||||
Result ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
Result RegisterProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
Result RegisterProgramPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
Result RegisterProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
Result RegisterProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
Result UnregisterProgramPath(ncm::TitleId tid);
|
Result UnregisterProgramPath(ncm::ProgramId tid);
|
||||||
Result RedirectProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
Result RedirectProgramPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
Result RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
Result RedirectProgramPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
Result ResolveHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
|
Result ResolveHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId tid);
|
||||||
Result RegisterHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
Result RegisterHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
Result RegisterHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
Result RegisterHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
Result UnregisterHtmlDocumentPath(ncm::TitleId tid);
|
Result UnregisterHtmlDocumentPath(ncm::ProgramId tid);
|
||||||
Result RedirectHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
|
Result RedirectHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId tid);
|
||||||
Result RedirectHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId owner_tid);
|
Result RedirectHtmlDocumentPath(const Path &path, ncm::ProgramId tid, ncm::ProgramId owner_tid);
|
||||||
Result Refresh();
|
Result Refresh();
|
||||||
Result RefreshExcluding(InBuffer<ncm::TitleId> tids);
|
Result RefreshExcluding(const sf::InArray<ncm::ProgramId> &tids);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, ResolveProgramPath),
|
MAKE_SERVICE_COMMAND_META(ResolveProgramPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterProgramPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RegisterProgramPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterProgramPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RegisterProgramPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, UnregisterProgramPath),
|
MAKE_SERVICE_COMMAND_META(UnregisterProgramPath),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectProgramPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectProgramPathDeprecated, hos::Version_100, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectProgramPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectProgramPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, ResolveHtmlDocumentPath, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(ResolveHtmlDocumentPath, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterHtmlDocumentPathDeprecated, FirmwareVersion_200, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RegisterHtmlDocumentPathDeprecated, hos::Version_200, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterHtmlDocumentPath, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RegisterHtmlDocumentPath, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, UnregisterHtmlDocumentPath, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(UnregisterHtmlDocumentPath, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectHtmlDocumentPathDeprecated, FirmwareVersion_200, FirmwareVersion_810),
|
MAKE_SERVICE_COMMAND_META(RedirectHtmlDocumentPathDeprecated, hos::Version_200, hos::Version_810),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectHtmlDocumentPathDeprecated, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RedirectHtmlDocumentPathDeprecated, hos::Version_900),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, Refresh, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(Refresh, hos::Version_700),
|
||||||
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RefreshExcluding, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(RefreshExcluding, hos::Version_900),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "impl/ncm_content_manager.hpp"
|
#include "impl/ncm_content_manager.hpp"
|
||||||
#include "ncm_content_manager_service.hpp"
|
#include "ncm_content_manager_service.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
Result ContentManagerService::CreateContentStorage(StorageId storage_id) {
|
Result ContentManagerService::CreateContentStorage(StorageId storage_id) {
|
||||||
return impl::CreateContentStorage(storage_id);
|
return impl::CreateContentStorage(storage_id);
|
||||||
@ -35,18 +35,18 @@ namespace sts::ncm {
|
|||||||
return impl::VerifyContentMetaDatabase(storage_id);
|
return impl::VerifyContentMetaDatabase(storage_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentManagerService::OpenContentStorage(Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id) {
|
Result ContentManagerService::OpenContentStorage(sf::Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id) {
|
||||||
std::shared_ptr<IContentStorage> content_storage;
|
std::shared_ptr<IContentStorage> content_storage;
|
||||||
R_TRY(impl::OpenContentStorage(&content_storage, storage_id));
|
R_TRY(impl::OpenContentStorage(&content_storage, storage_id));
|
||||||
out.SetValue(std::move(content_storage));
|
out.SetValue(std::move(content_storage));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentManagerService::OpenContentMetaDatabase(Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id) {
|
Result ContentManagerService::OpenContentMetaDatabase(sf::Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id) {
|
||||||
std::shared_ptr<IContentMetaDatabase> content_meta_database;
|
std::shared_ptr<IContentMetaDatabase> content_meta_database;
|
||||||
R_TRY(impl::OpenContentMetaDatabase(&content_meta_database, storage_id));
|
R_TRY(impl::OpenContentMetaDatabase(&content_meta_database, storage_id));
|
||||||
out.SetValue(std::move(content_meta_database));
|
out.SetValue(std::move(content_meta_database));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentManagerService::CloseContentStorageForcibly(StorageId storage_id) {
|
Result ContentManagerService::CloseContentStorageForcibly(StorageId storage_id) {
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include "ncm_icontentmetadatabase.hpp"
|
#include "ncm_icontentmetadatabase.hpp"
|
||||||
#include "ncm_icontentstorage.hpp"
|
#include "ncm_icontentstorage.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
class ContentManagerService final : public IServiceObject {
|
class ContentManagerService final : public sf::IServiceObject {
|
||||||
protected:
|
protected:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
CreateContentStorage = 0,
|
CreateContentStorage = 0,
|
||||||
@ -46,8 +46,8 @@ namespace sts::ncm {
|
|||||||
virtual Result CreateContentMetaDatabase(StorageId storage_id);
|
virtual Result CreateContentMetaDatabase(StorageId storage_id);
|
||||||
virtual Result VerifyContentStorage(StorageId storage_id);
|
virtual Result VerifyContentStorage(StorageId storage_id);
|
||||||
virtual Result VerifyContentMetaDatabase(StorageId storage_id);
|
virtual Result VerifyContentMetaDatabase(StorageId storage_id);
|
||||||
virtual Result OpenContentStorage(Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id);
|
virtual Result OpenContentStorage(sf::Out<std::shared_ptr<IContentStorage>> out, StorageId storage_id);
|
||||||
virtual Result OpenContentMetaDatabase(Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id);
|
virtual Result OpenContentMetaDatabase(sf::Out<std::shared_ptr<IContentMetaDatabase>> out, StorageId storage_id);
|
||||||
virtual Result CloseContentStorageForcibly(StorageId storage_id);
|
virtual Result CloseContentStorageForcibly(StorageId storage_id);
|
||||||
virtual Result CloseContentMetaDatabaseForcibly(StorageId storage_id);
|
virtual Result CloseContentMetaDatabaseForcibly(StorageId storage_id);
|
||||||
virtual Result CleanupContentMetaDatabase(StorageId storage_id);
|
virtual Result CleanupContentMetaDatabase(StorageId storage_id);
|
||||||
@ -58,20 +58,20 @@ namespace sts::ncm {
|
|||||||
virtual Result InvalidateRightsIdCache();
|
virtual Result InvalidateRightsIdCache();
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, CreateContentStorage),
|
MAKE_SERVICE_COMMAND_META(CreateContentStorage),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, CreateContentMetaDatabase),
|
MAKE_SERVICE_COMMAND_META(CreateContentMetaDatabase),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, VerifyContentStorage),
|
MAKE_SERVICE_COMMAND_META(VerifyContentStorage),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, VerifyContentMetaDatabase),
|
MAKE_SERVICE_COMMAND_META(VerifyContentMetaDatabase),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, OpenContentStorage),
|
MAKE_SERVICE_COMMAND_META(OpenContentStorage),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, OpenContentMetaDatabase),
|
MAKE_SERVICE_COMMAND_META(OpenContentMetaDatabase),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, CloseContentStorageForcibly, FirmwareVersion_100, FirmwareVersion_100),
|
MAKE_SERVICE_COMMAND_META(CloseContentStorageForcibly, hos::Version_100, hos::Version_100),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, CloseContentMetaDatabaseForcibly, FirmwareVersion_100, FirmwareVersion_100),
|
MAKE_SERVICE_COMMAND_META(CloseContentMetaDatabaseForcibly, hos::Version_100, hos::Version_100),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, CleanupContentMetaDatabase),
|
MAKE_SERVICE_COMMAND_META(CleanupContentMetaDatabase),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, ActivateContentStorage, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(ActivateContentStorage, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, InactivateContentStorage, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(InactivateContentStorage, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, ActivateContentMetaDatabase, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(ActivateContentMetaDatabase, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, InactivateContentMetaDatabase, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(InactivateContentMetaDatabase, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, InvalidateRightsIdCache, FirmwareVersion_900),
|
MAKE_SERVICE_COMMAND_META(InvalidateRightsIdCache, hos::Version_900),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "ncm_contentmetadatabase.hpp"
|
#include "ncm_contentmetadatabase.hpp"
|
||||||
#include "ncm_utils.hpp"
|
#include "ncm_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -32,20 +32,20 @@ namespace sts::ncm {
|
|||||||
static_assert(sizeof(ContentMetaHeader) == 0x8, "ContentMetaHeader definition!");
|
static_assert(sizeof(ContentMetaHeader) == 0x8, "ContentMetaHeader definition!");
|
||||||
|
|
||||||
struct ApplicationMetaExtendedHeader {
|
struct ApplicationMetaExtendedHeader {
|
||||||
TitleId patch_id;
|
ProgramId patch_id;
|
||||||
u32 required_system_version;
|
u32 required_system_version;
|
||||||
u32 required_application_version;
|
u32 required_application_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatchMetaExtendedHeader {
|
struct PatchMetaExtendedHeader {
|
||||||
TitleId application_id;
|
ProgramId application_id;
|
||||||
u32 required_system_version;
|
u32 required_system_version;
|
||||||
u32 extended_data_size;
|
u32 extended_data_size;
|
||||||
u8 reserved[0x8];
|
u8 reserved[0x8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AddOnContentMetaExtendedHeader {
|
struct AddOnContentMetaExtendedHeader {
|
||||||
TitleId application_id;
|
ProgramId application_id;
|
||||||
u32 required_application_version;
|
u32 required_application_version;
|
||||||
u32 padding;
|
u32 padding;
|
||||||
};
|
};
|
||||||
@ -74,18 +74,18 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
Result GetContentMetaSize(size_t *out, const ContentMetaKey &key, const kvdb::MemoryKeyValueStore<ContentMetaKey> *kvs) {
|
Result GetContentMetaSize(size_t *out, const ContentMetaKey &key, const kvdb::MemoryKeyValueStore<ContentMetaKey> *kvs) {
|
||||||
R_TRY_CATCH(kvs->GetValueSize(out, key)) {
|
R_TRY_CATCH(kvs->GetValueSize(out, key)) {
|
||||||
R_CATCH(ResultKvdbKeyNotFound) {
|
R_CATCH(kvdb::ResultKeyNotFound) {
|
||||||
return ResultNcmContentMetaNotFound;
|
return ResultContentMetaNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetContentMetaValuePointer(const void **out_value_ptr, size_t *out_size, const ContentMetaKey &key, const kvdb::MemoryKeyValueStore<ContentMetaKey> *kvs) {
|
Result GetContentMetaValuePointer(const void **out_value_ptr, size_t *out_size, const ContentMetaKey &key, const kvdb::MemoryKeyValueStore<ContentMetaKey> *kvs) {
|
||||||
R_TRY(GetContentMetaSize(out_size, key, kvs));
|
R_TRY(GetContentMetaSize(out_size, key, kvs));
|
||||||
R_TRY(kvs->GetValuePointer(out_value_ptr, key));
|
R_TRY(kvs->GetValuePointer(out_value_ptr, key));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
const auto it = this->kvs->lower_bound(key);
|
const auto it = this->kvs->lower_bound(key);
|
||||||
if (it == this->kvs->end() || it->GetKey().id != key.id) {
|
if (it == this->kvs->end() || it->GetKey().id != key.id) {
|
||||||
return ResultNcmContentMetaNotFound;
|
return ResultContentMetaNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto stored_key = it->GetKey();
|
const auto stored_key = it->GetKey();
|
||||||
@ -106,7 +106,7 @@ namespace sts::ncm {
|
|||||||
const auto header = GetValueHeader(value);
|
const auto header = GetValueHeader(value);
|
||||||
|
|
||||||
if (header->content_count == 0) {
|
if (header->content_count == 0) {
|
||||||
return ResultNcmContentNotFound;
|
return ResultContentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContentInfo* content_infos = GetValueContentInfos(value);
|
const ContentInfo* content_infos = GetValueContentInfos(value);
|
||||||
@ -136,14 +136,14 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found_content_info) {
|
if (!found_content_info) {
|
||||||
return ResultNcmContentNotFound;
|
return ResultContentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = found_content_info->content_id;
|
*out = found_content_info->content_id;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetLatestContentMetaKeyImpl(ContentMetaKey* out_key, TitleId tid) {
|
Result ContentMetaDatabaseInterface::GetLatestContentMetaKeyImpl(ContentMetaKey* out_key, ProgramId tid) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
ContentMetaKey key = {0};
|
ContentMetaKey key = {0};
|
||||||
@ -162,41 +162,41 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found_key) {
|
if (!found_key) {
|
||||||
return ResultNcmContentMetaNotFound;
|
return ResultContentMetaNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_key = key;
|
*out_key = key;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::Set(ContentMetaKey key, InBuffer<u8> value) {
|
Result ContentMetaDatabaseInterface::Set(ContentMetaKey key, sf::InBuffer value) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(this->kvs->Set(key, value.buffer, value.num_elements));
|
R_TRY(this->kvs->Set(key, value.GetPointer(), value.GetSize()));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::Get(Out<u64> out_size, ContentMetaKey key, OutBuffer<u8> out_value) {
|
Result ContentMetaDatabaseInterface::Get(sf::Out<u64> out_size, ContentMetaKey key, sf::OutBuffer out_value) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(this->kvs->Get(out_size.GetPointer(), out_value.buffer, out_value.num_elements, key));
|
R_TRY(this->kvs->Get(out_size.GetPointer(), out_value.GetPointer(), out_value.GetSize(), key));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::Remove(ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::Remove(ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(this->kvs->Remove(key));
|
R_TRY(this->kvs->Remove(key));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetContentIdByType(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type) {
|
Result ContentMetaDatabaseInterface::GetContentIdByType(sf::Out<ContentId> out_content_id, ContentMetaKey key, ContentType type) {
|
||||||
ContentId content_id;
|
ContentId content_id;
|
||||||
R_TRY(this->GetContentIdByTypeImpl(&content_id, key, type, std::nullopt));
|
R_TRY(this->GetContentIdByTypeImpl(&content_id, key, type, std::nullopt));
|
||||||
out_content_id.SetValue(content_id);
|
out_content_id.SetValue(content_id);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::ListContentInfo(Out<u32> out_count, OutBuffer<ContentInfo> out_info, ContentMetaKey key, u32 offset) {
|
Result ContentMetaDatabaseInterface::ListContentInfo(sf::Out<u32> out_count, const sf::OutArray<ContentInfo> &out_info, ContentMetaKey key, u32 offset) {
|
||||||
if (offset >> 0x1f != 0) {
|
if (offset >> 0x1f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
@ -207,15 +207,15 @@ namespace sts::ncm {
|
|||||||
const auto content_infos = GetValueContentInfos(value);
|
const auto content_infos = GetValueContentInfos(value);
|
||||||
|
|
||||||
size_t count;
|
size_t count;
|
||||||
for (count = 0; offset + count < header->content_count && count < out_info.num_elements; count++) {
|
for (count = 0; offset + count < header->content_count && count < out_info.GetSize(); count++) {
|
||||||
out_info[count] = content_infos[offset + count];
|
out_info[count] = content_infos[offset + count];
|
||||||
}
|
}
|
||||||
|
|
||||||
out_count.SetValue(count);
|
out_count.SetValue(count);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::List(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ContentMetaKey> out_info, ContentMetaType type, TitleId application_title_id, TitleId title_id_min, TitleId title_id_max, ContentInstallType install_type) {
|
Result ContentMetaDatabaseInterface::List(sf::Out<u32> out_entries_total, sf::Out<u32> out_entries_written, const sf::OutArray<ContentMetaKey> & out_info, ContentMetaType type, ProgramId application_title_id, ProgramId title_id_min, ProgramId title_id_max, ContentInstallType install_type) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
size_t entries_total = 0;
|
size_t entries_total = 0;
|
||||||
@ -225,7 +225,7 @@ namespace sts::ncm {
|
|||||||
if (this->kvs->GetCount() == 0) {
|
if (this->kvs->GetCount() == 0) {
|
||||||
out_entries_total.SetValue(entries_total);
|
out_entries_total.SetValue(entries_total);
|
||||||
out_entries_written.SetValue(entries_written);
|
out_entries_written.SetValue(entries_written);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto entry = this->kvs->begin(); entry != this->kvs->end(); entry++) {
|
for (auto entry = this->kvs->begin(); entry != this->kvs->end(); entry++) {
|
||||||
@ -243,14 +243,14 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
/* Each of these types are owned by an application. We need to check if their owner application matches the filter. */
|
/* Each of these types are owned by an application. We need to check if their owner application matches the filter. */
|
||||||
if (key.type == ContentMetaType::Application || key.type == ContentMetaType::Patch || key.type == ContentMetaType::AddOnContent || key.type == ContentMetaType::Delta) {
|
if (key.type == ContentMetaType::Application || key.type == ContentMetaType::Patch || key.type == ContentMetaType::AddOnContent || key.type == ContentMetaType::Delta) {
|
||||||
TitleId entry_application_tid = key.id;
|
ProgramId entry_application_tid = key.id;
|
||||||
|
|
||||||
switch (key.type) {
|
switch (key.type) {
|
||||||
case ContentMetaType::Application:
|
case ContentMetaType::Application:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* The first u64 of all non-application extended headers is the application title id. */
|
/* The first u64 of all non-application extended headers is the application title id. */
|
||||||
entry_application_tid = *GetValueExtendedHeader<TitleId>(value);
|
entry_application_tid = *GetValueExtendedHeader<ProgramId>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Application tid doesn't match filter, skip this entry. */
|
/* Application tid doesn't match filter, skip this entry. */
|
||||||
@ -261,7 +261,7 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the entry to the output buffer. */
|
/* Write the entry to the output buffer. */
|
||||||
if (entries_written < out_info.num_elements) {
|
if (entries_written < out_info.GetSize()) {
|
||||||
out_info[entries_written] = key;
|
out_info[entries_written] = key;
|
||||||
entries_written++;
|
entries_written++;
|
||||||
}
|
}
|
||||||
@ -271,18 +271,18 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
out_entries_total.SetValue(entries_total);
|
out_entries_total.SetValue(entries_total);
|
||||||
out_entries_written.SetValue(entries_written);
|
out_entries_written.SetValue(entries_written);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetLatestContentMetaKey(Out<ContentMetaKey> out_key, TitleId title_id) {
|
Result ContentMetaDatabaseInterface::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, ProgramId title_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
ContentMetaKey key;
|
ContentMetaKey key;
|
||||||
R_TRY(this->GetLatestContentMetaKeyImpl(&key, title_id));
|
R_TRY(this->GetLatestContentMetaKeyImpl(&key, title_id));
|
||||||
out_key.SetValue(key);
|
out_key.SetValue(key);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::ListApplication(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ApplicationContentMetaKey> out_keys, ContentMetaType type) {
|
Result ContentMetaDatabaseInterface::ListApplication(sf::Out<u32> out_entries_total, sf::Out<u32> out_entries_written, const sf::OutArray<ApplicationContentMetaKey> &out_keys, ContentMetaType type) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
size_t entries_total = 0;
|
size_t entries_total = 0;
|
||||||
@ -292,7 +292,7 @@ namespace sts::ncm {
|
|||||||
if (this->kvs->GetCount() == 0) {
|
if (this->kvs->GetCount() == 0) {
|
||||||
out_entries_total.SetValue(entries_total);
|
out_entries_total.SetValue(entries_total);
|
||||||
out_entries_written.SetValue(entries_written);
|
out_entries_written.SetValue(entries_written);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto entry = this->kvs->begin(); entry != this->kvs->end(); entry++) {
|
for (auto entry = this->kvs->begin(); entry != this->kvs->end(); entry++) {
|
||||||
@ -308,18 +308,18 @@ namespace sts::ncm {
|
|||||||
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
||||||
|
|
||||||
if (key.type == ContentMetaType::Application || key.type == ContentMetaType::Patch || key.type == ContentMetaType::AddOnContent || key.type == ContentMetaType::Delta) {
|
if (key.type == ContentMetaType::Application || key.type == ContentMetaType::Patch || key.type == ContentMetaType::AddOnContent || key.type == ContentMetaType::Delta) {
|
||||||
TitleId application_tid = key.id;
|
ProgramId application_tid = key.id;
|
||||||
|
|
||||||
switch (key.type) {
|
switch (key.type) {
|
||||||
case ContentMetaType::Application:
|
case ContentMetaType::Application:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* The first u64 of all non-application extended headers is the application title id. */
|
/* The first u64 of all non-application extended headers is the application title id. */
|
||||||
application_tid = *GetValueExtendedHeader<TitleId>(value);
|
application_tid = *GetValueExtendedHeader<ProgramId>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the entry to the output buffer. */
|
/* Write the entry to the output buffer. */
|
||||||
if (entries_written < out_keys.num_elements) {
|
if (entries_written < out_keys.GetSize()) {
|
||||||
ApplicationContentMetaKey* out_app_key = &out_keys[entries_written];
|
ApplicationContentMetaKey* out_app_key = &out_keys[entries_written];
|
||||||
out_app_key->application_title_id = application_tid;
|
out_app_key->application_title_id = application_tid;
|
||||||
out_app_key->key = key;
|
out_app_key->key = key;
|
||||||
@ -332,15 +332,15 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
out_entries_total.SetValue(entries_total);
|
out_entries_total.SetValue(entries_total);
|
||||||
out_entries_written.SetValue(entries_written);
|
out_entries_written.SetValue(entries_written);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::Has(Out<bool> out, ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::Has(sf::Out<bool> out, ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
if (this->kvs->GetCount() == 0) {
|
if (this->kvs->GetCount() == 0) {
|
||||||
out.SetValue(false);
|
out.SetValue(false);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has = false;
|
bool has = false;
|
||||||
@ -350,42 +350,42 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(has);
|
out.SetValue(has);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::HasAll(Out<bool> out, InBuffer<ContentMetaKey> keys) {
|
Result ContentMetaDatabaseInterface::HasAll(sf::Out<bool> out, const sf::InArray<ContentMetaKey> & keys) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
bool has = true;
|
bool has = true;
|
||||||
for (size_t i = 0; i < keys.num_elements && has; i++) {
|
for (size_t i = 0; i < keys.GetSize() && has; i++) {
|
||||||
R_TRY(this->Has(&has, keys[i]));
|
R_TRY(this->Has(&has, keys[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(has);
|
out.SetValue(has);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetSize(Out<u64> out_size, ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::GetSize(sf::Out<u64> out_size, ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
if (this->kvs->GetCount() == 0) {
|
if (this->kvs->GetCount() == 0) {
|
||||||
return ResultNcmContentMetaNotFound;
|
return ResultContentMetaNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto it = this->kvs->lower_bound(key);
|
const auto it = this->kvs->lower_bound(key);
|
||||||
if (it == this->kvs->end() || it->GetKey() != key) {
|
if (it == this->kvs->end() || it->GetKey() != key) {
|
||||||
return ResultNcmContentMetaNotFound;
|
return ResultContentMetaNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
out_size.SetValue(it->GetValueSize());
|
out_size.SetValue(it->GetValueSize());
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetRequiredSystemVersion(Out<u32> out_version, ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::GetRequiredSystemVersion(sf::Out<u32> out_version, ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
if (key.type != ContentMetaType::Application && key.type != ContentMetaType::Patch) {
|
if (key.type != ContentMetaType::Application && key.type != ContentMetaType::Patch) {
|
||||||
return ResultNcmInvalidContentMetaKey;
|
return ResultInvalidContentMetaKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* value = nullptr;
|
const void* value = nullptr;
|
||||||
@ -396,14 +396,14 @@ namespace sts::ncm {
|
|||||||
We use the application header for convenience. */
|
We use the application header for convenience. */
|
||||||
const auto ext_header = GetValueExtendedHeader<ApplicationMetaExtendedHeader>(value);
|
const auto ext_header = GetValueExtendedHeader<ApplicationMetaExtendedHeader>(value);
|
||||||
out_version.SetValue(ext_header->required_system_version);
|
out_version.SetValue(ext_header->required_system_version);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetPatchId(Out<TitleId> out_patch_id, ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::GetPatchId(sf::Out<ProgramId> out_patch_id, ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
if (key.type != ContentMetaType::Application) {
|
if (key.type != ContentMetaType::Application) {
|
||||||
return ResultNcmInvalidContentMetaKey;
|
return ResultInvalidContentMetaKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* value = nullptr;
|
const void* value = nullptr;
|
||||||
@ -412,28 +412,28 @@ namespace sts::ncm {
|
|||||||
const auto ext_header = GetValueExtendedHeader<ApplicationMetaExtendedHeader>(value);
|
const auto ext_header = GetValueExtendedHeader<ApplicationMetaExtendedHeader>(value);
|
||||||
|
|
||||||
out_patch_id.SetValue(ext_header->patch_id);
|
out_patch_id.SetValue(ext_header->patch_id);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::DisableForcibly() {
|
Result ContentMetaDatabaseInterface::DisableForcibly() {
|
||||||
this->disabled = true;
|
this->disabled = true;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::LookupOrphanContent(OutBuffer<bool> out_orphaned, InBuffer<ContentId> content_ids) {
|
Result ContentMetaDatabaseInterface::LookupOrphanContent(const sf::OutArray<bool> & out_orphaned, const sf::InArray<ContentId> &content_ids) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
if (out_orphaned.num_elements < content_ids.num_elements) {
|
if (out_orphaned.GetSize() < content_ids.GetSize()) {
|
||||||
return ResultNcmBufferInsufficient;
|
return ResultBufferInsufficient();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default to orphaned for all content ids. */
|
/* Default to orphaned for all content ids. */
|
||||||
if (out_orphaned.num_elements > 0) {
|
if (out_orphaned.GetSize() > 0) {
|
||||||
std::fill_n(out_orphaned.buffer, out_orphaned.num_elements, true);
|
std::fill_n(out_orphaned.GetPointer(), out_orphaned.GetSize(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->kvs->GetCount() == 0) {
|
if (this->kvs->GetCount() == 0) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto entry = this->kvs->begin(); entry != this->kvs->end(); entry++) {
|
for (auto entry = this->kvs->begin(); entry != this->kvs->end(); entry++) {
|
||||||
@ -444,7 +444,7 @@ namespace sts::ncm {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content_ids.num_elements == 0) {
|
if (content_ids.GetSize() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
/* Check if any of this entry's content infos matches one of the provided content ids.
|
/* Check if any of this entry's content infos matches one of the provided content ids.
|
||||||
If they do, then the content id isn't orphaned. */
|
If they do, then the content id isn't orphaned. */
|
||||||
for (size_t j = 0; j < content_ids.num_elements; j++) {
|
for (size_t j = 0; j < content_ids.GetSize(); j++) {
|
||||||
const ContentId content_id = content_ids[j];
|
const ContentId content_id = content_ids[j];
|
||||||
|
|
||||||
if (content_id == content_info->content_id) {
|
if (content_id == content_info->content_id) {
|
||||||
@ -465,17 +465,17 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::Commit() {
|
Result ContentMetaDatabaseInterface::Commit() {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(this->kvs->Save());
|
R_TRY(this->kvs->Save());
|
||||||
R_TRY(fsdevCommitDevice(this->mount_name));
|
R_TRY(fsdevCommitDevice(this->mount_name));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::HasContent(Out<bool> out, ContentMetaKey key, ContentId content_id) {
|
Result ContentMetaDatabaseInterface::HasContent(sf::Out<bool> out, ContentMetaKey key, ContentId content_id) {
|
||||||
const void* value = nullptr;
|
const void* value = nullptr;
|
||||||
size_t value_size = 0;
|
size_t value_size = 0;
|
||||||
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
||||||
@ -488,18 +488,18 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
if (content_id == content_info->content_id) {
|
if (content_id == content_info->content_id) {
|
||||||
out.SetValue(false);
|
out.SetValue(false);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(false);
|
out.SetValue(false);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::ListContentMetaInfo(Out<u32> out_entries_written, OutBuffer<ContentMetaInfo> out_meta_info, ContentMetaKey key, u32 start_index) {
|
Result ContentMetaDatabaseInterface::ListContentMetaInfo(sf::Out<u32> out_entries_written, const sf::OutArray<ContentMetaInfo> &out_meta_info, ContentMetaKey key, u32 start_index) {
|
||||||
if (start_index >> 0x1f != 0) {
|
if (start_index >> 0x1f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
@ -511,12 +511,12 @@ namespace sts::ncm {
|
|||||||
const auto content_meta_infos = GetValueContentMetaInfos(value);
|
const auto content_meta_infos = GetValueContentMetaInfos(value);
|
||||||
size_t entries_written = 0;
|
size_t entries_written = 0;
|
||||||
|
|
||||||
if (out_meta_info.num_elements == 0) {
|
if (out_meta_info.GetSize() == 0) {
|
||||||
out_entries_written.SetValue(0);
|
out_entries_written.SetValue(0);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = start_index; i < out_meta_info.num_elements; i++) {
|
for (size_t i = start_index; i < out_meta_info.GetSize(); i++) {
|
||||||
/* We have no more entries we can read out. */
|
/* We have no more entries we can read out. */
|
||||||
if (header->content_meta_count <= start_index + i) {
|
if (header->content_meta_count <= start_index + i) {
|
||||||
break;
|
break;
|
||||||
@ -527,10 +527,10 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_entries_written.SetValue(entries_written);
|
out_entries_written.SetValue(entries_written);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetAttributes(Out<ContentMetaAttribute> out_attributes, ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::GetAttributes(sf::Out<ContentMetaAttribute> out_attributes, ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
const void* value = nullptr;
|
const void* value = nullptr;
|
||||||
@ -538,10 +538,10 @@ namespace sts::ncm {
|
|||||||
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
||||||
const auto header = GetValueHeader(value);
|
const auto header = GetValueHeader(value);
|
||||||
out_attributes.SetValue(header->attributes);
|
out_attributes.SetValue(header->attributes);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetRequiredApplicationVersion(Out<u32> out_version, ContentMetaKey key) {
|
Result ContentMetaDatabaseInterface::GetRequiredApplicationVersion(sf::Out<u32> out_version, ContentMetaKey key) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
const void* value = nullptr;
|
const void* value = nullptr;
|
||||||
@ -549,44 +549,44 @@ namespace sts::ncm {
|
|||||||
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
R_TRY(GetContentMetaValuePointer(&value, &value_size, key, this->kvs));
|
||||||
|
|
||||||
/* As of 9.0.0, applications can be dependent on a specific base application version. */
|
/* As of 9.0.0, applications can be dependent on a specific base application version. */
|
||||||
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_900 && key.type == ContentMetaType::Application) {
|
if (hos::GetVersion() >= hos::Version_900 && key.type == ContentMetaType::Application) {
|
||||||
const auto ext_header = GetValueExtendedHeader<ApplicationMetaExtendedHeader>(value);
|
const auto ext_header = GetValueExtendedHeader<ApplicationMetaExtendedHeader>(value);
|
||||||
out_version.SetValue(ext_header->required_application_version);
|
out_version.SetValue(ext_header->required_application_version);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.type != ContentMetaType::AddOnContent) {
|
if (key.type != ContentMetaType::AddOnContent) {
|
||||||
return ResultNcmInvalidContentMetaKey;
|
return ResultInvalidContentMetaKey();
|
||||||
}
|
}
|
||||||
const auto ext_header = GetValueExtendedHeader<AddOnContentMetaExtendedHeader>(value);
|
const auto ext_header = GetValueExtendedHeader<AddOnContentMetaExtendedHeader>(value);
|
||||||
out_version.SetValue(ext_header->required_application_version);
|
out_version.SetValue(ext_header->required_application_version);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetContentIdByTypeAndIdOffset(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset) {
|
Result ContentMetaDatabaseInterface::GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset) {
|
||||||
ContentId content_id;
|
ContentId content_id;
|
||||||
R_TRY(this->GetContentIdByTypeImpl(&content_id, key, type, std::optional(id_offset)));
|
R_TRY(this->GetContentIdByTypeImpl(&content_id, key, type, std::optional(id_offset)));
|
||||||
out_content_id.SetValue(content_id);
|
out_content_id.SetValue(content_id);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetLatestProgram(ContentId* out_content_id, TitleId title_id) {
|
Result ContentMetaDatabaseInterface::GetLatestProgram(ContentId* out_content_id, ProgramId title_id) {
|
||||||
ContentMetaKey key;
|
ContentMetaKey key;
|
||||||
|
|
||||||
R_TRY(this->GetLatestContentMetaKey(&key, title_id));
|
R_TRY(this->GetLatestContentMetaKey(&key, title_id));
|
||||||
R_TRY(this->GetContentIdByType(out_content_id, key, ContentType::Program));
|
R_TRY(this->GetContentIdByType(out_content_id, key, ContentType::Program));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentMetaDatabaseInterface::GetLatestData(ContentId* out_content_id, TitleId title_id) {
|
Result ContentMetaDatabaseInterface::GetLatestData(ContentId* out_content_id, ProgramId title_id) {
|
||||||
ContentMetaKey key;
|
ContentMetaKey key;
|
||||||
|
|
||||||
R_TRY(this->GetLatestContentMetaKey(&key, title_id));
|
R_TRY(this->GetLatestContentMetaKey(&key, title_id));
|
||||||
R_TRY(this->GetContentIdByType(out_content_id, key, ContentType::Data));
|
R_TRY(this->GetContentIdByType(out_content_id, key, ContentType::Data));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OnMemoryContentMetaDatabaseInterface::GetLatestContentMetaKey(Out<ContentMetaKey> out_key, TitleId title_id) {
|
Result OnMemoryContentMetaDatabaseInterface::GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, ProgramId title_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
const ContentMetaKey key = ContentMetaKey::Make(title_id, 0, ContentMetaType::Unknown);
|
const ContentMetaKey key = ContentMetaKey::Make(title_id, 0, ContentMetaType::Unknown);
|
||||||
@ -601,20 +601,20 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found_key) {
|
if (!found_key) {
|
||||||
return ResultNcmContentMetaNotFound;
|
return ResultContentMetaNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_key = *found_key;
|
*out_key = *found_key;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OnMemoryContentMetaDatabaseInterface::LookupOrphanContent(OutBuffer<bool> out_orphaned, InBuffer<ContentId> content_ids) {
|
Result OnMemoryContentMetaDatabaseInterface::LookupOrphanContent(const sf::OutArray<bool> & out_orphaned, const sf::InArray<ContentId> &content_ids) {
|
||||||
return ResultNcmInvalidContentMetaDatabase;
|
return ResultInvalidContentMetaDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OnMemoryContentMetaDatabaseInterface::Commit() {
|
Result OnMemoryContentMetaDatabaseInterface::Commit() {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,125 +20,53 @@
|
|||||||
|
|
||||||
#include "ncm_icontentmetadatabase.hpp"
|
#include "ncm_icontentmetadatabase.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
class ContentMetaDatabaseInterface : public IContentMetaDatabase {
|
class ContentMetaDatabaseInterface : public IContentMetaDatabase {
|
||||||
public:
|
public:
|
||||||
ContentMetaDatabaseInterface(sts::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs, const char* mount_name) : IContentMetaDatabase(kvs, mount_name) {
|
ContentMetaDatabaseInterface(ams::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs, const char* mount_name) : IContentMetaDatabase(kvs, mount_name) {
|
||||||
}
|
}
|
||||||
ContentMetaDatabaseInterface(sts::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs) : IContentMetaDatabase(kvs) {
|
ContentMetaDatabaseInterface(ams::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs) : IContentMetaDatabase(kvs) {
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Result GetContentIdByTypeImpl(ContentId* out, const ContentMetaKey& key, ContentType type, std::optional<u8> id_offset);
|
Result GetContentIdByTypeImpl(ContentId* out, const ContentMetaKey& key, ContentType type, std::optional<u8> id_offset);
|
||||||
Result GetLatestContentMetaKeyImpl(ContentMetaKey* out_key, TitleId tid);
|
Result GetLatestContentMetaKeyImpl(ContentMetaKey* out_key, ProgramId tid);
|
||||||
public:
|
public:
|
||||||
virtual Result Set(ContentMetaKey key, InBuffer<u8> value) override;
|
virtual Result Set(ContentMetaKey key, sf::InBuffer value) override;
|
||||||
virtual Result Get(Out<u64> out_size, ContentMetaKey key, OutBuffer<u8> out_value) override;
|
virtual Result Get(sf::Out<u64> out_size, ContentMetaKey key, sf::OutBuffer out_value) override;
|
||||||
virtual Result Remove(ContentMetaKey key) override;
|
virtual Result Remove(ContentMetaKey key) override;
|
||||||
virtual Result GetContentIdByType(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type) override;
|
virtual Result GetContentIdByType(sf::Out<ContentId> out_content_id, ContentMetaKey key, ContentType type) override;
|
||||||
virtual Result ListContentInfo(Out<u32> out_entries_written, OutBuffer<ContentInfo> out_info, ContentMetaKey key, u32 start_index) override;
|
virtual Result ListContentInfo(sf::Out<u32> out_entries_written, const sf::OutArray<ContentInfo> &out_info, ContentMetaKey key, u32 start_index) override;
|
||||||
virtual Result List(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ContentMetaKey> out_info, ContentMetaType type, TitleId application_title_id, TitleId title_id_min, TitleId title_id_max, ContentInstallType install_type) override;
|
virtual Result List(sf::Out<u32> out_entries_total, sf::Out<u32> out_entries_written, const sf::OutArray<ContentMetaKey> &out_info, ContentMetaType type, ProgramId application_title_id, ProgramId title_id_min, ProgramId title_id_max, ContentInstallType install_type) override;
|
||||||
virtual Result GetLatestContentMetaKey(Out<ContentMetaKey> out_key, TitleId tid) override;
|
virtual Result GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, ProgramId tid) override;
|
||||||
virtual Result ListApplication(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ApplicationContentMetaKey> out_keys, ContentMetaType type) override;
|
virtual Result ListApplication(sf::Out<u32> out_entries_total, sf::Out<u32> out_entries_written, const sf::OutArray<ApplicationContentMetaKey> &out_keys, ContentMetaType type) override;
|
||||||
virtual Result Has(Out<bool> out, ContentMetaKey key) override;
|
virtual Result Has(sf::Out<bool> out, ContentMetaKey key) override;
|
||||||
virtual Result HasAll(Out<bool> out, InBuffer<ContentMetaKey> keys) override;
|
virtual Result HasAll(sf::Out<bool> out, const sf::InArray<ContentMetaKey> &keys) override;
|
||||||
virtual Result GetSize(Out<u64> out_size, ContentMetaKey key) override;
|
virtual Result GetSize(sf::Out<u64> out_size, ContentMetaKey key) override;
|
||||||
virtual Result GetRequiredSystemVersion(Out<u32> out_version, ContentMetaKey key) override;
|
virtual Result GetRequiredSystemVersion(sf::Out<u32> out_version, ContentMetaKey key) override;
|
||||||
virtual Result GetPatchId(Out<TitleId> out_patch_id, ContentMetaKey key) override;
|
virtual Result GetPatchId(sf::Out<ProgramId> out_patch_id, ContentMetaKey key) override;
|
||||||
virtual Result DisableForcibly() override;
|
virtual Result DisableForcibly() override;
|
||||||
virtual Result LookupOrphanContent(OutBuffer<bool> out_orphaned, InBuffer<ContentId> content_ids) override;
|
virtual Result LookupOrphanContent(const sf::OutArray<bool> &out_orphaned, const sf::InArray<ContentId> &content_ids) override;
|
||||||
virtual Result Commit() override;
|
virtual Result Commit() override;
|
||||||
virtual Result HasContent(Out<bool> out, ContentMetaKey key, ContentId content_id) override;
|
virtual Result HasContent(sf::Out<bool> out, ContentMetaKey key, ContentId content_id) override;
|
||||||
virtual Result ListContentMetaInfo(Out<u32> out_entries_written, OutBuffer<ContentMetaInfo> out_meta_info, ContentMetaKey key, u32 start_index) override;
|
virtual Result ListContentMetaInfo(sf::Out<u32> out_entries_written, const sf::OutArray<ContentMetaInfo> &out_meta_info, ContentMetaKey key, u32 start_index) override;
|
||||||
virtual Result GetAttributes(Out<ContentMetaAttribute> out_attributes, ContentMetaKey key) override;
|
virtual Result GetAttributes(sf::Out<ContentMetaAttribute> out_attributes, ContentMetaKey key) override;
|
||||||
virtual Result GetRequiredApplicationVersion(Out<u32> out_version, ContentMetaKey key) override;
|
virtual Result GetRequiredApplicationVersion(sf::Out<u32> out_version, ContentMetaKey key) override;
|
||||||
virtual Result GetContentIdByTypeAndIdOffset(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset) override;
|
virtual Result GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset) override;
|
||||||
|
|
||||||
/* APIs. */
|
/* APIs. */
|
||||||
virtual Result GetLatestProgram(ContentId* out_content_id, TitleId title_id) override;
|
virtual Result GetLatestProgram(ContentId* out_content_id, ProgramId title_id) override;
|
||||||
virtual Result GetLatestData(ContentId* out_content_id, TitleId title_id) override;
|
virtual Result GetLatestData(ContentId* out_content_id, ProgramId title_id) override;
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, Set),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, Get),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, Remove),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetContentIdByType),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, ListContentInfo),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, List),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetLatestContentMetaKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, ListApplication),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, Has),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, HasAll),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetSize),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetRequiredSystemVersion),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetPatchId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, DisableForcibly),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, LookupOrphanContent),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, Commit),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, HasContent),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, ListContentMetaInfo),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetAttributes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetRequiredApplicationVersion, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentMetaDatabaseInterface, GetContentIdByTypeAndIdOffset, FirmwareVersion_500),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OnMemoryContentMetaDatabaseInterface : public ContentMetaDatabaseInterface {
|
class OnMemoryContentMetaDatabaseInterface : public ContentMetaDatabaseInterface {
|
||||||
private:
|
|
||||||
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:
|
public:
|
||||||
OnMemoryContentMetaDatabaseInterface(sts::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs) : ContentMetaDatabaseInterface(kvs) {
|
OnMemoryContentMetaDatabaseInterface(ams::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs) : ContentMetaDatabaseInterface(kvs) {
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual Result GetLatestContentMetaKey(Out<ContentMetaKey> out_key, TitleId tid) override;
|
virtual Result GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, ProgramId tid) override;
|
||||||
virtual Result LookupOrphanContent(OutBuffer<bool> out_orphaned, InBuffer<ContentId> content_ids) override;
|
virtual Result LookupOrphanContent(const sf::OutArray<bool> & out_orphaned, const sf::InArray<ContentId> &content_ids) override;
|
||||||
virtual Result Commit() override;
|
virtual Result Commit() override;
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, Set),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, Get),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, Remove),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetContentIdByType),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, ListContentInfo),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, List),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetLatestContentMetaKey),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, ListApplication),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, Has),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, HasAll),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetSize),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetRequiredSystemVersion),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetPatchId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, DisableForcibly),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, LookupOrphanContent),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, Commit),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, HasContent),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, ListContentMetaInfo),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetAttributes),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetRequiredApplicationVersion, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(OnMemoryContentMetaDatabaseInterface, GetContentIdByTypeAndIdOffset, FirmwareVersion_500),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "ncm_make_path.hpp"
|
#include "ncm_make_path.hpp"
|
||||||
#include "ncm_utils.hpp"
|
#include "ncm_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
ContentStorageInterface::~ContentStorageInterface() {
|
ContentStorageInterface::~ContentStorageInterface() {
|
||||||
this->Finalize();
|
this->Finalize();
|
||||||
@ -38,7 +38,7 @@ namespace sts::ncm {
|
|||||||
this->make_content_path_func = *content_path_func;
|
this->make_content_path_func = *content_path_func;
|
||||||
this->placeholder_accessor.Initialize(this->root_path, *placeholder_path_func, delay_flush);
|
this->placeholder_accessor.Initialize(this->root_path, *placeholder_path_func, delay_flush);
|
||||||
this->rights_id_cache = rights_id_cache;
|
this->rights_id_cache = rights_id_cache;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentStorageInterface::Finalize() {
|
void ContentStorageInterface::Finalize() {
|
||||||
@ -69,30 +69,30 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
Result ContentStorageInterface::OpenCachedContentFile(ContentId content_id) {
|
Result ContentStorageInterface::OpenCachedContentFile(ContentId content_id) {
|
||||||
if (this->cached_content_id == content_id) {
|
if (this->cached_content_id == content_id) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(content_path, content_id);
|
||||||
|
|
||||||
R_TRY_CATCH(fs::OpenFile(&this->content_cache_file_handle, content_path, FS_OPEN_READ)) {
|
R_TRY_CATCH(fs::OpenFile(&this->content_cache_file_handle, content_path, FsOpenMode_Read)) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmContentNotFound;
|
return ResultContentNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
this->cached_content_id = content_id;
|
this->cached_content_id = content_id;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GeneratePlaceHolderId(Out<PlaceHolderId> out) {
|
Result ContentStorageInterface::GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
sts::rnd::GenerateRandomBytes(out.GetPointer(), sizeof(NcmNcaId));
|
ams::rnd::GenerateRandomBytes(out.GetPointer(), sizeof(PlaceHolderId));
|
||||||
char placeholder_str[FS_MAX_PATH] = {0};
|
char placeholder_str[FS_MAX_PATH] = {0};
|
||||||
GetStringFromPlaceHolderId(placeholder_str, *out.GetPointer());
|
GetStringFromPlaceHolderId(placeholder_str, *out.GetPointer());
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
Result ContentStorageInterface::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
||||||
@ -104,7 +104,7 @@ namespace sts::ncm {
|
|||||||
R_TRY(fs::EnsureParentDirectoryRecursively(content_path));
|
R_TRY(fs::EnsureParentDirectoryRecursively(content_path));
|
||||||
R_TRY(this->placeholder_accessor.Create(placeholder_id, size));
|
R_TRY(this->placeholder_accessor.Create(placeholder_id, size));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
Result ContentStorageInterface::DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
||||||
@ -112,7 +112,7 @@ namespace sts::ncm {
|
|||||||
return this->placeholder_accessor.Delete(placeholder_id);
|
return this->placeholder_accessor.Delete(placeholder_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::HasPlaceHolder(Out<bool> out, PlaceHolderId placeholder_id) {
|
Result ContentStorageInterface::HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
@ -122,18 +122,18 @@ namespace sts::ncm {
|
|||||||
R_TRY(fs::HasFile(&has, placeholder_path));
|
R_TRY(fs::HasFile(&has, placeholder_path));
|
||||||
out.SetValue(has);
|
out.SetValue(has);
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, InBuffer<u8> data) {
|
Result ContentStorageInterface::WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, sf::InBuffer data) {
|
||||||
/* Offset is too large */
|
/* Offset is too large */
|
||||||
if (offset >> 0x3f != 0) {
|
if (offset >> 0x3f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(this->placeholder_accessor.Write(placeholder_id, offset, data.buffer, data.num_elements));
|
R_TRY(this->placeholder_accessor.Write(placeholder_id, offset, data.GetPointer(), data.GetSize()));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
Result ContentStorageInterface::Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
||||||
@ -148,16 +148,16 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
if (rename(placeholder_path, content_path) != 0) {
|
if (rename(placeholder_path, content_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmPlaceHolderNotFound;
|
return ResultPlaceHolderNotFound();
|
||||||
}
|
}
|
||||||
R_CATCH(ResultFsPathAlreadyExists) {
|
R_CATCH(ams::fs::ResultPathAlreadyExists) {
|
||||||
return ResultNcmContentAlreadyExists;
|
return ResultContentAlreadyExists();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::Delete(ContentId content_id) {
|
Result ContentStorageInterface::Delete(ContentId content_id) {
|
||||||
@ -169,16 +169,16 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
if (std::remove(content_path) != 0) {
|
if (std::remove(content_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmContentNotFound;
|
return ResultContentNotFound();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::Has(Out<bool> out, ContentId content_id) {
|
Result ContentStorageInterface::Has(sf::Out<bool> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
@ -188,29 +188,29 @@ namespace sts::ncm {
|
|||||||
R_TRY(fs::HasFile(&has, content_path));
|
R_TRY(fs::HasFile(&has, content_path));
|
||||||
out.SetValue(has);
|
out.SetValue(has);
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetPath(OutPointerWithServerSize<lr::Path, 0x1> out, ContentId content_id) {
|
Result ContentStorageInterface::GetPath(sf::Out<lr::Path> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
char common_path[FS_MAX_PATH] = {0};
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(content_path, content_id);
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, content_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, content_path));
|
||||||
*out.pointer = common_path;
|
out.SetValue(lr::Path::Encode(common_path));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetPlaceHolderPath(OutPointerWithServerSize<lr::Path, 0x1> out, PlaceHolderId placeholder_id) {
|
Result ContentStorageInterface::GetPlaceHolderPath(sf::Out<lr::Path> out, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
char common_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
||||||
*out.pointer = common_path;
|
out.SetValue(lr::Path::Encode(common_path));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::CleanupAllPlaceHolder() {
|
Result ContentStorageInterface::CleanupAllPlaceHolder() {
|
||||||
@ -228,10 +228,10 @@ namespace sts::ncm {
|
|||||||
return fsdevGetLastResult();
|
return fsdevGetLastResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::ListPlaceHolder(Out<u32> out_count, OutBuffer<PlaceHolderId> out_buf) {
|
Result ContentStorageInterface::ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
char placeholder_root_path[FS_MAX_PATH] = {0};
|
||||||
@ -239,13 +239,13 @@ namespace sts::ncm {
|
|||||||
const unsigned int dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
const unsigned int dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
||||||
size_t entry_count = 0;
|
size_t entry_count = 0;
|
||||||
|
|
||||||
R_TRY(fs::TraverseDirectory(placeholder_root_path, dir_depth, [&](bool* should_continue, bool* should_retry_dir_read, const char* current_path, struct dirent* dir_entry) {
|
R_TRY(fs::TraverseDirectory(placeholder_root_path, dir_depth, [&](bool* should_continue, bool* should_retry_dir_read, const char* current_path, struct dirent* dir_entry) -> Result {
|
||||||
*should_continue = true;
|
*should_continue = true;
|
||||||
*should_retry_dir_read = false;
|
*should_retry_dir_read = false;
|
||||||
|
|
||||||
if (dir_entry->d_type == DT_REG) {
|
if (dir_entry->d_type == DT_REG) {
|
||||||
if (entry_count > out_buf.num_elements) {
|
if (entry_count > out_buf.GetSize()) {
|
||||||
return ResultNcmBufferInsufficient;
|
return ResultBufferInsufficient();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaceHolderId cur_entry_placeholder_id = {0};
|
PlaceHolderId cur_entry_placeholder_id = {0};
|
||||||
@ -253,14 +253,14 @@ namespace sts::ncm {
|
|||||||
out_buf[entry_count++] = cur_entry_placeholder_id;
|
out_buf[entry_count++] = cur_entry_placeholder_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
out_count.SetValue(static_cast<u32>(entry_count));
|
out_count.SetValue(static_cast<u32>(entry_count));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetContentCount(Out<u32> out_count) {
|
Result ContentStorageInterface::GetContentCount(sf::Out<u32> out_count) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_root_path[FS_MAX_PATH] = {0};
|
char content_root_path[FS_MAX_PATH] = {0};
|
||||||
@ -268,7 +268,7 @@ namespace sts::ncm {
|
|||||||
const unsigned int dir_depth = this->GetContentDirectoryDepth();
|
const unsigned int dir_depth = this->GetContentDirectoryDepth();
|
||||||
u32 content_count = 0;
|
u32 content_count = 0;
|
||||||
|
|
||||||
R_TRY(fs::TraverseDirectory(content_root_path, dir_depth, [&](bool* should_continue, bool* should_retry_dir_read, const char* current_path, struct dirent* dir_entry) {
|
R_TRY(fs::TraverseDirectory(content_root_path, dir_depth, [&](bool* should_continue, bool* should_retry_dir_read, const char* current_path, struct dirent* dir_entry) -> Result {
|
||||||
*should_continue = true;
|
*should_continue = true;
|
||||||
*should_retry_dir_read = false;
|
*should_retry_dir_read = false;
|
||||||
|
|
||||||
@ -276,16 +276,16 @@ namespace sts::ncm {
|
|||||||
content_count++;
|
content_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
out_count.SetValue(content_count);
|
out_count.SetValue(content_count);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::ListContentId(Out<u32> out_count, OutBuffer<ContentId> out_buf, u32 start_offset) {
|
Result ContentStorageInterface::ListContentId(sf::Out<u32> out_count, const sf::OutArray<ContentId> &out_buf, u32 start_offset) {
|
||||||
if (start_offset >> 0x1f != 0) {
|
if (start_offset >> 0x1f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
@ -303,13 +303,13 @@ namespace sts::ncm {
|
|||||||
/* Skip entries until we reach the start offset. */
|
/* Skip entries until we reach the start offset. */
|
||||||
if (start_offset > 0) {
|
if (start_offset > 0) {
|
||||||
start_offset--;
|
start_offset--;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't necessarily expect to be able to completely fill the output buffer. */
|
/* We don't necessarily expect to be able to completely fill the output buffer. */
|
||||||
if (entry_count > out_buf.num_elements) {
|
if (entry_count > out_buf.GetSize()) {
|
||||||
*should_continue = false;
|
*should_continue = false;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t name_len = strlen(dir_entry->d_name);
|
size_t name_len = strlen(dir_entry->d_name);
|
||||||
@ -317,13 +317,13 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
/* Skip to the next entry if the id was invalid. */
|
/* Skip to the next entry if the id was invalid. */
|
||||||
if (!content_id) {
|
if (!content_id) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
out_buf[entry_count++] = *content_id;
|
out_buf[entry_count++] = *content_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for (size_t i = 0; i < entry_count; i++) {
|
for (size_t i = 0; i < entry_count; i++) {
|
||||||
@ -332,10 +332,10 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_count.SetValue(static_cast<u32>(entry_count));
|
out_count.SetValue(static_cast<u32>(entry_count));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetSizeFromContentId(Out<u64> out_size, ContentId content_id) {
|
Result ContentStorageInterface::GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
@ -347,14 +347,14 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_size.SetValue(st.st_size);
|
out_size.SetValue(st.st_size);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::DisableForcibly() {
|
Result ContentStorageInterface::DisableForcibly() {
|
||||||
this->disabled = true;
|
this->disabled = true;
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
this->placeholder_accessor.InvalidateAll();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
Result ContentStorageInterface::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
||||||
@ -374,40 +374,40 @@ namespace sts::ncm {
|
|||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
if (rename(old_content_path, placeholder_path) != 0) {
|
if (rename(old_content_path, placeholder_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
return ResultNcmPlaceHolderNotFound;
|
return ResultPlaceHolderNotFound();
|
||||||
}
|
}
|
||||||
R_CATCH(ResultFsPathAlreadyExists) {
|
R_CATCH(ams::fs::ResultPathAlreadyExists) {
|
||||||
return ResultNcmPlaceHolderAlreadyExists;
|
return ResultPlaceHolderAlreadyExists();
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) {
|
Result ContentStorageInterface::SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(this->placeholder_accessor.SetSize(placeholder_id, size));
|
R_TRY(this->placeholder_accessor.SetSize(placeholder_id, size));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::ReadContentIdFile(OutBuffer<u8> buf, ContentId content_id, u64 offset) {
|
Result ContentStorageInterface::ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, u64 offset) {
|
||||||
/* Offset is too large */
|
/* Offset is too large */
|
||||||
if (offset >> 0x3f != 0) {
|
if (offset >> 0x3f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(content_path, content_id);
|
||||||
R_TRY(this->OpenCachedContentFile(content_id));
|
R_TRY(this->OpenCachedContentFile(content_id));
|
||||||
R_TRY(fs::ReadFile(this->content_cache_file_handle, offset, buf.buffer, buf.num_elements));
|
R_TRY(fs::ReadFile(this->content_cache_file_handle, offset, buf.GetPointer(), buf.GetSize()));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetRightsIdFromPlaceHolderId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id) {
|
Result ContentStorageInterface::GetRightsIdFromPlaceHolderId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
FsRightsId rights_id = {0};
|
FsRightsId rights_id = {0};
|
||||||
@ -422,14 +422,14 @@ namespace sts::ncm {
|
|||||||
out_rights_id.SetValue(rights_id);
|
out_rights_id.SetValue(rights_id);
|
||||||
out_key_generation.SetValue(static_cast<u64>(key_generation));
|
out_key_generation.SetValue(static_cast<u64>(key_generation));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id) {
|
Result ContentStorageInterface::GetRightsIdFromContentId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
std::scoped_lock<os::Mutex> lk(this->rights_id_cache->mutex);
|
||||||
|
|
||||||
/* Attempt to locate the content id in the cache. */
|
/* Attempt to locate the content id in the cache. */
|
||||||
for (size_t i = 0; i < impl::RightsIdCache::MaxEntries; i++) {
|
for (size_t i = 0; i < impl::RightsIdCache::MaxEntries; i++) {
|
||||||
@ -440,7 +440,7 @@ namespace sts::ncm {
|
|||||||
this->rights_id_cache->counter++;
|
this->rights_id_cache->counter++;
|
||||||
out_rights_id.SetValue(entry->rights_id);
|
out_rights_id.SetValue(entry->rights_id);
|
||||||
out_key_generation.SetValue(entry->key_generation);
|
out_key_generation.SetValue(entry->key_generation);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,7 +454,7 @@ namespace sts::ncm {
|
|||||||
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
std::scoped_lock<os::Mutex> lk(this->rights_id_cache->mutex);
|
||||||
impl::RightsIdCache::Entry* eviction_candidate = &this->rights_id_cache->entries[0];
|
impl::RightsIdCache::Entry* eviction_candidate = &this->rights_id_cache->entries[0];
|
||||||
|
|
||||||
/* Find a suitable existing entry to store our new one at. */
|
/* Find a suitable existing entry to store our new one at. */
|
||||||
@ -479,13 +479,13 @@ namespace sts::ncm {
|
|||||||
out_key_generation.SetValue(key_generation);
|
out_key_generation.SetValue(key_generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::WriteContentForDebug(ContentId content_id, u64 offset, InBuffer<u8> data) {
|
Result ContentStorageInterface::WriteContentForDebug(ContentId content_id, u64 offset, sf::InBuffer data) {
|
||||||
/* Offset is too large */
|
/* Offset is too large */
|
||||||
if (offset >> 0x3f != 0) {
|
if (offset >> 0x3f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
@ -502,43 +502,43 @@ namespace sts::ncm {
|
|||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(content_path, content_id);
|
||||||
|
|
||||||
FILE* f = nullptr;
|
FILE* f = nullptr;
|
||||||
R_TRY(fs::OpenFile(&f, content_path, FS_OPEN_WRITE));
|
R_TRY(fs::OpenFile(&f, content_path, FsOpenMode_Write));
|
||||||
|
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
};
|
};
|
||||||
|
|
||||||
R_TRY(fs::WriteFile(f, offset, data.buffer, data.num_elements, FS_WRITEOPTION_FLUSH));
|
R_TRY(fs::WriteFile(f, offset, data.GetPointer(), data.GetSize(), FsWriteOption_Flush));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetFreeSpaceSize(Out<u64> out_size) {
|
Result ContentStorageInterface::GetFreeSpaceSize(sf::Out<u64> out_size) {
|
||||||
struct statvfs st = {0};
|
struct statvfs st = {0};
|
||||||
if (statvfs(this->root_path, &st) == -1) {
|
if (statvfs(this->root_path, &st) == -1) {
|
||||||
return fsdevGetLastResult();
|
return fsdevGetLastResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
out_size.SetValue(st.f_bfree);
|
out_size.SetValue(st.f_bfree);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetTotalSpaceSize(Out<u64> out_size) {
|
Result ContentStorageInterface::GetTotalSpaceSize(sf::Out<u64> out_size) {
|
||||||
struct statvfs st = {0};
|
struct statvfs st = {0};
|
||||||
if (statvfs(this->root_path, &st) == -1) {
|
if (statvfs(this->root_path, &st) == -1) {
|
||||||
return fsdevGetLastResult();
|
return fsdevGetLastResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
out_size.SetValue(st.f_blocks);
|
out_size.SetValue(st.f_blocks);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::FlushPlaceHolder() {
|
Result ContentStorageInterface::FlushPlaceHolder() {
|
||||||
this->placeholder_accessor.InvalidateAll();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetSizeFromPlaceHolderId(Out<u64> out_size, PlaceHolderId placeholder_id) {
|
Result ContentStorageInterface::GetSizeFromPlaceHolderId(sf::Out<u64> out_size, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
bool found_in_cache = false;
|
bool found_in_cache = false;
|
||||||
@ -548,7 +548,7 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
if (found_in_cache) {
|
if (found_in_cache) {
|
||||||
out_size.SetValue(size);
|
out_size.SetValue(size);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
@ -560,7 +560,7 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_size.SetValue(st.st_size);
|
out_size.SetValue(st.st_size);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::RepairInvalidFileAttribute() {
|
Result ContentStorageInterface::RepairInvalidFileAttribute() {
|
||||||
@ -573,13 +573,13 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
if (dir_entry->d_type == DT_DIR) {
|
if (dir_entry->d_type == DT_DIR) {
|
||||||
if (path::IsNcaPath(current_path)) {
|
if (path::IsNcaPath(current_path)) {
|
||||||
if (R_SUCCEEDED(fsdevSetArchiveBit(current_path))) {
|
if (R_SUCCEEDED(fsdevSetConcatenationFileAttribute(current_path))) {
|
||||||
*should_retry_dir_read = true;
|
*should_retry_dir_read = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
};
|
};
|
||||||
|
|
||||||
R_TRY(fs::TraverseDirectory(content_root_path, dir_depth, fix_file_attributes));
|
R_TRY(fs::TraverseDirectory(content_root_path, dir_depth, fix_file_attributes));
|
||||||
@ -591,14 +591,14 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
R_TRY(fs::TraverseDirectory(placeholder_root_path, dir_depth, fix_file_attributes));
|
R_TRY(fs::TraverseDirectory(placeholder_root_path, dir_depth, fix_file_attributes));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageInterface::GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
Result ContentStorageInterface::GetRightsIdFromPlaceHolderIdWithCache(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
std::scoped_lock<os::Mutex> lk(this->rights_id_cache->mutex);
|
||||||
|
|
||||||
/* Attempt to locate the content id in the cache. */
|
/* Attempt to locate the content id in the cache. */
|
||||||
for (size_t i = 0; i < impl::RightsIdCache::MaxEntries; i++) {
|
for (size_t i = 0; i < impl::RightsIdCache::MaxEntries; i++) {
|
||||||
@ -609,7 +609,7 @@ namespace sts::ncm {
|
|||||||
this->rights_id_cache->counter++;
|
this->rights_id_cache->counter++;
|
||||||
out_rights_id.SetValue(entry->rights_id);
|
out_rights_id.SetValue(entry->rights_id);
|
||||||
out_key_generation.SetValue(entry->key_generation);
|
out_key_generation.SetValue(entry->key_generation);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -623,7 +623,7 @@ namespace sts::ncm {
|
|||||||
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
std::scoped_lock<os::Mutex> lk(this->rights_id_cache->mutex);
|
||||||
impl::RightsIdCache::Entry* eviction_candidate = &this->rights_id_cache->entries[0];
|
impl::RightsIdCache::Entry* eviction_candidate = &this->rights_id_cache->entries[0];
|
||||||
|
|
||||||
/* Find a suitable existing entry to store our new one at. */
|
/* Find a suitable existing entry to store our new one at. */
|
||||||
@ -648,7 +648,7 @@ namespace sts::ncm {
|
|||||||
out_key_generation.SetValue(key_generation);
|
out_key_generation.SetValue(key_generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "ncm_icontentstorage.hpp"
|
#include "ncm_icontentstorage.hpp"
|
||||||
#include "ncm_path_utils.hpp"
|
#include "ncm_path_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
class ContentStorageInterface : public IContentStorage {
|
class ContentStorageInterface : public IContentStorage {
|
||||||
protected:
|
protected:
|
||||||
@ -52,66 +52,34 @@ namespace sts::ncm {
|
|||||||
this->make_content_path_func(out_content_path, content_id, content_root_path);
|
this->make_content_path_func(out_content_path, content_id, content_root_path);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual Result GeneratePlaceHolderId(Out<PlaceHolderId> out) override;
|
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) override;
|
||||||
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) override;
|
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) override;
|
||||||
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) override;
|
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) override;
|
||||||
virtual Result HasPlaceHolder(Out<bool> out, PlaceHolderId placeholder_id) override;
|
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, InBuffer<u8> data) override;
|
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, sf::InBuffer data) override;
|
||||||
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) override;
|
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) override;
|
||||||
virtual Result Delete(ContentId content_id) override;
|
virtual Result Delete(ContentId content_id) override;
|
||||||
virtual Result Has(Out<bool> out, ContentId content_id) override;
|
virtual Result Has(sf::Out<bool> out, ContentId content_id) override;
|
||||||
virtual Result GetPath(OutPointerWithServerSize<lr::Path, 0x1> out, ContentId content_id) override;
|
virtual Result GetPath(sf::Out<lr::Path> out, ContentId content_id) override;
|
||||||
virtual Result GetPlaceHolderPath(OutPointerWithServerSize<lr::Path, 0x1> out, PlaceHolderId placeholder_id) override;
|
virtual Result GetPlaceHolderPath(sf::Out<lr::Path> out, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result CleanupAllPlaceHolder() override;
|
virtual Result CleanupAllPlaceHolder() override;
|
||||||
virtual Result ListPlaceHolder(Out<u32> out_count, OutBuffer<PlaceHolderId> out_buf) override;
|
virtual Result ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) override;
|
||||||
virtual Result GetContentCount(Out<u32> out_count) override;
|
virtual Result GetContentCount(sf::Out<u32> out_count) override;
|
||||||
virtual Result ListContentId(Out<u32> out_count, OutBuffer<ContentId> out_buf, u32 start_offset) override;
|
virtual Result ListContentId(sf::Out<u32> out_count, const sf::OutArray<ContentId> &out_buf, u32 start_offset) override;
|
||||||
virtual Result GetSizeFromContentId(Out<u64> out_size, ContentId content_id) override;
|
virtual Result GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) override;
|
||||||
virtual Result DisableForcibly() override;
|
virtual Result DisableForcibly() override;
|
||||||
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) override;
|
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) override;
|
||||||
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) override;
|
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) override;
|
||||||
virtual Result ReadContentIdFile(OutBuffer<u8> buf, ContentId content_id, u64 offset) override;
|
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, u64 offset) override;
|
||||||
virtual Result GetRightsIdFromPlaceHolderId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id) override;
|
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id) override;
|
virtual Result GetRightsIdFromContentId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, ContentId content_id) override;
|
||||||
virtual Result WriteContentForDebug(ContentId content_id, u64 offset, InBuffer<u8> data) override;
|
virtual Result WriteContentForDebug(ContentId content_id, u64 offset, sf::InBuffer data) override;
|
||||||
virtual Result GetFreeSpaceSize(Out<u64> out_size) override;
|
virtual Result GetFreeSpaceSize(sf::Out<u64> out_size) override;
|
||||||
virtual Result GetTotalSpaceSize(Out<u64> out_size) override;
|
virtual Result GetTotalSpaceSize(sf::Out<u64> out_size) override;
|
||||||
virtual Result FlushPlaceHolder() override;
|
virtual Result FlushPlaceHolder() override;
|
||||||
virtual Result GetSizeFromPlaceHolderId(Out<u64> out, PlaceHolderId placeholder_id) override;
|
virtual Result GetSizeFromPlaceHolderId(sf::Out<u64> out, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result RepairInvalidFileAttribute() override;
|
virtual Result RepairInvalidFileAttribute() override;
|
||||||
virtual Result GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) override;
|
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) override;
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GeneratePlaceHolderId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, CreatePlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, DeletePlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, HasPlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, WritePlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, Register),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, Delete),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, Has),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetPath),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetPlaceHolderPath),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, CleanupAllPlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, ListPlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GeneratePlaceHolderId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetContentCount),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, ListContentId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetSizeFromContentId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, DisableForcibly),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, RevertToPlaceHolder, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, SetPlaceHolderSize, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, ReadContentIdFile, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetRightsIdFromPlaceHolderId, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetRightsIdFromContentId, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, WriteContentForDebug, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetFreeSpaceSize, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetTotalSpaceSize, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, FlushPlaceHolder, FirmwareVersion_300),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetSizeFromPlaceHolderId, FirmwareVersion_400),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, RepairInvalidFileAttribute, FirmwareVersion_400),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ContentStorageInterface, GetRightsIdFromPlaceHolderIdWithCache, FirmwareVersion_800),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "ncm_fs.hpp"
|
#include "ncm_fs.hpp"
|
||||||
#include "ncm_path_utils.hpp"
|
#include "ncm_path_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::fs {
|
namespace ams::ncm::fs {
|
||||||
|
|
||||||
Result OpenFile(FILE** out, const char* path, u32 mode) {
|
Result OpenFile(FILE** out, const char* path, u32 mode) {
|
||||||
bool has = false;
|
bool has = false;
|
||||||
@ -29,14 +29,14 @@ namespace sts::ncm::fs {
|
|||||||
/* Manually check if the file already exists, so it doesn't get created automatically. */
|
/* Manually check if the file already exists, so it doesn't get created automatically. */
|
||||||
R_TRY(HasFile(&has, path));
|
R_TRY(HasFile(&has, path));
|
||||||
if (!has) {
|
if (!has) {
|
||||||
return ResultFsPathNotFound;
|
return ams::fs::ResultPathNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* fopen_mode = "";
|
const char* fopen_mode = "";
|
||||||
|
|
||||||
if (mode & FS_OPEN_WRITE) {
|
if (mode & FsOpenMode_Write) {
|
||||||
fopen_mode = "r+b";
|
fopen_mode = "r+b";
|
||||||
} else if (mode & FS_OPEN_READ) {
|
} else if (mode & FsOpenMode_Read) {
|
||||||
fopen_mode = "rb";
|
fopen_mode = "rb";
|
||||||
}
|
}
|
||||||
FILE* f = fopen(path, fopen_mode);
|
FILE* f = fopen(path, fopen_mode);
|
||||||
@ -46,7 +46,7 @@ namespace sts::ncm::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*out = f;
|
*out = f;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteFile(FILE* f, size_t offset, const void* buffer, size_t size, u32 option) {
|
Result WriteFile(FILE* f, size_t offset, const void* buffer, size_t size, u32 option) {
|
||||||
@ -56,7 +56,7 @@ namespace sts::ncm::fs {
|
|||||||
size_t existing_size = ftell(f);
|
size_t existing_size = ftell(f);
|
||||||
|
|
||||||
if (offset + size > existing_size) {
|
if (offset + size > existing_size) {
|
||||||
return ResultFsFileExtensionWithoutOpenModeAllowAppend;
|
return ams::fs::ResultFileExtensionWithoutOpenModeAllowAppend();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(f, offset, SEEK_SET) != 0) {
|
if (fseek(f, offset, SEEK_SET) != 0) {
|
||||||
@ -67,11 +67,11 @@ namespace sts::ncm::fs {
|
|||||||
return fsdevGetLastResult();
|
return fsdevGetLastResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option & FS_WRITEOPTION_FLUSH) {
|
if (option & FsWriteOption_Flush) {
|
||||||
fflush(f);
|
fflush(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(FILE* f, size_t offset, void* buffer, size_t size) {
|
Result ReadFile(FILE* f, size_t offset, void* buffer, size_t size) {
|
||||||
@ -83,7 +83,7 @@ namespace sts::ncm::fs {
|
|||||||
return fsdevGetLastResult();
|
return fsdevGetLastResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result HasFile(bool* out, const char* path) {
|
Result HasFile(bool* out, const char* path) {
|
||||||
@ -93,13 +93,13 @@ namespace sts::ncm::fs {
|
|||||||
*out = true;
|
*out = true;
|
||||||
} else {
|
} else {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
*out = false;
|
*out = false;
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result HasDirectory(bool* out, const char* path) {
|
Result HasDirectory(bool* out, const char* path) {
|
||||||
@ -109,13 +109,13 @@ namespace sts::ncm::fs {
|
|||||||
*out = true;
|
*out = true;
|
||||||
} else {
|
} else {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ams::fs::ResultPathNotFound) {
|
||||||
*out = false;
|
*out = false;
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheckContentStorageDirectoriesExist(const char* root_path) {
|
Result CheckContentStorageDirectoriesExist(const char* root_path) {
|
||||||
@ -125,7 +125,7 @@ namespace sts::ncm::fs {
|
|||||||
bool has_root = false;
|
bool has_root = false;
|
||||||
R_TRY(HasDirectory(&has_root, root_path));
|
R_TRY(HasDirectory(&has_root, root_path));
|
||||||
if (!has_root) {
|
if (!has_root) {
|
||||||
return ResultNcmStorageRootNotFound;
|
return ResultStorageRootNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
path::GetContentRootPath(content_root, root_path);
|
path::GetContentRootPath(content_root, root_path);
|
||||||
@ -133,7 +133,7 @@ namespace sts::ncm::fs {
|
|||||||
bool has_content_root = false;
|
bool has_content_root = false;
|
||||||
R_TRY(HasDirectory(&has_content_root, content_root));
|
R_TRY(HasDirectory(&has_content_root, content_root));
|
||||||
if (!has_content_root) {
|
if (!has_content_root) {
|
||||||
return ResultNcmStoragePathNotFound;
|
return ResultStoragePathNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
path::GetPlaceHolderRootPath(placeholder_root, root_path);
|
path::GetPlaceHolderRootPath(placeholder_root, root_path);
|
||||||
@ -141,10 +141,10 @@ namespace sts::ncm::fs {
|
|||||||
bool has_placeholder_root = false;
|
bool has_placeholder_root = false;
|
||||||
R_TRY(HasDirectory(&has_placeholder_root, placeholder_root));
|
R_TRY(HasDirectory(&has_placeholder_root, placeholder_root));
|
||||||
if (!has_placeholder_root) {
|
if (!has_placeholder_root) {
|
||||||
return ResultNcmStoragePathNotFound;
|
return ResultStoragePathNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EnsureContentAndPlaceHolderRoot(const char* root_path) {
|
Result EnsureContentAndPlaceHolderRoot(const char* root_path) {
|
||||||
@ -156,24 +156,24 @@ namespace sts::ncm::fs {
|
|||||||
path::GetPlaceHolderRootPath(placeholder_root, root_path);
|
path::GetPlaceHolderRootPath(placeholder_root, root_path);
|
||||||
R_TRY(EnsureDirectoryRecursively(placeholder_root));
|
R_TRY(EnsureDirectoryRecursively(placeholder_root));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EnsureDirectoryRecursively(const char* dir_path) {
|
Result EnsureDirectoryRecursively(const char* dir_path) {
|
||||||
R_TRY(EnsureRecursively(dir_path));
|
R_TRY(EnsureRecursively(dir_path));
|
||||||
if (mkdir(dir_path, S_IRWXU) == -1) {
|
if (mkdir(dir_path, S_IRWXU) == -1) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathAlreadyExists) {
|
R_CATCH(ams::fs::ResultPathAlreadyExists) {
|
||||||
/* If the path already exists, that's okay. Anything else is an error. */
|
/* If the path already exists, that's okay. Anything else is an error. */
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
}
|
}
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EnsureRecursively(const char* path) {
|
Result EnsureRecursively(const char* path) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return ResultFsNullptrArgument;
|
return ams::fs::ResultNullptrArgument();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t path_len = strlen(path);
|
size_t path_len = strlen(path);
|
||||||
@ -189,7 +189,7 @@ namespace sts::ncm::fs {
|
|||||||
working_path_buf[i + 1] = 0;
|
working_path_buf[i + 1] = 0;
|
||||||
if (mkdir(working_path_buf + 1, S_IRWXU) == -1) {
|
if (mkdir(working_path_buf + 1, S_IRWXU) == -1) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathAlreadyExists) {
|
R_CATCH(ams::fs::ResultPathAlreadyExists) {
|
||||||
/* If the path already exists, that's okay. Anything else is an error. */
|
/* If the path already exists, that's okay. Anything else is an error. */
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
@ -201,10 +201,10 @@ namespace sts::ncm::fs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return ResultNcmAllocationFailed;
|
return ResultAllocationFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EnsureParentDirectoryRecursively(const char* path) {
|
Result EnsureParentDirectoryRecursively(const char* path) {
|
||||||
@ -219,14 +219,14 @@ namespace sts::ncm::fs {
|
|||||||
ON_SCOPE_EXIT { fsDeviceOperatorClose(&devop); };
|
ON_SCOPE_EXIT { fsDeviceOperatorClose(&devop); };
|
||||||
|
|
||||||
R_TRY(fsDeviceOperatorGetGameCardHandle(&devop, out_handle));
|
R_TRY(fsDeviceOperatorGetGameCardHandle(&devop, out_handle));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 g_mount_index = 0;
|
static u32 g_mount_index = 0;
|
||||||
static HosMutex g_mount_index_lock;
|
static os::Mutex g_mount_index_lock;
|
||||||
|
|
||||||
MountName CreateUniqueMountName() {
|
MountName CreateUniqueMountName() {
|
||||||
std::scoped_lock<HosMutex> lk(g_mount_index_lock);
|
std::scoped_lock<os::Mutex> lk(g_mount_index_lock);
|
||||||
MountName mount_name;
|
MountName mount_name;
|
||||||
g_mount_index++;
|
g_mount_index++;
|
||||||
snprintf(mount_name.name, sizeof(MountName), "@ncm%08x", g_mount_index);
|
snprintf(mount_name.name, sizeof(MountName), "@ncm%08x", g_mount_index);
|
||||||
@ -238,31 +238,31 @@ namespace sts::ncm::fs {
|
|||||||
|
|
||||||
/* We should be given a qualified path. */
|
/* We should be given a qualified path. */
|
||||||
if (!unqual_path || unqual_path > path + 0xf) {
|
if (!unqual_path || unqual_path > path + 0xf) {
|
||||||
return ResultFsInvalidMountName;
|
return ams::fs::ResultInvalidMountName();
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(mount_name->name, path, unqual_path - path);
|
strncpy(mount_name->name, path, unqual_path - path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MountSystemSaveData(const char* mount_point, FsSaveDataSpaceId space_id, u64 save_id) {
|
Result MountSystemSaveData(const char* mount_point, FsSaveDataSpaceId space_id, u64 save_id) {
|
||||||
if (!mount_point) {
|
if (!mount_point) {
|
||||||
return ResultFsNullptrArgument;
|
return ams::fs::ResultNullptrArgument();
|
||||||
}
|
}
|
||||||
|
|
||||||
FsSave save = {
|
FsSaveDataAttribute save = {
|
||||||
.saveID = save_id,
|
.system_save_data_id = save_id,
|
||||||
.saveDataType = FsSaveDataType_SystemSaveData,
|
.save_data_type = FsSaveDataType_System,
|
||||||
};
|
};
|
||||||
|
|
||||||
FsFileSystem fs;
|
FsFileSystem fs;
|
||||||
R_TRY(fsMountSystemSaveData(&fs, space_id, &save));
|
R_TRY(fsOpenSaveDataFileSystemBySystemSaveDataId(&fs, space_id, &save));
|
||||||
|
|
||||||
if (fsdevMountDevice(mount_point, fs) == -1) {
|
if (fsdevMountDevice(mount_point, fs) == -1) {
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const char* SystemContentMountName = "@SystemContent";
|
constexpr const char* SystemContentMountName = "@SystemContent";
|
||||||
@ -277,7 +277,7 @@ namespace sts::ncm::fs {
|
|||||||
|
|
||||||
Result MountContentStorage(const char* mount_point, FsContentStorageId id) {
|
Result MountContentStorage(const char* mount_point, FsContentStorageId id) {
|
||||||
if (!mount_point) {
|
if (!mount_point) {
|
||||||
return ResultFsNullptrArgument;
|
return ams::fs::ResultNullptrArgument();
|
||||||
}
|
}
|
||||||
|
|
||||||
FsFileSystem fs;
|
FsFileSystem fs;
|
||||||
@ -288,25 +288,25 @@ namespace sts::ncm::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case FS_CONTENTSTORAGEID_NandSystem:
|
case FsContentStorageId_System:
|
||||||
g_mount_content_storage[mount_point] = SystemContentMountName;
|
g_mount_content_storage[mount_point] = SystemContentMountName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_CONTENTSTORAGEID_NandUser:
|
case FsContentStorageId_User:
|
||||||
g_mount_content_storage[mount_point] = UserContentMountName;
|
g_mount_content_storage[mount_point] = UserContentMountName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_CONTENTSTORAGEID_SdCard:
|
case FsContentStorageId_SdCard:
|
||||||
g_mount_content_storage[mount_point] = SdCardContentMountName;
|
g_mount_content_storage[mount_point] = SdCardContentMountName;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
};
|
};
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result MountGameCardPartition(const char* mount_point, const FsGameCardHandle handle, FsGameCardPartiton partition) {
|
Result MountGameCardPartition(const char* mount_point, const FsGameCardHandle handle, FsGameCardPartition partition) {
|
||||||
if (partition > 2) {
|
if (partition > 2) {
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
@ -321,12 +321,12 @@ namespace sts::ncm::fs {
|
|||||||
MountName mount = {0};
|
MountName mount = {0};
|
||||||
snprintf(mount.name, sizeof(MountName), "%s%s%08x", GameCardMountNameBase, GameCardPartitionLetters[partition], handle.value);
|
snprintf(mount.name, sizeof(MountName), "%s%s%08x", GameCardMountNameBase, GameCardPartitionLetters[partition], handle.value);
|
||||||
g_mount_content_storage[mount_point] = mount.name;
|
g_mount_content_storage[mount_point] = mount.name;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Unmount(const char* mount_point) {
|
Result Unmount(const char* mount_point) {
|
||||||
if (!mount_point) {
|
if (!mount_point) {
|
||||||
return ResultFsNullptrArgument;
|
return ams::fs::ResultNullptrArgument();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Erase any content storage mappings which may potentially exist. */
|
/* Erase any content storage mappings which may potentially exist. */
|
||||||
@ -336,19 +336,19 @@ namespace sts::ncm::fs {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ConvertToFsCommonPath(char* out_common_path, size_t out_len, const char* path) {
|
Result ConvertToFsCommonPath(char* out_common_path, size_t out_len, const char* path) {
|
||||||
if (!out_common_path || !path) {
|
if (!out_common_path || !path) {
|
||||||
return ResultFsNullptrArgument;
|
return ams::fs::ResultNullptrArgument();
|
||||||
}
|
}
|
||||||
|
|
||||||
MountName mount_name = {0};
|
MountName mount_name = {0};
|
||||||
R_TRY(GetMountNameFromPath(&mount_name, path));
|
R_TRY(GetMountNameFromPath(&mount_name, path));
|
||||||
|
|
||||||
if (!fsdevGetDeviceFileSystem(mount_name.name) || g_mount_content_storage.find(mount_name.name) == g_mount_content_storage.end()) {
|
if (!fsdevGetDeviceFileSystem(mount_name.name) || g_mount_content_storage.find(mount_name.name) == g_mount_content_storage.end()) {
|
||||||
return ResultFsMountNameNotFound;
|
return ams::fs::ResultNotMounted();
|
||||||
}
|
}
|
||||||
|
|
||||||
char translated_path[FS_MAX_PATH] = {0};
|
char translated_path[FS_MAX_PATH] = {0};
|
||||||
@ -359,7 +359,7 @@ namespace sts::ncm::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(out_common_path, out_len, "%s:%s", common_mount_name.c_str(), translated_path);
|
snprintf(out_common_path, out_len, "%s:%s", common_mount_name.c_str(), translated_path);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetSaveDataFlags(u32* out_flags, u64 save_id) {
|
Result GetSaveDataFlags(u32* out_flags, u64 save_id) {
|
||||||
@ -367,7 +367,7 @@ namespace sts::ncm::fs {
|
|||||||
|
|
||||||
R_TRY(fsReadSaveDataFileSystemExtraData(&extra_data, sizeof(FsSaveDataExtraData), save_id));
|
R_TRY(fsReadSaveDataFileSystemExtraData(&extra_data, sizeof(FsSaveDataExtraData), save_id));
|
||||||
*out_flags = extra_data.flags;
|
*out_flags = extra_data.flags;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetSaveDataFlags(u64 save_id, FsSaveDataSpaceId space_id, u32 flags) {
|
Result SetSaveDataFlags(u64 save_id, FsSaveDataSpaceId space_id, u32 flags) {
|
||||||
@ -376,7 +376,7 @@ namespace sts::ncm::fs {
|
|||||||
R_TRY(fsReadSaveDataFileSystemExtraData(&extra_data, sizeof(FsSaveDataExtraData), save_id));
|
R_TRY(fsReadSaveDataFileSystemExtraData(&extra_data, sizeof(FsSaveDataExtraData), save_id));
|
||||||
extra_data.flags = flags;
|
extra_data.flags = flags;
|
||||||
R_TRY(fsWriteSaveDataFileSystemExtraData(&extra_data, sizeof(FsSaveDataExtraData), space_id, save_id));
|
R_TRY(fsWriteSaveDataFileSystemExtraData(&extra_data, sizeof(FsSaveDataExtraData), space_id, save_id));
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include <sys/dirent.h>
|
#include <sys/dirent.h>
|
||||||
|
|
||||||
namespace sts::ncm::fs {
|
namespace ams::ncm::fs {
|
||||||
|
|
||||||
Result OpenFile(FILE** out, const char* path, u32 mode);
|
Result OpenFile(FILE** out, const char* path, u32 mode);
|
||||||
Result WriteFile(FILE* f, size_t offset, const void* buffer, size_t size, u32 option);
|
Result WriteFile(FILE* f, size_t offset, const void* buffer, size_t size, u32 option);
|
||||||
@ -43,7 +43,7 @@ namespace sts::ncm::fs {
|
|||||||
|
|
||||||
Result MountSystemSaveData(const char* mount_point, FsSaveDataSpaceId space_id, u64 save_id);
|
Result MountSystemSaveData(const char* mount_point, FsSaveDataSpaceId space_id, u64 save_id);
|
||||||
Result MountContentStorage(const char* mount_point, FsContentStorageId id);
|
Result MountContentStorage(const char* mount_point, FsContentStorageId id);
|
||||||
Result MountGameCardPartition(const char* mount_point, const FsGameCardHandle handle, FsGameCardPartiton partition);
|
Result MountGameCardPartition(const char* mount_point, const FsGameCardHandle handle, FsGameCardPartition partition);
|
||||||
Result Unmount(const char* mount_point);
|
Result Unmount(const char* mount_point);
|
||||||
Result ConvertToFsCommonPath(char* out_common_path, size_t len, const char* path);
|
Result ConvertToFsCommonPath(char* out_common_path, size_t len, const char* path);
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ namespace sts::ncm::fs {
|
|||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent* dir_entry = nullptr;
|
struct dirent* dir_entry = nullptr;
|
||||||
if (max_level < 1) {
|
if (max_level < 1) {
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool retry_dir_read = true;
|
bool retry_dir_read = true;
|
||||||
@ -84,7 +84,7 @@ namespace sts::ncm::fs {
|
|||||||
/* If the provided function wishes to terminate immediately, we should respect it. */
|
/* If the provided function wishes to terminate immediately, we should respect it. */
|
||||||
if (!should_continue) {
|
if (!should_continue) {
|
||||||
*out_should_continue = false;
|
*out_should_continue = false;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
if (should_retry_dir_read) {
|
if (should_retry_dir_read) {
|
||||||
retry_dir_read = true;
|
retry_dir_read = true;
|
||||||
@ -96,13 +96,13 @@ namespace sts::ncm::fs {
|
|||||||
|
|
||||||
if (!should_continue) {
|
if (!should_continue) {
|
||||||
*out_should_continue = false;
|
*out_should_continue = false;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019 Adubbz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ncm_icontentmetadatabase.hpp"
|
|
||||||
|
|
||||||
namespace sts::ncm {
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::EnsureEnabled() {
|
|
||||||
if (this->disabled) {
|
|
||||||
return ResultNcmInvalidContentMetaDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResultSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::Set(ContentMetaKey key, InBuffer<u8> value) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::Get(Out<u64> out_size, ContentMetaKey key, OutBuffer<u8> out_value) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::Remove(ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetContentIdByType(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::ListContentInfo(Out<u32> out_entries_written, OutBuffer<ContentInfo> out_info, ContentMetaKey key, u32 start_index) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::List(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ContentMetaKey> out_info, ContentMetaType type, TitleId application_title_id, TitleId title_id_min, TitleId title_id_max, ContentInstallType install_type) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetLatestContentMetaKey(Out<ContentMetaKey> out_key, TitleId title_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::ListApplication(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ApplicationContentMetaKey> out_keys, ContentMetaType type) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::Has(Out<bool> out, ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::HasAll(Out<bool> out, InBuffer<ContentMetaKey> keys) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetSize(Out<u64> out_size, ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetRequiredSystemVersion(Out<u32> out_version, ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetPatchId(Out<TitleId> out_patch_id, ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::DisableForcibly() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::LookupOrphanContent(OutBuffer<bool> out_orphaned, InBuffer<ContentId> content_ids) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::Commit() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::HasContent(Out<bool> out, ContentMetaKey key, ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::ListContentMetaInfo(Out<u32> out_entries_written, OutBuffer<ContentMetaInfo> out_meta_info, ContentMetaKey key, u32 start_index) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetAttributes(Out<ContentMetaAttribute> out_attributes, ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetRequiredApplicationVersion(Out<u32> out_version, ContentMetaKey key) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetContentIdByTypeAndIdOffset(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetLatestProgram(ContentId* out_content_id, TitleId title_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentMetaDatabase::GetLatestData(ContentId* out_content_id, TitleId title_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -19,9 +19,9 @@
|
|||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include <stratosphere/kvdb/kvdb_memory_key_value_store.hpp>
|
#include <stratosphere/kvdb/kvdb_memory_key_value_store.hpp>
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
class IContentMetaDatabase : public IServiceObject {
|
class IContentMetaDatabase : public sf::IServiceObject {
|
||||||
protected:
|
protected:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
Set = 0,
|
Set = 0,
|
||||||
@ -47,72 +47,77 @@ namespace sts::ncm {
|
|||||||
GetContentIdByTypeAndIdOffset = 20,
|
GetContentIdByTypeAndIdOffset = 20,
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
sts::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs;
|
ams::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs;
|
||||||
char mount_name[16];
|
char mount_name[16];
|
||||||
bool disabled;
|
bool disabled;
|
||||||
protected:
|
protected:
|
||||||
Result EnsureEnabled();
|
Result EnsureEnabled() {
|
||||||
|
if (this->disabled) {
|
||||||
|
return ResultInvalidContentMetaDatabase();
|
||||||
|
}
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
IContentMetaDatabase(sts::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs) :
|
IContentMetaDatabase(ams::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs) :
|
||||||
kvs(kvs), disabled(false)
|
kvs(kvs), disabled(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IContentMetaDatabase(sts::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs, const char* mount_name) :
|
IContentMetaDatabase(ams::kvdb::MemoryKeyValueStore<ContentMetaKey>* kvs, const char* mount_name) :
|
||||||
IContentMetaDatabase(kvs)
|
IContentMetaDatabase(kvs)
|
||||||
{
|
{
|
||||||
strcpy(this->mount_name, mount_name);
|
strcpy(this->mount_name, mount_name);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
virtual Result Set(ContentMetaKey key, InBuffer<u8> value);
|
virtual Result Set(ContentMetaKey key, sf::InBuffer value);
|
||||||
virtual Result Get(Out<u64> out_size, ContentMetaKey key, OutBuffer<u8> out_value);
|
virtual Result Get(sf::Out<u64> out_size, ContentMetaKey key, sf::OutBuffer out_value);
|
||||||
virtual Result Remove(ContentMetaKey key);
|
virtual Result Remove(ContentMetaKey key);
|
||||||
virtual Result GetContentIdByType(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type);
|
virtual Result GetContentIdByType(sf::Out<ContentId> out_content_id, ContentMetaKey key, ContentType type);
|
||||||
virtual Result ListContentInfo(Out<u32> out_entries_written, OutBuffer<ContentInfo> out_info, ContentMetaKey key, u32 start_index);
|
virtual Result ListContentInfo(sf::Out<u32> out_entries_written, const sf::OutArray<ContentInfo> &out_info, ContentMetaKey key, u32 start_index);
|
||||||
virtual Result List(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ContentMetaKey> out_info, ContentMetaType meta_type, TitleId application_title_id, TitleId title_id_min, TitleId title_id_max, ContentInstallType install_type);
|
virtual Result List(sf::Out<u32> out_entries_total, sf::Out<u32> out_entries_written, const sf::OutArray<ContentMetaKey> &out_info, ContentMetaType meta_type, ProgramId application_title_id, ProgramId title_id_min, ProgramId title_id_max, ContentInstallType install_type);
|
||||||
virtual Result GetLatestContentMetaKey(Out<ContentMetaKey> out_key, TitleId tid);
|
virtual Result GetLatestContentMetaKey(sf::Out<ContentMetaKey> out_key, ProgramId tid);
|
||||||
virtual Result ListApplication(Out<u32> out_entries_total, Out<u32> out_entries_written, OutBuffer<ApplicationContentMetaKey> out_keys, ContentMetaType meta_type);
|
virtual Result ListApplication(sf::Out<u32> out_entries_total, sf::Out<u32> out_entries_written, const sf::OutArray<ApplicationContentMetaKey> &out_keys, ContentMetaType meta_type);
|
||||||
virtual Result Has(Out<bool> out, ContentMetaKey key);
|
virtual Result Has(sf::Out<bool> out, ContentMetaKey key);
|
||||||
virtual Result HasAll(Out<bool> out, InBuffer<ContentMetaKey> keys);
|
virtual Result HasAll(sf::Out<bool> out, const sf::InArray<ContentMetaKey> &keys);
|
||||||
virtual Result GetSize(Out<u64> out_size, ContentMetaKey key);
|
virtual Result GetSize(sf::Out<u64> out_size, ContentMetaKey key);
|
||||||
virtual Result GetRequiredSystemVersion(Out<u32> out_version, ContentMetaKey key);
|
virtual Result GetRequiredSystemVersion(sf::Out<u32> out_version, ContentMetaKey key);
|
||||||
virtual Result GetPatchId(Out<TitleId> out_patch_id, ContentMetaKey key);
|
virtual Result GetPatchId(sf::Out<ProgramId> out_patch_id, ContentMetaKey key);
|
||||||
virtual Result DisableForcibly();
|
virtual Result DisableForcibly();
|
||||||
virtual Result LookupOrphanContent(OutBuffer<bool> out_orphaned, InBuffer<ContentId> content_ids);
|
virtual Result LookupOrphanContent(const sf::OutArray<bool> &out_orphaned, const sf::InArray<ContentId> &content_ids);
|
||||||
virtual Result Commit();
|
virtual Result Commit();
|
||||||
virtual Result HasContent(Out<bool> out, ContentMetaKey key, ContentId content_id);
|
virtual Result HasContent(sf::Out<bool> out, ContentMetaKey key, ContentId content_id);
|
||||||
virtual Result ListContentMetaInfo(Out<u32> out_entries_written, OutBuffer<ContentMetaInfo> out_meta_info, ContentMetaKey key, u32 start_index);
|
virtual Result ListContentMetaInfo(sf::Out<u32> out_entries_written, const sf::OutArray<ContentMetaInfo> &out_meta_info, ContentMetaKey key, u32 start_index);
|
||||||
virtual Result GetAttributes(Out<ContentMetaAttribute> out_attributes, ContentMetaKey key);
|
virtual Result GetAttributes(sf::Out<ContentMetaAttribute> out_attributes, ContentMetaKey key);
|
||||||
virtual Result GetRequiredApplicationVersion(Out<u32> out_version, ContentMetaKey key);
|
virtual Result GetRequiredApplicationVersion(sf::Out<u32> out_version, ContentMetaKey key);
|
||||||
virtual Result GetContentIdByTypeAndIdOffset(Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset);
|
virtual Result GetContentIdByTypeAndIdOffset(sf::Out<ContentId> out_content_id, ContentMetaKey key, ContentType type, u8 id_offset);
|
||||||
|
|
||||||
/* APIs. */
|
/* APIs. */
|
||||||
virtual Result GetLatestProgram(ContentId* out_content_id, TitleId title_id);
|
virtual Result GetLatestProgram(ContentId* out_content_id, ProgramId title_id);
|
||||||
virtual Result GetLatestData(ContentId* out_content_id, TitleId title_id);
|
virtual Result GetLatestData(ContentId* out_content_id, ProgramId title_id);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, Set),
|
MAKE_SERVICE_COMMAND_META(Set),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, Get),
|
MAKE_SERVICE_COMMAND_META(Get),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, Remove),
|
MAKE_SERVICE_COMMAND_META(Remove),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetContentIdByType),
|
MAKE_SERVICE_COMMAND_META(GetContentIdByType),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, ListContentInfo),
|
MAKE_SERVICE_COMMAND_META(ListContentInfo),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, List),
|
MAKE_SERVICE_COMMAND_META(List),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetLatestContentMetaKey),
|
MAKE_SERVICE_COMMAND_META(GetLatestContentMetaKey),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, ListApplication),
|
MAKE_SERVICE_COMMAND_META(ListApplication),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, Has),
|
MAKE_SERVICE_COMMAND_META(Has),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, HasAll),
|
MAKE_SERVICE_COMMAND_META(HasAll),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetSize),
|
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetRequiredSystemVersion),
|
MAKE_SERVICE_COMMAND_META(GetRequiredSystemVersion),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetPatchId),
|
MAKE_SERVICE_COMMAND_META(GetPatchId),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, DisableForcibly),
|
MAKE_SERVICE_COMMAND_META(DisableForcibly),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, LookupOrphanContent),
|
MAKE_SERVICE_COMMAND_META(LookupOrphanContent),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, Commit),
|
MAKE_SERVICE_COMMAND_META(Commit),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, HasContent),
|
MAKE_SERVICE_COMMAND_META(HasContent),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, ListContentMetaInfo),
|
MAKE_SERVICE_COMMAND_META(ListContentMetaInfo),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetAttributes),
|
MAKE_SERVICE_COMMAND_META(GetAttributes),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetRequiredApplicationVersion, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(GetRequiredApplicationVersion, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentMetaDatabase, GetContentIdByTypeAndIdOffset, FirmwareVersion_500),
|
MAKE_SERVICE_COMMAND_META(GetContentIdByTypeAndIdOffset, hos::Version_500),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019 Adubbz
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ncm_icontentstorage.hpp"
|
|
||||||
|
|
||||||
namespace sts::ncm {
|
|
||||||
|
|
||||||
Result IContentStorage::EnsureEnabled() {
|
|
||||||
if (this->disabled) {
|
|
||||||
return ResultNcmInvalidContentStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResultSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GeneratePlaceHolderId(Out<PlaceHolderId> out) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::HasPlaceHolder(Out<bool> out, PlaceHolderId placeholder_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, InBuffer<u8> data) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::Delete(ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::Has(Out<bool> out, ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetPath(OutPointerWithServerSize<lr::Path, 0x1> out, ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetPlaceHolderPath(OutPointerWithServerSize<lr::Path, 0x1> out, PlaceHolderId placeholder_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::CleanupAllPlaceHolder() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::ListPlaceHolder(Out<u32> out_count, OutBuffer<PlaceHolderId> out_buf) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetContentCount(Out<u32> out_count) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::ListContentId(Out<u32> out_count, OutBuffer<ContentId> out_buf, u32 start_offset) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetSizeFromContentId(Out<u64> out_size, ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::DisableForcibly() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::ReadContentIdFile(OutBuffer<u8> buf, ContentId content_id, u64 offset) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetRightsIdFromPlaceHolderId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::WriteContentForDebug(ContentId content_id, u64 offset, InBuffer<u8> data) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetFreeSpaceSize(Out<u64> out_size) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetTotalSpaceSize(Out<u64> out_size) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::FlushPlaceHolder() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetSizeFromPlaceHolderId(Out<u64> out_size, PlaceHolderId placeholder_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::RepairInvalidFileAttribute() {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IContentStorage::GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -18,9 +18,9 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
class IContentStorage : public IServiceObject {
|
class IContentStorage : public sf::IServiceObject {
|
||||||
protected:
|
protected:
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
GeneratePlaceHolderId = 0,
|
GeneratePlaceHolderId = 0,
|
||||||
@ -57,67 +57,72 @@ namespace sts::ncm {
|
|||||||
MakeContentPathFunc make_content_path_func;
|
MakeContentPathFunc make_content_path_func;
|
||||||
bool disabled;
|
bool disabled;
|
||||||
protected:
|
protected:
|
||||||
Result EnsureEnabled();
|
Result EnsureEnabled() {
|
||||||
|
if (this->disabled) {
|
||||||
|
return ResultInvalidContentStorage();
|
||||||
|
}
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
virtual Result GeneratePlaceHolderId(Out<PlaceHolderId> out);
|
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out);
|
||||||
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size);
|
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size);
|
||||||
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id);
|
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id);
|
||||||
virtual Result HasPlaceHolder(Out<bool> out, PlaceHolderId placeholder_id);
|
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id);
|
||||||
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, InBuffer<u8> data);
|
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, sf::InBuffer data);
|
||||||
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id);
|
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id);
|
||||||
virtual Result Delete(ContentId content_id);
|
virtual Result Delete(ContentId content_id);
|
||||||
virtual Result Has(Out<bool> out, ContentId content_id);
|
virtual Result Has(sf::Out<bool> out, ContentId content_id);
|
||||||
virtual Result GetPath(OutPointerWithServerSize<lr::Path, 0x1> out, ContentId content_id);
|
virtual Result GetPath(sf::Out<lr::Path> out, ContentId content_id);
|
||||||
virtual Result GetPlaceHolderPath(OutPointerWithServerSize<lr::Path, 0x1> out, PlaceHolderId placeholder_id);
|
virtual Result GetPlaceHolderPath(sf::Out<lr::Path> out, PlaceHolderId placeholder_id);
|
||||||
virtual Result CleanupAllPlaceHolder();
|
virtual Result CleanupAllPlaceHolder();
|
||||||
virtual Result ListPlaceHolder(Out<u32> out_count, OutBuffer<PlaceHolderId> out_buf);
|
virtual Result ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf);
|
||||||
virtual Result GetContentCount(Out<u32> out_count);
|
virtual Result GetContentCount(sf::Out<u32> out_count);
|
||||||
virtual Result ListContentId(Out<u32> out_count, OutBuffer<ContentId> out_buf, u32 start_offset);
|
virtual Result ListContentId(sf::Out<u32> out_count, const sf::OutArray<ContentId> &out_buf, u32 start_offset);
|
||||||
virtual Result GetSizeFromContentId(Out<u64> out_size, ContentId content_id);
|
virtual Result GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id);
|
||||||
virtual Result DisableForcibly();
|
virtual Result DisableForcibly();
|
||||||
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id);
|
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id);
|
||||||
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size);
|
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size);
|
||||||
virtual Result ReadContentIdFile(OutBuffer<u8> buf, ContentId content_id, u64 offset);
|
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, u64 offset);
|
||||||
virtual Result GetRightsIdFromPlaceHolderId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id);
|
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id);
|
||||||
virtual Result GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id);
|
virtual Result GetRightsIdFromContentId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, ContentId content_id);
|
||||||
virtual Result WriteContentForDebug(ContentId content_id, u64 offset, InBuffer<u8> data);
|
virtual Result WriteContentForDebug(ContentId content_id, u64 offset, sf::InBuffer data);
|
||||||
virtual Result GetFreeSpaceSize(Out<u64> out_size);
|
virtual Result GetFreeSpaceSize(sf::Out<u64> out_size);
|
||||||
virtual Result GetTotalSpaceSize(Out<u64> out_size);
|
virtual Result GetTotalSpaceSize(sf::Out<u64> out_size);
|
||||||
virtual Result FlushPlaceHolder();
|
virtual Result FlushPlaceHolder();
|
||||||
virtual Result GetSizeFromPlaceHolderId(Out<u64> out, PlaceHolderId placeholder_id);
|
virtual Result GetSizeFromPlaceHolderId(sf::Out<u64> out, PlaceHolderId placeholder_id);
|
||||||
virtual Result RepairInvalidFileAttribute();
|
virtual Result RepairInvalidFileAttribute();
|
||||||
virtual Result GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id);
|
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GeneratePlaceHolderId),
|
MAKE_SERVICE_COMMAND_META(GeneratePlaceHolderId),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, CreatePlaceHolder),
|
MAKE_SERVICE_COMMAND_META(CreatePlaceHolder),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, DeletePlaceHolder),
|
MAKE_SERVICE_COMMAND_META(DeletePlaceHolder),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, HasPlaceHolder),
|
MAKE_SERVICE_COMMAND_META(HasPlaceHolder),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, WritePlaceHolder),
|
MAKE_SERVICE_COMMAND_META(WritePlaceHolder),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, Register),
|
MAKE_SERVICE_COMMAND_META(Register),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, Delete),
|
MAKE_SERVICE_COMMAND_META(Delete),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, Has),
|
MAKE_SERVICE_COMMAND_META(Has),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetPath),
|
MAKE_SERVICE_COMMAND_META(GetPath),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetPlaceHolderPath),
|
MAKE_SERVICE_COMMAND_META(GetPlaceHolderPath),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, CleanupAllPlaceHolder),
|
MAKE_SERVICE_COMMAND_META(CleanupAllPlaceHolder),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, ListPlaceHolder),
|
MAKE_SERVICE_COMMAND_META(ListPlaceHolder),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GeneratePlaceHolderId),
|
MAKE_SERVICE_COMMAND_META(GeneratePlaceHolderId),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetContentCount),
|
MAKE_SERVICE_COMMAND_META(GetContentCount),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, ListContentId),
|
MAKE_SERVICE_COMMAND_META(ListContentId),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetSizeFromContentId),
|
MAKE_SERVICE_COMMAND_META(GetSizeFromContentId),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, DisableForcibly),
|
MAKE_SERVICE_COMMAND_META(DisableForcibly),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, RevertToPlaceHolder, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(RevertToPlaceHolder, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, SetPlaceHolderSize, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(SetPlaceHolderSize, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, ReadContentIdFile, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(ReadContentIdFile, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetRightsIdFromPlaceHolderId, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderId, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetRightsIdFromContentId, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(GetRightsIdFromContentId, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, WriteContentForDebug, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(WriteContentForDebug, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetFreeSpaceSize, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(GetFreeSpaceSize, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetTotalSpaceSize, FirmwareVersion_200),
|
MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize, hos::Version_200),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, FlushPlaceHolder, FirmwareVersion_300),
|
MAKE_SERVICE_COMMAND_META(FlushPlaceHolder, hos::Version_300),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetSizeFromPlaceHolderId, FirmwareVersion_400),
|
MAKE_SERVICE_COMMAND_META(GetSizeFromPlaceHolderId, hos::Version_400),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, RepairInvalidFileAttribute, FirmwareVersion_400),
|
MAKE_SERVICE_COMMAND_META(RepairInvalidFileAttribute, hos::Version_400),
|
||||||
MAKE_SERVICE_COMMAND_META(IContentStorage, GetRightsIdFromPlaceHolderIdWithCache, FirmwareVersion_800),
|
MAKE_SERVICE_COMMAND_META(GetRightsIdFromPlaceHolderIdWithCache, hos::Version_800),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,58 +36,27 @@ extern "C" {
|
|||||||
void __appExit(void);
|
void __appExit(void);
|
||||||
|
|
||||||
/* Exception handling. */
|
/* Exception handling. */
|
||||||
alignas(16) u8 __nx_exception_stack[0x1000];
|
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
|
||||||
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Ncm;
|
namespace ams {
|
||||||
|
|
||||||
namespace {
|
ncm::ProgramId CurrentProgramId = ncm::ProgramId::Ncm;
|
||||||
|
|
||||||
/* Convenience definitions. */
|
namespace result {
|
||||||
constexpr uintptr_t IramBase = 0x40000000ull;
|
|
||||||
constexpr uintptr_t IramPayloadBase = 0x40010000ull;
|
|
||||||
constexpr size_t IramSize = 0x40000;
|
|
||||||
constexpr size_t IramPayloadMaxSize = 0x2E000;
|
|
||||||
|
|
||||||
/* Globals. */
|
bool CallFatalOnResultAssertion = false;
|
||||||
u8 __attribute__ ((aligned (0x1000))) g_work_page[0x1000];
|
|
||||||
|
|
||||||
/* Helpers. */
|
|
||||||
void ClearIram() {
|
|
||||||
/* Make page FFs. */
|
|
||||||
memset(g_work_page, 0xFF, sizeof(g_work_page));
|
|
||||||
|
|
||||||
/* Overwrite all of IRAM with FFs. */
|
|
||||||
for (size_t ofs = 0; ofs < IramSize; ofs += sizeof(g_work_page)) {
|
|
||||||
CopyToIram(IramBase + ofs, g_work_page, sizeof(g_work_page));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoReboot(AtmosphereFatalErrorContext *ctx) {
|
|
||||||
/* Ensure clean IRAM state. */
|
|
||||||
ClearIram();
|
|
||||||
|
|
||||||
/* Copy in fatal error context, if relevant. */
|
|
||||||
if (ctx != nullptr) {
|
|
||||||
std::memset(g_work_page, 0xCC, sizeof(g_work_page));
|
|
||||||
std::memcpy(g_work_page, ctx, sizeof(*ctx));
|
|
||||||
CopyToIram(IramPayloadBase + IramPayloadMaxSize, g_work_page, sizeof(g_work_page));
|
|
||||||
}
|
|
||||||
|
|
||||||
RebootToRcm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace ams;
|
||||||
|
|
||||||
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
StratosphereCrashHandler(ctx);
|
ams::CrashHandler(ctx);
|
||||||
}
|
|
||||||
|
|
||||||
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) {
|
|
||||||
DoReboot(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
@ -103,13 +72,13 @@ void __libnx_initheap(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __appInit(void) {
|
void __appInit(void) {
|
||||||
SetFirmwareVersionForLibnx();
|
hos::SetVersionForLibnx();
|
||||||
|
|
||||||
DoWithSmSession([&]() {
|
sm::DoWithSession([&]() {
|
||||||
R_ASSERT(fsInitialize());
|
R_ASSERT(fsInitialize());
|
||||||
});
|
});
|
||||||
|
|
||||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
ams::CheckApiVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __appExit(void) {
|
void __appExit(void) {
|
||||||
@ -118,39 +87,49 @@ void __appExit(void) {
|
|||||||
fsExit();
|
fsExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ServerOptions {
|
namespace {
|
||||||
|
|
||||||
|
struct NcmServerOptions {
|
||||||
static constexpr size_t PointerBufferSize = 0x400;
|
static constexpr size_t PointerBufferSize = 0x400;
|
||||||
static constexpr size_t MaxDomains = 0;
|
static constexpr size_t MaxDomains = 0;
|
||||||
static constexpr size_t MaxDomainObjects = 0;
|
static constexpr size_t MaxDomainObjects = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr sm::ServiceName NcmServiceName = sm::ServiceName::Encode("ncm");
|
||||||
|
constexpr size_t NcmMaxSessions = 16;
|
||||||
|
constexpr size_t NcmNumServers = 1;
|
||||||
|
|
||||||
|
constexpr sm::ServiceName LrServiceName = sm::ServiceName::Encode("lr");
|
||||||
|
constexpr size_t LrMaxSessions = 16;
|
||||||
|
constexpr size_t LrNumServers = 1;
|
||||||
|
|
||||||
|
sf::hipc::ServerManager<NcmNumServers, NcmServerOptions, NcmMaxSessions> g_ncm_server_manager;
|
||||||
|
sf::hipc::ServerManager<LrNumServers, NcmServerOptions, LrMaxSessions> g_lr_server_manager;
|
||||||
|
}
|
||||||
|
|
||||||
void ContentManagerServerMain(void* arg) {
|
void ContentManagerServerMain(void* arg) {
|
||||||
static auto s_server_manager = WaitableManager<ServerOptions>(1);
|
|
||||||
|
|
||||||
/* Create services. */
|
/* Create services. */
|
||||||
s_server_manager.AddWaitable(new ServiceServer<sts::ncm::ContentManagerService>("ncm", 0x10));
|
R_ASSERT(g_ncm_server_manager.RegisterServer<ncm::ContentManagerService>(NcmServiceName, NcmMaxSessions));
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
s_server_manager.Process();
|
g_ncm_server_manager.LoopProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationResolverServerMain(void* arg) {
|
void LocationResolverServerMain(void* arg) {
|
||||||
static auto s_server_manager = WaitableManager<ServerOptions>(1);
|
|
||||||
|
|
||||||
/* Create services. */
|
/* Create services. */
|
||||||
s_server_manager.AddWaitable(new ServiceServer<sts::lr::LocationResolverManagerService>("lr", 0x10));
|
R_ASSERT(g_lr_server_manager.RegisterServer<lr::LocationResolverManagerService>(LrServiceName, LrMaxSessions));
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
s_server_manager.Process();
|
g_lr_server_manager.LoopProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
/* Initialize content manager implementation. */
|
/* Initialize content manager implementation. */
|
||||||
R_ASSERT(sts::ncm::impl::InitializeContentManager());
|
R_ASSERT(ams::ncm::impl::InitializeContentManager());
|
||||||
|
|
||||||
static HosThread s_content_manager_thread;
|
static os::Thread s_content_manager_thread;
|
||||||
static HosThread s_location_resolver_thread;
|
static os::Thread s_location_resolver_thread;
|
||||||
|
|
||||||
R_ASSERT(s_content_manager_thread.Initialize(&ContentManagerServerMain, nullptr, 0x4000, 0x15));
|
R_ASSERT(s_content_manager_thread.Initialize(&ContentManagerServerMain, nullptr, 0x4000, 0x15));
|
||||||
R_ASSERT(s_content_manager_thread.Start());
|
R_ASSERT(s_content_manager_thread.Start());
|
||||||
@ -161,7 +140,7 @@ int main(int argc, char **argv)
|
|||||||
s_content_manager_thread.Join();
|
s_content_manager_thread.Join();
|
||||||
s_location_resolver_thread.Join();
|
s_location_resolver_thread.Join();
|
||||||
|
|
||||||
sts::ncm::impl::FinalizeContentManager();
|
ams::ncm::impl::FinalizeContentManager();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "ncm_make_path.hpp"
|
#include "ncm_make_path.hpp"
|
||||||
#include "ncm_path_utils.hpp"
|
#include "ncm_path_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
void MakeContentPathFlat(char* out_path, ContentId content_id, const char* root);
|
void MakeContentPathFlat(char* out_path, ContentId content_id, const char* root);
|
||||||
void MakeContentPathHashByteLayered(char* out_path, ContentId content_id, const char* root);
|
void MakeContentPathHashByteLayered(char* out_path, ContentId content_id, const char* root);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include "ncm_path_utils.hpp"
|
#include "ncm_path_utils.hpp"
|
||||||
#include "ncm_utils.hpp"
|
#include "ncm_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
void GetContentMetaPath(char* out, ContentId content_id, MakeContentPathFunc path_func, const char* root_path) {
|
void GetContentMetaPath(char* out, ContentId content_id, MakeContentPathFunc path_func, const char* root_path) {
|
||||||
char tmp_path[FS_MAX_PATH-1] = {0};
|
char tmp_path[FS_MAX_PATH-1] = {0};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
namespace sts::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
inline void GetContentRootPath(char* out_content_root, const char* root_path) {
|
inline void GetContentRootPath(char* out_content_root, const char* root_path) {
|
||||||
/* TODO: Replace with BoundedString? */
|
/* TODO: Replace with BoundedString? */
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "ncm_path_utils.hpp"
|
#include "ncm_path_utils.hpp"
|
||||||
#include "ncm_readonlycontentstorage.hpp"
|
#include "ncm_readonlycontentstorage.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::Initialize(const char* root_path, MakeContentPathFunc content_path_func) {
|
Result ReadOnlyContentStorageInterface::Initialize(const char* root_path, MakeContentPathFunc content_path_func) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
@ -31,38 +31,38 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
||||||
this->make_content_path_func = *content_path_func;
|
this->make_content_path_func = *content_path_func;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GeneratePlaceHolderId(Out<PlaceHolderId> out) {
|
Result ReadOnlyContentStorageInterface::GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
Result ReadOnlyContentStorageInterface::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
Result ReadOnlyContentStorageInterface::DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::HasPlaceHolder(Out<bool> out, PlaceHolderId placeholder_id) {
|
Result ReadOnlyContentStorageInterface::HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, InBuffer<u8> data) {
|
Result ReadOnlyContentStorageInterface::WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, sf::InBuffer data) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
Result ReadOnlyContentStorageInterface::Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::Delete(ContentId content_id) {
|
Result ReadOnlyContentStorageInterface::Delete(ContentId content_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::Has(Out<bool> out, ContentId content_id) {
|
Result ReadOnlyContentStorageInterface::Has(sf::Out<bool> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
@ -77,10 +77,10 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out.SetValue(has);
|
out.SetValue(has);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetPath(OutPointerWithServerSize<lr::Path, 0x1> out, ContentId content_id) {
|
Result ReadOnlyContentStorageInterface::GetPath(sf::Out<lr::Path> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
@ -95,32 +95,32 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, content_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, content_path));
|
||||||
*out.pointer = common_path;
|
out.SetValue(lr::Path::Encode(common_path));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetPlaceHolderPath(OutPointerWithServerSize<lr::Path, 0x1> out, PlaceHolderId placeholder_id) {
|
Result ReadOnlyContentStorageInterface::GetPlaceHolderPath(sf::Out<lr::Path> out, PlaceHolderId placeholder_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::CleanupAllPlaceHolder() {
|
Result ReadOnlyContentStorageInterface::CleanupAllPlaceHolder() {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::ListPlaceHolder(Out<u32> out_count, OutBuffer<PlaceHolderId> out_buf) {
|
Result ReadOnlyContentStorageInterface::ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetContentCount(Out<u32> out_count) {
|
Result ReadOnlyContentStorageInterface::GetContentCount(sf::Out<u32> out_count) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::ListContentId(Out<u32> out_count, OutBuffer<ContentId> out_buf, u32 start_offset) {
|
Result ReadOnlyContentStorageInterface::ListContentId(sf::Out<u32> out_count, const sf::OutArray<ContentId> &out_buf, u32 start_offset) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetSizeFromContentId(Out<u64> out_size, ContentId content_id) {
|
Result ReadOnlyContentStorageInterface::GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
@ -139,26 +139,26 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_size.SetValue(st.st_size);
|
out_size.SetValue(st.st_size);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::DisableForcibly() {
|
Result ReadOnlyContentStorageInterface::DisableForcibly() {
|
||||||
this->disabled = true;
|
this->disabled = true;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
Result ReadOnlyContentStorageInterface::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) {
|
Result ReadOnlyContentStorageInterface::SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::ReadContentIdFile(OutBuffer<u8> buf, ContentId content_id, u64 offset) {
|
Result ReadOnlyContentStorageInterface::ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, u64 offset) {
|
||||||
/* Offset is too large */
|
/* Offset is too large */
|
||||||
if (offset >> 0x3f != 0) {
|
if (offset >> 0x3f != 0) {
|
||||||
return ResultNcmInvalidOffset;
|
return ResultInvalidOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
@ -174,22 +174,22 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FILE* f = nullptr;
|
FILE* f = nullptr;
|
||||||
R_TRY(fs::OpenFile(&f, content_path, FS_OPEN_READ));
|
R_TRY(fs::OpenFile(&f, content_path, FsOpenMode_Read));
|
||||||
|
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
};
|
};
|
||||||
|
|
||||||
R_TRY(fs::ReadFile(f, offset, buf.buffer, buf.num_elements));
|
R_TRY(fs::ReadFile(f, offset, buf.GetPointer(), buf.GetSize()));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetRightsIdFromPlaceHolderId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id) {
|
Result ReadOnlyContentStorageInterface::GetRightsIdFromPlaceHolderId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id) {
|
Result ReadOnlyContentStorageInterface::GetRightsIdFromContentId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
FsRightsId rights_id = {0};
|
FsRightsId rights_id = {0};
|
||||||
@ -212,37 +212,37 @@ namespace sts::ncm {
|
|||||||
out_rights_id.SetValue(rights_id);
|
out_rights_id.SetValue(rights_id);
|
||||||
out_key_generation.SetValue(static_cast<u64>(key_generation));
|
out_key_generation.SetValue(static_cast<u64>(key_generation));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::WriteContentForDebug(ContentId content_id, u64 offset, InBuffer<u8> data) {
|
Result ReadOnlyContentStorageInterface::WriteContentForDebug(ContentId content_id, u64 offset, sf::InBuffer data) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetFreeSpaceSize(Out<u64> out_size) {
|
Result ReadOnlyContentStorageInterface::GetFreeSpaceSize(sf::Out<u64> out_size) {
|
||||||
out_size.SetValue(0);
|
out_size.SetValue(0);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetTotalSpaceSize(Out<u64> out_size) {
|
Result ReadOnlyContentStorageInterface::GetTotalSpaceSize(sf::Out<u64> out_size) {
|
||||||
out_size.SetValue(0);
|
out_size.SetValue(0);
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::FlushPlaceHolder() {
|
Result ReadOnlyContentStorageInterface::FlushPlaceHolder() {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetSizeFromPlaceHolderId(Out<u64> out, PlaceHolderId placeholder_id) {
|
Result ReadOnlyContentStorageInterface::GetSizeFromPlaceHolderId(sf::Out<u64> out, PlaceHolderId placeholder_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::RepairInvalidFileAttribute() {
|
Result ReadOnlyContentStorageInterface::RepairInvalidFileAttribute() {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadOnlyContentStorageInterface::GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
Result ReadOnlyContentStorageInterface::GetRightsIdFromPlaceHolderIdWithCache(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
||||||
return ResultNcmInvalidContentStorageOperation;
|
return ResultInvalidContentStorageOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,72 +20,40 @@
|
|||||||
|
|
||||||
#include "ncm_icontentstorage.hpp"
|
#include "ncm_icontentstorage.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
class ReadOnlyContentStorageInterface : public IContentStorage {
|
class ReadOnlyContentStorageInterface : public IContentStorage {
|
||||||
public:
|
public:
|
||||||
Result Initialize(const char* root_path, MakeContentPathFunc content_path_func);
|
Result Initialize(const char* root_path, MakeContentPathFunc content_path_func);
|
||||||
public:
|
public:
|
||||||
virtual Result GeneratePlaceHolderId(Out<PlaceHolderId> out) override;
|
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) override;
|
||||||
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) override;
|
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) override;
|
||||||
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) override;
|
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id) override;
|
||||||
virtual Result HasPlaceHolder(Out<bool> out, PlaceHolderId placeholder_id) override;
|
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, InBuffer<u8> data) override;
|
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, u64 offset, sf::InBuffer data) override;
|
||||||
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) override;
|
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id) override;
|
||||||
virtual Result Delete(ContentId content_id) override;
|
virtual Result Delete(ContentId content_id) override;
|
||||||
virtual Result Has(Out<bool> out, ContentId content_id) override;
|
virtual Result Has(sf::Out<bool> out, ContentId content_id) override;
|
||||||
virtual Result GetPath(OutPointerWithServerSize<lr::Path, 0x1> out, ContentId content_id) override;
|
virtual Result GetPath(sf::Out<lr::Path> out, ContentId content_id) override;
|
||||||
virtual Result GetPlaceHolderPath(OutPointerWithServerSize<lr::Path, 0x1> out, PlaceHolderId placeholder_id) override;
|
virtual Result GetPlaceHolderPath(sf::Out<lr::Path> out, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result CleanupAllPlaceHolder() override;
|
virtual Result CleanupAllPlaceHolder() override;
|
||||||
virtual Result ListPlaceHolder(Out<u32> out_count, OutBuffer<PlaceHolderId> out_buf) override;
|
virtual Result ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) override;
|
||||||
virtual Result GetContentCount(Out<u32> out_count) override;
|
virtual Result GetContentCount(sf::Out<u32> out_count) override;
|
||||||
virtual Result ListContentId(Out<u32> out_count, OutBuffer<ContentId> out_buf, u32 start_offset) override;
|
virtual Result ListContentId(sf::Out<u32> out_count, const sf::OutArray<ContentId> &out_buf, u32 start_offset) override;
|
||||||
virtual Result GetSizeFromContentId(Out<u64> out_size, ContentId content_id) override;
|
virtual Result GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) override;
|
||||||
virtual Result DisableForcibly() override;
|
virtual Result DisableForcibly() override;
|
||||||
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) override;
|
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) override;
|
||||||
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) override;
|
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, u64 size) override;
|
||||||
virtual Result ReadContentIdFile(OutBuffer<u8> buf, ContentId content_id, u64 offset) override;
|
virtual Result ReadContentIdFile(sf::OutBuffer buf, ContentId content_id, u64 offset) override;
|
||||||
virtual Result GetRightsIdFromPlaceHolderId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id) override;
|
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id) override;
|
virtual Result GetRightsIdFromContentId(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, ContentId content_id) override;
|
||||||
virtual Result WriteContentForDebug(ContentId content_id, u64 offset, InBuffer<u8> data) override;
|
virtual Result WriteContentForDebug(ContentId content_id, u64 offset, sf::InBuffer data) override;
|
||||||
virtual Result GetFreeSpaceSize(Out<u64> out_size) override;
|
virtual Result GetFreeSpaceSize(sf::Out<u64> out_size) override;
|
||||||
virtual Result GetTotalSpaceSize(Out<u64> out_size) override;
|
virtual Result GetTotalSpaceSize(sf::Out<u64> out_size) override;
|
||||||
virtual Result FlushPlaceHolder() override;
|
virtual Result FlushPlaceHolder() override;
|
||||||
virtual Result GetSizeFromPlaceHolderId(Out<u64> out, PlaceHolderId placeholder_id) override;
|
virtual Result GetSizeFromPlaceHolderId(sf::Out<u64> out, PlaceHolderId placeholder_id) override;
|
||||||
virtual Result RepairInvalidFileAttribute() override;
|
virtual Result RepairInvalidFileAttribute() override;
|
||||||
virtual Result GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) override;
|
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<FsRightsId> out_rights_id, sf::Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) override;
|
||||||
public:
|
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GeneratePlaceHolderId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, CreatePlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, DeletePlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, HasPlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, WritePlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, Register),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, Delete),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, Has),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetPath),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetPlaceHolderPath),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, CleanupAllPlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, ListPlaceHolder),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GeneratePlaceHolderId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetContentCount),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, ListContentId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetSizeFromContentId),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, DisableForcibly),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, RevertToPlaceHolder, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, SetPlaceHolderSize, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, ReadContentIdFile, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetRightsIdFromPlaceHolderId, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetRightsIdFromContentId, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, WriteContentForDebug, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetFreeSpaceSize, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetTotalSpaceSize, FirmwareVersion_200),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, FlushPlaceHolder, FirmwareVersion_300),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetSizeFromPlaceHolderId, FirmwareVersion_400),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, RepairInvalidFileAttribute, FirmwareVersion_400),
|
|
||||||
MAKE_SERVICE_COMMAND_META(ReadOnlyContentStorageInterface, GetRightsIdFromPlaceHolderIdWithCache, FirmwareVersion_800),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include "ncm_utils.hpp"
|
#include "ncm_utils.hpp"
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
void GetStringFromContentId(char* out, ContentId content_id) {
|
void GetStringFromContentId(char* out, ContentId content_id) {
|
||||||
for (size_t i = 0; i < sizeof(ContentId); i++) {
|
for (size_t i = 0; i < sizeof(ContentId); i++) {
|
||||||
@ -32,7 +32,7 @@ namespace sts::ncm {
|
|||||||
|
|
||||||
Result GetPlaceHolderIdFromDirEntry(PlaceHolderId* out, struct dirent* dir_entry) {
|
Result GetPlaceHolderIdFromDirEntry(PlaceHolderId* out, struct dirent* dir_entry) {
|
||||||
if (strnlen(dir_entry->d_name, 0x30) != 0x24 || strncmp(dir_entry->d_name + 0x20, ".nca", 4) != 0) {
|
if (strnlen(dir_entry->d_name, 0x30) != 0x24 || strncmp(dir_entry->d_name + 0x20, ".nca", 4) != 0) {
|
||||||
return ResultNcmInvalidPlaceHolderDirectoryEntry;
|
return ResultInvalidPlaceHolderDirectoryEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaceHolderId placeholder_id = {0};
|
PlaceHolderId placeholder_id = {0};
|
||||||
@ -51,7 +51,7 @@ namespace sts::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*out = placeholder_id;
|
*out = placeholder_id;
|
||||||
return ResultSuccess;
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ContentId> GetContentIdFromString(const char* str, size_t len) {
|
std::optional<ContentId> GetContentIdFromString(const char* str, size_t len) {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include <sys/dirent.h>
|
#include <sys/dirent.h>
|
||||||
|
|
||||||
namespace sts::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
void GetStringFromContentId(char* out, ContentId content_id);
|
void GetStringFromContentId(char* out, ContentId content_id);
|
||||||
void GetStringFromPlaceHolderId(char* out, PlaceHolderId placeholder_id);
|
void GetStringFromPlaceHolderId(char* out, PlaceHolderId placeholder_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user