From c1d023565af92b9e3d3cc6c198191e652616f47e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 6 May 2019 13:52:15 +0300 Subject: [PATCH] mf: Implement SetObject()/GetObject() for topology node. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- 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 f233cff3fc6..bdb493cc605 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 059062f6989..cea5f98f6e1 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 #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 543e08fb247..e01444b8ce7 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 #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;