[PATCH 3/6] mf: Implement SetObject()/GetObject() for topology node.

Nikolay Sivov nsivov at codeweavers.com
Mon May 6 05:52:15 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/tests/Makefile.in |  2 +-
 dlls/mf/tests/mf.c        | 83 +++++++++++++++++++++++++++++++++++++++
 dlls/mf/topology.c        | 78 ++++++++++++++++++++++++++++++++++--
 3 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/dlls/mf/tests/Makefile.in b/dlls/mf/tests/Makefile.in
index f233cff3fc..bdb493cc60 100644
--- a/dlls/mf/tests/Makefile.in
+++ b/dlls/mf/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = mf.dll
-IMPORTS   = mf mfplat
+IMPORTS   = mf mfplat mfuuid
 
 C_SRCS = \
 	mf.c
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 059062f698..cea5f98f6e 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -27,6 +27,12 @@
 #include "winbase.h"
 
 #include "initguid.h"
+#include "ole2.h"
+
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
+#undef INITGUID
+#include <guiddef.h>
 #include "mfapi.h"
 #include "mferror.h"
 #include "mfidl.h"
@@ -35,11 +41,45 @@
 
 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
+static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
+{
+    if (IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI test_unk_Release(IUnknown *iface)
+{
+    return 1;
+}
+
+static const IUnknownVtbl test_unk_vtbl =
+{
+    test_unk_QueryInterface,
+    test_unk_AddRef,
+    test_unk_Release,
+};
+
 static void test_topology(void)
 {
     IMFCollection *collection, *collection2;
+    IUnknown test_unk2 = { &test_unk_vtbl };
+    IUnknown test_unk = { &test_unk_vtbl };
     IMFTopologyNode *node, *node2, *node3;
     IMFTopology *topology, *topology2;
+    UINT32 attr_count;
+    IUnknown *object;
     DWORD size;
     WORD count;
     HRESULT hr;
@@ -302,6 +342,49 @@ static void test_topology(void)
     ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
     hr = IMFTopology_AddNode(topology, node);
     ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
+
+    /* Associated object. */
+    hr = IMFTopologyNode_SetObject(node, NULL);
+    ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_GetObject(node, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    object = (void *)0xdeadbeef;
+    hr = IMFTopologyNode_GetObject(node, &object);
+    ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
+    ok(!object, "Unexpected object %p.\n", object);
+
+    hr = IMFTopologyNode_SetObject(node, &test_unk);
+    ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_GetObject(node, &object);
+    ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
+    ok(object == &test_unk, "Unexpected object %p.\n", object);
+    IUnknown_Release(object);
+
+    hr = IMFTopologyNode_SetObject(node, &test_unk2);
+    ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_GetCount(node, &attr_count);
+    ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
+    ok(attr_count == 0, "Unexpected attribute count %u.\n", attr_count);
+
+    hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &MF_TOPONODE_TRANSFORM_OBJECTID);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_SetObject(node, NULL);
+    ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
+
+    object = (void *)0xdeadbeef;
+    hr = IMFTopologyNode_GetObject(node, &object);
+    ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
+    ok(!object, "Unexpected object %p.\n", object);
+
+    hr = IMFTopologyNode_GetCount(node, &attr_count);
+    ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
+    ok(attr_count == 1, "Unexpected attribute count %u.\n", attr_count);
+
     IMFTopologyNode_Release(node);
 
     hr = IMFTopology_GetOutputNodeCollection(topology, &collection);
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index 543e08fb24..e01444b8ce 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -25,7 +25,13 @@
 
 #include "windef.h"
 #include "winbase.h"
+
 #include "initguid.h"
+#include "ole2.h"
+#include "ocidl.h"
+
+#undef INITGUID
+#include <guiddef.h>
 #include "mfapi.h"
 #include "mferror.h"
 #include "mfidl.h"
@@ -54,6 +60,8 @@ struct topology_node
     IMFAttributes *attributes;
     MF_TOPOLOGY_TYPE node_type;
     TOPOID id;
+    IUnknown *object;
+    CRITICAL_SECTION cs;
 };
 
 struct topology_loader
@@ -755,7 +763,10 @@ static ULONG WINAPI topology_node_Release(IMFTopologyNode *iface)
 
     if (!refcount)
     {
+        if (node->object)
+            IUnknown_Release(node->object);
         IMFAttributes_Release(node->attributes);
+        DeleteCriticalSection(&node->cs);
         heap_free(node);
     }
 
@@ -1038,16 +1049,74 @@ static HRESULT WINAPI topology_node_CopyAllItems(IMFTopologyNode *iface, IMFAttr
 
 static HRESULT WINAPI topology_node_SetObject(IMFTopologyNode *iface, IUnknown *object)
 {
-    FIXME("(%p)->(%p)\n", iface, object);
+    static const GUID *iids[3] = { &IID_IPersist, &IID_IPersistStorage, &IID_IPersistPropertyBag };
+    struct topology_node *node = impl_from_IMFTopologyNode(iface);
+    IPersist *persist = NULL;
+    BOOL has_object_id;
+    GUID object_id;
+    unsigned int i;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, object);
+
+    has_object_id = IMFAttributes_GetGUID(node->attributes, &MF_TOPONODE_TRANSFORM_OBJECTID, &object_id) == S_OK;
+
+    if (object && !has_object_id)
+    {
+        for (i = 0; i < ARRAY_SIZE(iids); ++i)
+        {
+            persist = NULL;
+            if (SUCCEEDED(hr = IUnknown_QueryInterface(object, iids[i], (void **)&persist)))
+                break;
+        }
+
+        if (persist)
+        {
+            if (FAILED(hr = IPersist_GetClassID(persist, &object_id)))
+            {
+                IPersist_Release(persist);
+                persist = NULL;
+            }
+        }
+    }
+
+    EnterCriticalSection(&node->cs);
+
+    if (node->object)
+        IUnknown_Release(node->object);
+    node->object = object;
+    if (node->object)
+        IUnknown_AddRef(node->object);
+
+    if (persist)
+        IMFAttributes_SetGUID(node->attributes, &MF_TOPONODE_TRANSFORM_OBJECTID, &object_id);
+
+    LeaveCriticalSection(&node->cs);
+
+    if (persist)
+        IPersist_Release(persist);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI topology_node_GetObject(IMFTopologyNode *iface, IUnknown **object)
 {
-    FIXME("(%p)->(%p)\n", iface, object);
+    struct topology_node *node = impl_from_IMFTopologyNode(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, object);
+
+    if (!object)
+        return E_POINTER;
+
+    EnterCriticalSection(&node->cs);
+
+    *object = node->object;
+    if (*object)
+        IUnknown_AddRef(*object);
+
+    LeaveCriticalSection(&node->cs);
+
+    return *object ? S_OK : E_FAIL;
 }
 
 static HRESULT WINAPI topology_node_GetNodeType(IMFTopologyNode *iface, MF_TOPOLOGY_TYPE *node_type)
@@ -1243,6 +1312,7 @@ HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode
         return hr;
     }
     object->id = ((TOPOID)GetCurrentProcessId() << 32) | InterlockedIncrement(&next_node_id);
+    InitializeCriticalSection(&object->cs);
 
     *node = &object->IMFTopologyNode_iface;
 
-- 
2.20.1




More information about the wine-devel mailing list