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