libstrat: support arbitrary service object constructors

This commit is contained in:
Michael Scire 2019-04-20 16:17:24 -07:00
parent 163d9259a3
commit 016f2ecb25
2 changed files with 22 additions and 15 deletions

View File

@ -23,7 +23,7 @@
void RegisterMitmServerQueryHandle(Handle query_h, ServiceObjectHolder &&service); void RegisterMitmServerQueryHandle(Handle query_h, ServiceObjectHolder &&service);
template <typename T> template <typename T, auto MakeShared>
class MitmServer : public IWaitable { class MitmServer : public IWaitable {
static_assert(std::is_base_of<IMitmServiceObject, T>::value, "MitM Service Objects must derive from IMitmServiceObject"); static_assert(std::is_base_of<IMitmServiceObject, T>::value, "MitM Service Objects must derive from IMitmServiceObject");
private: private:
@ -76,7 +76,7 @@ class MitmServer : public IWaitable {
} }
/* Create a forward service for this instance. */ /* Create a forward service for this instance. */
std::shared_ptr<Service>forward_service(new Service(), [](Service *s) { std::shared_ptr<Service> forward_service(new Service(), [](Service *s) {
/* Custom deleter to ensure service is open as long as necessary. */ /* Custom deleter to ensure service is open as long as necessary. */
serviceClose(s); serviceClose(s);
delete s; delete s;
@ -95,14 +95,21 @@ class MitmServer : public IWaitable {
smMitMExit(); smMitMExit();
this->GetSessionManager()->AddWaitable(new MitmSession(session_h, client_pid, forward_service, std::make_shared<T>(forward_service, client_pid))); this->GetSessionManager()->AddWaitable(new MitmSession(session_h, client_pid, forward_service, MakeShared(forward_service, client_pid)));
return ResultSuccess; return ResultSuccess;
} }
}; };
template<typename T> template<typename T>
struct MakeSharedMitmHelper {
static constexpr std::shared_ptr<T> Make(std::shared_ptr<Service> forward_srv, u64 client_pid) {
return std::make_shared<T>(forward_srv, client_pid);
}
};
template<typename T, auto MakeShared = MakeSharedMitmHelper<T>::Make>
static void AddMitmServerToManager(SessionManagerBase *manager, const char *srv_name, unsigned int max_sessions) { static void AddMitmServerToManager(SessionManagerBase *manager, const char *srv_name, unsigned int max_sessions) {
auto *srv = new MitmServer<T>(srv_name, max_sessions); auto *srv = new MitmServer<T, MakeShared>(srv_name, max_sessions);
manager->AddWaitable(srv); manager->AddWaitable(srv);
} }

View File

@ -20,7 +20,7 @@
#include "iwaitable.hpp" #include "iwaitable.hpp"
#include "ipc.hpp" #include "ipc.hpp"
template<typename T> template<typename T, auto MakeShared>
class IServer : public IWaitable { class IServer : public IWaitable {
static_assert(std::is_base_of<IServiceObject, T>::value, "Service Objects must derive from IServiceObject"); static_assert(std::is_base_of<IServiceObject, T>::value, "Service Objects must derive from IServiceObject");
protected: protected:
@ -53,33 +53,33 @@ class IServer : public IWaitable {
return rc; return rc;
} }
this->GetSessionManager()->AddSession(session_h, std::move(ServiceObjectHolder(std::move(std::make_shared<T>())))); this->GetSessionManager()->AddSession(session_h, std::move(ServiceObjectHolder(std::move(MakeShared()))));
return ResultSuccess; return ResultSuccess;
} }
}; };
template <typename T> template <typename T, auto MakeShared = std::make_shared<T>>
class ServiceServer : public IServer<T> { class ServiceServer : public IServer<T, MakeShared> {
public: public:
ServiceServer(const char *service_name, unsigned int max_s) : IServer<T>(max_s) { ServiceServer(const char *service_name, unsigned int max_s) : IServer<T, MakeShared>(max_s) {
if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) { if (R_FAILED(smRegisterService(&this->port_handle, service_name, false, this->max_sessions))) {
/* TODO: Panic. */ /* TODO: Panic. */
} }
} }
}; };
template <typename T> template <typename T, auto MakeShared = std::make_shared<T>>
class ExistingPortServer : public IServer<T> { class ExistingPortServer : public IServer<T, MakeShared> {
public: public:
ExistingPortServer(Handle port_h, unsigned int max_s) : IServer<T>(max_s) { ExistingPortServer(Handle port_h, unsigned int max_s) : IServer<T, MakeShared>(max_s) {
this->port_handle = port_h; this->port_handle = port_h;
} }
}; };
template <typename T> template <typename T, auto MakeShared = std::make_shared<T>>
class ManagedPortServer : public IServer<T> { class ManagedPortServer : public IServer<T, MakeShared> {
public: public:
ManagedPortServer(const char *service_name, unsigned int max_s) : IServer<T>(max_s) { ManagedPortServer(const char *service_name, unsigned int max_s) : IServer<T, MakeShared>(max_s) {
if (R_FAILED(svcManageNamedPort(&this->port_handle, service_name, this->max_sessions))) { if (R_FAILED(svcManageNamedPort(&this->port_handle, service_name, this->max_sessions))) {
/* TODO: panic */ /* TODO: panic */
} }