#include "main.h" #include "./deviceManager.h" #include "./deviceEventManager.h" static void DeviceManager_ReleaseDispatchables(Dispatchable** buffer, size_t count) { if(NULL == buffer) return; while(count--) { Dispatchable *object = buffer[count]; if (NULL != object) object->Release(); } } DeviceManager::DeviceManager() : ref(1), #pragma warning(push) #pragma warning(disable:4355) typeStore(ObjectAddedCallback, ObjectRemovedCallback, this), connectionStore(ObjectAddedCallback, ObjectRemovedCallback, this), commandStore(ObjectAddedCallback, ObjectRemovedCallback, this), deviceStore(ObjectAddedCallback, ObjectRemovedCallback, this) #pragma warning(pop) { InitializeCriticalSection(&eventLock); InitializeCriticalSection(&providerLock); } DeviceManager::~DeviceManager() { EnterCriticalSection(&providerLock); DeviceManager_ReleaseDispatchables((Dispatchable**)(providerList.size() ? &providerList.at(0) : nullptr), providerList.size()); providerList.clear(); LeaveCriticalSection(&providerLock); DeleteCriticalSection(&providerLock); EnterCriticalSection(&eventLock); DeviceManager_ReleaseDispatchables((Dispatchable**)(eventList.size() ? &eventList.at(0) : nullptr), eventList.size()); eventList.clear(); LeaveCriticalSection(&eventLock); DeleteCriticalSection(&eventLock); } HRESULT DeviceManager::CreateInstance(DeviceManager **instance) { if (NULL == instance) return E_POINTER; *instance = new DeviceManager(); if (NULL == *instance) return E_OUTOFMEMORY; return S_OK; } size_t DeviceManager::AddRef() { return InterlockedIncrement((LONG*)&ref); } size_t DeviceManager::Release() { if (0 == ref) return ref; LONG r = InterlockedDecrement((LONG*)&ref); if (0 == r) delete(this); return r; } int DeviceManager::QueryInterface(GUID interface_guid, void **object) { if (NULL == object) return E_POINTER; if (IsEqualIID(interface_guid, DeviceManagerGUID)) *object = static_cast(this); else { *object = NULL; return E_NOINTERFACE; } if (NULL == *object) return E_UNEXPECTED; AddRef(); return S_OK; } size_t DeviceManager::TypeRegister(ifc_devicetype **types, size_t count) { return typeStore.AddRange((ifc_deviceobject**)types, count); } size_t DeviceManager::TypeRegisterIndirect(const char **names, size_t count, DeviceTypeCreator callback, void *user) { return typeStore.AddIndirect(names, count, (DeviceObjectCreator)callback, user); } HRESULT DeviceManager::TypeUnregister(const char *name) { return typeStore.Remove(name); } HRESULT DeviceManager::TypeFind(const char *name, ifc_devicetype **type) { return typeStore.Find(name, (ifc_deviceobject**)type); } HRESULT DeviceManager::TypeEnumerate(ifc_deviceobjectenum **enumerator) { return typeStore.Enumerate((DeviceObjectEnum**)enumerator); } size_t DeviceManager::ConnectionRegister(ifc_deviceconnection **connections, size_t count) { return connectionStore.AddRange((ifc_deviceobject**)connections, count); } size_t DeviceManager::ConnectionRegisterIndirect(const char **names, size_t count, DeviceConnectionCreator callback, void *user) { return connectionStore.AddIndirect(names, count, (DeviceObjectCreator)callback, user); } HRESULT DeviceManager::ConnectionUnregister(const char *name) { return connectionStore.Remove(name); } HRESULT DeviceManager::ConnectionFind(const char *name, ifc_deviceconnection **connection) { return connectionStore.Find(name, (ifc_deviceobject**)connection); } HRESULT DeviceManager::ConnectionEnumerate(ifc_deviceobjectenum **enumerator) { return connectionStore.Enumerate((DeviceObjectEnum**)enumerator); } size_t DeviceManager::CommandRegister(ifc_devicecommand **commands, size_t count) { return commandStore.AddRange((ifc_deviceobject**)commands, count); } size_t DeviceManager::CommandRegisterIndirect(const char **names, size_t count, DeviceCommandCreator callback, void *user) { return commandStore.AddIndirect(names, count, (DeviceObjectCreator)callback, user); } HRESULT DeviceManager::CommandUnregister(const char *name) { return commandStore.Remove(name); } HRESULT DeviceManager::CommandFind(const char *name, ifc_devicecommand **command) { return commandStore.Find(name, (ifc_deviceobject**)command); } HRESULT DeviceManager::CommandEnumerate(ifc_deviceobjectenum **enumerator) { return commandStore.Enumerate((DeviceObjectEnum**)enumerator); } size_t DeviceManager::DeviceRegister(ifc_device **devices, size_t count) { return deviceStore.AddRange((ifc_deviceobject**)devices, count); } HRESULT DeviceManager::DeviceUnregister(const char *name) { return deviceStore.Remove(name); } HRESULT DeviceManager::DeviceFind(const char *name, ifc_device **device) { return deviceStore.Find(name, (ifc_deviceobject**)device); } HRESULT DeviceManager::DeviceEnumerate(ifc_deviceobjectenum **enumerator) { return deviceStore.Enumerate((DeviceObjectEnum**)enumerator); } HRESULT DeviceManager::IsDiscoveryActive() { return (FALSE != discoveryMonitor.IsActive()) ? S_OK : S_FALSE; } HRESULT DeviceManager::BeginDiscovery() { size_t index, started; EnterCriticalSection(&providerLock); started = 0; index = providerList.size(); while(index--) { if (providerList[index] && SUCCEEDED(providerList[index]->BeginDiscovery((api_devicemanager*)this))) started++; } LeaveCriticalSection(&providerLock); return (0 != started) ? S_OK : E_FAIL; } HRESULT DeviceManager::CancelDiscovery() { size_t index; EnterCriticalSection(&providerLock); index = providerList.size(); while(index--) { providerList[index]->CancelDiscovery(); } LeaveCriticalSection(&providerLock); return S_OK; } HRESULT DeviceManager::SetProviderActive(ifc_deviceprovider *provider, BOOL activeState) { if (FALSE != activeState) { if (FALSE != discoveryMonitor.Register(provider)) EventDiscoveryStarted(); } else { if (FALSE != discoveryMonitor.Unregister(provider)) EventDiscoveryFinished(); } return S_OK; } HRESULT DeviceManager::RegisterProvider(ifc_deviceprovider *provider) { HRESULT hr; size_t index; if (NULL == provider) return E_INVALIDARG; hr = S_OK; EnterCriticalSection(&providerLock); index = providerList.size(); while(index--) { if (provider == providerList[index]) { hr = S_FALSE; break; } } if(S_OK == hr) { providerList.push_back(provider); provider->AddRef(); SetProviderActive(provider, (S_OK == provider->GetActive())); } LeaveCriticalSection(&providerLock); return hr; } HRESULT DeviceManager::UnregisterProvider(ifc_deviceprovider *provider) { HRESULT hr; size_t index; if (NULL == provider) return E_INVALIDARG; hr = S_FALSE; EnterCriticalSection(&providerLock); index = providerList.size(); while(index--) { if (provider == providerList[index]) { ifc_deviceprovider *object; object = providerList[index]; SetProviderActive(object, (S_OK == object->GetActive())); providerList.erase(providerList.begin() + index); object->Release(); hr = S_OK; break; } } LeaveCriticalSection(&providerLock); return hr; } HRESULT DeviceManager::Advise(ifc_devicemanagerevent *handler) { HRESULT hr; size_t index; if (NULL == handler) return E_INVALIDARG; hr = S_OK; EnterCriticalSection(&eventLock); index = eventList.size(); while(index--) { if (handler == eventList[index]) { hr = S_FALSE; break; } } if(S_OK == hr) { eventList.push_back(handler); handler->AddRef(); } LeaveCriticalSection(&eventLock); return hr; } HRESULT DeviceManager::Unadvise(ifc_devicemanagerevent *handler) { HRESULT hr; size_t index; if (NULL == handler) return E_INVALIDARG; hr = S_FALSE; EnterCriticalSection(&eventLock); index = eventList.size(); while(index--) { if (handler == eventList[index]) { ifc_devicemanagerevent *object; object = eventList[index]; eventList.erase(eventList.begin() + index); object->Release(); hr = S_OK; break; } } LeaveCriticalSection(&eventLock); return hr; } HRESULT DeviceManager::CreateDeviceEventManager(ifc_deviceeventmanager **eventManager) { return DeviceEventManager::CreateInstance( reinterpret_cast(eventManager)); } HRESULT DeviceManager::CreateSupportedCommandStore(ifc_devicesupportedcommandstore **store) { return DeviceSupportedCommandStore::CreateInstance( reinterpret_cast(store)); } HRESULT DeviceManager::CreateSupportedCommandEnum(ifc_devicesupportedcommand **commands, size_t count, ifc_devicesupportedcommandenum **enumerator) { return DeviceSupportedCommandEnum::CreateInstance(commands, count, reinterpret_cast(enumerator)); } HRESULT DeviceManager::CreateIconStore(ifc_deviceiconstore **store) { return DeviceIconStore::CreateInstance( reinterpret_cast(store)); } HRESULT DeviceManager::CreateType(const char *name, ifc_devicetype **type) { return DeviceType::CreateInstance(name, reinterpret_cast(type)); } HRESULT DeviceManager::CreateCommand(const char *name, ifc_devicecommand **command) { return DeviceCommand::CreateInstance(name, reinterpret_cast(command)); } HRESULT DeviceManager::CreateConnection(const char *name, ifc_deviceconnection **connection) { return DeviceConnection::CreateInstance(name, reinterpret_cast(connection)); } void DeviceManager::ObjectAddedCallback(DeviceObjectStore *store, ifc_deviceobject *object, void *userData) { DeviceManager *manager; manager = (DeviceManager*)userData; if (NULL == manager) return; if (store == &manager->typeStore) manager->EventTypeAdded((ifc_devicetype*)object); else if (store == &manager->connectionStore) manager->EventConnectionAdded((ifc_deviceconnection*)object); else if (store == &manager->commandStore) manager->EventCommandAdded((ifc_devicecommand*)object); else if (store == &manager->deviceStore) manager->EventDeviceAdded((ifc_device*)object); } void DeviceManager::ObjectRemovedCallback(DeviceObjectStore *store, ifc_deviceobject *object, void *userData) { DeviceManager *manager; manager = (DeviceManager*)userData; if (NULL == manager) return; if (store == &manager->typeStore) manager->EventTypeRemoved((ifc_devicetype*)object); else if (store == &manager->connectionStore) manager->EventConnectionRemoved((ifc_deviceconnection*)object); else if (store == &manager->commandStore) manager->EventCommandRemoved((ifc_devicecommand*)object); else if (store == &manager->deviceStore) manager->EventDeviceRemoved((ifc_device*)object); } void DeviceManager::EventTypeAdded(ifc_devicetype *type) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->TypeAdded((api_devicemanager*)this, type); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventTypeRemoved(ifc_devicetype *type) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->TypeRemoved((api_devicemanager*)this, type); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventConnectionAdded(ifc_deviceconnection *connection) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->ConnectionAdded((api_devicemanager*)this, connection); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventConnectionRemoved(ifc_deviceconnection *connection) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->ConnectionRemoved((api_devicemanager*)this, connection); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventCommandAdded(ifc_devicecommand *command) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->CommandAdded((api_devicemanager*)this, command); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventCommandRemoved(ifc_devicecommand *command) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->CommandRemoved((api_devicemanager*)this, command); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventDeviceAdded(ifc_device *device) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->DeviceAdded((api_devicemanager*)this, device); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventDeviceRemoved(ifc_device *device) { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->DeviceRemoved((api_devicemanager*)this, device); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventDiscoveryStarted() { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->DiscoveryStarted((api_devicemanager*)this); } LeaveCriticalSection(&eventLock); } void DeviceManager::EventDiscoveryFinished() { EnterCriticalSection(&eventLock); size_t index = eventList.size(); while(index--) { ifc_devicemanagerevent *handler = eventList[index]; handler->DiscoveryFinished((api_devicemanager*)this); } LeaveCriticalSection(&eventLock); } #define CBCLASS DeviceManager START_DISPATCH; CB(ADDREF, AddRef) CB(RELEASE, Release) CB(QUERYINTERFACE, QueryInterface) CB(API_TYPEREGISTER, TypeRegister) CB(API_TYPEREGISTERINDIRECT, TypeRegisterIndirect) CB(API_TYPEUNREGISTER, TypeUnregister) CB(API_TYPEFIND, TypeFind) CB(API_TYPEENUMERATE, TypeEnumerate) CB(API_CONNECTIONREGISTER, ConnectionRegister) CB(API_CONNECTIONREGISTERINDIRECT, ConnectionRegisterIndirect) CB(API_CONNECTIONUNREGISTER, ConnectionUnregister) CB(API_CONNECTIONFIND, ConnectionFind) CB(API_CONNECTIONENUMERATE, ConnectionEnumerate) CB(API_COMMANDREGISTER, CommandRegister) CB(API_COMMANDREGISTERINDIRECT, CommandRegisterIndirect) CB(API_COMMANDUNREGISTER, CommandUnregister) CB(API_COMMANDFIND, CommandFind) CB(API_COMMANDENUMERATE, CommandEnumerate) CB(API_DEVICEREGISTER, DeviceRegister) CB(API_DEVICEUNREGISTER, DeviceUnregister) CB(API_DEVICEFIND, DeviceFind) CB(API_DEVICEENUMERATE, DeviceEnumerate) CB(API_ISDISCOVERYACTIVE, IsDiscoveryActive) CB(API_BEGINDISCOVERY, BeginDiscovery) CB(API_CANCELDISCOVERY, CancelDiscovery) CB(API_REGISTERPROVIDER, RegisterProvider) CB(API_UNREGISTERPROVIDER, UnregisterProvider) CB(API_SETPROVIDERACTIVE, SetProviderActive) CB(API_ADVISE, Advise) CB(API_UNADVISE, Unadvise) CB(API_CREATEDEVICEEVENTMANAGER, CreateDeviceEventManager) CB(API_CREATESUPPORTEDCOMMANDSTORE, CreateSupportedCommandStore) CB(API_CREATESUPPORTEDCOMMANDENUM, CreateSupportedCommandEnum) CB(API_CREATEICONSTORE, CreateIconStore) CB(API_CREATETYPE, CreateType) CB(API_CREATECOMMAND, CreateCommand) CB(API_CREATECONNECTION, CreateConnection) END_DISPATCH; #undef CBCLASS