diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec index 10b682a21bd..e04c471e634 100644 --- a/dlls/mf/mf.spec +++ b/dlls/mf/mf.spec @@ -57,7 +57,7 @@ @ stub MFCreateSequencerSource @ stub MFCreateSequencerSourceRemoteStream @ stub MFCreateSimpleTypeHandler -@ stub MFCreateSourceResolver +@ stdcall MFCreateSourceResolver(ptr) mfplat.MFCreateSourceResolver @ stub MFCreateStandardQualityManager @ stub MFCreateTopoLoader @ stub MFCreateTopology diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 56bc2840f08..8fd5faf5d33 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -29,6 +29,7 @@ #include "initguid.h" #include "mfapi.h" +#include "mfidl.h" #include "mferror.h" #include "wine/debug.h" @@ -869,7 +870,7 @@ static const IMFAttributesVtbl mfattributes_vtbl = }; /*********************************************************************** - * MFMFCreateAttributes (mfplat.@) + * MFCreateAttributes (mfplat.@) */ HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size) { @@ -887,3 +888,168 @@ HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size) *attributes = &object->IMFAttributes_iface; return S_OK; } + +typedef struct _mfsourceresolver +{ + IMFSourceResolver IMFSourceResolver_iface; + LONG ref; +} mfsourceresolver; + +static inline mfsourceresolver *impl_from_IMFSourceResolver(IMFSourceResolver *iface) +{ + return CONTAINING_RECORD(iface, mfsourceresolver, IMFSourceResolver_iface); +} + +static HRESULT WINAPI mfsourceresolver_QueryInterface(IMFSourceResolver *iface, REFIID riid, void **obj) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + TRACE("(%p->(%s, %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IMFSourceResolver) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = &This->IMFSourceResolver_iface; + } + else + { + *obj = NULL; + FIXME("unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*obj); + return S_OK; +} + +static ULONG WINAPI mfsourceresolver_AddRef(IMFSourceResolver *iface) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(%u)\n", This, ref); + + return ref; +} + +static ULONG WINAPI mfsourceresolver_Release(IMFSourceResolver *iface) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(%u)\n", This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI mfsourceresolver_CreateObjectFromURL(IMFSourceResolver *iface, const WCHAR *url, + DWORD flags, IPropertyStore *props, MF_OBJECT_TYPE *obj_type, IUnknown **object) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%s, %#x, %p, %p, %p): stub\n", This, debugstr_w(url), flags, props, obj_type, object); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsourceresolver_CreateObjectFromByteStream(IMFSourceResolver *iface, IMFByteStream *stream, + const WCHAR *url, DWORD flags, IPropertyStore *props, MF_OBJECT_TYPE *obj_type, IUnknown **object) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%p, %s, %#x, %p, %p, %p): stub\n", This, stream, debugstr_w(url), flags, props, obj_type, object); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsourceresolver_BeginCreateObjectFromURL(IMFSourceResolver *iface, const WCHAR *url, + DWORD flags, IPropertyStore *props, IUnknown **cancel_cookie, IMFAsyncCallback *callback, IUnknown *unk_state) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%s, %#x, %p, %p, %p, %p): stub\n", This, debugstr_w(url), flags, props, cancel_cookie, + callback, unk_state); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsourceresolver_EndCreateObjectFromURL(IMFSourceResolver *iface, IMFAsyncResult *result, + MF_OBJECT_TYPE *obj_type, IUnknown **object) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%p, %p, %p): stub\n", This, result, obj_type, object); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsourceresolver_BeginCreateObjectFromByteStream(IMFSourceResolver *iface, IMFByteStream *stream, + const WCHAR *url, DWORD flags, IPropertyStore *props, IUnknown **cancel_cookie, IMFAsyncCallback *callback, + IUnknown *unk_state) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%p, %s, %#x, %p, %p, %p, %p): stub\n", This, stream, debugstr_w(url), flags, props, cancel_cookie, + callback, unk_state); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsourceresolver_EndCreateObjectFromByteStream(IMFSourceResolver *iface, IMFAsyncResult *result, + MF_OBJECT_TYPE *obj_type, IUnknown **object) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%p, %p, %p): stub\n", This, result, obj_type, object); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsourceresolver_CancelObjectCreation(IMFSourceResolver *iface, IUnknown *cancel_cookie) +{ + mfsourceresolver *This = impl_from_IMFSourceResolver(iface); + + FIXME("(%p)->(%p): stub\n", This, cancel_cookie); + + return E_NOTIMPL; +} + +static const IMFSourceResolverVtbl mfsourceresolvervtbl = +{ + mfsourceresolver_QueryInterface, + mfsourceresolver_AddRef, + mfsourceresolver_Release, + mfsourceresolver_CreateObjectFromURL, + mfsourceresolver_CreateObjectFromByteStream, + mfsourceresolver_BeginCreateObjectFromURL, + mfsourceresolver_EndCreateObjectFromURL, + mfsourceresolver_BeginCreateObjectFromByteStream, + mfsourceresolver_EndCreateObjectFromByteStream, + mfsourceresolver_CancelObjectCreation, +}; + +/*********************************************************************** + * MFCreateSourceResolver (mfplat.@) + */ +HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver) +{ + mfsourceresolver *object; + + TRACE("%p\n", resolver); + + if (!resolver) + return E_POINTER; + + object = HeapAlloc( GetProcessHeap(), 0, sizeof(*object) ); + if (!object) + return E_OUTOFMEMORY; + + object->IMFSourceResolver_iface.lpVtbl = &mfsourceresolvervtbl; + object->ref = 1; + + *resolver = &object->IMFSourceResolver_iface; + return S_OK; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index d96eb517c1b..2d737fb545f 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -58,7 +58,7 @@ @ stub MFCreateSample @ stub MFCreateSocket @ stub MFCreateSocketListener -@ stub MFCreateSourceResolver +@ stdcall MFCreateSourceResolver(ptr) @ stub MFCreateStreamDescriptor @ stub MFCreateSystemTimeSource @ stub MFCreateSystemUnderlyingClock diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 4a95137bc48..83e15386867 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -30,10 +30,13 @@ #include "initguid.h" #include "mfapi.h" +#include "mfidl.h" #include "mferror.h" #include "wine/test.h" +static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver); + DEFINE_GUID(MFT_CATEGORY_OTHER, 0x90175d57,0xb7ea,0x4901,0xae,0xb3,0x93,0x3a,0x87,0x47,0x75,0x6f); DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19); @@ -154,12 +157,48 @@ if(0) ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret); } +static void test_source_resolver(void) +{ + IMFSourceResolver *resolver, *resolver2; + HRESULT hr; + + if (!pMFCreateSourceResolver) + { + win_skip("MFCreateSourceResolver() not found\n"); + return; + } + + hr = pMFCreateSourceResolver(NULL); + ok(hr == E_POINTER, "got %#x\n", hr); + + hr = pMFCreateSourceResolver(&resolver); + ok(hr == S_OK, "got %#x\n", hr); + + hr = pMFCreateSourceResolver(&resolver2); + ok(hr == S_OK, "got %#x\n", hr); + ok(resolver != resolver2, "Expected new instance\n"); + + IMFSourceResolver_Release(resolver); + IMFSourceResolver_Release(resolver2); +} + +static void init_functions(void) +{ + HMODULE mod = GetModuleHandleA("mfplat.dll"); + +#define X(f) if (!(p##f = (void*)GetProcAddress(mod, #f))) return; + X(MFCreateSourceResolver); +#undef X +} START_TEST(mfplat) { CoInitialize(NULL); + init_functions(); + test_register(); + test_source_resolver(); CoUninitialize(); } diff --git a/include/mfidl.idl b/include/mfidl.idl index 2002ad35fd1..925fbcc4fab 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -162,3 +162,5 @@ interface IMFSourceResolver : IUnknown [out] MF_OBJECT_TYPE *obj_type, [out] IUnknown **object); [local] HRESULT CanceObjectCreation([in] IUnknown *cancel_cookie); } + +cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);")