[PATCH v2 2/7] wmp: Implement IConnectionPoint[Container] and add _WMPOCXEvents

Anton Romanov theli.ua at gmail.com
Fri Feb 2 00:00:12 CST 2018


Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---
 dlls/wmp/Makefile.in    |   3 +-
 dlls/wmp/events.c       | 388 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/wmp/oleobj.c       |  78 +++-------
 dlls/wmp/player.c       |   9 +-
 dlls/wmp/tests/oleobj.c |   2 +-
 dlls/wmp/wmp_main.c     |   2 +
 dlls/wmp/wmp_private.h  |  36 +++--
 7 files changed, 438 insertions(+), 80 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..204b2f6527
--- /dev/null
+++ b/dlls/wmp/events.c
@@ -0,0 +1,388 @@
+#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++;
+    }
+
+    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 call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams)
+{
+    DWORD i;
+
+    for(i=0; i<This->sinks_size; i++) {
+        if(This->sinks[i])
+            IDispatch_Invoke(This->sinks[i], dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                             DISPATCH_METHOD, dispparams, NULL, NULL, NULL);
+    }
+}
+
+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 ea989f00e3..8ac978218e 100644
--- a/dlls/wmp/oleobj.c
+++ b/dlls/wmp/oleobj.c
@@ -18,11 +18,11 @@
 
 #include "wmp_private.h"
 #include "olectl.h"
-
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wmp);
 
+
 static HWND get_container_hwnd(WindowsMediaPlayer *This)
 {
     IOleWindow *ole_window;
@@ -306,6 +306,8 @@ static ULONG WINAPI OleObject_Release(IOleObject *iface)
 
     if(!ref) {
         release_client_site(This);
+        ConnectionPointContainer_Destroy(This);
+        destroy_player(This);
         heap_free(This);
     }
 
@@ -874,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)
 {
@@ -941,22 +894,25 @@ 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);
-
-    hdc = GetDC(0);
-    dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
-    dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
-    ReleaseDC(0, hdc);
+    hres = init_player(wmp);
+    if (hres == S_OK) {
+        ConnectionPointContainer_Init(wmp);
+        hdc = GetDC(0);
+        dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
+        dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
+        ReleaseDC(0, hdc);
 
-    wmp->extent.cx = MulDiv(192, 2540, dpi_x);
-    wmp->extent.cy = MulDiv(192, 2540, dpi_y);
+        wmp->extent.cx = MulDiv(192, 2540, dpi_x);
+        wmp->extent.cy = MulDiv(192, 2540, dpi_y);
 
-    hres = IOleObject_QueryInterface(&wmp->IOleObject_iface, riid, ppv);
-    IOleObject_Release(&wmp->IOleObject_iface);
+        hres = IOleObject_QueryInterface(&wmp->IOleObject_iface, riid, ppv);
+        IOleObject_Release(&wmp->IOleObject_iface);
+    }
+    if(hres != S_OK)
+        destroy_player(wmp);
     return hres;
 }
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
index 4c11c88d74..c410d6ef8f 100644
--- a/dlls/wmp/player.c
+++ b/dlls/wmp/player.c
@@ -22,6 +22,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(wmp);
 
+static void update_state(WindowsMediaPlayer *wmp, int state);
+
 static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface)
 {
     return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface);
@@ -661,8 +663,13 @@ static const IWMPSettingsVtbl WMPSettingsVtbl = {
     WMPSettings_put_enableErrorDialogs
 };
 
-void init_player_ifaces(WindowsMediaPlayer *wmp)
+void destroy_player(WindowsMediaPlayer* wmp) {
+    heap_free(wmp);
+}
+
+HRESULT init_player(WindowsMediaPlayer *wmp)
 {
     wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl;
     wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl;
+    return S_OK;
 }
diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c
index 2b646d7b1d..08c000590a 100644
--- a/dlls/wmp/tests/oleobj.c
+++ b/dlls/wmp/tests/oleobj.c
@@ -896,7 +896,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);
 
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 7b7f51cd63..d599c5bc6b 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;
@@ -37,27 +49,19 @@ struct WindowsMediaPlayer {
     IOleClientSite *client_site;
     HWND hwnd;
     SIZEL extent;
+
+    ConnectionPoint *wmpocx;
 };
 
-void init_player_ifaces(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
+HRESULT init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
+void destroy_player(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;
 
+void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams);
+
 void unregister_wmp_class(void) DECLSPEC_HIDDEN;
 
 extern HINSTANCE wmp_instance DECLSPEC_HIDDEN;
-
-static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t len)
-{
-    return HeapAlloc(GetProcessHeap(), 0, len);
-}
-
-static inline void* __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len)
-{
-    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
-}
-
-static inline BOOL heap_free(void *mem)
-{
-    return HeapFree(GetProcessHeap(), 0, mem);
-}
-- 
2.16.1




More information about the wine-devel mailing list