Maarten Lankhorst : quartz: Fix FilterGraph2_Connect to be thread-safe and not recurse infinitely.
Alexandre Julliard
julliard at winehq.org
Mon Nov 17 09:14:18 CST 2008
Module: wine
Branch: master
Commit: 8699661e969fb966da937fcb4be2163dbcbe7327
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8699661e969fb966da937fcb4be2163dbcbe7327
Author: Maarten Lankhorst <maarten at codeweavers.com>
Date: Fri Nov 14 16:42:41 2008 +0100
quartz: Fix FilterGraph2_Connect to be thread-safe and not recurse infinitely.
---
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 7b773ef..c53771e 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,
@@ -898,9 +899,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)
{
@@ -913,42 +923,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));
@@ -959,7 +971,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;
@@ -1086,6 +1098,9 @@ error:
IEnumMediaTypes_Release(penummt);
DeleteMediaType(mt);
+out:
+ --This->recursioncount;
+ LeaveCriticalSection(&This->cs);
TRACE("--> %08x\n", hr);
return SUCCEEDED(hr) ? S_OK : hr;
}
@@ -5432,6 +5447,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,
More information about the wine-cvs
mailing list