From 0765edd5f24e8f1af340c538c8a860b5527f3623 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 26 Feb 2019 22:56:28 -0600 Subject: [PATCH] quartz/tests/avisplit: Add some tests for IBaseFilter_EnumPins(). Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/quartz/tests/avisplit.c | 249 ++++++++++++++++++++++++++--------- 1 file changed, 187 insertions(+), 62 deletions(-) diff --git a/dlls/quartz/tests/avisplit.c b/dlls/quartz/tests/avisplit.c index 2ad7e0f36f8..418fcb9fc0c 100644 --- a/dlls/quartz/tests/avisplit.c +++ b/dlls/quartz/tests/avisplit.c @@ -23,6 +23,8 @@ #include "dshow.h" #include "wine/test.h" +static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0}; + static IBaseFilter *create_avi_splitter(void) { IBaseFilter *filter = NULL; @@ -32,6 +34,72 @@ static IBaseFilter *create_avi_splitter(void) return filter; } +static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0}; + +static WCHAR *load_resource(const WCHAR *name) +{ + 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, "Failed to create file %s, error %u.\n", + wine_dbgstr_w(pathW), GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok(!!res, "Failed to load resource, error %u.\n", GetLastError()); + ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource.\n"); + CloseHandle(file); + + return pathW; +} + +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +static IFilterGraph2 *connect_input(IBaseFilter *splitter, const WCHAR *filename) +{ + static const WCHAR outputW[] = {'O','u','t','p','u','t',0}; + IFileSourceFilter *filesource; + IFilterGraph2 *graph; + IBaseFilter *reader; + IPin *source, *sink; + HRESULT hr; + + CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&reader); + IBaseFilter_QueryInterface(reader, &IID_IFileSourceFilter, (void **)&filesource); + IFileSourceFilter_Load(filesource, filename, NULL); + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + IFilterGraph2_AddFilter(graph, reader, NULL); + IFilterGraph2_AddFilter(graph, splitter, NULL); + + IBaseFilter_FindPin(splitter, sink_name, &sink); + IBaseFilter_FindPin(reader, outputW, &source); + + hr = IFilterGraph2_ConnectDirect(graph, source, sink, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IPin_Release(source); + IPin_Release(sink); + IBaseFilter_Release(reader); + IFileSourceFilter_Release(filesource); + return graph; +} + #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) { @@ -72,84 +140,141 @@ static void test_interfaces(void) IBaseFilter_Release(filter); } -static void test_pin(IPin *pin) +static void test_enum_pins(void) { - IMemInputPin *mpin = NULL; - - IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&mpin); - - ok(mpin == NULL, "IMemInputPin found!\n"); - if (mpin) - IMemInputPin_Release(mpin); - /* TODO */ -} - -static void test_basefilter(void) -{ - IEnumPins *pin_enum = NULL; - IBaseFilter *base = create_avi_splitter(); - IPin *pins[2]; - ULONG ref; + const WCHAR *filename = load_resource(avifile); + IBaseFilter *filter = create_avi_splitter(); + IEnumPins *enum1, *enum2; + IFilterGraph2 *graph; + ULONG count, ref; + IPin *pins[3]; HRESULT hr; + BOOL ret; - hr = IBaseFilter_EnumPins(base, NULL); - ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr); + ref = get_refcount(filter); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); - hr= IBaseFilter_EnumPins(base, &pin_enum); - ok(hr == S_OK, "hr = %08x and not S_OK\n", hr); + hr = IBaseFilter_EnumPins(filter, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); - hr = IEnumPins_Next(pin_enum, 1, NULL, NULL); - ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr); + hr = IBaseFilter_EnumPins(filter, &enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(enum1); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); - hr = IEnumPins_Next(pin_enum, 2, pins, NULL); - ok(hr == E_INVALIDARG, "hr = %08x and not E_INVALIDARG\n", hr); + hr = IEnumPins_Next(enum1, 1, NULL, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); - pins[0] = (void *)0xdead; - pins[1] = (void *)0xdeed; + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); +todo_wine + ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(pins[0]); +todo_wine + ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(enum1); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + IPin_Release(pins[0]); + ref = get_refcount(filter); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); - hr = IEnumPins_Next(pin_enum, 2, pins, &ref); - ok(hr == S_FALSE, "hr = %08x instead of S_FALSE\n", hr); - ok(pins[0] != (void *)0xdead && pins[0] != NULL, - "pins[0] = %p\n", pins[0]); - if (pins[0] != (void *)0xdead && pins[0] != NULL) - { - test_pin(pins[0]); - IPin_Release(pins[0]); - } + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); - ok(pins[1] == (void *)0xdeed, "pins[1] = %p\n", pins[1]); + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); - ref = IEnumPins_Release(pin_enum); - ok(ref == 0, "ref is %u and not 0!\n", ref); + hr = IEnumPins_Next(enum1, 1, pins, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 1, "Got count %u.\n", count); + IPin_Release(pins[0]); - IBaseFilter_Release(base); -} + hr = IEnumPins_Next(enum1, 1, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(!count, "Got count %u.\n", count); -static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0}; + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); -static WCHAR *load_resource(const WCHAR *name) -{ - static WCHAR pathW[MAX_PATH]; - DWORD written; - HANDLE file; - HRSRC res; - void *ptr; + hr = IEnumPins_Next(enum1, 2, pins, NULL); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); - GetTempPathW(ARRAY_SIZE(pathW), pathW); - lstrcatW(pathW, name); + hr = IEnumPins_Next(enum1, 2, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(count == 1, "Got count %u.\n", count); + IPin_Release(pins[0]); - 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()); + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); - 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 ); + hr = IEnumPins_Clone(enum1, &enum2); + ok(hr == S_OK, "Got hr %#x.\n", hr); - return pathW; + hr = IEnumPins_Skip(enum1, 2); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 1); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum2, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + IEnumPins_Release(enum2); + + graph = connect_input(filter, filename); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); +todo_wine + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 2, pins, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 2, "Got count %u.\n", count); + IPin_Release(pins[0]); + IPin_Release(pins[1]); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 3, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(count == 2, "Got count %u.\n", count); + IPin_Release(pins[0]); + IPin_Release(pins[1]); + + IEnumPins_Release(enum1); + IFilterGraph2_Release(graph); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ret = DeleteFileW(filename); + ok(ret, "Failed to delete file, error %u.\n", GetLastError()); } static void test_filter_graph(void) @@ -399,7 +524,7 @@ START_TEST(avisplit) CoInitialize(NULL); test_interfaces(); - test_basefilter(); + test_enum_pins(); test_filter_graph(); CoUninitialize();