1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-18 16:32:05 +00:00

loader/ECS: don't clear ECS on failure, add ClearExternalContentSource command

This commit is contained in:
misson20000 2019-01-06 16:30:05 -08:00 committed by Michael Scire
parent d0505d3c11
commit 35cf3b65a3
4 changed files with 34 additions and 6 deletions

View file

@ -67,16 +67,35 @@ For example, `override_key=!R` will run the game only while holding down R when
When the Stratosphere implementation of loader creates a new process, it notifies [sm](sm.md) through the `AtmosphereAssociatePidTidForMitm` command to notify any MITM services of new processes' identities. When the Stratosphere implementation of loader creates a new process, it notifies [sm](sm.md) through the `AtmosphereAssociatePidTidForMitm` command to notify any MITM services of new processes' identities.
### IPC: AtmosphereSetExternalContentSource ### IPC: AtmosphereSetExternalContentSource and AtmosphereClearExternalContentSource
An additional command is added to the [`ldr:shel`](https://reswitched.github.io/SwIPC/ifaces.html#nn::ro::detail::ILdrShellInterface) interface, called `AtmosphereSetExternalContentSource`. It's command ID is `65000` on all system firmware versions. It takes a `u64 tid` and returns a server-side session handle. The client is expected to implement the `IFileSystem` interface on the returned handle. The next time the title specified by the given title ID is launched, its ExeFS contents will be loaded from the custom `IFileSystem` instead of from SD card or original ExeFS. NSOs loaded from external content source may still be subject to exefs IPS patches. After the title is launched, the `IFileSystem` is closed and the external content source override is removed. If `AtmosphereSetExternalContentSource` is called on a title that already has an external content source set for it, the existing one will be removed and replaced with the new one. It is illegal to call `AtmosphereSetExternalContentSource` while the title is being launched. Two additional commands are added to the [`ldr:shel`](https://reswitched.github.io/SwIPC/ifaces.html#nn::ro::detail::ILdrShellInterface) interface, called `AtmosphereSetExternalContentSource` and `AtmosphereClearExternalContentSource`.
Their command IDs are `65000` and `65001` on all system firmware versions.
The `IFileSystem` only needs to implement `OpenFile`. The paths received by the `IFileSystem`'s `OpenFile` command begin with slashes, as in `/main`, `/rtld`, and `/main.npdm`. A result code of 0x202 should be returned if the file does not exist. The `IFile`s returned from `OpenFile` only need to implement `Read` and `GetSize`. `AtmosphereSetExternalContentSource` takes a `u64 tid` and returns a server-side session handle.
The client is expected to implement the `IFileSystem` interface on the returned handle. The next
time the title specified by the given title ID is launched, its ExeFS contents will be loaded from
the custom `IFileSystem` instead of from SD card or original ExeFS. NSOs loaded from external
content source may still be subject to exefs IPS patches. After the title is launched successfuly,
the `IFileSystem` is closed and the external content source override is removed. If
`AtmosphereSetExternalContentSource` is called on a title that already has an external content
source set for it, the existing one will be removed and replaced with the new one. It is illegal to
call `AtmosphereSetExternalContentSource` while the title is being launched.
The SwIPC definition for the `AtmosphereSetExternalContentSource` command follows. If title launching fails, the external content source remains registered. The
`AtmosphereClearExternalContentSource` command can be used to clear an external content source if
title launch fails.
The `IFileSystem` only needs to implement `OpenFile` and `GetFileTimeStampRaw`. The paths received
by the `IFileSystem`'s `OpenFile` command begin with slashes, as in `/main`, `/rtld`, and `/main.npdm`.
A result code of 0x202 should be returned if the file does not exist. `GetFileTimeStampRaw` can just
be a stub. The `IFile`s returned from `OpenFile` only need to implement `Read` and `GetSize`.
The SwIPC definitions for the extension commands follow.
``` ```
interface nn::ldr::detail::IShellInterface is ldr:shel { interface nn::ldr::detail::IShellInterface is ldr:shel {
... ...
[65000] AtmosphereSetExternalContentSource(u64 tid) -> handle<copy, session_server> ifilesystem_handle; [65000] AtmosphereSetExternalContentSource(u64 tid) -> handle<copy, session_server> ifilesystem_handle;
[65001] AtmosphereClearExternalContentSource(u64 tid);
} }
``` ```

View file

@ -214,8 +214,8 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
Registration::AssociatePidTidForMitM(index); Registration::AssociatePidTidForMitM(index);
rc = 0; rc = 0;
CREATE_PROCESS_END:
/* ECS is a one-shot operation. */ /* ECS is a one-shot operation, but we don't clear on failure. */
ContentManagement::ClearExternalContentSource(target_process->tid_sid.title_id); ContentManagement::ClearExternalContentSource(target_process->tid_sid.title_id);
if (mounted_code) { if (mounted_code) {
if (R_SUCCEEDED(rc) && target_process->tid_sid.storage_id != FsStorageId_None) { if (R_SUCCEEDED(rc) && target_process->tid_sid.storage_id != FsStorageId_None) {
@ -224,6 +224,8 @@ CREATE_PROCESS_END:
ContentManagement::UnmountCode(); ContentManagement::UnmountCode();
} }
} }
CREATE_PROCESS_END:
if (R_SUCCEEDED(rc)) { if (R_SUCCEEDED(rc)) {
*out_process_h = process_h; *out_process_h = process_h;
} else { } else {

View file

@ -45,3 +45,7 @@ Result ShellService::SetExternalContentSource(Out<MovedHandle> out, u64 tid) {
out.SetValue(server_h); out.SetValue(server_h);
return 0; return 0;
} }
void ShellService::ClearExternalContentSource(u64 tid) {
ContentManagement::ClearExternalContentSource(tid);
}

View file

@ -23,6 +23,7 @@ enum ShellServiceCmd {
Shell_Cmd_ClearLaunchQueue = 1, Shell_Cmd_ClearLaunchQueue = 1,
Shell_Cmd_AtmosphereSetExternalContentSource = 65000, Shell_Cmd_AtmosphereSetExternalContentSource = 65000,
Shell_Cmd_AtmosphereClearExternalContentSource = 65001,
}; };
class ShellService final : public IServiceObject { class ShellService final : public IServiceObject {
@ -33,10 +34,12 @@ class ShellService final : public IServiceObject {
/* Atmosphere commands. */ /* Atmosphere commands. */
Result SetExternalContentSource(Out<MovedHandle> out, u64 tid); Result SetExternalContentSource(Out<MovedHandle> out, u64 tid);
void ClearExternalContentSource(u64 tid);
public: public:
DEFINE_SERVICE_DISPATCH_TABLE { DEFINE_SERVICE_DISPATCH_TABLE {
MakeServiceCommandMeta<Shell_Cmd_AddTitleToLaunchQueue, &ShellService::AddTitleToLaunchQueue>(), MakeServiceCommandMeta<Shell_Cmd_AddTitleToLaunchQueue, &ShellService::AddTitleToLaunchQueue>(),
MakeServiceCommandMeta<Shell_Cmd_ClearLaunchQueue, &ShellService::ClearLaunchQueue>(), MakeServiceCommandMeta<Shell_Cmd_ClearLaunchQueue, &ShellService::ClearLaunchQueue>(),
MakeServiceCommandMeta<Shell_Cmd_AtmosphereSetExternalContentSource, &ShellService::SetExternalContentSource>(), MakeServiceCommandMeta<Shell_Cmd_AtmosphereSetExternalContentSource, &ShellService::SetExternalContentSource>(),
MakeServiceCommandMeta<Shell_Cmd_AtmosphereClearExternalContentSource, &ShellService::ClearExternalContentSource>(),
}; };
}; };