winamp/Src/Plugins/Library/ml_online/serviceHost.cpp

395 lines
9.6 KiB
C++

#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