Signed-off-by: Gijs Vermeulen gijsvrm@codeweavers.com --- dlls/wmp/tests/media.c | 66 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index dd6fdcbc91..c190eee9fc 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -489,11 +489,40 @@ playback_skip:
static void test_media_item(void) { + static const WCHAR slashW[] = {'\',0}; static const WCHAR testW[] = {'t','e','s','t',0}; + static const WCHAR fooW[] = {'f','o','o',':','/','/',0}; + static const WCHAR fileW[] = {'f','i','l','e',':','/','/','/',0}; + static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; + static const WCHAR httpsW[] = {'h','t','t','p','s',':','/','/',0}; + static const WCHAR invalidurlW[] = {'i','n','v','a','l','i','d','_','u','r','l',0}; + static const WCHAR invalidurlmp3W[] = {'i','n','v','a','l','i','d','_','u','r','l','.','m','p','3',0}; + static const WCHAR winehqurlW[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g', + '/','t','e','s','t','s','/','t','e','s','t','.','m','p','3',0}; + static WCHAR pathW[MAX_PATH]; + static WCHAR currentdirW[MAX_PATH]; + struct { + const WCHAR *prefix; + const WCHAR *filename; + const WCHAR *expected; + } tests[] = { + { NULL, invalidurlmp3W, invalidurlW }, + { currentdirW, mp3file, testW }, + { currentdirW, invalidurlmp3W, invalidurlW }, + { httpW, winehqurlW, testW }, + { httpW, invalidurlmp3W, invalidurlmp3W }, + { httpsW, winehqurlW, testW }, + { httpsW, invalidurlmp3W, invalidurlmp3W }, + { fileW, mp3file, testW }, + { fileW, invalidurlmp3W, invalidurlW }, + { fooW, mp3file, mp3file }, + { fooW, invalidurlmp3W, invalidurlmp3W } + }; IWMPMedia *media, *media2; IWMPPlayer4 *player; HRESULT hr; BSTR str; + int i;
hr = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IWMPPlayer4, (void **)&player); if (hr == REGDB_E_CLASSNOTREG) @@ -505,6 +534,9 @@ static void test_media_item(void)
hr = IWMPPlayer4_newMedia(player, NULL, &media); ok(hr == S_OK, "Failed to create a media item, hr %#x.\n", hr); + hr = IWMPMedia_get_name(media, NULL); +todo_wine + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); hr = IWMPMedia_get_name(media, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); ok(*str == 0, "Unexpected name %s.\n", wine_dbgstr_w(str)); @@ -542,7 +574,15 @@ static void test_media_item(void) hr = IWMPMedia_get_name(media, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); todo_wine - ok(!lstrcmpW(str, testW), "Unexpected name %s.\n", wine_dbgstr_w(str)); + ok(!lstrcmpW(str, testW), "Expected %s, got %s\n", wine_dbgstr_w(testW), wine_dbgstr_w(str)); + SysFreeString(str); + hr = IWMPMedia_put_name(media, NULL); +todo_wine + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + hr = IWMPMedia_get_name(media, &str); + ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); +todo_wine + ok(!lstrcmpW(str, testW), "Expected %s, got %s\n", wine_dbgstr_w(testW), wine_dbgstr_w(str)); SysFreeString(str);
hr = IWMPPlayer4_put_currentMedia(player, media); @@ -555,10 +595,32 @@ todo_wine hr = IWMPMedia_get_name(media2, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); todo_wine - ok(!lstrcmpW(str, testW), "Unexpected name %s.\n", wine_dbgstr_w(str)); + ok(!lstrcmpW(str, testW), "Expected %s, got %s\n", wine_dbgstr_w(testW), wine_dbgstr_w(str)); SysFreeString(str); IWMPMedia_Release(media2);
+ GetCurrentDirectoryW(ARRAY_SIZE(currentdirW), currentdirW); + lstrcatW(currentdirW, slashW); + + for (i=0; i<ARRAY_SIZE(tests); i++) + { + + pathW[0] = '\0'; + if(tests[i].prefix) lstrcatW(pathW, tests[i].prefix); + lstrcatW(pathW, tests[i].filename); + + str = SysAllocString(pathW); + hr = IWMPPlayer4_newMedia(player, str, &media); + ok(hr == S_OK, "Failed to create a media item, hr %#x.\n", hr); + SysFreeString(str); + hr = IWMPMedia_get_name(media, &str); + ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); + todo_wine + ok(!lstrcmpW(str, tests[i].expected), "Expected %s, got %s\n", wine_dbgstr_w(tests[i].expected), wine_dbgstr_w(str)); + SysFreeString(str); + IWMPMedia_Release(media); + } + IWMPPlayer4_Release(player); }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47029 Signed-off-by: Gijs Vermeulen gijsvrm@codeweavers.com --- dlls/wmp/Makefile.in | 2 +- dlls/wmp/player.c | 61 +++++++++++++++++++++++++++++++++++++----- dlls/wmp/tests/media.c | 5 ---- dlls/wmp/wmp_private.h | 1 + 4 files changed, 56 insertions(+), 13 deletions(-)
diff --git a/dlls/wmp/Makefile.in b/dlls/wmp/Makefile.in index 5ed3d42cd8..e7312cf18b 100644 --- a/dlls/wmp/Makefile.in +++ b/dlls/wmp/Makefile.in @@ -1,5 +1,5 @@ MODULE = wmp.dll -IMPORTS = oleaut32 ole32 user32 gdi32 +IMPORTS = oleaut32 ole32 user32 gdi32 urlmon shlwapi
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 7a1befea21..5673d0e75a 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -21,6 +21,7 @@ #include "wine/debug.h" #include <nserror.h> #include "wmpids.h" +#include "shlwapi.h"
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
@@ -1730,6 +1731,7 @@ static ULONG WINAPI WMPMedia_Release(IWMPMedia *iface)
if(!ref) { heap_free(This->url); + heap_free(This->name); heap_free(This); }
@@ -1789,17 +1791,21 @@ static HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *name) { WMPMedia *This = impl_from_IWMPMedia(iface);
- FIXME("(%p)->(%p)\n", This, name); + TRACE("(%p)->(%p)\n", This, name);
- /* FIXME: this should be a display name */ - return return_bstr(This->url, name); + return return_bstr(This->name, name); }
-static HRESULT WINAPI WMPMedia_put_name(IWMPMedia *iface, BSTR pbstrName) +static HRESULT WINAPI WMPMedia_put_name(IWMPMedia *iface, BSTR name) { WMPMedia *This = impl_from_IWMPMedia(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(pbstrName)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(name)); + + if (!name) return E_POINTER; + + This->name = heap_strdupW(name); + return S_OK; }
static HRESULT WINAPI WMPMedia_get_imageSourceWidth(IWMPMedia *iface, LONG *pWidth) @@ -2022,13 +2028,54 @@ WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface) HRESULT create_media_from_url(BSTR url, double duration, IWMPMedia **ppMedia) { WMPMedia *media; + IUri *uri; + BSTR path; + HRESULT hr; + WCHAR *name_dup, slashW[] = {'/',0};
media = heap_alloc_zero(sizeof(*media)); if (!media) return E_OUTOFMEMORY;
media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; - media->url = url ? heap_strdupW(url) : heap_strdupW(emptyW); + + if (url) + { + media->url = heap_strdupW(url); + name_dup = heap_strdupW(url); + + hr = CreateUri(name_dup, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &uri); + if (FAILED(hr)) + { + heap_free(name_dup); + return hr; + } + hr = IUri_GetPath(uri, &path); + if (hr != S_OK) + { + heap_free(name_dup); + IUri_Release(uri); + return hr; + } + + /* GetPath() will return "/" for invalid uri's + * only strip extension when uri is valid + */ + if (wcscmp(path, slashW) != 0) + PathRemoveExtensionW(name_dup); + PathStripPathW(name_dup); + + media->name = name_dup; + + SysFreeString(path); + IUri_Release(uri); + } + else + { + media->url = heap_strdupW(emptyW); + media->name = heap_strdupW(emptyW); + } + media->duration = duration; media->ref = 1;
diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index c190eee9fc..3d750e13b2 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -573,15 +573,12 @@ todo_wine SysFreeString(str); hr = IWMPMedia_get_name(media, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); -todo_wine ok(!lstrcmpW(str, testW), "Expected %s, got %s\n", wine_dbgstr_w(testW), wine_dbgstr_w(str)); SysFreeString(str); hr = IWMPMedia_put_name(media, NULL); -todo_wine ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); hr = IWMPMedia_get_name(media, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); -todo_wine ok(!lstrcmpW(str, testW), "Expected %s, got %s\n", wine_dbgstr_w(testW), wine_dbgstr_w(str)); SysFreeString(str);
@@ -594,7 +591,6 @@ todo_wine ok(media2 != NULL, "Unexpected media instance.\n"); hr = IWMPMedia_get_name(media2, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); -todo_wine ok(!lstrcmpW(str, testW), "Expected %s, got %s\n", wine_dbgstr_w(testW), wine_dbgstr_w(str)); SysFreeString(str); IWMPMedia_Release(media2); @@ -615,7 +611,6 @@ todo_wine SysFreeString(str); hr = IWMPMedia_get_name(media, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); - todo_wine ok(!lstrcmpW(str, tests[i].expected), "Expected %s, got %s\n", wine_dbgstr_w(tests[i].expected), wine_dbgstr_w(str)); SysFreeString(str); IWMPMedia_Release(media); diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 27ec55ecc3..5149d73942 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -56,6 +56,7 @@ typedef struct { LONG ref;
WCHAR *url; + WCHAR *name;
DOUBLE duration; } WMPMedia;
Signed-off-by: Gijs Vermeulen gijsvrm@codeweavers.com --- dlls/wmp/tests/media.c | 1 - dlls/wmp/wmp_private.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index 3d750e13b2..7e76aee744 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -535,7 +535,6 @@ static void test_media_item(void) hr = IWMPPlayer4_newMedia(player, NULL, &media); ok(hr == S_OK, "Failed to create a media item, hr %#x.\n", hr); hr = IWMPMedia_get_name(media, NULL); -todo_wine ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); hr = IWMPMedia_get_name(media, &str); ok(hr == S_OK, "Failed to get item name, hr %#x.\n", hr); diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 5149d73942..0b1b02305f 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -135,7 +135,7 @@ static inline WCHAR *heap_strdupW(const WCHAR *str) static inline HRESULT return_bstr(const WCHAR *value, BSTR *p) { if(!p) - return E_INVALIDARG; + return E_POINTER;
if(value) { *p = SysAllocString(value);
Hi,
While running your changed tests, 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=55015
Your paranoid android.
=== debian10 (32 bit WoW report) ===
wmp: media: Timeout
Signed-off-by: Gijs Vermeulen gijsvrm@codeweavers.com --- dlls/wmp/player.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 5673d0e75a..fc4439d6f0 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1874,11 +1874,11 @@ static HRESULT WINAPI WMPMedia_getAttributeName(IWMPMedia *iface, LONG lIndex, B return E_NOTIMPL; }
-static HRESULT WINAPI WMPMedia_getItemInfo(IWMPMedia *iface, BSTR bstrItemName, BSTR *pbstrVal) +static HRESULT WINAPI WMPMedia_getItemInfo(IWMPMedia *iface, BSTR item_name, BSTR *value) { WMPMedia *This = impl_from_IWMPMedia(iface); - FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrItemName), pbstrVal); - return E_NOTIMPL; + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(item_name), value); + return return_bstr(NULL, value); }
static HRESULT WINAPI WMPMedia_setItemInfo(IWMPMedia *iface, BSTR bstrItemName, BSTR bstrVal)
Signed-off-by: Gijs Vermeulen gijsvrm@codeweavers.com --- dlls/wmp/player.c | 253 +++++++++++++++++++++++++++++++++++++++- dlls/wmp/tests/oleobj.c | 15 +++ dlls/wmp/wmp_private.h | 12 ++ 3 files changed, 277 insertions(+), 3 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index fc4439d6f0..4007215a1e 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -47,6 +47,11 @@ static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state) call_sink(wmp->wmpocx, type, &dispparams); }
+static inline WMPPlaylist *impl_from_IWMPPlaylist(IWMPPlaylist *iface) +{ + return CONTAINING_RECORD(iface, WMPPlaylist, IWMPPlaylist_iface); +} + static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface) { return CONTAINING_RECORD(iface, WMPMedia, IWMPMedia_iface); @@ -337,11 +342,13 @@ static HRESULT WINAPI WMPPlayer4_get_dvd(IWMPPlayer4 *iface, IWMPDVD **ppDVD) return E_NOTIMPL; }
-static HRESULT WINAPI WMPPlayer4_newPlaylist(IWMPPlayer4 *iface, BSTR name, BSTR url, IWMPPlaylist **ppPlaylist) +static HRESULT WINAPI WMPPlayer4_newPlaylist(IWMPPlayer4 *iface, BSTR name, BSTR url, IWMPPlaylist **playlist) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(url), ppPlaylist); - return E_NOTIMPL; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(url), playlist); + + return create_playlist(name, url, playlist); }
static HRESULT WINAPI WMPPlayer4_newMedia(IWMPPlayer4 *iface, BSTR url, IWMPMedia **media) @@ -1937,6 +1944,208 @@ static const IWMPMediaVtbl WMPMediaVtbl = { WMPMedia_isReadOnlyItem };
+static HRESULT WINAPI WMPPlaylist_QueryInterface(IWMPPlaylist *iface, REFIID riid, void **ppv) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + TRACE("(%p)\n", This); + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IWMPPlaylist_iface; + }else if(IsEqualGUID(&IID_IDispatch, riid)) { + TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); + *ppv = &This->IWMPPlaylist_iface; + }else if(IsEqualGUID(&IID_IWMPPlaylist, riid)) { + TRACE("(%p)->(IID_IWMPPlaylist %p)\n", This, ppv); + *ppv = &This->IWMPPlaylist_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 WMPPlaylist_AddRef(IWMPPlaylist *iface) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI WMPPlaylist_Release(IWMPPlaylist *iface) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI WMPPlaylist_GetTypeInfoCount(IWMPPlaylist *iface, UINT *pctinfo) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_GetTypeInfo(IWMPPlaylist *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_GetIDsOfNames(IWMPPlaylist *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_Invoke(IWMPPlaylist *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(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 WMPPlaylist_get_count(IWMPPlaylist *iface, LONG *count) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p)\n", This, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_get_name(IWMPPlaylist *iface, BSTR *name) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p)\n", This, name); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_put_name(IWMPPlaylist *iface, BSTR name) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_get_attributeCount(IWMPPlaylist *iface, LONG *count) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p)\n", This, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_get_attributeName(IWMPPlaylist *iface, LONG index, BSTR *attribute_name) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%d %p)\n", This, index, attribute_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_get_Item(IWMPPlaylist *iface, LONG index, IWMPMedia **media) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%d %p)\n", This, index, media); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_getItemInfo(IWMPPlaylist *iface, BSTR name, BSTR *value) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(name), value); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_setItemInfo(IWMPPlaylist *iface, BSTR name, BSTR value) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_w(value)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_get_isIdentical(IWMPPlaylist *iface, IWMPPlaylist *playlist, VARIANT_BOOL *var) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p %p)\n", This, playlist, var); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_clear(IWMPPlaylist *iface) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_insertItem(IWMPPlaylist *iface, LONG index, IWMPMedia *media) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%d %p)\n", This, index, media); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_appendItem(IWMPPlaylist *iface, IWMPMedia *media) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p)\n", This, media); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_removeItem(IWMPPlaylist *iface, IWMPMedia *media) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%p)\n", This, media); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPPlaylist_moveItem(IWMPPlaylist *iface, LONG old_index, LONG new_index) +{ + WMPPlaylist *This = impl_from_IWMPPlaylist(iface); + FIXME("(%p)->(%d %d)\n", This, old_index, new_index); + return E_NOTIMPL; +} + +static const IWMPPlaylistVtbl WMPPlaylistVtbl = { + WMPPlaylist_QueryInterface, + WMPPlaylist_AddRef, + WMPPlaylist_Release, + WMPPlaylist_GetTypeInfoCount, + WMPPlaylist_GetTypeInfo, + WMPPlaylist_GetIDsOfNames, + WMPPlaylist_Invoke, + WMPPlaylist_get_count, + WMPPlaylist_get_name, + WMPPlaylist_put_name, + WMPPlaylist_get_attributeCount, + WMPPlaylist_get_attributeName, + WMPPlaylist_get_Item, + WMPPlaylist_getItemInfo, + WMPPlaylist_setItemInfo, + WMPPlaylist_get_isIdentical, + WMPPlaylist_clear, + WMPPlaylist_insertItem, + WMPPlaylist_appendItem, + WMPPlaylist_removeItem, + WMPPlaylist_moveItem +}; + static LRESULT WINAPI player_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_WMPEVENT && wParam == 0) { @@ -1985,6 +2194,8 @@ void unregister_player_msg_class(void) {
BOOL init_player(WindowsMediaPlayer *wmp) { + IWMPPlaylist *playlist; + InitOnceExecuteOnce(&class_init_once, register_player_msg_class, NULL, NULL); wmp->msg_window = CreateWindowW( MAKEINTRESOURCEW(player_msg_class), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, wmp_instance, wmp ); @@ -2003,6 +2214,11 @@ BOOL init_player(WindowsMediaPlayer *wmp) wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl; wmp->IWMPNetwork_iface.lpVtbl = &WMPNetworkVtbl;
+ if (SUCCEEDED(create_playlist(NULL, NULL, &playlist))) + wmp->playlist = unsafe_impl_from_IWMPPlaylist(playlist); + else + wmp->playlist = NULL; + wmp->invoke_urls = VARIANT_TRUE; wmp->auto_start = VARIANT_TRUE; wmp->volume = 100; @@ -2025,6 +2241,14 @@ WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface) return NULL; }
+WMPPlaylist *unsafe_impl_from_IWMPPlaylist(IWMPPlaylist *iface) +{ + if (iface->lpVtbl == &WMPPlaylistVtbl) { + return CONTAINING_RECORD(iface, WMPPlaylist, IWMPPlaylist_iface); + } + return NULL; +} + HRESULT create_media_from_url(BSTR url, double duration, IWMPMedia **ppMedia) { WMPMedia *media; @@ -2087,3 +2311,26 @@ HRESULT create_media_from_url(BSTR url, double duration, IWMPMedia **ppMedia) IWMPMedia_Release(&media->IWMPMedia_iface); return E_OUTOFMEMORY; } + +HRESULT create_playlist(BSTR name, BSTR url, IWMPPlaylist **ppPlaylist) +{ + WMPPlaylist *playlist; + + playlist = heap_alloc_zero(sizeof(*playlist)); + if (!playlist) + return E_OUTOFMEMORY; + + playlist->IWMPPlaylist_iface.lpVtbl = &WMPPlaylistVtbl; + playlist->url = url ? heap_strdupW(url) : heap_strdupW(emptyW); + playlist->name = name ? heap_strdupW(name) : heap_strdupW(emptyW); + playlist->ref = 1; + + if (playlist->url) + { + *ppPlaylist = &playlist->IWMPPlaylist_iface; + return S_OK; + } + + IWMPPlaylist_Release(&playlist->IWMPPlaylist_iface); + return E_OUTOFMEMORY; +} diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c index deac5cd3db..dbd9e936ed 100644 --- a/dlls/wmp/tests/oleobj.c +++ b/dlls/wmp/tests/oleobj.c @@ -894,6 +894,7 @@ static void test_wmp_ifaces(IOleObject *oleobj) IWMPSettings *settings, *settings_qi; IWMPPlayer4 *player4; IWMPPlayer *player; + IWMPPlaylist *playlist; IWMPMedia *media; IWMPControls *controls; VARIANT_BOOL vbool; @@ -937,6 +938,20 @@ static void test_wmp_ifaces(IOleObject *oleobj)
IWMPNetwork_Release(network);
+ playlist = NULL; + hres = IWMPPlayer4_QueryInterface(player4, &IID_IWMPPlaylist, (void**)&playlist); + ok(hres == E_NOINTERFACE, "Getting IWMPPlaylist from IWMPPlayer4 succeeded: %08x\n", hres); + ok(playlist == NULL, "playlist != NULL\n"); + + playlist = NULL; + hres = IWMPPlayer4_get_currentPlaylist(player4, &playlist); +todo_wine { + ok(hres == S_OK, "IWMPPlayer4_get_currentPlaylist failed: %08x\n", hres); + ok(playlist != NULL, "playlist != NULL\n"); +} + + if (playlist) IWMPPlaylist_Release(playlist); + 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 0b1b02305f..32b4e1f6ae 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -61,6 +61,15 @@ typedef struct { DOUBLE duration; } WMPMedia;
+typedef struct { + IWMPPlaylist IWMPPlaylist_iface; + + LONG ref; + + WCHAR *url; + WCHAR *name; +} WMPPlaylist; + struct WindowsMediaPlayer { IOleObject IOleObject_iface; IProvideClassInfo2 IProvideClassInfo2_iface; @@ -89,6 +98,7 @@ struct WindowsMediaPlayer { ConnectionPoint *wmpocx;
WMPMedia *media; + WMPPlaylist *playlist;
/* DirectShow stuff */ IGraphBuilder* filter_graph; @@ -104,7 +114,9 @@ struct WindowsMediaPlayer { BOOL init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface) DECLSPEC_HIDDEN; +WMPPlaylist *unsafe_impl_from_IWMPPlaylist(IWMPPlaylist *iface) DECLSPEC_HIDDEN; HRESULT create_media_from_url(BSTR url, double duration, IWMPMedia **ppMedia) DECLSPEC_HIDDEN; +HRESULT create_playlist(BSTR name, BSTR url, IWMPPlaylist **ppPlaylist) DECLSPEC_HIDDEN; void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams) DECLSPEC_HIDDEN;