diff options
Diffstat (limited to 'Src/omBrowser/service.cpp')
-rw-r--r-- | Src/omBrowser/service.cpp | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/Src/omBrowser/service.cpp b/Src/omBrowser/service.cpp new file mode 100644 index 00000000..4a2f6a63 --- /dev/null +++ b/Src/omBrowser/service.cpp @@ -0,0 +1,391 @@ +#include "./main.h" +#include "./service.h" +#include "./ifc_omservicehost.h" +#include "./ifc_omserviceeventmngr.h" + +#include "../winamp/wa_ipc.h" + +#include <strsafe.h> + +#define DEFAULT_GENERATION 2 + +#define IS_INVALIDISPATCH(__disp) (((IDispatch *)1) == (__disp) || NULL == (__disp)) + +OmService::OmService(UINT serviceId, ifc_omservicehost *serviceHost) + : ref(1), id(serviceId), name(NULL), url(NULL), icon(NULL), rating(0), version(0), + flags(0), generation(2), description(NULL), authorFirst(NULL), authorLast(NULL), + published(NULL), updated(NULL), thumbnail(NULL), screenshot(NULL), address(NULL), + host(serviceHost) +{ + if (NULL != host) + host->AddRef(); + + modified.SetEventHandler(ModifiedEvent, (ULONG_PTR)this); + + InitializeCriticalSection(&lock); + InitializeCriticalSection(&eventLock); +} + +OmService::~OmService() +{ + Plugin_FreeString(name); + Plugin_FreeString(url); + Plugin_FreeString(icon); + Plugin_FreeString(address); + + Plugin_FreeString(description); + Plugin_FreeString(authorFirst); + Plugin_FreeString(authorLast); + Plugin_FreeString(published); + Plugin_FreeString(updated); + Plugin_FreeString(thumbnail); + Plugin_FreeString(screenshot); + + UnregisterAllEventHandlers(); + + if (NULL != host) + host->Release(); + + DeleteCriticalSection(&lock); + DeleteCriticalSection(&eventLock); +} + +HRESULT OmService::CreateInstance(UINT serviceId, ifc_omservicehost *host, OmService **serviceOut) +{ + if (NULL == serviceOut) return E_POINTER; + *serviceOut = new OmService(serviceId, host); + if (NULL == *serviceOut) return E_OUTOFMEMORY; + + return S_OK; +} + +size_t OmService::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t OmService::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int OmService::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_OmService)) + *object = static_cast<ifc_omservice*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceDetails)) + *object = static_cast<ifc_omservicedetails*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceEditor)) + *object = static_cast<ifc_omserviceeditor*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceCopier)) + *object = static_cast<ifc_omservicecopier*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceCommand)) + *object = static_cast<ifc_omservicecommand*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceEventMngr)) + *object = static_cast<ifc_omserviceeventmngr*>(this); + else if (IsEqualIID(interface_guid, IFC_OmServiceHostExt)) + *object = static_cast<ifc_omservicehostext*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +HRESULT OmService::StringCchCopyExMT(LPTSTR pszDest, size_t cchDest, LPCTSTR pszSrc, LPTSTR *ppszDestEnd, size_t *pcchRemaining, DWORD dwFlags) +{ + if (NULL == pszDest) + return E_POINTER; + + EnterCriticalSection(&lock); + HRESULT hr = StringCchCopyEx(pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); + LeaveCriticalSection(&lock); + return hr; +} + +UINT OmService::GetId() +{ + return id; +} + +HRESULT OmService::SetId(UINT serviceId) +{ + id = serviceId; + return S_OK; +} + +HRESULT OmService::GetName(LPWSTR pszBuffer, UINT cchBufferMax) +{ + return StringCchCopyExMT(pszBuffer, cchBufferMax, name, NULL, NULL,STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE); +} + +HRESULT OmService::GetUrl(LPWSTR pszBuffer, UINT cchBufferMax) +{ + EnterCriticalSection(&lock); + + HRESULT hr = GetUrlDirect(pszBuffer, cchBufferMax); + if(SUCCEEDED(hr)) + { + if (NULL != host) + { + HRESULT hostResult = host->GetUrl(this, pszBuffer, cchBufferMax); + if (FAILED(hostResult) && E_NOTIMPL != hostResult) + hr = hostResult; + } + } + + LeaveCriticalSection(&lock); + return hr; +} + +HRESULT OmService::GetUrlDirect(LPWSTR pszBuffer, UINT cchBufferMax) +{ + return StringCchCopyExMT(pszBuffer, cchBufferMax, url, NULL, NULL, STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE); +} + +HRESULT OmService::GetIcon(LPWSTR pszBuffer, UINT cchBufferMax) +{ + return StringCchCopyExMT(pszBuffer, cchBufferMax, icon, NULL, NULL, STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE); +} + +HRESULT OmService::GetExternal(IDispatch **ppDispatch) +{ + if (NULL == ppDispatch) + return E_POINTER; + + *ppDispatch = NULL; + + HWND hWinamp = NULL; + IDispatch *winampDisp = NULL; + + if (SUCCEEDED(Plugin_GetWinampWnd(&hWinamp)) && NULL != hWinamp) + { + EnterCriticalSection(&lock); + UINT generation_cached = generation; + LeaveCriticalSection(&lock); + + if (2 == generation_cached) + { + WCHAR szBuffer[64] = {0}; + if (SUCCEEDED(StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"%u", id))) + winampDisp = (IDispatch*)SENDWAIPC(hWinamp, IPC_JSAPI2_GET_DISPATCH_OBJECT, (WPARAM)szBuffer); + } + else if (1 == generation_cached) + { + winampDisp = (IDispatch*)SENDWAIPC(hWinamp, IPC_GET_DISPATCH_OBJECT, 0); + } + + if (IS_INVALIDISPATCH(winampDisp)) + winampDisp = NULL; + } + + *ppDispatch = winampDisp; + + EnterCriticalSection(&lock); + ifc_omservicehost *host_cached = host; + if (NULL != host_cached) + host_cached->AddRef(); + + LeaveCriticalSection(&lock); + + if (NULL != host_cached) + { + host_cached->GetExternal(this, ppDispatch); + host_cached->Release(); + } + + return S_OK; +} + +HRESULT OmService::GetRating(UINT *ratingOut) +{ + if (NULL == ratingOut) + return E_POINTER; + + *ratingOut = rating; + return S_OK; +} + +HRESULT OmService::GetVersion(UINT *versionOut) +{ + if (NULL == versionOut) + return E_POINTER; + + *versionOut = version; + return S_OK; +} + +HRESULT OmService::GetGeneration(UINT *generationOut) +{ + if (NULL == generationOut) + return E_POINTER; + + EnterCriticalSection(&lock); + *generationOut = (0 == generation) ? DEFAULT_GENERATION : generation; + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmService::GetFlags(UINT *flagsOut) +{ + if (NULL == flagsOut) + return E_POINTER; + + *flagsOut = flags; + return S_OK; +} + +HRESULT OmService::UpdateFlags(UINT flagsIn) +{ + flags = flagsIn; + return S_OK; +} + +HRESULT OmService::SetAddress(LPCWSTR pszAddress) +{ + EnterCriticalSection(&lock); + + HRESULT hr; + Plugin_FreeString(address); + if (NULL == pszAddress) + { + address = NULL; + hr = S_OK; + } + else + { + address = Plugin_CopyString(pszAddress); + hr = (NULL == address) ? E_OUTOFMEMORY : S_OK; + } + + LeaveCriticalSection(&lock); + return hr; +} + +HRESULT OmService::GetAddress(LPWSTR pszBuffer, UINT cchBufferMax) +{ + return StringCchCopyExMT(pszBuffer, cchBufferMax, address, NULL, NULL,STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE); +} + +HRESULT OmService::GetHost(ifc_omservicehost **ppHost) +{ + if (NULL == ppHost) return E_POINTER; + + EnterCriticalSection(&lock); + + *ppHost = host; + if (NULL != host) + host->AddRef(); + + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmService::SetHost(ifc_omservicehost *serviceHost) +{ + EnterCriticalSection(&lock); + + if (NULL != host) + host->Release(); + + host = serviceHost; + + if (NULL != host) + host->AddRef(); + + LeaveCriticalSection(&lock); + + return S_OK; +} + +void CALLBACK OmService::ModifiedEvent(UINT nMark, FlagTracker *instance, ULONG_PTR user) +{ + OmService *service = (OmService*)user; + if (NULL == service) return; + + service->Signal_ServiceChange(nMark); +} + +HRESULT OmService::CopyTo(ifc_omservice *service, UINT *modifiedFlags) +{ + if (NULL == service || id != service->GetId()) + return E_INVALIDARG; + + HRESULT hr; + ifc_omserviceeditor *editor = NULL; + hr = service->QueryInterface(IFC_OmServiceEditor, (void**)&editor); + if (SUCCEEDED(hr) && editor != NULL) + { + editor->BeginUpdate(); + + if (FAILED(editor->SetName(name, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetUrl(url, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetIcon(icon, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetRating(rating))) hr = E_FAIL; + if (FAILED(editor->SetVersion(version))) hr = E_FAIL; + if (FAILED(editor->SetFlags(flags, 0xFFFFFFFF))) hr = E_FAIL; + if (FAILED(editor->SetDescription(description, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetAuthorFirst(authorFirst, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetAuthorLast(authorLast, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetUpdated(updated, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetPublished(published, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetThumbnail(thumbnail, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetScreenshot(screenshot, FALSE))) hr = E_FAIL; + if (FAILED(editor->SetGeneration(generation))) hr = E_FAIL; + + editor->EndUpdate(); + + if (NULL != modifiedFlags) + editor->GetModified(modifiedFlags); + + editor->Release(); + } + + return hr; +} + +HRESULT OmService::QueryState(HWND hBrowser, const GUID *commandGroup, UINT commandId) +{ + HRESULT hr; + + EnterCriticalSection(&lock); + + if (NULL != host) + hr = host->QueryCommandState(this, hBrowser, commandGroup, commandId); + else + hr = E_NOTIMPL; + + LeaveCriticalSection(&lock); + return hr; +} + +HRESULT OmService::Exec(HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg) +{ + HRESULT hr; + + EnterCriticalSection(&lock); + + if (NULL != host) + hr = host->ExecuteCommand(this, hBrowser, commandGroup, commandId, commandArg); + else + hr = E_NOTIMPL; + + LeaveCriticalSection(&lock); + return hr; +}
\ No newline at end of file |