[PATCH] quartz: Fix FilterGraph2_Connect to be thread-safe and not recurse infinitely any more
Maarten Lankhorst
maarten at codeweavers.com
Fri Nov 14 09:42:41 CST 2008
---
dlls/quartz/filtergraph.c | 40 ++++++++++++++++++++++++++++------------
1 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index eec0e44..5b23ab2 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -204,6 +204,7 @@ typedef struct _IFilterGraphImpl {
LONGLONG start_time;
LONGLONG position;
LONGLONG stop_position;
+ LONG recursioncount;
} IFilterGraphImpl;
static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
@@ -895,9 +896,18 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
IBaseFilter_Release(PinInfo.pFilter);
}
+ EnterCriticalSection(&This->cs);
+ ++This->recursioncount;
+ if (This->recursioncount >= 5)
+ {
+ WARN("Recursion count has reached %d\n", This->recursioncount);
+ hr = VFW_E_CANNOT_CONNECT;
+ goto out;
+ }
+
hr = IPin_QueryDirection(ppinOut, &dir);
if (FAILED(hr))
- return hr;
+ goto out;
if (dir == PINDIR_INPUT)
{
@@ -910,42 +920,44 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
hr = CheckCircularConnection(This, ppinOut, ppinIn);
if (FAILED(hr))
- return hr;
+ goto out;
/* Try direct connection first */
hr = IPin_Connect(ppinOut, ppinIn, NULL);
- if (SUCCEEDED(hr)) {
- return S_OK;
- }
+ if (SUCCEEDED(hr))
+ goto out;
+
TRACE("Direct connection failed, trying to render using extra filters\n");
hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
if (FAILED(hr))
- return hr;
+ goto out;
hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
IBaseFilter_Release(PinInfo.pFilter);
if (FAILED(hr))
- return hr;
+ goto out;
/* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
* filter to the minor mediatype of input pin of the renderer */
hr = IPin_EnumMediaTypes(ppinOut, &penummt);
- if (FAILED(hr)) {
+ if (FAILED(hr))
+ {
WARN("EnumMediaTypes (%x)\n", hr);
- return hr;
+ goto out;
}
hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
if (FAILED(hr)) {
WARN("IEnumMediaTypes_Next (%x)\n", hr);
- return hr;
+ goto out;
}
if (!nbmt)
{
WARN("No media type found!\n");
- return S_OK;
+ hr = VFW_E_INVALIDMEDIATYPE;
+ goto out;
}
TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
@@ -956,7 +968,7 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
if (FAILED(hr)) {
WARN("Unable to enum filters (%x)\n", hr);
- return hr;
+ goto out;
}
hr = VFW_E_CANNOT_RENDER;
@@ -1083,6 +1095,9 @@ error:
IEnumMediaTypes_Release(penummt);
DeleteMediaType(mt);
+out:
+ --This->recursioncount;
+ LeaveCriticalSection(&This->cs);
TRACE("--> %08x\n", hr);
return SUCCEEDED(hr) ? S_OK : hr;
}
@@ -5429,6 +5444,7 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
fimpl->start_time = fimpl->position = 0;
fimpl->stop_position = -1;
fimpl->punkFilterMapper2 = NULL;
+ fimpl->recursioncount = 0;
/* create Filtermapper aggregated. */
hr = CoCreateInstance(&CLSID_FilterMapper2, pUnkOuter ? pUnkOuter : (IUnknown*)&fimpl->IInner_vtbl, CLSCTX_INPROC_SERVER,
--
1.5.6.5
--------------060200030508050908050507--
More information about the wine-patches
mailing list