diff --git a/stratosphere/libstratosphere/include/stratosphere/ipc/ipc_service_object.hpp b/stratosphere/libstratosphere/include/stratosphere/ipc/ipc_service_object.hpp index 979cd22a1..c2189920d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/ipc/ipc_service_object.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ipc/ipc_service_object.hpp @@ -124,6 +124,7 @@ class ServiceObjectHolder { } ServiceObjectHolder Clone() { - return ServiceObjectHolder(*this); + ServiceObjectHolder clone(*this); + return clone; } }; diff --git a/stratosphere/libstratosphere/include/stratosphere/mitm/imitmserviceobject.hpp b/stratosphere/libstratosphere/include/stratosphere/mitm/imitmserviceobject.hpp index 873487be5..e37ba152c 100644 --- a/stratosphere/libstratosphere/include/stratosphere/mitm/imitmserviceobject.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/mitm/imitmserviceobject.hpp @@ -28,6 +28,14 @@ class IMitmServiceObject : public IServiceObject { public: IMitmServiceObject(std::shared_ptr s) : forward_service(s) {} + virtual u64 GetTitleId() { + return this->title_id; + } + + virtual u64 GetProcessId() { + return this->process_id; + } + static bool ShouldMitm(u64 pid, u64 tid); protected: diff --git a/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_server.hpp b/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_server.hpp index dc7dbac6e..113df8a55 100644 --- a/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_server.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_server.hpp @@ -32,7 +32,10 @@ class MitmServer : public IWaitable { public: MitmServer(Handle *out_query_h, const char *service_name, unsigned int max_s) : port_handle(0), max_sessions(max_s) { Handle tmp_hnd; - Result rc; + Result rc = smMitMInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } if (R_SUCCEEDED((rc = smGetServiceOriginal(&tmp_hnd, smEncodeName(service_name))))) { svcCloseHandle(tmp_hnd); @@ -44,6 +47,8 @@ class MitmServer : public IWaitable { if (R_FAILED((rc = smMitMInstall(&this->port_handle, out_query_h, mitm_name)))) { fatalSimple(rc); } + + smMitMExit(); } virtual ~MitmServer() override { @@ -79,10 +84,17 @@ class MitmServer : public IWaitable { delete s; }); + rc = smMitMInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + if (R_FAILED(smMitMGetService(forward_service.get(), mitm_name))) { /* TODO: Panic. */ } + smMitMExit(); + this->GetSessionManager()->AddWaitable(new MitmSession(session_h, forward_service, std::make_shared(forward_service))); return 0; } diff --git a/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_session.hpp b/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_session.hpp index 33deb8b03..f4df504f1 100644 --- a/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_session.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/mitm/mitm_session.hpp @@ -30,7 +30,7 @@ class MitmSession final : public ServiceSession { void (*service_post_process_handler)(IMitmServiceObject *, IpcResponseContext *); /* For cleanup usage. */ - u32 num_fwd_copy_hnds; + u32 num_fwd_copy_hnds = 0; Handle fwd_copy_hnds[8]; public: template @@ -46,7 +46,7 @@ class MitmSession final : public ServiceSession { } this->pointer_buffer.resize(pbs); this->control_holder.Reset(); - this->control_holder = ServiceObjectHolder(std::make_shared(this)); + this->control_holder = std::move(ServiceObjectHolder(std::move(std::make_shared(this)))); } MitmSession(Handle s_h, std::shared_ptr fs, ServiceObjectHolder &&h, void (*pph)(IMitmServiceObject *, IpcResponseContext *)) : ServiceSession(s_h) { @@ -62,7 +62,7 @@ class MitmSession final : public ServiceSession { } this->pointer_buffer.resize(pbs); this->control_holder.Reset(); - this->control_holder = ServiceObjectHolder(std::make_shared(this)); + this->control_holder = std::move(ServiceObjectHolder(std::move(std::make_shared(this)))); } virtual void PreProcessRequest(IpcResponseContext *ctx) override { @@ -101,7 +101,7 @@ class MitmSession final : public ServiceSession { } return rc; } - + virtual Result GetResponse(IpcResponseContext *ctx) { Result rc = 0xF601; FirmwareVersion fw = GetRuntimeFirmwareVersion(); @@ -130,7 +130,8 @@ class MitmSession final : public ServiceSession { { auto sub_obj = ctx->obj_holder->GetServiceObject()->GetObject(ctx->request.InThisObjectId); if (sub_obj == nullptr) { - return ForwardRequest(ctx); + rc = ForwardRequest(ctx); + return rc; } dispatch_table = sub_obj->GetDispatchTable(); entry_count = sub_obj->GetDispatchTableEntryCount(); @@ -152,7 +153,7 @@ class MitmSession final : public ServiceSession { memcpy(armGetTls(), this->backup_tls, sizeof(this->backup_tls)); rc = ForwardRequest(ctx); } - + return rc; } diff --git a/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp b/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp index 9ce75d9f0..099c8dfbd 100644 --- a/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp @@ -165,6 +165,7 @@ class WaitableManager : public SessionManagerBase { if (result == nullptr) { std::vector handles; + std::vector wait_list; int handle_index = 0; Result rc; @@ -174,11 +175,14 @@ class WaitableManager : public SessionManagerBase { /* Copy out handles. */ handles.resize(this->waitables.size() + 1); + wait_list.resize(this->waitables.size() + 1); handles[0] = this->new_waitable_event->GetHandle(); + wait_list[0] = this->new_waitable_event; unsigned int num_handles = 1; for (unsigned int i = 0; i < this->waitables.size(); i++) { Handle h = this->waitables[i]->GetHandle(); if (h != INVALID_HANDLE) { + wait_list[num_handles] = this->waitables[i]; handles[num_handles++] = h; } } @@ -194,14 +198,15 @@ class WaitableManager : public SessionManagerBase { /* Wait forever. */ rc = svcWaitSynchronization(&handle_index, handles.data(), num_handles, U64_MAX); - IWaitable *w = this->waitables[handle_index - 1]; + IWaitable *w = wait_list[handle_index]; + size_t w_ind = std::distance(this->waitables.begin(), std::find(this->waitables.begin(), this->waitables.end(), w)); if (R_SUCCEEDED(rc)) { if (handle_index == 0) { AddWaitablesInternal(); continue; } - std::for_each(waitables.begin(), waitables.begin() + handle_index - 1, std::mem_fn(&IWaitable::UpdatePriority)); + std::for_each(waitables.begin(), waitables.begin() + w_ind, std::mem_fn(&IWaitable::UpdatePriority)); result = w; } else if (rc == 0xEA01) { /* Timeout: Just update priorities. */ @@ -216,8 +221,9 @@ class WaitableManager : public SessionManagerBase { if (handle_index == 0) { std::abort(); } - this->waitables.erase(this->waitables.begin() + handle_index - 1); - std::for_each(waitables.begin(), waitables.begin() + handle_index - 1, std::mem_fn(&IWaitable::UpdatePriority)); + + this->waitables.erase(this->waitables.begin() + w_ind); + std::for_each(waitables.begin(), waitables.begin() + w_ind - 1, std::mem_fn(&IWaitable::UpdatePriority)); delete w; } }