[PATCH v3 8/8] quartz/tests: Add some tests for IGraphBuilder::AddSourceFilter().

Zebediah Figura zfigura at codeweavers.com
Tue Aug 6 14:58:37 CDT 2019


From: Zebediah Figura <z.figura12 at gmail.com>

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/quartz/tests/filtergraph.c | 236 ++++++++++++++++++++++++++++----
 1 file changed, 213 insertions(+), 23 deletions(-)

diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index aec93926eba..d7ae766f117 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -46,31 +46,35 @@ static const WCHAR mpegfile[] = {'t','e','s','t','.','m','p','g',0};
 static const WCHAR mp3file[] = {'t','e','s','t','.','m','p','3',0};
 static const WCHAR wavefile[] = {'t','e','s','t','.','w','a','v',0};
 
-static WCHAR *load_resource(const WCHAR *name)
+static WCHAR *create_file(const WCHAR *name, const char *data, DWORD size)
 {
     static WCHAR pathW[MAX_PATH];
     DWORD written;
     HANDLE file;
-    HRSRC res;
-    void *ptr;
 
     GetTempPathW(ARRAY_SIZE(pathW), pathW);
     lstrcatW(pathW, name);
-
     file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
-    ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW),
-        GetLastError());
-
-    res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
-    ok( res != 0, "couldn't find resource\n" );
-    ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
-    WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
-    ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
-    CloseHandle( file );
+    ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %u.\n",
+            wine_dbgstr_w(pathW), GetLastError());
+    WriteFile(file, data, size, &written, NULL);
+    ok(written = size, "Failed to write file data, error %u.\n", GetLastError());
+    CloseHandle(file);
 
     return pathW;
 }
 
+static WCHAR *load_resource(const WCHAR *name)
+{
+    HRSRC res;
+    void *ptr;
+
+    res = FindResourceW(NULL, name, (const WCHAR *)RT_RCDATA);
+    ok(!!res, "Failed to find resource %s, error %u.\n", wine_dbgstr_w(name), GetLastError());
+    ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
+    return create_file(name, ptr, SizeofResource(GetModuleHandleA(NULL), res));
+}
+
 static IFilterGraph2 *create_graph(void)
 {
     IFilterGraph2 *ret;
@@ -1175,6 +1179,9 @@ struct testfilter
     double seek_rate;
 
     IReferenceClock IReferenceClock_iface;
+
+    IFileSourceFilter IFileSourceFilter_iface;
+    WCHAR filename[MAX_PATH];
 };
 
 static inline struct testfilter *impl_from_IEnumPins(IEnumPins *iface)
@@ -1267,30 +1274,31 @@ static HRESULT WINAPI testfilter_QueryInterface(IBaseFilter *iface, REFIID iid,
             || IsEqualGUID(iid, &IID_IBaseFilter))
     {
         *out = &filter->IBaseFilter_iface;
-        IBaseFilter_AddRef(*out);
-        return S_OK;
     }
     else if (IsEqualGUID(iid, &IID_IAMFilterMiscFlags) && filter->IAMFilterMiscFlags_iface.lpVtbl)
     {
         *out = &filter->IAMFilterMiscFlags_iface;
-        IAMFilterMiscFlags_AddRef(*out);
-        return S_OK;
     }
     else if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl)
     {
         *out = &filter->IMediaSeeking_iface;
-        IMediaSeeking_AddRef(*out);
-        return S_OK;
     }
     else if (IsEqualGUID(iid, &IID_IReferenceClock) && filter->IReferenceClock_iface.lpVtbl)
     {
         *out = &filter->IReferenceClock_iface;
-        IMediaSeeking_AddRef(*out);
-        return S_OK;
+    }
+    else if (IsEqualGUID(iid, &IID_IFileSourceFilter) && filter->IFileSourceFilter_iface.lpVtbl)
+    {
+        *out = &filter->IFileSourceFilter_iface;
+    }
+    else
+    {
+        *out = NULL;
+        return E_NOINTERFACE;
     }
 
-    *out = NULL;
-    return E_NOINTERFACE;
+    IUnknown_AddRef((IUnknown *)*out);
+    return S_OK;
 }
 
 static ULONG WINAPI testfilter_AddRef(IBaseFilter *iface)
@@ -1742,6 +1750,56 @@ static const IReferenceClockVtbl testclock_vtbl =
     testclock_Unadvise,
 };
 
+static struct testfilter *impl_from_IFileSourceFilter(IFileSourceFilter *iface)
+{
+    return CONTAINING_RECORD(iface, struct testfilter, IFileSourceFilter_iface);
+}
+
+static HRESULT WINAPI testfilesource_QueryInterface(IFileSourceFilter *iface, REFIID iid, void **out)
+{
+    struct testfilter *filter = impl_from_IFileSourceFilter(iface);
+    return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
+}
+
+static ULONG WINAPI testfilesource_AddRef(IFileSourceFilter *iface)
+{
+    struct testfilter *filter = impl_from_IFileSourceFilter(iface);
+    return InterlockedIncrement(&filter->ref);
+}
+
+static ULONG WINAPI testfilesource_Release(IFileSourceFilter *iface)
+{
+    struct testfilter *filter = impl_from_IFileSourceFilter(iface);
+    return InterlockedDecrement(&filter->ref);
+}
+
+static HRESULT WINAPI testfilesource_Load(IFileSourceFilter *iface,
+        const WCHAR *filename, const AM_MEDIA_TYPE *mt)
+{
+    struct testfilter *filter = impl_from_IFileSourceFilter(iface);
+    if (winetest_debug > 1) trace("%p->Load()\n", iface);
+
+    wcscpy(filter->filename, filename);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilesource_GetCurFile(IFileSourceFilter *iface,
+        WCHAR **filename, AM_MEDIA_TYPE *mt)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static const IFileSourceFilterVtbl testfilesource_vtbl =
+{
+    testfilesource_QueryInterface,
+    testfilesource_AddRef,
+    testfilesource_Release,
+    testfilesource_Load,
+    testfilesource_GetCurFile,
+};
+
 struct testfilter_cf
 {
     IClassFactory IClassFactory_iface;
@@ -3827,6 +3885,137 @@ static void test_default_sync_source(void)
     ok(source.ref == 1, "Got outstanding refcount %d.\n", source.ref);
 }
 
+static void test_add_source_filter(void)
+{
+    static const char bogus_data[20] = {0xde, 0xad, 0xbe, 0xef};
+    static const char midi_data[20] = {'M','T','h','d'};
+    static const WCHAR testW[] = {'t','e','s','t',0};
+
+    IFilterGraph2 *graph = create_graph();
+    IFileSourceFilter *filesource;
+    IBaseFilter *filter, *filter2;
+    FILTER_INFO filter_info;
+    const WCHAR *filename;
+    WCHAR *ret_filename;
+    AM_MEDIA_TYPE mt;
+    CLSID clsid;
+    HRESULT hr;
+    ULONG ref;
+    BOOL ret;
+    HKEY key;
+
+    /* Test a file which should be registered by extension. */
+
+    filename = create_file(mp3file, midi_data, sizeof(midi_data));
+    hr = IFilterGraph2_AddSourceFilter(graph, filename, testW, &filter);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+    hr = IBaseFilter_GetClassID(filter, &clsid);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(IsEqualGUID(&clsid, &CLSID_AsyncReader), "Got filter %s.\n", wine_dbgstr_guid(&clsid));
+    hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(!wcscmp(filter_info.achName, testW), "Got unexpected name %s.\n", wine_dbgstr_w(filter_info.achName));
+    IFilterGraph_Release(filter_info.pGraph);
+
+    hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    hr = IFileSourceFilter_GetCurFile(filesource, &ret_filename, &mt);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(!wcscmp(ret_filename, filename), "Expected filename %s, got %s.\n",
+            wine_dbgstr_w(filename), wine_dbgstr_w(ret_filename));
+    ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream), "Got major type %s.\n", wine_dbgstr_guid(&mt.majortype));
+    ok(IsEqualGUID(&mt.subtype, &MEDIASUBTYPE_MPEG1Audio), "Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype));
+    IFileSourceFilter_Release(filesource);
+
+    hr = IFilterGraph2_AddSourceFilter(graph, filename, testW, &filter2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(filter2 != filter, "Filters shouldn't match.\n");
+    hr = IFilterGraph2_RemoveFilter(graph, filter2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ref = IBaseFilter_Release(filter2);
+    ok(!ref, "Got outstanding refcount %d.\n", ref);
+
+    hr = IFilterGraph2_RemoveFilter(graph, filter);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ref = IBaseFilter_Release(filter);
+    ok(!ref, "Got outstanding refcount %d.\n", ref);
+    ret = DeleteFileW(filename);
+    ok(ret, "Failed to delete %s, error %u.\n", wine_dbgstr_w(filename), GetLastError());
+
+    /* Test a file which should be registered by signature. */
+
+    filename = create_file(avifile, midi_data, sizeof(midi_data));
+    hr = IFilterGraph2_AddSourceFilter(graph, filename, NULL, &filter);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+    hr = IBaseFilter_GetClassID(filter, &clsid);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(IsEqualGUID(&clsid, &CLSID_AsyncReader), "Got filter %s.\n", wine_dbgstr_guid(&clsid));
+    hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    todo_wine ok(!wcscmp(filter_info.achName, filename), "Got unexpected name %s.\n", wine_dbgstr_w(filter_info.achName));
+    IFilterGraph_Release(filter_info.pGraph);
+
+    hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    hr = IFileSourceFilter_GetCurFile(filesource, &ret_filename, &mt);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(!wcscmp(ret_filename, filename), "Expected filename %s, got %s.\n",
+            wine_dbgstr_w(filename), wine_dbgstr_w(ret_filename));
+    ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream), "Got major type %s.\n", wine_dbgstr_guid(&mt.majortype));
+    ok(IsEqualGUID(&mt.subtype, &MEDIATYPE_Midi), "Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype));
+    IFileSourceFilter_Release(filesource);
+
+    hr = IFilterGraph2_RemoveFilter(graph, filter);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ref = IBaseFilter_Release(filter);
+    ok(!ref, "Got outstanding refcount %d.\n", ref);
+    ret = DeleteFileW(filename);
+    ok(ret, "Failed to delete %s, error %u.\n", wine_dbgstr_w(filename), GetLastError());
+
+    if (!RegCreateKeyA(HKEY_CLASSES_ROOT, "Media Type\\{abbccdde-0000-0000-0000-000000000000}"
+            "\\{bccddeef-0000-0000-0000-000000000000}", &key))
+    {
+        static const GUID testfilter_clsid = {0x12345678};
+        struct testpin testfilter_pin;
+        struct testfilter testfilter;
+        struct testfilter_cf cf = {{&testfilter_cf_vtbl}, &testfilter};
+        DWORD cookie;
+
+        testsource_init(&testfilter_pin, NULL, 0);
+        testfilter_init(&testfilter, &testfilter_pin, 1);
+        testfilter.IFileSourceFilter_iface.lpVtbl = &testfilesource_vtbl;
+
+        CoRegisterClassObject(&testfilter_clsid, (IUnknown *)&cf.IClassFactory_iface,
+                CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
+        RegSetValueExA(key, "0", 0, REG_SZ, (const BYTE *)"0,4,,deadbeef", 14);
+        RegSetValueExA(key, "Source Filter", 0, REG_SZ, (const BYTE *)"{12345678-0000-0000-0000-000000000000}", 39);
+
+        filename = create_file(avifile, bogus_data, sizeof(bogus_data));
+        hr = IFilterGraph2_AddSourceFilter(graph, filename, NULL, &filter);
+        ok(hr == S_OK, "Got hr %#x.\n", hr);
+        ok(filter == &testfilter.IBaseFilter_iface, "Got unexpected filter %p.\n", filter);
+
+        hr = IFilterGraph2_RemoveFilter(graph, filter);
+        ok(hr == S_OK, "Got hr %#x.\n", hr);
+        IBaseFilter_Release(filter);
+        ref = IBaseFilter_Release(&testfilter.IBaseFilter_iface);
+        ok(!ref, "Got outstanding refcount %d.\n", ref);
+        ret = DeleteFileW(filename);
+        ok(ret, "Failed to delete %s, error %u.\n", wine_dbgstr_w(filename), GetLastError());
+        RegDeleteKeyA(HKEY_CLASSES_ROOT, "Media Type\\{abbccdde-0000-0000-0000-000000000000}"
+            "\\{bccddeef-0000-0000-0000-000000000000}");
+        RegDeleteKeyA(HKEY_CLASSES_ROOT, "Media Type\\{abbccdde-0000-0000-0000-000000000000}");
+        CoRevokeClassObject(cookie);
+    }
+    else
+        skip("Not enough permission to register media types.\n");
+
+    ref = IFilterGraph2_Release(graph);
+    ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
+
 START_TEST(filtergraph)
 {
     CoInitializeEx(NULL, COINIT_MULTITHREADED);
@@ -3848,6 +4037,7 @@ START_TEST(filtergraph)
     test_ec_complete();
     test_graph_seeking();
     test_default_sync_source();
+    test_add_source_filter();
 
     CoUninitialize();
     test_render_with_multithread();
-- 
2.20.1




More information about the wine-devel mailing list