From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/dmoguids/dmoguids.c | 1 + include/Makefile.in | 1 + include/dmodshow.idl | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 include/dmodshow.idl
diff --git a/dlls/dmoguids/dmoguids.c b/dlls/dmoguids/dmoguids.c index b764c1f74f0..15a0540170d 100644 --- a/dlls/dmoguids/dmoguids.c +++ b/dlls/dmoguids/dmoguids.c @@ -25,3 +25,4 @@
#include "mediaobj.h" #include "dmoreg.h" +#include "dmodshow.h" diff --git a/include/Makefile.in b/include/Makefile.in index 0e5dd475e04..21b4233ecd9 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -212,6 +212,7 @@ SOURCES = \ dmerror.h \ dmksctrl.h \ dmo.h \ + dmodshow.idl \ dmoreg.h \ dmort.h \ dmplugin.h \ diff --git a/include/dmodshow.idl b/include/dmodshow.idl new file mode 100644 index 00000000000..986b6c1ec33 --- /dev/null +++ b/include/dmodshow.idl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 Zebediah Figura + * + * 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 + */ + +import "unknwn.idl"; +import "objidl.idl"; +import "mediaobj.idl"; + +cpp_quote("DEFINE_GUID(CLSID_DMOWrapperFilter, 0x94297043,0xbd82,0x4dfd,0xb0,0xde,0x81,0x77,0x73,0x9c,0x6d,0x20);") +cpp_quote("DEFINE_GUID(CLSID_DMOFilterCategory,0xbcd5796c,0xbd52,0x4d30,0xab,0x76,0x70,0xf9,0x75,0xb8,0x91,0x99);") + +[ + object, + uuid(52d6f586-9f0f-4824-8fc8-e32ca04930c2), +] +interface IDMOWrapperFilter : IUnknown +{ + HRESULT Init(REFCLSID clsid, REFCLSID category); +}
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/mediaobj.idl | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/include/mediaobj.idl b/include/mediaobj.idl index 77599214852..793e1bcf8e0 100644 --- a/include/mediaobj.idl +++ b/include/mediaobj.idl @@ -21,9 +21,6 @@ import "unknwn.idl"; import "objidl.idl"; import "strmif.idl";
-interface IDMOQualityControl; -interface IDMOVideoOutputOptimizations; - typedef struct _DMOMediaType { GUID majortype; @@ -252,3 +249,38 @@ interface IMediaObjectInPlace : IUnknown { [out] REFERENCE_TIME *pLatencyTime ); } + +enum _DMO_QUALITY_STATUS_FLAGS +{ + DMO_QUALITY_STATUS_ENABLED = 0x00000001, +}; + +[ + object, + uuid(65abea96-cf36-453f-af8a-705e98f16260), + local +] +interface IDMOQualityControl : IUnknown +{ + HRESULT SetNow([in] REFERENCE_TIME now); + HRESULT SetStatus([in] DWORD flags); + HRESULT GetStatus([out] DWORD *flags); +} + +enum _DMO_VIDEO_OUTPUT_STREAM_FLAGS +{ + DMO_VOSF_NEEDS_PREVIOUS_SAMPLE = 0x00000001, +}; + +[ + object, + uuid(be8f4f4e-5b16-4d29-b350-7f6b5d9298ac), + local +] +interface IDMOVideoOutputOptimizations : IUnknown +{ + HRESULT QueryOperationModePreferences(ULONG index, DWORD *flags); + HRESULT SetOperationMode(ULONG index, DWORD flags); + HRESULT GetCurrentOperationMode(ULONG index, DWORD *flags); + HRESULT GetCurrentSampleRequirements(ULONG index, DWORD *flags); +}
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- configure | 3 + configure.ac | 2 + dlls/qasf/Makefile.in | 11 +++ dlls/qasf/dmowrapper.c | 68 +++++++++++++ dlls/qasf/qasf.spec | 4 + dlls/qasf/qasf_classes.idl | 27 ++++++ dlls/qasf/qasf_main.c | 137 ++++++++++++++++++++++++++ dlls/qasf/qasf_private.h | 34 +++++++ dlls/qasf/tests/Makefile.in | 5 + dlls/qasf/tests/dmowrapper.c | 182 +++++++++++++++++++++++++++++++++++ 10 files changed, 473 insertions(+) create mode 100644 dlls/qasf/Makefile.in create mode 100644 dlls/qasf/dmowrapper.c create mode 100644 dlls/qasf/qasf.spec create mode 100644 dlls/qasf/qasf_classes.idl create mode 100644 dlls/qasf/qasf_main.c create mode 100644 dlls/qasf/qasf_private.h create mode 100644 dlls/qasf/tests/Makefile.in create mode 100644 dlls/qasf/tests/dmowrapper.c
diff --git a/configure b/configure index b83487616a7..265681b99b2 100755 --- a/configure +++ b/configure @@ -1521,6 +1521,7 @@ enable_prntvpt enable_propsys enable_psapi enable_pstorec +enable_qasf enable_qcap enable_qedit enable_qmgr @@ -20832,6 +20833,8 @@ wine_fn_config_makefile dlls/psapi enable_psapi wine_fn_config_makefile dlls/psapi/tests enable_tests wine_fn_config_makefile dlls/pstorec enable_pstorec wine_fn_config_makefile dlls/pstorec/tests enable_tests +wine_fn_config_makefile dlls/qasf enable_qasf +wine_fn_config_makefile dlls/qasf/tests enable_tests wine_fn_config_makefile dlls/qcap enable_qcap wine_fn_config_makefile dlls/qcap/tests enable_tests wine_fn_config_makefile dlls/qedit enable_qedit diff --git a/configure.ac b/configure.ac index 3baf7bca3ba..b74d5f07bb8 100644 --- a/configure.ac +++ b/configure.ac @@ -3581,6 +3581,8 @@ WINE_CONFIG_MAKEFILE(dlls/psapi) WINE_CONFIG_MAKEFILE(dlls/psapi/tests) WINE_CONFIG_MAKEFILE(dlls/pstorec) WINE_CONFIG_MAKEFILE(dlls/pstorec/tests) +WINE_CONFIG_MAKEFILE(dlls/qasf) +WINE_CONFIG_MAKEFILE(dlls/qasf/tests) WINE_CONFIG_MAKEFILE(dlls/qcap) WINE_CONFIG_MAKEFILE(dlls/qcap/tests) WINE_CONFIG_MAKEFILE(dlls/qedit) diff --git a/dlls/qasf/Makefile.in b/dlls/qasf/Makefile.in new file mode 100644 index 00000000000..7ca314e20ba --- /dev/null +++ b/dlls/qasf/Makefile.in @@ -0,0 +1,11 @@ +MODULE = qasf.dll +IMPORTS = strmbase dmoguids strmiids uuid + +EXTRADLLFLAGS = -mno-cygwin + +C_SRCS = \ + dmowrapper.c \ + qasf_main.c + +IDL_SRCS = \ + qasf_classes.idl diff --git a/dlls/qasf/dmowrapper.c b/dlls/qasf/dmowrapper.c new file mode 100644 index 00000000000..c7c5d3df9ea --- /dev/null +++ b/dlls/qasf/dmowrapper.c @@ -0,0 +1,68 @@ +/* + * DMO wrapper filter + * + * Copyright (C) 2019 Zebediah Figura + * + * 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 "qasf_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qasf); + +struct dmo_wrapper +{ + struct strmbase_filter filter; +}; + +static inline struct dmo_wrapper *impl_from_strmbase_filter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct dmo_wrapper, filter); +} + +static struct strmbase_pin *dmo_wrapper_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + return NULL; +} + +static void dmo_wrapper_destroy(struct strmbase_filter *iface) +{ + struct dmo_wrapper *filter = impl_from_strmbase_filter(iface); + + strmbase_filter_cleanup(&filter->filter); + free(filter); +} + +static struct strmbase_filter_ops filter_ops = +{ + .filter_get_pin = dmo_wrapper_get_pin, + .filter_destroy = dmo_wrapper_destroy, +}; + +HRESULT dmo_wrapper_create(IUnknown *outer, IUnknown **out) +{ + struct dmo_wrapper *object; + + if (!(object = calloc(sizeof(*object), 1))) + return E_OUTOFMEMORY; + + /* Always pass NULL as the outer object; see test_aggregation(). */ + strmbase_filter_init(&object->filter, NULL, &CLSID_DMOWrapperFilter, &filter_ops); + + TRACE("Created DMO wrapper %p.\n", object); + *out = &object->filter.IUnknown_inner; + + return S_OK; +} diff --git a/dlls/qasf/qasf.spec b/dlls/qasf/qasf.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/dlls/qasf/qasf.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/dlls/qasf/qasf_classes.idl b/dlls/qasf/qasf_classes.idl new file mode 100644 index 00000000000..0acf3806910 --- /dev/null +++ b/dlls/qasf/qasf_classes.idl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 Zebediah Figura + * + * 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 + */ + +#pragma makedep register + +#include "dmodshow.idl" + +[ + threading(both), + uuid(94297043-bd82-4dfd-b0de-8177739c6d20), +] +coclass DMOWrapperFilter {} diff --git a/dlls/qasf/qasf_main.c b/dlls/qasf/qasf_main.c new file mode 100644 index 00000000000..5df23649f0d --- /dev/null +++ b/dlls/qasf/qasf_main.c @@ -0,0 +1,137 @@ +/* + * DirectShow ASF filters + * + * Copyright (C) 2019 Zebediah Figura + * + * 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 "qasf_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qasf); + +static HINSTANCE qasf_instance; + +struct class_factory +{ + IClassFactory IClassFactory_iface; + HRESULT (*create_instance)(IUnknown *outer, IUnknown **out); +}; + +static struct class_factory *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface); +} + +static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *out = iface; + return S_OK; + } + + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI class_factory_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI class_factory_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, + IUnknown *outer, REFIID iid, void **out) +{ + struct class_factory *factory = impl_from_IClassFactory(iface); + IUnknown *unk; + HRESULT hr; + + TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out); + + *out = NULL; + + if (outer && !IsEqualGUID(iid, &IID_IUnknown)) + return E_NOINTERFACE; + + if (SUCCEEDED(hr = factory->create_instance(outer, &unk))) + { + hr = IUnknown_QueryInterface(unk, iid, out); + IUnknown_Release(unk); + } + return hr; +} + +static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock) +{ + FIXME("lock %d, stub!\n", lock); + return S_OK; +} + +static const IClassFactoryVtbl class_factory_vtbl = +{ + class_factory_QueryInterface, + class_factory_AddRef, + class_factory_Release, + class_factory_CreateInstance, + class_factory_LockServer, +}; + +static struct class_factory dmo_wrapper_cf = {{&class_factory_vtbl}, dmo_wrapper_create}; + +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) +{ + if (reason == DLL_PROCESS_ATTACH) + { + DisableThreadLibraryCalls(instance); + qasf_instance = instance; + } + return TRUE; +} + +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) +{ + TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out); + + if (IsEqualGUID(clsid, &CLSID_DMOWrapperFilter)) + return IClassFactory_QueryInterface(&dmo_wrapper_cf.IClassFactory_iface, iid, out); + + FIXME("%s not available, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid)); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} + +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources(qasf_instance); +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources(qasf_instance); +} diff --git a/dlls/qasf/qasf_private.h b/dlls/qasf/qasf_private.h new file mode 100644 index 00000000000..bdb2e433b2f --- /dev/null +++ b/dlls/qasf/qasf_private.h @@ -0,0 +1,34 @@ +/* + * DirectShow ASF filters + * + * Copyright (C) 2019 Zebediah Figura + * + * 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 + */ + +#ifndef QASF_PRIVATE_H +#define QASF_PRIVATE_H + +#define COBJMACROS +#include "dshow.h" +#include "dmo.h" +#include "dmodshow.h" +#include "rpcproxy.h" +#include "wine/debug.h" +#include "wine/strmbase.h" + +HRESULT dmo_wrapper_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; + +#endif /* QASF_PRIVATE_H */ diff --git a/dlls/qasf/tests/Makefile.in b/dlls/qasf/tests/Makefile.in new file mode 100644 index 00000000000..dd04f4b438f --- /dev/null +++ b/dlls/qasf/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = qasf.dll +IMPORTS = dmoguids strmiids uuid ole32 + +C_SRCS = \ + dmowrapper.c diff --git a/dlls/qasf/tests/dmowrapper.c b/dlls/qasf/tests/dmowrapper.c new file mode 100644 index 00000000000..397980b3760 --- /dev/null +++ b/dlls/qasf/tests/dmowrapper.c @@ -0,0 +1,182 @@ +/* + * DMO wrapper filter unit tests + * + * Copyright (C) 2019 Zebediah Figura + * + * 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 + */ + +#define COBJMACROS +#include "dshow.h" +#include "dmo.h" +#include "dmodshow.h" +#include "wine/test.h" + +static const GUID test_iid = {0x33333333}; + +static IBaseFilter *create_dmo_wrapper(void) +{ + IBaseFilter *filter = NULL; + HRESULT hr = CoCreateInstance(&CLSID_DMOWrapperFilter, NULL, + CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + return filter; +} + +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + +static void test_interfaces(void) +{ + IBaseFilter *filter = create_dmo_wrapper(); + + check_interface(filter, &IID_IBaseFilter, TRUE); + todo_wine check_interface(filter, &IID_IDMOWrapperFilter, TRUE); + check_interface(filter, &IID_IMediaFilter, TRUE); + check_interface(filter, &IID_IPersist, TRUE); + todo_wine check_interface(filter, &IID_IPersistStream, TRUE); + check_interface(filter, &IID_IUnknown, TRUE); + + check_interface(filter, &IID_IAMFilterMiscFlags, FALSE); + check_interface(filter, &IID_IBasicAudio, FALSE); + check_interface(filter, &IID_IBasicVideo, FALSE); + check_interface(filter, &IID_IKsPropertySet, FALSE); + check_interface(filter, &IID_IMediaPosition, FALSE); + check_interface(filter, &IID_IMediaSeeking, FALSE); + check_interface(filter, &IID_IPersistPropertyBag, FALSE); + check_interface(filter, &IID_IPin, FALSE); + check_interface(filter, &IID_IQualityControl, FALSE); + check_interface(filter, &IID_IQualProp, FALSE); + check_interface(filter, &IID_IReferenceClock, FALSE); + check_interface(filter, &IID_IVideoWindow, FALSE); + + IBaseFilter_Release(filter); +} + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + ok(0, "Unexpected call.\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + ok(0, "Unexpected call.\n"); + return 2; +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + ok(0, "Unexpected call.\n"); + return 1; +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) +{ + IBaseFilter *filter, *filter2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + /* The DMO wrapper filter pretends to support aggregation, but doesn't + * actually aggregate anything. */ + + filter = (IBaseFilter *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_DMOWrapperFilter, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!filter, "Got interface %p.\n", filter); + + hr = CoCreateInstance(&CLSID_DMOWrapperFilter, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); + ref = get_refcount(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter2 == filter, "Got unexpected IBaseFilter %p.\n", filter2); + IBaseFilter_Release(filter2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + IBaseFilter_Release(filter); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); +} + +START_TEST(dmowrapper) +{ + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + test_interfaces(); + test_aggregation(); + + CoUninitialize(); +}
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=65353
Your paranoid android.
=== debian10 (32 bit report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit French report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit Japanese:Japan report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit WoW report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (64 bit WoW report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
From: Zebediah Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34622 Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/qasf/dmowrapper.c | 56 ++++++++++++++++++++++++++++++++++++ dlls/qasf/tests/dmowrapper.c | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/dlls/qasf/dmowrapper.c b/dlls/qasf/dmowrapper.c index c7c5d3df9ea..d4547d4ba30 100644 --- a/dlls/qasf/dmowrapper.c +++ b/dlls/qasf/dmowrapper.c @@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qasf); struct dmo_wrapper { struct strmbase_filter filter; + IDMOWrapperFilter IDMOWrapperFilter_iface; };
static inline struct dmo_wrapper *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -32,6 +33,44 @@ static inline struct dmo_wrapper *impl_from_strmbase_filter(struct strmbase_filt return CONTAINING_RECORD(iface, struct dmo_wrapper, filter); }
+static inline struct dmo_wrapper *impl_from_IDMOWrapperFilter(IDMOWrapperFilter *iface) +{ + return CONTAINING_RECORD(iface, struct dmo_wrapper, IDMOWrapperFilter_iface); +} + +static HRESULT WINAPI dmo_wrapper_filter_QueryInterface(IDMOWrapperFilter *iface, REFIID iid, void **out) +{ + struct dmo_wrapper *filter = impl_from_IDMOWrapperFilter(iface); + return IUnknown_QueryInterface(filter->filter.outer_unk, iid, out); +} + +static ULONG WINAPI dmo_wrapper_filter_AddRef(IDMOWrapperFilter *iface) +{ + struct dmo_wrapper *filter = impl_from_IDMOWrapperFilter(iface); + return IUnknown_AddRef(filter->filter.outer_unk); +} + +static ULONG WINAPI dmo_wrapper_filter_Release(IDMOWrapperFilter *iface) +{ + struct dmo_wrapper *filter = impl_from_IDMOWrapperFilter(iface); + return IUnknown_Release(filter->filter.outer_unk); +} + +static HRESULT WINAPI dmo_wrapper_filter_Init(IDMOWrapperFilter *iface, REFCLSID clsid, REFCLSID category) +{ + FIXME("iface %p, clsid %s, category %s, stub!\n", + iface, wine_dbgstr_guid(clsid), wine_dbgstr_guid(category)); + return E_NOTIMPL; +} + +static const IDMOWrapperFilterVtbl dmo_wrapper_filter_vtbl = +{ + dmo_wrapper_filter_QueryInterface, + dmo_wrapper_filter_AddRef, + dmo_wrapper_filter_Release, + dmo_wrapper_filter_Init, +}; + static struct strmbase_pin *dmo_wrapper_get_pin(struct strmbase_filter *iface, unsigned int index) { return NULL; @@ -45,10 +84,25 @@ static void dmo_wrapper_destroy(struct strmbase_filter *iface) free(filter); }
+static HRESULT dmo_wrapper_query_interface(struct strmbase_filter *iface, REFIID iid, void **out) +{ + struct dmo_wrapper *filter = impl_from_strmbase_filter(iface); + + if (IsEqualGUID(iid, &IID_IDMOWrapperFilter)) + { + *out = &filter->IDMOWrapperFilter_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + return E_NOINTERFACE; +} + static struct strmbase_filter_ops filter_ops = { .filter_get_pin = dmo_wrapper_get_pin, .filter_destroy = dmo_wrapper_destroy, + .filter_query_interface = dmo_wrapper_query_interface, };
HRESULT dmo_wrapper_create(IUnknown *outer, IUnknown **out) @@ -61,6 +115,8 @@ HRESULT dmo_wrapper_create(IUnknown *outer, IUnknown **out) /* Always pass NULL as the outer object; see test_aggregation(). */ strmbase_filter_init(&object->filter, NULL, &CLSID_DMOWrapperFilter, &filter_ops);
+ object->IDMOWrapperFilter_iface.lpVtbl = &dmo_wrapper_filter_vtbl; + TRACE("Created DMO wrapper %p.\n", object); *out = &object->filter.IUnknown_inner;
diff --git a/dlls/qasf/tests/dmowrapper.c b/dlls/qasf/tests/dmowrapper.c index 397980b3760..e061ca24177 100644 --- a/dlls/qasf/tests/dmowrapper.c +++ b/dlls/qasf/tests/dmowrapper.c @@ -62,7 +62,7 @@ static void test_interfaces(void) IBaseFilter *filter = create_dmo_wrapper();
check_interface(filter, &IID_IBaseFilter, TRUE); - todo_wine check_interface(filter, &IID_IDMOWrapperFilter, TRUE); + check_interface(filter, &IID_IDMOWrapperFilter, TRUE); check_interface(filter, &IID_IMediaFilter, TRUE); check_interface(filter, &IID_IPersist, TRUE); todo_wine check_interface(filter, &IID_IPersistStream, TRUE);
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=65354
Your paranoid android.
=== debian10 (32 bit report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit French report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit Japanese:Japan report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit WoW report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (64 bit WoW report) ===
qasf: dmowrapper.c:34: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0040100e).
Report validation errors: qasf:dmowrapper crashed (c0000005)
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/qasf/Makefile.in | 2 +- dlls/qasf/dmowrapper.c | 26 ++- dlls/qasf/tests/Makefile.in | 2 +- dlls/qasf/tests/dmowrapper.c | 307 +++++++++++++++++++++++++++++++++++ 4 files changed, 332 insertions(+), 5 deletions(-)
diff --git a/dlls/qasf/Makefile.in b/dlls/qasf/Makefile.in index 7ca314e20ba..c1d34a42dab 100644 --- a/dlls/qasf/Makefile.in +++ b/dlls/qasf/Makefile.in @@ -1,5 +1,5 @@ MODULE = qasf.dll -IMPORTS = strmbase dmoguids strmiids uuid +IMPORTS = strmbase dmoguids strmiids uuid ole32
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/qasf/dmowrapper.c b/dlls/qasf/dmowrapper.c index d4547d4ba30..1f11c9ff7ef 100644 --- a/dlls/qasf/dmowrapper.c +++ b/dlls/qasf/dmowrapper.c @@ -26,6 +26,8 @@ struct dmo_wrapper { struct strmbase_filter filter; IDMOWrapperFilter IDMOWrapperFilter_iface; + + IUnknown *dmo; };
static inline struct dmo_wrapper *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -58,9 +60,23 @@ static ULONG WINAPI dmo_wrapper_filter_Release(IDMOWrapperFilter *iface)
static HRESULT WINAPI dmo_wrapper_filter_Init(IDMOWrapperFilter *iface, REFCLSID clsid, REFCLSID category) { - FIXME("iface %p, clsid %s, category %s, stub!\n", - iface, wine_dbgstr_guid(clsid), wine_dbgstr_guid(category)); - return E_NOTIMPL; + struct dmo_wrapper *filter = impl_from_IDMOWrapperFilter(iface); + IUnknown *unk; + HRESULT hr; + + TRACE("filter %p, clsid %s, category %s.\n", filter, debugstr_guid(clsid), debugstr_guid(category)); + + if (FAILED(hr = CoCreateInstance(clsid, &filter->filter.IUnknown_inner, + CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk))) + return hr; + + EnterCriticalSection(&filter->filter.csFilter); + + filter->dmo = unk; + + LeaveCriticalSection(&filter->filter.csFilter); + + return S_OK; }
static const IDMOWrapperFilterVtbl dmo_wrapper_filter_vtbl = @@ -80,6 +96,8 @@ static void dmo_wrapper_destroy(struct strmbase_filter *iface) { struct dmo_wrapper *filter = impl_from_strmbase_filter(iface);
+ if (filter->dmo) + IUnknown_Release(filter->dmo); strmbase_filter_cleanup(&filter->filter); free(filter); } @@ -95,6 +113,8 @@ static HRESULT dmo_wrapper_query_interface(struct strmbase_filter *iface, REFIID return S_OK; }
+ if (filter->dmo && !IsEqualGUID(iid, &IID_IUnknown)) + return IUnknown_QueryInterface(filter->dmo, iid, out); return E_NOINTERFACE; }
diff --git a/dlls/qasf/tests/Makefile.in b/dlls/qasf/tests/Makefile.in index dd04f4b438f..47bb22e78ab 100644 --- a/dlls/qasf/tests/Makefile.in +++ b/dlls/qasf/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = qasf.dll -IMPORTS = dmoguids strmiids uuid ole32 +IMPORTS = dmoguids strmiids uuid msdmo ole32
C_SRCS = \ dmowrapper.c diff --git a/dlls/qasf/tests/dmowrapper.c b/dlls/qasf/tests/dmowrapper.c index e061ca24177..9345b91a178 100644 --- a/dlls/qasf/tests/dmowrapper.c +++ b/dlls/qasf/tests/dmowrapper.c @@ -24,14 +24,286 @@ #include "dmodshow.h" #include "wine/test.h"
+static const GUID testdmo_clsid = {0x1234}; static const GUID test_iid = {0x33333333};
+static const IMediaObjectVtbl dmo_vtbl; + +static IMediaObject testdmo = {&dmo_vtbl}; +static IUnknown *testdmo_outer_unk; +static LONG testdmo_refcount = 1; + +static HRESULT WINAPI dmo_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid)); + + if (IsEqualGUID(iid, &IID_IUnknown)) + *out = iface; + else if (IsEqualGUID(iid, &IID_IMediaObject) || IsEqualGUID(iid, &test_iid)) + *out = &testdmo; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI dmo_inner_AddRef(IUnknown *iface) +{ + return InterlockedIncrement(&testdmo_refcount); +} + +static ULONG WINAPI dmo_inner_Release(IUnknown *iface) +{ + return InterlockedDecrement(&testdmo_refcount); +} + +static const IUnknownVtbl dmo_inner_vtbl = +{ + dmo_inner_QueryInterface, + dmo_inner_AddRef, + dmo_inner_Release, +}; + +static IUnknown testdmo_inner = {&dmo_inner_vtbl}; + +static HRESULT WINAPI dmo_QueryInterface(IMediaObject *iface, REFIID iid, void **out) +{ + return IUnknown_QueryInterface(testdmo_outer_unk, iid, out); +} + +static ULONG WINAPI dmo_AddRef(IMediaObject *iface) +{ + return IUnknown_AddRef(testdmo_outer_unk); +} + +static ULONG WINAPI dmo_Release(IMediaObject *iface) +{ + return IUnknown_Release(testdmo_outer_unk); +} + +static HRESULT WINAPI dmo_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output) +{ + if (winetest_debug > 1) trace("GetStreamCount()\n"); + *input = 1; + *output = 2; + return S_OK; +} + +static HRESULT WINAPI dmo_GetInputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetOutputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{ + if (winetest_debug > 1) trace("GetOutputStreamInfo(%u)\n", index); + *flags = 0; + return S_OK; +} + +static HRESULT WINAPI dmo_GetInputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetOutputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetInputSizeInfo(IMediaObject *iface, DWORD index, + DWORD *size, DWORD *lookahead, DWORD *align) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_SetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME latency) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_Flush(IMediaObject *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_Discontinuity(IMediaObject *iface, DWORD index) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_AllocateStreamingResources(IMediaObject *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_FreeStreamingResources(IMediaObject *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_GetInputStatus(IMediaObject *iface, DWORD index, DWORD *flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_ProcessInput(IMediaObject *iface, DWORD index, + IMediaBuffer *buffer, DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME timelength) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_ProcessOutput(IMediaObject *iface, DWORD flags, + DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI dmo_Lock(IMediaObject *iface, LONG lock) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static const IMediaObjectVtbl dmo_vtbl = +{ + dmo_QueryInterface, + dmo_AddRef, + dmo_Release, + dmo_GetStreamCount, + dmo_GetInputStreamInfo, + dmo_GetOutputStreamInfo, + dmo_GetInputType, + dmo_GetOutputType, + dmo_SetInputType, + dmo_SetOutputType, + dmo_GetInputCurrentType, + dmo_GetOutputCurrentType, + dmo_GetInputSizeInfo, + dmo_GetOutputSizeInfo, + dmo_GetInputMaxLatency, + dmo_SetInputMaxLatency, + dmo_Flush, + dmo_Discontinuity, + dmo_AllocateStreamingResources, + dmo_FreeStreamingResources, + dmo_GetInputStatus, + dmo_ProcessInput, + dmo_ProcessOutput, + dmo_Lock, +}; + +static HRESULT WINAPI dmo_cf_QueryInterface(IClassFactory *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory)) + { + *out = iface; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI dmo_cf_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI dmo_cf_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI dmo_cf_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out) +{ + ok(!!outer, "Expected to be created aggregated.\n"); + ok(IsEqualGUID(iid, &IID_IUnknown), "Got unexpected iid %s.\n", wine_dbgstr_guid(iid)); + + *out = &testdmo_inner; + IUnknown_AddRef(&testdmo_inner); + testdmo_outer_unk = outer; + return S_OK; +} + +static HRESULT WINAPI dmo_cf_LockServer(IClassFactory *iface, BOOL lock) +{ + ok(0, "Unexpected call.\n"); + return S_OK; +} + +static const IClassFactoryVtbl dmo_cf_vtbl = +{ + dmo_cf_QueryInterface, + dmo_cf_AddRef, + dmo_cf_Release, + dmo_cf_CreateInstance, + dmo_cf_LockServer, +}; + +static IClassFactory testdmo_cf = {&dmo_cf_vtbl}; + static IBaseFilter *create_dmo_wrapper(void) { + IDMOWrapperFilter *wrapper; IBaseFilter *filter = NULL; HRESULT hr = CoCreateInstance(&CLSID_DMOWrapperFilter, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&filter); ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_QueryInterface(filter, &IID_IDMOWrapperFilter, (void **)&wrapper); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IDMOWrapperFilter_Init(wrapper, &testdmo_clsid, &DMOCATEGORY_AUDIO_DECODER); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IDMOWrapperFilter_Release(wrapper); + return filter; }
@@ -169,14 +441,49 @@ static void test_aggregation(void) IBaseFilter_Release(filter); ref = IUnknown_Release(unk); ok(!ref, "Got unexpected refcount %d.\n", ref); + + /* Test also aggregation of the inner media object. */ + + filter = create_dmo_wrapper(); + + hr = IBaseFilter_QueryInterface(filter, &IID_IMediaObject, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk == (IUnknown *)&testdmo, "Got unexpected object %p.\n", unk); + IUnknown_Release(unk); + + hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk == (IUnknown *)&testdmo, "Got unexpected object %p.\n", unk); + IUnknown_Release(unk); + + ref = IBaseFilter_Release(filter); + ok(!ref, "Got unexpected refcount %d.\n", ref); }
START_TEST(dmowrapper) { + DWORD cookie; + HRESULT hr; + CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ hr = DMORegister(L"Wine test DMO", &testdmo_clsid, &DMOCATEGORY_AUDIO_DECODER, 0, 0, NULL, 0, NULL); + if (FAILED(hr)) + { + skip("Failed to register DMO, hr %#x.\n", hr); + return; + } + ok(hr == S_OK, "Failed to register class, hr %#x.\n", hr); + + hr = CoRegisterClassObject(&testdmo_clsid, (IUnknown *)&testdmo_cf, + CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie); + ok(hr == S_OK, "Failed to register class, hr %#x.\n", hr); + test_interfaces(); test_aggregation();
+ CoRevokeClassObject(cookie); + DMOUnregister(&testdmo_clsid, &DMOCATEGORY_AUDIO_DECODER); + CoUninitialize(); }
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=65355
Your paranoid android.
=== debian10 (32 bit report) ===
qasf: dmowrapper.c:299: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004018c3).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit French report) ===
qasf: dmowrapper.c:299: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004018c3).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit Japanese:Japan report) ===
qasf: dmowrapper.c:299: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004018c3).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
qasf: dmowrapper.c:299: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004018c3).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (32 bit WoW report) ===
qasf: dmowrapper.c:299: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004018c3).
Report validation errors: qasf:dmowrapper crashed (c0000005)
=== debian10 (64 bit WoW report) ===
qasf: dmowrapper.c:299: Test failed: Got hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004018c3).
Report validation errors: qasf:dmowrapper crashed (c0000005)