mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
394 lines
9.6 KiB
C++
394 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
|