Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/oleobj.c | 1 + dlls/wmp/player.c | 293 +++++++++++++++++++++++++++++++++++++++++++-- dlls/wmp/tests/Makefile.in | 3 + dlls/wmp/tests/av.mp4 | Bin 0 -> 1493 bytes dlls/wmp/tests/oleobj.c | 78 ++++++++++++ dlls/wmp/tests/rsrc.rc | 22 ++++ dlls/wmp/wmp_private.h | 29 +++++ 7 files changed, 418 insertions(+), 8 deletions(-) create mode 100644 dlls/wmp/tests/av.mp4 create mode 100644 dlls/wmp/tests/rsrc.rc
diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c index 25787fa759..cc0e9a9d98 100644 --- a/dlls/wmp/oleobj.c +++ b/dlls/wmp/oleobj.c @@ -308,6 +308,7 @@ static ULONG WINAPI OleObject_Release(IOleObject *iface) if(!ref) { release_client_site(This); ConnectionPointContainer_Destroy(This); + destroy_player(This); heap_free(This); }
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 2628fa4b5d..1febb3f6ce 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -22,6 +22,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
+static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface) +{ + return CONTAINING_RECORD(iface, WMPMedia, IWMPMedia_iface); +} + static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface) { return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface); @@ -98,15 +103,23 @@ static HRESULT WINAPI WMPPlayer4_close(IWMPPlayer4 *iface) static HRESULT WINAPI WMPPlayer4_get_URL(IWMPPlayer4 *iface, BSTR *pbstrURL) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, pbstrURL); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pbstrURL); + if(This->wmpmedia == NULL) { + return S_FALSE; + } + return IWMPMedia_get_sourceURL(This->wmpmedia, pbstrURL); }
static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(url)); - return E_NOTIMPL; + IWMPMedia *media; + TRACE("(%p)->(%s)\n", This, debugstr_w(url)); + if(url == NULL) { + return E_POINTER; + } + media = create_media_from_url(url); + return IWMPPlayer4_put_currentMedia(iface, media); }
static HRESULT WINAPI WMPPlayer4_get_openState(IWMPPlayer4 *iface, WMPOpenState *pwmpos) @@ -148,15 +161,28 @@ static HRESULT WINAPI WMPPlayer4_get_settings(IWMPPlayer4 *iface, IWMPSettings * static HRESULT WINAPI WMPPlayer4_get_currentMedia(IWMPPlayer4 *iface, IWMPMedia **ppMedia) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, ppMedia); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, ppMedia); + if(This->wmpmedia == NULL) { + return S_FALSE; + } + IWMPMedia_AddRef(This->wmpmedia); + *ppMedia = This->wmpmedia; + return S_OK; }
static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia *pMedia) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, pMedia); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pMedia); + if(pMedia == NULL) { + return E_POINTER; + } + if(This->wmpmedia != NULL) { + IWMPMedia_Release(This->wmpmedia); + } + This->wmpmedia = pMedia; + IWMPMedia_AddRef(This->wmpmedia); + return S_OK; }
static HRESULT WINAPI WMPPlayer4_get_mediaCollection(IWMPPlayer4 *iface, IWMPMediaCollection **ppMediaCollection) @@ -1157,6 +1183,241 @@ static const IWMPControlsVtbl WMPControlsVtbl = { WMPControls_playItem, };
+static HRESULT WINAPI WMPMedia_QueryInterface(IWMPMedia *iface, REFIID riid, void **ppv) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + TRACE("(%p)\n", This); + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IWMPMedia_iface; + }else if(IsEqualGUID(&IID_IDispatch, riid)) { + TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); + *ppv = &This->IWMPMedia_iface; + }else if(IsEqualGUID(&IID_IWMPMedia, riid)) { + TRACE("(%p)->(IID_IWMPMedia %p)\n", This, ppv); + *ppv = &This->IWMPMedia_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 WMPMedia_AddRef(IWMPMedia *iface) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI WMPMedia_Release(IWMPMedia *iface) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + heap_free(This->url); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI WMPMedia_GetTypeInfoCount(IWMPMedia *iface, UINT *pctinfo) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_GetTypeInfo(IWMPMedia *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_GetIDsOfNames(IWMPMedia *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_Invoke(IWMPMedia *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_isIdentical(IWMPMedia *iface, IWMPMedia *other, VARIANT_BOOL *pvBool) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p, %p)\n", This, other, pvBool); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_sourceURL(IWMPMedia *iface, BSTR *pbstrSourceUrl) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pbstrSourceUrl); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *pbstrName) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pbstrName); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_put_name(IWMPMedia *iface, BSTR pbstrName) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pbstrName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_imageSourceWidth(IWMPMedia *iface, LONG *pWidth) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pWidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_imageSourceHeight(IWMPMedia *iface, LONG *pHeight) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pHeight); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_markerCount(IWMPMedia *iface, LONG* pMarkerCount) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pMarkerCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_getMarkerTime(IWMPMedia *iface, LONG MarkerNum, DOUBLE *pMarkerTime) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, MarkerNum, pMarkerTime); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_getMarkerName(IWMPMedia *iface, LONG MarkerNum, BSTR *pbstrMarkerName) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, MarkerNum, pbstrMarkerName); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_duration(IWMPMedia *iface, DOUBLE *pDuration) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pDuration); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_durationString(IWMPMedia *iface, BSTR *pbstrDuration) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pbstrDuration); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_get_attributeCount(IWMPMedia *iface, LONG *plCount) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, plCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_getAttributeName(IWMPMedia *iface, LONG lIndex, BSTR *pbstrItemName) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, lIndex, pbstrItemName); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_getItemInfo(IWMPMedia *iface, BSTR bstrItemName, BSTR *pbstrVal) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrItemName), pbstrVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_setItemInfo(IWMPMedia *iface, BSTR bstrItemName, BSTR bstrVal) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s, %s)\n", This, debugstr_w(bstrItemName), debugstr_w(bstrVal)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_getItemInfoByAtom(IWMPMedia *iface, LONG lAtom, BSTR *pbstrVal) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, lAtom, pbstrVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_isMemberOf(IWMPMedia *iface, IWMPPlaylist *pPlaylist, VARIANT_BOOL *pvarfIsMemberOf) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p, %p)\n", This, pPlaylist, pvarfIsMemberOf); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_isReadOnlyItem(IWMPMedia *iface, BSTR bstrItemName, VARIANT_BOOL *pvarfIsReadOnly) +{ + WMPMedia *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrItemName), pvarfIsReadOnly); + return E_NOTIMPL; +} + +static const IWMPMediaVtbl WMPMediaVtbl = { + WMPMedia_QueryInterface, + WMPMedia_AddRef, + WMPMedia_Release, + WMPMedia_GetTypeInfoCount, + WMPMedia_GetTypeInfo, + WMPMedia_GetIDsOfNames, + WMPMedia_Invoke, + WMPMedia_get_isIdentical, + WMPMedia_get_sourceURL, + WMPMedia_get_name, + WMPMedia_put_name, + WMPMedia_get_imageSourceWidth, + WMPMedia_get_imageSourceHeight, + WMPMedia_get_markerCount, + WMPMedia_getMarkerTime, + WMPMedia_getMarkerName, + WMPMedia_get_duration, + WMPMedia_get_durationString, + WMPMedia_get_attributeCount, + WMPMedia_getAttributeName, + WMPMedia_getItemInfo, + WMPMedia_setItemInfo, + WMPMedia_getItemInfoByAtom, + WMPMedia_isMemberOf, + WMPMedia_isReadOnlyItem +}; + void init_player(WindowsMediaPlayer *wmp) { wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; @@ -1167,3 +1428,19 @@ void init_player(WindowsMediaPlayer *wmp) wmp->invoke_urls = VARIANT_TRUE; wmp->auto_start = VARIANT_TRUE; } + +void destroy_player(WindowsMediaPlayer *wmp) +{ + if(wmp->wmpmedia) + IWMPMedia_Release(wmp->wmpmedia); +} + +IWMPMedia* create_media_from_url(BSTR url){ + + WMPMedia *media = heap_alloc_zero(sizeof(WMPMedia)); + media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; + media->url = heap_strdupW(url); + media->ref = 1; + + return &media->IWMPMedia_iface; +} diff --git a/dlls/wmp/tests/Makefile.in b/dlls/wmp/tests/Makefile.in index df770c78c6..dded3a4a7e 100644 --- a/dlls/wmp/tests/Makefile.in +++ b/dlls/wmp/tests/Makefile.in @@ -2,3 +2,6 @@ TESTDLL = wmp.dll IMPORTS = ole32 oleaut32 user32 gdi32
C_SRCS = oleobj.c + +RC_SRCS = \ + rsrc.rc diff --git a/dlls/wmp/tests/av.mp4 b/dlls/wmp/tests/av.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..1431e98dd3f5bb28c282d3d732a3a1fc13cf3d63 GIT binary patch literal 1493 zcmeHHO-sW-5Z$D$cn}OyK`=rq^=7}c+G`IUJa`ik#7o*uZD_U$*=<2j`7uHf{1GDl z1OJ2v!Gm5r>6;{NZ56!et&eVJ_RZ{@-Py2=F|(~MeMfqNF`bdc*b#oM${1U02eu9V zMQ}^yjZE%({o@Y&97zZ2!~blBKX3W>_ST2tck=HTAD{cZ@Vo&eT`}nJY3bAx=4GZa z`b{u30X;KsOfrA+Qdsb;0;`MQx#~tW!HuCOUU|%5K~!R<&M$QfHdhiFrtM0VXpus! z8w+y59SdAe@Y%E99^ge_ClAreVu!myqQRus?~Q!2$C&d&tH)iNa<paP^xAL?DW*gV zJmyUv*c2zwHkSH<n@jvhshTeQ3#sJjGAQR1Zxn5mK=T+nGsvN>0=u^4bYPYW!*CPt zTN*aoSS3n(!+3qqfYDcs1sIL`ye3uDqbLP`;L_xqDBmInpmH=QpDe|$U`GJ2p{zzd z&Pvttk^tpyV>J6*S+Hlqjx2@qU;BwW2rS>HV~<gE;!E4QQ633y;7KMC5@ko$puM+W Ks#QwWO7#=93TT)B
literal 0 HcmV?d00001
diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c index 42ed858b85..5185710716 100644 --- a/dlls/wmp/tests/oleobj.c +++ b/dlls/wmp/tests/oleobj.c @@ -18,12 +18,16 @@
#define WIN32_LEAN_AND_MEAN #define COBJMACROS +#include <stdarg.h> #include <initguid.h> +#include <windef.h> +#include <winbase.h> #include <windows.h> #include <wmp.h> #include <olectl.h>
#include "wine/test.h" +#include "wine/heap.h"
#define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE @@ -60,6 +64,32 @@ DEFINE_EXPECT(GetWindowContext); DEFINE_EXPECT(ShowObject); DEFINE_EXPECT(OnShowWindow_FALSE);
+static const WCHAR mp4file[] = {'a','v','.','m','p','4',0}; +static inline WCHAR *load_resource(const WCHAR *name) +{ + static WCHAR pathW[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); + lstrcatW(pathW, name); + + file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW), + GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); + WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); + ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); + CloseHandle( file ); + + return pathW; +} + static HWND container_hwnd;
static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv) @@ -859,9 +889,12 @@ static void test_wmp_ifaces(IOleObject *oleobj) IWMPSettings *settings, *settings_qi; IWMPPlayer4 *player4; IWMPPlayer *player; + IWMPMedia *media; IWMPControls *controls; VARIANT_BOOL vbool; HRESULT hres; + WCHAR *filename; + BSTR url;
hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer4, (void**)&player4); ok(hres == S_OK, "Could not get IWMPPlayer4 iface: %08x\n", hres); @@ -878,6 +911,50 @@ static void test_wmp_ifaces(IOleObject *oleobj)
IWMPControls_Release(controls);
+ media = NULL; + hres = IWMPPlayer4_QueryInterface(player4, &IID_IWMPMedia, (void**)&media); + ok(hres == E_NOINTERFACE, "get_currentMedia SUCCEEDED: %08x\n", hres); + ok(media == NULL, "media != NULL\n"); + + /* Test media put/get */ + media = NULL; + hres = IWMPPlayer4_get_currentMedia(player4, &media); + ok(hres == S_FALSE, "get_currentMedia SUCCEEDED\n"); + ok(media == NULL, "media != NULL\n"); + + filename = load_resource(mp4file); + + SET_EXPECT(GetContainer); + SET_EXPECT(Invoke_USERMODE); + hres = IWMPPlayer4_put_URL(player4, filename); + ok(hres == S_OK, "IWMPPlayer4_put_URL failed: %08x\n", hres); + todo_wine CHECK_CALLED(GetContainer); + todo_wine CHECK_CALLED(Invoke_USERMODE); + + SET_EXPECT(Invoke_USERMODE); + hres = IWMPPlayer4_get_URL(player4, &url); + todo_wine ok(hres == S_OK, "IWMPPlayer4_get_URL failed: %08x\n", hres); + todo_wine ok(0 == lstrcmpW(url, filename), "%s != %s", wine_dbgstr_w(url), wine_dbgstr_w(filename)); + todo_wine CHECK_CALLED(Invoke_USERMODE); + heap_free(url); + + hres = IWMPPlayer4_get_currentMedia(player4, &media); + ok(hres == S_OK, "get_currentMedia failed: %08x\n", hres); + ok(media != NULL, "media = (%p)\n", media); + + SET_EXPECT(GetContainer); + hres = IWMPPlayer4_put_currentMedia(player4, media); + ok(hres == S_OK, "put_currentMedia failed: %08x\n", hres); + todo_wine CHECK_CALLED(GetContainer); + + IWMPMedia_Release(media); + + hres = IWMPPlayer4_get_currentMedia(player4, &media); + ok(hres == S_OK, "get_currentMedia failed: %08x\n", hres); + ok(media != NULL, "media = (%p)\n", media); + + IWMPMedia_Release(media); + settings = NULL; hres = IWMPPlayer4_get_settings(player4, &settings); ok(hres == S_OK, "get_settings failed: %08x\n", hres); @@ -934,6 +1011,7 @@ static void test_wmp_ifaces(IOleObject *oleobj)
IWMPSettings_Release(settings); IWMPPlayer_Release(player); + heap_free(filename); }
#define test_rect_size(a,b,c) _test_rect_size(__LINE__,a,b,c) diff --git a/dlls/wmp/tests/rsrc.rc b/dlls/wmp/tests/rsrc.rc new file mode 100644 index 0000000000..fb30ae6940 --- /dev/null +++ b/dlls/wmp/tests/rsrc.rc @@ -0,0 +1,22 @@ +/* + * Resource file for wmp tests. + * + * 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 "windef.h" + +/* @makedep: av.mp4 */ +av.mp4 RCDATA "av.mp4" diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index a3baaf7206..465721bf4d 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -20,6 +20,7 @@
#include "windows.h" #include "wine/heap.h" +#include "wine/unicode.h" #include "ole2.h" #include "wmp.h"
@@ -34,6 +35,14 @@ typedef struct { IID iid; } ConnectionPoint;
+typedef struct { + IWMPMedia IWMPMedia_iface; + + LONG ref; + + WCHAR *url; +} WMPMedia; + struct WindowsMediaPlayer { IOleObject IOleObject_iface; IProvideClassInfo2 IProvideClassInfo2_iface; @@ -58,9 +67,13 @@ struct WindowsMediaPlayer { VARIANT_BOOL enable_error_dialogs;
ConnectionPoint *wmpocx; + + IWMPMedia *wmpmedia; };
void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; +void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; +IWMPMedia* create_media_from_url(BSTR url); void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN;
@@ -69,3 +82,19 @@ HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) void unregister_wmp_class(void) DECLSPEC_HIDDEN;
extern HINSTANCE wmp_instance DECLSPEC_HIDDEN; + +static inline WCHAR *heap_strdupW(const WCHAR *str) +{ + WCHAR *ret; + + if(str) { + size_t size = strlenW(str)+1; + ret = heap_alloc(size*sizeof(WCHAR)); + if(ret) + memcpy(ret, str, size*sizeof(WCHAR)); + }else { + ret = NULL; + } + + return ret; +}
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/tests/oleobj.c | 14 +++ dlls/wmp/wmp_private.h | 1 + 3 files changed, 321 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 1febb3f6ce..cb8e074103 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -27,6 +27,11 @@ static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface) return CONTAINING_RECORD(iface, WMPMedia, IWMPMedia_iface); }
+static inline WindowsMediaPlayer *impl_from_IWMPNetwork(IWMPNetwork *iface) +{ + return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPNetwork_iface); +} + static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface) { return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface); @@ -223,8 +228,11 @@ static HRESULT WINAPI WMPPlayer4_launchURL(IWMPPlayer4 *iface, BSTR url) static HRESULT WINAPI WMPPlayer4_get_network(IWMPPlayer4 *iface, IWMPNetwork **ppQNI) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, ppQNI); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, ppQNI); + + IWMPNetwork_AddRef(&This->IWMPNetwork_iface); + *ppQNI = &This->IWMPNetwork_iface; + return S_OK; }
static HRESULT WINAPI WMPPlayer4_get_currentPlaylist(IWMPPlayer4 *iface, IWMPPlaylist **ppPL) @@ -984,6 +992,301 @@ static const IWMPSettingsVtbl WMPSettingsVtbl = { WMPSettings_put_enableErrorDialogs };
+static HRESULT WINAPI WMPNetwork_QueryInterface(IWMPNetwork *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(riid, &IID_IDispatch)) { + *ppv = iface; + }else if(IsEqualGUID(riid, &IID_IWMPNetwork)) { + *ppv = iface; + }else { + WARN("Unsupported interface (%s)\n", wine_dbgstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI WMPNetwork_AddRef(IWMPNetwork *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + return IOleObject_AddRef(&This->IOleObject_iface); +} + +static ULONG WINAPI WMPNetwork_Release(IWMPNetwork *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + return IOleObject_Release(&This->IOleObject_iface); +} + +static HRESULT WINAPI WMPNetwork_GetTypeInfoCount(IWMPNetwork *iface, UINT *pctinfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_GetTypeInfo(IWMPNetwork *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_GetIDsOfNames(IWMPNetwork *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_Invoke(IWMPNetwork *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bandWidth(IWMPNetwork *iface, LONG *plBandwidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBandwidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_recoveredPackets(IWMPNetwork *iface, LONG *plRecoveredPackets) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plRecoveredPackets); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_sourceProtocol(IWMPNetwork *iface, BSTR *pbstrSourceProtocol) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, pbstrSourceProtocol); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_receivedPackets(IWMPNetwork *iface, LONG *plReceivedPackets) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plReceivedPackets); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_lostPackets(IWMPNetwork *iface, LONG *plLostPackets) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plLostPackets); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_receptionQuality(IWMPNetwork *iface, LONG *plReceptionQuality) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plReceptionQuality); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bufferingCount(IWMPNetwork *iface, LONG *plBufferingCount) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBufferingCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bufferingProgress(IWMPNetwork *iface, LONG *plBufferingProgress) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBufferingProgress); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bufferingTime(IWMPNetwork *iface, LONG *plBufferingTime) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBufferingTime); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_put_bufferingTime(IWMPNetwork *iface, LONG lBufferingTime) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%d)\n", This, lBufferingTime); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_frameRate(IWMPNetwork *iface, LONG *plFrameRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plFrameRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_maxBitRate(IWMPNetwork *iface, LONG *plBitRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBitRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bitRate(IWMPNetwork *iface, LONG *plBitRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBitRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxySettings(IWMPNetwork *iface, BSTR bstrProtocol, LONG *plProxySetting) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), plProxySetting); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxySettings(IWMPNetwork *iface, BSTR bstrProtocol, LONG lProxySetting) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %d)\n", This, debugstr_w(bstrProtocol), lProxySetting); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyName(IWMPNetwork *iface, BSTR bstrProtocol, BSTR *pbstrProxyName) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), pbstrProxyName); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyName(IWMPNetwork *iface, BSTR bstrProtocol, BSTR bstrProxyName) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %s)\n", This, debugstr_w(bstrProtocol), debugstr_w(bstrProxyName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyPort(IWMPNetwork *iface, BSTR bstrProtocol, LONG *plProxyPort) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), plProxyPort); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyPort(IWMPNetwork *iface, BSTR bstrProtocol, LONG lProxyPort) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %d)\n", This, debugstr_w(bstrProtocol), lProxyPort); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyExceptionList(IWMPNetwork *iface, BSTR bstrProtocol, BSTR *pbstrExceptionList) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), pbstrExceptionList); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyExceptionList(IWMPNetwork *iface, BSTR bstrProtocol, BSTR bstrExceptionList) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %s)\n", This, debugstr_w(bstrProtocol), debugstr_w(bstrExceptionList)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyBypassForLocal(IWMPNetwork *iface, BSTR bstrProtocol, VARIANT_BOOL *pfBypassForLocal) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), pfBypassForLocal); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyBypassForLocal(IWMPNetwork *iface, BSTR bstrProtocol, VARIANT_BOOL fBypassForLocal) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %d)\n", This, debugstr_w(bstrProtocol), fBypassForLocal); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_maxBandwidth(IWMPNetwork *iface, LONG *plMaxBandwidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plMaxBandwidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_put_maxBandwidth(IWMPNetwork *iface, LONG lMaxBandwidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%d)\n", This, lMaxBandwidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_downloadProgress(IWMPNetwork *iface, LONG *plDownloadProgress) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plDownloadProgress); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_encodedFrameRate(IWMPNetwork *iface, LONG *plFrameRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plFrameRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_framesSkipped(IWMPNetwork *iface, LONG *plFrames) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plFrames); + return E_NOTIMPL; +} + +static const IWMPNetworkVtbl WMPNetworkVtbl = { + WMPNetwork_QueryInterface, + WMPNetwork_AddRef, + WMPNetwork_Release, + WMPNetwork_GetTypeInfoCount, + WMPNetwork_GetTypeInfo, + WMPNetwork_GetIDsOfNames, + WMPNetwork_Invoke, + WMPNetwork_get_bandWidth, + WMPNetwork_get_recoveredPackets, + WMPNetwork_get_sourceProtocol, + WMPNetwork_get_receivedPackets, + WMPNetwork_get_lostPackets, + WMPNetwork_get_receptionQuality, + WMPNetwork_get_bufferingCount, + WMPNetwork_get_bufferingProgress, + WMPNetwork_get_bufferingTime, + WMPNetwork_put_bufferingTime, + WMPNetwork_get_frameRate, + WMPNetwork_get_maxBitRate, + WMPNetwork_get_bitRate, + WMPNetwork_getProxySettings, + WMPNetwork_setProxySettings, + WMPNetwork_getProxyName, + WMPNetwork_setProxyName, + WMPNetwork_getProxyPort, + WMPNetwork_setProxyPort, + WMPNetwork_getProxyExceptionList, + WMPNetwork_setProxyExceptionList, + WMPNetwork_getProxyBypassForLocal, + WMPNetwork_setProxyBypassForLocal, + WMPNetwork_get_maxBandwidth, + WMPNetwork_put_maxBandwidth, + WMPNetwork_get_downloadProgress, + WMPNetwork_get_encodedFrameRate, + WMPNetwork_get_framesSkipped, +}; + static HRESULT WINAPI WMPControls_QueryInterface(IWMPControls *iface, REFIID riid, void **ppv) { if(IsEqualGUID(riid, &IID_IDispatch)) { @@ -1424,6 +1727,7 @@ void init_player(WindowsMediaPlayer *wmp) wmp->IWMPPlayer_iface.lpVtbl = &WMPPlayerVtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl; + wmp->IWMPNetwork_iface.lpVtbl = &WMPNetworkVtbl;
wmp->invoke_urls = VARIANT_TRUE; wmp->auto_start = VARIANT_TRUE; diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c index 5185710716..f9ccbd626e 100644 --- a/dlls/wmp/tests/oleobj.c +++ b/dlls/wmp/tests/oleobj.c @@ -892,6 +892,7 @@ static void test_wmp_ifaces(IOleObject *oleobj) IWMPMedia *media; IWMPControls *controls; VARIANT_BOOL vbool; + IWMPNetwork *network; HRESULT hres; WCHAR *filename; BSTR url; @@ -911,6 +912,19 @@ static void test_wmp_ifaces(IOleObject *oleobj)
IWMPControls_Release(controls);
+ /* IWPNetwork */ + network = NULL; + hres = IWMPPlayer4_get_network(player4, &network); + ok(hres == S_OK, "get_network failed: %08x\n", hres); + ok(network != NULL, "network = NULL\n"); + + player = NULL; + hres = IWMPNetwork_QueryInterface(network, &IID_IWMPPlayer, (void**)&player); + ok(hres != S_OK, "Getting IWMPPlayer from IWMPNetwork SUCCEEDED\n"); + ok(player == NULL, "player != NULL\n"); + + IWMPNetwork_Release(network); + media = NULL; hres = IWMPPlayer4_QueryInterface(player4, &IID_IWMPMedia, (void**)&media); ok(hres == E_NOINTERFACE, "get_currentMedia SUCCEEDED: %08x\n", hres); diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 465721bf4d..e95b194d77 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -54,6 +54,7 @@ struct WindowsMediaPlayer { IWMPPlayer IWMPPlayer_iface; IWMPSettings IWMPSettings_iface; IWMPControls IWMPControls_iface; + IWMPNetwork IWMPNetwork_iface;
LONG ref;
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=36503
Your paranoid android.
=== wxppro (32 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer oleobj.c:962: Test failed: expected GetContainer
=== w2003std (32 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer oleobj.c:962: Test failed: expected GetContainer
=== wvistau64 (32 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer oleobj.c:962: Test failed: expected GetContainer
=== wvistau64_zh_CN (32 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer oleobj.c:962: Test failed: expected GetContainer
=== wvistau64_fr (32 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer oleobj.c:962: Test failed: expected GetContainer
=== wvistau64_he (32 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer oleobj.c:962: Test failed: expected GetContainer
=== wvistau64 (64 bit oleobj) === oleobj.c:945: Test failed: expected GetContainer wmp:oleobj crashed (c0000374)
=== w7pro64 (64 bit oleobj) === wmp:oleobj crashed (c0000374)
=== w864 (64 bit oleobj) === wmp:oleobj crashed (c0000374)
=== w1064 (64 bit oleobj) === wmp:oleobj crashed (c0000374)
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=36502
Your paranoid android.
=== wxppro (32 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer oleobj.c:948: Test failed: expected GetContainer
=== w2003std (32 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer oleobj.c:948: Test failed: expected GetContainer
=== wvistau64 (32 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer oleobj.c:948: Test failed: expected GetContainer
=== wvistau64_zh_CN (32 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer oleobj.c:948: Test failed: expected GetContainer
=== wvistau64_fr (32 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer oleobj.c:948: Test failed: expected GetContainer
=== wvistau64_he (32 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer oleobj.c:948: Test failed: expected GetContainer
=== wvistau64 (64 bit oleobj) === oleobj.c:931: Test failed: expected GetContainer wmp:oleobj crashed (c0000374)
=== w7pro64 (64 bit oleobj) === wmp:oleobj crashed (c0000374)
=== w864 (64 bit oleobj) === wmp:oleobj crashed (c0000374)
=== w1064 (64 bit oleobj) === wmp:oleobj crashed (c0000374)