diff --git a/stratosphere/fs_mitm/source/fs_shim.c b/stratosphere/fs_mitm/source/fs_shim.c index 0c510dbba..134d83498 100644 --- a/stratosphere/fs_mitm/source/fs_shim.c +++ b/stratosphere/fs_mitm/source/fs_shim.c @@ -17,47 +17,6 @@ #include #include "fs_shim.h" -/* Necessary evil. */ -Result ipcCopyFromDomain(Handle session, u32 object_id, Service *out) { - u32* buf = (u32*)armGetTls(); - - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 object_id; - } *raw; - - raw = ipcPrepareHeader(&c, sizeof(*raw)); - buf[0] = IpcCommandType_Control; - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1; - raw->object_id = object_id; - - Result rc = ipcDispatch(session); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParse(&r); - - struct ipcCopyFromDomainResponse { - u64 magic; - u64 result; - } *raw = (struct ipcCopyFromDomainResponse*)r.Raw; - - rc = raw->result; - - if (R_SUCCEEDED(rc)) { - serviceCreate(out, r.Handles[0]); - } - } - - return rc; -} - - /* Missing fsp-srv commands. */ Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) { IpcCommand c; @@ -68,7 +27,7 @@ Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) { u64 cmd_id; } *raw; - raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 200; @@ -77,60 +36,25 @@ Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) { if (R_SUCCEEDED(rc)) { IpcParsedCommand r; - ipcParse(&r); - struct { u64 magic; u64 result; - } *resp = r.Raw; + } *resp; + + serviceIpcParse(s, &r, sizeof(*resp)); + resp = r.Raw; rc = resp->result; if (R_SUCCEEDED(rc)) { - serviceCreate(&out->s, r.Handles[0]); + serviceCreateSubservice(&out->s, s, &r, 0); } } return rc; } -Result fsOpenDataStorageByCurrentProcessFromDomainFwd(Service* s, u32 *out_object_id) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), s->object_id); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 200; - - Result rc = serviceIpcDispatch(s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParseForDomain(&r); - - struct { - u64 magic; - u64 result; - u32 object_id; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out_object_id = resp->object_id; - } - } - - return rc; -} - -Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out) { +Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out) { IpcCommand c; ipcInitialize(&c); @@ -141,7 +65,7 @@ Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id u64 data_id; } *raw; - raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 202; @@ -152,58 +76,18 @@ Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id if (R_SUCCEEDED(rc)) { IpcParsedCommand r; - ipcParse(&r); - struct { u64 magic; u64 result; - } *resp = r.Raw; + } *resp; + + serviceIpcParse(s, &r, sizeof(*resp)); + resp = r.Raw; rc = resp->result; if (R_SUCCEEDED(rc)) { - serviceCreate(&out->s, r.Handles[0]); - } - } - - return rc; -} - - -Result fsOpenDataStorageByDataIdFromDomain(Service* s, FsStorageId storage_id, u64 data_id, u32 *out_object_id) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - FsStorageId storage_id; - u64 data_id; - } *raw; - - raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), s->object_id); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 202; - raw->storage_id = storage_id; - raw->data_id = data_id; - - Result rc = serviceIpcDispatch(s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - ipcParseForDomain(&r); - - struct { - u64 magic; - u64 result; - u32 object_id; - } *resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out_object_id = resp->object_id; + serviceCreateSubservice(&out->s, s, &r, 0); } } @@ -223,7 +107,7 @@ Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *o u64 len; } *raw; - raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(&f->s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 5; @@ -235,13 +119,14 @@ Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *o if (R_SUCCEEDED(rc)) { IpcParsedCommand r; - ipcParse(&r); - struct { u64 magic; u64 result; FsRangeInfo range_info; - } *resp = r.Raw; + } *resp; + + serviceIpcParse(&f->s, &r, sizeof(*resp)); + resp = r.Raw; rc = resp->result; if (R_SUCCEEDED(rc) && out) *out = resp->range_info; @@ -263,7 +148,7 @@ Result fsStorageOperateRange(FsStorage* s, u32 op_id, u64 off, u64 len, FsRangeI u64 len; } *raw; - raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; raw->cmd_id = 5; @@ -275,13 +160,14 @@ Result fsStorageOperateRange(FsStorage* s, u32 op_id, u64 off, u64 len, FsRangeI if (R_SUCCEEDED(rc)) { IpcParsedCommand r; - ipcParse(&r); - struct { u64 magic; u64 result; FsRangeInfo range_info; - } *resp = r.Raw; + } *resp; + + serviceIpcParse(&s->s, &r, sizeof(*resp)); + resp = r.Raw; rc = resp->result; if (R_SUCCEEDED(rc) && out) *out = resp->range_info; diff --git a/stratosphere/fs_mitm/source/fs_shim.h b/stratosphere/fs_mitm/source/fs_shim.h index 9030078e7..d73c2595b 100644 --- a/stratosphere/fs_mitm/source/fs_shim.h +++ b/stratosphere/fs_mitm/source/fs_shim.h @@ -16,14 +16,9 @@ typedef struct { u32 flags[0x40/sizeof(u32)]; } FsRangeInfo; -/* Necessary evils. */ -Result ipcCopyFromDomain(Handle session, u32 object_id, Service *out); - /* Missing fsp-srv commands. */ Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out); -Result fsOpenDataStorageByCurrentProcessFromDomainFwd(Service* s, u32 *out_object_id); -Result fsOpenDataStorageByDataId(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out); -Result fsOpenDataStorageByDataIdFromDomain(Service* s, FsStorageId storage_id, u64 data_id, u32 *out_object_id); +Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out); /* Missing FS File commands. */ Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *out); diff --git a/stratosphere/fs_mitm/source/fsmitm_service.cpp b/stratosphere/fs_mitm/source/fsmitm_service.cpp index 07f5c3156..d139cc328 100644 --- a/stratosphere/fs_mitm/source/fsmitm_service.cpp +++ b/stratosphere/fs_mitm/source/fsmitm_service.cpp @@ -91,7 +91,11 @@ std::tuple> FsMitMService::open_data_stora Result rc; if (this->romfs_storage != nullptr) { if (this->get_owner() != NULL) { - rc = fsOpenDataStorageByCurrentProcessFromDomainFwd(this->forward_service, &out_domain_id); + FsStorage s = {0}; + rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &s); + if (R_SUCCEEDED(rc)) { + out_domain_id = s.s.object_id; + } } else { rc = 0; } @@ -102,15 +106,9 @@ std::tuple> FsMitMService::open_data_stora } else { FsStorage data_storage; FsFile data_file; + + rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &data_storage); - if (this->get_owner() == NULL) { - rc = fsOpenDataStorageByCurrentProcessFwd(this->forward_service, &data_storage); - } else { - rc = fsOpenDataStorageByCurrentProcessFromDomainFwd(this->forward_service, &out_domain_id); - if (R_SUCCEEDED(rc)) { - rc = ipcCopyFromDomain(this->forward_service->handle, out_domain_id, &data_storage.s); - } - } Log(armGetTls(), 0x100); if (R_SUCCEEDED(rc)) { /* TODO: Is there a sensible path that ends in ".romfs" we can use?" */ @@ -123,6 +121,8 @@ std::tuple> FsMitMService::open_data_stora out_session = new IPCSession(out_storage); if (this->get_owner() == NULL) { FsMitMWorker::AddWaitable(out_session); + } else { + out_domain_id = data_storage.s.object_id; } } } @@ -140,14 +140,9 @@ std::tuple> FsMitMService::open_data_stora FsFile data_file; u32 out_domain_id = 0; Result rc; - if (this->get_owner() == NULL) { - rc = fsOpenDataStorageByDataId(this->forward_service, storage_id, data_id, &data_storage); - } else { - rc = fsOpenDataStorageByDataIdFromDomain(this->forward_service, storage_id, data_id, &out_domain_id); - if (R_SUCCEEDED(rc)) { - rc = ipcCopyFromDomain(this->forward_service->handle, out_domain_id, &data_storage.s); - } - } + + rc = fsOpenDataStorageByDataIdFwd(this->forward_service, storage_id, data_id, &data_storage); + if (R_SUCCEEDED(rc)) { /* TODO: Is there a sensible path that ends in ".romfs" we can use?" */ if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(data_id, "romfs.bin", FS_OPEN_READ, &data_file))) { @@ -157,6 +152,8 @@ std::tuple> FsMitMService::open_data_stora } if (this->get_owner() == NULL) { FsMitMWorker::AddWaitable(out_session); + } else { + out_domain_id = data_storage.s.object_id; } } diff --git a/stratosphere/fs_mitm/source/mitm_session.hpp b/stratosphere/fs_mitm/source/mitm_session.hpp index 0d535b529..c49915e69 100644 --- a/stratosphere/fs_mitm/source/mitm_session.hpp +++ b/stratosphere/fs_mitm/source/mitm_session.hpp @@ -87,20 +87,20 @@ class MitMSession final : public ISession { if (r.CommandType == IpcCommandType_Request || r.CommandType == IpcCommandType_RequestWithContext) { std::shared_ptr obj; - if (r.IsDomainMessage) { - obj = this->domain->get_domain_object(r.ThisObjectId); - if (obj != nullptr && r.MessageType == DomainMessageType_Close) { - if (r.ThisObjectId == this->mitm_domain_id) { + if (r.IsDomainRequest) { + obj = this->domain->get_domain_object(r.InThisObjectId); + if (obj != nullptr && r.InMessageType == DomainMessageType_Close) { + if (r.InThisObjectId == this->mitm_domain_id) { Reboot(); } - this->domain->delete_object(r.ThisObjectId); + this->domain->delete_object(r.InThisObjectId); struct { u64 magic; u64 result; } *o_resp; o_resp = (decltype(o_resp)) ipcPrepareHeaderForDomain(&c, sizeof(*o_resp), 0); - *(DomainMessageHeader *)((uintptr_t)o_resp - sizeof(DomainMessageHeader)) = {0}; + *(DomainResponseHeader *)((uintptr_t)o_resp - sizeof(DomainResponseHeader)) = {0}; o_resp->magic = SFCO_MAGIC; o_resp->result = 0x0; Log(armGetTls(), 0x100); @@ -112,8 +112,9 @@ class MitMSession final : public ISession { if (obj != nullptr) { retval = obj->dispatch(r, c, cmd_id, (u8 *)this->pointer_buffer.data(), this->pointer_buffer.size()); if (R_SUCCEEDED(retval)) { - if (r.IsDomainMessage) { - ipcParseForDomain(&cur_out_r); + if (r.IsDomainRequest) { + /* We never work with out object ids, so this should be fine. */ + ipcParseDomainResponse(&cur_out_r, 0); } else { ipcParse(&cur_out_r); } @@ -182,8 +183,9 @@ class MitMSession final : public ISession { Log(armGetTls(), 0x100); retval = serviceIpcDispatch(&forward_service); if (R_SUCCEEDED(retval)) { - if (r.IsDomainMessage) { - ipcParseForDomain(&cur_out_r); + if (r.IsDomainRequest) { + /* We never work with out object ids, so this should be fine. */ + ipcParseDomainResponse(&cur_out_r, 0); } else { ipcParse(&cur_out_r); } diff --git a/stratosphere/libstratosphere/include/stratosphere/ipc_templating.hpp b/stratosphere/libstratosphere/include/stratosphere/ipc_templating.hpp index 7f9c2c89e..d37857ae8 100644 --- a/stratosphere/libstratosphere/include/stratosphere/ipc_templating.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ipc_templating.hpp @@ -459,7 +459,9 @@ struct Encoder> { raw = (decltype(raw))ipcPrepareHeader(&out_command, sizeof(*raw) + size_in_raw_data_for_arguments::value - sizeof(Result)); } else { raw = (decltype(raw))ipcPrepareHeaderForDomain(&out_command, sizeof(*raw) + size_in_raw_data_for_arguments::value + (num_out_sessions_in_arguments::value * sizeof(u32)) - sizeof(Result), 0); - *((DomainMessageHeader *)((uintptr_t)raw - sizeof(DomainMessageHeader))) = {0}; + auto resp_header = (DomainResponseHeader *)((uintptr_t)raw - sizeof(DomainResponseHeader)); + *resp_header = {0}; + resp_header->NumObjectIds = num_out_sessions_in_arguments::value; } @@ -474,7 +476,13 @@ struct Encoder> { if (R_FAILED(rc)) { std::fill(tls, tls + 0x100, 0x00); ipcInitialize(&out_command); - raw = (decltype(raw))ipcPrepareHeader(&out_command, sizeof(raw)); + if (domain_owner != NULL) { + raw = (decltype(raw))ipcPrepareHeaderForDomain(&out_command, sizeof(raw), 0); + auto resp_header = (DomainResponseHeader *)((uintptr_t)raw - sizeof(DomainResponseHeader)); + *resp_header = {0}; + } else { + raw = (decltype(raw))ipcPrepareHeader(&out_command, sizeof(raw)); + } raw->magic = SFCO_MAGIC; raw->result = rc; } @@ -526,7 +534,7 @@ Result WrapIpcCommandImpl(Class *this_ptr, IpcParsedCommand& r, IpcCommand &out_ auto args = Decoder::Decode(r, out_command, pointer_buffer); auto result = std::apply( [=](auto&&... args) { return (this_ptr->*IpcCommandImpl)(args...); }, args); DomainOwner *down = NULL; - if (r.IsDomainMessage) { + if (r.IsDomainRequest) { down = this_ptr->get_owner(); } diff --git a/stratosphere/libstratosphere/include/stratosphere/isession.hpp b/stratosphere/libstratosphere/include/stratosphere/isession.hpp index 842dfd412..95156a2d0 100644 --- a/stratosphere/libstratosphere/include/stratosphere/isession.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/isession.hpp @@ -118,12 +118,12 @@ class ISession : public IWaitable { IpcCommand c; ipcInitialize(&c); - if (r.IsDomainMessage && this->active_object == NULL) { + if (r.IsDomainRequest && this->active_object == NULL) { return 0xF601; } - if (r.IsDomainMessage && r.MessageType == DomainMessageType_Close) { + if (r.IsDomainRequest && r.InMessageType == DomainMessageType_Close) { this->domain->delete_object(this->active_object); this->active_object = NULL; struct { @@ -198,11 +198,11 @@ class ISession : public IWaitable { Result retval = ipcParse(&r); if (R_SUCCEEDED(retval)) { if (this->is_domain && (r.CommandType == IpcCommandType_Request || r.CommandType == IpcCommandType_RequestWithContext)) { - retval = ipcParseForDomain(&r); - if (!r.IsDomainMessage || r.ThisObjectId >= DOMAIN_ID_MAX) { + retval = ipcParseDomainRequest(&r); + if (!r.IsDomainRequest || r.InThisObjectId >= DOMAIN_ID_MAX) { retval = 0xF601; } else { - this->active_object = this->domain->get_domain_object(r.ThisObjectId); + this->active_object = this->domain->get_domain_object(r.InThisObjectId); } } else { this->active_object = this->service_object;