[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