[QUARTZ_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Fri, 11 Oct 2013 13:13:45 +0000 (13:13 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Fri, 11 Oct 2013 13:13:45 +0000 (13:13 +0000)
* Sync with Wine 1.7.1.
CORE-7469

svn path=/trunk/; revision=60607

rostests/winetests/quartz/CMakeLists.txt
rostests/winetests/quartz/avisplitter.c
rostests/winetests/quartz/dsoundrender.c
rostests/winetests/quartz/fil_data.idl [new file with mode: 0644]
rostests/winetests/quartz/filtergraph.c
rostests/winetests/quartz/filtermapper.c
rostests/winetests/quartz/memallocator.c
rostests/winetests/quartz/misc.c
rostests/winetests/quartz/referenceclock.c
rostests/winetests/quartz/testlist.c
rostests/winetests/quartz/videorenderer.c

index fae39d3..3d517b4 100644 (file)
@@ -1,8 +1,4 @@
 
-add_definitions(
-    -D__ROS_LONG64__
-    -D_DLL -D__USE_CRTIMP)
-
 list(APPEND SOURCE
     avisplitter.c
     dsoundrender.c
@@ -15,7 +11,8 @@ list(APPEND SOURCE
     testlist.c)
 
 add_executable(quartz_winetest ${SOURCE})
-target_link_libraries(quartz_winetest wine uuid)
+target_link_libraries(quartz_winetest uuid)
+add_dependencies(quartz_winetest quartz_idlheader)
 set_module_type(quartz_winetest win32cui)
 add_importlibs(quartz_winetest ole32 oleaut32 advapi32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET quartz_winetest DESTINATION reactos/bin FOR all)
index 33a0d6d..ad01906 100644 (file)
@@ -89,29 +89,23 @@ static void test_query_interface(void)
     ULONG ref;
     IUnknown *iface= NULL;
 
-    hr = IUnknown_QueryInterface(pAviSplitter, &IID_IBaseFilter,
-        (void**)&iface);
-
-    ok(hr == S_OK,
-        "IID_IBaseFilter should exist, got %08x!\n", GetLastError());
-    if (hr == S_OK)
-    {
-        ref = IUnknown_Release(iface);
-        iface = NULL;
-        ok(ref == 1, "Reference is %u, expected 1\n", ref);
-    }
-
-    hr = IUnknown_QueryInterface(pAviSplitter, &IID_IMediaSeeking,
-        (void**)&iface);
-    if (hr == S_OK)
-        ref = IUnknown_Release(iface);
-    iface = NULL;
-    todo_wine ok(hr == E_NOINTERFACE,
-        "Query for IMediaSeeking returned: %08x\n", hr);
-
-/* These interfaces should not be present:
-    IID_IKsPropertySet, IID_IMediaPosition, IID_IQualityControl, IID_IQualProp
-*/
+#define TEST_INTERFACE(riid,expected) do { \
+    hr = IUnknown_QueryInterface(pAviSplitter, &riid, (void**)&iface); \
+    ok( hr == expected, #riid" should %s got %08X\n", expected==S_OK ? "exist" : "not be present", GetLastError() ); \
+    if (hr == S_OK) { \
+        ref = IUnknown_Release(iface); \
+        ok(ref == 1, "Reference is %u, expected 1\n", ref); \
+    } \
+    iface = NULL; \
+    } while(0)
+
+    TEST_INTERFACE(IID_IBaseFilter,S_OK);
+    TEST_INTERFACE(IID_IMediaSeeking,E_NOINTERFACE);
+    TEST_INTERFACE(IID_IKsPropertySet,E_NOINTERFACE);
+    TEST_INTERFACE(IID_IMediaPosition,E_NOINTERFACE);
+    TEST_INTERFACE(IID_IQualityControl,E_NOINTERFACE);
+    TEST_INTERFACE(IID_IQualProp,E_NOINTERFACE);
+#undef TEST_INTERFACE
 }
 
 static void test_pin(IPin *pin)
@@ -179,10 +173,10 @@ static const WCHAR wfile[] = {'t','e','s','t','.','a','v','i',0};
 static const char afile[] = "test.avi";
 
 /* This test doesn't use the quartz filtergraph because it makes it impossible
- * to be certain that a thread is really one owned by the avi splitter
- * A lot of the decoder filters will also have their own thread, and windows'
+ * to be certain that a thread is really one owned by the avi splitter.
+ * A lot of the decoder filters will also have their own thread, and Windows'
  * filtergraph has a separate thread for start/stop/seeking requests.
- * By avoiding the filtergraph altogether and connecting streams directly to
+ * By avoiding the filtergraph altogether and connecting streams directly to
  * the null renderer I am sure that this is not the case here.
  */
 static void test_threads(void)
@@ -206,7 +200,7 @@ static void test_threads(void)
         return;
     }
 
-    /* Before doing anything (number of threads at the start differs per OS) */
+    /* Before doing anything (the thread count at the start differs per OS) */
     baselevel = count_threads();
 
     file = CreateFileW(wfile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
@@ -233,7 +227,7 @@ static void test_threads(void)
     ok(hr == E_NOINTERFACE,
         "Avi splitter returns unexpected error: %08x\n", hr);
     if (pfile)
-        IUnknown_Release(pfile);
+        IFileSourceFilter_Release(pfile);
     pfile = NULL;
 
     hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
@@ -242,7 +236,7 @@ static void test_threads(void)
     if (hr != S_OK)
         goto fail;
 
-    hr = IUnknown_QueryInterface(preader, &IID_IFileSourceFilter,
+    hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter,
         (void**)&pfile);
     ok(hr == S_OK, "Could not get IFileSourceFilter: %08x\n", hr);
     if (hr != S_OK)
@@ -271,7 +265,7 @@ static void test_threads(void)
     if (hr != S_OK)
         goto fail;
 
-    IUnknown_Release(enumpins);
+    IEnumPins_Release(enumpins);
     enumpins = NULL;
 
     hr = IBaseFilter_EnumPins(pavi, &enumpins);
@@ -286,7 +280,7 @@ static void test_threads(void)
 
     curlevel = count_threads();
     ok(curlevel == baselevel,
-        "Amount of threads should be %d not %d\n", baselevel, curlevel);
+        "The thread count should be %d not %d\n", baselevel, curlevel);
 
     hr = IPin_Connect(filepin, avipin, NULL);
     ok(hr == S_OK, "Could not connect: %08x\n", hr);
@@ -296,9 +290,9 @@ static void test_threads(void)
     expected = 1 + baselevel;
     curlevel = count_threads();
     ok(curlevel == expected,
-        "Amount of threads should be %d not %d\n", expected, curlevel);
+        "The thread count should be %d not %d\n", expected, curlevel);
 
-    IUnknown_Release(avipin);
+    IPin_Release(avipin);
     avipin = NULL;
 
     IEnumPins_Reset(enumpins);
@@ -309,7 +303,6 @@ static void test_threads(void)
      */
     while (IEnumPins_Next(enumpins, 1, &avipin, NULL) == S_OK)
     {
-        ok(hr == S_OK, "hr: %08x\n", hr);
         IPin_QueryDirection(avipin, &dir);
         if (dir == PINDIR_OUTPUT)
         {
@@ -341,18 +334,18 @@ static void test_threads(void)
             ++expected;
         }
 
-        IUnknown_Release(avipin);
+        IPin_Release(avipin);
         avipin = NULL;
     }
 
     if (avipin)
-        IUnknown_Release(avipin);
+        IPin_Release(avipin);
     avipin = NULL;
 
     if (hr != S_OK)
         goto fail2;
     /* At this point there is a minimalistic connected avi splitter that can
-     * Be used for all sorts of source filter tests, however that still needs
+     * be used for all sorts of source filter tests. However that still needs
      * to be written at a later time.
      *
      * Interesting tests:
@@ -372,7 +365,7 @@ static void test_threads(void)
 
     curlevel = count_threads();
     ok(curlevel == expected,
-        "Amount of threads should be %d not %d\n", expected, curlevel);
+        "The thread count should be %d not %d\n", expected, curlevel);
 
     IBaseFilter_Pause(pavi);
     IBaseFilter_Pause(preader);
@@ -421,10 +414,10 @@ fail:
     if (hr != S_OK)
         skip("Prerequisites not matched, skipping remainder of test\n");
     if (enumpins)
-        IUnknown_Release(enumpins);
+        IEnumPins_Release(enumpins);
 
     if (avipin)
-        IUnknown_Release(avipin);
+        IPin_Release(avipin);
     if (filepin)
     {
         IPin *to = NULL;
@@ -435,20 +428,20 @@ fail:
             IPin_Disconnect(filepin);
             IPin_Disconnect(to);
         }
-        IUnknown_Release(filepin);
+        IPin_Release(filepin);
     }
 
     if (preader)
-        IUnknown_Release(preader);
+        IBaseFilter_Release(preader);
     if (pavi)
-        IUnknown_Release(pavi);
+        IBaseFilter_Release(pavi);
     if (pfile)
-        IUnknown_Release(pfile);
+        IFileSourceFilter_Release(pfile);
 
     curlevel = count_threads();
     todo_wine
     ok(curlevel == baselevel,
-        "Amount of threads should be %d not %d\n", baselevel, curlevel);
+        "The thread count should be %d not %d\n", baselevel, curlevel);
 }
 
 START_TEST(avisplitter)
index e36b756..336cbfa 100644 (file)
@@ -33,7 +33,7 @@
     ok(ppv != NULL, "Pointer is NULL\n");
 
 #define RELEASE_EXPECT(iface, num) if (iface) { \
-    hr = IUnknown_Release(iface); \
+    hr = IUnknown_Release((IUnknown*)iface); \
     ok(hr == num, "IUnknown_Release should return %d, got %d\n", num, hr); \
 }
 
@@ -148,11 +148,11 @@ static void test_query_interface(void)
         ok(hr == S_OK, "Couldn't load default device: %08x\n", hr);
     }
     RELEASE_EXPECT(ppb, 1);
+    }
     QI_SUCCEED(pDSRender, IID_IMediaPosition, pMediaPosition);
     RELEASE_EXPECT(pMediaPosition, 1);
     QI_SUCCEED(pDSRender, IID_IQualityControl, pQualityControl);
     RELEASE_EXPECT(pQualityControl, 1);
-    }
 }
 
 static void test_pin(IPin *pin)
@@ -221,11 +221,11 @@ static void test_basefilter(void)
 
 START_TEST(dsoundrender)
 {
-if(!winetest_interactive)
-{
-    skip("Skipping dsoundrender test, see ROSTESTS_116\n");
-    return;
-}
+    if (!winetest_interactive)
+    {
+        skip("Skipping dsoundrender test, see ROSTESTS-116\n");
+        return;
+    }
     CoInitialize(NULL);
     if (!create_dsound_renderer())
         return;
diff --git a/rostests/winetests/quartz/fil_data.idl b/rostests/winetests/quartz/fil_data.idl
new file mode 100644 (file)
index 0000000..93cdf1e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Vitaliy Margolen
+ *
+ * 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 "objidl.idl";
+import "strmif.idl";
+import "unknwn.idl";
+
+
+/*****************************************************************************
+ * IAMFilterData interface
+ *
+ * Notes:
+ *     - This interface is deprecated and IFilterMapper2 should be used instead.
+ *     - There is no full replacement for IAMFilterData::ParseFilterData short of manually
+ *       parsing out the REGFILTER2 struct from the binary blob.
+ */
+[
+    object,
+    uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
+    pointer_default(unique)
+]
+interface IAMFilterData : IUnknown
+{
+    typedef [unique] IAMFilterData *LPIAMFILTERDATA;
+
+    HRESULT ParseFilterData(
+        [in] BYTE * rgbFilterData,
+        [in] ULONG cb,
+        [out] BYTE ** prgbRegFilter2);
+
+    HRESULT CreateFilterData(
+        [in] REGFILTER2 * prf2,
+        [out] BYTE ** prgbFilterData,
+        [out] ULONG * pcb);
+}
index 8e3948d..50ab5cf 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include <assert.h>
-
 #define COBJMACROS
+#define CONST_VTABLE
 
 #include "wine/test.h"
 #include "dshow.h"
 #include "control.h"
 
-#define FILE_LEN 9
-static const char avifileA[FILE_LEN] = "test.avi";
-static const char mpegfileA[FILE_LEN] = "test.mpg";
+typedef struct TestFilterImpl
+{
+    IBaseFilter IBaseFilter_iface;
 
-IGraphBuilder* pgraph;
+    LONG refCount;
+    CRITICAL_SECTION csFilter;
+    FILTER_STATE state;
+    FILTER_INFO filterInfo;
+    CLSID clsid;
+    IPin **ppPins;
+    UINT nPins;
+} TestFilterImpl;
+
+static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0};
+static const WCHAR mpegfile[] = {'t','e','s','t','.','m','p','g',0};
+
+static IGraphBuilder *pgraph;
 
 static int createfiltergraph(void)
 {
@@ -39,17 +50,6 @@ static int createfiltergraph(void)
         &CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (LPVOID*)&pgraph);
 }
 
-static void renderfile(const char * fileA)
-{
-    HRESULT hr;
-    WCHAR fileW[FILE_LEN];
-
-    MultiByteToWideChar(CP_ACP, 0, fileA, -1, fileW, FILE_LEN);
-
-    hr = IGraphBuilder_RenderFile(pgraph, fileW, NULL);
-    ok(hr==S_OK, "RenderFile returned: %x\n", hr);
-}
-
 static void rungraph(void)
 {
     HRESULT hr;
@@ -141,17 +141,19 @@ static void releasefiltergraph(void)
     ok(hr==0, "Releasing filtergraph returned: %x\n", hr);
 }
 
-static void test_render_run(const char * fileA)
+static void test_render_run(const WCHAR *file)
 {
     HANDLE h;
+    HRESULT hr;
 
     if (!createfiltergraph())
         return;
 
-    h = CreateFileA(fileA, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+    h = CreateFileW(file, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
     if (h != INVALID_HANDLE_VALUE) {
         CloseHandle(h);
-        renderfile(fileA);
+        hr = IGraphBuilder_RenderFile(pgraph, file, NULL);
+        ok(hr==S_OK, "RenderFile returned: %x\n", hr);
         rungraph();
     }
 
@@ -234,7 +236,7 @@ static void test_graph_builder_addfilter(void)
 
     hr = IGraphBuilder_AddFilter(pgraph, pF, NULL);
     ok(hr == S_OK, "IGraphBuilder_AddFilter returned: %x\n", hr);
-    IMediaFilter_Release(pF);
+    IBaseFilter_Release(pF);
 }
 
 static void test_mediacontrol(void)
@@ -245,26 +247,26 @@ static void test_mediacontrol(void)
     IMediaFilter *filter = NULL;
     IMediaControl *control = NULL;
 
-    IFilterGraph2_SetDefaultSyncSource(pgraph);
-    hr = IFilterGraph2_QueryInterface(pgraph, &IID_IMediaSeeking, (void**) &seeking);
+    IGraphBuilder_SetDefaultSyncSource(pgraph);
+    hr = IGraphBuilder_QueryInterface(pgraph, &IID_IMediaSeeking, (void**) &seeking);
     ok(hr == S_OK, "QueryInterface IMediaControl failed: %08x\n", hr);
     if (FAILED(hr))
         return;
 
-    hr = IFilterGraph2_QueryInterface(pgraph, &IID_IMediaFilter, (void**) &filter);
+    hr = IGraphBuilder_QueryInterface(pgraph, &IID_IMediaFilter, (void**) &filter);
     ok(hr == S_OK, "QueryInterface IMediaFilter failed: %08x\n", hr);
     if (FAILED(hr))
     {
-        IUnknown_Release(seeking);
+        IMediaSeeking_Release(seeking);
         return;
     }
 
-    hr = IFilterGraph2_QueryInterface(pgraph, &IID_IMediaControl, (void**) &control);
+    hr = IGraphBuilder_QueryInterface(pgraph, &IID_IMediaControl, (void**) &control);
     ok(hr == S_OK, "QueryInterface IMediaControl failed: %08x\n", hr);
     if (FAILED(hr))
     {
-        IUnknown_Release(seeking);
-        IUnknown_Release(filter);
+        IMediaSeeking_Release(seeking);
+        IMediaFilter_Release(filter);
         return;
     }
 
@@ -286,9 +288,9 @@ static void test_mediacontrol(void)
     hr = IMediaControl_GetState(control, 1000, NULL);
     ok(hr == E_POINTER, "GetState expected %08x, got %08x\n", E_POINTER, hr);
 
-    IUnknown_Release(control);
-    IUnknown_Release(seeking);
-    IUnknown_Release(filter);
+    IMediaControl_Release(control);
+    IMediaSeeking_Release(seeking);
+    IMediaFilter_Release(filter);
     releasefiltergraph();
 }
 
@@ -364,7 +366,7 @@ static void DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
 
 typedef struct IEnumMediaTypesImpl
 {
-    const IEnumMediaTypesVtbl * lpVtbl;
+    IEnumMediaTypes IEnumMediaTypes_iface;
     LONG refCount;
     AM_MEDIA_TYPE *pMediaTypes;
     ULONG cMediaTypes;
@@ -373,6 +375,11 @@ typedef struct IEnumMediaTypesImpl
 
 static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
 
+static inline IEnumMediaTypesImpl *impl_from_IEnumMediaTypes(IEnumMediaTypes *iface)
+{
+    return CONTAINING_RECORD(iface, IEnumMediaTypesImpl, IEnumMediaTypes_iface);
+}
+
 static HRESULT IEnumMediaTypesImpl_Construct(const AM_MEDIA_TYPE * pMediaTypes, ULONG cMediaTypes, IEnumMediaTypes ** ppEnum)
 {
     ULONG i;
@@ -383,7 +390,7 @@ static HRESULT IEnumMediaTypesImpl_Construct(const AM_MEDIA_TYPE * pMediaTypes,
         *ppEnum = NULL;
         return E_OUTOFMEMORY;
     }
-    pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl;
+    pEnumMediaTypes->IEnumMediaTypes_iface.lpVtbl = &IEnumMediaTypesImpl_Vtbl;
     pEnumMediaTypes->refCount = 1;
     pEnumMediaTypes->uIndex = 0;
     pEnumMediaTypes->cMediaTypes = cMediaTypes;
@@ -396,7 +403,7 @@ static HRESULT IEnumMediaTypesImpl_Construct(const AM_MEDIA_TYPE * pMediaTypes,
            CoTaskMemFree(pEnumMediaTypes->pMediaTypes);
            return E_OUTOFMEMORY;
         }
-    *ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl);
+    *ppEnum = &pEnumMediaTypes->IEnumMediaTypes_iface;
     return S_OK;
 }
 
@@ -420,7 +427,7 @@ static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface
 
 static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
 {
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface);
     ULONG refCount = InterlockedIncrement(&This->refCount);
 
     return refCount;
@@ -428,7 +435,7 @@ static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
 
 static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
 {
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface);
     ULONG refCount = InterlockedDecrement(&This->refCount);
 
     if (!refCount)
@@ -445,7 +452,7 @@ static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
 static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched)
 {
     ULONG cFetched;
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface);
 
     cFetched = min(This->cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex;
 
@@ -474,7 +481,7 @@ static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cM
 
 static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes)
 {
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface);
 
     if (This->uIndex + cMediaTypes < This->cMediaTypes)
     {
@@ -486,7 +493,7 @@ static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cM
 
 static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
 {
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface);
 
     This->uIndex = 0;
     return S_OK;
@@ -495,7 +502,7 @@ static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
 static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum)
 {
     HRESULT hr;
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface);
 
     hr = IEnumMediaTypesImpl_Construct(This->pMediaTypes, This->cMediaTypes, ppEnum);
     if (FAILED(hr))
@@ -526,15 +533,20 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
 
 typedef struct ITestPinImpl
 {
-       const struct IPinVtbl * lpVtbl;
-       LONG refCount;
-       LPCRITICAL_SECTION pCritSec;
-       PIN_INFO pinInfo;
-       IPin * pConnectedTo;
-       AM_MEDIA_TYPE mtCurrent;
-       LPVOID pUserData;
+    IPin IPin_iface;
+    LONG refCount;
+    LPCRITICAL_SECTION pCritSec;
+    PIN_INFO pinInfo;
+    IPin * pConnectedTo;
+    AM_MEDIA_TYPE mtCurrent;
+    LPVOID pUserData;
 } ITestPinImpl;
 
+static inline ITestPinImpl *impl_from_IPin(IPin *iface)
+{
+    return CONTAINING_RECORD(iface, ITestPinImpl, IPin_iface);
+}
+
 static HRESULT WINAPI  TestFilter_Pin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
 {
     *ppv = NULL;
@@ -555,20 +567,19 @@ static HRESULT WINAPI  TestFilter_Pin_QueryInterface(IPin * iface, REFIID riid,
 
 static ULONG WINAPI TestFilter_Pin_AddRef(IPin * iface)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
     ULONG refCount = InterlockedIncrement(&This->refCount);
     return refCount;
 }
 
 static ULONG WINAPI TestFilter_Pin_Release(IPin * iface)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
     ULONG refCount = InterlockedDecrement(&This->refCount);
 
     if (!refCount)
     {
         FreeMediaType(&This->mtCurrent);
-        This->lpVtbl = NULL;
         CoTaskMemFree(This);
         return 0;
     }
@@ -583,7 +594,7 @@ static HRESULT WINAPI TestFilter_InputPin_Connect(IPin * iface, IPin * pConnecto
 
 static HRESULT WINAPI TestFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
     PIN_DIRECTION pindirReceive;
     HRESULT hr = S_OK;
 
@@ -621,7 +632,7 @@ static HRESULT WINAPI TestFilter_InputPin_ReceiveConnection(IPin * iface, IPin *
 static HRESULT WINAPI TestFilter_Pin_Disconnect(IPin * iface)
 {
     HRESULT hr;
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     EnterCriticalSection(This->pCritSec);
     {
@@ -642,7 +653,7 @@ static HRESULT WINAPI TestFilter_Pin_Disconnect(IPin * iface)
 static HRESULT WINAPI TestFilter_Pin_ConnectedTo(IPin * iface, IPin ** ppPin)
 {
     HRESULT hr;
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     EnterCriticalSection(This->pCritSec);
     {
@@ -666,7 +677,7 @@ static HRESULT WINAPI TestFilter_Pin_ConnectedTo(IPin * iface, IPin ** ppPin)
 static HRESULT WINAPI TestFilter_Pin_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt)
 {
     HRESULT hr;
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     EnterCriticalSection(This->pCritSec);
     {
@@ -688,7 +699,7 @@ static HRESULT WINAPI TestFilter_Pin_ConnectionMediaType(IPin * iface, AM_MEDIA_
 
 static HRESULT WINAPI TestFilter_Pin_QueryPinInfo(IPin * iface, PIN_INFO * pInfo)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     Copy_PinInfo(pInfo, &This->pinInfo);
     IBaseFilter_AddRef(pInfo->pFilter);
@@ -698,7 +709,7 @@ static HRESULT WINAPI TestFilter_Pin_QueryPinInfo(IPin * iface, PIN_INFO * pInfo
 
 static HRESULT WINAPI TestFilter_Pin_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     *pPinDir = This->pinInfo.dir;
 
@@ -712,7 +723,7 @@ static HRESULT WINAPI TestFilter_Pin_QueryId(IPin * iface, LPWSTR * Id)
 
 static HRESULT WINAPI TestFilter_Pin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     if (IsEqualIID(&pmt->majortype, &This->mtCurrent.majortype) && (IsEqualIID(&pmt->subtype, &This->mtCurrent.subtype) ||
                                                                     IsEqualIID(&GUID_NULL, &This->mtCurrent.subtype)))
@@ -723,7 +734,7 @@ static HRESULT WINAPI TestFilter_Pin_QueryAccept(IPin * iface, const AM_MEDIA_TY
 
 static HRESULT WINAPI TestFilter_Pin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
 
     return IEnumMediaTypesImpl_Construct(&This->mtCurrent, 1, ppEnum);
 }
@@ -781,15 +792,15 @@ static HRESULT WINAPI TestFilter_OutputPin_ReceiveConnection(IPin * iface, IPin
 }
 
 /* Private helper function */
-static HRESULT TestFilter_OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+static HRESULT TestFilter_OutputPin_ConnectSpecific(ITestPinImpl * This, IPin * pReceivePin,
+        const AM_MEDIA_TYPE * pmt)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
     HRESULT hr;
 
     This->pConnectedTo = pReceivePin;
     IPin_AddRef(pReceivePin);
 
-    hr = IPin_ReceiveConnection(pReceivePin, iface, pmt);
+    hr = IPin_ReceiveConnection(pReceivePin, &This->IPin_iface, pmt);
 
     if (FAILED(hr))
     {
@@ -802,7 +813,7 @@ static HRESULT TestFilter_OutputPin_ConnectSpecific(IPin * iface, IPin * pReceiv
 
 static HRESULT WINAPI TestFilter_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
 {
-    ITestPinImpl *This = (ITestPinImpl *)iface;
+    ITestPinImpl *This = impl_from_IPin(iface);
     HRESULT hr;
 
     EnterCriticalSection(This->pCritSec);
@@ -810,11 +821,11 @@ static HRESULT WINAPI TestFilter_OutputPin_Connect(IPin * iface, IPin * pReceive
         /* if we have been a specific type to connect with, then we can either connect
          * with that or fail. We cannot choose different AM_MEDIA_TYPE */
         if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL))
-            hr = TestFilter_OutputPin_ConnectSpecific(iface, pReceivePin, pmt);
+            hr = TestFilter_OutputPin_ConnectSpecific(This, pReceivePin, pmt);
         else
         {
             if (( !pmt || CompareMediaTypes(pmt, &This->mtCurrent, TRUE) ) &&
-                (TestFilter_OutputPin_ConnectSpecific(iface, pReceivePin, &This->mtCurrent) == S_OK))
+                (TestFilter_OutputPin_ConnectSpecific(This, pReceivePin, &This->mtCurrent) == S_OK))
                         hr = S_OK;
             else hr = VFW_E_NO_ACCEPTABLE_TYPES;
         } /* if negotiate media type */
@@ -864,29 +875,34 @@ static HRESULT TestFilter_Pin_Construct(const IPinVtbl *Pin_Vtbl, const PIN_INFO
     Copy_PinInfo(&pPinImpl->pinInfo, pPinInfo);
     pPinImpl->mtCurrent = *pinmt;
 
-    pPinImpl->lpVtbl = Pin_Vtbl;
+    pPinImpl->IPin_iface.lpVtbl = Pin_Vtbl;
 
-    *ppPin = (IPin *)pPinImpl;
+    *ppPin = &pPinImpl->IPin_iface;
     return S_OK;
 }
 
 /* IEnumPins implementation */
 
-typedef HRESULT (* FNOBTAINPIN)(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick);
+typedef HRESULT (* FNOBTAINPIN)(TestFilterImpl *tf, ULONG pos, IPin **pin, DWORD *lastsynctick);
 
 typedef struct IEnumPinsImpl
 {
-    const IEnumPinsVtbl * lpVtbl;
+    IEnumPins IEnumPins_iface;
     LONG refCount;
     ULONG uIndex;
-    IBaseFilter *base;
+    TestFilterImpl *base;
     FNOBTAINPIN receive_pin;
     DWORD synctime;
 } IEnumPinsImpl;
 
 static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl;
 
-static HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base)
+static inline IEnumPinsImpl *impl_from_IEnumPins(IEnumPins *iface)
+{
+    return CONTAINING_RECORD(iface, IEnumPinsImpl, IEnumPins_iface);
+}
+
+static HRESULT createenumpins(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, TestFilterImpl *base)
 {
     IEnumPinsImpl * pEnumPins;
 
@@ -899,13 +915,13 @@ static HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_
         *ppEnum = NULL;
         return E_OUTOFMEMORY;
     }
-    pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl;
+    pEnumPins->IEnumPins_iface.lpVtbl = &IEnumPinsImpl_Vtbl;
     pEnumPins->refCount = 1;
     pEnumPins->uIndex = 0;
     pEnumPins->receive_pin = receive_pin;
     pEnumPins->base = base;
-    IBaseFilter_AddRef(base);
-    *ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl);
+    IBaseFilter_AddRef(&base->IBaseFilter_iface);
+    *ppEnum = &pEnumPins->IEnumPins_iface;
 
     receive_pin(base, ~0, NULL, &pEnumPins->synctime);
 
@@ -932,7 +948,7 @@ static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID rii
 
 static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface)
 {
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    IEnumPinsImpl *This = impl_from_IEnumPins(iface);
     ULONG refCount = InterlockedIncrement(&This->refCount);
 
     return refCount;
@@ -940,12 +956,12 @@ static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface)
 
 static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface)
 {
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    IEnumPinsImpl *This = impl_from_IEnumPins(iface);
     ULONG refCount = InterlockedDecrement(&This->refCount);
 
     if (!refCount)
     {
-        IBaseFilter_Release(This->base);
+        IBaseFilter_Release(&This->base->IBaseFilter_iface);
         CoTaskMemFree(This);
         return 0;
     }
@@ -955,7 +971,7 @@ static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface)
 
 static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** ppPins, ULONG * pcFetched)
 {
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    IEnumPinsImpl *This = impl_from_IEnumPins(iface);
     DWORD synctime = This->synctime;
     HRESULT hr = S_OK;
     ULONG i = 0;
@@ -994,7 +1010,7 @@ static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin **
 
 static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins)
 {
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    IEnumPinsImpl *This = impl_from_IEnumPins(iface);
     DWORD synctime = This->synctime;
     HRESULT hr;
     IPin *pin = NULL;
@@ -1014,7 +1030,7 @@ static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins)
 
 static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface)
 {
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    IEnumPinsImpl *This = impl_from_IEnumPins(iface);
 
     This->receive_pin(This->base, ~0, NULL, &This->synctime);
 
@@ -1025,9 +1041,9 @@ static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface)
 static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins * iface, IEnumPins ** ppEnum)
 {
     HRESULT hr;
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    IEnumPinsImpl *This = impl_from_IEnumPins(iface);
 
-    hr = IEnumPinsImpl_Construct(ppEnum, This->receive_pin, This->base);
+    hr = createenumpins(ppEnum, This->receive_pin, This->base);
     if (FAILED(hr))
         return hr;
     return IEnumPins_Skip(*ppEnum, This->uIndex);
@@ -1053,22 +1069,15 @@ PIN_DIRECTION pinDir;
 const GUID *mediasubtype;
 } TestFilterPinData;
 
-typedef struct TestFilterImpl
-{
-    const IBaseFilterVtbl * lpVtbl;
-
-    LONG refCount;
-    CRITICAL_SECTION csFilter;
-    FILTER_STATE state;
-    FILTER_INFO filterInfo;
-    CLSID clsid;
-    IPin ** ppPins;
-    UINT nPins;
-} TestFilterImpl;
-
 static const IBaseFilterVtbl TestFilter_Vtbl;
 
-static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *pinData, LPVOID * ppv)
+static inline TestFilterImpl *impl_from_IBaseFilter(IBaseFilter *iface)
+{
+    return CONTAINING_RECORD(iface, TestFilterImpl, IBaseFilter_iface);
+}
+
+static HRESULT createtestfilter(const CLSID* pClsid, const TestFilterPinData *pinData,
+        TestFilterImpl **tf)
 {
     static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
     static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0};
@@ -1082,9 +1091,10 @@ static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *p
     if (!pTestFilter) return E_OUTOFMEMORY;
 
     pTestFilter->clsid = *pClsid;
-    pTestFilter->lpVtbl = &TestFilter_Vtbl;
+    pTestFilter->IBaseFilter_iface.lpVtbl = &TestFilter_Vtbl;
     pTestFilter->refCount = 1;
     InitializeCriticalSection(&pTestFilter->csFilter);
+    pTestFilter->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TestFilterImpl.csFilter");
     pTestFilter->state = State_Stopped;
 
     ZeroMemory(&pTestFilter->filterInfo, sizeof(FILTER_INFO));
@@ -1108,7 +1118,7 @@ static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *p
         mt.subtype = *pinData[i].mediasubtype;
 
         pinInfo.dir = pinData[i].pinDir;
-        pinInfo.pFilter = (IBaseFilter *)pTestFilter;
+        pinInfo.pFilter = &pTestFilter->IBaseFilter_iface;
         if (pinInfo.dir == PINDIR_INPUT)
         {
             lstrcpynW(pinInfo.achName, wcsInputPinName, sizeof(pinInfo.achName) / sizeof(pinInfo.achName[0]));
@@ -1126,7 +1136,7 @@ static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *p
     }
 
     pTestFilter->nPins = nPins;
-    *ppv = pTestFilter;
+    *tf = pTestFilter;
     return S_OK;
 
     error:
@@ -1139,6 +1149,7 @@ static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *p
         }
     }
     CoTaskMemFree(pTestFilter->ppPins);
+    pTestFilter->csFilter.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&pTestFilter->csFilter);
     CoTaskMemFree(pTestFilter);
 
@@ -1147,7 +1158,7 @@ static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *p
 
 static HRESULT WINAPI TestFilter_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
 
     *ppv = NULL;
 
@@ -1171,7 +1182,7 @@ static HRESULT WINAPI TestFilter_QueryInterface(IBaseFilter * iface, REFIID riid
 
 static ULONG WINAPI TestFilter_AddRef(IBaseFilter * iface)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
     ULONG refCount = InterlockedIncrement(&This->refCount);
 
     return refCount;
@@ -1179,7 +1190,7 @@ static ULONG WINAPI TestFilter_AddRef(IBaseFilter * iface)
 
 static ULONG WINAPI TestFilter_Release(IBaseFilter * iface)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
     ULONG refCount = InterlockedDecrement(&This->refCount);
 
     if (!refCount)
@@ -1201,8 +1212,8 @@ static ULONG WINAPI TestFilter_Release(IBaseFilter * iface)
         }
 
         CoTaskMemFree(This->ppPins);
-        This->lpVtbl = NULL;
 
+        This->csFilter.DebugInfo->Spare[0] = 0;
         DeleteCriticalSection(&This->csFilter);
 
         CoTaskMemFree(This);
@@ -1216,7 +1227,7 @@ static ULONG WINAPI TestFilter_Release(IBaseFilter * iface)
 
 static HRESULT WINAPI TestFilter_GetClassID(IBaseFilter * iface, CLSID * pClsid)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
 
     *pClsid = This->clsid;
 
@@ -1242,7 +1253,7 @@ static HRESULT WINAPI TestFilter_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
 
 static HRESULT WINAPI TestFilter_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
 
     EnterCriticalSection(&This->csFilter);
     {
@@ -1265,24 +1276,24 @@ static HRESULT WINAPI TestFilter_GetSyncSource(IBaseFilter * iface, IReferenceCl
 
 /** IBaseFilter implementation **/
 
-static HRESULT TestFilter_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
+static HRESULT getpin_callback(TestFilterImpl *tf, ULONG pos, IPin **pin, DWORD *lastsynctick)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
-
     /* Our pins are static, not changing so setting static tick count is ok */
     *lastsynctick = 0;
 
-    if (pos >= This->nPins)
+    if (pos >= tf->nPins)
         return S_FALSE;
 
-    *pin = This->ppPins[pos];
+    *pin = tf->ppPins[pos];
     IPin_AddRef(*pin);
     return S_OK;
 }
 
 static HRESULT WINAPI TestFilter_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
 {
-    return IEnumPinsImpl_Construct(ppEnum, TestFilter_GetPin, iface);
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
+
+    return createenumpins(ppEnum, getpin_callback, This);
 }
 
 static HRESULT WINAPI TestFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
@@ -1292,7 +1303,7 @@ static HRESULT WINAPI TestFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin *
 
 static HRESULT WINAPI TestFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
 {
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
 
     lstrcpyW(pInfo->achName, This->filterInfo.achName);
     pInfo->pGraph = This->filterInfo.pGraph;
@@ -1306,7 +1317,7 @@ static HRESULT WINAPI TestFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INF
 static HRESULT WINAPI TestFilter_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
 {
     HRESULT hr = S_OK;
-    TestFilterImpl *This = (TestFilterImpl *)iface;
+    TestFilterImpl *This = impl_from_IBaseFilter(iface);
 
     EnterCriticalSection(&This->csFilter);
     {
@@ -1349,11 +1360,16 @@ static const IBaseFilterVtbl TestFilter_Vtbl =
 
 typedef struct TestClassFactoryImpl
 {
-    IClassFactoryVtbl *lpVtbl;
+    IClassFactory IClassFactory_iface;
     const TestFilterPinData *filterPinData;
     const CLSID *clsid;
 } TestClassFactoryImpl;
 
+static inline TestClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+{
+    return CONTAINING_RECORD(iface, TestClassFactoryImpl, IClassFactory_iface);
+}
+
 static HRESULT WINAPI Test_IClassFactory_QueryInterface(
     LPCLASSFACTORY iface,
     REFIID riid,
@@ -1389,18 +1405,18 @@ static HRESULT WINAPI Test_IClassFactory_CreateInstance(
     REFIID riid,
     LPVOID *ppvObj)
 {
-    TestClassFactoryImpl *This = (TestClassFactoryImpl *)iface;
+    TestClassFactoryImpl *This = impl_from_IClassFactory(iface);
     HRESULT hr;
-    IUnknown *punk = NULL;
+    TestFilterImpl *testfilter;
 
     *ppvObj = NULL;
 
     if (pUnkOuter) return CLASS_E_NOAGGREGATION;
 
-    hr = TestFilter_Create(This->clsid, This->filterPinData, (LPVOID *) &punk);
+    hr = createtestfilter(This->clsid, This->filterPinData, &testfilter);
     if (SUCCEEDED(hr)) {
-        hr = IUnknown_QueryInterface(punk, riid, ppvObj);
-        IUnknown_Release(punk);
+        hr = IBaseFilter_QueryInterface(&testfilter->IBaseFilter_iface, riid, ppvObj);
+        IBaseFilter_Release(&testfilter->IBaseFilter_iface);
     }
     return hr;
 }
@@ -1464,8 +1480,8 @@ static void test_render_filter_priority(void)
     HRESULT hr;
     IFilterGraph2* pgraph2 = NULL;
     IFilterMapper2 *pMapper2 = NULL;
-    IBaseFilter* ptestfilter = NULL;
-    IBaseFilter* ptestfilter2 = NULL;
+    TestFilterImpl *ptestfilter = NULL;
+    TestFilterImpl *ptestfilter2 = NULL;
     static const CLSID CLSID_TestFilter2 = {
         0x37a4edb0,
         0x4d13,
@@ -1517,9 +1533,18 @@ static void test_render_filter_priority(void)
             { PINDIR_INPUT,  &mediasubtype2 },
             { 0, 0 }
         };
-    TestClassFactoryImpl Filter1ClassFactory = { &TestClassFactory_Vtbl, PinData2, &CLSID_TestFilter2 };
-    TestClassFactoryImpl Filter2ClassFactory = { &TestClassFactory_Vtbl, PinData4, &CLSID_TestFilter3 };
-    TestClassFactoryImpl Filter3ClassFactory = { &TestClassFactory_Vtbl, PinData5, &CLSID_TestFilter4 };
+    TestClassFactoryImpl Filter1ClassFactory = {
+            { &TestClassFactory_Vtbl },
+            PinData2, &CLSID_TestFilter2
+        };
+    TestClassFactoryImpl Filter2ClassFactory = {
+            { &TestClassFactory_Vtbl },
+            PinData4, &CLSID_TestFilter3
+        };
+    TestClassFactoryImpl Filter3ClassFactory = {
+            { &TestClassFactory_Vtbl },
+            PinData5, &CLSID_TestFilter4
+        };
     char ConnectedFilterName1[MAX_FILTER_NAME];
     char ConnectedFilterName2[MAX_FILTER_NAME];
     REGFILTER2 rgf2;
@@ -1541,40 +1566,40 @@ static void test_render_filter_priority(void)
     ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
     if (!pgraph2) return;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData1, (LPVOID)&ptestfilter);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter, wszFilterInstanceName1);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = TestFilter_Create(&GUID_NULL, PinData2, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName2);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData3, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData3, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName3);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = IFilterGraph2_Render(pgraph2, ((TestFilterImpl*)ptestfilter)->ppPins[0]);
+    hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
     ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
 
-    hr = get_connected_filter_name((TestFilterImpl*)ptestfilter, ConnectedFilterName1);
+    hr = get_connected_filter_name(ptestfilter, ConnectedFilterName1);
 
     IFilterGraph2_Release(pgraph2);
     pgraph2 = NULL;
-    IBaseFilter_Release(ptestfilter);
+    IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
     ptestfilter = NULL;
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
     if (hr == E_NOTIMPL)
@@ -1587,45 +1612,45 @@ static void test_render_filter_priority(void)
     ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
     if (!pgraph2) goto out;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData1, (LPVOID)&ptestfilter);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter, wszFilterInstanceName1);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = TestFilter_Create(&GUID_NULL, PinData3, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData3, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName3);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData2, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName2);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = IFilterGraph2_Render(pgraph2, ((TestFilterImpl*)ptestfilter)->ppPins[0]);
+    hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
     ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
 
     hr = IFilterGraph2_Disconnect(pgraph2, NULL);
     ok(hr == E_POINTER, "IFilterGraph2_Disconnect failed. Expected E_POINTER, received %08x\n", hr);
 
-    get_connected_filter_name((TestFilterImpl*)ptestfilter, ConnectedFilterName2);
+    get_connected_filter_name(ptestfilter, ConnectedFilterName2);
     ok(lstrcmp(ConnectedFilterName1, ConnectedFilterName2),
         "expected connected filters to be different but got %s both times\n", ConnectedFilterName1);
 
     IFilterGraph2_Release(pgraph2);
     pgraph2 = NULL;
-    IBaseFilter_Release(ptestfilter);
+    IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
     ptestfilter = NULL;
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
     /* Test if any preference is given to existing renderer which renders the pin directly vs
@@ -1636,96 +1661,96 @@ static void test_render_filter_priority(void)
     ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
     if (!pgraph2) goto out;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData1, (LPVOID)&ptestfilter);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter, wszFilterInstanceName1);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = TestFilter_Create(&GUID_NULL, PinData2, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName2);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData4, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData4, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName3);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData5, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData5, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName4);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName4);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = IFilterGraph2_Render(pgraph2, ((TestFilterImpl*)ptestfilter)->ppPins[0]);
+    hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
     ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
 
-    get_connected_filter_name((TestFilterImpl*)ptestfilter, ConnectedFilterName1);
+    get_connected_filter_name(ptestfilter, ConnectedFilterName1);
     ok(!lstrcmp(ConnectedFilterName1, "TestfilterInstance3") || !lstrcmp(ConnectedFilterName1, "TestfilterInstance2"),
             "unexpected connected filter: %s\n", ConnectedFilterName1);
 
     IFilterGraph2_Release(pgraph2);
     pgraph2 = NULL;
-    IBaseFilter_Release(ptestfilter);
+    IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
     ptestfilter = NULL;
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
     hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (LPVOID*)&pgraph2);
     ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
     if (!pgraph2) goto out;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData1, (LPVOID)&ptestfilter);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter, wszFilterInstanceName1);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = TestFilter_Create(&GUID_NULL, PinData4, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData4, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName3);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName3);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData5, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData5, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName4);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName4);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData2, (LPVOID)&ptestfilter2);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData2, &ptestfilter2);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter2, wszFilterInstanceName2);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter2->IBaseFilter_iface, wszFilterInstanceName2);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
-    hr = IFilterGraph2_Render(pgraph2, ((TestFilterImpl*)ptestfilter)->ppPins[0]);
+    hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
     ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
 
-    get_connected_filter_name((TestFilterImpl*)ptestfilter, ConnectedFilterName2);
+    get_connected_filter_name(ptestfilter, ConnectedFilterName2);
     ok(!lstrcmp(ConnectedFilterName2, "TestfilterInstance3") || !lstrcmp(ConnectedFilterName2, "TestfilterInstance2"),
             "unexpected connected filter: %s\n", ConnectedFilterName2);
     ok(lstrcmp(ConnectedFilterName1, ConnectedFilterName2),
@@ -1733,9 +1758,9 @@ static void test_render_filter_priority(void)
 
     IFilterGraph2_Release(pgraph2);
     pgraph2 = NULL;
-    IBaseFilter_Release(ptestfilter);
+    IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
     ptestfilter = NULL;
-    IBaseFilter_Release(ptestfilter2);
+    IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     ptestfilter2 = NULL;
 
     /* Test if renderers are tried before non-renderers (intermediary filters). */
@@ -1747,31 +1772,34 @@ static void test_render_filter_priority(void)
     ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
     if (!pMapper2) goto out;
 
-    hr = TestFilter_Create(&GUID_NULL, PinData1, (LPVOID)&ptestfilter);
-    ok(hr == S_OK, "TestFilter_Create failed with %08x\n", hr);
+    hr = createtestfilter(&GUID_NULL, PinData1, &ptestfilter);
+    ok(hr == S_OK, "createtestfilter failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterGraph2_AddFilter(pgraph2, ptestfilter, wszFilterInstanceName1);
+    hr = IFilterGraph2_AddFilter(pgraph2, &ptestfilter->IBaseFilter_iface, wszFilterInstanceName1);
     ok(hr == S_OK, "IFilterGraph2_AddFilter failed with %08x\n", hr);
 
     /* Register our filters with COM and with Filtermapper. */
-    hr = CoRegisterClassObject(Filter1ClassFactory.clsid, (IUnknown *)&Filter1ClassFactory,
-                               CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie1);
+    hr = CoRegisterClassObject(Filter1ClassFactory.clsid,
+            (IUnknown *)&Filter1ClassFactory.IClassFactory_iface, CLSCTX_INPROC_SERVER,
+            REGCLS_MULTIPLEUSE, &cookie1);
     ok(hr == S_OK, "CoRegisterClassObject failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
-    hr = CoRegisterClassObject(Filter2ClassFactory.clsid, (IUnknown *)&Filter2ClassFactory,
-                               CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie2);
+    hr = CoRegisterClassObject(Filter2ClassFactory.clsid,
+            (IUnknown *)&Filter2ClassFactory.IClassFactory_iface, CLSCTX_INPROC_SERVER,
+            REGCLS_MULTIPLEUSE, &cookie2);
     ok(hr == S_OK, "CoRegisterClassObject failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
-    hr = CoRegisterClassObject(Filter3ClassFactory.clsid, (IUnknown *)&Filter3ClassFactory,
-                               CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie3);
+    hr = CoRegisterClassObject(Filter3ClassFactory.clsid,
+            (IUnknown *)&Filter3ClassFactory.IClassFactory_iface, CLSCTX_INPROC_SERVER,
+            REGCLS_MULTIPLEUSE, &cookie3);
     ok(hr == S_OK, "CoRegisterClassObject failed with %08x\n", hr);
     if (FAILED(hr)) goto out;
 
     rgf2.dwVersion = 2;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S1(U(rgf2)).cPins2 = 1;
-    S1(U(rgf2)).rgPins2 = rgPins2;
+    S2(U(rgf2)).cPins2 = 1;
+    S2(U(rgf2)).rgPins2 = rgPins2;
     rgPins2[0].dwFlags = REG_PINFLAG_B_RENDERER;
     rgPins2[0].cInstances = 1;
     rgPins2[0].nMediaTypes = 1;
@@ -1784,39 +1812,44 @@ static void test_render_filter_priority(void)
 
     hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter2, wszFilterInstanceName2, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+    if (hr == E_ACCESSDENIED)
+        skip("Not authorized to register filters\n");
+    else
+    {
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
-    rgf2.dwMerit = MERIT_PREFERRED;
-    rgPinType[0].clsMinorType = &mediasubtype2;
+        rgf2.dwMerit = MERIT_PREFERRED;
+        rgPinType[0].clsMinorType = &mediasubtype2;
 
-    hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter4, wszFilterInstanceName4, NULL,
+        hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter4, wszFilterInstanceName4, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
-
-    S1(U(rgf2)).cPins2 = 2;
-    rgPins2[0].dwFlags = 0;
-    rgPinType[0].clsMinorType = &mediasubtype1;
-
-    rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
-    rgPins2[1].cInstances = 1;
-    rgPins2[1].nMediaTypes = 1;
-    rgPins2[1].lpMediaType = &rgPinType[1];
-    rgPins2[1].nMediums = 0;
-    rgPins2[1].lpMedium = NULL;
-    rgPins2[1].clsPinCategory = NULL;
-    rgPinType[1].clsMajorType = &MEDIATYPE_Video;
-    rgPinType[1].clsMinorType = &mediasubtype2;
-
-    hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter3, wszFilterInstanceName3, NULL,
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+
+        S2(U(rgf2)).cPins2 = 2;
+        rgPins2[0].dwFlags = 0;
+        rgPinType[0].clsMinorType = &mediasubtype1;
+
+        rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
+        rgPins2[1].cInstances = 1;
+        rgPins2[1].nMediaTypes = 1;
+        rgPins2[1].lpMediaType = &rgPinType[1];
+        rgPins2[1].nMediums = 0;
+        rgPins2[1].lpMedium = NULL;
+        rgPins2[1].clsPinCategory = NULL;
+        rgPinType[1].clsMajorType = &MEDIATYPE_Video;
+        rgPinType[1].clsMinorType = &mediasubtype2;
+
+        hr = IFilterMapper2_RegisterFilter(pMapper2, &CLSID_TestFilter3, wszFilterInstanceName3, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
-    hr = IFilterGraph2_Render(pgraph2, ((TestFilterImpl*)ptestfilter)->ppPins[0]);
-    ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
+        hr = IFilterGraph2_Render(pgraph2, ptestfilter->ppPins[0]);
+        ok(hr == S_OK, "IFilterGraph2_Render failed with %08x\n", hr);
 
-    get_connected_filter_name((TestFilterImpl*)ptestfilter, ConnectedFilterName1);
-    ok(!lstrcmp(ConnectedFilterName1, "TestfilterInstance3"),
-            "unexpected connected filter: %s\n", ConnectedFilterName1);
+        get_connected_filter_name(ptestfilter, ConnectedFilterName1);
+        ok(!lstrcmp(ConnectedFilterName1, "TestfilterInstance3"),
+           "unexpected connected filter: %s\n", ConnectedFilterName1);
+    }
 
     hr = IFilterMapper2_UnregisterFilter(pMapper2, &CLSID_LegacyAmFilterCategory, NULL,
             &CLSID_TestFilter2);
@@ -1830,8 +1863,8 @@ static void test_render_filter_priority(void)
 
     out:
 
-    if (ptestfilter) IBaseFilter_Release(ptestfilter);
-    if (ptestfilter2) IBaseFilter_Release(ptestfilter2);
+    if (ptestfilter) IBaseFilter_Release(&ptestfilter->IBaseFilter_iface);
+    if (ptestfilter2) IBaseFilter_Release(&ptestfilter2->IBaseFilter_iface);
     if (pgraph2) IFilterGraph2_Release(pgraph2);
     if (pMapper2) IFilterMapper2_Release(pMapper2);
 
@@ -1845,20 +1878,27 @@ static void test_render_filter_priority(void)
 
 START_TEST(filtergraph)
 {
+    HRESULT hr;
+
+    if (!winetest_interactive)
+    {
+        skip("Skipping filtergraph test, see ROSTESTS-116\n");
+        return;
+    }
+
     CoInitializeEx(NULL, COINIT_MULTITHREADED);
-if(!winetest_interactive)
-{
-    skip("Skipping filtergraph test, see ROSTESTS_116\n");
-    return;
-}
-else{
-    test_render_run(avifileA);
-    test_render_run(mpegfileA);
+    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_IGraphBuilder, (LPVOID*)&pgraph);
+    if (FAILED(hr)) {
+        skip("Creating filtergraph returned %08x, skipping tests\n", hr);
+        return;
+    }
+    test_render_run(avifile);
+    test_render_run(mpegfile);
     test_graph_builder();
     test_graph_builder_addfilter();
     test_mediacontrol();
     test_filter_graph2();
     test_render_filter_priority();
-}
     CoUninitialize();
 }
index 4a8a3bb..b52d17e 100644 (file)
@@ -24,6 +24,9 @@
 #include "winbase.h"
 #include "initguid.h"
 #include "dshow.h"
+#include "winternl.h"
+
+#include "fil_data.h"
 
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
@@ -101,8 +104,8 @@ static void test_fm2_enummatchingfilters(void)
     /* Test that a test renderer filter is returned when enumerating filters with bRender=FALSE */
     rgf2.dwVersion = 2;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S1(U(rgf2)).cPins2 = 1;
-    S1(U(rgf2)).rgPins2 = rgPins2;
+    S2(U(rgf2)).cPins2 = 1;
+    S2(U(rgf2)).rgPins2 = rgPins2;
 
     rgPins2[0].dwFlags = REG_PINFLAG_B_RENDERER;
     rgPins2[0].cInstances = 1;
@@ -117,58 +120,63 @@ static void test_fm2_enummatchingfilters(void)
 
     hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter1, wszFilterName1, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+    if (hr == E_ACCESSDENIED)
+        skip("Not authorized to register filters\n");
+    else
+    {
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
-    rgPins2[0].dwFlags = 0;
+        rgPins2[0].dwFlags = 0;
 
-    rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
-    rgPins2[1].cInstances = 1;
-    rgPins2[1].nMediaTypes = 1;
-    rgPins2[1].lpMediaType = &rgPinType;
-    rgPins2[1].nMediums = 0;
-    rgPins2[1].lpMedium = NULL;
-    rgPins2[1].clsPinCategory = NULL;
+        rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
+        rgPins2[1].cInstances = 1;
+        rgPins2[1].nMediaTypes = 1;
+        rgPins2[1].lpMediaType = &rgPinType;
+        rgPins2[1].nMediums = 0;
+        rgPins2[1].lpMedium = NULL;
+        rgPins2[1].clsPinCategory = NULL;
 
-    S1(U(rgf2)).cPins2 = 2;
+        S2(U(rgf2)).cPins2 = 2;
 
-    hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter2, wszFilterName2, NULL,
+        hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter2, wszFilterName2, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName1, pEnum);
-        ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
-    }
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName1, pEnum);
+            ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
+        }
 
-    if (pEnum) IEnumMoniker_Release(pEnum);
-    pEnum = NULL;
+        if (pEnum) IEnumMoniker_Release(pEnum);
+        pEnum = NULL;
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName2, pEnum);
-        ok(found, "EnumMatchingFilters failed to return the test filter 2\n");
-    }
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName2, pEnum);
+            ok(found, "EnumMatchingFilters failed to return the test filter 2\n");
+        }
 
-    if (pEnum) IEnumMoniker_Release(pEnum);
-    pEnum = NULL;
+        if (pEnum) IEnumMoniker_Release(pEnum);
+        pEnum = NULL;
 
-    /* Non renderer must not be returned with bRender=TRUE */
+        /* Non renderer must not be returned with bRender=TRUE */
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, TRUE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
 
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName1, pEnum);
-        ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName1, pEnum);
+            ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
+        }
     }
 
     if (pEnum) IEnumMoniker_Release(pEnum);
@@ -245,67 +253,72 @@ static void test_legacy_filter_registration(void)
     /* Register---- functions need a filter class key to write pin and pin media type data to. Create a bogus
      * class key for it. */
     lRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, szRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
-    ok(lRet == ERROR_SUCCESS, "RegCreateKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+    if (lRet == ERROR_ACCESS_DENIED)
+        skip("Not authorized to register filters\n");
+    else
+    {
+        ok(lRet == ERROR_SUCCESS, "RegCreateKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
 
-    /* Set default value - this is interpreted as "friendly name" later. */
-    lRet = RegSetValueExA(hKey, NULL, 0, REG_SZ, (LPBYTE)szFilterName, lstrlenA(szFilterName) + 1);
-    ok(lRet == ERROR_SUCCESS, "RegSetValueExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+        /* Set default value - this is interpreted as "friendly name" later. */
+        lRet = RegSetValueExA(hKey, NULL, 0, REG_SZ, (LPBYTE)szFilterName, lstrlenA(szFilterName) + 1);
+        ok(lRet == ERROR_SUCCESS, "RegSetValueExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
 
-    if (hKey) RegCloseKey(hKey);
-    hKey = NULL;
+        if (hKey) RegCloseKey(hKey);
+        hKey = NULL;
 
-    hr = IFilterMapper_RegisterFilter(pMapper, clsidFilter, wszFilterName, MERIT_UNLIKELY);
-    ok(hr == S_OK, "IFilterMapper_RegisterFilter failed with %x\n", hr);
+        hr = IFilterMapper_RegisterFilter(pMapper, clsidFilter, wszFilterName, MERIT_UNLIKELY);
+        ok(hr == S_OK, "IFilterMapper_RegisterFilter failed with %x\n", hr);
 
-    hr = IFilterMapper_RegisterPin(pMapper, clsidFilter, wszPinName, TRUE, FALSE, FALSE, FALSE, GUID_NULL, NULL);
-    ok(hr == S_OK, "IFilterMapper_RegisterPin failed with %x\n", hr);
+        hr = IFilterMapper_RegisterPin(pMapper, clsidFilter, wszPinName, TRUE, FALSE, FALSE, FALSE, GUID_NULL, NULL);
+        ok(hr == S_OK, "IFilterMapper_RegisterPin failed with %x\n", hr);
 
-    hr = IFilterMapper_RegisterPinType(pMapper, clsidFilter, wszPinName, GUID_NULL, GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper_RegisterPinType failed with %x\n", hr);
+        hr = IFilterMapper_RegisterPinType(pMapper, clsidFilter, wszPinName, GUID_NULL, GUID_NULL);
+        ok(hr == S_OK, "IFilterMapper_RegisterPinType failed with %x\n", hr);
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper2, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper2, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName, pEnum);
-        ok(found, "IFilterMapper2_EnumMatchingFilters failed to return the test filter\n");
-    }
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName, pEnum);
+            ok(found, "IFilterMapper2_EnumMatchingFilters failed to return the test filter\n");
+        }
 
-    if (pEnum) IEnumMoniker_Release(pEnum);
-    pEnum = NULL;
+        if (pEnum) IEnumMoniker_Release(pEnum);
+        pEnum = NULL;
 
-    found = FALSE;
-    hr = IFilterMapper_EnumMatchingFilters(pMapper, &pRegEnum, MERIT_UNLIKELY, TRUE, GUID_NULL, GUID_NULL,
+        found = FALSE;
+        hr = IFilterMapper_EnumMatchingFilters(pMapper, &pRegEnum, MERIT_UNLIKELY, TRUE, GUID_NULL, GUID_NULL,
             FALSE, FALSE, GUID_NULL, GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pRegEnum)
-    {
-        ULONG cFetched;
-        REGFILTER *prgf;
-
-        while(!found && IEnumRegFilters_Next(pRegEnum, 1, &prgf, &cFetched) == S_OK)
+        ok(hr == S_OK, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pRegEnum)
         {
-            CHAR val[512];
+            ULONG cFetched;
+            REGFILTER *prgf;
 
-            WideCharToMultiByte(CP_ACP, 0, prgf->Name, -1, val, sizeof(val), 0, 0);
-            if (!lstrcmpA(val, szFilterName)) found = TRUE;
+            while(!found && IEnumRegFilters_Next(pRegEnum, 1, &prgf, &cFetched) == S_OK)
+            {
+                CHAR val[512];
 
-            CoTaskMemFree(prgf);
-        }
+                WideCharToMultiByte(CP_ACP, 0, prgf->Name, -1, val, sizeof(val), 0, 0);
+                if (!lstrcmpA(val, szFilterName)) found = TRUE;
 
-        IEnumRegFilters_Release(pRegEnum);
-    }
-    ok(found, "IFilterMapper_EnumMatchingFilters failed to return the test filter\n");
+                CoTaskMemFree(prgf);
+            }
 
-    hr = IFilterMapper_UnregisterFilter(pMapper, clsidFilter);
-    ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
+            IEnumRegFilters_Release(pRegEnum);
+        }
+        ok(found, "IFilterMapper_EnumMatchingFilters failed to return the test filter\n");
+
+        hr = IFilterMapper_UnregisterFilter(pMapper, clsidFilter);
+        ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
 
-    lRet = RegOpenKeyExA(HKEY_CLASSES_ROOT, szClsid, 0, KEY_WRITE | DELETE, &hKey);
-    ok(lRet == ERROR_SUCCESS, "RegOpenKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+        lRet = RegOpenKeyExA(HKEY_CLASSES_ROOT, szClsid, 0, KEY_WRITE | DELETE, &hKey);
+        ok(lRet == ERROR_SUCCESS, "RegOpenKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
 
-    lRet = RegDeleteKeyA(hKey, szGuidstring);
-    ok(lRet == ERROR_SUCCESS, "RegDeleteKeyA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+        lRet = RegDeleteKeyA(hKey, szGuidstring);
+        ok(lRet == ERROR_SUCCESS, "RegDeleteKeyA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+    }
 
     if (hKey) RegCloseKey(hKey);
     hKey = NULL;
@@ -405,8 +418,8 @@ static void test_register_filter_with_null_clsMinorType(void)
     ZeroMemory(&rgf2, sizeof(rgf2));
     rgf2.dwVersion = 1;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S(U(rgf2)).cPins = 1;
-    S(U(rgf2)).rgPins = &rgPins;
+    S1(U(rgf2)).cPins = 1;
+    S1(U(rgf2)).rgPins = &rgPins;
 
     rgPins.strName = wszPinName;
     rgPins.bRendered = 1;
@@ -420,6 +433,11 @@ static void test_register_filter_with_null_clsMinorType(void)
 
     hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter1, wszFilterName1, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
+    if (hr == E_ACCESSDENIED)
+    {
+        skip("Not authorized to register filters\n");
+        goto out;
+    }
     ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
     hr = IFilterMapper2_UnregisterFilter(pMapper, &CLSID_LegacyAmFilterCategory, NULL, &clsidFilter1);
@@ -429,8 +447,8 @@ static void test_register_filter_with_null_clsMinorType(void)
     ZeroMemory(&rgf2, sizeof(rgf2));
     rgf2.dwVersion = 2;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S1(U(rgf2)).cPins2 = 1;
-    S1(U(rgf2)).rgPins2 = &rgPins2;
+    S2(U(rgf2)).cPins2 = 1;
+    S2(U(rgf2)).rgPins2 = &rgPins2;
 
     rgPins2.dwFlags = REG_PINFLAG_B_RENDERER;
     rgPins2.cInstances = 1;
@@ -452,6 +470,70 @@ static void test_register_filter_with_null_clsMinorType(void)
     if (pMapper) IFilterMapper2_Release(pMapper);
 }
 
+static void test_parse_filter_data(void)
+{
+    static const BYTE data_block[] = {
+  0x02,0x00,0x00,0x00,0xff,0xff,0x5f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x70,0x69,0x33,
+  0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x31,0x70,0x69,0x33,
+  0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x76,0x69,0x64,0x73,
+  0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+    BYTE *prgbRegFilter2 = NULL;
+    REGFILTER2 *pRegFilter = NULL;
+    IFilterMapper2 *pMapper = NULL;
+    SAFEARRAYBOUND saBound;
+    SAFEARRAY *psa = NULL;
+    LPBYTE pbSAData = NULL;
+    HRESULT hr;
+
+    IAMFilterData *pData = NULL;
+
+    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IFilterMapper2, (LPVOID*)&pMapper);
+    ok((hr == S_OK || broken(hr != S_OK)), "CoCreateInstance failed with %x\n", hr);
+    if (FAILED(hr)) goto out;
+
+    hr = IFilterMapper2_QueryInterface(pMapper, &IID_IAMFilterData, (LPVOID*)&pData);
+    ok((hr == S_OK || broken(hr != S_OK)), "Unable to find IID_IAMFilterData interface\n");
+    if (FAILED(hr)) goto out;
+
+    saBound.lLbound = 0;
+    saBound.cElements = sizeof(data_block);
+    psa = SafeArrayCreate(VT_UI1, 1, &saBound);
+    ok(psa != NULL, "Unable to crate safe array\n");
+    if (!psa) goto out;
+    hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData);
+    ok(hr == S_OK, "Unable to access array data\n");
+    if (FAILED(hr)) goto out;
+    memcpy(pbSAData, data_block, sizeof(data_block));
+
+    hr = IAMFilterData_ParseFilterData(pData, pbSAData, sizeof(data_block), &prgbRegFilter2);
+    /* We cannot do anything here.  prgbRegFilter2 is very unstable */
+    /* Pre Vista, this is a stack pointer so anything that changes the stack invalidats it */
+    /* Post Vista, it is a static pointer in the data section of the module */
+    pRegFilter =((REGFILTER2**)prgbRegFilter2)[0];
+    ok (hr==S_OK,"Failed to Parse filter Data\n");
+
+    ok(IsBadReadPtr(prgbRegFilter2,sizeof(REGFILTER2*))==0,"Bad read pointer returned\n");
+    ok(IsBadReadPtr(pRegFilter,sizeof(REGFILTER2))==0,"Bad read pointer for FilterData\n");
+    ok(pRegFilter->dwMerit == 0x5fffff,"Incorrect merit returned\n");
+
+out:
+    if (pRegFilter)
+        CoTaskMemFree(pRegFilter);
+    if (psa)
+    {
+        SafeArrayUnaccessData(psa);
+        SafeArrayDestroy(psa);
+    }
+    if (pData)
+        IAMFilterData_Release(pData);
+    if (pMapper)
+        IFilterMapper2_Release(pMapper);
+}
 
 START_TEST(filtermapper)
 {
@@ -461,6 +543,7 @@ START_TEST(filtermapper)
     test_legacy_filter_registration();
     test_ifiltermapper_from_filtergraph();
     test_register_filter_with_null_clsMinorType();
+    test_parse_filter_data();
 
     CoUninitialize();
 }
index c5313f7..1086ed5 100644 (file)
@@ -18,8 +18,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include <assert.h>
-
 #define COBJMACROS
 
 #include "wine/test.h"
@@ -71,9 +69,9 @@ static void CommitDecommitTest(void)
 
             hr = IMemAllocator_GetBuffer(pMemAllocator, &sample2, NULL, NULL, 0);
             ok(hr==S_OK, "Could not get a buffer: %x\n", hr);
-            IUnknown_Release(sample);
+            IMediaSample_Release(sample);
             if (sample2)
-                IUnknown_Release(sample2);
+                IMediaSample_Release(sample2);
 
             hr = IMemAllocator_Decommit(pMemAllocator);
             ok(hr==S_OK, "Cecommit returned: %x\n", hr);
index 2830e48..743d23b 100644 (file)
@@ -69,6 +69,11 @@ static void test_aggregation(const CLSID clsidOuter, const CLSID clsidInner,
     /* for aggregation, we should only be able to request IUnknown */
     hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER,
                           &iidInner, (LPVOID*)&pUnkInnerFail);
+    if (hr == REGDB_E_CLASSNOTREG)
+    {
+        skip("Class not registered\n");
+        return;
+    }
     ok(hr == E_NOINTERFACE, "CoCreateInstance returned %x\n", hr);
     ok(pUnkInnerFail == NULL, "pUnkInnerFail is not NULL\n");
 
@@ -157,6 +162,19 @@ static void test_aggregation(const CLSID clsidOuter, const CLSID clsidInner,
     } while (refCount);
 }
 
+static void test_null_renderer_aggregations(void)
+{
+    const IID * iids[] = {
+        &IID_IMediaFilter, &IID_IBaseFilter
+    };
+    int i;
+
+    for (i = 0; i < sizeof(iids) / sizeof(iids[0]); i++)
+    {
+        test_aggregation(CLSID_SystemClock, CLSID_NullRenderer, IID_IReferenceClock, *iids[i]);
+    }
+}
+
 static void test_video_renderer_aggregations(void)
 {
     const IID * iids[] = {
@@ -206,15 +224,17 @@ START_TEST(misc)
 {
     CoInitialize(NULL);
 
-if(!winetest_interactive)
-{
-    skip("Skipping misc test, see ROSTESTS_116\n");
-    return;
-}
-else{
-    test_video_renderer_aggregations();
-    test_filter_graph_aggregations();
-    test_filter_mapper_aggregations();
-}
+    if (!winetest_interactive)
+    {
+        skip("Skipping misc test, see ROSTESTS-116\n");
+        return;
+    }
+    else
+    {
+        test_null_renderer_aggregations();
+        test_video_renderer_aggregations();
+        test_filter_graph_aggregations();
+        test_filter_mapper_aggregations();
+    }
     CoUninitialize();
 }
index ddce02e..a96bd48 100644 (file)
@@ -18,8 +18,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include <assert.h>
-
 #define COBJMACROS
 
 #include "wine/test.h"
index 8ed62d1..a41126c 100644 (file)
@@ -1,10 +1,7 @@
 /* Automatically generated file; DO NOT EDIT!! */
 
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
 #define STANDALONE
-#include "wine/test.h"
+#include <wine/test.h>
 
 extern void func_avisplitter(void);
 extern void func_dsoundrender(void);
index 0f198c7..67f7dd8 100644 (file)
@@ -28,7 +28,7 @@
     ok(ppv != NULL, "Pointer is NULL\n");
 
 #define RELEASE_EXPECT(iface, num) if (iface) { \
-    hr = IUnknown_Release(iface); \
+    hr = IUnknown_Release((IUnknown*)iface); \
     ok(hr == num, "IUnknown_Release should return %d, got %d\n", num, hr); \
 }
 
@@ -70,18 +70,18 @@ static void test_query_interface(void)
     RELEASE_EXPECT(pBasicVideo, 1);
     QI_SUCCEED(pVideoRenderer, IID_IMediaSeeking, pMediaSeeking);
     RELEASE_EXPECT(pMediaSeeking, 1);
+    QI_SUCCEED(pVideoRenderer, IID_IQualityControl, pQualityControl);
+    RELEASE_EXPECT(pQualityControl, 1);
     todo_wine {
     QI_SUCCEED(pVideoRenderer, IID_IDirectDrawVideo, pDirectDrawVideo);
     RELEASE_EXPECT(pDirectDrawVideo, 1);
     QI_SUCCEED(pVideoRenderer, IID_IKsPropertySet, pKsPropertySet);
     RELEASE_EXPECT(pKsPropertySet, 1);
-    QI_SUCCEED(pVideoRenderer, IID_IMediaPosition, pMediaPosition);
-    RELEASE_EXPECT(pMediaPosition, 1);
-    QI_SUCCEED(pVideoRenderer, IID_IQualityControl, pQualityControl);
-    RELEASE_EXPECT(pQualityControl, 1);
     QI_SUCCEED(pVideoRenderer, IID_IQualProp, pQualProp);
     RELEASE_EXPECT(pQualProp, 1);
     }
+    QI_SUCCEED(pVideoRenderer, IID_IMediaPosition, pMediaPosition);
+    RELEASE_EXPECT(pMediaPosition, 1);
     QI_SUCCEED(pVideoRenderer, IID_IVideoWindow, pVideoWindow);
     RELEASE_EXPECT(pVideoWindow, 1);
 }
@@ -156,15 +156,16 @@ START_TEST(videorenderer)
     if (!create_video_renderer())
         return;
 
-if(!winetest_interactive)
-{
-    skip("Skipping filtergraph test, see ROSTESTS_116\n");
-    return;
-}
-else{
-    test_query_interface();
-    test_basefilter();
-}
+    if (!winetest_interactive)
+    {
+        skip("Skipping filtergraph test, see ROSTESTS-116\n");
+        return;
+    }
+    else
+    {
+        test_query_interface();
+        test_basefilter();
+    }
     release_video_renderer();
 
     CoUninitialize();