Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/oleobj.c | 3 + dlls/wmp/player.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++ dlls/wmp/tests/oleobj.c | 17 +++ dlls/wmp/wmp_private.h | 1 + include/wmp.idl | 27 ++++- 5 files changed, 318 insertions(+), 1 deletion(-)
diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c index acf38f3223..fbad032648 100644 --- a/dlls/wmp/oleobj.c +++ b/dlls/wmp/oleobj.c @@ -263,6 +263,9 @@ static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, v }else if(IsEqualGUID(riid, &IID_IWMPPlayer4)) { TRACE("(%p)->(IID_IWMPPlayer4 %p)\n", This, ppv); *ppv = &This->IWMPPlayer4_iface; + }else if(IsEqualGUID(riid, &IID_IWMPPlayer)) { + TRACE("(%p)->(IID_IWMPPlayer %p)\n", This, ppv); + *ppv = &This->IWMPPlayer_iface; }else if(IsEqualGUID(riid, &IID_IWMPSettings)) { TRACE("(%p)->(IID_IWMPSettings %p)\n", This, ppv); *ppv = &This->IWMPSettings_iface; diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 4c11c88d74..accf5401ed 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -27,6 +27,11 @@ static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface) return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface); }
+static inline WindowsMediaPlayer *impl_from_IWMPPlayer(IWMPPlayer *iface) +{ + return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer_iface); +} + static HRESULT WINAPI WMPPlayer4_QueryInterface(IWMPPlayer4 *iface, REFIID riid, void **ppv) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); @@ -362,6 +367,271 @@ static HRESULT WINAPI WMPPlayer4_openPlayer(IWMPPlayer4 *iface, BSTR url) return E_NOTIMPL; }
+static HRESULT WINAPI WMPPlayer_QueryInterface(IWMPPlayer *iface, REFIID riid, void **ppv) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_QueryInterface(&This->IWMPPlayer4_iface, riid, ppv); +} + +static ULONG WINAPI WMPPlayer_AddRef(IWMPPlayer *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_AddRef(&This->IWMPPlayer4_iface); +} + +static ULONG WINAPI WMPPlayer_Release(IWMPPlayer *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_Release(&This->IWMPPlayer4_iface); +} + +static HRESULT WINAPI WMPPlayer_GetTypeInfoCount(IWMPPlayer *iface, UINT *pctinfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_GetTypeInfoCount(&This->IWMPPlayer4_iface, pctinfo); +} + +static HRESULT WINAPI WMPPlayer_GetTypeInfo(IWMPPlayer *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + + return WMPPlayer4_GetTypeInfo(&This->IWMPPlayer4_iface, iTInfo, + lcid, ppTInfo); +} + +static HRESULT WINAPI WMPPlayer_GetIDsOfNames(IWMPPlayer *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_GetIDsOfNames(&This->IWMPPlayer4_iface, riid, + rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI WMPPlayer_Invoke(IWMPPlayer *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_Invoke(&This->IWMPPlayer4_iface, dispIdMember, + riid, lcid, wFlags, pDispParams, pVarResult, + pExcepInfo, puArgErr); +} + +static HRESULT WINAPI WMPPlayer_close(IWMPPlayer *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_close(&This->IWMPPlayer4_iface); +} + +static HRESULT WINAPI WMPPlayer_get_URL(IWMPPlayer *iface, BSTR *pbstrURL) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_URL(&This->IWMPPlayer4_iface, pbstrURL); +} + +static HRESULT WINAPI WMPPlayer_put_URL(IWMPPlayer *iface, BSTR url) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_URL(&This->IWMPPlayer4_iface, url); +} + +static HRESULT WINAPI WMPPlayer_get_openState(IWMPPlayer *iface, WMPOpenState *pwmpos) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_openState(&This->IWMPPlayer4_iface, pwmpos); +} + +static HRESULT WINAPI WMPPlayer_get_playState(IWMPPlayer *iface, WMPPlayState *pwmpps) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_playState(&This->IWMPPlayer4_iface, pwmpps); +} + +static HRESULT WINAPI WMPPlayer_get_controls(IWMPPlayer *iface, IWMPControls **ppControl) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_controls(&This->IWMPPlayer4_iface, ppControl); +} + +static HRESULT WINAPI WMPPlayer_get_settings(IWMPPlayer *iface, IWMPSettings **ppSettings) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_settings(&This->IWMPPlayer4_iface, ppSettings); +} + +static HRESULT WINAPI WMPPlayer_get_currentMedia(IWMPPlayer *iface, IWMPMedia **ppMedia) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_currentMedia(&This->IWMPPlayer4_iface, ppMedia); +} + +static HRESULT WINAPI WMPPlayer_put_currentMedia(IWMPPlayer *iface, IWMPMedia *pMedia) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_currentMedia(&This->IWMPPlayer4_iface, pMedia); +} + +static HRESULT WINAPI WMPPlayer_get_mediaCollection(IWMPPlayer *iface, IWMPMediaCollection **ppMediaCollection) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_mediaCollection(&This->IWMPPlayer4_iface, ppMediaCollection); +} + +static HRESULT WINAPI WMPPlayer_get_playlistCollection(IWMPPlayer *iface, IWMPPlaylistCollection **ppPlaylistCollection) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_playlistCollection(&This->IWMPPlayer4_iface, ppPlaylistCollection); +} + +static HRESULT WINAPI WMPPlayer_get_versionInfo(IWMPPlayer *iface, BSTR *version) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_versionInfo(&This->IWMPPlayer4_iface, version); +} + +static HRESULT WINAPI WMPPlayer_launchURL(IWMPPlayer *iface, BSTR url) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_launchURL(&This->IWMPPlayer4_iface, url); +} + +static HRESULT WINAPI WMPPlayer_get_network(IWMPPlayer *iface, IWMPNetwork **ppQNI) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_network(&This->IWMPPlayer4_iface, ppQNI); +} + +static HRESULT WINAPI WMPPlayer_get_currentPlaylist(IWMPPlayer *iface, IWMPPlaylist **ppPL) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_currentPlaylist(&This->IWMPPlayer4_iface, ppPL); +} + +static HRESULT WINAPI WMPPlayer_put_currentPlaylist(IWMPPlayer *iface, IWMPPlaylist *pPL) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_currentPlaylist(&This->IWMPPlayer4_iface, pPL); +} + +static HRESULT WINAPI WMPPlayer_get_cdromCollection(IWMPPlayer *iface, IWMPCdromCollection **ppCdromCollection) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_cdromCollection(&This->IWMPPlayer4_iface, ppCdromCollection); +} + +static HRESULT WINAPI WMPPlayer_get_closedCaption(IWMPPlayer *iface, IWMPClosedCaption **ppClosedCaption) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_closedCaption(&This->IWMPPlayer4_iface, ppClosedCaption); +} + +static HRESULT WINAPI WMPPlayer_get_isOnline(IWMPPlayer *iface, VARIANT_BOOL *pfOnline) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_isOnline(&This->IWMPPlayer4_iface, pfOnline); +} + +static HRESULT WINAPI WMPPlayer_get_Error(IWMPPlayer *iface, IWMPError **ppError) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_Error(&This->IWMPPlayer4_iface, ppError); +} + +static HRESULT WINAPI WMPPlayer_get_Status(IWMPPlayer *iface, BSTR *pbstrStatus) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_Status(&This->IWMPPlayer4_iface, pbstrStatus); +} + +static HRESULT WINAPI WMPPlayer_get_enabled(IWMPPlayer *iface, VARIANT_BOOL *pbEnabled) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_enabled(&This->IWMPPlayer4_iface, pbEnabled); +} + +static HRESULT WINAPI WMPPlayer_put_enabled(IWMPPlayer *iface, VARIANT_BOOL enabled) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_enabled(&This->IWMPPlayer4_iface, enabled); +} + +static HRESULT WINAPI WMPPlayer_get_fullScreen(IWMPPlayer *iface, VARIANT_BOOL *pbFullScreen) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_fullScreen(&This->IWMPPlayer4_iface, pbFullScreen); +} + +static HRESULT WINAPI WMPPlayer_put_fullScreen(IWMPPlayer *iface, VARIANT_BOOL fullscreen) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_fullScreen(&This->IWMPPlayer4_iface, fullscreen); +} + +static HRESULT WINAPI WMPPlayer_get_enableContextMenu(IWMPPlayer *iface, VARIANT_BOOL *pbEnableContextMenu) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_enableContextMenu(&This->IWMPPlayer4_iface, pbEnableContextMenu); +} + +static HRESULT WINAPI WMPPlayer_put_enableContextMenu(IWMPPlayer *iface, VARIANT_BOOL enable) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_enableContextMenu(&This->IWMPPlayer4_iface, enable); +} + +static HRESULT WINAPI WMPPlayer_put_uiMode(IWMPPlayer *iface, BSTR mode) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_put_uiMode(&This->IWMPPlayer4_iface, mode); +} + +static HRESULT WINAPI WMPPlayer_get_uiMode(IWMPPlayer *iface, BSTR *pbstrMode) +{ + WindowsMediaPlayer *This = impl_from_IWMPPlayer(iface); + return WMPPlayer4_get_uiMode(&This->IWMPPlayer4_iface, pbstrMode); +} + +static IWMPPlayerVtbl WMPPlayerVtbl = { + WMPPlayer_QueryInterface, + WMPPlayer_AddRef, + WMPPlayer_Release, + WMPPlayer_GetTypeInfoCount, + WMPPlayer_GetTypeInfo, + WMPPlayer_GetIDsOfNames, + WMPPlayer_Invoke, + WMPPlayer_close, + WMPPlayer_get_URL, + WMPPlayer_put_URL, + WMPPlayer_get_openState, + WMPPlayer_get_playState, + WMPPlayer_get_controls, + WMPPlayer_get_settings, + WMPPlayer_get_currentMedia, + WMPPlayer_put_currentMedia, + WMPPlayer_get_mediaCollection, + WMPPlayer_get_playlistCollection, + WMPPlayer_get_versionInfo, + WMPPlayer_launchURL, + WMPPlayer_get_network, + WMPPlayer_get_currentPlaylist, + WMPPlayer_put_currentPlaylist, + WMPPlayer_get_cdromCollection, + WMPPlayer_get_closedCaption, + WMPPlayer_get_isOnline, + WMPPlayer_get_Error, + WMPPlayer_get_Status, + WMPPlayer_get_enabled, + WMPPlayer_put_enabled, + WMPPlayer_get_fullScreen, + WMPPlayer_put_fullScreen, + WMPPlayer_get_enableContextMenu, + WMPPlayer_put_enableContextMenu, + WMPPlayer_put_uiMode, + WMPPlayer_get_uiMode, +}; + + static IWMPPlayer4Vtbl WMPPlayer4Vtbl = { WMPPlayer4_QueryInterface, WMPPlayer4_AddRef, @@ -664,5 +934,6 @@ static const IWMPSettingsVtbl WMPSettingsVtbl = { void init_player_ifaces(WindowsMediaPlayer *wmp) { wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; + wmp->IWMPPlayer_iface.lpVtbl = &WMPPlayerVtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; } diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c index 2b646d7b1d..05861e1c10 100644 --- a/dlls/wmp/tests/oleobj.c +++ b/dlls/wmp/tests/oleobj.c @@ -792,6 +792,7 @@ static void test_wmp_ifaces(IOleObject *oleobj) { IWMPSettings *settings, *settings_qi; IWMPPlayer4 *player4; + IWMPPlayer *player; HRESULT hres;
hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer4, (void**)&player4); @@ -809,6 +810,22 @@ static void test_wmp_ifaces(IOleObject *oleobj)
IWMPSettings_Release(settings); IWMPPlayer4_Release(player4); + + hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer, (void**)&player); + ok(hres == S_OK, "Could not get IWMPPlayer iface: %08x\n", hres); + + settings = NULL; + hres = IWMPPlayer_get_settings(player, &settings); + ok(hres == S_OK, "get_settings failed: %08x\n", hres); + ok(settings != NULL, "settings = NULL\n"); + + hres = IOleObject_QueryInterface(oleobj, &IID_IWMPSettings, (void**)&settings_qi); + ok(hres == S_OK, "Could not get IWMPSettings iface: %08x\n", hres); + ok(settings == settings_qi, "settings != settings_qi\n"); + IWMPSettings_Release(settings_qi); + + IWMPSettings_Release(settings); + IWMPPlayer_Release(player); }
#define test_rect_size(a,b,c) _test_rect_size(__LINE__,a,b,c) diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 7b7f51cd63..aaff9777d4 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -30,6 +30,7 @@ struct WindowsMediaPlayer { IConnectionPointContainer IConnectionPointContainer_iface; IOleControl IOleControl_iface; IWMPPlayer4 IWMPPlayer4_iface; + IWMPPlayer IWMPPlayer_iface; IWMPSettings IWMPSettings_iface;
LONG ref; diff --git a/include/wmp.idl b/include/wmp.idl index a879ab7c83..442b702138 100644 --- a/include/wmp.idl +++ b/include/wmp.idl @@ -1007,6 +1007,31 @@ library WMPLib { HRESULT openPlayer([in] BSTR bstrURL); }
+ [ + odl, + uuid(6BF52A4F-394A-11D3-B153-00C04F79FAA6), + dual, + oleautomation + ] + interface IWMPPlayer : IWMPCore { + [id(0x00000013), propget] + HRESULT enabled([out, retval] VARIANT_BOOL* pbEnabled); + [id(0x00000013), propput] + HRESULT enabled([in] VARIANT_BOOL pbEnabled); + [id(0x00000015), propget] + HRESULT fullScreen([out, retval] VARIANT_BOOL* pbFullScreen); + [id(0x00000015), propput] + HRESULT fullScreen(VARIANT_BOOL pbFullScreen); + [id(0x00000016), propget] + HRESULT enableContextMenu([out, retval] VARIANT_BOOL* pbEnableContextMenu); + [id(0x00000016), propput] + HRESULT enableContextMenu(VARIANT_BOOL pbEnableContextMenu); + [id(0x00000017), propput] + HRESULT uiMode([in] BSTR pbstrMode); + [id(0x00000017), propget] + HRESULT uiMode([out, retval] BSTR* pbstrMode); + }; + [ odl, uuid(82a2986c-0293-4fd0-b279-b21b86c058be), @@ -1406,7 +1431,7 @@ library WMPLib { [default] interface IWMPPlayer4; /* interface IWMPPlayer3; */ /* interface IWMPPlayer2; */ - /* interface IWMPPlayer; */ + interface IWMPPlayer; interface IWMPControls; interface IWMPSettings; interface IWMPPlaylist;
Signed-off-by: Anton Romanov theli.ua@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 | 70 ++++++++- dlls/wmp/wmp_main.c | 2 + dlls/wmp/wmp_private.h | 36 +++-- 7 files changed, 506 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 fbad032648..7be92865ae 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 accf5401ed..7fc5be2546 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); @@ -931,9 +933,14 @@ 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->IWMPPlayer_iface.lpVtbl = &WMPPlayerVtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; + return S_OK; } 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 aaff9777d4..895906e493 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,27 +50,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); -}
Hi Anton,
On 02/07/2018 09:24 PM, Anton Romanov wrote:
- 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];
I think you're missing IUnknown_AddRef() here.
+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);
- }
+}
You don't use it in this patch, so it's a dead code. Please remove it from this patch (and introduce it with a patch that uses it).
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)
return hres;destroy_player(wmp);
Error handling looks wrong here. If QueryInterface() fails, you'd both release wmp and call destroy_wmp. Also init_player can't fail, so it should return void.
Thanks, Jacek
On 02/09/2018 04:21 PM, Jacek Caban wrote:
Hi Anton,
On 02/07/2018 09:24 PM, Anton Romanov wrote:
- 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];
I think you're missing IUnknown_AddRef() here.
+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);
- }
+}
You don't use it in this patch, so it's a dead code. Please remove it from this patch (and introduce it with a patch that uses it).
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)
return hres;destroy_player(wmp);
Error handling looks wrong here. If QueryInterface() fails, you'd both release wmp and call destroy_wmp. Also init_player can't fail, so it should return void.
Thanks, Jacek
Also events.c is missing license header.
Thanks,
Jacek
- 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];
I think you're missing IUnknown_AddRef() here.
It does look like it should addref those. I will doublecheck. Also, all of this code is for the most part a copy of dlls/ieframe/events.c . That means that it might also be impacted by this.
+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);
- }
+}
You don't use it in this patch, so it's a dead code. Please remove it from this patch (and introduce it with a patch that uses it).
Sure. I'll move this part to patch where I start using it.
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)
return hres;destroy_player(wmp);
Error handling looks wrong here. If QueryInterface() fails, you'd both release wmp and call destroy_wmp. Also init_player can't fail, so it should return void.
Thanks, you are right. I broke that logic and it may lead to double free :( And I'll change init to void until later patch where it may actually fail, sure.