123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #include "LazyServiceFactory.h"
- #include "w5s.h"
- #include "api.h"
- #include <strsafe.h>
- /*
- various implementation notes:
- 1) register for service notifications after registering service, so we can know if our service got loaded indirectly
- */
- LazyServiceFactory::LazyServiceFactory(FOURCC _service_type, GUID _service_guid, char *_service_name, char *_service_test_string, const wchar_t *_service_filename)
- {
- service_type=_service_type;
- service_guid=_service_guid;
- service_name=_service_name;
- service_test_string = _service_test_string;
- StringCbCopyW(service_filename, sizeof(service_filename), _service_filename);
- }
- LazyServiceFactory::~LazyServiceFactory()
- {
- WASABI_API_SVC->service_deregister(this);
- free(service_name);
- free(service_test_string);
- }
- FOURCC LazyServiceFactory::GetServiceType()
- {
- return service_type;
- }
- const char *LazyServiceFactory::GetServiceName()
- {
- return service_name;
- }
- GUID LazyServiceFactory::GetGUID()
- {
- return service_guid;
- }
- void *LazyServiceFactory::GetInterface(int global_lock)
- {
- //load target W5S
- w5s_load(service_filename);
- // ask the service manager remove our service factory and put the new one in our old place (to keep enumeration valid)
- WASABI_API_SVC->service_compactDuplicates(this);
- // call the service manager to get the "real" service which should now (hopefully) be loaded
- waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(service_guid);
- if (sf && sf != this)
- return sf->getInterface();
- return 0;
- }
- int LazyServiceFactory::SupportNonLockingInterface()
- {
- return 1;
- }
- int LazyServiceFactory::ReleaseInterface(void *ifc)
- {
- // someone may have held on to our service factory when they loaded the service
- // so they call us instead of the real service factory
- // so go grab the 'real' service and release through that
- waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(service_guid);
- if (sf && sf != this) // make sure we didn't just grab ourselves :)
- {
- return sf->releaseInterface(ifc);
- }
- return 0;
- }
- const char *LazyServiceFactory::GetTestString()
- {
- return service_test_string;
- }
- int LazyServiceFactory::ServiceNotify(int msg, intptr_t param1, intptr_t param2)
- {
- switch (msg)
- {
- case SvcNotify::ONDEREGISTERED:
- WASABI_API_SYSCB->syscb_deregisterCallback(this);
- break;
- case SvcNotify::ONREGISTERED:
- WASABI_API_SYSCB->syscb_registerCallback(this);
- break;
- }
- return 1;
- }
- int LazyServiceFactory::Notify(int msg, intptr_t param1, intptr_t param2)
- {
- switch (msg)
- {
- case SvcCallback::ONREGISTER:
- {
- waServiceFactory *sf = reinterpret_cast<waServiceFactory*>(param2);
- GUID serviceGUID = sf->getGuid();
- if (sf != this && serviceGUID != INVALID_GUID && serviceGUID == service_guid)
- {
- // real service got loaded, so unregister ourselves
- WASABI_API_SVC->service_compactDuplicates(this);
- }
- }
- break;
- default: return 0;
- }
- return 1;
- }
- #define CBCLASS LazyServiceFactory
- START_MULTIPATCH;
- START_PATCH(ServiceFactoryPatch)
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_GETSERVICETYPE, GetServiceType);
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_GETSERVICENAME, GetServiceName);
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_GETGUID, GetGUID);
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_GETINTERFACE, GetInterface);
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface) ;
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface);
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_GETTESTSTRING, GetTestString);
- M_CB(ServiceFactoryPatch, waServiceFactory, WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify);
- NEXT_PATCH(SysCallbackPatch)
- M_CB(SysCallbackPatch, SysCallback, SYSCALLBACK_GETEVENTTYPE, GetEventType);
- M_CB(SysCallbackPatch, SysCallback, SYSCALLBACK_NOTIFY, Notify);
- END_PATCH
- END_MULTIPATCH;
- #undef CBCLASS
|