[PATCH] wmp: Implement GetClassInfo().
Nikolay Sivov
nsivov at codeweavers.com
Tue Aug 21 01:03:41 CDT 2018
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/wmp/oleobj.c | 11 +++++--
dlls/wmp/tests/oleobj.c | 12 ++++++++
dlls/wmp/wmp_main.c | 66 +++++++++++++++++++++++++++++++++++++++++
dlls/wmp/wmp_private.h | 15 ++++++++++
4 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c
index a90a0c2c6c..cbbd965c38 100644
--- a/dlls/wmp/oleobj.c
+++ b/dlls/wmp/oleobj.c
@@ -760,11 +760,16 @@ static ULONG WINAPI ProvideClassInfo2_Release(IProvideClassInfo2 *iface)
return IOleObject_Release(&This->IOleObject_iface);
}
-static HRESULT WINAPI ProvideClassInfo2_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI)
+static HRESULT WINAPI ProvideClassInfo2_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ti)
{
WindowsMediaPlayer *This = impl_from_IProvideClassInfo2(iface);
- FIXME("(%p)->(%p)\n", This, ppTI);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%p)\n", This, ti);
+
+ if (!ti)
+ return E_POINTER;
+
+ return get_typeinfo(WindowsMediaPlayer_tid, ti);
}
static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID)
diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c
index 472b985244..2a69a102de 100644
--- a/dlls/wmp/tests/oleobj.c
+++ b/dlls/wmp/tests/oleobj.c
@@ -1199,6 +1199,8 @@ static void test_wmp(void)
IOleObject *oleobj;
IWMPCore *wmpcore;
DWORD misc_status;
+ TYPEATTR *attr;
+ ITypeInfo *ti;
RECT pos = {0,0,100,100};
HWND hwnd;
GUID guid;
@@ -1232,6 +1234,16 @@ static void test_wmp(void)
ok(hres == S_OK, "GetGUID failed: %08x\n", hres);
ok(IsEqualGUID(&guid, &IID__WMPOCXEvents), "guid = %s\n", wine_dbgstr_guid(&guid));
+ hres = IProvideClassInfo2_GetClassInfo(class_info, NULL);
+ ok(hres == E_POINTER, "Unexpected hr %#x.\n", hres);
+ hres = IProvideClassInfo2_GetClassInfo(class_info, &ti);
+ ok(hres == S_OK, "Failed to get class info, hr %#x.\n", hres);
+ hres = ITypeInfo_GetTypeAttr(ti, &attr);
+ ok(hres == S_OK, "Failed to get type attributes, hr %#x.\n", hres);
+ ok(IsEqualGUID(&CLSID_WindowsMediaPlayer, &attr->guid), "Unexpected typeinfo guid %s\n", wine_dbgstr_guid(&attr->guid));
+ ITypeInfo_ReleaseTypeAttr(ti, attr);
+ ITypeInfo_Release(ti);
+
IProvideClassInfo2_Release(class_info);
test_QI((IUnknown*)oleobj);
diff --git a/dlls/wmp/wmp_main.c b/dlls/wmp/wmp_main.c
index 273d193e58..2541fc54ff 100644
--- a/dlls/wmp/wmp_main.c
+++ b/dlls/wmp/wmp_main.c
@@ -27,6 +27,71 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
HINSTANCE wmp_instance;
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+static REFIID tid_ids[] = {
+#define XIID(iface) &IID_ ## iface,
+#define CTID(name) &CLSID_ ## name,
+TID_LIST
+#undef XIID
+#undef CTID
+};
+
+static ITypeLib *typelib;
+static ITypeInfo *typeinfos[LAST_tid];
+
+static HRESULT load_typelib(void)
+{
+ ITypeLib *tl;
+ HRESULT hr;
+
+ hr = LoadRegTypeLib(&LIBID_WMPLib, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
+ if (FAILED(hr)) {
+ ERR("LoadRegTypeLib failed: %08x\n", hr);
+ return hr;
+ }
+
+ if (InterlockedCompareExchangePointer((void **)&typelib, tl, NULL))
+ ITypeLib_Release(tl);
+ return hr;
+}
+
+HRESULT get_typeinfo(typeinfo_id tid, ITypeInfo **typeinfo)
+{
+ HRESULT hr;
+
+ if (!typelib)
+ hr = load_typelib();
+ if (!typelib)
+ return hr;
+
+ if (!typeinfos[tid]) {
+ ITypeInfo *ti;
+
+ hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
+ if (FAILED(hr)) {
+ ERR("GetTypeInfoOfGuid (%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
+ return hr;
+ }
+
+ if (InterlockedCompareExchangePointer((void **)(typeinfos + tid), ti, NULL))
+ ITypeInfo_Release(ti);
+ }
+
+ *typeinfo = typeinfos[tid];
+ ITypeInfo_AddRef(*typeinfo);
+ return S_OK;
+}
+
+static void release_typelib(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
+ if (typeinfos[i])
+ ITypeInfo_Release(typeinfos[i]);
+
+ ITypeLib_Release(typelib);
+}
+
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
@@ -93,6 +158,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
case DLL_PROCESS_DETACH:
unregister_wmp_class();
unregister_player_msg_class();
+ release_typelib();
break;
}
diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
index 9617be0c7f..ab9c6d098c 100644
--- a/dlls/wmp/wmp_private.h
+++ b/dlls/wmp/wmp_private.h
@@ -25,6 +25,21 @@
#include "dshow.h"
#include "wmp.h"
+#define TID_LIST \
+ XIID(NULL) \
+ CTID(WindowsMediaPlayer)
+
+typedef enum {
+#define XIID(iface) iface ## _tid,
+#define CTID(name) name ## _tid,
+TID_LIST
+#undef XIID
+#undef CTID
+ LAST_tid
+} typeinfo_id;
+
+HRESULT get_typeinfo(typeinfo_id tid, ITypeInfo **typeinfo) DECLSPEC_HIDDEN;
+
typedef struct {
IConnectionPoint IConnectionPoint_iface;
--
2.18.0
More information about the wine-devel
mailing list