[PATCH 5/5] wmp: Add IWMPPlaylist stub.

Gijs Vermeulen gijsvrm at gmail.com
Thu Aug 1 07:47:23 CDT 2019


Signed-off-by: Gijs Vermeulen <gijsvrm at 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;
-- 
2.22.0




More information about the wine-devel mailing list