Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/filtergraph.c | 25 ++++++++++++++ dlls/quartz/tests/filtermapper.c | 58 -------------------------------- 2 files changed, 25 insertions(+), 58 deletions(-)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index cd3c6354b07..afb32a01569 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -2496,6 +2496,7 @@ static IUnknown test_outer = {&outer_vtbl}; static void test_aggregation(void) { IFilterGraph2 *graph, *graph2; + IFilterMapper2 *mapper; IUnknown *unk, *unk2; HRESULT hr; ULONG ref; @@ -2550,6 +2551,30 @@ static void test_aggregation(void) ref = IUnknown_Release(unk); ok(!ref, "Got unexpected refcount %d.\n", ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + /* Test the aggregated filter mapper. */ + + graph = create_graph(); + + ref = get_refcount(graph); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + hr = IFilterGraph2_QueryInterface(graph, &IID_IFilterMapper2, (void **)&mapper); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ref = get_refcount(graph); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(mapper); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + + hr = IFilterMapper2_QueryInterface(mapper, &IID_IFilterGraph2, (void **)&graph2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(graph2 == graph, "Got unexpected IFilterGraph2 %p.\n", graph2); + IFilterGraph2_Release(graph2); + + IFilterMapper2_Release(mapper); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got unexpected refcount %d.\n", ref); }
/* Test how methods from "control" interfaces (IBasicAudio, IBasicVideo, diff --git a/dlls/quartz/tests/filtermapper.c b/dlls/quartz/tests/filtermapper.c index 0f03b5ee0a9..5ca59a62e4e 100644 --- a/dlls/quartz/tests/filtermapper.c +++ b/dlls/quartz/tests/filtermapper.c @@ -370,63 +370,6 @@ static void test_legacy_filter_registration(void) IFilterMapper2_Release(mapper2); }
-static ULONG getRefcount(IUnknown *iface) -{ - IUnknown_AddRef(iface); - return IUnknown_Release(iface); -} - -static void test_ifiltermapper_from_filtergraph(void) -{ - IFilterGraph2* pgraph2 = NULL; - IFilterMapper2 *pMapper2 = NULL; - IFilterGraph *filtergraph = NULL; - HRESULT hr; - ULONG refcount; - - 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 = IFilterGraph2_QueryInterface(pgraph2, &IID_IFilterMapper2, (LPVOID*)&pMapper2); - ok(hr == S_OK, "IFilterGraph2_QueryInterface failed with %08x\n", hr); - if (!pMapper2) goto out; - - refcount = getRefcount((IUnknown*)pgraph2); - ok(refcount == 2, "unexpected reference count: %u\n", refcount); - refcount = getRefcount((IUnknown*)pMapper2); - ok(refcount == 2, "unexpected reference count: %u\n", refcount); - - IFilterMapper2_AddRef(pMapper2); - refcount = getRefcount((IUnknown*)pgraph2); - ok(refcount == 3, "unexpected reference count: %u\n", refcount); - refcount = getRefcount((IUnknown*)pMapper2); - ok(refcount == 3, "unexpected reference count: %u\n", refcount); - IFilterMapper2_Release(pMapper2); - - hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterGraph, (LPVOID*)&filtergraph); - ok(hr == S_OK, "IFilterMapper2_QueryInterface failed with %08x\n", hr); - if (!filtergraph) goto out; - - IFilterMapper2_Release(pMapper2); - pMapper2 = NULL; - IFilterGraph_Release(filtergraph); - filtergraph = NULL; - - hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pMapper2); - ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr); - if (!pMapper2) goto out; - - hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterGraph, (LPVOID*)&filtergraph); - ok(hr == E_NOINTERFACE, "IFilterMapper2_QueryInterface unexpected result: %08x\n", hr); - - out: - - if (pMapper2) IFilterMapper2_Release(pMapper2); - if (filtergraph) IFilterGraph_Release(filtergraph); - if (pgraph2) IFilterGraph2_Release(pgraph2); -} - static void test_register_filter_with_null_clsMinorType(void) { static WCHAR wszPinName[] = L"Pin"; @@ -945,7 +888,6 @@ START_TEST(filtermapper) test_interfaces(); test_fm2_enummatchingfilters(); test_legacy_filter_registration(); - test_ifiltermapper_from_filtergraph(); test_register_filter_with_null_clsMinorType(); test_parse_filter_data(); test_aggregation();
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/Makefile.in | 1 - dlls/quartz/enumregfilters.c | 224 ----------------------------------- dlls/quartz/filtermapper.c | 162 ++++++++++++++++++++++++- dlls/quartz/quartz_private.h | 2 - 4 files changed, 160 insertions(+), 229 deletions(-) delete mode 100644 dlls/quartz/enumregfilters.c
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 14ba932a312..2d1f637aca7 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -9,7 +9,6 @@ C_SRCS = \ avidec.c \ dsoundrender.c \ enummoniker.c \ - enumregfilters.c \ filesource.c \ filtergraph.c \ filtermapper.c \ diff --git a/dlls/quartz/enumregfilters.c b/dlls/quartz/enumregfilters.c deleted file mode 100644 index 42dccf3b625..00000000000 --- a/dlls/quartz/enumregfilters.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Implementation of IEnumRegFilters Interface - * - * Copyright 2004 Christian Costa - * - * 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 - */ - -#include "quartz_private.h" - - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -typedef struct IEnumRegFiltersImpl -{ - IEnumRegFilters IEnumRegFilters_iface; - LONG refCount; - ULONG size; - REGFILTER* RegFilters; - ULONG uIndex; -} IEnumRegFiltersImpl; - -static inline IEnumRegFiltersImpl *impl_from_IEnumRegFilters(IEnumRegFilters *iface) -{ - return CONTAINING_RECORD(iface, IEnumRegFiltersImpl, IEnumRegFilters_iface); -} - -static const struct IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl; - -HRESULT IEnumRegFiltersImpl_Construct(REGFILTER* pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum) -{ - IEnumRegFiltersImpl* pEnumRegFilters; - REGFILTER* pRegFilters = NULL; - unsigned int i; - - TRACE("(%p, %d, %p)\n", pInRegFilters, size, ppEnum); - - pEnumRegFilters = CoTaskMemAlloc(sizeof(IEnumRegFiltersImpl)); - if (!pEnumRegFilters) - { - *ppEnum = NULL; - return E_OUTOFMEMORY; - } - - /* Accept size of 0 */ - if (size) - { - pRegFilters = CoTaskMemAlloc(sizeof(REGFILTER)*size); - if (!pRegFilters) - { - CoTaskMemFree(pEnumRegFilters); - *ppEnum = NULL; - return E_OUTOFMEMORY; - } - } - - for(i = 0; i < size; i++) - { - pRegFilters[i].Clsid = pInRegFilters[i].Clsid; - pRegFilters[i].Name = CoTaskMemAlloc((lstrlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR)); - if (!pRegFilters[i].Name) - { - while(i) - CoTaskMemFree(pRegFilters[--i].Name); - CoTaskMemFree(pRegFilters); - CoTaskMemFree(pEnumRegFilters); - return E_OUTOFMEMORY; - } - CopyMemory(pRegFilters[i].Name, pInRegFilters[i].Name, (lstrlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR)); - } - - pEnumRegFilters->IEnumRegFilters_iface.lpVtbl = &IEnumRegFiltersImpl_Vtbl; - pEnumRegFilters->refCount = 1; - pEnumRegFilters->uIndex = 0; - pEnumRegFilters->RegFilters = pRegFilters; - pEnumRegFilters->size = size; - - *ppEnum = &pEnumRegFilters->IEnumRegFilters_iface; - - return S_OK; -} - -static HRESULT WINAPI IEnumRegFiltersImpl_QueryInterface(IEnumRegFilters * iface, REFIID riid, LPVOID * ppv) -{ - TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IEnumRegFilters)) - *ppv = iface; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IEnumRegFiltersImpl_AddRef(IEnumRegFilters * iface) -{ - IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p)\n", iface); - - return refCount; -} - -static ULONG WINAPI IEnumRegFiltersImpl_Release(IEnumRegFilters * iface) -{ - IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("(%p)\n", iface); - - if (!refCount) - { - ULONG i; - - for(i = 0; i < This->size; i++) - { - CoTaskMemFree(This->RegFilters[i].Name); - } - CoTaskMemFree(This->RegFilters); - CoTaskMemFree(This); - return 0; - } else - return refCount; -} - -static HRESULT WINAPI IEnumRegFiltersImpl_Next(IEnumRegFilters * iface, ULONG cFilters, REGFILTER ** ppRegFilter, ULONG * pcFetched) -{ - ULONG cFetched; - IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); - unsigned int i; - - cFetched = min(This->size, This->uIndex + cFilters) - This->uIndex; - - TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppRegFilter, pcFetched); - - if (cFetched > 0) - { - for(i = 0; i < cFetched; i++) - { - /* The string in the REGFILTER structure must be allocated in the same block as the REGFILTER structure itself */ - ppRegFilter[i] = CoTaskMemAlloc(sizeof(REGFILTER)+(lstrlenW(This->RegFilters[This->uIndex + i].Name)+1)*sizeof(WCHAR)); - if (!ppRegFilter[i]) - { - while(i) - { - CoTaskMemFree(ppRegFilter[--i]); - ppRegFilter[i] = NULL; - } - return E_OUTOFMEMORY; - } - ppRegFilter[i]->Clsid = This->RegFilters[This->uIndex + i].Clsid; - ppRegFilter[i]->Name = (WCHAR*)((char*)ppRegFilter[i]+sizeof(REGFILTER)); - CopyMemory(ppRegFilter[i]->Name, This->RegFilters[This->uIndex + i].Name, - (lstrlenW(This->RegFilters[This->uIndex + i].Name)+1)*sizeof(WCHAR)); - } - - This->uIndex += cFetched; - if (pcFetched) - *pcFetched = cFetched; - return S_OK; - } - - return S_FALSE; -} - -static HRESULT WINAPI IEnumRegFiltersImpl_Skip(IEnumRegFilters * iface, ULONG n) -{ - TRACE("(%p)->(%u)\n", iface, n); - - return E_NOTIMPL; -} - -static HRESULT WINAPI IEnumRegFiltersImpl_Reset(IEnumRegFilters * iface) -{ - IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); - - TRACE("(%p)\n", iface); - - This->uIndex = 0; - return S_OK; -} - -static HRESULT WINAPI IEnumRegFiltersImpl_Clone(IEnumRegFilters * iface, IEnumRegFilters ** ppEnum) -{ - TRACE("(%p)->(%p)\n", iface, ppEnum); - - return E_NOTIMPL; -} - -static const IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl = -{ - IEnumRegFiltersImpl_QueryInterface, - IEnumRegFiltersImpl_AddRef, - IEnumRegFiltersImpl_Release, - IEnumRegFiltersImpl_Next, - IEnumRegFiltersImpl_Skip, - IEnumRegFiltersImpl_Reset, - IEnumRegFiltersImpl_Clone -}; diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index 2068131b9eb..69e9ef90e27 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -42,6 +42,164 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+struct enum_reg_filters +{ + IEnumRegFilters IEnumRegFilters_iface; + LONG refcount; + + unsigned int index, count; + REGFILTER *filters; +}; + +static struct enum_reg_filters *impl_from_IEnumRegFilters(IEnumRegFilters *iface) +{ + return CONTAINING_RECORD(iface, struct enum_reg_filters, IEnumRegFilters_iface); +} + +static HRESULT WINAPI enum_reg_filters_QueryInterface(IEnumRegFilters *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumRegFilters)) + { + IEnumRegFilters_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI enum_reg_filters_AddRef(IEnumRegFilters *iface) +{ + struct enum_reg_filters *enumerator = impl_from_IEnumRegFilters(iface); + ULONG refcount = InterlockedIncrement(&enumerator->refcount); + TRACE("%p increasing refcount to %u.\n", enumerator, refcount); + return refcount; +} + +static ULONG WINAPI enum_reg_filters_Release(IEnumRegFilters *iface) +{ + struct enum_reg_filters *enumerator = impl_from_IEnumRegFilters(iface); + ULONG refcount = InterlockedDecrement(&enumerator->refcount); + unsigned int i; + + TRACE("%p decreasing refcount to %u.\n", enumerator, refcount); + if (!refcount) + { + for (i = 0; i < enumerator->count; ++i) + free(enumerator->filters[i].Name); + free(enumerator->filters); + free(enumerator); + } + return refcount; +} + +static HRESULT WINAPI enum_reg_filters_Next(IEnumRegFilters *iface, ULONG count, + REGFILTER **filters, ULONG *ret_count) +{ + struct enum_reg_filters *enumerator = impl_from_IEnumRegFilters(iface); + unsigned int i; + + TRACE("iface %p, count %u, filters %p, ret_count %p.\n", iface, count, filters, ret_count); + + for (i = 0; i < count && enumerator->index + i < enumerator->count; ++i) + { + REGFILTER *filter = &enumerator->filters[enumerator->index + i]; + + if (!(filters[i] = CoTaskMemAlloc(sizeof(REGFILTER) + (wcslen(filter->Name) + 1) * sizeof(WCHAR)))) + { + while (i--) + CoTaskMemFree(filters[i]); + memset(filters, 0, count * sizeof(*filters)); + *ret_count = 0; + return E_OUTOFMEMORY; + } + + filters[i]->Clsid = filter->Clsid; + filters[i]->Name = (WCHAR *)(filters[i] + 1); + wcscpy(filters[i]->Name, filter->Name); + } + + enumerator->index += i; + if (ret_count) + *ret_count = i; + return i ? S_OK : S_FALSE; +} + +static HRESULT WINAPI enum_reg_filters_Skip(IEnumRegFilters *iface, ULONG count) +{ + TRACE("iface %p, count %u, unimplemented.\n", iface, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI enum_reg_filters_Reset(IEnumRegFilters *iface) +{ + struct enum_reg_filters *enumerator = impl_from_IEnumRegFilters(iface); + + TRACE("iface %p.\n", iface); + + enumerator->index = 0; + return S_OK; +} + +static HRESULT WINAPI enum_reg_filters_Clone(IEnumRegFilters *iface, IEnumRegFilters **out) +{ + TRACE("iface %p, out %p, unimplemented.\n", iface, out); + return E_NOTIMPL; +} + +static const IEnumRegFiltersVtbl enum_reg_filters_vtbl = +{ + enum_reg_filters_QueryInterface, + enum_reg_filters_AddRef, + enum_reg_filters_Release, + enum_reg_filters_Next, + enum_reg_filters_Skip, + enum_reg_filters_Reset, + enum_reg_filters_Clone, +}; + +static HRESULT enum_reg_filters_create(REGFILTER *filters, unsigned int count, IEnumRegFilters **out) +{ + struct enum_reg_filters *object; + unsigned int i; + + *out = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (!(object->filters = malloc(count * sizeof(*object->filters)))) + { + free(object); + return E_OUTOFMEMORY; + } + + for (i = 0; i < count; ++i) + { + object->filters[i].Clsid = filters[i].Clsid; + if (!(object->filters[i].Name = wcsdup(filters[i].Name))) + { + while (i--) + free(object->filters[i].Name); + free(object->filters); + free(object); + return E_OUTOFMEMORY; + } + } + + object->IEnumRegFilters_iface.lpVtbl = &enum_reg_filters_vtbl; + object->refcount = 1; + object->count = count; + + TRACE("Created enumerator %p.\n", object); + *out = &object->IEnumRegFilters_iface; + return S_OK; +} + typedef struct FilterMapper3Impl { IUnknown IUnknown_inner; @@ -1030,7 +1188,7 @@ static HRESULT WINAPI FilterMapper_EnumMatchingFilters( if (!nb_mon) { IEnumMoniker_Release(ppEnumMoniker); - return IEnumRegFiltersImpl_Construct(NULL, 0, ppEnum); + return enum_reg_filters_create(NULL, 0, ppEnum); }
regfilters = CoTaskMemAlloc(nb_mon * sizeof(REGFILTER)); @@ -1087,7 +1245,7 @@ static HRESULT WINAPI FilterMapper_EnumMatchingFilters(
if (SUCCEEDED(hr)) { - hr = IEnumRegFiltersImpl_Construct(regfilters, idx, ppEnum); + hr = enum_reg_filters_create(regfilters, idx, ppEnum); }
for (idx = 0; idx < nb_mon; idx++) diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 5c391481f25..0f38563e365 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -81,8 +81,6 @@ HRESULT vmr9_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) DECLSPEC_HIDDEN;
-HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum) DECLSPEC_HIDDEN; - extern const char * qzdebugstr_guid(const GUID * id) DECLSPEC_HIDDEN; extern void video_unregister_windowclass(void) DECLSPEC_HIDDEN;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/Makefile.in | 1 - dlls/quartz/enummoniker.c | 208 ----------------------------------- dlls/quartz/filtermapper.c | 136 ++++++++++++++++++++++- dlls/quartz/quartz_private.h | 2 - 4 files changed, 135 insertions(+), 212 deletions(-) delete mode 100644 dlls/quartz/enummoniker.c
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 2d1f637aca7..110377bec79 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -8,7 +8,6 @@ C_SRCS = \ acmwrapper.c \ avidec.c \ dsoundrender.c \ - enummoniker.c \ filesource.c \ filtergraph.c \ filtermapper.c \ diff --git a/dlls/quartz/enummoniker.c b/dlls/quartz/enummoniker.c deleted file mode 100644 index c0071a3360b..00000000000 --- a/dlls/quartz/enummoniker.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * IEnumMoniker implementation - * - * Copyright 2003 Robert Shearman - * - * 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 - */ - -#define COBJMACROS - -#include "quartz_private.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -typedef struct EnumMonikerImpl -{ - IEnumMoniker IEnumMoniker_iface; - LONG ref; - IMoniker ** ppMoniker; - ULONG nMonikerCount; - ULONG index; -} EnumMonikerImpl; - -static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl; - -static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface) -{ - return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface); -} - -static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface); - -HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) -{ - /* NOTE: assumes that array of IMonikers has already been AddRef'd - * I.e. this function does not AddRef the array of incoming - * IMonikers */ - EnumMonikerImpl * pemi = CoTaskMemAlloc(sizeof(EnumMonikerImpl)); - - TRACE("(%p, %d, %p)\n", ppMoniker, nMonikerCount, ppEnum); - - *ppEnum = NULL; - - if (!pemi) - return E_OUTOFMEMORY; - - pemi->IEnumMoniker_iface.lpVtbl = &EnumMonikerImpl_Vtbl; - pemi->ref = 1; - pemi->ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker*)); - memcpy(pemi->ppMoniker, ppMoniker, nMonikerCount*sizeof(IMoniker*)); - pemi->nMonikerCount = nMonikerCount; - pemi->index = 0; - - *ppEnum = &pemi->IEnumMoniker_iface; - - return S_OK; -} - -/********************************************************************** - * IEnumMoniker_QueryInterface (also IUnknown) - */ -static HRESULT WINAPI EnumMonikerImpl_QueryInterface( - LPENUMMONIKER iface, - REFIID riid, - LPVOID *ppvObj) -{ - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); - - if (This == NULL || ppvObj == NULL) return E_POINTER; - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IEnumMoniker)) - { - *ppvObj = iface; - EnumMonikerImpl_AddRef(iface); - return S_OK; - } - - *ppvObj = NULL; - FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -/********************************************************************** - * IEnumMoniker_AddRef (also IUnknown) - */ -static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface) -{ - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - ULONG ref; - - if (This == NULL) return E_POINTER; - - ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->() AddRef from %d\n", iface, ref - 1); - - return ref; -} - -/********************************************************************** - * IEnumMoniker_Release (also IUnknown) - */ -static ULONG WINAPI EnumMonikerImpl_Release(LPENUMMONIKER iface) -{ - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->() Release from %d\n", iface, ref + 1); - - if (!ref) - { - ULONG i; - - for (i = 0; i < This->nMonikerCount; i++) - IMoniker_Release(This->ppMoniker[i]); - - CoTaskMemFree(This->ppMoniker); - This->ppMoniker = NULL; - CoTaskMemFree(This); - return 0; - } - return ref; -} - -static HRESULT WINAPI EnumMonikerImpl_Next(LPENUMMONIKER iface, ULONG celt, IMoniker ** rgelt, ULONG * pceltFetched) -{ - ULONG fetched; - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - - TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched); - - for (fetched = 0; (This->index + fetched < This->nMonikerCount) && (fetched < celt); fetched++) - { - rgelt[fetched] = This->ppMoniker[This->index + fetched]; - IMoniker_AddRef(rgelt[fetched]); - } - - This->index += fetched; - - TRACE("-- fetched %d\n", fetched); - - if (pceltFetched) - *pceltFetched = fetched; - - if (fetched != celt) - return S_FALSE; - else - return S_OK; -} - -static HRESULT WINAPI EnumMonikerImpl_Skip(LPENUMMONIKER iface, ULONG celt) -{ - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - - TRACE("(%p)->(%d)\n", iface, celt); - - This->index += celt; - - return S_OK; -} - -static HRESULT WINAPI EnumMonikerImpl_Reset(LPENUMMONIKER iface) -{ - EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); - - TRACE("(%p)->()\n", iface); - - This->index = 0; - - return S_OK; -} - -static HRESULT WINAPI EnumMonikerImpl_Clone(LPENUMMONIKER iface, IEnumMoniker ** ppenum) -{ - FIXME("(%p)->(%p): stub\n", iface, ppenum); - - return E_NOTIMPL; -} - -/********************************************************************** - * IEnumMoniker_Vtbl - */ -static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl = -{ - EnumMonikerImpl_QueryInterface, - EnumMonikerImpl_AddRef, - EnumMonikerImpl_Release, - EnumMonikerImpl_Next, - EnumMonikerImpl_Skip, - EnumMonikerImpl_Reset, - EnumMonikerImpl_Clone -}; diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index 69e9ef90e27..78353c00534 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -200,6 +200,140 @@ static HRESULT enum_reg_filters_create(REGFILTER *filters, unsigned int count, I return S_OK; }
+struct enum_moniker +{ + IEnumMoniker IEnumMoniker_iface; + LONG refcount; + + unsigned int index, count; + IMoniker **filters; +}; + +static struct enum_moniker *impl_from_IEnumMoniker(IEnumMoniker *iface) +{ + return CONTAINING_RECORD(iface, struct enum_moniker, IEnumMoniker_iface); +} + +static HRESULT WINAPI enum_moniker_QueryInterface(IEnumMoniker *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumMoniker)) + { + IEnumMoniker_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI enum_moniker_AddRef(IEnumMoniker *iface) +{ + struct enum_moniker *enumerator = impl_from_IEnumMoniker(iface); + ULONG refcount = InterlockedIncrement(&enumerator->refcount); + TRACE("%p increasing refcount to %u.\n", enumerator, refcount); + return refcount; +} + +static ULONG WINAPI enum_moniker_Release(IEnumMoniker *iface) +{ + struct enum_moniker *enumerator = impl_from_IEnumMoniker(iface); + ULONG refcount = InterlockedDecrement(&enumerator->refcount); + unsigned int i; + + TRACE("%p decreasing refcount to %u.\n", enumerator, refcount); + if (!refcount) + { + for (i = 0; i < enumerator->count; ++i) + IMoniker_Release(enumerator->filters[i]); + free(enumerator->filters); + free(enumerator); + } + return refcount; +} + +static HRESULT WINAPI enum_moniker_Next(IEnumMoniker *iface, ULONG count, + IMoniker **filters, ULONG *ret_count) +{ + struct enum_moniker *enumerator = impl_from_IEnumMoniker(iface); + unsigned int i; + + TRACE("iface %p, count %u, filters %p, ret_count %p.\n", iface, count, filters, ret_count); + + for (i = 0; i < count && enumerator->index + i < enumerator->count; ++i) + IMoniker_AddRef(filters[i] = enumerator->filters[enumerator->index + i]); + + enumerator->index += i; + if (ret_count) + *ret_count = i; + return i ? S_OK : S_FALSE; +} + +static HRESULT WINAPI enum_moniker_Skip(IEnumMoniker *iface, ULONG count) +{ + struct enum_moniker *enumerator = impl_from_IEnumMoniker(iface); + + TRACE("iface %p, count %u.\n", iface, count); + + enumerator->index += count; + return S_OK; +} + +static HRESULT WINAPI enum_moniker_Reset(IEnumMoniker *iface) +{ + struct enum_moniker *enumerator = impl_from_IEnumMoniker(iface); + + TRACE("iface %p.\n", iface); + + enumerator->index = 0; + return S_OK; +} + +static HRESULT WINAPI enum_moniker_Clone(IEnumMoniker *iface, IEnumMoniker **out) +{ + TRACE("iface %p, out %p, unimplemented.\n", iface, out); + return E_NOTIMPL; +} + +static const IEnumMonikerVtbl enum_moniker_vtbl = +{ + enum_moniker_QueryInterface, + enum_moniker_AddRef, + enum_moniker_Release, + enum_moniker_Next, + enum_moniker_Skip, + enum_moniker_Reset, + enum_moniker_Clone, +}; + +static HRESULT enum_moniker_create(IMoniker **filters, unsigned int count, IEnumMoniker **out) +{ + struct enum_moniker *object; + + *out = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (!(object->filters = malloc(count * sizeof(*object->filters)))) + { + free(object); + return E_OUTOFMEMORY; + } + memcpy(object->filters, filters, count * sizeof(*filters)); + + object->IEnumMoniker_iface.lpVtbl = &enum_moniker_vtbl; + object->refcount = 1; + object->count = count; + + TRACE("Created enumerator %p.\n", object); + *out = &object->IEnumMoniker_iface; + return S_OK; +} + typedef struct FilterMapper3Impl { IUnknown IUnknown_inner; @@ -1070,7 +1204,7 @@ static HRESULT WINAPI FilterMapper3_EnumMatchingFilters( /* no need to AddRef here as already AddRef'd above */ ppMoniker[i] = ((struct MONIKER_MERIT *)monikers.pData)[i].pMoniker; } - hr = EnumMonikerImpl_Create(ppMoniker, nMonikerCount, ppEnum); + hr = enum_moniker_create(ppMoniker, nMonikerCount, ppEnum); CoTaskMemFree(ppMoniker); }
diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 0f38563e365..de83c2535db 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -79,8 +79,6 @@ HRESULT video_renderer_default_create(IUnknown *outer, IUnknown **out) DECLSPEC_ HRESULT vmr7_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT vmr9_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
-HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) DECLSPEC_HIDDEN; - extern const char * qzdebugstr_guid(const GUID * id) DECLSPEC_HIDDEN; extern void video_unregister_windowclass(void) DECLSPEC_HIDDEN;