mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-23 03:06:52 -04:00
strat: TitleId -> ProgramId, titles->contents
This commit is contained in:
parent
1636668762
commit
ea3ebbaa7d
86 changed files with 1138 additions and 1140 deletions
|
@ -20,16 +20,15 @@ namespace ams::ldr::args {
|
|||
namespace {
|
||||
|
||||
/* Convenience definitions. */
|
||||
constexpr ncm::TitleId FreeTitleId = {};
|
||||
constexpr size_t MaxArgumentInfos = 10;
|
||||
|
||||
/* Global storage. */
|
||||
ArgumentInfo g_argument_infos[MaxArgumentInfos];
|
||||
|
||||
/* Helpers. */
|
||||
ArgumentInfo *FindArgumentInfo(ncm::TitleId title_id) {
|
||||
ArgumentInfo *FindArgumentInfo(ncm::ProgramId program_id) {
|
||||
for (size_t i = 0; i < MaxArgumentInfos; i++) {
|
||||
if (g_argument_infos[i].title_id == title_id) {
|
||||
if (g_argument_infos[i].program_id == program_id) {
|
||||
return &g_argument_infos[i];
|
||||
}
|
||||
}
|
||||
|
@ -37,34 +36,34 @@ namespace ams::ldr::args {
|
|||
}
|
||||
|
||||
ArgumentInfo *FindFreeArgumentInfo() {
|
||||
return FindArgumentInfo(FreeTitleId);
|
||||
return FindArgumentInfo(ncm::InvalidProgramId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* API. */
|
||||
const ArgumentInfo *Get(ncm::TitleId title_id) {
|
||||
return FindArgumentInfo(title_id);
|
||||
const ArgumentInfo *Get(ncm::ProgramId program_id) {
|
||||
return FindArgumentInfo(program_id);
|
||||
}
|
||||
|
||||
Result Set(ncm::TitleId title_id, const void *args, size_t args_size) {
|
||||
Result Set(ncm::ProgramId program_id, const void *args, size_t args_size) {
|
||||
R_UNLESS(args_size < ArgumentSizeMax, ldr::ResultTooLongArgument());
|
||||
|
||||
ArgumentInfo *arg_info = FindArgumentInfo(title_id);
|
||||
ArgumentInfo *arg_info = FindArgumentInfo(program_id);
|
||||
if (arg_info == nullptr) {
|
||||
arg_info = FindFreeArgumentInfo();
|
||||
}
|
||||
R_UNLESS(arg_info != nullptr, ldr::ResultTooManyArguments());
|
||||
|
||||
arg_info->title_id = title_id;
|
||||
arg_info->program_id = program_id;
|
||||
arg_info->args_size = args_size;
|
||||
std::memcpy(arg_info->args, args, args_size);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Clear() {
|
||||
Result Flush() {
|
||||
for (size_t i = 0; i < MaxArgumentInfos; i++) {
|
||||
g_argument_infos[i].title_id = FreeTitleId;
|
||||
g_argument_infos[i].program_id = ncm::InvalidProgramId;
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -21,14 +21,14 @@ namespace ams::ldr::args {
|
|||
constexpr size_t ArgumentSizeMax = 0x8000;
|
||||
|
||||
struct ArgumentInfo {
|
||||
ncm::TitleId title_id;
|
||||
ncm::ProgramId program_id;
|
||||
size_t args_size;
|
||||
u8 args[ArgumentSizeMax];
|
||||
};
|
||||
|
||||
/* API. */
|
||||
const ArgumentInfo *Get(ncm::TitleId title_id);
|
||||
Result Set(ncm::TitleId title_id, const void *args, size_t args_size);
|
||||
Result Clear();
|
||||
const ArgumentInfo *Get(ncm::ProgramId program_id);
|
||||
Result Set(ncm::ProgramId program_id, const void *args, size_t args_size);
|
||||
Result Flush();
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace ams::ldr {
|
|||
/* Globals. */
|
||||
bool g_has_mounted_sd_card = false;
|
||||
|
||||
ncm::TitleId g_should_override_title_id;
|
||||
ncm::ProgramId g_should_override_program_id;
|
||||
bool g_should_override_hbl = false;
|
||||
bool g_should_override_sd = false;
|
||||
|
||||
|
@ -53,24 +53,24 @@ namespace ams::ldr {
|
|||
return relative_path;
|
||||
}
|
||||
|
||||
void UpdateShouldOverrideCache(ncm::TitleId title_id) {
|
||||
if (g_should_override_title_id != title_id) {
|
||||
cfg::GetOverrideKeyHeldStatus(&g_should_override_hbl, &g_should_override_sd, title_id);
|
||||
void UpdateShouldOverrideCache(ncm::ProgramId program_id) {
|
||||
if (g_should_override_program_id != program_id) {
|
||||
cfg::GetOverrideKeyHeldStatus(&g_should_override_hbl, &g_should_override_sd, program_id);
|
||||
}
|
||||
g_should_override_title_id = title_id;
|
||||
g_should_override_program_id = program_id;
|
||||
}
|
||||
|
||||
void InvalidateShouldOverrideCache() {
|
||||
g_should_override_title_id = {};
|
||||
g_should_override_program_id = {};
|
||||
}
|
||||
|
||||
bool ShouldOverrideWithHbl(ncm::TitleId title_id) {
|
||||
UpdateShouldOverrideCache(title_id);
|
||||
bool ShouldOverrideWithHbl(ncm::ProgramId program_id) {
|
||||
UpdateShouldOverrideCache(program_id);
|
||||
return g_should_override_hbl;
|
||||
}
|
||||
|
||||
bool ShouldOverrideWithSd(ncm::TitleId title_id) {
|
||||
UpdateShouldOverrideCache(title_id);
|
||||
bool ShouldOverrideWithSd(ncm::ProgramId program_id) {
|
||||
UpdateShouldOverrideCache(program_id);
|
||||
return g_should_override_sd;
|
||||
}
|
||||
|
||||
|
@ -97,31 +97,31 @@ namespace ams::ldr {
|
|||
return fopen(path, "rb");
|
||||
}
|
||||
|
||||
FILE *OpenLooseSdFile(ncm::TitleId title_id, const char *relative_path) {
|
||||
FILE *OpenLooseSdFile(ncm::ProgramId program_id, const char *relative_path) {
|
||||
/* Allow nullptr relative path -- those are simply not openable. */
|
||||
if (relative_path == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char path[FS_MAX_PATH];
|
||||
std::snprintf(path, FS_MAX_PATH, "/atmosphere/titles/%016lx/exefs/%s", static_cast<u64>(title_id), GetRelativePathStart(relative_path));
|
||||
std::snprintf(path, FS_MAX_PATH, "/atmosphere/contents/%016lx/exefs/%s", static_cast<u64>(program_id), GetRelativePathStart(relative_path));
|
||||
FixFileSystemPath(path);
|
||||
return OpenFile(SdCardFileSystemDeviceName, path);
|
||||
}
|
||||
|
||||
bool IsFileStubbed(ncm::TitleId title_id, const char *relative_path) {
|
||||
bool IsFileStubbed(ncm::ProgramId program_id, const char *relative_path) {
|
||||
/* Allow nullptr relative path -- those are simply not openable. */
|
||||
if (relative_path == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Only allow stubbing in the case where we're considering SD card content. */
|
||||
if (!ShouldOverrideWithSd(title_id)) {
|
||||
if (!ShouldOverrideWithSd(program_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char path[FS_MAX_PATH];
|
||||
std::snprintf(path, FS_MAX_PATH, "/atmosphere/titles/%016lx/exefs/%s.stub", static_cast<u64>(title_id), GetRelativePathStart(relative_path));
|
||||
std::snprintf(path, FS_MAX_PATH, "/atmosphere/contents/%016lx/exefs/%s.stub", static_cast<u64>(program_id), GetRelativePathStart(relative_path));
|
||||
FixFileSystemPath(path);
|
||||
FILE *f = OpenFile(SdCardFileSystemDeviceName, path);
|
||||
if (f == nullptr) {
|
||||
|
@ -131,14 +131,14 @@ namespace ams::ldr {
|
|||
return true;
|
||||
}
|
||||
|
||||
FILE *OpenBaseExefsFile(ncm::TitleId title_id, const char *relative_path) {
|
||||
FILE *OpenBaseExefsFile(ncm::ProgramId program_id, const char *relative_path) {
|
||||
/* Allow nullptr relative path -- those are simply not openable. */
|
||||
if (relative_path == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Check if stubbed. */
|
||||
if (IsFileStubbed(title_id, relative_path)) {
|
||||
if (IsFileStubbed(program_id, relative_path)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* ScopedCodeMount functionality. */
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::TitleLocation &loc) : is_code_mounted(false), is_hbl_mounted(false) {
|
||||
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc) : is_code_mounted(false), is_hbl_mounted(false) {
|
||||
this->result = this->Initialize(loc);
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ namespace ams::ldr {
|
|||
InvalidateShouldOverrideCache();
|
||||
}
|
||||
|
||||
Result ScopedCodeMount::MountCodeFileSystem(const ncm::TitleLocation &loc) {
|
||||
Result ScopedCodeMount::MountCodeFileSystem(const ncm::ProgramLocation &loc) {
|
||||
char path[FS_MAX_PATH];
|
||||
|
||||
/* Try to get the content path. */
|
||||
|
@ -173,7 +173,7 @@ namespace ams::ldr {
|
|||
|
||||
/* Try to mount the content path. */
|
||||
FsFileSystem fs;
|
||||
R_TRY(fsldrOpenCodeFileSystem(static_cast<u64>(loc.title_id), path, &fs));
|
||||
R_TRY(fsldrOpenCodeFileSystem(static_cast<u64>(loc.program_id), path, &fs));
|
||||
AMS_ASSERT(fsdevMountDevice(CodeFileSystemDeviceName, fs) != -1);
|
||||
|
||||
/* Note that we mounted code. */
|
||||
|
@ -181,11 +181,11 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ScopedCodeMount::MountSdCardCodeFileSystem(const ncm::TitleLocation &loc) {
|
||||
Result ScopedCodeMount::MountSdCardCodeFileSystem(const ncm::ProgramLocation &loc) {
|
||||
char path[FS_MAX_PATH];
|
||||
|
||||
/* Print and fix path. */
|
||||
std::snprintf(path, FS_MAX_PATH, "%s:/atmosphere/titles/%016lx/exefs.nsp", SdCardStorageMountPoint, static_cast<u64>(loc.title_id));
|
||||
std::snprintf(path, FS_MAX_PATH, "%s:/atmosphere/contents/%016lx/exefs.nsp", SdCardStorageMountPoint, static_cast<u64>(loc.program_id));
|
||||
FixFileSystemPath(path);
|
||||
R_TRY(MountNspFileSystem(CodeFileSystemDeviceName, path));
|
||||
|
||||
|
@ -208,7 +208,7 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
|
||||
Result ScopedCodeMount::Initialize(const ncm::TitleLocation &loc) {
|
||||
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc) {
|
||||
bool is_sd_initialized = cfg::IsSdCardInitialized();
|
||||
|
||||
/* Check if we're ready to mount the SD card. */
|
||||
|
@ -220,11 +220,11 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* Check if we should override contents. */
|
||||
if (ShouldOverrideWithHbl(loc.title_id)) {
|
||||
if (ShouldOverrideWithHbl(loc.program_id)) {
|
||||
/* Try to mount HBL. */
|
||||
this->MountHblFileSystem();
|
||||
}
|
||||
if (ShouldOverrideWithSd(loc.title_id)) {
|
||||
if (ShouldOverrideWithSd(loc.program_id)) {
|
||||
/* Try to mount Code NSP on SD. */
|
||||
this->MountSdCardCodeFileSystem(loc);
|
||||
}
|
||||
|
@ -237,25 +237,25 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenCodeFile(FILE *&out, ncm::TitleId title_id, const char *relative_path) {
|
||||
Result OpenCodeFile(FILE *&out, ncm::ProgramId program_id, const char *relative_path) {
|
||||
FILE *f = nullptr;
|
||||
const char *ecs_device_name = ecs::Get(title_id);
|
||||
const char *ecs_device_name = ecs::Get(program_id);
|
||||
|
||||
if (ecs_device_name != nullptr) {
|
||||
/* First priority: Open from external content. */
|
||||
f = OpenFile(ecs_device_name, relative_path);
|
||||
} else if (ShouldOverrideWithHbl(title_id)) {
|
||||
} else if (ShouldOverrideWithHbl(program_id)) {
|
||||
/* Next, try to open from HBL. */
|
||||
f = OpenFile(HblFileSystemDeviceName, relative_path);
|
||||
} else {
|
||||
/* If not ECS or HBL, try a loose file on the SD. */
|
||||
if (ShouldOverrideWithSd(title_id)) {
|
||||
f = OpenLooseSdFile(title_id, relative_path);
|
||||
if (ShouldOverrideWithSd(program_id)) {
|
||||
f = OpenLooseSdFile(program_id, relative_path);
|
||||
}
|
||||
|
||||
/* If we fail, try the original exefs. */
|
||||
if (f == nullptr) {
|
||||
f = OpenBaseExefsFile(title_id, relative_path);
|
||||
f = OpenBaseExefsFile(program_id, relative_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,9 +266,9 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenCodeFileFromBaseExefs(FILE *&out, ncm::TitleId title_id, const char *relative_path) {
|
||||
Result OpenCodeFileFromBaseExefs(FILE *&out, ncm::ProgramId program_id, const char *relative_path) {
|
||||
/* Open the file. */
|
||||
FILE *f = OpenBaseExefsFile(title_id, relative_path);
|
||||
FILE *f = OpenBaseExefsFile(program_id, relative_path);
|
||||
R_UNLESS(f != nullptr, fs::ResultPathNotFound());
|
||||
|
||||
out = f;
|
||||
|
@ -276,7 +276,7 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* Redirection API. */
|
||||
Result ResolveContentPath(char *out_path, const ncm::TitleLocation &loc) {
|
||||
Result ResolveContentPath(char *out_path, const ncm::ProgramLocation &loc) {
|
||||
char path[FS_MAX_PATH];
|
||||
|
||||
/* Try to get the path from the registered resolver. */
|
||||
|
@ -284,14 +284,14 @@ namespace ams::ldr {
|
|||
R_TRY(lrOpenRegisteredLocationResolver(®));
|
||||
ON_SCOPE_EXIT { serviceClose(®.s); };
|
||||
|
||||
R_TRY_CATCH(lrRegLrResolveProgramPath(®, static_cast<u64>(loc.title_id), path)) {
|
||||
R_TRY_CATCH(lrRegLrResolveProgramPath(®, static_cast<u64>(loc.program_id), path)) {
|
||||
R_CATCH(lr::ResultProgramNotFound) {
|
||||
/* Program wasn't found via registered resolver, fall back to the normal resolver. */
|
||||
LrLocationResolver lr;
|
||||
R_TRY(lrOpenLocationResolver(static_cast<FsStorageId>(loc.storage_id), &lr));
|
||||
ON_SCOPE_EXIT { serviceClose(&lr.s); };
|
||||
|
||||
R_TRY(lrLrResolveProgramPath(&lr, static_cast<u64>(loc.title_id), path));
|
||||
R_TRY(lrLrResolveProgramPath(&lr, static_cast<u64>(loc.program_id), path));
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
|
@ -301,15 +301,15 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result RedirectContentPath(const char *path, const ncm::TitleLocation &loc) {
|
||||
Result RedirectContentPath(const char *path, const ncm::ProgramLocation &loc) {
|
||||
LrLocationResolver lr;
|
||||
R_TRY(lrOpenLocationResolver(static_cast<FsStorageId>(loc.storage_id), &lr));
|
||||
ON_SCOPE_EXIT { serviceClose(&lr.s); };
|
||||
|
||||
return lrLrRedirectProgramPath(&lr, static_cast<u64>(loc.title_id), path);
|
||||
return lrLrRedirectProgramPath(&lr, static_cast<u64>(loc.program_id), path);
|
||||
}
|
||||
|
||||
Result RedirectHtmlDocumentPathForHbl(const ncm::TitleLocation &loc) {
|
||||
Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc) {
|
||||
char path[FS_MAX_PATH];
|
||||
|
||||
/* Open a location resolver. */
|
||||
|
@ -318,11 +318,11 @@ namespace ams::ldr {
|
|||
ON_SCOPE_EXIT { serviceClose(&lr.s); };
|
||||
|
||||
/* If there's already a Html Document path, we don't need to set one. */
|
||||
R_UNLESS(R_FAILED(lrLrResolveApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.title_id), path)), ResultSuccess());
|
||||
R_UNLESS(R_FAILED(lrLrResolveApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.program_id), path)), ResultSuccess());
|
||||
|
||||
/* We just need to set this to any valid NCA path. Let's use the executable path. */
|
||||
R_TRY(lrLrResolveProgramPath(&lr, static_cast<u64>(loc.title_id), path));
|
||||
R_TRY(lrLrRedirectApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.title_id), static_cast<u64>(loc.title_id), path));
|
||||
R_TRY(lrLrResolveProgramPath(&lr, static_cast<u64>(loc.program_id), path));
|
||||
R_TRY(lrLrRedirectApplicationHtmlDocumentPath(&lr, static_cast<u64>(loc.program_id), static_cast<u64>(loc.program_id), path));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::ldr {
|
|||
bool is_code_mounted;
|
||||
bool is_hbl_mounted;
|
||||
public:
|
||||
ScopedCodeMount(const ncm::TitleLocation &loc);
|
||||
ScopedCodeMount(const ncm::ProgramLocation &loc);
|
||||
~ScopedCodeMount();
|
||||
|
||||
Result GetResult() const {
|
||||
|
@ -42,20 +42,20 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
private:
|
||||
Result Initialize(const ncm::TitleLocation &loc);
|
||||
Result Initialize(const ncm::ProgramLocation &loc);
|
||||
|
||||
Result MountCodeFileSystem(const ncm::TitleLocation &loc);
|
||||
Result MountSdCardCodeFileSystem(const ncm::TitleLocation &loc);
|
||||
Result MountCodeFileSystem(const ncm::ProgramLocation &loc);
|
||||
Result MountSdCardCodeFileSystem(const ncm::ProgramLocation &loc);
|
||||
Result MountHblFileSystem();
|
||||
};
|
||||
|
||||
/* Content Management API. */
|
||||
Result OpenCodeFile(FILE *&out, ncm::TitleId title_id, const char *relative_path);
|
||||
Result OpenCodeFileFromBaseExefs(FILE *&out, ncm::TitleId title_id, const char *relative_path);
|
||||
Result OpenCodeFile(FILE *&out, ncm::ProgramId program_id, const char *relative_path);
|
||||
Result OpenCodeFileFromBaseExefs(FILE *&out, ncm::ProgramId program_id, const char *relative_path);
|
||||
|
||||
/* Redirection API. */
|
||||
Result ResolveContentPath(char *out_path, const ncm::TitleLocation &loc);
|
||||
Result RedirectContentPath(const char *path, const ncm::TitleLocation &loc);
|
||||
Result RedirectHtmlDocumentPathForHbl(const ncm::TitleLocation &loc);
|
||||
Result ResolveContentPath(char *out_path, const ncm::ProgramLocation &loc);
|
||||
Result RedirectContentPath(const char *path, const ncm::ProgramLocation &loc);
|
||||
Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc);
|
||||
|
||||
}
|
||||
|
|
|
@ -49,24 +49,24 @@ namespace ams::ldr::ecs {
|
|||
}
|
||||
|
||||
/* API. */
|
||||
const char *Get(ncm::TitleId title_id) {
|
||||
auto it = g_map.find(static_cast<u64>(title_id));
|
||||
const char *Get(ncm::ProgramId program_id) {
|
||||
auto it = g_map.find(static_cast<u64>(program_id));
|
||||
if (it == g_map.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second.GetDeviceName();
|
||||
}
|
||||
|
||||
Result Set(Handle *out, ncm::TitleId title_id) {
|
||||
Result Set(Handle *out, ncm::ProgramId program_id) {
|
||||
/* TODO: Is this an appropriate error? */
|
||||
R_UNLESS(g_map.size() < MaxExternalContentSourceCount, ldr::ResultTooManyArguments());
|
||||
|
||||
/* Clear any sources. */
|
||||
R_ASSERT(Clear(title_id));
|
||||
R_ASSERT(Clear(program_id));
|
||||
|
||||
/* Generate mountpoint. */
|
||||
char device_name[DeviceNameSizeMax];
|
||||
std::snprintf(device_name, DeviceNameSizeMax, "ecs-%016lx", static_cast<u64>(title_id));
|
||||
std::snprintf(device_name, DeviceNameSizeMax, "ecs-%016lx", static_cast<u64>(program_id));
|
||||
|
||||
/* Create session. */
|
||||
os::ManagedHandle server, client;
|
||||
|
@ -83,14 +83,14 @@ namespace ams::ldr::ecs {
|
|||
fs_guard.Cancel();
|
||||
|
||||
/* Add to map. */
|
||||
g_map.emplace(static_cast<u64>(title_id), device_name);
|
||||
g_map.emplace(static_cast<u64>(program_id), device_name);
|
||||
*out = server.Move();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Clear(ncm::TitleId title_id) {
|
||||
Result Clear(ncm::ProgramId program_id) {
|
||||
/* Delete if present. */
|
||||
g_map.erase(static_cast<u64>(title_id));
|
||||
g_map.erase(static_cast<u64>(program_id));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
namespace ams::ldr::ecs {
|
||||
|
||||
/* External Content Source API. */
|
||||
const char *Get(ncm::TitleId title_id);
|
||||
Result Set(Handle *out, ncm::TitleId title_id);
|
||||
Result Clear(ncm::TitleId title_id);
|
||||
const char *Get(ncm::ProgramId program_id);
|
||||
Result Set(Handle *out, ncm::ProgramId program_id);
|
||||
Result Clear(ncm::ProgramId program_id);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,17 +20,17 @@ namespace ams::ldr {
|
|||
namespace {
|
||||
|
||||
/* Global cache. */
|
||||
std::set<u64> g_launched_titles;
|
||||
std::set<u64> g_launched_programs;
|
||||
|
||||
}
|
||||
|
||||
/* Launch Record API. */
|
||||
bool HasLaunchedTitle(ncm::TitleId title_id) {
|
||||
return g_launched_titles.find(static_cast<u64>(title_id)) != g_launched_titles.end();
|
||||
bool HasLaunchedProgram(ncm::ProgramId program_id) {
|
||||
return g_launched_programs.find(static_cast<u64>(program_id)) != g_launched_programs.end();
|
||||
}
|
||||
|
||||
void SetLaunchedTitle(ncm::TitleId title_id) {
|
||||
g_launched_titles.insert(static_cast<u64>(title_id));
|
||||
void SetLaunchedProgram(ncm::ProgramId program_id) {
|
||||
g_launched_programs.insert(static_cast<u64>(program_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ namespace ams::ldr {
|
|||
/* This is necessary to prevent circular dependencies. */
|
||||
namespace ams::pm::info {
|
||||
|
||||
Result HasLaunchedTitle(bool *out, ncm::TitleId title_id) {
|
||||
*out = ldr::HasLaunchedTitle(title_id);
|
||||
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) {
|
||||
*out = ldr::HasLaunchedProgram(program_id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
namespace ams::ldr {
|
||||
|
||||
/* Launch Record API. */
|
||||
bool HasLaunchedTitle(ncm::TitleId title_id);
|
||||
void SetLaunchedTitle(ncm::TitleId title_id);
|
||||
bool HasLaunchedProgram(ncm::ProgramId program_id);
|
||||
void SetLaunchedProgram(ncm::ProgramId program_id);
|
||||
|
||||
}
|
|
@ -26,11 +26,11 @@ namespace ams::ldr {
|
|||
/* Official commands. */
|
||||
Result LoaderService::CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h) {
|
||||
os::ManagedHandle reslimit_holder(reslimit_h.GetValue());
|
||||
ncm::TitleLocation loc;
|
||||
ncm::ProgramLocation loc;
|
||||
char path[FS_MAX_PATH];
|
||||
|
||||
/* Get location. */
|
||||
R_TRY(ldr::ro::GetTitleLocation(&loc, id));
|
||||
R_TRY(ldr::ro::GetProgramLocation(&loc, id));
|
||||
|
||||
if (loc.storage_id != static_cast<u8>(ncm::StorageId::None)) {
|
||||
R_TRY(ResolveContentPath(path, loc));
|
||||
|
@ -39,42 +39,42 @@ namespace ams::ldr {
|
|||
return ldr::CreateProcess(proc_h.GetHandlePointer(), id, loc, path, flags, reslimit_holder.Get());
|
||||
}
|
||||
|
||||
Result LoaderService::GetProgramInfo(sf::Out<ProgramInfo> out, const ncm::TitleLocation &loc) {
|
||||
Result LoaderService::GetProgramInfo(sf::Out<ProgramInfo> out, const ncm::ProgramLocation &loc) {
|
||||
/* Zero output. */
|
||||
std::memset(out.GetPointer(), 0, sizeof(*out.GetPointer()));
|
||||
|
||||
R_TRY(ldr::GetProgramInfo(out.GetPointer(), loc));
|
||||
|
||||
if (loc.storage_id != static_cast<u8>(ncm::StorageId::None) && loc.title_id != out->title_id) {
|
||||
if (loc.storage_id != static_cast<u8>(ncm::StorageId::None) && loc.program_id != out->program_id) {
|
||||
char path[FS_MAX_PATH];
|
||||
const ncm::TitleLocation new_loc = ncm::TitleLocation::Make(out->title_id, static_cast<ncm::StorageId>(loc.storage_id));
|
||||
const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast<ncm::StorageId>(loc.storage_id));
|
||||
|
||||
R_TRY(ResolveContentPath(path, loc));
|
||||
R_TRY(RedirectContentPath(path, new_loc));
|
||||
|
||||
const auto arg_info = args::Get(loc.title_id);
|
||||
const auto arg_info = args::Get(loc.program_id);
|
||||
if (arg_info != nullptr) {
|
||||
R_TRY(args::Set(new_loc.title_id, arg_info->args, arg_info->args_size));
|
||||
R_TRY(args::Set(new_loc.program_id, arg_info->args, arg_info->args_size));
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LoaderService::PinTitle(sf::Out<PinId> out_id, const ncm::TitleLocation &loc) {
|
||||
return ldr::ro::PinTitle(out_id.GetPointer(), loc);
|
||||
Result LoaderService::PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc) {
|
||||
return ldr::ro::PinProgram(out_id.GetPointer(), loc);
|
||||
}
|
||||
|
||||
Result LoaderService::UnpinTitle(PinId id) {
|
||||
return ldr::ro::UnpinTitle(id);
|
||||
Result LoaderService::UnpinProgram(PinId id) {
|
||||
return ldr::ro::UnpinProgram(id);
|
||||
}
|
||||
|
||||
Result LoaderService::SetTitleArguments(ncm::TitleId title_id, const sf::InPointerBuffer &args, u32 args_size) {
|
||||
return args::Set(title_id, args.GetPointer(), std::min(args.GetSize(), size_t(args_size)));
|
||||
Result LoaderService::SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size) {
|
||||
return args::Set(program_id, args.GetPointer(), std::min(args.GetSize(), size_t(args_size)));
|
||||
}
|
||||
|
||||
Result LoaderService::ClearArguments() {
|
||||
return args::Clear();
|
||||
Result LoaderService::FlushArguments() {
|
||||
return args::Flush();
|
||||
}
|
||||
|
||||
Result LoaderService::GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id) {
|
||||
|
@ -83,16 +83,16 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* Atmosphere commands. */
|
||||
Result LoaderService::AtmosphereSetExternalContentSource(sf::OutMoveHandle out, ncm::TitleId title_id) {
|
||||
return ecs::Set(out.GetHandlePointer(), title_id);
|
||||
Result LoaderService::AtmosphereSetExternalContentSource(sf::OutMoveHandle out, ncm::ProgramId program_id) {
|
||||
return ecs::Set(out.GetHandlePointer(), program_id);
|
||||
}
|
||||
|
||||
void LoaderService::AtmosphereClearExternalContentSource(ncm::TitleId title_id) {
|
||||
R_ASSERT(ecs::Clear(title_id));
|
||||
void LoaderService::AtmosphereClearExternalContentSource(ncm::ProgramId program_id) {
|
||||
R_ASSERT(ecs::Clear(program_id));
|
||||
}
|
||||
|
||||
void LoaderService::AtmosphereHasLaunchedTitle(sf::Out<bool> out, ncm::TitleId title_id) {
|
||||
out.SetValue(ldr::HasLaunchedTitle(title_id));
|
||||
void LoaderService::AtmosphereHasLaunchedProgram(sf::Out<bool> out, ncm::ProgramId program_id) {
|
||||
out.SetValue(ldr::HasLaunchedProgram(program_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,17 +22,17 @@ namespace ams::ldr {
|
|||
protected:
|
||||
/* Official commands. */
|
||||
virtual Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h);
|
||||
virtual Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::TitleLocation &loc);
|
||||
virtual Result PinTitle(sf::Out<PinId> out_id, const ncm::TitleLocation &loc);
|
||||
virtual Result UnpinTitle(PinId id);
|
||||
virtual Result SetTitleArguments(ncm::TitleId title_id, const sf::InPointerBuffer &args, u32 args_size);
|
||||
virtual Result ClearArguments();
|
||||
virtual Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc);
|
||||
virtual Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc);
|
||||
virtual Result UnpinProgram(PinId id);
|
||||
virtual Result SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size);
|
||||
virtual Result FlushArguments();
|
||||
virtual Result GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id);
|
||||
|
||||
/* Atmosphere commands. */
|
||||
virtual Result AtmosphereSetExternalContentSource(sf::OutMoveHandle out, ncm::TitleId title_id);
|
||||
virtual void AtmosphereClearExternalContentSource(ncm::TitleId title_id);
|
||||
virtual void AtmosphereHasLaunchedTitle(sf::Out<bool> out, ncm::TitleId title_id);
|
||||
virtual Result AtmosphereSetExternalContentSource(sf::OutMoveHandle out, ncm::ProgramId program_id);
|
||||
virtual void AtmosphereClearExternalContentSource(ncm::ProgramId program_id);
|
||||
virtual void AtmosphereHasLaunchedProgram(sf::Out<bool> out, ncm::ProgramId program_id);
|
||||
};
|
||||
|
||||
namespace pm {
|
||||
|
@ -42,19 +42,19 @@ namespace ams::ldr {
|
|||
enum class CommandId {
|
||||
CreateProcess = 0,
|
||||
GetProgramInfo = 1,
|
||||
PinTitle = 2,
|
||||
UnpinTitle = 3,
|
||||
PinProgram = 2,
|
||||
UnpinProgram = 3,
|
||||
|
||||
AtmosphereHasLaunchedTitle = 65000,
|
||||
AtmosphereHasLaunchedProgram = 65000,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(CreateProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetProgramInfo),
|
||||
MAKE_SERVICE_COMMAND_META(PinTitle),
|
||||
MAKE_SERVICE_COMMAND_META(UnpinTitle),
|
||||
MAKE_SERVICE_COMMAND_META(PinProgram),
|
||||
MAKE_SERVICE_COMMAND_META(UnpinProgram),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedTitle),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedProgram),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -65,19 +65,19 @@ namespace ams::ldr {
|
|||
class DebugMonitorInterface final : public LoaderService {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
SetTitleArguments = 0,
|
||||
ClearArguments = 1,
|
||||
SetProgramArguments = 0,
|
||||
FlushArguments = 1,
|
||||
GetProcessModuleInfo = 2,
|
||||
|
||||
AtmosphereHasLaunchedTitle = 65000,
|
||||
AtmosphereHasLaunchedProgram = 65000,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetTitleArguments),
|
||||
MAKE_SERVICE_COMMAND_META(ClearArguments),
|
||||
MAKE_SERVICE_COMMAND_META(SetProgramArguments),
|
||||
MAKE_SERVICE_COMMAND_META(FlushArguments),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessModuleInfo),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedTitle),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedProgram),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -88,16 +88,16 @@ namespace ams::ldr {
|
|||
class ShellInterface final : public LoaderService {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
SetTitleArguments = 0,
|
||||
ClearArguments = 1,
|
||||
SetProgramArguments = 0,
|
||||
FlushArguments = 1,
|
||||
|
||||
AtmosphereSetExternalContentSource = 65000,
|
||||
AtmosphereClearExternalContentSource = 65001,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetTitleArguments),
|
||||
MAKE_SERVICE_COMMAND_META(ClearArguments),
|
||||
MAKE_SERVICE_COMMAND_META(SetProgramArguments),
|
||||
MAKE_SERVICE_COMMAND_META(FlushArguments),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereSetExternalContentSource),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereClearExternalContentSource),
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x4000
|
||||
#define INNER_HEAP_SIZE 0x8000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
char nx_inner_heap[INNER_HEAP_SIZE];
|
||||
|
||||
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
|
||||
namespace ams {
|
||||
|
||||
ncm::TitleId CurrentTitleId = ncm::TitleId::Loader;
|
||||
ncm::ProgramId CurrentProgramId = ncm::ProgramId::Loader;
|
||||
|
||||
namespace result {
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::ldr {
|
|||
};
|
||||
|
||||
/* Global storage. */
|
||||
ncm::TitleId g_cached_title_id;
|
||||
ncm::ProgramId g_cached_program_id;
|
||||
MetaCache g_meta_cache;
|
||||
MetaCache g_original_meta_cache;
|
||||
|
||||
|
@ -144,25 +144,25 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* API. */
|
||||
Result LoadMeta(Meta *out_meta, ncm::TitleId title_id) {
|
||||
Result LoadMeta(Meta *out_meta, ncm::ProgramId program_id) {
|
||||
FILE *f = nullptr;
|
||||
|
||||
/* Try to load meta from file. */
|
||||
R_TRY(OpenCodeFile(f, title_id, MetaFilePath));
|
||||
R_TRY(OpenCodeFile(f, program_id, MetaFilePath));
|
||||
{
|
||||
ON_SCOPE_EXIT { fclose(f); };
|
||||
R_TRY(LoadMetaFromFile(f, &g_meta_cache));
|
||||
}
|
||||
|
||||
/* Patch meta. Start by setting all title ids to the current title id. */
|
||||
/* Patch meta. Start by setting all program ids to the current program id. */
|
||||
Meta *meta = &g_meta_cache.meta;
|
||||
meta->acid->title_id_min = title_id;
|
||||
meta->acid->title_id_max = title_id;
|
||||
meta->aci->title_id = title_id;
|
||||
meta->acid->program_id_min = program_id;
|
||||
meta->acid->program_id_max = program_id;
|
||||
meta->aci->program_id = program_id;
|
||||
|
||||
/* For HBL, we need to copy some information from the base meta. */
|
||||
if (cfg::IsHblOverrideKeyHeld(title_id)) {
|
||||
if (R_SUCCEEDED(OpenCodeFileFromBaseExefs(f, title_id, MetaFilePath))) {
|
||||
if (cfg::IsHblOverrideKeyHeld(program_id)) {
|
||||
if (R_SUCCEEDED(OpenCodeFileFromBaseExefs(f, program_id, MetaFilePath))) {
|
||||
ON_SCOPE_EXIT { fclose(f); };
|
||||
if (R_SUCCEEDED(LoadMetaFromFile(f, &g_original_meta_cache))) {
|
||||
Meta *o_meta = &g_original_meta_cache.meta;
|
||||
|
@ -181,23 +181,23 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* Set output. */
|
||||
g_cached_title_id = title_id;
|
||||
g_cached_program_id = program_id;
|
||||
*out_meta = *meta;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LoadMetaFromCache(Meta *out_meta, ncm::TitleId title_id) {
|
||||
if (g_cached_title_id != title_id) {
|
||||
return LoadMeta(out_meta, title_id);
|
||||
Result LoadMetaFromCache(Meta *out_meta, ncm::ProgramId program_id) {
|
||||
if (g_cached_program_id != program_id) {
|
||||
return LoadMeta(out_meta, program_id);
|
||||
}
|
||||
*out_meta = g_meta_cache.meta;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void InvalidateMetaCache() {
|
||||
/* Set the cached title id back to zero. */
|
||||
g_cached_title_id = {};
|
||||
/* Set the cached program id back to zero. */
|
||||
g_cached_program_id = {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ namespace ams::ldr {
|
|||
};
|
||||
|
||||
/* Meta API. */
|
||||
Result LoadMeta(Meta *out_meta, ncm::TitleId title_id);
|
||||
Result LoadMetaFromCache(Meta *out_meta, ncm::TitleId title_id);
|
||||
Result LoadMeta(Meta *out_meta, ncm::ProgramId program_id);
|
||||
Result LoadMetaFromCache(Meta *out_meta, ncm::ProgramId program_id);
|
||||
void InvalidateMetaCache();
|
||||
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace ams::ldr {
|
|||
struct CreateProcessInfo {
|
||||
char name[12];
|
||||
u32 version;
|
||||
ncm::TitleId title_id;
|
||||
ncm::ProgramId program_id;
|
||||
u64 code_address;
|
||||
u32 code_num_pages;
|
||||
u32 flags;
|
||||
|
@ -95,8 +95,8 @@ namespace ams::ldr {
|
|||
NsoHeader g_nso_headers[Nso_Count];
|
||||
|
||||
/* Anti-downgrade. */
|
||||
struct MinimumTitleVersion {
|
||||
ncm::TitleId title_id;
|
||||
struct MinimumProgramVersion {
|
||||
ncm::ProgramId program_id;
|
||||
u32 version;
|
||||
};
|
||||
|
||||
|
@ -104,104 +104,104 @@ namespace ams::ldr {
|
|||
return (major << 26) | (minor << 20) | (micro << 16);
|
||||
}
|
||||
|
||||
constexpr MinimumTitleVersion g_MinimumTitleVersions810[] = {
|
||||
{ncm::TitleId::Settings, 1},
|
||||
{ncm::TitleId::Bus, 1},
|
||||
{ncm::TitleId::Audio, 1},
|
||||
{ncm::TitleId::NvServices, 1},
|
||||
{ncm::TitleId::Ns, 1},
|
||||
{ncm::TitleId::Ssl, 1},
|
||||
{ncm::TitleId::Es, 1},
|
||||
{ncm::TitleId::Creport, 1},
|
||||
{ncm::TitleId::Ro, 1},
|
||||
constexpr MinimumProgramVersion g_MinimumProgramVersions810[] = {
|
||||
{ncm::ProgramId::Settings, 1},
|
||||
{ncm::ProgramId::Bus, 1},
|
||||
{ncm::ProgramId::Audio, 1},
|
||||
{ncm::ProgramId::NvServices, 1},
|
||||
{ncm::ProgramId::Ns, 1},
|
||||
{ncm::ProgramId::Ssl, 1},
|
||||
{ncm::ProgramId::Es, 1},
|
||||
{ncm::ProgramId::Creport, 1},
|
||||
{ncm::ProgramId::Ro, 1},
|
||||
};
|
||||
constexpr size_t g_MinimumTitleVersionsCount810 = util::size(g_MinimumTitleVersions810);
|
||||
constexpr size_t g_MinimumProgramVersionsCount810 = util::size(g_MinimumProgramVersions810);
|
||||
|
||||
constexpr MinimumTitleVersion g_MinimumTitleVersions900[] = {
|
||||
constexpr MinimumProgramVersion g_MinimumProgramVersions900[] = {
|
||||
/* All non-Development System Modules. */
|
||||
{ncm::TitleId::Usb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Tma, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Boot2, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Settings, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Bus, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Bluetooth, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Bcat, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Dmnt, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::Friends, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Nifm, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Ptm, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Shell, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::BsdSockets, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Hid, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Audio, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::LogManager, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Wlan, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Cs, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::Ldn, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::NvServices, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Pcv, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Ppc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::NvnFlinger, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Pcie, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Account, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Ns, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Nfc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Psc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::CapSrv, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Am, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Ssl, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Nim, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Cec, MakeSystemVersion(9, 0, 0)}, */
|
||||
/* {ncm::TitleId::Tspm, MakeSystemVersion(9, 0, 0)}, */
|
||||
/* {ncm::TitleId::Spl, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::Lbl, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Btm, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Erpt, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Time, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::Vi, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Pctl, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Npns, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Eupld, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Glue, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Eclct, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Es, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Fatal, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Grc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Creport, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Ro, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Profiler, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::Sdb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Migration, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Jit, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::JpegDec, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::SafeMode, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::Olsc, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::TitleId::Dt, MakeSystemVersion(9, 0, 0)}, */
|
||||
/* {ncm::TitleId::Nd, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::TitleId::Ngct, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Usb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Tma, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Boot2, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Settings, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Bus, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Bluetooth, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Bcat, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Dmnt, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::Friends, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Nifm, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Ptm, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Shell, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::BsdSockets, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Hid, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Audio, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::LogManager, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Wlan, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Cs, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::Ldn, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::NvServices, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Pcv, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Ppc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::NvnFlinger, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Pcie, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Account, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Ns, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Nfc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Psc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::CapSrv, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Am, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Ssl, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Nim, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Cec, MakeSystemVersion(9, 0, 0)}, */
|
||||
/* {ncm::ProgramId::Tspm, MakeSystemVersion(9, 0, 0)}, */
|
||||
/* {ncm::ProgramId::Spl, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::Lbl, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Btm, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Erpt, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Time, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::Vi, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Pctl, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Npns, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Eupld, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Glue, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Eclct, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Es, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Fatal, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Grc, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Creport, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Ro, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Profiler, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::Sdb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Migration, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Jit, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::JpegDec, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::SafeMode, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::Olsc, MakeSystemVersion(9, 0, 0)},
|
||||
/* {ncm::ProgramId::Dt, MakeSystemVersion(9, 0, 0)}, */
|
||||
/* {ncm::ProgramId::Nd, MakeSystemVersion(9, 0, 0)}, */
|
||||
{ncm::ProgramId::Ngct, MakeSystemVersion(9, 0, 0)},
|
||||
|
||||
/* All Web Applets. */
|
||||
{ncm::TitleId::AppletWeb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::AppletShop, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::AppletOfflineWeb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::AppletLoginShare, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::TitleId::AppletWifiWebAuth, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::AppletWeb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::AppletShop, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::AppletOfflineWeb, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::AppletLoginShare, MakeSystemVersion(9, 0, 0)},
|
||||
{ncm::ProgramId::AppletWifiWebAuth, MakeSystemVersion(9, 0, 0)},
|
||||
};
|
||||
constexpr size_t g_MinimumTitleVersionsCount900 = util::size(g_MinimumTitleVersions900);
|
||||
constexpr size_t g_MinimumProgramVersionsCount900 = util::size(g_MinimumProgramVersions900);
|
||||
|
||||
Result ValidateTitleVersion(ncm::TitleId title_id, u32 version) {
|
||||
Result ValidateProgramVersion(ncm::ProgramId program_id, u32 version) {
|
||||
R_UNLESS(hos::GetVersion() >= hos::Version_810, ResultSuccess());
|
||||
#ifdef LDR_VALIDATE_PROCESS_VERSION
|
||||
const MinimumTitleVersion *entries = nullptr;
|
||||
const MinimumProgramVersion *entries = nullptr;
|
||||
size_t num_entries = 0;
|
||||
switch (hos::GetVersion()) {
|
||||
case hos::Version_810:
|
||||
entries = g_MinimumTitleVersions810;
|
||||
num_entries = g_MinimumTitleVersionsCount810;
|
||||
entries = g_MinimumProgramVersions810;
|
||||
num_entries = g_MinimumProgramVersionsCount810;
|
||||
break;
|
||||
case hos::Version_900:
|
||||
entries = g_MinimumTitleVersions900;
|
||||
num_entries = g_MinimumTitleVersionsCount900;
|
||||
entries = g_MinimumProgramVersions900;
|
||||
num_entries = g_MinimumProgramVersionsCount900;
|
||||
break;
|
||||
default:
|
||||
entries = nullptr;
|
||||
|
@ -210,7 +210,7 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < num_entries; i++) {
|
||||
if (entries[i].title_id == title_id) {
|
||||
if (entries[i].program_id == program_id) {
|
||||
R_UNLESS(entries[i].version <= version, ResultInvalidVersion());
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ namespace ams::ldr {
|
|||
out->main_thread_priority = meta->npdm->main_thread_priority;
|
||||
out->default_cpu_id = meta->npdm->default_cpu_id;
|
||||
out->main_thread_stack_size = meta->npdm->main_thread_stack_size;
|
||||
out->title_id = meta->aci->title_id;
|
||||
out->program_id = meta->aci->program_id;
|
||||
|
||||
/* Copy access controls. */
|
||||
size_t offset = 0;
|
||||
|
@ -265,14 +265,14 @@ namespace ams::ldr {
|
|||
return static_cast<Acid::PoolPartition>((meta->acid->flags & Acid::AcidFlag_PoolPartitionMask) >> Acid::AcidFlag_PoolPartitionShift);
|
||||
}
|
||||
|
||||
Result LoadNsoHeaders(ncm::TitleId title_id, NsoHeader *nso_headers, bool *has_nso) {
|
||||
Result LoadNsoHeaders(ncm::ProgramId program_id, NsoHeader *nso_headers, bool *has_nso) {
|
||||
/* Clear NSOs. */
|
||||
std::memset(nso_headers, 0, sizeof(*nso_headers) * Nso_Count);
|
||||
std::memset(has_nso, 0, sizeof(*has_nso) * Nso_Count);
|
||||
|
||||
for (size_t i = 0; i < Nso_Count; i++) {
|
||||
FILE *f = nullptr;
|
||||
if (R_SUCCEEDED(OpenCodeFile(f, title_id, GetNsoName(i)))) {
|
||||
if (R_SUCCEEDED(OpenCodeFile(f, program_id, GetNsoName(i)))) {
|
||||
ON_SCOPE_EXIT { fclose(f); };
|
||||
/* Read NSO header. */
|
||||
R_UNLESS(fread(nso_headers + i, sizeof(*nso_headers), 1, f) == 1, ResultInvalidNso());
|
||||
|
@ -302,13 +302,13 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ValidateMeta(const Meta *meta, const ncm::TitleLocation &loc) {
|
||||
Result ValidateMeta(const Meta *meta, const ncm::ProgramLocation &loc) {
|
||||
/* Validate version. */
|
||||
R_TRY(ValidateTitleVersion(loc.title_id, meta->npdm->version));
|
||||
R_TRY(ValidateProgramVersion(loc.program_id, meta->npdm->version));
|
||||
|
||||
/* Validate title id. */
|
||||
R_UNLESS(meta->aci->title_id >= meta->acid->title_id_min, ResultInvalidProgramId());
|
||||
R_UNLESS(meta->aci->title_id <= meta->acid->title_id_max, ResultInvalidProgramId());
|
||||
/* Validate program id. */
|
||||
R_UNLESS(meta->aci->program_id >= meta->acid->program_id_min, ResultInvalidProgramId());
|
||||
R_UNLESS(meta->aci->program_id <= meta->acid->program_id_max, ResultInvalidProgramId());
|
||||
|
||||
/* Validate the kernel capabilities. */
|
||||
R_TRY(caps::ValidateCapabilities(meta->acid_kac, meta->acid->kac_size, meta->aci_kac, meta->aci->kac_size));
|
||||
|
@ -404,10 +404,10 @@ namespace ams::ldr {
|
|||
/* Clear output. */
|
||||
std::memset(out, 0, sizeof(*out));
|
||||
|
||||
/* Set name, version, title id, resource limit handle. */
|
||||
std::memcpy(out->name, meta->npdm->title_name, sizeof(out->name) - 1);
|
||||
/* Set name, version, program id, resource limit handle. */
|
||||
std::memcpy(out->name, meta->npdm->program_name, sizeof(out->name) - 1);
|
||||
out->version = meta->npdm->version;
|
||||
out->title_id = meta->aci->title_id;
|
||||
out->program_id = meta->aci->program_id;
|
||||
out->reslimit = reslimit_h;
|
||||
|
||||
/* Set flags. */
|
||||
|
@ -611,14 +611,14 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LoadNsosIntoProcessMemory(const ProcessInfo *process_info, const ncm::TitleId title_id, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
|
||||
Result LoadNsosIntoProcessMemory(const ProcessInfo *process_info, const ncm::ProgramId program_id, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
|
||||
const Handle process_handle = process_info->process_handle.Get();
|
||||
|
||||
/* Load each NSO. */
|
||||
for (size_t i = 0; i < Nso_Count; i++) {
|
||||
if (has_nso[i]) {
|
||||
FILE *f = nullptr;
|
||||
R_TRY(OpenCodeFile(f, title_id, GetNsoName(i)));
|
||||
R_TRY(OpenCodeFile(f, program_id, GetNsoName(i)));
|
||||
ON_SCOPE_EXIT { fclose(f); };
|
||||
|
||||
uintptr_t map_address = 0;
|
||||
|
@ -655,11 +655,11 @@ namespace ams::ldr {
|
|||
}
|
||||
|
||||
/* Process Creation API. */
|
||||
Result CreateProcess(Handle *out, PinId pin_id, const ncm::TitleLocation &loc, const char *path, u32 flags, Handle reslimit_h) {
|
||||
Result CreateProcess(Handle *out, PinId pin_id, const ncm::ProgramLocation &loc, const char *path, u32 flags, Handle reslimit_h) {
|
||||
/* Use global storage for NSOs. */
|
||||
NsoHeader *nso_headers = g_nso_headers;
|
||||
bool *has_nso = g_has_nso;
|
||||
const auto arg_info = args::Get(loc.title_id);
|
||||
const auto arg_info = args::Get(loc.program_id);
|
||||
|
||||
{
|
||||
/* Mount code. */
|
||||
|
@ -668,13 +668,13 @@ namespace ams::ldr {
|
|||
|
||||
/* Load meta, possibly from cache. */
|
||||
Meta meta;
|
||||
R_TRY(LoadMetaFromCache(&meta, loc.title_id));
|
||||
R_TRY(LoadMetaFromCache(&meta, loc.program_id));
|
||||
|
||||
/* Validate meta. */
|
||||
R_TRY(ValidateMeta(&meta, loc));
|
||||
|
||||
/* Load, validate NSOs. */
|
||||
R_TRY(LoadNsoHeaders(loc.title_id, nso_headers, has_nso));
|
||||
R_TRY(LoadNsoHeaders(loc.program_id, nso_headers, has_nso));
|
||||
R_TRY(ValidateNsoHeaders(nso_headers, has_nso));
|
||||
|
||||
/* Actually create process. */
|
||||
|
@ -682,7 +682,7 @@ namespace ams::ldr {
|
|||
R_TRY(CreateProcessImpl(&info, &meta, nso_headers, has_nso, arg_info, flags, reslimit_h));
|
||||
|
||||
/* Load NSOs into process memory. */
|
||||
R_TRY(LoadNsosIntoProcessMemory(&info, loc.title_id, nso_headers, has_nso, arg_info));
|
||||
R_TRY(LoadNsosIntoProcessMemory(&info, loc.program_id, nso_headers, has_nso, arg_info));
|
||||
|
||||
/* Register NSOs with ro manager. */
|
||||
{
|
||||
|
@ -690,7 +690,7 @@ namespace ams::ldr {
|
|||
os::ProcessId process_id = os::GetProcessId(info.process_handle.Get());
|
||||
|
||||
/* Register new process. */
|
||||
ldr::ro::RegisterProcess(pin_id, process_id, loc.title_id);
|
||||
ldr::ro::RegisterProcess(pin_id, process_id, loc.program_id);
|
||||
|
||||
/* Register all NSOs. */
|
||||
for (size_t i = 0; i < Nso_Count; i++) {
|
||||
|
@ -706,11 +706,11 @@ namespace ams::ldr {
|
|||
RedirectHtmlDocumentPathForHbl(loc);
|
||||
}
|
||||
|
||||
/* Clear the ECS entry for the title. */
|
||||
R_ASSERT(ecs::Clear(loc.title_id));
|
||||
/* Clear the ECS entry for the program. */
|
||||
R_ASSERT(ecs::Clear(loc.program_id));
|
||||
|
||||
/* Note that we've created the title. */
|
||||
SetLaunchedTitle(loc.title_id);
|
||||
/* Note that we've created the program. */
|
||||
SetLaunchedProgram(loc.program_id);
|
||||
|
||||
/* Move the process handle to output. */
|
||||
*out = info.process_handle.Move();
|
||||
|
@ -719,14 +719,14 @@ namespace ams::ldr {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::TitleLocation &loc) {
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) {
|
||||
Meta meta;
|
||||
|
||||
/* Load Meta. */
|
||||
{
|
||||
ScopedCodeMount mount(loc);
|
||||
R_TRY(mount.GetResult());
|
||||
R_TRY(LoadMeta(&meta, loc.title_id));
|
||||
R_TRY(LoadMeta(&meta, loc.program_id));
|
||||
}
|
||||
|
||||
return GetProgramInfoFromMeta(out, &meta);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
namespace ams::ldr {
|
||||
|
||||
/* Process Creation API. */
|
||||
Result CreateProcess(Handle *out, PinId pin_id, const ncm::TitleLocation &loc, const char *path, u32 flags, Handle reslimit_h);
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::TitleLocation &loc);
|
||||
Result CreateProcess(Handle *out, PinId pin_id, const ncm::ProgramLocation &loc, const char *path, u32 flags, Handle reslimit_h);
|
||||
Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc);
|
||||
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ namespace ams::ldr::ro {
|
|||
struct ProcessInfo {
|
||||
PinId pin_id;
|
||||
os::ProcessId process_id;
|
||||
ncm::TitleId title_id;
|
||||
ncm::TitleLocation loc;
|
||||
ncm::ProgramId program_id;
|
||||
ncm::ProgramLocation loc;
|
||||
ModuleInfo modules[ModuleCountMax];
|
||||
bool in_use;
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ namespace ams::ldr::ro {
|
|||
}
|
||||
|
||||
/* RO Manager API. */
|
||||
Result PinTitle(PinId *out, const ncm::TitleLocation &loc) {
|
||||
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc) {
|
||||
*out = InvalidPinId;
|
||||
ProcessInfo *info = GetFreeProcessInfo();
|
||||
R_UNLESS(info != nullptr, ldr::ResultTooManyProcesses());
|
||||
|
@ -91,7 +91,7 @@ namespace ams::ldr::ro {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UnpinTitle(PinId id) {
|
||||
Result UnpinProgram(PinId id) {
|
||||
ProcessInfo *info = GetProcessInfo(id);
|
||||
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
|
||||
|
||||
|
@ -100,7 +100,7 @@ namespace ams::ldr::ro {
|
|||
}
|
||||
|
||||
|
||||
Result GetTitleLocation(ncm::TitleLocation *out, PinId id) {
|
||||
Result GetProgramLocation(ncm::ProgramLocation *out, PinId id) {
|
||||
ProcessInfo *info = GetProcessInfo(id);
|
||||
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
|
||||
|
||||
|
@ -108,11 +108,11 @@ namespace ams::ldr::ro {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result RegisterProcess(PinId id, os::ProcessId process_id, ncm::TitleId title_id) {
|
||||
Result RegisterProcess(PinId id, os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
ProcessInfo *info = GetProcessInfo(id);
|
||||
R_UNLESS(info != nullptr, ldr::ResultNotPinned());
|
||||
|
||||
info->title_id = title_id;
|
||||
info->program_id = program_id;
|
||||
info->process_id = process_id;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
namespace ams::ldr::ro {
|
||||
|
||||
/* RO Manager API. */
|
||||
Result PinTitle(PinId *out, const ncm::TitleLocation &loc);
|
||||
Result UnpinTitle(PinId id);
|
||||
Result GetTitleLocation(ncm::TitleLocation *out, PinId id);
|
||||
Result RegisterProcess(PinId id, os::ProcessId process_id, ncm::TitleId title_id);
|
||||
Result PinProgram(PinId *out, const ncm::ProgramLocation &loc);
|
||||
Result UnpinProgram(PinId id);
|
||||
Result GetProgramLocation(ncm::ProgramLocation *out, PinId id);
|
||||
Result RegisterProcess(PinId id, os::ProcessId process_id, ncm::ProgramId program_id);
|
||||
Result RegisterModule(PinId id, const u8 *build_id, uintptr_t address, size_t size);
|
||||
Result GetProcessModuleInfo(u32 *out_count, ModuleInfo *out, size_t max_out_count, os::ProcessId process_id);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue