Commit 8699661e authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

quartz: Fix FilterGraph2_Connect to be thread-safe and not recurse infinitely.

parent 61ea936d
...@@ -204,6 +204,7 @@ typedef struct _IFilterGraphImpl { ...@@ -204,6 +204,7 @@ typedef struct _IFilterGraphImpl {
LONGLONG start_time; LONGLONG start_time;
LONGLONG position; LONGLONG position;
LONGLONG stop_position; LONGLONG stop_position;
LONG recursioncount;
} IFilterGraphImpl; } IFilterGraphImpl;
static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This, static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
...@@ -898,9 +899,18 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, ...@@ -898,9 +899,18 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
IBaseFilter_Release(PinInfo.pFilter); 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); hr = IPin_QueryDirection(ppinOut, &dir);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto out;
if (dir == PINDIR_INPUT) if (dir == PINDIR_INPUT)
{ {
...@@ -913,42 +923,44 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, ...@@ -913,42 +923,44 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
hr = CheckCircularConnection(This, ppinOut, ppinIn); hr = CheckCircularConnection(This, ppinOut, ppinIn);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto out;
/* Try direct connection first */ /* Try direct connection first */
hr = IPin_Connect(ppinOut, ppinIn, NULL); hr = IPin_Connect(ppinOut, ppinIn, NULL);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr))
return S_OK; goto out;
}
TRACE("Direct connection failed, trying to render using extra filters\n"); TRACE("Direct connection failed, trying to render using extra filters\n");
hr = IPin_QueryPinInfo(ppinIn, &PinInfo); hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto out;
hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID); hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
IBaseFilter_Release(PinInfo.pFilter); IBaseFilter_Release(PinInfo.pFilter);
if (FAILED(hr)) 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 /* 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 */ * filter to the minor mediatype of input pin of the renderer */
hr = IPin_EnumMediaTypes(ppinOut, &penummt); hr = IPin_EnumMediaTypes(ppinOut, &penummt);
if (FAILED(hr)) { if (FAILED(hr))
{
WARN("EnumMediaTypes (%x)\n", hr); WARN("EnumMediaTypes (%x)\n", hr);
return hr; goto out;
} }
hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt); hr = IEnumMediaTypes_Next(penummt, 1, &mt, &nbmt);
if (FAILED(hr)) { if (FAILED(hr)) {
WARN("IEnumMediaTypes_Next (%x)\n", hr); WARN("IEnumMediaTypes_Next (%x)\n", hr);
return hr; goto out;
} }
if (!nbmt) if (!nbmt)
{ {
WARN("No media type found!\n"); WARN("No media type found!\n");
return S_OK; hr = VFW_E_INVALIDMEDIATYPE;
goto out;
} }
TRACE("MajorType %s\n", debugstr_guid(&mt->majortype)); TRACE("MajorType %s\n", debugstr_guid(&mt->majortype));
TRACE("SubType %s\n", debugstr_guid(&mt->subtype)); TRACE("SubType %s\n", debugstr_guid(&mt->subtype));
...@@ -959,7 +971,7 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, ...@@ -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); hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL);
if (FAILED(hr)) { if (FAILED(hr)) {
WARN("Unable to enum filters (%x)\n", hr); WARN("Unable to enum filters (%x)\n", hr);
return hr; goto out;
} }
hr = VFW_E_CANNOT_RENDER; hr = VFW_E_CANNOT_RENDER;
...@@ -1086,6 +1098,9 @@ error: ...@@ -1086,6 +1098,9 @@ error:
IEnumMediaTypes_Release(penummt); IEnumMediaTypes_Release(penummt);
DeleteMediaType(mt); DeleteMediaType(mt);
out:
--This->recursioncount;
LeaveCriticalSection(&This->cs);
TRACE("--> %08x\n", hr); TRACE("--> %08x\n", hr);
return SUCCEEDED(hr) ? S_OK : hr; return SUCCEEDED(hr) ? S_OK : hr;
} }
...@@ -5432,6 +5447,7 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) ...@@ -5432,6 +5447,7 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
fimpl->start_time = fimpl->position = 0; fimpl->start_time = fimpl->position = 0;
fimpl->stop_position = -1; fimpl->stop_position = -1;
fimpl->punkFilterMapper2 = NULL; fimpl->punkFilterMapper2 = NULL;
fimpl->recursioncount = 0;
/* create Filtermapper aggregated. */ /* create Filtermapper aggregated. */
hr = CoCreateInstance(&CLSID_FilterMapper2, pUnkOuter ? pUnkOuter : (IUnknown*)&fimpl->IInner_vtbl, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_FilterMapper2, pUnkOuter ? pUnkOuter : (IUnknown*)&fimpl->IInner_vtbl, CLSCTX_INPROC_SERVER,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment