strat: TitleId -> ProgramId, titles->contents

This commit is contained in:
Michael Scire 2019-10-27 21:43:01 -07:00 committed by SciresM
parent 1636668762
commit ea3ebbaa7d
86 changed files with 1138 additions and 1140 deletions

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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(&reg));
ON_SCOPE_EXIT { serviceClose(&reg.s); };
R_TRY_CATCH(lrRegLrResolveProgramPath(&reg, static_cast<u64>(loc.title_id), path)) {
R_TRY_CATCH(lrRegLrResolveProgramPath(&reg, 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();
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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));
}
}

View file

@ -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),

View file

@ -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 {

View file

@ -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 = {};
}
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);