diff options
Diffstat (limited to 'Src/devices')
61 files changed, 7145 insertions, 0 deletions
diff --git a/Src/devices/api_devicemanager.h b/Src/devices/api_devicemanager.h new file mode 100644 index 00000000..13eaac0e --- /dev/null +++ b/Src/devices/api_devicemanager.h @@ -0,0 +1,305 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {CB360A8F-0636-4a0d-9374-3BBCC18C8B40} +static const GUID DeviceManagerGUID = +{ 0xcb360a8f, 0x636, 0x4a0d, { 0x93, 0x74, 0x3b, 0xbc, 0xc1, 0x8c, 0x8b, 0x40 } }; + + +#include <bfc/dispatch.h> +#include "ifc_device.h" +#include "ifc_deviceobjectenum.h" +#include "ifc_devicetype.h" +#include "ifc_devicetypeeditor.h" +#include "ifc_devicecommand.h" +#include "ifc_devicecommandeditor.h" +#include "ifc_deviceconnection.h" +#include "ifc_deviceconnectioneditor.h" +#include "ifc_devicemanagerevent.h" +#include "ifc_deviceprovider.h" +#include "ifc_deviceeventmanager.h" +#include "ifc_devicesupportedcommand.h" +#include "ifc_devicesupportedcommandstore.h" +#include "ifc_devicesupportedcommandenum.h" +#include "ifc_deviceiconstore.h" +#include "ifc_deviceactivity.h" + +typedef ifc_devicetype *(_cdecl *DeviceTypeCreator)(const char * /*name*/, void * /*user*/); +typedef ifc_devicecommand *(_cdecl *DeviceCommandCreator)(const char * /*name*/, void * /*user*/); +typedef ifc_deviceconnection *(_cdecl *DeviceConnectionCreator)(const char * /*name*/, void * /*user*/); + + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) api_devicemanager : public Dispatchable +{ +protected: + api_devicemanager() {} + ~api_devicemanager() {} + +public: + + /* types */ + size_t TypeRegister(ifc_devicetype **types, size_t count); // return number of registered types + size_t TypeRegisterIndirect(const char **names, size_t count, DeviceTypeCreator callback, void *user); + HRESULT TypeUnregister(const char *name); + HRESULT TypeFind(const char *name, ifc_devicetype **type); + HRESULT TypeEnumerate(ifc_deviceobjectenum **enumerator); + + /* connections */ + size_t ConnectionRegister(ifc_deviceconnection **connections, size_t count); + size_t ConnectionRegisterIndirect(const char **names, size_t count, DeviceConnectionCreator callback, void *user); + HRESULT ConnectionUnregister(const char *name); + HRESULT ConnectionFind(const char *name, ifc_deviceconnection **connection); + HRESULT ConnectionEnumerate(ifc_deviceobjectenum **enumerator); + + /* commmands */ + size_t CommandRegister(ifc_devicecommand **commands, size_t count); + size_t CommandRegisterIndirect(const char **names, size_t count, DeviceCommandCreator callback, void *user); + HRESULT CommandUnregister(const char *name); + HRESULT CommandFind(const char *name, ifc_devicecommand **command); + HRESULT CommandEnumerate(ifc_deviceobjectenum **enumerator); + + /* devices */ + size_t DeviceRegister(ifc_device **devices, size_t count); + HRESULT DeviceUnregister(const char *name); + HRESULT DeviceFind(const char *name, ifc_device **device); + HRESULT DeviceEnumerate(ifc_deviceobjectenum **enumerator); + + /* discovery */ + HRESULT IsDiscoveryActive(); + HRESULT BeginDiscovery(); + HRESULT CancelDiscovery(); + HRESULT RegisterProvider(ifc_deviceprovider *provider); + HRESULT UnregisterProvider(ifc_deviceprovider *provider); + HRESULT SetProviderActive(ifc_deviceprovider *provider, BOOL activeState); + + /* events */ + HRESULT Advise(ifc_devicemanagerevent *handler); + HRESULT Unadvise(ifc_devicemanagerevent *handler); + + /* misc helpers */ + HRESULT CreateDeviceEventManager(ifc_deviceeventmanager **eventManager); + HRESULT CreateSupportedCommandStore(ifc_devicesupportedcommandstore **store); + HRESULT CreateSupportedCommandEnum(ifc_devicesupportedcommand **commands, size_t count, ifc_devicesupportedcommandenum **enumerator); + HRESULT CreateIconStore(ifc_deviceiconstore **store); + HRESULT CreateType(const char *name, ifc_devicetype **type); + HRESULT CreateCommand(const char *name, ifc_devicecommand **command); + HRESULT CreateConnection(const char *name, ifc_deviceconnection **connection); + +public: + DISPATCH_CODES + { + API_TYPEREGISTER = 10, + API_TYPEREGISTERINDIRECT = 20, + API_TYPEUNREGISTER = 30, + API_TYPEFIND = 40, + API_TYPEENUMERATE = 50, + API_CONNECTIONREGISTER = 60, + API_CONNECTIONREGISTERINDIRECT = 70, + API_CONNECTIONUNREGISTER = 80, + API_CONNECTIONFIND = 90, + API_CONNECTIONENUMERATE = 100, + API_COMMANDREGISTER = 110, + API_COMMANDREGISTERINDIRECT = 120, + API_COMMANDUNREGISTER = 130, + API_COMMANDFIND = 140, + API_COMMANDENUMERATE = 150, + API_DEVICEREGISTER = 160, + API_DEVICEUNREGISTER = 170, + API_DEVICEFIND = 180, + API_DEVICEENUMERATE = 190, + API_ISDISCOVERYACTIVE = 200, + API_BEGINDISCOVERY = 210, + API_CANCELDISCOVERY = 220, + API_REGISTERPROVIDER = 230, + API_UNREGISTERPROVIDER = 240, + API_SETPROVIDERACTIVE = 250, + API_ADVISE = 260, + API_UNADVISE = 270, + API_CREATEDEVICEEVENTMANAGER = 400, + API_CREATESUPPORTEDCOMMANDSTORE = 410, + API_CREATESUPPORTEDCOMMANDENUM = 420, + API_CREATEICONSTORE = 430, + API_CREATETYPE = 440, + API_CREATECOMMAND = 450, + API_CREATECONNECTION = 460, + }; +}; + +inline size_t api_devicemanager::TypeRegister(ifc_devicetype **types, size_t count) +{ + return _call(API_TYPEREGISTER, (size_t)0, types, count); +} + +inline size_t api_devicemanager::TypeRegisterIndirect(const char **names, size_t count, DeviceTypeCreator callback, void *user) +{ + return _call(API_TYPEREGISTERINDIRECT, (size_t)0, names, count, callback, user); +} + +inline HRESULT api_devicemanager::TypeUnregister(const char *name) +{ + return _call(API_TYPEUNREGISTER, (HRESULT)E_NOTIMPL, name); +} + +inline HRESULT api_devicemanager::TypeFind(const char *name, ifc_devicetype **type) +{ + return _call(API_TYPEFIND, (HRESULT)E_NOTIMPL, name, type); +} + +inline HRESULT api_devicemanager::TypeEnumerate(ifc_deviceobjectenum **enumerator) +{ + return _call(API_TYPEENUMERATE, (HRESULT)E_NOTIMPL, enumerator); +} + +inline size_t api_devicemanager::ConnectionRegister(ifc_deviceconnection **connections, size_t count) +{ + return _call(API_CONNECTIONREGISTER, (size_t)0, connections, count); +} + +inline size_t api_devicemanager::ConnectionRegisterIndirect(const char **names, size_t count, DeviceConnectionCreator callback, void *user) +{ + return _call(API_CONNECTIONREGISTERINDIRECT, (size_t)0, names, count, callback, user); +} + +inline HRESULT api_devicemanager::ConnectionUnregister(const char *name) +{ + return _call(API_CONNECTIONUNREGISTER, (HRESULT)E_NOTIMPL, name); +} + +inline HRESULT api_devicemanager::ConnectionFind(const char *name, ifc_deviceconnection **connection) +{ + return _call(API_CONNECTIONFIND, (HRESULT)E_NOTIMPL, name, connection); +} + +inline HRESULT api_devicemanager::ConnectionEnumerate(ifc_deviceobjectenum **enumerator) +{ + return _call(API_CONNECTIONENUMERATE, (HRESULT)E_NOTIMPL, enumerator); +} + +inline size_t api_devicemanager::CommandRegister(ifc_devicecommand **commands, size_t count) +{ + return _call(API_COMMANDREGISTER, (size_t)0, commands, count); +} + +inline size_t api_devicemanager::CommandRegisterIndirect(const char **names, size_t count, DeviceCommandCreator callback, void *user) +{ + return _call(API_COMMANDREGISTERINDIRECT, (size_t)0, names, count, callback, user); +} + +inline HRESULT api_devicemanager::CommandUnregister(const char *name) +{ + return _call(API_COMMANDUNREGISTER, (HRESULT)E_NOTIMPL, name); +} + +inline HRESULT api_devicemanager::CommandFind(const char *name, ifc_devicecommand **command) +{ + return _call(API_COMMANDFIND, (HRESULT)E_NOTIMPL, name, command); +} + +inline HRESULT api_devicemanager::CommandEnumerate(ifc_deviceobjectenum **enumerator) +{ + return _call(API_COMMANDENUMERATE, (HRESULT)E_NOTIMPL, enumerator); +} + +inline size_t api_devicemanager::DeviceRegister(ifc_device **devices, size_t count) +{ + return _call(API_DEVICEREGISTER, (size_t)0, devices, count); +} + +inline HRESULT api_devicemanager::DeviceUnregister(const char *name) +{ + return _call(API_DEVICEUNREGISTER, (HRESULT)E_NOTIMPL, name); +} + +inline HRESULT api_devicemanager::DeviceFind(const char *name, ifc_device **device) +{ + return _call(API_DEVICEFIND, (HRESULT)E_NOTIMPL, name, device); +} + +inline HRESULT api_devicemanager::DeviceEnumerate(ifc_deviceobjectenum **enumerator) +{ + return _call(API_DEVICEENUMERATE, (HRESULT)E_NOTIMPL, enumerator); +} + +inline HRESULT api_devicemanager::IsDiscoveryActive() +{ + return _call(API_ISDISCOVERYACTIVE, (HRESULT)E_NOTIMPL); +} + +inline HRESULT api_devicemanager::BeginDiscovery() +{ + return _call(API_BEGINDISCOVERY, (HRESULT)E_NOTIMPL); +} + +inline HRESULT api_devicemanager::CancelDiscovery() +{ + return _call(API_CANCELDISCOVERY, (HRESULT)E_NOTIMPL); +} + +inline HRESULT api_devicemanager::RegisterProvider(ifc_deviceprovider *provider) +{ + return _call(API_REGISTERPROVIDER, (HRESULT)E_NOTIMPL, provider); +} + +inline HRESULT api_devicemanager::UnregisterProvider(ifc_deviceprovider *provider) +{ + return _call(API_UNREGISTERPROVIDER, (HRESULT)E_NOTIMPL, provider); +} + +inline HRESULT api_devicemanager::SetProviderActive(ifc_deviceprovider *provider, BOOL activeState) +{ + return _call(API_SETPROVIDERACTIVE, (HRESULT)E_NOTIMPL, provider, activeState); +} + +inline HRESULT api_devicemanager::Advise(ifc_devicemanagerevent *handler) +{ + return _call(API_ADVISE, (HRESULT)E_NOTIMPL, handler); +} + +inline HRESULT api_devicemanager::Unadvise(ifc_devicemanagerevent *handler) +{ + return _call(API_UNADVISE, (HRESULT)E_NOTIMPL, handler); +} + +inline HRESULT api_devicemanager::CreateDeviceEventManager(ifc_deviceeventmanager **eventManager) +{ + return _call(API_CREATEDEVICEEVENTMANAGER, (HRESULT)E_NOTIMPL, eventManager); +} + +inline HRESULT api_devicemanager::CreateSupportedCommandStore(ifc_devicesupportedcommandstore **store) +{ + return _call(API_CREATESUPPORTEDCOMMANDSTORE, (HRESULT)E_NOTIMPL, store); +} + +inline HRESULT api_devicemanager::CreateSupportedCommandEnum(ifc_devicesupportedcommand **commands, size_t count, ifc_devicesupportedcommandenum **enumerator) +{ + return _call(API_CREATESUPPORTEDCOMMANDENUM, (HRESULT)E_NOTIMPL, commands, count, enumerator); +} + +inline HRESULT api_devicemanager::CreateIconStore(ifc_deviceiconstore **store) +{ + return _call(API_CREATEICONSTORE, (HRESULT)E_NOTIMPL, store); +} + +inline HRESULT api_devicemanager::CreateType(const char *name, ifc_devicetype **type) +{ + return _call(API_CREATETYPE, (HRESULT)E_NOTIMPL, name, type); +} + +inline HRESULT api_devicemanager::CreateCommand(const char *name, ifc_devicecommand **command) +{ + return _call(API_CREATECOMMAND, (HRESULT)E_NOTIMPL, name, command); +} + +inline HRESULT api_devicemanager::CreateConnection(const char *name, ifc_deviceconnection **connection) +{ + return _call(API_CREATECONNECTION, (HRESULT)E_NOTIMPL, name, connection); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/common.h b/Src/devices/common.h new file mode 100644 index 00000000..d1d8f19c --- /dev/null +++ b/Src/devices/common.h @@ -0,0 +1,76 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_COMMON_HEADER +#define _NULLSOFT_WINAMP_DEVICES_COMMON_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef LONGX86 +#ifdef _WIN64 + #define LONGX86 LONG_PTR +#else /*_WIN64*/ + #define LONGX86 LONG +#endif /*_WIN64*/ +#endif // LONGX86 + +#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) + +#ifdef __cplusplus + #define SENDMSG(__hwnd, __msgId, __wParam, __lParam) ::SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam)) +#else + #define SENDMSG(__hwnd, __msgId, __wParam, __lParam) SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam)) +#endif // __cplusplus + +#define SENDMLIPC(__hwndML, __ipcMsgId, __param) SENDMSG((__hwndML), WM_ML_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId)) + +#define SENDWAIPC(__hwndWA, __ipcMsgId, __param) SENDMSG((__hwndWA), WM_WA_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId)) + +#define SENDCMD(__hwnd, __ctrlId, __eventId, __hctrl) (SENDMSG((__hwnd), WM_COMMAND, MAKEWPARAM(__ctrlId, __eventId), (LPARAM)(__hctrl))) + +#define DIALOG_RESULT(__hwnd, __result) { SetWindowLongPtrW((__hwnd), DWLP_MSGRESULT, ((LONGX86)(LONG_PTR)(__result))); return TRUE; } + +#ifndef GetWindowStyle + #define GetWindowStyle(__hwnd) ((UINT)GetWindowLongPtr((__hwnd), GWL_STYLE)) +#endif //GetWindowStyle + +#ifndef SetWindowStyle + #define SetWindowStyle(__hwnd, __style) (SetWindowLongPtr((__hwnd), GWL_STYLE, (__style))) +#endif //SetWindowStyle + +#ifndef GetWindowStyleEx + #define GetWindowStyleEx(__hwnd) ((UINT)GetWindowLongPtr((__hwnd), GWL_EXSTYLE)) +#endif // GetWindowStyleEx + +#ifndef SetWindowStyleEx + #define SetWindowStyleEx(__hwnd, __style) (SetWindowLongPtr((__hwnd), GWL_EXSTYLE, (__style))) +#endif //SetWindowStyle + +#ifndef RECTWIDTH + #define RECTWIDTH(__r) ((__r).right - (__r).left) +#endif + +#ifndef RECTHEIGHT + #define RECTHEIGHT(__r) ((__r).bottom - (__r).top) +#endif + +#undef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +#ifndef ARRAYSIZE + #define ARRAYSIZE(_a) (sizeof(_a)/sizeof((_a)[0])) +#endif + +#ifndef ABS + #define ABS(x) (((x) > 0) ? (x) : (-x)) +#endif + +#ifndef MIN + #define MIN(v1, v2) (((v1) < (v2)) ? (v1) : (v2)) +#endif + +#ifndef MAX + #define MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2)) +#endif + + +#endif //_NULLSOFT_WINAMP_DEVICES_COMMON_HEADER diff --git a/Src/devices/component.cpp b/Src/devices/component.cpp new file mode 100644 index 00000000..3f4bd8fe --- /dev/null +++ b/Src/devices/component.cpp @@ -0,0 +1,84 @@ +#include "main.h" +#include "./component.h" +#include "./deviceManagerFactory.h" + +static DeviceManagerFactory deviceManagerFactory; + +DevicesComponent::DevicesComponent() +{ + InitializeCriticalSection(&lock); +} + +DevicesComponent::~DevicesComponent() +{ + EnterCriticalSection(&lock); + + ReleaseServices(); + + LeaveCriticalSection(&lock); + + DeleteCriticalSection(&lock); +} + +size_t DevicesComponent::AddRef() +{ + return 1; +} + +size_t DevicesComponent::Release() +{ + return 1; +} + +int DevicesComponent::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) + return E_POINTER; + + *object = NULL; + return E_NOINTERFACE; +} + +void DevicesComponent::RegisterServices(api_service *service) +{ + EnterCriticalSection(&lock); + + deviceManagerFactory.Register(service); + + LeaveCriticalSection(&lock); + + aTRACE_LINE("Devices Service Registered"); +} + +int DevicesComponent::RegisterServicesSafeModeOk() +{ + return 1; +} + +void DevicesComponent::DeregisterServices(api_service *service) +{ + EnterCriticalSection(&lock); + + deviceManagerFactory.Unregister(service); + + ReleaseServices(); + + LeaveCriticalSection(&lock); + + aTRACE_LINE("Devices Service Unregistered"); +} + +void DevicesComponent::ReleaseServices() +{ +} + +#define CBCLASS DevicesComponent +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices) +CB(15, RegisterServicesSafeModeOk) +VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/devices/component.h b/Src/devices/component.h new file mode 100644 index 00000000..7d1babe2 --- /dev/null +++ b/Src/devices/component.h @@ -0,0 +1,39 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_COMPONENT_HEADER +#define _NULLSOFT_WINAMP_DEVICES_COMPONENT_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <wtypes.h> +#include "../Agave/Component/ifc_wa5component.h" + +class DevicesComponent : public ifc_wa5component +{ +public: + DevicesComponent(); + ~DevicesComponent(); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_wa5component */ + void RegisterServices(api_service *service); + int RegisterServicesSafeModeOk(); + void DeregisterServices(api_service *service); + +protected: + void ReleaseServices(void); + +protected: + RECVS_DISPATCH; + +private: + CRITICAL_SECTION lock; +}; + + +#endif //_NULLSOFT_WINAMP_DEVICES_COMPONENT_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceCommand.cpp b/Src/devices/deviceCommand.cpp new file mode 100644 index 00000000..b41d198d --- /dev/null +++ b/Src/devices/deviceCommand.cpp @@ -0,0 +1,239 @@ +#include "main.h" +#include "./deviceCommand.h" + +#include <strsafe.h> + +DeviceCommand::DeviceCommand() + : ref(1), name(NULL), displayName(NULL), description(NULL) +{ + if (FAILED(DeviceIconStore::CreateInstance(&iconStore))) + iconStore = NULL; + + InitializeCriticalSection(&lock); +} + +DeviceCommand::~DeviceCommand() +{ + AnsiString_Free(name); + String_Free(displayName); + String_Free(description); + + if (NULL != iconStore) + iconStore->Release(); + + DeleteCriticalSection(&lock); +} + +HRESULT DeviceCommand::CreateInstance(const char *name, DeviceCommand **instance) +{ + char *nameCopy; + + if (NULL == instance) + return E_POINTER; + + if (FALSE != IS_STRING_EMPTY(name)) + return E_INVALIDARG; + + *instance = new DeviceCommand(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + nameCopy = AnsiString_Duplicate(name); + if (NULL == nameCopy) + { + (*instance)->Release(); + return E_OUTOFMEMORY; + } + + (*instance)->name = nameCopy; + + return S_OK; +} + +size_t DeviceCommand::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceCommand::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceCommand::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceCommand)) + *object = static_cast<ifc_devicecommand*>(this); + else if (IsEqualIID(interface_guid, IFC_DeviceCommandEditor)) + *object = static_cast<ifc_devicecommandeditor*>(this); + else if (IsEqualIID(interface_guid, IFC_DeviceObject)) + *object = static_cast<ifc_deviceobject*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +void DeviceCommand::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceCommand::Unlock() +{ + LeaveCriticalSection(&lock); +} + +const char *DeviceCommand::GetName() +{ + return name; +} + +HRESULT DeviceCommand::GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + if (NULL == iconStore) + hr = E_UNEXPECTED; + else + hr = iconStore->Get(buffer, bufferSize, width, height); + + Unlock(); + + return hr; +} + +HRESULT DeviceCommand::GetDisplayName(wchar_t *buffer, size_t bufferSize) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + hr = StringCchCopyExW(buffer, bufferSize, displayName, NULL, NULL, STRSAFE_IGNORE_NULLS); + + Unlock(); + + return hr; +} + +HRESULT DeviceCommand::GetDescription(wchar_t *buffer, size_t bufferSize) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + hr = StringCchCopyExW(buffer, bufferSize, description, NULL, NULL, STRSAFE_IGNORE_NULLS); + + Unlock(); + + return hr; +} + +HRESULT DeviceCommand::GetIconStore(ifc_deviceiconstore **store) +{ + HRESULT hr; + + if (NULL == store) + return E_POINTER; + + Lock(); + + if (NULL == iconStore) + hr = E_UNEXPECTED; + else + { + iconStore->AddRef(); + *store = iconStore; + hr = S_OK; + } + + Unlock(); + + return hr; +} + +HRESULT DeviceCommand::SetDisplayName(const wchar_t *displayName) +{ + HRESULT hr; + + Lock(); + + String_Free(this->displayName); + this->displayName = String_Duplicate(displayName); + + if (NULL == this->displayName && NULL != displayName) + hr = E_OUTOFMEMORY; + else + hr = S_OK; + + Unlock(); + + return hr; +} + +HRESULT DeviceCommand::SetDescription(const wchar_t *description) +{ + HRESULT hr; + + Lock(); + + String_Free(this->description); + this->description = String_Duplicate(description); + + if (NULL == this->description && NULL != description) + hr = E_OUTOFMEMORY; + else + hr = S_OK; + + Unlock(); + + return hr; +} + +#define CBCLASS DeviceCommand +START_MULTIPATCH; + START_PATCH(MPIID_DEVICECOMMAND) + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, ADDREF, AddRef); + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, RELEASE, Release); + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, API_GETNAME, GetName); + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, API_GETICON, GetIcon); + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, API_GETDISPLAYNAME, GetDisplayName); + M_CB(MPIID_DEVICECOMMAND, ifc_devicecommand, API_GETDESCRIPTION, GetDescription); + NEXT_PATCH(MPIID_DEVICECOMMANDEDITOR) + M_CB(MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor, ADDREF, AddRef); + M_CB(MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor, RELEASE, Release); + M_CB(MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor, API_SETDISPLAYNAME, SetDisplayName); + M_CB(MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor, API_SETDESCRIPTION, SetDescription); + M_CB(MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor, API_GETICONSTORE, GetIconStore); + END_PATCH +END_MULTIPATCH; diff --git a/Src/devices/deviceCommand.h b/Src/devices/deviceCommand.h new file mode 100644 index 00000000..60b9ee70 --- /dev/null +++ b/Src/devices/deviceCommand.h @@ -0,0 +1,64 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_devicecommand.h" +#include "./ifc_devicecommandeditor.h" +#include "./ifc_deviceiconstore.h" +#include "./deviceIconStore.h" + +#include <bfc/multipatch.h> + +#define MPIID_DEVICECOMMAND 10 +#define MPIID_DEVICECOMMANDEDITOR 20 + + +class DeviceCommand : public MultiPatch<MPIID_DEVICECOMMAND, ifc_devicecommand>, + public MultiPatch<MPIID_DEVICECOMMANDEDITOR, ifc_devicecommandeditor> +{ + +protected: + DeviceCommand(); + ~DeviceCommand(); + +public: + static HRESULT CreateInstance(const char *name, DeviceCommand **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_devicecommand */ + const char *GetName(); + HRESULT GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height); + HRESULT GetDisplayName(wchar_t *buffer, size_t bufferSize); + HRESULT GetDescription(wchar_t *buffer, size_t bufferSize); + + /* ifc_devicetypeeditor */ + HRESULT GetIconStore(ifc_deviceiconstore **store); + HRESULT SetDisplayName(const wchar_t *displayName); + HRESULT SetDescription(const wchar_t *description); + +public: + void Lock(); + void Unlock(); + + +protected: + size_t ref; + char *name; + wchar_t *displayName; + wchar_t *description; + DeviceIconStore *iconStore; + CRITICAL_SECTION lock; + +protected: + RECVS_MULTIPATCH; +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_HEADER diff --git a/Src/devices/deviceConnection.cpp b/Src/devices/deviceConnection.cpp new file mode 100644 index 00000000..b8d6697a --- /dev/null +++ b/Src/devices/deviceConnection.cpp @@ -0,0 +1,200 @@ +#include "main.h" +#include "./deviceConnection.h" + +#include <strsafe.h> + +DeviceConnection::DeviceConnection() + : ref(1), name(NULL), displayName(NULL) +{ + if (FAILED(DeviceIconStore::CreateInstance(&iconStore))) + iconStore = NULL; + + InitializeCriticalSection(&lock); +} + +DeviceConnection::~DeviceConnection() +{ + AnsiString_Free(name); + String_Free(displayName); + if (NULL != iconStore) + iconStore->Release(); + + DeleteCriticalSection(&lock); +} + +HRESULT DeviceConnection::CreateInstance(const char *name, DeviceConnection **instance) +{ + char *nameCopy; + + if (NULL == instance) + return E_POINTER; + + if (FALSE != IS_STRING_EMPTY(name)) + return E_INVALIDARG; + + *instance = new DeviceConnection(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + nameCopy = AnsiString_Duplicate(name); + if (NULL == nameCopy) + { + (*instance)->Release(); + return E_OUTOFMEMORY; + } + + (*instance)->name = nameCopy; + + return S_OK; +} + +size_t DeviceConnection::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceConnection::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceConnection::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceConnection)) + *object = static_cast<ifc_deviceconnection*>(this); + else if (IsEqualIID(interface_guid, IFC_DeviceConnectionEditor)) + *object = static_cast<ifc_deviceconnectioneditor*>(this); + else if (IsEqualIID(interface_guid, IFC_DeviceObject)) + *object = static_cast<ifc_deviceobject*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +void DeviceConnection::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceConnection::Unlock() +{ + LeaveCriticalSection(&lock); +} + +const char *DeviceConnection::GetName() +{ + return name; +} + +HRESULT DeviceConnection::GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + if (NULL == iconStore) + hr = E_UNEXPECTED; + else + hr = iconStore->Get(buffer, bufferSize, width, height); + + Unlock(); + + return hr; +} + +HRESULT DeviceConnection::GetDisplayName(wchar_t *buffer, size_t bufferSize) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + hr = StringCchCopyExW(buffer, bufferSize, displayName, NULL, NULL, STRSAFE_IGNORE_NULLS); + + Unlock(); + + return hr; +} + +HRESULT DeviceConnection::GetIconStore(ifc_deviceiconstore **store) +{ + HRESULT hr; + + if (NULL == store) + return E_POINTER; + + Lock(); + + if (NULL == iconStore) + hr = E_UNEXPECTED; + else + { + iconStore->AddRef(); + *store = iconStore; + hr = S_OK; + } + + Unlock(); + + return hr; +} + +HRESULT DeviceConnection::SetDisplayName(const wchar_t *displayName) +{ + HRESULT hr; + + Lock(); + + String_Free(this->displayName); + this->displayName = String_Duplicate(displayName); + + if (NULL == this->displayName && NULL != displayName) + hr = E_OUTOFMEMORY; + else + hr = S_OK; + + Unlock(); + + return hr; +} + +#define CBCLASS DeviceConnection +START_MULTIPATCH; + START_PATCH(MPIID_DEVICECONNECTION) + M_CB(MPIID_DEVICECONNECTION, ifc_deviceconnection, ADDREF, AddRef); + M_CB(MPIID_DEVICECONNECTION, ifc_deviceconnection, RELEASE, Release); + M_CB(MPIID_DEVICECONNECTION, ifc_deviceconnection, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_DEVICECONNECTION, ifc_deviceconnection, API_GETNAME, GetName); + M_CB(MPIID_DEVICECONNECTION, ifc_deviceconnection, API_GETICON, GetIcon); + M_CB(MPIID_DEVICECONNECTION, ifc_deviceconnection, API_GETDISPLAYNAME, GetDisplayName); + NEXT_PATCH(MPIID_DEVICECONNECTIONEDITOR) + M_CB(MPIID_DEVICECONNECTIONEDITOR, ifc_deviceconnectioneditor, ADDREF, AddRef); + M_CB(MPIID_DEVICECONNECTIONEDITOR, ifc_deviceconnectioneditor, RELEASE, Release); + M_CB(MPIID_DEVICECONNECTIONEDITOR, ifc_deviceconnectioneditor, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_DEVICECONNECTIONEDITOR, ifc_deviceconnectioneditor, API_SETDISPLAYNAME, SetDisplayName); + M_CB(MPIID_DEVICECONNECTIONEDITOR, ifc_deviceconnectioneditor, API_GETICONSTORE, GetIconStore); + END_PATCH +END_MULTIPATCH;
\ No newline at end of file diff --git a/Src/devices/deviceConnection.h b/Src/devices/deviceConnection.h new file mode 100644 index 00000000..3d2dd8e2 --- /dev/null +++ b/Src/devices/deviceConnection.h @@ -0,0 +1,59 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_deviceconnection.h" +#include "./ifc_deviceconnectioneditor.h" +#include "./ifc_deviceiconstore.h" +#include "./deviceIconStore.h" + +#include <bfc/multipatch.h> + +#define MPIID_DEVICECONNECTION 10 +#define MPIID_DEVICECONNECTIONEDITOR 20 + +class DeviceConnection : public MultiPatch<MPIID_DEVICECONNECTION, ifc_deviceconnection>, + public MultiPatch<MPIID_DEVICECONNECTIONEDITOR, ifc_deviceconnectioneditor> +{ + +protected: + DeviceConnection(); + ~DeviceConnection(); + +public: + static HRESULT CreateInstance(const char *name, DeviceConnection **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_deviceconnection */ + const char *GetName(); + HRESULT GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height); + HRESULT GetDisplayName(wchar_t *buffer, size_t bufferSize); + + /* ifc_deviceconnectioneditor */ + HRESULT GetIconStore(ifc_deviceiconstore **store); + HRESULT SetDisplayName(const wchar_t *displayName); + +public: + void Lock(); + void Unlock(); + +protected: + size_t ref; + char *name; + wchar_t *displayName; + DeviceIconStore *iconStore; + CRITICAL_SECTION lock; + +protected: + RECVS_MULTIPATCH; +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_HEADER diff --git a/Src/devices/deviceEventManager.cpp b/Src/devices/deviceEventManager.cpp new file mode 100644 index 00000000..73afe55a --- /dev/null +++ b/Src/devices/deviceEventManager.cpp @@ -0,0 +1,303 @@ +#include "main.h" +#include "./deviceEventManager.h" + +DeviceEventManager::DeviceEventManager() + : ref(1) +{ + InitializeCriticalSection(&lock); +} + +DeviceEventManager::~DeviceEventManager() +{ + Lock(); + + size_t index = handlerList.size(); + while(index--) + { + ifc_deviceevent *handler = handlerList[index]; + handler->Release(); + } + + Unlock(); + + DeleteCriticalSection(&lock); +} + +HRESULT DeviceEventManager::CreateInstance(DeviceEventManager **instance) +{ + if (NULL == instance) + return E_POINTER; + + *instance = new DeviceEventManager(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + return S_OK; +} + +size_t DeviceEventManager::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceEventManager::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceEventManager::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceEventManager)) + *object = static_cast<ifc_deviceeventmanager*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +void DeviceEventManager::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceEventManager::Unlock() +{ + LeaveCriticalSection(&lock); +} + +HRESULT DeviceEventManager::Advise(ifc_deviceevent *handler) +{ + HRESULT hr; + size_t index; + + Lock(); + + hr = S_OK; + index = handlerList.size(); + + while(index--) + { + if (handler == handlerList[index]) + { + hr = E_FAIL; + break; + } + } + + if (SUCCEEDED(hr)) + { + handlerList.push_back(handler); + handler->AddRef(); + } + + Unlock(); + + return hr; +} + +HRESULT DeviceEventManager::Unadvise(ifc_deviceevent *handler) +{ + Lock(); + + HRESULT hr = S_FALSE; + size_t index = handlerList.size(); + + while(index--) + { + if (handler == handlerList[index]) + { + handlerList.erase(handlerList.begin() + index); + handler->Release(); + hr = S_OK; + break; + } + } + Unlock(); + + return hr; +} + +void DeviceEventManager::Notify_IconChanged(ifc_device *device) +{ + Lock(); + + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->IconChanged(device); + } + Unlock(); +} + +void DeviceEventManager::Notify_DisplayNameChanged(ifc_device *device, const wchar_t *displayName) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->DisplayNameChanged(device, displayName); + } + Unlock(); +} + +void DeviceEventManager::Notify_AttachmentChanged(ifc_device *device, BOOL attached) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->AttachmentChanged(device, attached); + } + Unlock(); +} + +void DeviceEventManager::Notify_VisibilityChanged(ifc_device *device, BOOL visible) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->VisibilityChanged(device, visible); + } + Unlock(); +} + +void DeviceEventManager::Notify_TotalSpaceChanged(ifc_device *device, uint64_t space) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->TotalSpaceChanged(device, space); + } + Unlock(); +} + +void DeviceEventManager::Notify_UsedSpaceChanged(ifc_device *device, uint64_t space) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->UsedSpaceChanged(device, space); + } + Unlock(); +} + +void DeviceEventManager::Notfiy_CommandChanged(ifc_device *device) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->CommandChanged(device); + } + Unlock(); +} + +void DeviceEventManager::Notify_ActivityStarted(ifc_device *device, ifc_deviceactivity *activity) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->ActivityStarted(device, activity); + } + Unlock(); +} + +void DeviceEventManager::Notify_ActivityFinished(ifc_device *device, ifc_deviceactivity *activity) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->ActivityFinished(device, activity); + } + Unlock(); +} + +void DeviceEventManager::Notify_ActivityChanged(ifc_device *device, ifc_deviceactivity *activity) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->ActivityChanged(device, activity); + } + Unlock(); +} + +void DeviceEventManager::Notify_ModelChanged(ifc_device *device, const wchar_t *model) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->ModelChanged(device, model); + } + Unlock(); +} + +void DeviceEventManager::Notify_StatusChanged(ifc_device *device, const wchar_t *status) +{ + Lock(); + size_t index, count = handlerList.size(); + for(index = 0; index < count;index++) + { + ifc_deviceevent *handler = handlerList[index]; + handler->StatusChanged(device, status); + } + Unlock(); +} + + +#define CBCLASS DeviceEventManager +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_ADVISE, Advise) +CB(API_UNADVISE, Unadvise) +VCB(API_NOTIFY_ICONCHANGED, Notify_IconChanged) +VCB(API_NOTIFY_DISPLAYNAMECHANGED, Notify_DisplayNameChanged) +VCB(API_NOTIFY_ATTACHMENTCHANGED, Notify_AttachmentChanged) +VCB(API_NOTIFY_VISIBILITYCHANGED, Notify_VisibilityChanged) +VCB(API_NOTIFY_TOTALSPACECHANGED, Notify_TotalSpaceChanged) +VCB(API_NOTIFY_USEDSPACECHANGED, Notify_UsedSpaceChanged) +VCB(API_NOTIFY_COMMANDCHANGED, Notfiy_CommandChanged) +VCB(API_NOTIFY_ACTIVITYSTARTED, Notify_ActivityStarted) +VCB(API_NOTIFY_ACTIVITYFINISHED, Notify_ActivityFinished) +VCB(API_NOTIFY_ACTIVITYCHANGED, Notify_ActivityChanged) +VCB(API_NOTIFY_MODELCHANGED, Notify_ModelChanged) +VCB(API_NOTIFY_STATUSCHANGED, Notify_StatusChanged) +END_DISPATCH; +#undef CBCLASS diff --git a/Src/devices/deviceEventManager.h b/Src/devices/deviceEventManager.h new file mode 100644 index 00000000..c5790fe9 --- /dev/null +++ b/Src/devices/deviceEventManager.h @@ -0,0 +1,64 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_MANAGER_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_MANAGER_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_deviceevent.h" +#include "./ifc_deviceeventmanager.h" +#include <vector> + +class DeviceEventManager : public ifc_deviceeventmanager +{ + +protected: + DeviceEventManager(); + ~DeviceEventManager(); + +public: + static HRESULT CreateInstance(DeviceEventManager **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_deviceeventmanager */ + HRESULT Advise(ifc_deviceevent *handler); + HRESULT Unadvise(ifc_deviceevent *handler); + + void Notify_IconChanged(ifc_device *device); + void Notify_DisplayNameChanged(ifc_device *device, const wchar_t *displayName); + void Notify_AttachmentChanged(ifc_device *device, BOOL attached); + void Notify_VisibilityChanged(ifc_device *device, BOOL visible); + void Notify_TotalSpaceChanged(ifc_device *device, uint64_t space); + void Notify_UsedSpaceChanged(ifc_device *device, uint64_t space); + void Notfiy_CommandChanged(ifc_device *device); + void Notify_ActivityStarted(ifc_device *device, ifc_deviceactivity *activity); + void Notify_ActivityFinished(ifc_device *device, ifc_deviceactivity *activity); + void Notify_ActivityChanged(ifc_device *device, ifc_deviceactivity *activity); + void Notify_ModelChanged(ifc_device *device, const wchar_t *model); + void Notify_StatusChanged(ifc_device *device, const wchar_t *status); + +public: + void Lock(); + void Unlock(); + +protected: + typedef std::vector<ifc_deviceevent*> HandlerList; + +protected: + size_t ref; + HandlerList handlerList; + CRITICAL_SECTION lock; + +protected: + RECVS_DISPATCH; + + + +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_MANAGER_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceIconStore.cpp b/Src/devices/deviceIconStore.cpp new file mode 100644 index 00000000..45b48b06 --- /dev/null +++ b/Src/devices/deviceIconStore.cpp @@ -0,0 +1,501 @@ +#include "main.h" +#include "./deviceIconStore.h" + +#include <strsafe.h> + +DeviceIconStore::DeviceIconStore() + : ref(1), base(NULL) +{ + InitializeCriticalSection(&lock); +} + +DeviceIconStore::~DeviceIconStore() +{ + RemoveAll(); + String_Free(base); + DeleteCriticalSection(&lock); +} + +HRESULT DeviceIconStore::CreateInstance(DeviceIconStore **instance) +{ + if (NULL == instance) + return E_POINTER; + + *instance = new DeviceIconStore(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + return S_OK; +} + +size_t DeviceIconStore::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceIconStore::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceIconStore::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceIconStore)) + *object = static_cast<ifc_deviceiconstore*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +void DeviceIconStore::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceIconStore::Unlock() +{ + LeaveCriticalSection(&lock); +} + +HRESULT DeviceIconStore::Add(const wchar_t *path, unsigned int width, unsigned int height, BOOL replaceExisting) +{ + if (FALSE != IS_STRING_EMPTY(path)) + return E_INVALIDARG; + + if(width < 1) + width = 1; + + if(height < 1) + height = 1; + + HRESULT hr = S_FALSE; + + Lock(); + + size_t index = list.size(); + while(index--) + { + Record *record = &list[index]; + if (width == record->width && + height == record->height) + { + if (FALSE == replaceExisting) + hr = E_FAIL; + else + { + wchar_t *pathCopy; + pathCopy = String_Duplicate(path); + if (NULL == pathCopy) + hr = E_OUTOFMEMORY; + else + { + record->path = pathCopy; + hr = S_OK; + } + } + break; + } + } + + if (S_FALSE == hr) + { + Record newRecord; + newRecord.path = String_Duplicate(path); + if (NULL == newRecord.path) + hr = E_OUTOFMEMORY; + else + { + newRecord.width = width; + newRecord.height = height; + list.push_back(newRecord); + hr = S_OK; + } + } + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::Remove(unsigned int width, unsigned int height) +{ + HRESULT hr; + size_t index; + Record *record; + + if(width < 1) + width = 1; + + if(height < 1) + height = 1; + + hr = S_FALSE; + + Lock(); + + index = list.size(); + while(index--) + { + record = &list[index]; + if (record->width == width && + record->height == height) + { + String_Free(record->path); + list.erase(list.begin() + index); + hr = S_OK; + break; + } + } + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::RemovePath(const wchar_t *path) +{ + HRESULT hr; + size_t index; + Record *record; + + if (FALSE != IS_STRING_EMPTY(path)) + return E_INVALIDARG; + + hr = S_FALSE; + + Lock(); + + index = list.size(); + while(index--) + { + record = &list[index]; + if(CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, record->path, -1, path, -1)) + { + String_Free(record->path); + list.erase(list.begin() + index); + hr = S_OK; + } + } + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::RemoveAll() +{ + size_t index; + Record *record; + + Lock(); + + index = list.size(); + while(index--) + { + record = &list[index]; + String_Free(record->path); + } + list.clear(); + + Unlock(); + + return S_OK; +} + +HRESULT DeviceIconStore::Get(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height) +{ + HRESULT hr; + Record *record; + const wchar_t *path; + size_t index; + double widthDbl, heightDbl; + double scaleMin, scaleHorz, scaleVert; + + if (NULL == buffer) + return E_POINTER; + + if (width < 1) + width = 1; + + if (height < 1) + height = 1; + + path = NULL; + + widthDbl = width; + heightDbl = height; + + Lock(); + + index = list.size(); + if (index > 0) + { + record = &list[--index]; + scaleHorz = widthDbl/record->width; + scaleVert = heightDbl/record->height; + scaleMin = (scaleHorz < scaleVert) ? scaleHorz : scaleVert; + path = record->path; + if (1.0 != scaleMin) + { + scaleMin = fabs(1.0 - scaleMin); + while(index--) + { + record = &list[index]; + scaleHorz = widthDbl/record->width; + scaleVert = heightDbl/record->height; + if (scaleHorz > scaleVert) + scaleHorz = scaleVert; + + if (1.0 == scaleHorz) + { + path = record->path; + break; + } + + scaleHorz = fabs(1.0 - scaleHorz); + if (scaleHorz < scaleMin) + { + scaleMin = scaleHorz; + path = record->path; + } + } + } + } + + if (NULL == path) + hr = E_FAIL; + else + hr = GetFullPath(buffer, bufferMax, path); + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::GetExact(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height) +{ + HRESULT hr; + size_t index; + Record *record; + + if (NULL == buffer) + return E_POINTER; + + if(width < 1) + width = 1; + + if(height < 1) + height = 1; + + hr = E_FAIL; + + Lock(); + + index = list.size(); + while(index--) + { + record = &list[index]; + if (record->width == width && + record->height == height) + { + hr = GetFullPath(buffer, bufferMax, record->path); + break; + } + } + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::SetBasePath(const wchar_t *path) +{ + HRESULT hr; + + Lock(); + + String_Free(base); + base = String_Duplicate(path); + + if (NULL == base && NULL != path) + hr = E_OUTOFMEMORY; + else + hr = S_OK; + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::GetBasePath(wchar_t *buffer, size_t bufferMax) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + if (0 == String_CopyTo(buffer, base, bufferMax) && + FALSE == IS_STRING_EMPTY(base)) + { + hr = E_FAIL; + } + else + hr = S_OK; + + Unlock(); + + return hr; +} + +HRESULT DeviceIconStore::Clone(ifc_deviceiconstore **instance) +{ + HRESULT hr; + DeviceIconStore *clone; + + if (NULL == instance) + return E_POINTER; + + hr = DeviceIconStore::CreateInstance(&clone); + if (FAILED(hr)) + return hr; + + Lock(); + + clone->base = String_Duplicate(base); + if (NULL == clone->base && NULL != base) + hr = E_OUTOFMEMORY; + else + { + size_t index, count; + Record target; + const Record *source; + + count = list.size(); + + for(index = 0; index < count; index++) + { + source = &list[index]; + target.path = String_Duplicate(source->path); + if (NULL == target.path) + { + hr = E_OUTOFMEMORY; + break; + } + else + { + target.width = source->width; + target.height = source->height; + clone->list.push_back(target); + } + } + } + + Unlock(); + + if (FAILED(hr)) + clone->Release(); + else + *instance = clone; + + return hr; +} + +HRESULT DeviceIconStore::Enumerate(EnumeratorCallback callback, void *user) +{ + size_t index, count; + wchar_t buffer[MAX_PATH*2] = {0}; + Record *record; + + if (NULL == callback) + return E_POINTER; + + Lock(); + + count = list.size(); + for(index = 0; index < count; index++) + { + record = &list[index]; + if (SUCCEEDED(GetFullPath(buffer, ARRAYSIZE(buffer), record->path))) + { + if (FALSE == callback(buffer, record->width, record->height, user)) + { + break; + } + } + } + + Unlock(); + + return S_OK; +} + +HRESULT DeviceIconStore::GetFullPath(wchar_t *buffer, size_t bufferMax, const wchar_t *path) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + if (FALSE != IS_STRING_EMPTY(path)) + return E_INVALIDARG; + + Lock(); + + if (FALSE == PathIsRelative(path) || + FALSE != IS_STRING_EMPTY(base)) + { + if (0 == String_CopyTo(buffer, path, bufferMax)) + hr = E_OUTOFMEMORY; + else + hr = S_OK; + } + else + { + if (NULL == PathCombine(buffer, base, path)) + hr = E_FAIL; + else + hr = S_OK; + } + + Unlock(); + + return hr; +} + +#define CBCLASS DeviceIconStore +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_ADD, Add) +CB(API_REMOVE, Remove) +CB(API_REMOVEPATH, RemovePath) +CB(API_REMOVEALL, RemoveAll) +CB(API_GET, Get) +CB(API_GETEXACT, GetExact) +CB(API_SETBASEPATH, SetBasePath) +CB(API_GETBASEPATH, GetBasePath) +CB(API_CLONE, Clone) +CB(API_ENUMERATE, Enumerate) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/devices/deviceIconStore.h b/Src/devices/deviceIconStore.h new file mode 100644 index 00000000..6b23151d --- /dev/null +++ b/Src/devices/deviceIconStore.h @@ -0,0 +1,71 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_ICON_STORE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_ICON_STORE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_deviceiconstore.h" +#include <vector> + +class DeviceIconStore : public ifc_deviceiconstore +{ + +protected: + DeviceIconStore(); + ~DeviceIconStore(); + +public: + static HRESULT CreateInstance(DeviceIconStore **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_deviceiconstore */ + HRESULT Add(const wchar_t *path, unsigned int width, unsigned int height, BOOL replaceExisting); + HRESULT Remove(unsigned int width, unsigned int height); + HRESULT RemovePath(const wchar_t *path); + HRESULT RemoveAll(); + HRESULT Get(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height); + HRESULT GetExact(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height); + + HRESULT SetBasePath(const wchar_t *path); + HRESULT GetBasePath(wchar_t *buffer, size_t bufferMax); + + HRESULT Clone(ifc_deviceiconstore **instance); + + HRESULT Enumerate(EnumeratorCallback callback, void *user); + +public: + void Lock(); + void Unlock(); + + HRESULT GetFullPath(wchar_t *buffer, size_t bufferMax, const wchar_t *path); + +protected: + typedef struct Record + { + unsigned int width; + unsigned int height; + wchar_t *path; + } Record; + + typedef std::vector<Record> RecordList; + +protected: + size_t ref; + wchar_t *base; + RecordList list; + CRITICAL_SECTION lock; + +protected: + RECVS_DISPATCH; + + + +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_ICON_STORE_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceManager.cpp b/Src/devices/deviceManager.cpp new file mode 100644 index 00000000..a68eec69 --- /dev/null +++ b/Src/devices/deviceManager.cpp @@ -0,0 +1,650 @@ +#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<api_devicemanager*>(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<DeviceEventManager**>(eventManager)); +} + +HRESULT DeviceManager::CreateSupportedCommandStore(ifc_devicesupportedcommandstore **store) +{ + return DeviceSupportedCommandStore::CreateInstance( + reinterpret_cast<DeviceSupportedCommandStore**>(store)); +} + +HRESULT DeviceManager::CreateSupportedCommandEnum(ifc_devicesupportedcommand **commands, size_t count, ifc_devicesupportedcommandenum **enumerator) +{ + return DeviceSupportedCommandEnum::CreateInstance(commands, count, + reinterpret_cast<DeviceSupportedCommandEnum**>(enumerator)); +} + +HRESULT DeviceManager::CreateIconStore(ifc_deviceiconstore **store) +{ + return DeviceIconStore::CreateInstance( + reinterpret_cast<DeviceIconStore**>(store)); +} + +HRESULT DeviceManager::CreateType(const char *name, ifc_devicetype **type) +{ + return DeviceType::CreateInstance(name, reinterpret_cast<DeviceType**>(type)); +} + +HRESULT DeviceManager::CreateCommand(const char *name, ifc_devicecommand **command) +{ + return DeviceCommand::CreateInstance(name, reinterpret_cast<DeviceCommand**>(command)); + +} + +HRESULT DeviceManager::CreateConnection(const char *name, ifc_deviceconnection **connection) +{ + return DeviceConnection::CreateInstance(name, reinterpret_cast<DeviceConnection**>(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
\ No newline at end of file diff --git a/Src/devices/deviceManager.h b/Src/devices/deviceManager.h new file mode 100644 index 00000000..df076cb9 --- /dev/null +++ b/Src/devices/deviceManager.h @@ -0,0 +1,111 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./api_devicemanager.h" +#include "./deviceObjectStore.h" +#include "./discoveryMonitor.h" +#include <vector> + +class DeviceManager : public api_devicemanager +{ + +protected: + DeviceManager(); + ~DeviceManager(); + +public: + static HRESULT CreateInstance(DeviceManager **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* api_devicemanager */ + size_t TypeRegister(ifc_devicetype **types, size_t count); + size_t TypeRegisterIndirect(const char **names, size_t count, DeviceTypeCreator callback, void *user); + HRESULT TypeUnregister(const char *name); + HRESULT TypeFind(const char *name, ifc_devicetype **type); + HRESULT TypeEnumerate(ifc_deviceobjectenum **enumerator); + + size_t ConnectionRegister(ifc_deviceconnection **connections, size_t count); + size_t ConnectionRegisterIndirect(const char **names, size_t count, DeviceConnectionCreator callback, void *user); + HRESULT ConnectionUnregister(const char *name); + HRESULT ConnectionFind(const char *name, ifc_deviceconnection **connection); + HRESULT ConnectionEnumerate(ifc_deviceobjectenum **enumerator); + + size_t CommandRegister(ifc_devicecommand **commands, size_t count); + size_t CommandRegisterIndirect(const char **names, size_t count, DeviceCommandCreator callback, void *user); + HRESULT CommandUnregister(const char *name); + HRESULT CommandFind(const char *name, ifc_devicecommand **command); + HRESULT CommandEnumerate(ifc_deviceobjectenum **enumerator); + + size_t DeviceRegister(ifc_device **devices, size_t count); + HRESULT DeviceUnregister(const char *name); + HRESULT DeviceFind(const char *name, ifc_device **device); + HRESULT DeviceEnumerate(ifc_deviceobjectenum **enumerator); + + HRESULT IsDiscoveryActive(); + HRESULT BeginDiscovery(); + HRESULT CancelDiscovery(); + HRESULT RegisterProvider(ifc_deviceprovider *provider); + HRESULT UnregisterProvider(ifc_deviceprovider *provider); + HRESULT SetProviderActive(ifc_deviceprovider *provider, BOOL activeState); + + HRESULT Advise(ifc_devicemanagerevent *handler); + HRESULT Unadvise(ifc_devicemanagerevent *handler); + + HRESULT CreateDeviceEventManager(ifc_deviceeventmanager **eventManager); + HRESULT CreateSupportedCommandStore(ifc_devicesupportedcommandstore **store); + HRESULT CreateSupportedCommandEnum(ifc_devicesupportedcommand **commands, size_t count, ifc_devicesupportedcommandenum **enumerator); + HRESULT CreateIconStore(ifc_deviceiconstore **store); + HRESULT CreateType(const char *name, ifc_devicetype **type); + HRESULT CreateCommand(const char *name, ifc_devicecommand **command); + HRESULT CreateConnection(const char *name, ifc_deviceconnection **connection); + +protected: + void EventTypeAdded(ifc_devicetype *type); + void EventTypeRemoved(ifc_devicetype *type); + void EventConnectionAdded(ifc_deviceconnection *connection); + void EventConnectionRemoved(ifc_deviceconnection *connection); + void EventCommandAdded(ifc_devicecommand *command); + void EventCommandRemoved(ifc_devicecommand *command); + void EventDeviceAdded(ifc_device *device); + void EventDeviceRemoved(ifc_device *device); + void EventDiscoveryStarted(); + void EventDiscoveryFinished(); + +protected: + static void ObjectAddedCallback(DeviceObjectStore *store, ifc_deviceobject *object, void *userData); + static void ObjectRemovedCallback(DeviceObjectStore *store, ifc_deviceobject *object, void *userData); + +protected: + typedef std::vector<ifc_devicemanagerevent*> EventList; + typedef std::vector<ifc_deviceprovider*> ProviderList; + +protected: + size_t ref; + + DeviceObjectStore typeStore; + DeviceObjectStore connectionStore; + DeviceObjectStore commandStore; + DeviceObjectStore deviceStore; + + CRITICAL_SECTION eventLock; + EventList eventList; + + CRITICAL_SECTION providerLock; + ProviderList providerList; + + DiscoveryMonitor discoveryMonitor; + +protected: + RECVS_DISPATCH; +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_HEADER diff --git a/Src/devices/deviceManagerFactory.cpp b/Src/devices/deviceManagerFactory.cpp new file mode 100644 index 00000000..8ee804cd --- /dev/null +++ b/Src/devices/deviceManagerFactory.cpp @@ -0,0 +1,100 @@ +#include "main.h" +#include "./deviceManager.h" +#include "./deviceManagerFactory.h" + +DeviceManagerFactory::DeviceManagerFactory() + : object(NULL) +{ +} + +DeviceManagerFactory::~DeviceManagerFactory() +{ + if (NULL != object) + object->Release(); +} + +FOURCC DeviceManagerFactory::GetServiceType() +{ + return WaSvc::UNIQUE; +} + +const char *DeviceManagerFactory::GetServiceName() +{ + return "Device Manager Interface"; +} + +GUID DeviceManagerFactory::GetGUID() +{ + return DeviceManagerGUID; +} + +void *DeviceManagerFactory::GetInterface(int global_lock) +{ + if (NULL == object) + { + if (FAILED(DeviceManager::CreateInstance(&object))) + object = NULL; + + if (NULL == object) + return NULL; + } + + object->AddRef(); + return object; +} + +int DeviceManagerFactory::SupportNonLockingInterface() +{ + return 1; +} + +int DeviceManagerFactory::ReleaseInterface(void *ifc) +{ + DeviceManager *object = (DeviceManager*)ifc; + if (NULL != object) + object->Release(); + + return 1; +} + +const char *DeviceManagerFactory::GetTestString() +{ + return NULL; +} + +int DeviceManagerFactory::ServiceNotify(int msg, int param1, int param2) +{ + return 1; +} + +HRESULT DeviceManagerFactory::Register(api_service *service) +{ + if (NULL == service) + return E_INVALIDARG; + + service->service_register(this); + return S_OK; +} + +HRESULT DeviceManagerFactory::Unregister(api_service *service) +{ + if (NULL == service) + return E_INVALIDARG; + + service->service_deregister(this); + return S_OK; +} + +#define CBCLASS DeviceManagerFactory +START_DISPATCH; +CB( WASERVICEFACTORY_GETSERVICETYPE, GetServiceType ) +CB( WASERVICEFACTORY_GETSERVICENAME, GetServiceName ) +CB( WASERVICEFACTORY_GETGUID, GetGUID ) +CB( WASERVICEFACTORY_GETINTERFACE, GetInterface ) +CB( WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface ) +CB( WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface ) +CB( WASERVICEFACTORY_GETTESTSTRING, GetTestString ) +CB( WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify ) +END_DISPATCH; + +#undef CBCLASS
\ No newline at end of file diff --git a/Src/devices/deviceManagerFactory.h b/Src/devices/deviceManagerFactory.h new file mode 100644 index 00000000..f5759587 --- /dev/null +++ b/Src/devices/deviceManagerFactory.h @@ -0,0 +1,42 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_FACTORY_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_FACTORY_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <api/service/waservicefactory.h> +#include <api/service/services.h> + +class DeviceManager; + +class DeviceManagerFactory : public waServiceFactory +{ +public: + DeviceManagerFactory(); + ~DeviceManagerFactory(); + +public: + FOURCC GetServiceType(); + const char *GetServiceName(); + GUID GetGUID(); + void *GetInterface(int global_lock); + int SupportNonLockingInterface(); + int ReleaseInterface(void *ifc); + const char *GetTestString(); + int ServiceNotify(int msg, int param1, int param2); + +public: + HRESULT Register(api_service *service); + HRESULT Unregister(api_service *service); + +protected: + RECVS_DISPATCH; + +protected: + DeviceManager *object; +}; + + + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_FACTORY_HEADER diff --git a/Src/devices/deviceObjectEnum.cpp b/Src/devices/deviceObjectEnum.cpp new file mode 100644 index 00000000..e60b39d6 --- /dev/null +++ b/Src/devices/deviceObjectEnum.cpp @@ -0,0 +1,175 @@ +#include "main.h" +#include "./deviceObjectEnum.h" +#include <new> + +DeviceObjectEnum::DeviceObjectEnum() + : ref(1), buffer(NULL), size(0), cursor(0) +{ +} + +DeviceObjectEnum::~DeviceObjectEnum() +{ + if (NULL != buffer) + { + while(size--) + { + buffer[size]->Release(); + } + } +} + +HRESULT DeviceObjectEnum::CreateInstance(ifc_deviceobject **objects, + size_t count, + DeviceObjectEnum **instance) +{ + size_t index, size; + void *storage; + ifc_deviceobject *o; + DeviceObjectEnum *enumerator; + + + if (NULL == instance) + return E_POINTER; + + *instance = NULL; + + size = sizeof(DeviceObjectEnum) + (sizeof(ifc_deviceobject**) * count); + storage = calloc(1, size); + if (NULL == storage) + return E_OUTOFMEMORY; + + enumerator = new(storage) DeviceObjectEnum(); + if (NULL == enumerator) + { + free(storage); + return E_FAIL; + } + + enumerator->buffer = (ifc_deviceobject**)(((BYTE*)enumerator) + sizeof(DeviceObjectEnum)); + + for (index = 0; index < count; index++) + { + o = objects[index]; + if (NULL != o) + { + enumerator->buffer[enumerator->size] = o; + o->AddRef(); + enumerator->size++; + } + } + + *instance = enumerator; + return S_OK; +} + + + +size_t DeviceObjectEnum::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceObjectEnum::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceObjectEnum::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceObjectEnum)) + *object = static_cast<ifc_deviceobjectenum*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +HRESULT DeviceObjectEnum::Next(ifc_deviceobject **objects, size_t bufferMax, size_t *fetched) +{ + size_t available, copied, index; + ifc_deviceobject **source; + + if (NULL == objects) + return E_POINTER; + + if (0 == bufferMax) + return E_INVALIDARG; + + if (cursor >= size) + { + if (NULL != fetched) + *fetched = 0; + + return S_FALSE; + } + + available = size - cursor; + copied = ((available > bufferMax) ? bufferMax : available); + + source = buffer + cursor; + CopyMemory(objects, source, copied * sizeof(ifc_deviceobject*)); + + for(index = 0; index < copied; index++) + objects[index]->AddRef(); + + cursor += copied; + + if (NULL != fetched) + *fetched = copied; + + return (bufferMax == copied) ? S_OK : S_FALSE; +} + +HRESULT DeviceObjectEnum::Reset(void) +{ + cursor = 0; + return S_OK; +} + +HRESULT DeviceObjectEnum::Skip(size_t count) +{ + cursor += count; + if (cursor > size) + cursor = size; + + return (cursor < size) ? S_OK : S_FALSE; +} + + +HRESULT DeviceObjectEnum::GetCount(size_t *count) +{ + if (NULL == count) + return E_POINTER; + + *count = size; + + return S_OK; +} + +#define CBCLASS DeviceObjectEnum +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_NEXT, Next) +CB(API_RESET, Reset) +CB(API_SKIP, Skip) +CB(API_GETCOUNT, GetCount) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/devices/deviceObjectEnum.h b/Src/devices/deviceObjectEnum.h new file mode 100644 index 00000000..7efbcbb4 --- /dev/null +++ b/Src/devices/deviceObjectEnum.h @@ -0,0 +1,44 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_ENUMERATOR_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_ENUMERATOR_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_deviceobject.h" +#include "./ifc_deviceobjectenum.h" + +class DeviceObjectEnum : public ifc_deviceobjectenum +{ +protected: + DeviceObjectEnum(); + ~DeviceObjectEnum(); + +public: + static HRESULT CreateInstance(ifc_deviceobject **objects, + size_t count, + DeviceObjectEnum **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_deviceobjectenum */ + HRESULT Next(ifc_deviceobject **objects, size_t bufferMax, size_t *fetched); + HRESULT Reset(void); + HRESULT Skip(size_t count); + HRESULT GetCount(size_t *count); + +protected: + size_t ref; + ifc_deviceobject **buffer; + size_t size; + size_t cursor; + +protected: + RECVS_DISPATCH; +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_ENUMERATOR_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceObjectStore.cpp b/Src/devices/deviceObjectStore.cpp new file mode 100644 index 00000000..075270cd --- /dev/null +++ b/Src/devices/deviceObjectStore.cpp @@ -0,0 +1,356 @@ +#include "main.h" +#include "./deviceObjectStore.h" +#include <algorithm> + +template <typename T> +struct GenericComparator +{ + typedef const char* (T::*GETTER)(); + GETTER m_getterFunc; + const char *m_data; + GenericComparator(GETTER getterFunc, const char *data) + { + m_getterFunc = getterFunc; + m_data = data; + } + bool operator()(const T& obj) + { + return strcmp(((obj).*m_getterFunc)(), m_data) == 0; + } +}; + +static ifc_deviceobject * +DeviceObjectStore_FindLocation(const char *name, std::vector<ifc_deviceobject*> &list) +{ + if (FALSE != IS_STRING_EMPTY(name)) + return NULL; + + //size_t name_length; + //name_length = lstrlenA(name) * sizeof(char); + // + //return (ifc_deviceobject*)bsearch_s(name, buffer, length, + // sizeof(ifc_deviceobject*), + // DeviceObjectStore_FindComparer, + // (void*)name_length); + + //auto it = std::find_if(list.begin(), list.begin(), GenericComparator<ifc_deviceobject>(&ifc_deviceobject::GetName, name)); + + const auto it = std::find_if(list.begin(), list.end(), + [&](ifc_deviceobject* upT) -> bool + { + return strcmp(upT->GetName(), name) == 0; + } + ); + if (it != list.end()) + { + return *it; + } + return nullptr; +} + +int DeviceObjectComparer(const char* arg1, const char* arg2) +{ + return stricmp(arg1, arg2); +} + + +// Created for std::sort +static bool DeviceObjectStore_SortComparer_V2(const void* element1, const void* element2) +{ + //return DeviceObjectStore_SortComparer(element1, element2) < 0; + const char* name1 = (((ifc_deviceobject*)element1))->GetName(); + const char* name2 = (((ifc_deviceobject*)element2))->GetName(); + return DeviceObjectComparer(name1, name2) < 0; +} + +static ifc_deviceobject * +DeviceObjectStore_FindUnsortedObject(const char *name, ifc_deviceobject **objects, size_t count) +{ + size_t index; + size_t length; + + if (0 == count) + return NULL; + + length = lstrlenA(name) * sizeof(char); + + for(index = 0; index < count; index++) + { + //if (0 == DeviceObjectStore_NameCompare(name, length, objects[index]->GetName())) + if(0 == DeviceObjectComparer(name, objects[index]->GetName())) + return objects[index]; + } + + return NULL; +} + + +DeviceObjectStore::DeviceObjectStore(DeviceObjectCallback addCallback, + DeviceObjectCallback _removeCallback, void *callbackData) +{ + this->addCallback = addCallback; + this->removeCallback = _removeCallback; + this->callbackData = callbackData; + + InitializeCriticalSection(&lock); +} + +DeviceObjectStore::~DeviceObjectStore() +{ + RemoveAll(); + DeleteCriticalSection(&lock); +} + +void DeviceObjectStore::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceObjectStore::Unlock() +{ + LeaveCriticalSection(&lock); +} + +CRITICAL_SECTION *DeviceObjectStore::GetLock() +{ + return &lock; +} + +HRESULT DeviceObjectStore::Add(ifc_deviceobject *object) +{ + const char *name; + + if (NULL == object) + return E_POINTER; + + name = object->GetName(); + + if (NULL == name || '\0' == *name) + return E_INVALIDARG; + + return (1 == AddRange(&object, 1)) ? S_OK : S_FALSE; +} + +size_t DeviceObjectStore::AddRange(ifc_deviceobject **objects, size_t count) +{ + const char *name; + size_t index, registered, added; + ifc_deviceobject *object; + + + if (NULL == objects || 0 == count) + return 0; + + Lock(); + + added = 0; + registered = list.size(); + + for(index = 0; index < count; index++) + { + object = objects[index]; + if (NULL != object) + { + name = object->GetName(); + + if (NULL != name && + '\0' != *name && + NULL == DeviceObjectStore_FindLocation(name, list)) + //&& NULL == DeviceObjectStore_FindUnsortedObject(name, buffer + registered, added)) + { + list.push_back(object); + object->AddRef(); + + if (NULL != addCallback) + this->addCallback(this, object, callbackData); + + added++; + } + } + } + + if (0 != added) + { + //qsort(list.first(), list.size(), + // sizeof(ifc_deviceobject**), + // DeviceObjectStore_SortComparer); + + std::sort(list.begin(), list.end(), DeviceObjectStore_SortComparer_V2); + } + + Unlock(); + + return added; +} + +size_t DeviceObjectStore::AddIndirect(const char **names, size_t count, DeviceObjectCreator callback, void *user) +{ + size_t index, registered, added; + ifc_deviceobject *object; + + if (NULL == names || 0 == count || NULL == callback) + return 0; + + Lock(); + + added = 0; + registered = list.size(); + + + for(index = 0; index < count; index++) + { + const char *name = names[index]; + + if (NULL != name && + '\0' != *name && + NULL == DeviceObjectStore_FindLocation(name, list) ) + //&& NULL == DeviceObjectStore_FindUnsortedObject(name, buffer + registered, added)) + { + object = callback(name, user); + if (NULL != object) + { + list.push_back(object); + + if (NULL != addCallback) + this->addCallback(this, object, callbackData); + + added++; + } + } + } + + if (0 != added) + { + //qsort(list.first(), list.size(), + // sizeof(ifc_deviceobject**), + // DeviceObjectStore_SortComparer); + + std::sort(list.begin(), list.end(), DeviceObjectStore_SortComparer_V2); + } + + Unlock(); + + return added; +} + +HRESULT DeviceObjectStore::Remove(const char *name) +{ + HRESULT hr = hr = S_FALSE; + + if (NULL == name || '\0' == *name) + return E_INVALIDARG; + + Lock(); + + //object_ptr = DeviceObjectStore_FindLocation(name, list); + //if (NULL != object_ptr) + //{ + // hr = S_OK; + + // ifc_deviceobject *object = *object_ptr; + + // size_t index = (size_t)(object_ptr - buffer); + // list.erase(list.begin() + index); + + // if (NULL != removeCallback) + // removeCallback(this, object, callbackData); + + // object->Release(); + //} + //else + //{ + // hr = S_FALSE; + //} + + const auto it = std::find_if(list.begin(), list.end(), + [&](ifc_deviceobject* upT) -> bool + { + return strcmp(upT->GetName(), name) == 0; + } + ); + + if (it != list.end()) + { + ifc_deviceobject* object = *it; + list.erase(it); + if (NULL != removeCallback) + { + removeCallback(this, object, callbackData); + } + object->Release(); + hr = S_OK; + } + Unlock(); + + return hr; +} + +void DeviceObjectStore::RemoveAll() +{ + Lock(); + + size_t index = list.size(); + while(index--) + { + ifc_deviceobject *object = list[index]; + if (NULL != removeCallback) + removeCallback(this, object, callbackData); + + object->Release(); + } + + list.clear(); + Unlock(); +} + +HRESULT DeviceObjectStore::Find(const char *name, ifc_deviceobject **object) +{ + HRESULT hr; + ifc_deviceobject *object_ptr; + + if (NULL == name || '\0' == *name) + return E_INVALIDARG; + + if (NULL == object) + return E_POINTER; + + Lock(); + + object_ptr = DeviceObjectStore_FindLocation(name, list); + + if (NULL != object_ptr) + { + if (NULL != object) + { + *object = object_ptr; + (*object)->AddRef(); + } + hr = S_OK; + } + else + { + if (NULL != object) + *object = NULL; + hr = S_FALSE; + } + + Unlock(); + + return hr; +} + +HRESULT DeviceObjectStore::Enumerate(DeviceObjectEnum **enumerator) +{ + HRESULT hr; + + if (NULL == enumerator) + return E_POINTER; + + Lock(); + + hr = DeviceObjectEnum::CreateInstance(list.size() ? &list.at(0) : nullptr, list.size(), enumerator); + + Unlock(); + + return hr; +} diff --git a/Src/devices/deviceObjectStore.h b/Src/devices/deviceObjectStore.h new file mode 100644 index 00000000..fad1f858 --- /dev/null +++ b/Src/devices/deviceObjectStore.h @@ -0,0 +1,55 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_STORE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_STORE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_deviceobject.h" +#include "./deviceObjectEnum.h" +#include <vector> + +class DeviceObjectStore; + +typedef void (__cdecl *DeviceObjectCallback)(DeviceObjectStore * /*store*/, + ifc_deviceobject * /*object*/, + void * /*user*/); + +typedef ifc_deviceobject *(_cdecl *DeviceObjectCreator)(const char * /*name*/, + void * /*user*/); + +class DeviceObjectStore +{ +public: + DeviceObjectStore(DeviceObjectCallback addCallback, + DeviceObjectCallback removeCallback, + void *callbackData); + + ~DeviceObjectStore(); + +public: + void Lock(); + void Unlock(); + CRITICAL_SECTION *GetLock(); + + HRESULT Add(ifc_deviceobject *object); + size_t AddRange(ifc_deviceobject **objects, size_t count); + size_t AddIndirect(const char **names, size_t count, DeviceObjectCreator callback, void *user); + + HRESULT Remove(const char *name); + void RemoveAll(); + HRESULT Find(const char *name, ifc_deviceobject **object); + HRESULT Enumerate(DeviceObjectEnum **enumerator); + +private: + std::vector<ifc_deviceobject*> list; + CRITICAL_SECTION lock; + DeviceObjectCallback addCallback; + DeviceObjectCallback removeCallback; + void *callbackData; + + + +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_STORE_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceSupportedCommand.cpp b/Src/devices/deviceSupportedCommand.cpp new file mode 100644 index 00000000..b5e09147 --- /dev/null +++ b/Src/devices/deviceSupportedCommand.cpp @@ -0,0 +1,120 @@ +#include "main.h" +#include "./deviceSupportedCommand.h" + +DeviceSupportedCommand::DeviceSupportedCommand() + : ref(1), name(NULL), flags(DeviceCommandFlag_None) +{ +} + +DeviceSupportedCommand::~DeviceSupportedCommand() +{ + AnsiString_Free(name); +} + +HRESULT DeviceSupportedCommand::CreateInstance(const char *name, DeviceSupportedCommand **instance) +{ + DeviceSupportedCommand *self; + + if (NULL == instance) + return E_POINTER; + + *instance = NULL; + + self = new DeviceSupportedCommand(); + if (NULL == self) + return E_OUTOFMEMORY; + + self->name = AnsiString_Duplicate(name); + + *instance = self; + return S_OK; +} + +size_t DeviceSupportedCommand::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceSupportedCommand::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceSupportedCommand::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) + return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceSupportedCommand)) + *object = static_cast<ifc_devicesupportedcommand*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +const char *DeviceSupportedCommand::GetName() +{ + return name; +} + +HRESULT DeviceSupportedCommand::GetFlags(DeviceCommandFlags *flagsOut) +{ + if (NULL == flagsOut) + return E_POINTER; + + *flagsOut = flags; + + return S_OK; +} + +HRESULT DeviceSupportedCommand::SetFlags(DeviceCommandFlags mask, DeviceCommandFlags value) +{ + DeviceCommandFlags temp; + temp = (flags & mask) | (mask & value); + + if (temp == flags) + return S_FALSE; + + flags = temp; + + return S_OK; +} + +HRESULT DeviceSupportedCommand::Clone(DeviceSupportedCommand **instance) +{ + HRESULT hr; + + hr = DeviceSupportedCommand::CreateInstance(name, instance); + if (SUCCEEDED(hr)) + { + (*instance)->flags = flags; + } + + return hr; + +} + +#define CBCLASS DeviceSupportedCommand +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_GETNAME, GetName) +CB(API_GETFLAGS, GetFlags) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/devices/deviceSupportedCommand.h b/Src/devices/deviceSupportedCommand.h new file mode 100644 index 00000000..c0d0fce5 --- /dev/null +++ b/Src/devices/deviceSupportedCommand.h @@ -0,0 +1,47 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <wtypes.h> +#include "./ifc_devicesupportedcommand.h" + + +class DeviceSupportedCommand : public ifc_devicesupportedcommand +{ +protected: + DeviceSupportedCommand(); + ~DeviceSupportedCommand(); + +public: + static HRESULT CreateInstance(const char *name, + DeviceSupportedCommand **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_devicesupportedcommand */ + const char *GetName(); + HRESULT GetFlags(DeviceCommandFlags *flags); + +public: + HRESULT SetFlags(DeviceCommandFlags mask, DeviceCommandFlags value); + HRESULT Clone(DeviceSupportedCommand **instance); + +protected: + size_t ref; + char *name; + DeviceCommandFlags flags; + + +protected: + RECVS_DISPATCH; +}; + + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceSupportedCommandEnum.cpp b/Src/devices/deviceSupportedCommandEnum.cpp new file mode 100644 index 00000000..9466f378 --- /dev/null +++ b/Src/devices/deviceSupportedCommandEnum.cpp @@ -0,0 +1,172 @@ +#include "main.h" +#include "./deviceSupportedCommandEnum.h" +#include <new> + +DeviceSupportedCommandEnum::DeviceSupportedCommandEnum() + : ref(1), commands(NULL), count(0), cursor(0) +{ +} + +DeviceSupportedCommandEnum::~DeviceSupportedCommandEnum() +{ + if (NULL != commands) + { + while(count--) + commands[count]->Release(); + } +} + +HRESULT DeviceSupportedCommandEnum::CreateInstance(ifc_devicesupportedcommand **commands, size_t count, + DeviceSupportedCommandEnum **instance) +{ + size_t index, size; + void *storage; + ifc_devicesupportedcommand *c; + DeviceSupportedCommandEnum *enumerator; + + + if (NULL == instance) + return E_POINTER; + + *instance = NULL; + + size = sizeof(DeviceSupportedCommandEnum) + (sizeof(ifc_devicesupportedcommand**) * count); + storage = calloc(1, size); + if (NULL == storage) + return E_OUTOFMEMORY; + + enumerator = new(storage) DeviceSupportedCommandEnum(); + if (NULL == enumerator) + { + free(storage); + return E_FAIL; + } + + enumerator->commands = (ifc_devicesupportedcommand**)(((BYTE*)enumerator) + sizeof(DeviceSupportedCommandEnum)); + + for (index = 0; index < count; index++) + { + c = commands[index]; + if (NULL != c) + { + enumerator->commands[enumerator->count] = c; + c->AddRef(); + enumerator->count++; + } + } + + *instance = enumerator; + return S_OK; +} + + + +size_t DeviceSupportedCommandEnum::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceSupportedCommandEnum::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceSupportedCommandEnum::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceSupportedCommandEnum)) + *object = static_cast<ifc_devicesupportedcommandenum*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +HRESULT DeviceSupportedCommandEnum::Next(ifc_devicesupportedcommand **objects, size_t bufferMax, size_t *fetched) +{ + size_t available, copied, index; + ifc_devicesupportedcommand **source; + + if (NULL == objects) + return E_POINTER; + + if (0 == bufferMax) + return E_INVALIDARG; + + if (cursor >= count) + { + if (NULL != fetched) + *fetched = 0; + + return S_FALSE; + } + + available = count - cursor; + copied = ((available > bufferMax) ? bufferMax : available); + + source = commands + cursor; + CopyMemory(objects, source, copied * sizeof(ifc_devicesupportedcommand*)); + + for(index = 0; index < copied; index++) + objects[index]->AddRef(); + + cursor += copied; + + if (NULL != fetched) + *fetched = copied; + + return (bufferMax == copied) ? S_OK : S_FALSE; +} + +HRESULT DeviceSupportedCommandEnum::Reset(void) +{ + cursor = 0; + return S_OK; +} + +HRESULT DeviceSupportedCommandEnum::Skip(size_t count) +{ + cursor += count; + if (cursor > this->count) + cursor = this->count; + + return (cursor < this->count) ? S_OK : S_FALSE; +} + + +HRESULT DeviceSupportedCommandEnum::GetCount(size_t *count) +{ + if (NULL == count) + return E_POINTER; + + *count = this->count; + + return S_OK; +} + +#define CBCLASS DeviceSupportedCommandEnum +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_NEXT, Next) +CB(API_RESET, Reset) +CB(API_SKIP, Skip) +CB(API_GETCOUNT, GetCount) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/devices/deviceSupportedCommandEnum.h b/Src/devices/deviceSupportedCommandEnum.h new file mode 100644 index 00000000..976595ee --- /dev/null +++ b/Src/devices/deviceSupportedCommandEnum.h @@ -0,0 +1,48 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_ENUM_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_ENUM_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_devicesupportedcommandenum.h" +#include "./ifC_devicesupportedcommand.h" + +class DeviceSupportedCommandEnum : public ifc_devicesupportedcommandenum +{ + +protected: + DeviceSupportedCommandEnum(); + ~DeviceSupportedCommandEnum(); + +public: + static HRESULT CreateInstance(ifc_devicesupportedcommand **commands, + size_t count, + DeviceSupportedCommandEnum **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_devicesupportedcommandenum*/ + HRESULT Next(ifc_devicesupportedcommand **buffer, size_t bufferMax, size_t *count); + HRESULT Reset(void); + HRESULT Skip(size_t count); + HRESULT GetCount(size_t *count); + +protected: + size_t ref; + ifc_devicesupportedcommand **commands; + size_t count; + size_t cursor; + +protected: + RECVS_DISPATCH; + + + +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_ENUM_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceSupportedCommandStore.cpp b/Src/devices/deviceSupportedCommandStore.cpp new file mode 100644 index 00000000..8e6c9034 --- /dev/null +++ b/Src/devices/deviceSupportedCommandStore.cpp @@ -0,0 +1,342 @@ +#include "main.h" +#include "./deviceSupportedCommandStore.h" + +DeviceSupportedCommandStore::DeviceSupportedCommandStore() + : ref(1) +{ + InitializeCriticalSection(&lock); +} + +DeviceSupportedCommandStore::~DeviceSupportedCommandStore() +{ + RemoveAll(); + DeleteCriticalSection(&lock); +} + +HRESULT DeviceSupportedCommandStore::CreateInstance(DeviceSupportedCommandStore **instance) +{ + if (NULL == instance) + return E_POINTER; + + *instance = new DeviceSupportedCommandStore(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + return S_OK; +} + +size_t DeviceSupportedCommandStore::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceSupportedCommandStore::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceSupportedCommandStore::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceSupportedCommandStore)) + *object = static_cast<ifc_devicesupportedcommandstore*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +void DeviceSupportedCommandStore::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceSupportedCommandStore::Unlock() +{ + LeaveCriticalSection(&lock); +} + +int +DeviceSupportedCommandStore::SortCallback(const void *element1, const void *element2) +{ + DeviceSupportedCommand *command1, *command2; + + command1 = *(DeviceSupportedCommand**)element1; + command2 = *(DeviceSupportedCommand**)element2; + + return CompareStringA(CSTR_INVARIANT, 0, command1->GetName(), -1, command2->GetName(), -1) - 2; +} + +int +DeviceSupportedCommandStore::SearchCallback(const void *key, const void *element) +{ + const char *name; + DeviceSupportedCommand *command; + + name = (const char*)key; + command = *(DeviceSupportedCommand**)element; + + return CompareStringA(CSTR_INVARIANT, 0, name, -1, command->GetName(), -1) - 2; +} + +DeviceSupportedCommand *DeviceSupportedCommandStore::Find(const char *name, size_t *indexOut) +{ + DeviceSupportedCommand *command; + int length; + size_t index, count; + + if (NULL == name || '\0' == *name) + return NULL; + + length = lstrlenA(name); + + count = commandList.size(); + for(index = 0; index < count; index++) + { + command = commandList[index]; + if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, 0, name, length, command->GetName(), -1)) + break; + } + + if (count == index) + return NULL; + + if (NULL != indexOut) + *indexOut = index; + + return command; + +} + + +HRESULT DeviceSupportedCommandStore::Add(const char *name, DeviceCommandFlags flags) +{ + HRESULT hr; + DeviceSupportedCommand *command; + + + hr = DeviceSupportedCommand::CreateInstance(name, &command); + if (FAILED(hr)) + return hr; + + Lock(); + + if (NULL == Find(name, NULL)) + { + command->SetFlags(flags, flags); + commandList.push_back(command); + } + else + { + command->Release(); + hr = S_FALSE; + } + + Unlock(); + + return hr; +} + +HRESULT DeviceSupportedCommandStore::Remove(const char *name) +{ + HRESULT hr; + size_t index; + DeviceSupportedCommand *command; + + Lock(); + + command = Find(name, &index); + if (NULL != command) + { + commandList.erase(commandList.begin() + index); + command->Release(); + hr = S_OK; + } + else + { + hr = S_FALSE; + } + + Unlock(); + + return hr; +} + +HRESULT DeviceSupportedCommandStore::RemoveAll() +{ + Lock(); + + size_t index = commandList.size(); + while(index--) + { + DeviceSupportedCommand *command = commandList[index]; + command->Release(); + } + + commandList.clear(); + + Unlock(); + + return S_OK; +} + +HRESULT DeviceSupportedCommandStore::GetFlags(const char *name, DeviceCommandFlags *flagsOut) +{ + HRESULT hr; + DeviceSupportedCommand *command; + + if (NULL == flagsOut) + return E_POINTER; + + Lock(); + + command = Find(name, NULL); + hr = (NULL != command) ? command->GetFlags(flagsOut) : E_FAIL; + + Unlock(); + + return hr; +} + +HRESULT DeviceSupportedCommandStore::SetFlags(const char *name, DeviceCommandFlags mask, DeviceCommandFlags value) +{ + HRESULT hr; + DeviceSupportedCommand *command; + + Lock(); + + command = Find(name, NULL); + hr = (NULL != command) ? command->SetFlags(mask, value) : E_FAIL; + + Unlock(); + + return hr; +} + +HRESULT DeviceSupportedCommandStore::Get(const char *name, ifc_devicesupportedcommand **command) +{ + HRESULT hr; + + if (NULL == command) + return E_POINTER; + + Lock(); + + *command = Find(name, NULL); + if (NULL != *command) + { + (*command)->AddRef(); + hr = S_OK; + } + else + hr = E_FAIL; + + Unlock(); + + return hr; +} + +HRESULT DeviceSupportedCommandStore::GetActive(ifc_devicesupportedcommand **command) +{ + return E_NOTIMPL; +} + +HRESULT DeviceSupportedCommandStore::Enumerate(ifc_devicesupportedcommandenum **enumerator) +{ + HRESULT hr; + + Lock(); + hr = DeviceSupportedCommandEnum::CreateInstance( + reinterpret_cast<ifc_devicesupportedcommand**>(commandList.size() ? &commandList.at(0) : nullptr), + commandList.size(), + reinterpret_cast<DeviceSupportedCommandEnum**>(enumerator)); + + + Unlock(); + + return hr; +} + +HRESULT DeviceSupportedCommandStore::Clone(ifc_devicesupportedcommandstore **instance, BOOL fullCopy) +{ + HRESULT hr; + DeviceSupportedCommandStore *clone; + DeviceSupportedCommand *command; + + if (NULL == instance) + return E_POINTER; + + Lock(); + + hr = CreateInstance(&clone); + if (SUCCEEDED(hr)) + { + size_t index, count; + + count = commandList.size(); + + for(index = 0; index < count; index++) + { + command = commandList[index]; + if (FALSE != fullCopy) + { + DeviceSupportedCommand *commandClone; + + hr = command->Clone(&commandClone); + if(SUCCEEDED(hr)) + command = commandClone; + else + break; + } + else + command->AddRef(); + + clone->commandList.push_back(command); + } + } + + Unlock(); + + if (FAILED(hr) && NULL != clone) + { + clone->Release(); + *instance = NULL; + } + else + *instance = clone; + + return hr; +} + +#define CBCLASS DeviceSupportedCommandStore +START_DISPATCH; +CB(ADDREF, AddRef) +CB(RELEASE, Release) +CB(QUERYINTERFACE, QueryInterface) +CB(API_ADD, Add) +CB(API_REMOVE, Remove) +CB(API_REMOVEALL, RemoveAll) +CB(API_GETFLAGS, GetFlags) +CB(API_SETFLAGS, SetFlags) +CB(API_GET, Get) +CB(API_GETACTIVE, GetActive) +CB(API_ENUMERATE, Enumerate) +CB(API_CLONE, Clone) +END_DISPATCH; +#undef CBCLASS diff --git a/Src/devices/deviceSupportedCommandStore.h b/Src/devices/deviceSupportedCommandStore.h new file mode 100644 index 00000000..88e6f142 --- /dev/null +++ b/Src/devices/deviceSupportedCommandStore.h @@ -0,0 +1,69 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_STORE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_STORE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + + +#include "./ifc_devicesupportedcommandstore.h" +#include "./deviceSupportedCommand.h" +#include "./ifc_devicesupportedcommandenum.h" +#include <vector> + +class DeviceSupportedCommandStore : public ifc_devicesupportedcommandstore +{ + +protected: + DeviceSupportedCommandStore(); + ~DeviceSupportedCommandStore(); + +public: + static HRESULT CreateInstance(DeviceSupportedCommandStore **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_devicesupportedcommandstore*/ + HRESULT Add(const char *name, DeviceCommandFlags flags); + HRESULT Remove(const char *name); + HRESULT RemoveAll(); + + HRESULT GetFlags(const char *name, DeviceCommandFlags *flagsOut); + HRESULT SetFlags(const char *name, DeviceCommandFlags mask, DeviceCommandFlags value); + + HRESULT Get(const char *name, ifc_devicesupportedcommand **command); + HRESULT GetActive(ifc_devicesupportedcommand **command); + + HRESULT Enumerate(ifc_devicesupportedcommandenum **enumerator); + + HRESULT Clone(ifc_devicesupportedcommandstore **instance, BOOL fullCopy); + +public: + void Lock(); + void Unlock(); + +protected: + static int SearchCallback(const void *key, const void *element); + static int SortCallback(const void *element1, const void *element2); + DeviceSupportedCommand *Find(const char *name, size_t *indexOut); + +protected: + typedef std::vector<DeviceSupportedCommand*> CommandList; + +protected: + size_t ref; + CommandList commandList; + CRITICAL_SECTION lock; + +protected: + RECVS_DISPATCH; + + + +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_STORE_HEADER
\ No newline at end of file diff --git a/Src/devices/deviceType.cpp b/Src/devices/deviceType.cpp new file mode 100644 index 00000000..ae8feabe --- /dev/null +++ b/Src/devices/deviceType.cpp @@ -0,0 +1,200 @@ +#include "main.h" +#include "./deviceType.h" + +#include <strsafe.h> + +DeviceType::DeviceType() + : ref(1), name(NULL), displayName(NULL) +{ + if (FAILED(DeviceIconStore::CreateInstance(&iconStore))) + iconStore = NULL; + + InitializeCriticalSection(&lock); +} + +DeviceType::~DeviceType() +{ + AnsiString_Free(name); + String_Free(displayName); + if (NULL != iconStore) + iconStore->Release(); + + DeleteCriticalSection(&lock); +} + +HRESULT DeviceType::CreateInstance(const char *name, DeviceType **instance) +{ + char *nameCopy; + + if (NULL == instance) + return E_POINTER; + + if (FALSE != IS_STRING_EMPTY(name)) + return E_INVALIDARG; + + *instance = new DeviceType(); + + if (NULL == *instance) + return E_OUTOFMEMORY; + + nameCopy = AnsiString_Duplicate(name); + if (NULL == nameCopy) + { + (*instance)->Release(); + return E_OUTOFMEMORY; + } + + (*instance)->name = nameCopy; + + return S_OK; +} + +size_t DeviceType::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t DeviceType::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int DeviceType::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_DeviceType)) + *object = static_cast<ifc_devicetype*>(this); + else if (IsEqualIID(interface_guid, IFC_DeviceTypeEditor)) + *object = static_cast<ifc_devicetypeeditor*>(this); + else if (IsEqualIID(interface_guid, IFC_DeviceObject)) + *object = static_cast<ifc_deviceobject*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +void DeviceType::Lock() +{ + EnterCriticalSection(&lock); +} + +void DeviceType::Unlock() +{ + LeaveCriticalSection(&lock); +} + +const char *DeviceType::GetName() +{ + return name; +} + +HRESULT DeviceType::GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + if (NULL == iconStore) + hr = E_UNEXPECTED; + else + hr = iconStore->Get(buffer, bufferSize, width, height); + + Unlock(); + + return hr; +} + +HRESULT DeviceType::GetDisplayName(wchar_t *buffer, size_t bufferSize) +{ + HRESULT hr; + + if (NULL == buffer) + return E_POINTER; + + Lock(); + + hr = StringCchCopyExW(buffer, bufferSize, displayName, NULL, NULL, STRSAFE_IGNORE_NULLS); + + Unlock(); + + return hr; +} + +HRESULT DeviceType::GetIconStore(ifc_deviceiconstore **store) +{ + HRESULT hr; + + if (NULL == store) + return E_POINTER; + + Lock(); + + if (NULL == iconStore) + hr = E_UNEXPECTED; + else + { + iconStore->AddRef(); + *store = iconStore; + hr = S_OK; + } + + Unlock(); + + return hr; +} + +HRESULT DeviceType::SetDisplayName(const wchar_t *displayName) +{ + HRESULT hr; + + Lock(); + + String_Free(this->displayName); + this->displayName = String_Duplicate(displayName); + + if (NULL == this->displayName && NULL != displayName) + hr = E_OUTOFMEMORY; + else + hr = S_OK; + + Unlock(); + + return hr; +} + +#define CBCLASS DeviceType +START_MULTIPATCH; + START_PATCH(MPIID_DEVICETYPE) + M_CB(MPIID_DEVICETYPE, ifc_devicetype, ADDREF, AddRef); + M_CB(MPIID_DEVICETYPE, ifc_devicetype, RELEASE, Release); + M_CB(MPIID_DEVICETYPE, ifc_devicetype, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_DEVICETYPE, ifc_devicetype, API_GETNAME, GetName); + M_CB(MPIID_DEVICETYPE, ifc_devicetype, API_GETICON, GetIcon); + M_CB(MPIID_DEVICETYPE, ifc_devicetype, API_GETDISPLAYNAME, GetDisplayName); + NEXT_PATCH(MPIID_DEVICETYPEEDITOR) + M_CB(MPIID_DEVICETYPEEDITOR, ifc_devicetypeeditor, ADDREF, AddRef); + M_CB(MPIID_DEVICETYPEEDITOR, ifc_devicetypeeditor, RELEASE, Release); + M_CB(MPIID_DEVICETYPEEDITOR, ifc_devicetypeeditor, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_DEVICETYPEEDITOR, ifc_devicetypeeditor, API_SETDISPLAYNAME, SetDisplayName); + M_CB(MPIID_DEVICETYPEEDITOR, ifc_devicetypeeditor, API_GETICONSTORE, GetIconStore); + END_PATCH +END_MULTIPATCH;
\ No newline at end of file diff --git a/Src/devices/deviceType.h b/Src/devices/deviceType.h new file mode 100644 index 00000000..9b9caf43 --- /dev/null +++ b/Src/devices/deviceType.h @@ -0,0 +1,59 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "./ifc_devicetype.h" +#include "./ifc_devicetypeeditor.h" +#include "./ifc_deviceiconstore.h" +#include "./deviceIconStore.h" + +#include <bfc/multipatch.h> + +#define MPIID_DEVICETYPE 10 +#define MPIID_DEVICETYPEEDITOR 20 + +class DeviceType : public MultiPatch<MPIID_DEVICETYPE, ifc_devicetype>, + public MultiPatch<MPIID_DEVICETYPEEDITOR, ifc_devicetypeeditor> +{ + +protected: + DeviceType(); + ~DeviceType(); + +public: + static HRESULT CreateInstance(const char *name, DeviceType **instance); + +public: + /* Dispatchable */ + size_t AddRef(); + size_t Release(); + int QueryInterface(GUID interface_guid, void **object); + + /* ifc_devicetype */ + const char *GetName(); + HRESULT GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height); + HRESULT GetDisplayName(wchar_t *buffer, size_t bufferSize); + + /* ifc_devicetypeeditor */ + HRESULT GetIconStore(ifc_deviceiconstore **store); + HRESULT SetDisplayName(const wchar_t *displayName); + +public: + void Lock(); + void Unlock(); + +protected: + size_t ref; + char *name; + wchar_t *displayName; + DeviceIconStore *iconStore; + CRITICAL_SECTION lock; + +protected: + RECVS_MULTIPATCH; +}; + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_HEADER diff --git a/Src/devices/devices.rc b/Src/devices/devices.rc new file mode 100644 index 00000000..c0624c79 --- /dev/null +++ b/Src/devices/devices.rc @@ -0,0 +1,63 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Src/devices/devices.sln b/Src/devices/devices.sln new file mode 100644 index 00000000..9d1b6fc9 --- /dev/null +++ b/Src/devices/devices.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29424.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "devices", "devices.vcxproj", "{06F6E796-653F-48A9-BA2F-46B679D35F9E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Debug|Win32.ActiveCfg = Debug|Win32 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Debug|Win32.Build.0 = Debug|Win32 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Release|Win32.ActiveCfg = Release|Win32 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Release|Win32.Build.0 = Release|Win32 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Debug|x64.ActiveCfg = Debug|x64 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Debug|x64.Build.0 = Debug|x64 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Release|x64.ActiveCfg = Release|x64 + {06F6E796-653F-48A9-BA2F-46B679D35F9E}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D0F6DA48-1297-47B2-83FC-D727EAA945AF} + EndGlobalSection +EndGlobal diff --git a/Src/devices/devices.vcxproj b/Src/devices/devices.vcxproj new file mode 100644 index 00000000..33ce27f7 --- /dev/null +++ b/Src/devices/devices.vcxproj @@ -0,0 +1,323 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{06F6E796-653F-48A9-BA2F-46B679D35F9E}</ProjectGuid> + <RootNamespace>devices</RootNamespace> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..;../wasabi;../agave;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <EnablePREfast>false</EnablePREfast> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <SupportUnloadOfDelayLoadedDLL>true</SupportUnloadOfDelayLoadedDLL> + <ImportLibrary>$(ProjectDir)x86_Debug\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <Xdcmake> + <OutputFile>$(ProjectDir)x86_Debug\$(ProjectName).xml</OutputFile> + </Xdcmake> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..;../wasabi;../agave;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <EnablePREfast>false</EnablePREfast> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <SupportUnloadOfDelayLoadedDLL>true</SupportUnloadOfDelayLoadedDLL> + <ImportLibrary>$(ProjectDir)x64_Debug\$(ProjectName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <Xdcmake> + <OutputFile>$(ProjectDir)x64_Debug\$(ProjectName).xml</OutputFile> + </Xdcmake> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>.;..;../wasabi;../agave;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <SupportUnloadOfDelayLoadedDLL>true</SupportUnloadOfDelayLoadedDLL> + <ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <Xdcmake> + <OutputFile>$(ProjectDir)x86_Release\$(ProjectName).xml</OutputFile> + </Xdcmake> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>.;..;../wasabi;../agave;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <SupportUnloadOfDelayLoadedDLL>true</SupportUnloadOfDelayLoadedDLL> + <ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <Xdcmake> + <OutputFile>$(ProjectDir)x64_Release\$(ProjectName).xml</OutputFile> + </Xdcmake> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\nu\trace.cpp" /> + <ClCompile Include="component.cpp" /> + <ClCompile Include="deviceCommand.cpp" /> + <ClCompile Include="deviceConnection.cpp" /> + <ClCompile Include="deviceEventManager.cpp" /> + <ClCompile Include="deviceIconStore.cpp" /> + <ClCompile Include="deviceManager.cpp" /> + <ClCompile Include="deviceManagerFactory.cpp" /> + <ClCompile Include="deviceObjectEnum.cpp" /> + <ClCompile Include="deviceObjectStore.cpp" /> + <ClCompile Include="deviceSupportedCommand.cpp" /> + <ClCompile Include="deviceSupportedCommandEnum.cpp" /> + <ClCompile Include="deviceSupportedCommandStore.cpp" /> + <ClCompile Include="deviceType.cpp" /> + <ClCompile Include="discoveryMonitor.cpp" /> + <ClCompile Include="main.cpp" /> + <ClCompile Include="plugin.cpp" /> + <ClCompile Include="strings.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\nu\trace.h" /> + <ClInclude Include="api_devicemanager.h" /> + <ClInclude Include="common.h" /> + <ClInclude Include="component.h" /> + <ClInclude Include="deviceCommand.h" /> + <ClInclude Include="deviceConnection.h" /> + <ClInclude Include="deviceEventManager.h" /> + <ClInclude Include="deviceIconStore.h" /> + <ClInclude Include="deviceManager.h" /> + <ClInclude Include="deviceManagerFactory.h" /> + <ClInclude Include="deviceObjectEnum.h" /> + <ClInclude Include="deviceObjectStore.h" /> + <ClInclude Include="deviceSupportedCommand.h" /> + <ClInclude Include="deviceSupportedCommandEnum.h" /> + <ClInclude Include="deviceSupportedCommandStore.h" /> + <ClInclude Include="deviceType.h" /> + <ClInclude Include="discoveryMonitor.h" /> + <ClInclude Include="ifc_device.h" /> + <ClInclude Include="ifc_deviceactivity.h" /> + <ClInclude Include="ifc_devicecommand.h" /> + <ClInclude Include="ifc_devicecommandeditor.h" /> + <ClInclude Include="ifc_deviceconnection.h" /> + <ClInclude Include="ifc_deviceconnectioneditor.h" /> + <ClInclude Include="ifc_deviceevent.h" /> + <ClInclude Include="ifc_deviceeventmanager.h" /> + <ClInclude Include="ifc_deviceiconstore.h" /> + <ClInclude Include="ifc_devicemanagerevent.h" /> + <ClInclude Include="ifc_deviceobject.h" /> + <ClInclude Include="ifc_deviceobjectenum.h" /> + <ClInclude Include="ifc_deviceprovider.h" /> + <ClInclude Include="ifc_devicesupportedcommand.h" /> + <ClInclude Include="ifc_devicesupportedcommandenum.h" /> + <ClInclude Include="ifc_devicesupportedcommandstore.h" /> + <ClInclude Include="ifc_devicetype.h" /> + <ClInclude Include="ifc_devicetypeeditor.h" /> + <ClInclude Include="main.h" /> + <ClInclude Include="plugin.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="strings.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="devices.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Wasabi\Wasabi.vcxproj"> + <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Src/devices/devices.vcxproj.filters b/Src/devices/devices.vcxproj.filters new file mode 100644 index 00000000..6c7f4487 --- /dev/null +++ b/Src/devices/devices.vcxproj.filters @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="..\nu\trace.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="component.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceCommand.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceConnection.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceEventManager.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceIconStore.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceManager.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceManagerFactory.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceObjectEnum.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceObjectStore.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceSupportedCommand.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceSupportedCommandEnum.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceSupportedCommandStore.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="deviceType.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="discoveryMonitor.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="plugin.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="strings.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="api_devicemanager.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="component.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceCommand.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceConnection.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceEventManager.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceIconStore.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceManager.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceManagerFactory.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceObjectEnum.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceObjectStore.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceSupportedCommand.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceSupportedCommandEnum.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceSupportedCommandStore.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="deviceType.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_device.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="discoveryMonitor.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceactivity.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicecommand.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicecommandeditor.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceconnection.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceconnectioneditor.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceevent.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceeventmanager.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceiconstore.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicemanagerevent.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceobject.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceobjectenum.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_deviceprovider.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicesupportedcommand.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicesupportedcommandenum.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicesupportedcommandstore.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicetype.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ifc_devicetypeeditor.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="main.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="plugin.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="strings.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\nu\trace.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{f4644265-34b9-4067-a619-473804a3f141}</UniqueIdentifier> + </Filter> + <Filter Include="Ressource Files"> + <UniqueIdentifier>{1284fd85-642e-4ad1-8852-9ac396edb47e}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{cdd62d9b-fcfc-49c5-bbb9-ab546b57bb1e}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="devices.rc"> + <Filter>Ressource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Src/devices/discoveryMonitor.cpp b/Src/devices/discoveryMonitor.cpp new file mode 100644 index 00000000..3a42bd08 --- /dev/null +++ b/Src/devices/discoveryMonitor.cpp @@ -0,0 +1,105 @@ +#include "main.h" +#include "./discoveryMonitor.h" + +DiscoveryMonitor::DiscoveryMonitor() +{ + InitializeCriticalSection(&lock); +} + +DiscoveryMonitor::~DiscoveryMonitor() +{ + DeleteCriticalSection(&lock); +} + +void DiscoveryMonitor::Lock() +{ + EnterCriticalSection(&lock); +} + +void DiscoveryMonitor::Unlock() +{ + LeaveCriticalSection(&lock); +} + +BOOL DiscoveryMonitor::Register(ifc_deviceprovider *provider) +{ + Lock(); + + size_t index = activityList.size(); + while(index--) + { + ActiveDiscovery *entry = &activityList[index]; + if ((intptr_t)provider == entry->providerId) + { + entry->ref++; + Unlock(); + return FALSE; + } + } + + ActiveDiscovery record; + record.providerId = (intptr_t)provider; + record.ref = 1; + + activityList.push_back(record); + index = activityList.size(); + + Unlock(); + return (1 == index); +} + +BOOL DiscoveryMonitor::Unregister(ifc_deviceprovider *provider) +{ + Lock(); + + size_t index = activityList.size(); + while(index--) + { + ActiveDiscovery *entry = &activityList[index]; + if ((intptr_t)provider == entry->providerId) + { + if (1 == entry->ref) + { + activityList.erase(activityList.begin() + index); + index = activityList.size(); + Unlock(); + return (0 == index); + } + + entry->ref--; + break; + } + } + + Unlock(); + return FALSE; +} + +BOOL DiscoveryMonitor::IsActive() +{ + size_t count; + + Lock(); + + count = activityList.size(); + + Unlock(); + + return (0 != count); +} + +BOOL DiscoveryMonitor::Reset() +{ + size_t count; + + Lock(); + + count = activityList.size(); + activityList.clear(); + + Unlock(); + + return (0 != count); +} + + diff --git a/Src/devices/discoveryMonitor.h b/Src/devices/discoveryMonitor.h new file mode 100644 index 00000000..7b838c15 --- /dev/null +++ b/Src/devices/discoveryMonitor.h @@ -0,0 +1,43 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DISCOVERY_MONITOR_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DISCOVERY_MONITOR_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include "ifc_deviceprovider.h" +#include <vector> + +class DiscoveryMonitor +{ +public: + DiscoveryMonitor(); + ~DiscoveryMonitor(); + +public: + BOOL Register(ifc_deviceprovider *provider); + BOOL Unregister(ifc_deviceprovider *provider); + BOOL IsActive(); + BOOL Reset(); + +protected: + void Lock(); + void Unlock(); + +private: + typedef struct ActiveDiscovery + { + intptr_t providerId; + size_t ref; + } ActiveDiscovery; + + typedef std::vector<ActiveDiscovery> ActivityList; + +private: + CRITICAL_SECTION lock; + ActivityList activityList; +}; + + + +#endif // _NULLSOFT_WINAMP_DEVICES_DISCOVERY_MONITOR_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_device.h b/Src/devices/ifc_device.h new file mode 100644 index 00000000..b672b1e8 --- /dev/null +++ b/Src/devices/ifc_device.h @@ -0,0 +1,203 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {CAC1D7F6-AA27-47eb-BAF7-512BAAE04F07} +static const GUID IFC_Device = +{ 0xcac1d7f6, 0xaa27, 0x47eb, { 0xba, 0xf7, 0x51, 0x2b, 0xaa, 0xe0, 0x4f, 0x7 } }; + +#include "ifc_deviceobject.h" + +class ifc_deviceevent; +class ifc_devicesupportedcommandenum; +class ifc_deviceactivity; + +typedef enum DeviceCommandFlags DeviceCommandFlags; +typedef enum DeviceCommandContext DeviceCommandContext; + + +class __declspec(novtable) ifc_device : public ifc_deviceobject +{ +protected: + ifc_device() {} + ~ifc_device() {} + +public: + const char *GetType(); + const char *GetDisplayType(); + const char *GetConnection(); + + BOOL GetHidden(); + + HRESULT GetTotalSpace(uint64_t *size); + HRESULT GetUsedSpace(uint64_t *size); + + BOOL GetAttached(); + HRESULT Attach(HWND hostWindow); + HRESULT Detach(HWND hostWindow); + + HRESULT EnumerateCommands(ifc_devicesupportedcommandenum **enumerator, DeviceCommandContext context); + HRESULT SendCommand(const char *command, HWND hostWindow, ULONG_PTR param); + HRESULT GetCommandFlags(const char *command, DeviceCommandFlags *flags); + + HRESULT GetActivity(ifc_deviceactivity **activity); + + HRESULT Advise(ifc_deviceevent *handler); + HRESULT Unadvise(ifc_deviceevent *handler); + + HWND CreateView(HWND parentWindow); + void SetNavigationItem(void *navigationItem); + + HRESULT GetDropSupported(unsigned int dataType); + HRESULT Drop(void *data, unsigned int dataType); + + HRESULT SetDisplayName(const wchar_t *displayName); + + HRESULT GetModel(wchar_t *buffer, size_t bufferSize); // - end-user-visible name for the end produt. + HRESULT GetStatus(wchar_t *buffer, size_t bufferSize); // - free-form status message (example: "Last synchronized 19:20 01/10/10"). + +public: + DISPATCH_CODES + { + API_GETTYPE = 10, + API_GETCONNECTION = 20, + API_GETHIDDEN = 30, + API_GETTOTALSPACE = 40, + API_GETUSEDSPACE = 50, + API_GETATTACHED = 60, + API_ATTACH = 70, + API_DETACH = 80, + API_ENUMERATECOMMANDS = 90, + API_SENDCOMMAND = 100, + API_GETCOMMANDFLAGS = 110, + API_GETACTIVITY = 120, + API_ADVISE = 130, + API_UNADVISE = 140, + API_CREATEVIEW = 150, + API_SETNAVIGATIONITEM = 160, + API_GETDROPSUPPORTED = 170, + API_DROP = 180, + API_SETDISPLAYNAME = 190, + API_GETMODEL = 200, + API_GETSTATUS = 210, + API_GETDISPLAYTYPE = 220, + }; +}; + + +inline const char *ifc_device::GetType() +{ + return _call(API_GETTYPE, (const char*)NULL); +} + +inline const char *ifc_device::GetDisplayType() +{ + return _call(API_GETDISPLAYTYPE, (const char*)NULL); +} + +inline const char *ifc_device::GetConnection() +{ + return _call(API_GETCONNECTION, (const char*)NULL); +} + +inline BOOL ifc_device::GetHidden() +{ + return _call(API_GETHIDDEN, (BOOL)FALSE); +} + +inline HRESULT ifc_device::GetTotalSpace(uint64_t *size) +{ + return _call(API_GETTOTALSPACE, (HRESULT)E_NOTIMPL, size); +} + +inline HRESULT ifc_device::GetUsedSpace(uint64_t *size) +{ + return _call(API_GETUSEDSPACE, (HRESULT)E_NOTIMPL, size); +} + +inline BOOL ifc_device::GetAttached() +{ + return _call(API_GETATTACHED, (BOOL)FALSE); +} + +inline HRESULT ifc_device::Attach(HWND hostWindow) +{ + return _call(API_ATTACH, (HRESULT)E_NOTIMPL, hostWindow); +} + +inline HRESULT ifc_device::Detach(HWND hostWindow) +{ + return _call(API_DETACH, (HRESULT)E_NOTIMPL, hostWindow); +} + +inline HRESULT ifc_device::EnumerateCommands(ifc_devicesupportedcommandenum **enumerator, DeviceCommandContext context) +{ + return _call(API_ENUMERATECOMMANDS, (HRESULT)E_NOTIMPL, enumerator, context); +} + +inline HRESULT ifc_device::SendCommand(const char *command, HWND hostWindow, ULONG_PTR param) +{ + return _call(API_SENDCOMMAND, (HRESULT)E_NOTIMPL, command, hostWindow, param); +} + +inline HRESULT ifc_device::GetCommandFlags(const char *command, DeviceCommandFlags *flags) +{ + return _call(API_GETCOMMANDFLAGS, (HRESULT)E_NOTIMPL, command, flags); +} + +inline HRESULT ifc_device::GetActivity(ifc_deviceactivity **activity) +{ + return _call(API_GETACTIVITY, (HRESULT)E_NOTIMPL, activity); +} + +inline HRESULT ifc_device::Advise(ifc_deviceevent *handler) +{ + return _call(API_ADVISE, (HRESULT)E_NOTIMPL, handler); +} + +inline HRESULT ifc_device::Unadvise(ifc_deviceevent *handler) +{ + return _call(API_UNADVISE, (HRESULT)E_NOTIMPL, handler); +} + +inline HWND ifc_device::CreateView(HWND parentWindow) +{ + return _call(API_CREATEVIEW, (HWND)NULL, parentWindow); +} + +inline void ifc_device::SetNavigationItem(void *navigationItem) +{ + _voidcall(API_SETNAVIGATIONITEM, navigationItem); +} + +inline HRESULT ifc_device::GetDropSupported(unsigned int dataType) +{ + return _call(API_GETDROPSUPPORTED, (HRESULT)E_NOTIMPL, dataType); +} + +inline HRESULT ifc_device::Drop(void *data, unsigned int dataType) +{ + return _call(API_DROP, (HRESULT)E_NOTIMPL, data, dataType); +} + +inline HRESULT ifc_device::SetDisplayName(const wchar_t *displayName) +{ + return _call(API_SETDISPLAYNAME, (HRESULT)E_NOTIMPL, displayName); +} + +inline HRESULT ifc_device::GetModel(wchar_t *buffer, size_t bufferSize) +{ + return _call(API_GETMODEL, (HRESULT)E_NOTIMPL, buffer, bufferSize); +} + +inline HRESULT ifc_device::GetStatus(wchar_t *buffer, size_t bufferSize) +{ + return _call(API_GETSTATUS, (HRESULT)E_NOTIMPL, buffer, bufferSize); +} + +#endif // _NULLSOFT_WINAMP_DEVICES_DEVICE_INTERFACE_HEADER diff --git a/Src/devices/ifc_deviceactivity.h b/Src/devices/ifc_deviceactivity.h new file mode 100644 index 00000000..357bdbc1 --- /dev/null +++ b/Src/devices/ifc_deviceactivity.h @@ -0,0 +1,74 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_ACTIVITY_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_ACTIVITY_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {6FE2E838-6C56-4b14-8CE0-FA9B19113DA5} +static const GUID IFC_DeviceActivity = +{ 0x6fe2e838, 0x6c56, 0x4b14, { 0x8c, 0xe0, 0xfa, 0x9b, 0x19, 0x11, 0x3d, 0xa5 } }; + + +#include <bfc/dispatch.h> + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_deviceactivity: public Dispatchable +{ +protected: + ifc_deviceactivity() {} + ~ifc_deviceactivity() {} + +public: + BOOL GetActive(); + BOOL GetCancelable(); + HRESULT GetProgress(unsigned int *percentCompleted); + HRESULT GetDisplayName(wchar_t *buffer, size_t bufferMax); + HRESULT GetStatus(wchar_t *buffer, size_t bufferMax); + HRESULT Cancel(HWND hostWindow); + +public: + DISPATCH_CODES + { + API_GETACTIVE = 10, + API_GETCANCELABLE = 20, + API_GETPROGRESS = 30, + API_GETDISPLAYNAME = 40, + API_GETSTATUS = 50, + API_CANCEL = 60, + }; +}; + +inline BOOL ifc_deviceactivity::GetActive() +{ + return _call(API_GETACTIVE, (BOOL)FALSE); +} + +inline BOOL ifc_deviceactivity::GetCancelable() +{ + return _call(API_GETCANCELABLE, (BOOL)FALSE); +} + +inline HRESULT ifc_deviceactivity::GetProgress(unsigned int *percentCompleted) +{ + return _call(API_GETPROGRESS, (HRESULT)E_NOTIMPL, percentCompleted); +} + +inline HRESULT ifc_deviceactivity::GetDisplayName(wchar_t *buffer, size_t bufferMax) +{ + return _call(API_GETDISPLAYNAME, (HRESULT)E_NOTIMPL, buffer, bufferMax); +} + +inline HRESULT ifc_deviceactivity::GetStatus(wchar_t *buffer, size_t bufferMax) +{ + return _call(API_GETSTATUS, (HRESULT)E_NOTIMPL, buffer, bufferMax); +} + +inline HRESULT ifc_deviceactivity::Cancel(HWND hostWindow) +{ + return _call(API_CANCEL, (HRESULT)E_NOTIMPL, hostWindow); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_ACTIVITY_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicecommand.h b/Src/devices/ifc_devicecommand.h new file mode 100644 index 00000000..810f40b2 --- /dev/null +++ b/Src/devices/ifc_devicecommand.h @@ -0,0 +1,58 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {52C5C581-65DC-435e-AEFA-1616CB81B283} +static const GUID IFC_DeviceCommand = +{ 0x52c5c581, 0x65dc, 0x435e, { 0xae, 0xfa, 0x16, 0x16, 0xcb, 0x81, 0xb2, 0x83 } }; + + +#include "ifc_deviceobject.h" + +typedef enum DeviceCommandFlags +{ + DeviceCommandFlag_None = 0, + DeviceCommandFlag_Primary = (1 << 0), + DeviceCommandFlag_Disabled = (1 << 1), + DeviceCommandFlag_Active = (1 << 2), + DeviceCommandFlag_Hidden = (1 << 3), + DeviceCommandFlag_Group = (1 << 4), +}DeviceCommandFlags; +DEFINE_ENUM_FLAG_OPERATORS(DeviceCommandFlags); + +typedef enum DeviceCommandContext +{ + DeviceCommandContext_Unknown = 0, + DeviceCommandContext_NavigationMenu = 1, + DeviceCommandContext_ViewMenu = 2, + DeviceCommandContext_View = 3, + +} DeviceCommandContext; + +class __declspec(novtable) ifc_devicecommand : public ifc_deviceobject +{ +protected: + ifc_devicecommand() {} + ~ifc_devicecommand() {} + +public: + HRESULT GetDescription(wchar_t *buffer, size_t bufferSize); + +public: + DISPATCH_CODES + { + API_GETDESCRIPTION = 10, + }; +}; + +inline HRESULT ifc_devicecommand::GetDescription(wchar_t *buffer, size_t bufferSize) +{ + return _call(API_GETDESCRIPTION, (HRESULT)E_NOTIMPL, buffer, bufferSize); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicecommandeditor.h b/Src/devices/ifc_devicecommandeditor.h new file mode 100644 index 00000000..678610bd --- /dev/null +++ b/Src/devices/ifc_devicecommandeditor.h @@ -0,0 +1,55 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_EDITOR_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_EDITOR_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {94A35125-3AD5-4339-870E-4ACB24F00FE8} +static const GUID IFC_DeviceCommandEditor = +{ 0x94a35125, 0x3ad5, 0x4339, { 0x87, 0xe, 0x4a, 0xcb, 0x24, 0xf0, 0xf, 0xe8 } }; + + +#include <bfc/dispatch.h> + +class ifc_deviceiconstore; + +class __declspec(novtable) ifc_devicecommandeditor : public Dispatchable +{ +protected: + ifc_devicecommandeditor() {} + ~ifc_devicecommandeditor() {} + +public: + HRESULT GetIconStore(ifc_deviceiconstore **iconStore); + HRESULT SetDisplayName(const wchar_t *displayName); + HRESULT SetDescription(const wchar_t *description); + +public: + DISPATCH_CODES + { + API_GETICONSTORE = 10, + API_SETDISPLAYNAME = 20, + API_SETDESCRIPTION = 30, + }; +}; + +inline HRESULT ifc_devicecommandeditor::GetIconStore(ifc_deviceiconstore **iconStore) +{ + return _call(API_GETICONSTORE, (HRESULT)E_NOTIMPL, iconStore); +} + +inline HRESULT ifc_devicecommandeditor::SetDisplayName(const wchar_t *displayName) +{ + return _call(API_SETDISPLAYNAME, (HRESULT)E_NOTIMPL, displayName); +} + +inline HRESULT ifc_devicecommandeditor::SetDescription(const wchar_t *description) +{ + return _call(API_SETDESCRIPTION, (HRESULT)E_NOTIMPL, description); +} + + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_EDITOR_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicecommandinfo.h b/Src/devices/ifc_devicecommandinfo.h new file mode 100644 index 00000000..3e327728 --- /dev/null +++ b/Src/devices/ifc_devicecommandinfo.h @@ -0,0 +1,50 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_INFO_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_INFO_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + + +// {EFFB983B-D087-4021-8894-BA795626048B} +static const GUID IFC_DeviceCommandInfo = +{ 0xeffb983b, 0xd087, 0x4021, { 0x88, 0x94, 0xba, 0x79, 0x56, 0x26, 0x4, 0x8b } }; + +#include <bfc/dispatch.h> + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_devicecommandinfo : public Dispatchable +{ +protected: + ifc_devicecommandinfo() {} + ~ifc_devicecommandinfo() {} + +public: + const wchar_t *GetName(); + HRESULT GetState(DeviceCommandState *state); + +public: + DISPATCH_CODES + { + API_GETNAME = 10, + API_GETSTATE = 20, + }; +}; + + +inline const wchar_t *ifc_devicetype::GetName() +{ + return _call(API_GETNAME, (const wchar_t *)NULL); +} + +inline HRESULT ifc_devicetype::GetIcon(wchar_t *buffer, size_t bufferSize, DeviceIconType preferredType) +{ + return _call(API_GETICON, (HRESULT)E_NOTIMPL, buffer, bufferSize, preferredType); +} + +inline HRESULT ifc_devicetype::GetDisplayName(wchar_t *buffer, size_t bufferSize) +{ + return _call(API_GETDISPLAYNAME, (HRESULT)E_NOTIMPL, buffer, bufferSize); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_COMMAND_INFO_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceconnection.h b/Src/devices/ifc_deviceconnection.h new file mode 100644 index 00000000..84eed307 --- /dev/null +++ b/Src/devices/ifc_deviceconnection.h @@ -0,0 +1,24 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {0CF89CC5-AD4E-4c81-AF74-AB2FDB6F56CE} +static const GUID IFC_DeviceConnection = +{ 0xcf89cc5, 0xad4e, 0x4c81, { 0xaf, 0x74, 0xab, 0x2f, 0xdb, 0x6f, 0x56, 0xce } }; + +#include "ifc_deviceobject.h" + +class __declspec(novtable) ifc_deviceconnection : public ifc_deviceobject +{ +protected: + ifc_deviceconnection() {} + ~ifc_deviceconnection() {} + +}; + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceconnectioneditor.h b/Src/devices/ifc_deviceconnectioneditor.h new file mode 100644 index 00000000..6d9c5a09 --- /dev/null +++ b/Src/devices/ifc_deviceconnectioneditor.h @@ -0,0 +1,49 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_EDITOR_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_EDITOR_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {B4CAEAF3-4488-4313-8A66-DEA916DEFCCC} +static const GUID IFC_DeviceConnectionEditor = +{ 0xb4caeaf3, 0x4488, 0x4313, { 0x8a, 0x66, 0xde, 0xa9, 0x16, 0xde, 0xfc, 0xcc } }; + + + +#include <bfc/dispatch.h> + +class ifc_deviceiconstore; + +class __declspec(novtable) ifc_deviceconnectioneditor : public Dispatchable +{ +protected: + ifc_deviceconnectioneditor() {} + ~ifc_deviceconnectioneditor() {} + +public: + HRESULT GetIconStore(ifc_deviceiconstore **iconStore); + HRESULT SetDisplayName(const wchar_t *displayName); + +public: + DISPATCH_CODES + { + API_GETICONSTORE = 10, + API_SETDISPLAYNAME = 20, + }; +}; + +inline HRESULT ifc_deviceconnectioneditor::GetIconStore(ifc_deviceiconstore **iconStore) +{ + return _call(API_GETICONSTORE, (HRESULT)E_NOTIMPL, iconStore); +} + +inline HRESULT ifc_deviceconnectioneditor::SetDisplayName(const wchar_t *displayName) +{ + return _call(API_SETDISPLAYNAME, (HRESULT)E_NOTIMPL, displayName); +} + + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_CONNECTION_EDITOR_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceevent.h b/Src/devices/ifc_deviceevent.h new file mode 100644 index 00000000..feda77f2 --- /dev/null +++ b/Src/devices/ifc_deviceevent.h @@ -0,0 +1,119 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {4D0B21E9-B3D0-4f51-8264-575CBF6A2CFA} +static const GUID IFC_DeviceEvent = +{ 0x4d0b21e9, 0xb3d0, 0x4f51, { 0x82, 0x64, 0x57, 0x5c, 0xbf, 0x6a, 0x2c, 0xfa } }; + +#include <bfc/dispatch.h> + +class ifc_device; +class ifc_deviceactivity; + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_deviceevent : public Dispatchable +{ +protected: + ifc_deviceevent() {} + ~ifc_deviceevent() {} + +public: + void IconChanged(ifc_device *device); + void DisplayNameChanged(ifc_device *device, const wchar_t *displayName); + void AttachmentChanged(ifc_device *device, BOOL attached); + void VisibilityChanged(ifc_device *device, BOOL visible); + void TotalSpaceChanged(ifc_device *device, uint64_t space); + void UsedSpaceChanged(ifc_device *device, uint64_t space); + void CommandChanged(ifc_device *device); + void ActivityStarted(ifc_device *device, ifc_deviceactivity *activity); + void ActivityFinished(ifc_device *device, ifc_deviceactivity *activity); + void ActivityChanged(ifc_device *device, ifc_deviceactivity *activity); + void ModelChanged(ifc_device *device, const wchar_t *model); + void StatusChanged(ifc_device *device, const wchar_t *status); + + +public: + DISPATCH_CODES + { + API_ICONCHANGED = 10, + API_DISPLAYNAMECHANGED = 20, + API_ATTACHMENTCHANGED = 30, + API_VISIBILITYCHANGED = 40, + API_TOTALSPACECHANGED = 50, + API_USEDSPACECHANGED = 60, + API_COMMANDCHANGED = 70, + API_ACTIVITYSTARTED = 80, + API_ACTIVITYFINISHED = 90, + API_ACTIVITYCHANGED = 100, + API_MODELCHANGED = 110, + API_STATUSCHANGED = 120, + }; +}; + +inline void ifc_deviceevent::IconChanged(ifc_device *device) +{ + _voidcall(API_ICONCHANGED, device); +} + +inline void ifc_deviceevent::DisplayNameChanged(ifc_device *device, const wchar_t *displayName) +{ + _voidcall(API_DISPLAYNAMECHANGED, device, displayName); +} + +inline void ifc_deviceevent::AttachmentChanged(ifc_device *device, BOOL attached) +{ + _voidcall(API_ATTACHMENTCHANGED, device, attached); +} + +inline void ifc_deviceevent::VisibilityChanged(ifc_device *device, BOOL visible) +{ + _voidcall(API_VISIBILITYCHANGED, device, visible); +} + +inline void ifc_deviceevent::TotalSpaceChanged(ifc_device *device, uint64_t space) +{ + _voidcall(API_TOTALSPACECHANGED, device, space); +} + +inline void ifc_deviceevent::UsedSpaceChanged(ifc_device *device, uint64_t space) +{ + _voidcall(API_USEDSPACECHANGED, device, space); +} + +inline void ifc_deviceevent::CommandChanged(ifc_device *device) +{ + _voidcall(API_COMMANDCHANGED, device); +} + +inline void ifc_deviceevent::ActivityStarted(ifc_device *device, ifc_deviceactivity *activity) +{ + _voidcall(API_ACTIVITYSTARTED, device, activity); +} + +inline void ifc_deviceevent::ActivityFinished(ifc_device *device, ifc_deviceactivity *activity) +{ + _voidcall(API_ACTIVITYFINISHED, device, activity); +} + +inline void ifc_deviceevent::ActivityChanged(ifc_device *device, ifc_deviceactivity *activity) +{ + _voidcall(API_ACTIVITYCHANGED, device, activity); +} + +inline void ifc_deviceevent::ModelChanged(ifc_device *device, const wchar_t *model) +{ + _voidcall(API_MODELCHANGED, device, model); +} + +inline void ifc_deviceevent::StatusChanged(ifc_device *device, const wchar_t *status) +{ + _voidcall(API_STATUSCHANGED, device, status); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceeventmanager.h b/Src/devices/ifc_deviceeventmanager.h new file mode 100644 index 00000000..287a81fe --- /dev/null +++ b/Src/devices/ifc_deviceeventmanager.h @@ -0,0 +1,133 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_MANAGER_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_MANAGER_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {C563C537-DFFC-4210-BB1E-E424426789E2} +static const GUID IFC_DeviceEventManager = +{ 0xc563c537, 0xdffc, 0x4210, { 0xbb, 0x1e, 0xe4, 0x24, 0x42, 0x67, 0x89, 0xe2 } }; + +#include <bfc/dispatch.h> + +class ifc_deviceevent; + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_deviceeventmanager : public Dispatchable +{ +protected: + ifc_deviceeventmanager() {} + ~ifc_deviceeventmanager() {} + +public: + HRESULT Advise(ifc_deviceevent *handler); + HRESULT Unadvise(ifc_deviceevent *handler); + + void Notify_IconChanged(ifc_device *device); + void Notify_DisplayNameChanged(ifc_device *device, const wchar_t *displayName); + void Notify_AttachmentChanged(ifc_device *device, BOOL attached); + void Notify_VisibilityChanged(ifc_device *device, BOOL visible); + void Notify_TotalSpaceChanged(ifc_device *device, uint64_t space); + void Notify_UsedSpaceChanged(ifc_device *device, uint64_t space); + void Notify_CommandChanged(ifc_device *device); + void Notify_ActivityStarted(ifc_device *device, ifc_deviceactivity *activity); + void Notify_ActivityFinished(ifc_device *device, ifc_deviceactivity *activity); + void Notify_ActivityChanged(ifc_device *device, ifc_deviceactivity *activity); + void Notify_ModelChanged(ifc_device *device, const wchar_t *model); + void Notify_StatusChanged(ifc_device *device, const wchar_t *status); + +public: + DISPATCH_CODES + { + API_ADVISE = 10, + API_UNADVISE = 20, + API_NOTIFY_ICONCHANGED = 30, + API_NOTIFY_DISPLAYNAMECHANGED = 40, + API_NOTIFY_ATTACHMENTCHANGED = 50, + API_NOTIFY_VISIBILITYCHANGED = 60, + API_NOTIFY_TOTALSPACECHANGED = 70, + API_NOTIFY_USEDSPACECHANGED = 80, + API_NOTIFY_COMMANDCHANGED = 90, + API_NOTIFY_ACTIVITYSTARTED = 100, + API_NOTIFY_ACTIVITYFINISHED = 110, + API_NOTIFY_ACTIVITYCHANGED = 120, + API_NOTIFY_MODELCHANGED = 130, + API_NOTIFY_STATUSCHANGED = 140, + }; +}; + +inline HRESULT ifc_deviceeventmanager::Advise(ifc_deviceevent *handler) +{ + return _call(API_ADVISE, (HRESULT)E_NOTIMPL, handler); +} + +inline HRESULT ifc_deviceeventmanager::Unadvise(ifc_deviceevent *handler) +{ + return _call(API_UNADVISE, (HRESULT)E_NOTIMPL, handler); +} + +inline void ifc_deviceeventmanager::Notify_IconChanged(ifc_device *device) +{ + _voidcall(API_NOTIFY_ICONCHANGED, device); +} + +inline void ifc_deviceeventmanager::Notify_DisplayNameChanged(ifc_device *device, const wchar_t *displayName) +{ + _voidcall(API_NOTIFY_DISPLAYNAMECHANGED, device, displayName); +} + +inline void ifc_deviceeventmanager::Notify_AttachmentChanged(ifc_device *device, BOOL attached) +{ + _voidcall(API_NOTIFY_ATTACHMENTCHANGED, device, attached); +} + +inline void ifc_deviceeventmanager::Notify_VisibilityChanged(ifc_device *device, BOOL visible) +{ + _voidcall(API_NOTIFY_VISIBILITYCHANGED, device, visible); +} + +inline void ifc_deviceeventmanager::Notify_TotalSpaceChanged(ifc_device *device, uint64_t space) +{ + _voidcall(API_NOTIFY_TOTALSPACECHANGED, device, space); +} + +inline void ifc_deviceeventmanager::Notify_UsedSpaceChanged(ifc_device *device, uint64_t space) +{ + _voidcall(API_NOTIFY_USEDSPACECHANGED, device, space); +} + + +inline void ifc_deviceeventmanager::Notify_CommandChanged(ifc_device *device) +{ + _voidcall(API_NOTIFY_COMMANDCHANGED, device); +} + +inline void ifc_deviceeventmanager::Notify_ActivityStarted(ifc_device *device, ifc_deviceactivity *activity) +{ + _voidcall(API_NOTIFY_ACTIVITYSTARTED, device, activity); +} + +inline void ifc_deviceeventmanager::Notify_ActivityFinished(ifc_device *device, ifc_deviceactivity *activity) +{ + _voidcall(API_NOTIFY_ACTIVITYFINISHED, device, activity); +} + +inline void ifc_deviceeventmanager::Notify_ActivityChanged(ifc_device *device, ifc_deviceactivity *activity) +{ + _voidcall(API_NOTIFY_ACTIVITYCHANGED, device, activity); +} + +inline void ifc_deviceeventmanager::Notify_ModelChanged(ifc_device *device, const wchar_t *model) +{ + _voidcall(API_NOTIFY_MODELCHANGED, device, model); +} + +inline void ifc_deviceeventmanager::Notify_StatusChanged(ifc_device *device, const wchar_t *status) +{ + _voidcall(API_NOTIFY_STATUSCHANGED, device, status); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_EVENT_MANAGER_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceiconstore.h b/Src/devices/ifc_deviceiconstore.h new file mode 100644 index 00000000..03939c9c --- /dev/null +++ b/Src/devices/ifc_deviceiconstore.h @@ -0,0 +1,107 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_ICON_STORE_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_ICON_STORE_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {0CEFAC39-DCA5-4c6f-89E3-1C7573B98664} +static const GUID IFC_DeviceIconStore = +{ 0xcefac39, 0xdca5, 0x4c6f, { 0x89, 0xe3, 0x1c, 0x75, 0x73, 0xb9, 0x86, 0x64 } }; + +#include <bfc/dispatch.h> + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_deviceiconstore : public Dispatchable +{ +public: + typedef BOOL (*EnumeratorCallback)(const wchar_t *path, unsigned int width, unsigned int height, void *user); + +protected: + ifc_deviceiconstore() {} + ~ifc_deviceiconstore() {} + +public: + HRESULT Add(const wchar_t *path, unsigned int width, unsigned int height, BOOL replaceExisting); + HRESULT Remove(unsigned int width, unsigned int height); + HRESULT RemovePath(const wchar_t *path); + HRESULT RemoveAll(); + HRESULT Get(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height); + HRESULT GetExact(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height); + + HRESULT SetBasePath(const wchar_t *path); + HRESULT GetBasePath(wchar_t *buffer, size_t bufferMax); + + HRESULT Clone(ifc_deviceiconstore **instance); + + HRESULT Enumerate(EnumeratorCallback callback, void *user); + +public: + DISPATCH_CODES + { + API_ADD = 10, + API_REMOVE = 20, + API_REMOVEPATH = 30, + API_REMOVEALL = 40, + API_GET = 50, + API_GETEXACT = 60, + API_GETBASEPATH = 70, + API_SETBASEPATH = 80, + API_CLONE = 90, + API_ENUMERATE = 100, + }; +}; + +inline HRESULT ifc_deviceiconstore::Add(const wchar_t *path, unsigned int width, unsigned int height, BOOL replaceExisting) +{ + return _call(API_ADD, (HRESULT)E_NOTIMPL, path, width, height, replaceExisting); +} + +inline HRESULT ifc_deviceiconstore::Remove(unsigned int width, unsigned int height) +{ + return _call(API_REMOVE, (HRESULT)E_NOTIMPL, width, height); +} + +inline HRESULT ifc_deviceiconstore::RemovePath(const wchar_t *path) +{ + return _call(API_REMOVEPATH, (HRESULT)E_NOTIMPL, path); +} + +inline HRESULT ifc_deviceiconstore::RemoveAll() +{ + return _call(API_REMOVEALL, (HRESULT)E_NOTIMPL); +} + +inline HRESULT ifc_deviceiconstore::Get(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height) +{ + return _call(API_GET, (HRESULT)E_NOTIMPL, buffer, bufferMax, width, height); +} + +inline HRESULT ifc_deviceiconstore::GetExact(wchar_t *buffer, size_t bufferMax, unsigned int width, unsigned int height) +{ + return _call(API_GETEXACT, (HRESULT)E_NOTIMPL, buffer, bufferMax, width, height); +} + +inline HRESULT ifc_deviceiconstore::SetBasePath(const wchar_t *path) +{ + return _call(API_SETBASEPATH, (HRESULT)E_NOTIMPL, path); +} + +inline HRESULT ifc_deviceiconstore::GetBasePath(wchar_t *buffer, size_t bufferMax) +{ + return _call(API_GETBASEPATH, (HRESULT)E_NOTIMPL, buffer, bufferMax); +} + +inline HRESULT ifc_deviceiconstore::Clone(ifc_deviceiconstore **instance) +{ + return _call(API_CLONE, (HRESULT)E_NOTIMPL, instance); +} + +inline HRESULT ifc_deviceiconstore::Enumerate(EnumeratorCallback callback, void *user) +{ + return _call(API_ENUMERATE, (HRESULT)E_NOTIMPL, callback, user); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_ICON_STORE_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicemanagerevent.h b/Src/devices/ifc_devicemanagerevent.h new file mode 100644 index 00000000..68cc1c14 --- /dev/null +++ b/Src/devices/ifc_devicemanagerevent.h @@ -0,0 +1,104 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_EVENT_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_EVENT_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {3D58B8B4-74C8-4fa2-B28D-86E96ABC7200} +static const GUID IFC_DeviceManagerEvent = +{ 0x3d58b8b4, 0x74c8, 0x4fa2, { 0xb2, 0x8d, 0x86, 0xe9, 0x6a, 0xbc, 0x72, 0x0 } }; + + +#include <bfc/dispatch.h> + +class api_devicemanager; + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_devicemanagerevent : public Dispatchable +{ +protected: + ifc_devicemanagerevent() {} + ~ifc_devicemanagerevent() {} + +public: + void TypeAdded(api_devicemanager *manager, ifc_devicetype *type); + void TypeRemoved(api_devicemanager *manager, ifc_devicetype *type); + void ConnectionAdded(api_devicemanager *manager, ifc_deviceconnection *connection); + void ConnectionRemoved(api_devicemanager *manager, ifc_deviceconnection *connection); + void CommandAdded(api_devicemanager *manager, ifc_devicecommand *command); + void CommandRemoved(api_devicemanager *manager, ifc_devicecommand *command); + void DeviceAdded(api_devicemanager *manager, ifc_device *device); + void DeviceRemoved(api_devicemanager *manager, ifc_device *device); + void DiscoveryStarted(api_devicemanager *manager); + void DiscoveryFinished(api_devicemanager *manager); + +public: + DISPATCH_CODES + { + API_TYPEADDED = 10, + API_TYPEREMOVED = 20, + API_CONNECTIONADDED = 30, + API_CONNECTIONREMOVED = 40, + API_COMMANDADDED = 50, + API_COMMANDREMOVED = 60, + API_DEVICEADDED = 70, + API_DEVICEREMOVED = 80, + API_DISCOVERYSTARTED = 90, + API_DISCOVERYFINISHED = 100, + }; +}; + +inline void ifc_devicemanagerevent::TypeAdded(api_devicemanager *manager, ifc_devicetype *type) +{ + _voidcall(API_TYPEADDED, manager, type); +} + +inline void ifc_devicemanagerevent::TypeRemoved(api_devicemanager *manager, ifc_devicetype *type) +{ + _voidcall(API_TYPEREMOVED, manager, type); +} + +inline void ifc_devicemanagerevent::ConnectionAdded(api_devicemanager *manager, ifc_deviceconnection *connection) +{ + _voidcall(API_CONNECTIONADDED, manager, connection); +} + +inline void ifc_devicemanagerevent::ConnectionRemoved(api_devicemanager *manager, ifc_deviceconnection *connection) +{ + _voidcall(API_CONNECTIONREMOVED, manager, connection); +} + +inline void ifc_devicemanagerevent::CommandAdded(api_devicemanager *manager, ifc_devicecommand *command) +{ + _voidcall(API_COMMANDADDED, manager, command); +} + +inline void ifc_devicemanagerevent::CommandRemoved(api_devicemanager *manager, ifc_devicecommand *command) +{ + _voidcall(API_COMMANDREMOVED, manager, command); +} + +inline void ifc_devicemanagerevent::DeviceAdded(api_devicemanager *manager, ifc_device *device) +{ + _voidcall(API_DEVICEADDED, manager, device); +} + +inline void ifc_devicemanagerevent::DeviceRemoved(api_devicemanager *manager, ifc_device *device) +{ + _voidcall(API_DEVICEREMOVED, manager, device); +} + +inline void ifc_devicemanagerevent::DiscoveryStarted(api_devicemanager *manager) +{ + _voidcall(API_DISCOVERYSTARTED, manager); +} + +inline void ifc_devicemanagerevent::DiscoveryFinished(api_devicemanager *manager) +{ + _voidcall(API_DISCOVERYFINISHED, manager); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_MANAGER_EVENT_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceobject.h b/Src/devices/ifc_deviceobject.h new file mode 100644 index 00000000..3653e649 --- /dev/null +++ b/Src/devices/ifc_deviceobject.h @@ -0,0 +1,55 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {90A1273D-3E52-415f-ADC1-F151E6240C5B} +static const GUID IFC_DeviceObject = +{ 0x90a1273d, 0x3e52, 0x415f, { 0xad, 0xc1, 0xf1, 0x51, 0xe6, 0x24, 0xc, 0x5b } }; + + +#include <bfc/dispatch.h> + + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_deviceobject : public Dispatchable +{ +protected: + ifc_deviceobject() {} + ~ifc_deviceobject() {} + +public: + const char *GetName(); + HRESULT GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height); + HRESULT GetDisplayName(wchar_t *buffer, size_t bufferSize); + +public: + DISPATCH_CODES + { + API_GETNAME = -10, + API_GETICON = -11, + API_GETDISPLAYNAME = -12, + }; +}; + + +inline const char *ifc_deviceobject::GetName() +{ + return _call(API_GETNAME, (const char *)NULL); +} + +inline HRESULT ifc_deviceobject::GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height) +{ + return _call(API_GETICON, (HRESULT)E_NOTIMPL, buffer, bufferSize, width, height); +} + +inline HRESULT ifc_deviceobject::GetDisplayName(wchar_t *buffer, size_t bufferSize) +{ + return _call(API_GETDISPLAYNAME, (HRESULT)E_NOTIMPL, buffer, bufferSize); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_deviceobjectenum.h b/Src/devices/ifc_deviceobjectenum.h new file mode 100644 index 00000000..5dcfbaf6 --- /dev/null +++ b/Src/devices/ifc_deviceobjectenum.h @@ -0,0 +1,63 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_ENUMERATOR_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_ENUMERATOR_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {21135710-8161-46c8-83C5-134CC1E832DF} +static const GUID IFC_DeviceObjectEnum = +{ 0x21135710, 0x8161, 0x46c8, { 0x83, 0xc5, 0x13, 0x4c, 0xc1, 0xe8, 0x32, 0xdf } }; + + +#include <bfc/dispatch.h> + +class ifc_deviceobject; + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_deviceobjectenum : public Dispatchable +{ +protected: + ifc_deviceobjectenum() {} + ~ifc_deviceobjectenum() {} + +public: + HRESULT Next(ifc_deviceobject **buffer, size_t bufferMax, size_t *fetched); + HRESULT Reset(void); + HRESULT Skip(size_t count); + HRESULT GetCount(size_t *count); + +public: + DISPATCH_CODES + { + API_NEXT = 10, + API_RESET = 20, + API_SKIP = 30, + API_GETCOUNT = 40, + + }; +}; + +inline HRESULT ifc_deviceobjectenum::Next(ifc_deviceobject **buffer, size_t bufferMax, size_t *fetched) +{ + return _call(API_NEXT, (HRESULT)E_NOTIMPL, buffer, bufferMax, fetched); +} + +inline HRESULT ifc_deviceobjectenum::Reset(void) +{ + return _call(API_RESET, (HRESULT)E_NOTIMPL); +} + +inline HRESULT ifc_deviceobjectenum::Skip(size_t count) +{ + return _call(API_SKIP, (HRESULT)E_NOTIMPL, count); +} + +inline HRESULT ifc_deviceobjectenum::GetCount(size_t *count) +{ + return _call(API_GETCOUNT, (HRESULT)E_NOTIMPL, count); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_OBJECT_ENUMERATOR_INTERFACE_HEADER diff --git a/Src/devices/ifc_deviceprovider.h b/Src/devices/ifc_deviceprovider.h new file mode 100644 index 00000000..6f5f5da6 --- /dev/null +++ b/Src/devices/ifc_deviceprovider.h @@ -0,0 +1,54 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_PROVIDER_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_PROVIDER_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {FAC6EBEE-107A-4133-A620-856A281EC704} +static const GUID IFC_DeviceProvider = +{ 0xfac6ebee, 0x107a, 0x4133, { 0xa6, 0x20, 0x85, 0x6a, 0x28, 0x1e, 0xc7, 0x4 } }; + +#include <bfc/dispatch.h> + +class api_devicemanager; + +class __declspec(novtable) ifc_deviceprovider : public Dispatchable +{ +protected: + ifc_deviceprovider() {} + ~ifc_deviceprovider() {} + +public: + HRESULT BeginDiscovery(api_devicemanager *manager); + HRESULT CancelDiscovery(); + HRESULT GetActive(); + +public: + DISPATCH_CODES + { + API_BEGINDISCOVERY = 10, + API_CANCELDISCOVERY = 20, + API_GETACTIVE = 30, + }; +}; + + +inline HRESULT ifc_deviceprovider::BeginDiscovery(api_devicemanager *manager) +{ + return _call(API_BEGINDISCOVERY, (HRESULT)E_NOTIMPL, manager); +} + +inline HRESULT ifc_deviceprovider::CancelDiscovery() +{ + return _call(API_CANCELDISCOVERY, (HRESULT)E_NOTIMPL); +} + +inline HRESULT ifc_deviceprovider::GetActive() +{ + return _call(API_GETACTIVE, (HRESULT)E_NOTIMPL); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_PROVIDER_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicesupportedcommand.h b/Src/devices/ifc_devicesupportedcommand.h new file mode 100644 index 00000000..f7dc4c7d --- /dev/null +++ b/Src/devices/ifc_devicesupportedcommand.h @@ -0,0 +1,46 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {EFFB983B-D087-4021-8894-BA795626048B} +static const GUID IFC_DeviceSupportedCommand = +{ 0xeffb983b, 0xd087, 0x4021, { 0x88, 0x94, 0xba, 0x79, 0x56, 0x26, 0x4, 0x8b } }; + + +#include <bfc/dispatch.h> + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_devicesupportedcommand : public Dispatchable +{ +protected: + ifc_devicesupportedcommand() {} + ~ifc_devicesupportedcommand() {} + +public: + const char *GetName(); + HRESULT GetFlags(DeviceCommandFlags *flags); + +public: + DISPATCH_CODES + { + API_GETNAME = 10, + API_GETFLAGS = 20, + }; +}; + +inline const char *ifc_devicesupportedcommand::GetName() +{ + return _call(API_GETNAME, (const char *)NULL); +} + +inline HRESULT ifc_devicesupportedcommand::GetFlags(DeviceCommandFlags *flags) +{ + return _call(API_GETFLAGS, (HRESULT)E_NOTIMPL, flags); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicesupportedcommandenum.h b/Src/devices/ifc_devicesupportedcommandenum.h new file mode 100644 index 00000000..ca68df50 --- /dev/null +++ b/Src/devices/ifc_devicesupportedcommandenum.h @@ -0,0 +1,63 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_ENUMERATOR_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_ENUMERATOR_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {BE64390B-D4D0-41d5-87A7-60597F410D97} +static const GUID IFC_DeviceSupportedCommandEnum = +{ 0xbe64390b, 0xd4d0, 0x41d5, { 0x87, 0xa7, 0x60, 0x59, 0x7f, 0x41, 0xd, 0x97 } }; + + +#include <bfc/dispatch.h> + +class ifc_devicesupportedcommand; + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_devicesupportedcommandenum : public Dispatchable +{ +protected: + ifc_devicesupportedcommandenum() {} + ~ifc_devicesupportedcommandenum() {} + +public: + HRESULT Next(ifc_devicesupportedcommand **buffer, size_t bufferMax, size_t *count); + HRESULT Reset(void); + HRESULT Skip(size_t count); + HRESULT GetCount(size_t *count); + +public: + DISPATCH_CODES + { + API_NEXT = 10, + API_RESET = 20, + API_SKIP = 30, + API_GETCOUNT = 40, + }; +}; + +inline HRESULT ifc_devicesupportedcommandenum::Next(ifc_devicesupportedcommand **buffer, size_t bufferMax, size_t *count) +{ + return _call(API_NEXT, (HRESULT)E_NOTIMPL, buffer, bufferMax, count); +} + +inline HRESULT ifc_devicesupportedcommandenum::Reset(void) +{ + return _call(API_RESET, (HRESULT)E_NOTIMPL); +} + +inline HRESULT ifc_devicesupportedcommandenum::Skip(size_t count) +{ + return _call(API_SKIP, (HRESULT)E_NOTIMPL, count); +} + +inline HRESULT ifc_devicesupportedcommandenum::GetCount(size_t *count) +{ + return _call(API_GETCOUNT, (HRESULT)E_NOTIMPL, count); +} + + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_ENUMERATOR_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicesupportedcommandstore.h b/Src/devices/ifc_devicesupportedcommandstore.h new file mode 100644 index 00000000..26373fd8 --- /dev/null +++ b/Src/devices/ifc_devicesupportedcommandstore.h @@ -0,0 +1,102 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_STORE_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_STORE_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {098C1639-7E02-4f03-9F75-B871EC867E61} +static const GUID IFC_DeviceSupportedCommandStore = +{ 0x98c1639, 0x7e02, 0x4f03, { 0x9f, 0x75, 0xb8, 0x71, 0xec, 0x86, 0x7e, 0x61 } }; + + +#include <bfc/dispatch.h> + +class ifc_devicesupportedcommand; + +// supports AddRef(), Release(), QueryInterface() +class __declspec(novtable) ifc_devicesupportedcommandstore : public Dispatchable +{ +protected: + ifc_devicesupportedcommandstore() {} + ~ifc_devicesupportedcommandstore() {} + +public: + HRESULT Add(const char *name, DeviceCommandFlags flags); + HRESULT Remove(const char *name); + HRESULT RemoveAll(); + + HRESULT GetFlags(const char *name, DeviceCommandFlags *flagsOut); + HRESULT SetFlags(const char *name, DeviceCommandFlags mask, DeviceCommandFlags value); + + HRESULT Get(const char *name, ifc_devicesupportedcommand **command); + HRESULT GetActive(ifc_devicesupportedcommand **command); + + HRESULT Enumerate(ifc_devicesupportedcommandenum **enumerator); + + HRESULT Clone(ifc_devicesupportedcommandstore **instance, BOOL fullCopy); + +public: + DISPATCH_CODES + { + API_ADD = 10, + API_REMOVE = 20, + API_REMOVEALL = 30, + API_GETFLAGS = 40, + API_SETFLAGS = 50, + API_GET = 60, + API_GETACTIVE = 70, + API_ENUMERATE = 80, + API_CLONE = 90, + }; +}; + + +inline HRESULT ifc_devicesupportedcommandstore::Add(const char *name, DeviceCommandFlags flags) +{ + return _call(API_ADD, (HRESULT)E_NOTIMPL, name, flags); +} + +inline HRESULT ifc_devicesupportedcommandstore::Remove(const char *name) +{ + return _call(API_REMOVE, (HRESULT)E_NOTIMPL, name); +} + +inline HRESULT ifc_devicesupportedcommandstore::RemoveAll() +{ + return _call(API_REMOVEALL, (HRESULT)E_NOTIMPL); +} + +inline HRESULT ifc_devicesupportedcommandstore::GetFlags(const char *name, DeviceCommandFlags *flagsOut) +{ + return _call(API_GETFLAGS, (HRESULT)E_NOTIMPL, name, flagsOut); +} + +inline HRESULT ifc_devicesupportedcommandstore::SetFlags(const char *name, DeviceCommandFlags mask, DeviceCommandFlags value) +{ + return _call(API_SETFLAGS, (HRESULT)E_NOTIMPL, name, mask, value); +} + +inline HRESULT ifc_devicesupportedcommandstore::Get(const char *name, ifc_devicesupportedcommand **command) +{ + return _call(API_GET, (HRESULT)E_NOTIMPL, name, command); +} + +inline HRESULT ifc_devicesupportedcommandstore::GetActive(ifc_devicesupportedcommand **command) +{ + return _call(API_GETACTIVE, (HRESULT)E_NOTIMPL, command); +} + +inline HRESULT ifc_devicesupportedcommandstore::Enumerate(ifc_devicesupportedcommandenum **enumerator) +{ + return _call(API_ENUMERATE, (HRESULT)E_NOTIMPL, enumerator); +} + +inline HRESULT ifc_devicesupportedcommandstore::Clone(ifc_devicesupportedcommandstore **instance, BOOL fullCopy) +{ + return _call(API_CLONE, (HRESULT)E_NOTIMPL, instance, fullCopy); +} + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_SUPPORTED_COMMAND_STORE_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicetype.h b/Src/devices/ifc_devicetype.h new file mode 100644 index 00000000..e03aaa68 --- /dev/null +++ b/Src/devices/ifc_devicetype.h @@ -0,0 +1,25 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {C2AB1F06-1D88-4d21-A8F4-1B36A1929281} +static const GUID IFC_DeviceType = +{ 0xc2ab1f06, 0x1d88, 0x4d21, { 0xa8, 0xf4, 0x1b, 0x36, 0xa1, 0x92, 0x92, 0x81 } }; + + +#include "ifc_deviceobject.h" + +class __declspec(novtable) ifc_devicetype : public ifc_deviceobject +{ +protected: + ifc_devicetype() {} + ~ifc_devicetype() {} + +}; + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/ifc_devicetypeeditor.h b/Src/devices/ifc_devicetypeeditor.h new file mode 100644 index 00000000..e6f3c817 --- /dev/null +++ b/Src/devices/ifc_devicetypeeditor.h @@ -0,0 +1,47 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_EDITOR_INTERFACE_HEADER +#define _NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_EDITOR_INTERFACE_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <bfc/platform/guid.h> + +// {D6CE88AA-94F1-4c7f-BEDB-A45B637CF804} +static const GUID IFC_DeviceTypeEditor = +{ 0xd6ce88aa, 0x94f1, 0x4c7f, { 0xbe, 0xdb, 0xa4, 0x5b, 0x63, 0x7c, 0xf8, 0x4 } }; + +#include <bfc/dispatch.h> + +class ifc_deviceiconstore; + +class __declspec(novtable) ifc_devicetypeeditor : public Dispatchable +{ +protected: + ifc_devicetypeeditor() {} + ~ifc_devicetypeeditor() {} + +public: + HRESULT GetIconStore(ifc_deviceiconstore **iconStore); + HRESULT SetDisplayName(const wchar_t *displayName); + +public: + DISPATCH_CODES + { + API_GETICONSTORE = 10, + API_SETDISPLAYNAME = 20, + }; +}; + +inline HRESULT ifc_devicetypeeditor::GetIconStore(ifc_deviceiconstore **iconStore) +{ + return _call(API_GETICONSTORE, (HRESULT)E_NOTIMPL, iconStore); +} + +inline HRESULT ifc_devicetypeeditor::SetDisplayName(const wchar_t *displayName) +{ + return _call(API_SETDISPLAYNAME, (HRESULT)E_NOTIMPL, displayName); +} + + +#endif //_NULLSOFT_WINAMP_DEVICES_DEVICE_TYPE_EDITOR_INTERFACE_HEADER
\ No newline at end of file diff --git a/Src/devices/main.cpp b/Src/devices/main.cpp new file mode 100644 index 00000000..707f9b5f --- /dev/null +++ b/Src/devices/main.cpp @@ -0,0 +1,3 @@ +#include <initguid.h> + +#include "main.h" diff --git a/Src/devices/main.h b/Src/devices/main.h new file mode 100644 index 00000000..6e20467d --- /dev/null +++ b/Src/devices/main.h @@ -0,0 +1,48 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_MAIN_HEADER +#define _NULLSOFT_WINAMP_DEVICES_MAIN_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <wtypes.h> + +#include "./common.h" +#include "./strings.h" +#include "./plugin.h" +#include "./ifc_deviceobject.h" +#include "./ifc_deviceobjectenum.h" +#include "./api_devicemanager.h" +#include "./ifc_device.h" +#include "./ifc_devicetype.h" +#include "./ifc_devicetypeeditor.h" +#include "./ifc_devicecommand.h" +#include "./ifc_devicecommandeditor.h" +#include "./ifc_deviceconnection.h" +#include "./ifc_deviceconnectioneditor.h" +#include "./ifc_deviceevent.h" +#include "./ifc_deviceeventmanager.h" +#include "./ifc_deviceprovider.h" +#include "./ifc_devicesupportedcommand.h" +#include "./ifc_devicesupportedcommandenum.h" +#include "./ifc_deviceiconstore.h" +#include "./deviceManager.h" +#include "./deviceEventManager.h" +#include "./deviceObjectStore.h" +#include "./deviceObjectEnum.h" +#include "./deviceCommand.h" +#include "./deviceSupportedCommand.h" +#include "./deviceSupportedCommandStore.h" +#include "./deviceSupportedCommandEnum.h" +#include "./deviceType.h" +#include "./deviceConnection.h" +#include "./deviceIconStore.h" +#include "./component.h" + + +#include "../nu/trace.h" + +#include <math.h> +#include <shlwapi.h> + +#endif //_NULLSOFT_WINAMP_DEVICES_MAIN_HEADER
\ No newline at end of file diff --git a/Src/devices/plugin.cpp b/Src/devices/plugin.cpp new file mode 100644 index 00000000..60c4e0df --- /dev/null +++ b/Src/devices/plugin.cpp @@ -0,0 +1,31 @@ +#include "main.h" +#include "./plugin.h" +#include "./component.h" + +static HINSTANCE pluginInstance = NULL; +static DevicesComponent component; + +HINSTANCE +Plugin_GetInstance() +{ + return pluginInstance; +} + +extern "C" __declspec(dllexport) ifc_wa5component * +GetWinamp5SystemComponent() +{ + return &component; +} + + +BOOL APIENTRY +DllMain(HANDLE hModule, DWORD uReason, void *reserved) +{ + switch(uReason) + { + case DLL_PROCESS_ATTACH: + pluginInstance = (HINSTANCE)hModule; + break; + } + return TRUE; +} diff --git a/Src/devices/plugin.h b/Src/devices/plugin.h new file mode 100644 index 00000000..767c4cc6 --- /dev/null +++ b/Src/devices/plugin.h @@ -0,0 +1,14 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_PLUGIN_HEADER +#define _NULLSOFT_WINAMP_DEVICES_PLUGIN_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#include <wtypes.h> + +HINSTANCE +Plugin_GetInstance(void); + + +#endif //_NULLSOFT_WINAMP_DEVICES_PLUGIN_HEADER
\ No newline at end of file diff --git a/Src/devices/resource.h b/Src/devices/resource.h new file mode 100644 index 00000000..f1cbc7b3 --- /dev/null +++ b/Src/devices/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by devices.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Src/devices/strings.cpp b/Src/devices/strings.cpp new file mode 100644 index 00000000..f3d4b5cc --- /dev/null +++ b/Src/devices/strings.cpp @@ -0,0 +1,152 @@ +#include "main.h" +#include "./strings.h" +#include <strsafe.h> + + +wchar_t * +String_Malloc(size_t size) +{ + return (wchar_t *)calloc(size, sizeof(wchar_t)); +} + +wchar_t * +String_ReAlloc(wchar_t *string, size_t size) +{ + return (wchar_t *)realloc(string, sizeof(wchar_t) * size); +} + +void +String_Free(wchar_t *string) +{ + if (NULL != string) + free(string); +} + +wchar_t * +String_Duplicate(const wchar_t *string) +{ + int length; + wchar_t *copy; + + if (NULL == string) + return NULL; + + length = lstrlenW(string) + 1; + + copy = String_Malloc(length); + if (NULL != copy) + CopyMemory(copy, string, sizeof(wchar_t) * length); + + return copy; +} + + +char * +String_ToAnsi(unsigned int codePage, unsigned long flags, const wchar_t *string, + int stringLength, const char *defaultChar, BOOL *usedDefaultChar) +{ + char *buffer; + int bufferSize; + + if (stringLength < 0) + stringLength = lstrlen(string); + + bufferSize = WideCharToMultiByte(codePage, flags, string, stringLength, + NULL, 0, defaultChar, usedDefaultChar); + if (0 == bufferSize) + return NULL; + + buffer = AnsiString_Malloc(bufferSize + 1); + if (NULL == buffer) + return NULL; + + bufferSize = WideCharToMultiByte(codePage, flags, string, stringLength, + buffer, bufferSize, defaultChar, usedDefaultChar); + if (0 == bufferSize) + { + AnsiString_Free(buffer); + return NULL; + } + buffer[bufferSize] = '\0'; + return buffer; +} + +size_t +String_CopyTo(wchar_t *destination, const wchar_t *source, size_t size) +{ + size_t remaining; + if (FAILED(StringCchCopyExW(destination, size, source, NULL, &remaining, 0))) + return 0; + + return (size - remaining); +} + +char * +AnsiString_Malloc(size_t size) +{ + return (char*)calloc(size, sizeof(char)); +} + +char * +AnsiString_ReAlloc(char *string, size_t size) +{ + return (char*)realloc(string, sizeof(char) * size); +} + +void +AnsiString_Free(char *string) +{ + if (NULL != string) + free(string); +} + +char * +AnsiString_Duplicate(const char *string) +{ + char *copy; + INT length; + + if (NULL == string) + return NULL; + + length = lstrlenA(string) + 1; + + copy = AnsiString_Malloc(length); + if (NULL != copy) + CopyMemory(copy, string, sizeof(char) * length); + + return copy; +} + + +wchar_t * +AnsiString_ToUnicode(unsigned int codePage, unsigned long flags, const char* string, INT stringLength) +{ + wchar_t *buffer; + int buffferSize; + + if (NULL == string) + return NULL; + + buffferSize = MultiByteToWideChar(codePage, flags, string, stringLength, NULL, 0); + if (0 == buffferSize) + return NULL; + + if (stringLength > 0) + buffferSize++; + + buffer = String_Malloc(buffferSize); + if (NULL == buffer) + return NULL; + + if (0 == MultiByteToWideChar(codePage, flags, string, stringLength, buffer, buffferSize)) + { + String_Free(buffer); + return NULL; + } + + if (stringLength > 0) + buffer[buffferSize - 1] = L'\0'; + + return buffer; +}
\ No newline at end of file diff --git a/Src/devices/strings.h b/Src/devices/strings.h new file mode 100644 index 00000000..c5a0316c --- /dev/null +++ b/Src/devices/strings.h @@ -0,0 +1,59 @@ +#ifndef _NULLSOFT_WINAMP_DEVICES_STRINGS_HEADER +#define _NULLSOFT_WINAMP_DEVICES_STRINGS_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#define IS_STRING_EMPTY(_string) (NULL == (_string) || L'\0' == *(_string)) + +wchar_t * +String_Malloc(size_t size); + +wchar_t * +String_ReAlloc(wchar_t *string, + size_t size); + +void +String_Free(wchar_t *string); + +wchar_t * +String_Duplicate(const wchar_t *string); + +char * +String_ToAnsi(unsigned int codePage, + unsigned long flags, + const wchar_t *string, + int stringLength, + const char *defaultChar, + BOOL *usedDefaultChar); + +size_t +String_CopyTo(wchar_t *destination, + const wchar_t *source, + size_t size); + +/* + Ansi String +*/ + +char * +AnsiString_Malloc(size_t size); + +char * +AnsiString_ReAlloc(char *string, + size_t size); + +void +AnsiString_Free(char *string); + +char * +AnsiString_Duplicate(const char *string); + +wchar_t * +AnsiString_ToUnicode(unsigned int codePage, + unsigned long flags, + const char *string, + int stringLength); + +#endif //_NULLSOFT_WINAMP_DEVICES_STRINGS_HEADER
\ No newline at end of file diff --git a/Src/devices/version.rc2 b/Src/devices/version.rc2 new file mode 100644 index 00000000..4a0e82ec --- /dev/null +++ b/Src/devices/version.rc2 @@ -0,0 +1,39 @@ + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "../Winamp/buildType.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINAMP_PRODUCTVER + PRODUCTVERSION WINAMP_PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Winamp SA" + VALUE "FileDescription", "Winamp 5.x System Component" + VALUE "FileVersion", STR_WINAMP_PRODUCTVER + VALUE "InternalName", "devices.w5s" + VALUE "LegalCopyright", "Copyright © 2006-2023 Winamp SA" + VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA" + VALUE "OriginalFilename", "devices.w5s" + VALUE "ProductName", "Winamp Devices Support Service" + VALUE "ProductVersion", STR_WINAMP_PRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END |