[PATCH 5/5] avifil32/tests: Add COM tests for AVIFile.

Michael Stefaniuc mstefani at redhat.de
Wed Mar 6 17:46:17 CST 2013


---
 dlls/avifil32/tests/Makefile.in |    2 +-
 dlls/avifil32/tests/api.c       |  119 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 114 insertions(+), 7 deletions(-)

diff --git a/dlls/avifil32/tests/Makefile.in b/dlls/avifil32/tests/Makefile.in
index 658b096..abe1ad4 100644
--- a/dlls/avifil32/tests/Makefile.in
+++ b/dlls/avifil32/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = avifil32.dll
-IMPORTS   = avifil32
+IMPORTS   = avifil32 ole32
 
 C_SRCS = \
 	api.c
diff --git a/dlls/avifil32/tests/api.c b/dlls/avifil32/tests/api.c
index 4b87806..22c15c5 100644
--- a/dlls/avifil32/tests/api.c
+++ b/dlls/avifil32/tests/api.c
@@ -19,14 +19,13 @@
  *
  */
 
-#include <stdarg.h>
+#define COBJMACROS
+#define CONST_VTABLE
 
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
+#include "wine/test.h"
+#include "initguid.h"
 #include "wingdi.h"
 #include "vfw.h"
-#include "wine/test.h"
 
 /* ########################### */
 
@@ -541,7 +540,114 @@ static void test_ash1_corruption2(void)
     ok(DeleteFile(filename) !=0, "Deleting file %s failed\n", filename);
 }
 
-/* ########################### */
+/* Outer IUnknown for COM aggregation tests */
+struct unk_impl {
+    IUnknown IUnknown_iface;
+    LONG ref;
+    IUnknown *inner_unk;
+};
+
+static inline struct unk_impl *impl_from_IUnknown(IUnknown *iface)
+{
+    return CONTAINING_RECORD(iface, struct unk_impl, IUnknown_iface);
+}
+
+static HRESULT WINAPI unk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
+{
+    struct unk_impl *This = impl_from_IUnknown(iface);
+    LONG ref = This->ref;
+    HRESULT hr;
+
+    if (IsEqualGUID(riid, &IID_IUnknown))
+    {
+        *ppv = iface;
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    hr = IUnknown_QueryInterface(This->inner_unk, riid, ppv);
+    if (hr == S_OK)
+    {
+        trace("Working around COM aggregation ref counting bug\n");
+        ok(ref == This->ref, "Outer ref count expected %d got %d\n", ref, This->ref);
+        IUnknown_AddRef((IUnknown*)*ppv);
+        ref = IUnknown_Release(This->inner_unk);
+        ok(ref == 1, "Inner ref count expected 1 got %d\n", ref);
+    }
+
+    return hr;
+}
+
+static ULONG WINAPI unk_AddRef(IUnknown *iface)
+{
+    struct unk_impl *This = impl_from_IUnknown(iface);
+
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI unk_Release(IUnknown *iface)
+{
+    struct unk_impl *This = impl_from_IUnknown(iface);
+
+    return InterlockedDecrement(&This->ref);
+}
+
+static const IUnknownVtbl unk_vtbl =
+{
+    unk_QueryInterface,
+    unk_AddRef,
+    unk_Release
+};
+
+static void test_COM(void)
+{
+    struct unk_impl unk_obj = {{&unk_vtbl}, 19, NULL};
+    IAVIFile *avif = NULL;
+    IPersistFile *pf;
+    IUnknown *unk;
+    LONG refcount;
+    HRESULT hr;
+
+    /* COM aggregation */
+    hr = CoCreateInstance(&CLSID_AVIFile, &unk_obj.IUnknown_iface, CLSCTX_INPROC_SERVER,
+            &IID_IUnknown, (void**)&unk_obj.inner_unk);
+    ok(hr == S_OK, "COM aggregation failed: %08x, expected S_OK\n", hr);
+    hr = IUnknown_QueryInterface(&unk_obj.IUnknown_iface, &IID_IAVIFile, (void**)&avif);
+    ok(hr == S_OK, "QueryInterface for IID_IAVIFile failed: %08x\n", hr);
+    refcount = IAVIFile_AddRef(avif);
+    ok(refcount == unk_obj.ref, "AVIFile just pretends to support COM aggregation\n");
+    refcount = IAVIFile_Release(avif);
+    ok(refcount == unk_obj.ref, "AVIFile just pretends to support COM aggregation\n");
+    hr = IAVIFile_QueryInterface(avif, &IID_IPersistFile, (void**)&pf);
+    ok(hr == S_OK, "QueryInterface for IID_IPersistFile failed: %08x\n", hr);
+    refcount = IPersistFile_Release(pf);
+    ok(refcount == unk_obj.ref, "AVIFile just pretends to support COM aggregation\n");
+    refcount = IAVIFile_Release(avif);
+    ok(refcount == 19, "Outer ref count should be back at 19 but is %d\n", refcount);
+    refcount = IUnknown_Release(unk_obj.inner_unk);
+    ok(refcount == 0, "Inner ref count should be 0 but is %u\n", refcount);
+
+    /* Invalid RIID */
+    hr = CoCreateInstance(&CLSID_AVIFile, NULL, CLSCTX_INPROC_SERVER, &IID_IAVIStream,
+            (void**)&avif);
+    ok(hr == E_NOINTERFACE, "AVIFile create failed: %08x, expected E_NOINTERFACE\n", hr);
+
+    /* Same refcount */
+    hr = CoCreateInstance(&CLSID_AVIFile, NULL, CLSCTX_INPROC_SERVER, &IID_IAVIFile, (void**)&avif);
+    ok(hr == S_OK, "AVIFile create failed: %08x, expected S_OK\n", hr);
+    refcount = IAVIFile_AddRef(avif);
+    ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
+    hr = IAVIFile_QueryInterface(avif, &IID_IUnknown, (void**)&unk);
+    ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
+    refcount = IUnknown_AddRef(unk);
+    ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
+    hr = IAVIFile_QueryInterface(avif, &IID_IPersistFile, (void**)&pf);
+    ok(hr == S_OK, "QueryInterface for IID_IPersistFile failed: %08x\n", hr);
+    refcount = IPersistFile_AddRef(pf);
+    ok(refcount == 6, "refcount == %u, expected 6\n", refcount);
+
+    while (IAVIFile_Release(avif));
+}
 
 START_TEST(api)
 {
@@ -553,6 +659,7 @@ START_TEST(api)
     test_amh_corruption();
     test_ash1_corruption();
     test_ash1_corruption2();
+    test_COM();
     AVIFileExit();
 
 }
-- 
1.7.6.5



More information about the wine-patches mailing list