From 007fee90ba8da501c652b3a1631c914b56960ec2 Mon Sep 17 00:00:00 2001 From: misson20000 Date: Sat, 12 Jun 2021 16:38:32 -0700 Subject: [PATCH] update pgl service bindings for TIPC on 12.0.0+ --- twili/Services.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/twili/Services.cpp b/twili/Services.cpp index ae2c49a..ab07fe4 100644 --- a/twili/Services.cpp +++ b/twili/Services.cpp @@ -21,6 +21,7 @@ #include "Services.hpp" #include "twili.hpp" +#include "tipc.hpp" using namespace trn; @@ -30,6 +31,7 @@ struct Target_1_0_0; struct Target_5_0_0; // renumbered pm:dmnt commands struct Target_6_0_0; // added pm:dmnt ClearHook struct Target_10_0_0; // added pgl +struct Target_12_0_0; // pgl converted to TIPC template struct ObjectsHolder; @@ -90,6 +92,16 @@ struct ObjectsHolder : public ObjectsHolder { trn::ipc::client::Object pgl; }; +template<> +struct ObjectsHolder : public ObjectsHolder { + ObjectsHolder(trn::service::SM &&sm) : + ObjectsHolder(std::move(sm)), + pgl(ResultCode::AssertOk(sm.GetHandleForService("pgl"))) { + } + + tipc::Object pgl; +}; + template struct PmDmntCommandTable { }; @@ -125,6 +137,11 @@ struct PmDmntCommandTable : public PmDmntCommandTable +struct PmDmntCommandTable : public PmDmntCommandTable { + // no changes +}; + template struct ServicesImpl; @@ -399,6 +416,84 @@ struct ServicesImpl : public ServicesImpl +struct ServicesImpl : public ServicesImpl { + ServicesImpl() : pgl_seo(GetPGLObserver(this->objects.pgl)) { + } + + /* and here, we see the magic of this approach- we can represent large + * services changes in separate subclasses */ + + /* ns:dev (1.0.0-9.2.0), pgl (10.0.0+) */ + virtual trn::ResultCode GetShellEventHandle(trn::KEvent *out) { + handle_t evt_h; + auto r = pgl_seo.template SendSyncRequest<0>( // GetProcessEventHandle + ipc::OutHandle(evt_h)); + + if(r == RESULT_OK) { + *out = trn::KEvent(evt_h); + return RESULT_OK; + } else { + return r; + } + } + + virtual trn::ResultCode GetShellEventInfo(std::optional *out) { + uint32_t evt; + uint64_t pid; + + auto r = pgl_seo.template SendSyncRequest<1>( // GetProcessEventInfo + ipc::OutRaw(evt), + ipc::OutRaw(pid)); + + if(r == MAKE_RESULT(228, 2)) { // pgl::ResultNotAvailable + out->reset(); + } else if(r == RESULT_OK) { + *out = hos_types::ShellEventInfo { pid, (hos_types::ShellEventType) evt }; + } else { + return r; + } + return RESULT_OK; + } + + virtual trn::ResultCode LaunchProgram(uint32_t launch_flags, uint64_t title_id, uint32_t storage_id, uint64_t *pid) { + uint32_t pgl_flags = 0; + uint32_t pm_flags = launch_flags; + + struct ProgramLocation { + uint64_t title_id; + uint8_t storage_id; + } loc; + + loc.title_id = title_id; + loc.storage_id = storage_id; + + printf("LaunchProgram via pgl, for 12.0.0+\n"); + + return this->objects.pgl.template SendSyncRequest<0>( // LaunchProgram + ipc::InRaw(loc), + ipc::InRaw(pm_flags), + ipc::InRaw(pgl_flags), // TODO: ugh wtf? this is supposed to be u8 according to SciresM + ipc::OutRaw(*pid)); + } + + virtual trn::ResultCode TerminateProgram(uint64_t pid) { + return this->objects.pgl.template SendSyncRequest<1>( // TerminateProcess + trn::ipc::InRaw(pid)); + } + + tipc::Object pgl_seo; // IShellEventObserver + + protected: + tipc::Object GetPGLObserver(tipc::Object &pgl) { + tipc::Object seo; + twili::Assert( + pgl.SendSyncRequest<20>( + ipc::OutObject(seo))); + return seo; + } +}; + std::unique_ptr Services::CreateForSystemVersion(const SystemVersion &sysver) { if(sysver < SystemVersion(1, 0, 0)) { twili::Abort(TWILI_ERR_OPERATION_NOT_SUPPORTED_FOR_SYSTEM_VERSION); @@ -408,8 +503,10 @@ std::unique_ptr Services::CreateForSystemVersion(const SystemVersion & return std::make_unique>(); } else if(sysver < SystemVersion(10, 0, 0)) { return std::make_unique>(); - } else { + } else if(sysver < SystemVersion(12, 0, 0)) { return std::make_unique>(); + } else { + return std::make_unique>(); } }