winamp/Src/omBrowser/browserObject.cpp
2024-09-24 14:54:57 +02:00

503 lines
12 KiB
C++

#include "main.h"
#include "./browserObject.h"
#include "./ifc_menucustomizer.h"
#include "./ifc_wasabihelper.h"
#include "./ifc_omconfig.h"
#include "./browserView.h"
#include "./browserPopup.h"
#include "./options.h"
#include "./ifc_ombrowserconfig.h"
#include "./ifc_ombrowserregistry.h"
#include "./ifc_ombrowserevent.h"
#include "./ifc_omtoolbarconfig.h"
#include "./ifc_omstatusbarconfig.h"
#include "./ifc_ombrowserclass.h"
#include "./ifc_omservice.h"
#include "./ieversion.h"
#include "./browserWndEnum.h"
#include "./browserWndRecord.h"
#include <strsafe.h>
OmBrowserObject::OmBrowserObject() : ref(1), flags(0), browserClass(NULL)
{
InitializeCriticalSection(&lock);
}
OmBrowserObject::~OmBrowserObject()
{
if (NULL != browserClass)
browserClass->Release();
DeleteCriticalSection(&lock);
}
HRESULT OmBrowserObject::CreateInstance(OmBrowserObject **instance)
{
if (NULL == instance) return E_POINTER;
*instance = new OmBrowserObject();
if (NULL == *instance) return E_OUTOFMEMORY;
return S_OK;
}
size_t OmBrowserObject::AddRef()
{
return InterlockedIncrement((LONG*)&ref);
}
size_t OmBrowserObject::Release()
{
if (0 == ref)
return ref;
LONG r = InterlockedDecrement((LONG*)&ref);
if (0 == r)
delete(this);
return r;
}
int OmBrowserObject::QueryInterface(GUID interface_guid, void **object)
{
if (NULL == object) return E_POINTER;
if (IsEqualIID(interface_guid, OBJ_OmBrowser))
*object = static_cast<obj_ombrowser*>(this);
else if (IsEqualIID(interface_guid, IFC_OmBrowserWindowManager))
*object = static_cast<ifc_ombrowserwndmngr*>(this);
else if (IsEqualIID(interface_guid, IFC_OmBrowserEventManager))
*object = static_cast<ifc_ombrowsereventmngr*>(this);
else
{
*object = NULL;
return E_NOINTERFACE;
}
if (NULL == *object)
return E_UNEXPECTED;
AddRef();
return S_OK;
}
HRESULT OmBrowserObject::Initialize(LPCWSTR pszName, HWND hwndWinamp)
{
if ( browserClass != NULL )
return S_FALSE;
HRESULT hr = Plugin_Initialize(hwndWinamp);
if (SUCCEEDED(hr))
{
if (NULL == pszName || L'\0' == *pszName)
pszName = OMBROWSER_NAME;
hr = Plugin_GetBrowserClass(pszName, &browserClass);
}
return hr;
}
HRESULT OmBrowserObject::Finish(void)
{
HRESULT hr = S_OK;
EnterCriticalSection(&lock);
flags |= flagFinishing;
size_t index = windowList.size();
while(index--)
{
OmBrowserWndRecord *r = windowList[index];
if (FALSE == DestroyWindow(r->GetHwnd()))
{
hr = E_FAIL;
}
else
{
windowList.erase(windowList.begin() + index);
r->Release();
}
}
while(!eventList.empty())
{
ifc_ombrowserevent *e = eventList.back();
if (NULL == e) break;
eventList.pop_back();
e->Release();
}
if (NULL != browserClass)
{
browserClass->Release();
browserClass = NULL;
}
LeaveCriticalSection(&lock);
return hr;
}
HRESULT OmBrowserObject::RegisterWinampHook(ifc_winamphook *hook, UINT *cookieOut)
{
return Plugin_RegisterWinampHook(hook, cookieOut);
}
HRESULT OmBrowserObject::UnregisterWinampHook(UINT cookie)
{
return Plugin_UnregisterWinampHook(cookie);
}
HRESULT OmBrowserObject::GetConfig(const GUID *configIfc, void **configOut)
{
if (NULL == configOut) return E_POINTER;
if (NULL == browserClass) return E_UNEXPECTED;
ifc_omconfig *config = NULL;
HRESULT hr = browserClass->GetConfig(&config);
if (SUCCEEDED(hr) && config != NULL)
{
if (NULL == configIfc || IsEqualIID(*configIfc, GUID_NULL))
*configOut = config;
else
{
hr = config->QueryInterface(*configIfc, configOut);
config->Release();
}
}
return hr;
}
HRESULT OmBrowserObject::GetSessionId(LPWSTR pszBuffer, INT cchBufferMax)
{
if (NULL == pszBuffer) return E_POINTER;
*pszBuffer = L'\0';
ifc_wasabihelper *wasabi = NULL;
HRESULT hr = Plugin_GetWasabiHelper(&wasabi);
if (SUCCEEDED(hr) && wasabi != NULL)
{
api_application *app = NULL;
hr = wasabi->GetApplicationApi(&app);
if (SUCCEEDED(hr))
{
UUID uid;
if (API_APPLICATION_SUCCESS == app->GetSessionID(&uid))
{
hr = Plugin_FormatUuidString(uid, pszBuffer, cchBufferMax);
}
else
{
hr = E_FAIL;
}
app->Release();
}
wasabi->Release();
}
if (FAILED(hr))
hr = StringCchCopy(pszBuffer, cchBufferMax, L"0123456789ABCDEF");
return hr;
}
HRESULT OmBrowserObject::GetClientId(LPWSTR pszBuffer, INT cchBufferMax)
{
if (NULL == pszBuffer) return E_POINTER;
*pszBuffer = L'\0';
ifc_ombrowserconfig *browserConfig;
if (FAILED(GetConfig(&IFC_OmBrowserConfig, (void**)&browserConfig)))
return E_NOINTERFACE;
HRESULT hr = browserConfig->GetClientId(pszBuffer, cchBufferMax);
if (S_OK != hr)
{
UUID uid;
LPWSTR cursor = NULL;
size_t remaining = 0;
StringCchCopyEx(pszBuffer, cchBufferMax, L"WA-", &cursor, &remaining, 0);
if (RPC_S_OK != UuidCreate(&uid) ||
FAILED(Plugin_FormatUuidString(uid, cursor, remaining)) ||
FAILED(browserConfig->SetClientId(pszBuffer)))
{
*pszBuffer = L'\0';
hr = E_FAIL;
}
}
browserConfig->Release();
return hr;
}
HRESULT OmBrowserObject::GetRegistry(ifc_ombrowserregistry **registryOut)
{
if (NULL == registryOut) return E_POINTER;
if (NULL == browserClass) return E_UNEXPECTED;
return browserClass->GetRegistry(registryOut);
}
HRESULT OmBrowserObject::CreateView(ifc_omservice *service, HWND hParent, LPCWSTR forceUrl, UINT viewStyle, HWND *hView)
{
if (NULL == hView) return E_POINTER;
*hView = NULL;
if (NULL == hParent) return E_INVALIDARG;
*hView = BrowserView_Create(this, service, hParent, forceUrl, viewStyle);
if (NULL == *hView) return E_FAIL;
BrowserView_UpdateSkin(*hView, FALSE);
return S_OK;
}
HRESULT OmBrowserObject::CreatePopup(ifc_omservice *service, INT x, INT y, INT cx, INT cy, HWND hOwner, LPCWSTR forceUrl, UINT viewStyle, HWND *hWindow)
{
if (NULL == hWindow) return E_POINTER;
*hWindow = NULL;
if (NULL == hOwner && FAILED(Plugin_GetWinampWnd(&hOwner)))
return E_INVALIDARG;
HWND hPopup = BrowserPopup_Create(this, service, viewStyle, x, y, cx, cy, hOwner, NULL, 0L);
if (NULL == hPopup) return E_FAIL;
*hWindow = hPopup;
BrowserPopup_UpdateSkin(hPopup, FALSE);
if (NULL != forceUrl)
{
BrowserPopup_Navigate(hPopup, forceUrl, 0L);
}
else
{
BrowserPopup_Navigate(hPopup, NAVIGATE_HOME, 0L);
}
return S_OK;
}
HRESULT OmBrowserObject::IsFinishing(void)
{
return (0 != (flagFinishing & flags)) ? S_OK : S_FALSE;
}
HRESULT OmBrowserObject::GetClass(ifc_ombrowserclass **instance)
{
if (NULL == instance)
return E_POINTER;
*instance = browserClass;
if (NULL == *instance) return E_UNEXPECTED;
browserClass->AddRef();
return S_OK;
}
HRESULT OmBrowserObject::GetVersion(int *major, int *minor)
{
if (NULL != major) *major = OMBROWSER_VERSION_MAJOR;
if (NULL != minor) *minor = OMBROWSER_VERSION_MINOR;
return S_OK;
}
HRESULT OmBrowserObject::GetIEVersion(int *major, int *minor, int *build, int *subbuild)
{
return MSIE_GetVersion(major, minor, build, subbuild);
}
HRESULT OmBrowserObject::ShowOptions(HWND hOwner, UINT style, BROWSEROPTIONSCALLBACK callback, ULONG_PTR user)
{
return BrowserOptions_ShowDialog(this, hOwner, style, callback, user);
}
HRESULT OmBrowserObject::RegisterWindow(HWND hwnd, const GUID *windowType)
{
if (NULL == hwnd) return E_INVALIDARG;
if (S_FALSE != IsFinishing())
return E_UNEXPECTED;
EnterCriticalSection(&lock);
size_t index = windowList.size();
while(index--)
{
if (windowList[index]->GetHwnd() == hwnd)
{
LeaveCriticalSection(&lock);
return S_FALSE;
}
}
OmBrowserWndRecord *r = NULL;
HRESULT hr = OmBrowserWndRecord::CreateInstance(hwnd, windowType, &r);
if (SUCCEEDED(hr) && r != NULL)
{
windowList.push_back(r);
}
LeaveCriticalSection(&lock);
return hr;
}
HRESULT OmBrowserObject::UnregisterWindow(HWND hwnd)
{
if (NULL == hwnd) return E_INVALIDARG;
if (S_FALSE != IsFinishing())
return E_PENDING;
EnterCriticalSection(&lock);
size_t index = windowList.size();
while(index--)
{
OmBrowserWndRecord *r = windowList[index];
if (r->GetHwnd() == hwnd)
{
windowList.erase(windowList.begin() + index);
r->Release();
LeaveCriticalSection(&lock);
return S_OK;
}
}
LeaveCriticalSection(&lock);
return S_FALSE;
}
HRESULT OmBrowserObject::Enumerate(const GUID *windowType, UINT *serviceIdFilter, ifc_ombrowserwndenum **enumerator)
{
EnterCriticalSection(&lock);
HRESULT hr = OmBrowserWndEnumerator::CreateInstance(windowType, serviceIdFilter, windowList.size() ? &windowList.at(0) : nullptr,
windowList.size(), (OmBrowserWndEnumerator**)enumerator);
LeaveCriticalSection(&lock);
return hr;
}
HRESULT OmBrowserObject::RegisterEventHandler(ifc_ombrowserevent *eventHandler)
{
if (NULL == eventHandler)
return E_INVALIDARG;
if (S_FALSE != IsFinishing())
return E_PENDING;
EnterCriticalSection(&lock);
size_t index = eventList.size();
while (index--)
{
if (eventList[index] == eventHandler)
{
LeaveCriticalSection(&lock);
return E_FAIL;
}
}
eventList.push_back(eventHandler);
eventHandler->AddRef();
LeaveCriticalSection(&lock);
return S_OK;
}
HRESULT OmBrowserObject::UnregisterEventHandler(ifc_ombrowserevent *eventHandler)
{
if (NULL == eventHandler)
return E_INVALIDARG;
if (S_FALSE != IsFinishing())
return E_PENDING;
EnterCriticalSection(&lock);
size_t index = eventList.size();
while (index--)
{
if (eventList[index] == eventHandler)
{
eventList.erase(eventList.begin() + index);
eventHandler->Release();
LeaveCriticalSection(&lock);
return S_OK;
}
}
LeaveCriticalSection(&lock);
return S_FALSE;
}
HRESULT OmBrowserObject::Signal_WindowCreate(HWND hwnd, const GUID *windowType)
{
EnterCriticalSection(&lock);
size_t index = eventList.size();
while (index--)
{
eventList[index]->WindowCreate(hwnd, windowType);
}
LeaveCriticalSection(&lock);
return S_OK;
}
HRESULT OmBrowserObject::Signal_WindowClose(HWND hwnd, const GUID *windowType)
{
EnterCriticalSection(&lock);
size_t index = eventList.size();
while (index--)
{
eventList[index]->WindowClose(hwnd, windowType);
}
LeaveCriticalSection(&lock);
return S_OK;
}
#define CBCLASS OmBrowserObject
START_MULTIPATCH;
START_PATCH(MPIID_OMBROWSER)
M_CB(MPIID_OMBROWSER, obj_ombrowser, ADDREF, AddRef);
M_CB(MPIID_OMBROWSER, obj_ombrowser, RELEASE, Release);
M_CB(MPIID_OMBROWSER, obj_ombrowser, QUERYINTERFACE, QueryInterface);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_INITIALIZE, Initialize);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_FINISH, Finish);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_REGISTERWINAMPHOOK, RegisterWinampHook);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_UNREGISTERWINAMPHOOK, UnregisterWinampHook);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETCONFIG, GetConfig);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETSESSIONID, GetSessionId);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETCLIENTID, GetClientId);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETREGISTRY, GetRegistry);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_CREATEVIEW, CreateView);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_CREATEPOPUP, CreatePopup);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_ISFINISHING, IsFinishing);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETCLASS, GetClass);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETVERSION, GetVersion);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_GETIEVERSION, GetIEVersion);
M_CB(MPIID_OMBROWSER, obj_ombrowser, API_SHOWOPTIONS, ShowOptions);
NEXT_PATCH(MPIID_OMBROWSERWNDMNGR)
M_CB(MPIID_OMBROWSERWNDMNGR, ifc_ombrowserwndmngr, ADDREF, AddRef);
M_CB(MPIID_OMBROWSERWNDMNGR, ifc_ombrowserwndmngr, RELEASE, Release);
M_CB(MPIID_OMBROWSERWNDMNGR, ifc_ombrowserwndmngr, QUERYINTERFACE, QueryInterface);
M_CB(MPIID_OMBROWSERWNDMNGR, ifc_ombrowserwndmngr, API_REGISTERWINDOW, RegisterWindow);
M_CB(MPIID_OMBROWSERWNDMNGR, ifc_ombrowserwndmngr, API_UNREGISTERWINDOW, UnregisterWindow);
M_CB(MPIID_OMBROWSERWNDMNGR, ifc_ombrowserwndmngr, API_ENUMERATE, Enumerate);
NEXT_PATCH(MPIID_OMBROWSEREVENTMNGR)
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, ADDREF, AddRef);
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, RELEASE, Release);
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, QUERYINTERFACE, QueryInterface);
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, API_REGISTERHANDLER, RegisterEventHandler);
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, API_UNREGISTERHANDLER, UnregisterEventHandler);
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, API_SIGNAL_WINDOWCREATE, Signal_WindowCreate);
M_CB(MPIID_OMBROWSEREVENTMNGR, ifc_ombrowsereventmngr, API_SIGNAL_WINDOWCLOSE, Signal_WindowClose);
END_PATCH
END_MULTIPATCH;
#undef CBCLASS