Updated AddOnContentLocationResolver and RegisteredLocationResolver to 9.0.0

This commit is contained in:
Adubbz 2019-10-01 22:02:09 +10:00
parent 514cec4028
commit e2bfbdfb11
7 changed files with 207 additions and 43 deletions

View file

@ -23,16 +23,21 @@ namespace sts::lr::impl {
NON_MOVEABLE(LocationRedirection);
private:
ncm::TitleId title_id;
ncm::TitleId application_id;
Path path;
u32 flags;
public:
LocationRedirection(ncm::TitleId title_id, const Path& path, u32 flags) :
title_id(title_id), path(path), flags(flags) { /* ... */ }
LocationRedirection(ncm::TitleId title_id, ncm::TitleId application_id, const Path& path, u32 flags) :
title_id(title_id), application_id(application_id), path(path), flags(flags) { /* ... */ }
ncm::TitleId GetTitleId() const {
return this->title_id;
}
ncm::TitleId GetApplicationId() const {
return this->application_id;
}
void GetPath(Path *out) const {
*out = this->path;
}
@ -61,8 +66,12 @@ namespace sts::lr::impl {
}
void LocationRedirector::SetRedirection(ncm::TitleId title_id, const Path &path, u32 flags) {
this->SetRedirection(title_id, path, flags);
}
void LocationRedirector::SetRedirection(ncm::TitleId title_id, ncm::TitleId application_id, const Path &path, u32 flags) {
this->EraseRedirection(title_id);
this->redirection_list.push_back(*(new LocationRedirection(title_id, path, flags)));
this->redirection_list.push_back(*(new LocationRedirection(title_id, application_id, path, flags)));
}
void LocationRedirector::SetRedirectionFlags(ncm::TitleId title_id, u32 flags) {
@ -96,4 +105,27 @@ namespace sts::lr::impl {
}
}
void LocationRedirector::ClearRedirections(const ncm::TitleId* excluding_tids, size_t num_tids) {
for (auto it = this->redirection_list.begin(); it != this->redirection_list.end();) {
bool skip = false;
for (size_t i = 0; i < num_tids; i++) {
ncm::TitleId tid = excluding_tids[i];
if (it->GetApplicationId() == tid) {
skip = true;
break;
}
}
if (skip) {
continue;
}
auto old = it;
it = this->redirection_list.erase(it);
delete &(*old);
it++;
}
}
}

View file

@ -37,9 +37,11 @@ namespace sts::lr::impl {
bool FindRedirection(Path *out, ncm::TitleId title_id);
void SetRedirection(ncm::TitleId title_id, const Path &path, u32 flags = RedirectionFlags_None);
void SetRedirection(ncm::TitleId title_id, ncm::TitleId application_id, const Path &path, u32 flags = RedirectionFlags_None);
void SetRedirectionFlags(ncm::TitleId title_id, u32 flags);
void EraseRedirection(ncm::TitleId title_id);
void ClearRedirections(u32 flags = RedirectionFlags_None);
void ClearRedirections(const ncm::TitleId* excluding_tids, size_t num_tids);
};
}

View file

@ -27,19 +27,21 @@ namespace sts::lr::impl {
private:
struct Entry {
Value value;
ncm::TitleId application_id;
Key key;
bool is_valid;
};
private:
Entry entries[NumEntries];
size_t soft_entry_limit;
public:
RegisteredData() {
RegisteredData(size_t soft_entry_limit = NumEntries) : soft_entry_limit(soft_entry_limit) {
this->Clear();
}
bool Register(const Key &key, const Value &value) {
bool Register(const Key &key, const Value &value, const ncm::TitleId application_id) {
/* Try to find an existing value. */
for (size_t i = 0; i < NumEntries; i++) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
Entry& entry = this->entries[i];
if (entry.is_valid && entry.key == key) {
entry.value = value;
@ -47,11 +49,12 @@ namespace sts::lr::impl {
}
}
for (size_t i = 0; i < NumEntries; i++) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
Entry& entry = this->entries[i];
if (!entry.is_valid) {
entry.key = key;
entry.value = value;
entry.application_id = application_id;
entry.is_valid = true;
return true;
}
@ -61,7 +64,7 @@ namespace sts::lr::impl {
}
void Unregister(const Key &key) {
for (size_t i = 0; i < NumEntries; i++) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
Entry& entry = this->entries[i];
if (entry.is_valid && entry.key == key) {
entry.is_valid = false;
@ -69,8 +72,17 @@ namespace sts::lr::impl {
}
}
void UnregisterApplication(ncm::TitleId application_id) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
Entry& entry = this->entries[i];
if (entry.application_id == application_id) {
entry.is_valid = false;
}
}
}
bool Find(Value *out, const Key &key) {
for (size_t i = 0; i < NumEntries; i++) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
Entry& entry = this->entries[i];
if (entry.is_valid && entry.key == key) {
*out = entry.value;
@ -82,10 +94,34 @@ namespace sts::lr::impl {
}
void Clear() {
for (size_t i = 0; i < NumEntries; i++) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
this->entries[i].is_valid = false;
}
}
void ClearExcluding(const ncm::TitleId* tids, size_t num_tids) {
for (size_t i = 0; i < this->GetSoftEntryLimit(); i++) {
Entry& entry = this->entries[i];
bool found = false;
for (size_t j = 0; j < num_tids; j++) {
ncm::TitleId tid = tids[j];
if (entry.application_id == tid) {
found = true;
break;
}
}
if (!found) {
entry.is_valid = false;
}
}
}
size_t GetSoftEntryLimit() const {
return this->soft_entry_limit;
}
};
template<typename Key, size_t NumEntries>

View file

@ -39,8 +39,16 @@ namespace sts::lr {
return ResultSuccess;
}
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::TitleId tid) {
if (!this->registered_storages.Register(tid, storage_id)) {
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::TitleId tid) {
if (!this->registered_storages.Register(tid, storage_id, ncm::TitleId::Invalid)) {
return ResultLrTooManyRegisteredPaths;
}
return ResultSuccess;
}
Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::TitleId tid, ncm::TitleId application_tid) {
if (!this->registered_storages.Register(tid, storage_id, application_tid)) {
return ResultLrTooManyRegisteredPaths;
}
@ -52,4 +60,19 @@ namespace sts::lr {
return ResultSuccess;
}
Result AddOnContentLocationResolverInterface::RefreshApplicationAddOnContent(InBuffer<ncm::TitleId> tids) {
if (tids.num_elements == 0) {
this->registered_storages.Clear();
return ResultSuccess;
}
this->registered_storages.ClearExcluding(tids.buffer, tids.num_elements);
return ResultSuccess;
}
Result AddOnContentLocationResolverInterface::UnregisterApplicationAddOnContent(ncm::TitleId tid) {
this->registered_storages.UnregisterApplication(tid);
return ResultSuccess;
}
}

View file

@ -26,20 +26,31 @@ namespace sts::lr {
protected:
enum class CommandId {
ResolveAddOnContentPath = 0,
RegisterAddOnContentStorageDeprecated = 1,
RegisterAddOnContentStorage = 1,
UnregisterAllAddOnContentPath = 2,
RefreshApplicationAddOnContent = 3,
UnregisterApplicationAddOnContent = 4,
};
private:
impl::RegisteredStorages<ncm::TitleId, 0x800> registered_storages;
public:
AddOnContentLocationResolverInterface() : registered_storages(GetRuntimeFirmwareVersion() < FirmwareVersion_900 ? 0x800 : 0x2) { /* ... */ }
virtual Result ResolveAddOnContentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
virtual Result RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::TitleId tid);
virtual Result RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::TitleId tid);
virtual Result RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::TitleId tid, ncm::TitleId application_tid);
virtual Result UnregisterAllAddOnContentPath();
virtual Result RefreshApplicationAddOnContent(InBuffer<ncm::TitleId> tids);
virtual Result UnregisterApplicationAddOnContent(ncm::TitleId tid);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, ResolveAddOnContentPath),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RegisterAddOnContentStorage),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, UnregisterAllAddOnContentPath),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, ResolveAddOnContentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RegisterAddOnContentStorageDeprecated, FirmwareVersion_200, FirmwareVersion_810),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RegisterAddOnContentStorage, FirmwareVersion_900),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, UnregisterAllAddOnContentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, RefreshApplicationAddOnContent, FirmwareVersion_900),
MAKE_SERVICE_COMMAND_META(AddOnContentLocationResolverInterface, UnregisterApplicationAddOnContent, FirmwareVersion_900),
};
};

View file

@ -28,14 +28,14 @@ namespace sts::lr {
this->program_redirector.ClearRedirections();
}
void RegisteredLocationResolverInterface::RegisterPath(const Path& path, impl::RegisteredLocations<ncm::TitleId, 16>* locations, ncm::TitleId tid) {
if (!locations->Register(tid, path)) {
void RegisteredLocationResolverInterface::RegisterPath(const Path& path, impl::RegisteredLocations<ncm::TitleId, RegisteredLocationResolverInterface::MaxRegisteredLocations>* locations, ncm::TitleId tid, ncm::TitleId application_id) {
if (!locations->Register(tid, path, application_id)) {
locations->Clear();
locations->Register(tid, path);
locations->Register(tid, path, application_id);
}
}
bool RegisteredLocationResolverInterface::ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::TitleId, 16>* locations, ncm::TitleId tid) {
bool RegisteredLocationResolverInterface::ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::TitleId, RegisteredLocationResolverInterface::MaxRegisteredLocations>* locations, ncm::TitleId tid) {
if (!redirector->FindRedirection(out, tid)) {
if (!locations->Find(out, tid)) {
return false;
@ -44,6 +44,24 @@ namespace sts::lr {
return true;
}
Result RegisteredLocationResolverInterface::RefreshImpl(const ncm::TitleId* excluding_tids, size_t num_tids) {
if (GetRuntimeFirmwareVersion() < FirmwareVersion_900) {
this->ClearRedirections();
return ResultSuccess;
}
if (num_tids == 0) {
this->ClearRedirections();
} else {
this->registered_program_locations.ClearExcluding(excluding_tids, num_tids);
this->registered_html_docs_locations.ClearExcluding(excluding_tids, num_tids);
}
this->program_redirector.ClearRedirections(excluding_tids, num_tids);
this->html_docs_redirector.ClearRedirections(excluding_tids, num_tids);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
if (!this->ResolvePath(out.pointer, &this->program_redirector, &this->registered_program_locations, tid)) {
return ResultLrProgramNotFound;
@ -52,8 +70,13 @@ namespace sts::lr {
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RegisterProgramPath(InPointer<const Path> path, ncm::TitleId tid) {
this->RegisterPath(*path.pointer, &this->registered_program_locations, tid);
Result RegisteredLocationResolverInterface::RegisterProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
this->RegisterPath(*path.pointer, &this->registered_program_locations, tid, ncm::TitleId::Invalid);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RegisterProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id) {
this->RegisterPath(*path.pointer, &this->registered_program_locations, tid, application_id);
return ResultSuccess;
}
@ -62,11 +85,16 @@ namespace sts::lr {
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid) {
Result RegisteredLocationResolverInterface::RedirectProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
this->program_redirector.SetRedirection(tid, *path.pointer);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id) {
this->program_redirector.SetRedirection(tid, application_id, *path.pointer);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::ResolveHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid) {
if (!this->ResolvePath(out.pointer, &this->html_docs_redirector, &this->registered_html_docs_locations, tid)) {
return ResultLrHtmlDocumentNotFound;
@ -75,8 +103,13 @@ namespace sts::lr {
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid) {
this->RegisterPath(*path.pointer, &this->registered_html_docs_locations, tid);
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
this->RegisterPath(*path.pointer, &this->registered_html_docs_locations, tid, ncm::TitleId::Invalid);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RegisterHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id) {
this->RegisterPath(*path.pointer, &this->registered_html_docs_locations, tid, application_id);
return ResultSuccess;
}
@ -85,14 +118,22 @@ namespace sts::lr {
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid) {
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid) {
this->html_docs_redirector.SetRedirection(tid, *path.pointer);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::Refresh() {
this->ClearRedirections();
Result RegisteredLocationResolverInterface::RedirectHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id) {
this->html_docs_redirector.SetRedirection(tid, application_id, *path.pointer);
return ResultSuccess;
}
Result RegisteredLocationResolverInterface::Refresh() {
return this->RefreshImpl(nullptr, 0);
}
Result RegisteredLocationResolverInterface::RefreshExcluding(InBuffer<ncm::TitleId> tids) {
return this->RefreshImpl(tids.buffer, tids.num_elements);
}
}

View file

@ -24,50 +24,69 @@
namespace sts::lr {
class RegisteredLocationResolverInterface final : public IServiceObject {
private:
static constexpr size_t MaxRegisteredLocations = 0x20;
protected:
enum class CommandId {
ResolveProgramPath = 0,
RegisterProgramPathDeprecated = 1,
RegisterProgramPath = 1,
UnregisterProgramPath = 2,
RedirectProgramPathDeprecated = 3,
RedirectProgramPath = 3,
ResolveHtmlDocumentPath = 4,
RegisterHtmlDocumentPathDeprecated = 5,
RegisterHtmlDocumentPath = 5,
UnregisterHtmlDocumentPath = 6,
RedirectHtmlDocumentPathDeprecated = 7,
RedirectHtmlDocumentPath = 7,
Refresh = 8,
RefreshExcluding = 9,
};
private:
impl::LocationRedirector program_redirector;
impl::RegisteredLocations<ncm::TitleId, 16> registered_program_locations;
impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations> registered_program_locations;
impl::LocationRedirector html_docs_redirector;
impl::RegisteredLocations<ncm::TitleId, 16> registered_html_docs_locations;
impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations> registered_html_docs_locations;
private:
void ClearRedirections(u32 flags = impl::RedirectionFlags_None);
void RegisterPath(const Path& path, impl::RegisteredLocations<ncm::TitleId, 16>* locations, ncm::TitleId tid);
bool ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::TitleId, 16>* locations, ncm::TitleId tid);
void RegisterPath(const Path& path, impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations>* locations, ncm::TitleId tid, ncm::TitleId application_id);
bool ResolvePath(Path* out, impl::LocationRedirector* redirector, impl::RegisteredLocations<ncm::TitleId, MaxRegisteredLocations>* locations, ncm::TitleId tid);
Result RefreshImpl(const ncm::TitleId* excluding_tids, size_t num_tids);
public:
RegisteredLocationResolverInterface() : registered_program_locations(GetRuntimeFirmwareVersion() < FirmwareVersion_900 ? 0x10 : MaxRegisteredLocations), registered_html_docs_locations(GetRuntimeFirmwareVersion() < FirmwareVersion_900 ? 0x10 : MaxRegisteredLocations) { /* ... */ }
~RegisteredLocationResolverInterface();
Result ResolveProgramPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
Result RegisterProgramPath(InPointer<const Path> path, ncm::TitleId tid);
Result RegisterProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
Result RegisterProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id);
Result UnregisterProgramPath(ncm::TitleId tid);
Result RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid);
Result RedirectProgramPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
Result RedirectProgramPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id);
Result ResolveHtmlDocumentPath(OutPointerWithServerSize<Path, 0x1> out, ncm::TitleId tid);
Result RegisterHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid);
Result RegisterHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
Result RegisterHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id);
Result UnregisterHtmlDocumentPath(ncm::TitleId tid);
Result RedirectHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid);
Result RedirectHtmlDocumentPathDeprecated(InPointer<const Path> path, ncm::TitleId tid);
Result RedirectHtmlDocumentPath(InPointer<const Path> path, ncm::TitleId tid, ncm::TitleId application_id);
Result Refresh();
Result RefreshExcluding(InBuffer<ncm::TitleId> tids);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, ResolveProgramPath),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterProgramPath),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterProgramPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterProgramPath, FirmwareVersion_900),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, UnregisterProgramPath),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectProgramPath),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, ResolveHtmlDocumentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterHtmlDocumentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, UnregisterHtmlDocumentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectHtmlDocumentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, Refresh, FirmwareVersion_700),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectProgramPathDeprecated, FirmwareVersion_100, FirmwareVersion_810),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectProgramPath, FirmwareVersion_900),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, ResolveHtmlDocumentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterHtmlDocumentPathDeprecated, FirmwareVersion_200, FirmwareVersion_810),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RegisterHtmlDocumentPath, FirmwareVersion_900),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, UnregisterHtmlDocumentPath, FirmwareVersion_200),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectHtmlDocumentPathDeprecated, FirmwareVersion_200, FirmwareVersion_810),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RedirectHtmlDocumentPathDeprecated, FirmwareVersion_900),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, Refresh, FirmwareVersion_700),
MAKE_SERVICE_COMMAND_META(RegisteredLocationResolverInterface, RefreshExcluding, FirmwareVersion_900),
};
};