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);
template <typename T>
template <typename T, auto MakeShared>
class MitmServer : public IWaitable {
static_assert(std::is_base_of<IMitmServiceObject, T>::value, "MitM Service Objects must derive from IMitmServiceObject");
private:
@ -95,14 +95,21 @@ class MitmServer : public IWaitable {
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;
}
};
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) {
auto *srv = new MitmServer<T>(srv_name, max_sessions);
auto *srv = new MitmServer<T, MakeShared>(srv_name, max_sessions);
manager->AddWaitable(srv);
}

View File

@ -20,7 +20,7 @@
#include "iwaitable.hpp"
#include "ipc.hpp"
template<typename T>
template<typename T, auto MakeShared>
class IServer : public IWaitable {
static_assert(std::is_base_of<IServiceObject, T>::value, "Service Objects must derive from IServiceObject");
protected:
@ -53,33 +53,33 @@ class IServer : public IWaitable {
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;
}
};
template <typename T>
class ServiceServer : public IServer<T> {
template <typename T, auto MakeShared = std::make_shared<T>>
class ServiceServer : public IServer<T, MakeShared> {
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))) {
/* TODO: Panic. */
}
}
};
template <typename T>
class ExistingPortServer : public IServer<T> {
template <typename T, auto MakeShared = std::make_shared<T>>
class ExistingPortServer : public IServer<T, MakeShared> {
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;
}
};
template <typename T>
class ManagedPortServer : public IServer<T> {
template <typename T, auto MakeShared = std::make_shared<T>>
class ManagedPortServer : public IServer<T, MakeShared> {
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))) {
/* TODO: panic */
}