Signed-off-by: Anton Romanov <theli.ua(a)gmail.com>
---
dlls/wmp/Makefile.in | 3 +-
dlls/wmp/events.c | 401 ++++++++++++++++++++++++++++++++++++++++++++++++
dlls/wmp/oleobj.c | 52 +------
dlls/wmp/tests/oleobj.c | 70 ++++++++-
dlls/wmp/wmp_main.c | 2 +
dlls/wmp/wmp_private.h | 16 ++
6 files changed, 492 insertions(+), 52 deletions(-)
create mode 100644 dlls/wmp/events.c
diff --git a/dlls/wmp/Makefile.in b/dlls/wmp/Makefile.in
index 71ca0e5c7a..14d0a5694f 100644
--- a/dlls/wmp/Makefile.in
+++ b/dlls/wmp/Makefile.in
@@ -1,9 +1,10 @@
MODULE = wmp.dll
-IMPORTS = user32 gdi32 oleaut32
+IMPORTS = uuid user32 gdi32 oleaut32 ole32
C_SRCS = \
oleobj.c \
player.c \
+ events.c \
wmp_main.c
RC_SRCS = rsrc.rc
diff --git a/dlls/wmp/events.c b/dlls/wmp/events.c
new file mode 100644
index 0000000000..f629fc3a76
--- /dev/null
+++ b/dlls/wmp/events.c
@@ -0,0 +1,401 @@
+/*
+ * This is for the most part a copy of dlls/ieframe/evemts.c
+ *
+ * Implementation of event-related interfaces for WebBrowser control:
+ *
+ * - IConnectionPointContainer
+ * - IConnectionPoint
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wmp_private.h"
+#include "olectl.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wmp);
+
+static inline WindowsMediaPlayer *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
+{
+ return CONTAINING_RECORD(iface, WindowsMediaPlayer, IConnectionPointContainer_iface);
+}
+
+static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
+ REFIID riid, LPVOID *ppv)
+{
+ WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
+ return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
+}
+
+static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
+{
+ WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
+ return IOleObject_AddRef(&This->IOleObject_iface);
+}
+
+static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
+{
+ WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
+ return IOleObject_Release(&This->IOleObject_iface);
+}
+
+static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
+ IEnumConnectionPoints **ppEnum)
+{
+ WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
+ FIXME("(%p)->(%p)\n", This, ppEnum);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
+ REFIID riid, IConnectionPoint **ppCP){
+ WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
+
+ if(!ppCP) {
+ WARN("ppCP == NULL\n");
+ return E_POINTER;
+ }
+
+ *ppCP = NULL;
+
+ if(IsEqualGUID(&IID__WMPOCXEvents, riid)) {
+ TRACE("(%p)->(IID__WMPOCXEvents %p)\n", This, ppCP);
+ *ppCP = &This->wmpocx->IConnectionPoint_iface;
+ }
+
+ if(*ppCP) {
+ IConnectionPoint_AddRef(*ppCP);
+ return S_OK;
+ }
+
+ WARN("Unsupported IID %s\n", debugstr_guid(riid));
+ return CONNECT_E_NOCONNECTION;
+}
+
+static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl =
+{
+ ConnectionPointContainer_QueryInterface,
+ ConnectionPointContainer_AddRef,
+ ConnectionPointContainer_Release,
+ ConnectionPointContainer_EnumConnectionPoints,
+ ConnectionPointContainer_FindConnectionPoint
+};
+
+static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
+{
+ return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
+}
+
+typedef struct {
+ IEnumConnections IEnumConnections_iface;
+
+ LONG ref;
+
+ ConnectionPoint *cp;
+ DWORD iter;
+} EnumConnections;
+
+static inline EnumConnections *impl_from_IEnumConnections(IEnumConnections *iface)
+{
+ return CONTAINING_RECORD(iface, EnumConnections, IEnumConnections_iface);
+}
+
+static HRESULT WINAPI EnumConnections_QueryInterface(IEnumConnections *iface, REFIID riid, void **ppv)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+ *ppv = &This->IEnumConnections_iface;
+ }else if(IsEqualGUID(&IID_IEnumConnections, riid)) {
+ TRACE("(%p)->(IID_IEnumConnections %p)\n", This, ppv);
+ *ppv = &This->IEnumConnections_iface;
+ }else {
+ WARN("Unsupported interface %s\n", debugstr_guid(riid));
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI EnumConnections_AddRef(IEnumConnections *iface)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+ LONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI EnumConnections_Release(IEnumConnections *iface)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+ LONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if(!ref) {
+ IConnectionPoint_Release(&This->cp->IConnectionPoint_iface);
+ heap_free(This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI EnumConnections_Next(IEnumConnections *iface, ULONG cConnections, CONNECTDATA *pgcd, ULONG *pcFetched)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+ ULONG cnt = 0;
+
+ TRACE("(%p)->(%u %p %p)\n", This, cConnections, pgcd, pcFetched);
+
+ while(cConnections--) {
+ while(This->iter < This->cp->sinks_size && !This->cp->sinks[This->iter])
+ This->iter++;
+ if(This->iter == This->cp->sinks_size)
+ break;
+
+ pgcd[cnt].pUnk = (IUnknown*)This->cp->sinks[This->iter];
+ pgcd[cnt].dwCookie = cnt+1;
+ This->iter++;
+ cnt++;
+ IUnknown_AddRef(pgcd[cnt].pUnk);
+ }
+
+ if(pcFetched)
+ *pcFetched = cnt;
+ return cnt ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI EnumConnections_Skip(IEnumConnections *iface, ULONG cConnections)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+ FIXME("(%p)->(%u)\n", This, cConnections);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI EnumConnections_Reset(IEnumConnections *iface)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+ FIXME("(%p)\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI EnumConnections_Clone(IEnumConnections *iface, IEnumConnections **ppEnum)
+{
+ EnumConnections *This = impl_from_IEnumConnections(iface);
+ FIXME("(%p)->(%p)\n", This, ppEnum);
+ return E_NOTIMPL;
+}
+
+static const IEnumConnectionsVtbl EnumConnectionsVtbl = {
+ EnumConnections_QueryInterface,
+ EnumConnections_AddRef,
+ EnumConnections_Release,
+ EnumConnections_Next,
+ EnumConnections_Skip,
+ EnumConnections_Reset,
+ EnumConnections_Clone
+};
+
+static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
+ REFIID riid, LPVOID *ppv)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+ *ppv = NULL;
+
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+ *ppv = &This->IConnectionPoint_iface;
+ }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
+ TRACE("(%p)->(IID_IConnectionPoint %p)\n", This, ppv);
+ *ppv = &This->IConnectionPoint_iface;
+ }
+
+ if(*ppv) {
+ IConnectionPointContainer_AddRef(This->container);
+ return S_OK;
+ }
+
+ WARN("Unsupported interface %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+ return IConnectionPointContainer_AddRef(This->container);
+}
+
+static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+ return IConnectionPointContainer_Release(This->container);
+}
+
+static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+ TRACE("(%p)->(%p)\n", This, pIID);
+
+ *pIID = This->iid;
+ return S_OK;
+}
+
+static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
+ IConnectionPointContainer **ppCPC)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+ TRACE("(%p)->(%p)\n", This, ppCPC);
+
+ *ppCPC = This->container;
+ IConnectionPointContainer_AddRef(This->container);
+ return S_OK;
+}
+
+static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
+ DWORD *pdwCookie)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+ IDispatch *disp;
+ DWORD i;
+ HRESULT hres;
+
+ TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie);
+
+ hres = IUnknown_QueryInterface(pUnkSink, &This->iid, (void**)&disp);
+ if(FAILED(hres)) {
+ hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&disp);
+ if(FAILED(hres))
+ return CONNECT_E_CANNOTCONNECT;
+ }
+
+ if(This->sinks) {
+ for(i=0; i<This->sinks_size; i++) {
+ if(!This->sinks[i])
+ break;
+ }
+
+ if(i == This->sinks_size)
+ This->sinks = heap_realloc(This->sinks,
+ (++This->sinks_size)*sizeof(*This->sinks));
+ }else {
+ This->sinks = heap_alloc(sizeof(*This->sinks));
+ This->sinks_size = 1;
+ i = 0;
+ }
+
+ This->sinks[i] = disp;
+ *pdwCookie = i+1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+ TRACE("(%p)->(%d)\n", This, dwCookie);
+
+ if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1])
+ return CONNECT_E_NOCONNECTION;
+
+ IDispatch_Release(This->sinks[dwCookie-1]);
+ This->sinks[dwCookie-1] = NULL;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
+ IEnumConnections **ppEnum)
+{
+ ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+ EnumConnections *ret;
+
+ TRACE("(%p)->(%p)\n", This, ppEnum);
+
+ ret = heap_alloc(sizeof(*ret));
+ if(!ret)
+ return E_OUTOFMEMORY;
+
+ ret->IEnumConnections_iface.lpVtbl = &EnumConnectionsVtbl;
+ ret->ref = 1;
+ ret->iter = 0;
+
+ IConnectionPoint_AddRef(&This->IConnectionPoint_iface);
+ ret->cp = This;
+
+ *ppEnum = &ret->IEnumConnections_iface;
+ return S_OK;
+}
+
+
+static const IConnectionPointVtbl ConnectionPointVtbl =
+{
+ ConnectionPoint_QueryInterface,
+ ConnectionPoint_AddRef,
+ ConnectionPoint_Release,
+ ConnectionPoint_GetConnectionInterface,
+ ConnectionPoint_GetConnectionPointContainer,
+ ConnectionPoint_Advise,
+ ConnectionPoint_Unadvise,
+ ConnectionPoint_EnumConnections
+};
+
+static void ConnectionPoint_Destroy(ConnectionPoint *This)
+{
+ DWORD i;
+
+ for(i=0; i<This->sinks_size; i++) {
+ if(This->sinks[i])
+ IDispatch_Release(This->sinks[i]);
+ }
+
+ heap_free(This->sinks);
+ heap_free(This);
+}
+
+static void ConnectionPoint_Create(REFIID riid, ConnectionPoint **cp,
+ IConnectionPointContainer *container)
+{
+ ConnectionPoint *ret = heap_alloc(sizeof(ConnectionPoint));
+
+ ret->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
+
+ ret->sinks = NULL;
+ ret->sinks_size = 0;
+ ret->container = container;
+
+ ret->iid = *riid;
+
+ *cp = ret;
+}
+
+void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp)
+{
+ wmp->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
+ ConnectionPoint_Create(&IID__WMPOCXEvents, &wmp->wmpocx, &wmp->IConnectionPointContainer_iface);
+}
+
+void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp)
+{
+ ConnectionPoint_Destroy(wmp->wmpocx);
+}
diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c
index 167b893206..1baf45a439 100644
--- a/dlls/wmp/oleobj.c
+++ b/dlls/wmp/oleobj.c
@@ -307,6 +307,7 @@ static ULONG WINAPI OleObject_Release(IOleObject *iface)
if(!ref) {
release_client_site(This);
+ ConnectionPointContainer_Destroy(This);
heap_free(This);
}
@@ -875,55 +876,6 @@ static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
PersistStreamInit_InitNew
};
-static inline WindowsMediaPlayer *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
-{
- return CONTAINING_RECORD(iface, WindowsMediaPlayer, IConnectionPointContainer_iface);
-}
-
-static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
- REFIID riid, LPVOID *ppv)
-{
- WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
- return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
-}
-
-static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
-{
- WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
- return IOleObject_AddRef(&This->IOleObject_iface);
-}
-
-static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
-{
- WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
- return IOleObject_Release(&This->IOleObject_iface);
-}
-
-static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
- IEnumConnectionPoints **ppEnum)
-{
- WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
- FIXME("(%p)->(%p)\n", This, ppEnum);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
- REFIID riid, IConnectionPoint **ppCP)
-{
- WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
- FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppCP);
- return CONNECT_E_NOCONNECTION;
-}
-
-static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl =
-{
- ConnectionPointContainer_QueryInterface,
- ConnectionPointContainer_AddRef,
- ConnectionPointContainer_Release,
- ConnectionPointContainer_EnumConnectionPoints,
- ConnectionPointContainer_FindConnectionPoint
-};
-
HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory *iface, IUnknown *outer,
REFIID riid, void **ppv)
{
@@ -942,13 +894,13 @@ HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory *iface, IUnknown *outer,
wmp->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl;
wmp->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
wmp->IOleInPlaceObjectWindowless_iface.lpVtbl = &OleInPlaceObjectWindowlessVtbl;
- wmp->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
wmp->IOleControl_iface.lpVtbl = &OleControlVtbl;
wmp->ref = 1;
init_player_ifaces(wmp);
+ ConnectionPointContainer_Init(wmp);
hdc = GetDC(0);
dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c
index 05861e1c10..46b0b72cd3 100644
--- a/dlls/wmp/tests/oleobj.c
+++ b/dlls/wmp/tests/oleobj.c
@@ -495,6 +495,43 @@ static const IDispatchVtbl DispatchVtbl = {
static IDispatch Dispatch = { &DispatchVtbl };
+static HRESULT WINAPI WMPOCXEvents_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(&IID__WMPOCXEvents, riid) || IsEqualGUID(&IID_IDispatch, riid)) {
+ *ppv = iface;
+ return S_OK;
+ }
+
+ ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI WMPOCXEvents_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
+ LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ switch(dispIdMember) {
+ default:
+ ok(0, "unexpected call Invoke(%d)\n", dispIdMember);
+ }
+
+ return E_NOTIMPL;
+}
+
+static IDispatchVtbl WMPOcxEventsVtbl = {
+ WMPOCXEvents_QueryInterface,
+ Dispatch_AddRef,
+ Dispatch_Release,
+ Dispatch_GetTypeInfoCount,
+ Dispatch_GetTypeInfo,
+ Dispatch_GetIDsOfNames,
+ WMPOCXEvents_Invoke,
+};
+
+static IDispatch WMPOCXEvents = { &WMPOcxEventsVtbl };
+
static HRESULT WINAPI InPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv)
{
return cs_qi(riid, ppv);
@@ -788,6 +825,35 @@ static HRESULT cs_qi(REFIID riid, void **ppv)
return S_OK;
}
+static void test_ConnectionPoint(IOleObject *unk)
+{
+ IConnectionPointContainer *container;
+ IConnectionPoint *point;
+ HRESULT hres;
+
+ static DWORD dw = 100;
+
+ hres = IOleObject_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
+ ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
+ if(FAILED(hres))
+ return;
+
+ hres = IConnectionPointContainer_FindConnectionPoint(container, &IID__WMPOCXEvents, &point);
+ IConnectionPointContainer_Release(container);
+ ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
+ if(FAILED(hres))
+ return;
+
+ hres = IConnectionPoint_Advise(point, (IUnknown*)&WMPOCXEvents, &dw);
+ ok(hres == S_OK, "Advise failed: %08x\n", hres);
+ ok(dw == 1, "dw=%d, expected 1\n", dw);
+ hres = IConnectionPoint_Unadvise(point, dw);
+ ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
+
+ IConnectionPoint_Release(point);
+}
+
+
static void test_wmp_ifaces(IOleObject *oleobj)
{
IWMPSettings *settings, *settings_qi;
@@ -913,7 +979,7 @@ static void test_IConnectionPointContainer(IOleObject *oleobj)
point = NULL;
hres = IConnectionPointContainer_FindConnectionPoint(container, &IID__WMPOCXEvents, &point);
- todo_wine ok(hres == S_OK, "got: %08x\n", hres);
+ ok(hres == S_OK, "got: %08x\n", hres);
if(point)
IConnectionPoint_Release(point);
@@ -1113,6 +1179,8 @@ static void test_wmp(void)
ok(hres == E_FAIL || broken(hres == S_OK), "GetClientSite failed: %08x\n", hres);
ok(!client_site, "client_site = %p\n", client_site);
+ test_ConnectionPoint(oleobj);
+
IPersistStreamInit_Release(psi);
IOleInPlaceObject_Release(ipobj);
diff --git a/dlls/wmp/wmp_main.c b/dlls/wmp/wmp_main.c
index 29b096f7fd..b97ad2879d 100644
--- a/dlls/wmp/wmp_main.c
+++ b/dlls/wmp/wmp_main.c
@@ -26,6 +26,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
HINSTANCE wmp_instance;
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index 1af0aef803..710793c513 100644
--- a/dlls/wmp/wmp_private.h
+++ b/dlls/wmp/wmp_private.h
@@ -19,9 +19,21 @@
#define COBJMACROS
#include "windows.h"
+#include "wine/heap.h"
#include "ole2.h"
#include "wmp.h"
+typedef struct {
+ IConnectionPoint IConnectionPoint_iface;
+
+ IConnectionPointContainer *container;
+
+ IDispatch **sinks;
+ DWORD sinks_size;
+
+ IID iid;
+} ConnectionPoint;
+
struct WindowsMediaPlayer {
IOleObject IOleObject_iface;
IProvideClassInfo2 IProvideClassInfo2_iface;
@@ -38,9 +50,13 @@ struct WindowsMediaPlayer {
IOleClientSite *client_site;
HWND hwnd;
SIZEL extent;
+
+ ConnectionPoint *wmpocx;
};
void init_player_ifaces(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
+void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN;
+void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN;
HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
--
2.16.1