diff options
Diffstat (limited to 'Src/Plugins/Library/ml_online/serviceHost.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_online/serviceHost.cpp | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_online/serviceHost.cpp b/Src/Plugins/Library/ml_online/serviceHost.cpp new file mode 100644 index 00000000..e907e345 --- /dev/null +++ b/Src/Plugins/Library/ml_online/serviceHost.cpp @@ -0,0 +1,394 @@ +#include "main.h" +#include "./serviceHost.h" +#include "./api__ml_online.h" +#include "./resource.h" +#include "./external.h" +#include "./navigation.h" +#include "./commands.h" +#include "./serviceHelper.h" + +#include <ifc_omservice.h> +#include <ifc_omserviceeditor.h> +#include <ifc_omservicecommand.h> + +#include <ifc_omstoragehelper.h> +#include <ifc_omstoragehandlerenum.h> +#include <ifc_omfilestorage.h> + +#include "../winamp/IWasabiDispatchable.h" +#include "../winamp/JSAPI_Info.h" + +#include <shlwapi.h> +#include <strsafe.h> + + +#define IS_INVALIDISPATCH(__disp) (((IDispatch *)1) == (__disp) || NULL == (__disp)) + +static ServiceHost *cachedInstance = NULL; + +static void CALLBACK StorageHandler_ReadAuth(ifc_omservice *service, LPCWSTR pszKey, LPCWSTR pszValue) +{ + INT iVal; + UINT flags = (NULL != pszValue && + FALSE != StrToIntEx(pszValue, STIF_SUPPORT_HEX, &iVal) && + 0 != iVal) ? + SVCF_USECLIENTOWEB : 0; + + ServiceHelper_SetFlags(service, flags, SVCF_USECLIENTOWEB); +} + + +static void CALLBACK StorageHandler_ReadBypass(ifc_omservice *service, LPCWSTR pszKey, LPCWSTR pszValue) +{ + INT iVal; + UINT flags = (NULL != pszValue && + FALSE != StrToIntEx(pszValue, STIF_SUPPORT_HEX, &iVal) && + 0 != iVal) ? + SVCF_PREAUTHORIZED : 0; + + ServiceHelper_SetFlags(service, flags, SVCF_PREAUTHORIZED); + +} + +static void CALLBACK StorageHandler_ReadSubscribed(ifc_omservice *service, LPCWSTR pszKey, LPCWSTR pszValue) +{ + INT iVal; + UINT flags = (NULL != pszValue && + FALSE != StrToIntEx(pszValue, STIF_SUPPORT_HEX, &iVal) && + 0 != iVal) ? + SVCF_SUBSCRIBED : 0; + + flags |= SVCF_AUTOUPGRADE; + ServiceHelper_SetFlags(service, flags, SVCF_SUBSCRIBED | SVCF_AUTOUPGRADE); + +} + +static const ifc_omstoragehelper::TemplateRecord szStorageExtXml[] = +{ + { L"auth", StorageHandler_ReadAuth }, + { L"bypass", StorageHandler_ReadBypass }, +}; + +static const ifc_omstoragehelper::TemplateRecord szStorageExtIni[] = +{ + { L"subscribed", StorageHandler_ReadSubscribed }, +}; + +ServiceHost::ServiceHost() + : ref(1), storageExtXml(NULL), storageExtIni(NULL) +{ + +} + +ServiceHost::~ServiceHost() +{ + if (NULL != storageExtXml) + storageExtXml->Release(); + + if (NULL != storageExtIni) + storageExtIni->Release(); +} + +HRESULT ServiceHost::CreateInstance(ServiceHost **instance) +{ + if (NULL == instance) + return E_POINTER; + + *instance = new ServiceHost(); + if (NULL == instance) return E_OUTOFMEMORY; + + return S_OK; +} + +HRESULT ServiceHost::GetCachedInstance(ServiceHost **instance) +{ + if (NULL == instance) + return E_POINTER; + + + if (NULL == cachedInstance) + { + HRESULT hr = CreateInstance(&cachedInstance); + if (FAILED(hr)) + { + *instance = NULL; + return hr; + } + } + + cachedInstance->AddRef(); + *instance = cachedInstance; + return S_OK; +} + +HRESULT ServiceHost::ReleseCache() +{ + if (NULL == cachedInstance) + return S_FALSE; + + ServiceHost *t = cachedInstance; + cachedInstance = NULL; + t->Release(); + + return S_OK; +} + +size_t ServiceHost::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t ServiceHost::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int ServiceHost::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_OmServiceHost)) + *object = static_cast<ifc_omservicehost*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceEvent)) + *object = static_cast<ifc_omserviceevent*>(this); + else if (IsEqualIID(interface_guid, IFC_OmStorageExt)) + *object = static_cast<ifc_omstorageext*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + + +HRESULT ServiceHost::GetExternal(ifc_omservice *service, IDispatch **ppDispatch) +{ + if (NULL == ppDispatch) + return E_POINTER; + + if (NULL != *ppDispatch) + { + // try to connect our external + IWasabiDispatchable *pWasabi; + if (SUCCEEDED((*ppDispatch)->QueryInterface(IID_IWasabiDispatchable, (void**)&pWasabi))) + { + JSAPI::ifc_info *pInfo; + if (SUCCEEDED(pWasabi->QueryDispatchable(JSAPI::IID_JSAPI_ifc_info, (Dispatchable**)&pInfo))) + { + ExternalDispatch *pExternal; + if (SUCCEEDED(ExternalDispatch::CreateInstance(&pExternal))) + { + pInfo->AddAPI(pExternal->GetName(), pExternal); + pExternal->Release(); + } + pInfo->Release(); + } + pWasabi->Release(); + } + } + + return S_OK; +} + +HRESULT ServiceHost::GetBasePath(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax) +{ + if (NULL == pszBuffer) + return E_POINTER; + + return StringCchCopy(pszBuffer, cchBufferMax, L".\\Plugins\\ml\\omServices"); +} + +HRESULT ServiceHost::GetDefaultName(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax) +{ + if (NULL == pszBuffer) + return E_POINTER; + + if (NULL == service) + return E_INVALIDARG; + + return StringCchPrintf(pszBuffer, cchBufferMax, L"omService_{%010u}.ini", service->GetId()); +} + +HRESULT ServiceHost::QueryCommandState(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId) +{ + if (NULL == service || NULL == commandGroup) + return E_NOTIMPL; + + if (IsEqualGUID(*commandGroup, CMDGROUP_SERVICE)) + { + switch(commandId) + { + case SVCCOMMAND_SHOWINFO: + case SVCCOMMAND_REPORT: + case SVCCOMMAND_UNSUBSCRIBE: + case SVCCOMMAND_RATE: + if (S_FALSE == ServiceHelper_IsSpecial(service)) + { + return CMDSTATE_ENABLED; + } + return CMDSTATE_UNKNOWN; + + case SVCCOMMAND_BLOCKNAV: + { + UINT flags; + if (FAILED(service->GetFlags(&flags))) + flags = 0; + + HRESULT state = (0 == (SVCF_VERSIONCHECK & flags)) ? + CMDSTATE_DISABLED : CMDSTATE_ENABLED; + + ServiceHelper_UpdateOperationInfo(hBrowser); + return state; + } + break; + } + } + return E_NOTIMPL; +} + +HRESULT ServiceHost::ExecuteCommand(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg) +{ + if (IsEqualGUID(CMDGROUP_SERVICE, *commandGroup)) + { + if (S_OK != ServiceHelper_IsSpecial(service)) + { + switch(commandId) + { + case SVCCOMMAND_SHOWINFO: Command_ShowServiceInfo(service); return S_OK; + case SVCCOMMAND_REPORT: Command_ReportService(service); return S_OK; + case SVCCOMMAND_UNSUBSCRIBE: Command_UnsubscribeService(service); return S_OK; + case SVCCOMMAND_RATE: Command_SetServiceRating(service, (UINT)commandArg); return S_OK; + } + } + } + + return E_NOTIMPL; +} + +void ServiceHost::ServiceChange(ifc_omservice *service, UINT nModified) +{ + if (NULL == service) return; + + Navigation *navigation; + if (SUCCEEDED(Plugin_GetNavigation(&navigation))) + { + navigation->UpdateService(service, nModified); + navigation->Release(); + } + +} + +HRESULT ServiceHost::EnumerateStorageExt(const GUID *storageId, ifc_omstoragehandlerenum **enumerator) +{ + if (NULL == storageId) + return E_INVALIDARG; + + if (IsEqualGUID(SUID_OmStorageXml, *storageId)) + { + if (NULL == storageExtXml) + { + ifc_omstoragehelper *storageHelper; + if (NULL != OMUTILITY && SUCCEEDED(OMUTILITY->GetStorageHelper(&storageHelper))) + { + if (FAILED(storageHelper->CreateEnumerator(szStorageExtXml, ARRAYSIZE(szStorageExtXml), &storageExtXml))) + storageExtXml = NULL; + storageHelper->Release(); + + } + + if (NULL == storageExtXml) + return E_FAIL; + } + + *enumerator = storageExtXml; + storageExtXml->AddRef(); + return S_OK; + } + else if (IsEqualGUID(SUID_OmStorageIni, *storageId)) + { + if (NULL == storageExtIni) + { + ifc_omstoragehelper *storageHelper; + if (NULL != OMUTILITY && SUCCEEDED(OMUTILITY->GetStorageHelper(&storageHelper))) + { + if (FAILED(storageHelper->CreateEnumerator(szStorageExtIni, ARRAYSIZE(szStorageExtIni), &storageExtIni))) + storageExtIni = NULL; + storageHelper->Release(); + + } + + if (NULL == storageExtIni) + return E_FAIL; + } + + *enumerator = storageExtIni; + storageExtIni->AddRef(); + return S_OK; + + } + return E_NOTIMPL; +} + +HRESULT ServiceHost::GetUrl(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax) +{ + UINT flags; + if (NULL != service && SUCCEEDED(service->GetFlags(&flags)) && + 0 != (SVCF_USECLIENTOWEB & flags) && NULL != AGAVE_API_AUTH) + { + LPWSTR pszUrl = Plugin_CopyString(pszBuffer); + if (NULL == pszUrl) return E_OUTOFMEMORY; + + HRESULT hr(E_NOTIMPL); + + if (0 == AGAVE_API_AUTH->ClientToWeb(GUID_NULL, pszUrl, pszBuffer, cchBufferMax)) + hr = S_OK; + + Plugin_FreeString(pszUrl); + return hr; + } + + return E_NOTIMPL; +} + +#define CBCLASS ServiceHost +START_MULTIPATCH; + START_PATCH(MPIID_OMSVCHOST) + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, ADDREF, AddRef); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, RELEASE, Release); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETEXTERNAL, GetExternal); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETBASEPATH, GetBasePath); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETDEFAULTNAME, GetDefaultName); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_QUERYCOMMANDSTATE, QueryCommandState); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_EXECUTECOMMAND, ExecuteCommand); + M_CB(MPIID_OMSVCHOST, ifc_omservicehost, API_GETURL, GetUrl); + + NEXT_PATCH(MPIID_OMSVCEVENT) + M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, ADDREF, AddRef); + M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, RELEASE, Release); + M_CB(MPIID_OMSVCEVENT, ifc_omserviceevent, QUERYINTERFACE, QueryInterface); + M_VCB(MPIID_OMSVCEVENT, ifc_omserviceevent, API_SERVICECHANGE, ServiceChange); + + NEXT_PATCH(MPIID_OMSTRGEXT) + M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, ADDREF, AddRef); + M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, RELEASE, Release); + M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_OMSTRGEXT, ifc_omstorageext, API_ENUMERATE, EnumerateStorageExt); + + + END_PATCH +END_MULTIPATCH; +#undef CBCLASS |