#include "main.h" #include "./serviceHost.h" #include "./wasabi.h" #include "./resource.h" #include "./external.h" #include "./navigation.h" #include "./commands.h" #include "./serviceHelper.h" #include #include #include #include #include "../winamp/wa_ipc.h" #include "../winamp/IWasabiDispatchable.h" #include "../winamp/JSAPI_Info.h" #include #define IS_INVALIDISPATCH(__disp) (((IDispatch *)1) == (__disp) || NULL == (__disp)) static WebDevServiceHost *cachedInstance = NULL; WebDevServiceHost::WebDevServiceHost() : ref(1) { } WebDevServiceHost::~WebDevServiceHost() { } HRESULT WebDevServiceHost::CreateInstance(WebDevServiceHost **instance) { if (NULL == instance) return E_POINTER; *instance = new WebDevServiceHost(); if (NULL == instance) return E_OUTOFMEMORY; return S_OK; } HRESULT WebDevServiceHost::GetCachedInstance(WebDevServiceHost **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 WebDevServiceHost::ReleseCache() { if (NULL == cachedInstance) return S_FALSE; WebDevServiceHost *t = cachedInstance; cachedInstance = NULL; t->Release(); return S_OK; } size_t WebDevServiceHost::AddRef() { return InterlockedIncrement((LONG*)&ref); } size_t WebDevServiceHost::Release() { if (0 == ref) return ref; LONG r = InterlockedDecrement((LONG*)&ref); if (0 == r) delete(this); return r; } int WebDevServiceHost::QueryInterface(GUID interface_guid, void **object) { if (NULL == object) return E_POINTER; if (IsEqualIID(interface_guid, IFC_OmServiceHost)) *object = static_cast(this); else if (IsEqualIID(interface_guid, IFC_OmServiceEvent)) *object = static_cast(this); else { *object = NULL; return E_NOINTERFACE; } if (NULL == *object) return E_UNEXPECTED; AddRef(); return S_OK; } HRESULT WebDevServiceHost::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 WebDevServiceHost::GetBasePath(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax) { if (NULL == pszBuffer) return E_POINTER; return StringCchCopy(pszBuffer, cchBufferMax, L".\\Plugins\\webDev"); } HRESULT WebDevServiceHost::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"wdService_{%010u}.ini", service->GetId()); } HRESULT WebDevServiceHost::QueryCommandState(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId) { if (NULL == service || NULL == commandGroup) return E_NOTIMPL; if (IsEqualGUID(*commandGroup, CMDGROUP_ADDRESSBAR)) { switch(commandId) { case ADDRESSCOMMAND_VISIBLE: if (S_FALSE == ServiceHelper_IsSpecial(service)) return CMDSTATE_ENABLED; return CMDSTATE_UNKNOWN; case ADDRESSCOMMAND_READONLY: if (S_FALSE == ServiceHelper_IsSpecial(service)) return CMDSTATE_DISABLED; return CMDSTATE_ENABLED; } } return E_NOTIMPL; } HRESULT WebDevServiceHost::ExecuteCommand(ifc_omservice *service, HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg) { return E_NOTIMPL; } HRESULT WebDevServiceHost::GetUrl(ifc_omservice *service, LPWSTR pszBuffer, UINT cchBufferMax) { return E_NOTIMPL; } void WebDevServiceHost::ServiceChange(ifc_omservice *service, UINT nModified) { if (NULL == service) return; Navigation *navigation; if (SUCCEEDED(Plugin_GetNavigation(&navigation))) { navigation->UpdateService(service, nModified); navigation->Release(); } if ( 0 != (ifc_omserviceeditor::modifiedUrl & nModified)) { Command_PostNavigateSvc(service, MAKEINTRESOURCE (NAVIGATE_HOME), TRUE); } if (0 != (ifc_omserviceeditor::modifiedFlags & nModified)) { ServiceHelper_RegisterPreAuthorized(service); } } #define CBCLASS WebDevServiceHost 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); END_PATCH END_MULTIPATCH; #undef CBCLASS