Piotr Caban : qcap: Don' t ignore type and category parameters in ICaptureGraphBuilder2::FindPin.
Alexandre Julliard
julliard at winehq.org
Wed Nov 20 13:38:56 CST 2013
Module: wine
Branch: master
Commit: 4adcca84f059ecb4a42c84b578560f11fe6f63c4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4adcca84f059ecb4a42c84b578560f11fe6f63c4
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed Nov 20 12:01:27 2013 +0100
qcap: Don't ignore type and category parameters in ICaptureGraphBuilder2::FindPin.
---
dlls/qcap/capturegraph.c | 90 +++++++++++++++++++++++++++++++++++----------
1 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/dlls/qcap/capturegraph.c b/dlls/qcap/capturegraph.c
index a852b61..5af4f3b 100644
--- a/dlls/qcap/capturegraph.c
+++ b/dlls/qcap/capturegraph.c
@@ -368,31 +368,73 @@ fnCaptureGraphBuilder2_CopyCaptureFile(ICaptureGraphBuilder2 * iface,
return E_NOTIMPL;
}
-static BOOL pin_matches(IPin *pin, PIN_DIRECTION direction, const GUID *cat, const GUID *type, BOOL unconnected)
+static HRESULT pin_matches(IPin *pin, PIN_DIRECTION direction, const GUID *cat, const GUID *type, BOOL unconnected)
{
IPin *partner;
PIN_DIRECTION pindir;
+ HRESULT hr;
- IPin_QueryDirection(pin, &pindir);
- if (pindir != direction)
- {
- TRACE("No match, wrong direction\n");
- return FALSE;
- }
+ hr = IPin_QueryDirection(pin, &pindir);
- if (unconnected && IPin_ConnectedTo(pin, &partner) == S_OK)
+ if (unconnected && IPin_ConnectedTo(pin, &partner) == S_OK && partner!=NULL)
{
IPin_Release(partner);
TRACE("No match, %p already connected to %p\n", pin, partner);
- return FALSE;
+ return FAILED(hr) ? hr : S_FALSE;
}
- if (cat || type)
- FIXME("Ignoring category/type\n");
+ if (FAILED(hr))
+ return hr;
+ if (SUCCEEDED(hr) && pindir != direction)
+ return S_FALSE;
+
+ if (cat)
+ {
+ IKsPropertySet *props;
+ GUID category;
+ DWORD fetched;
+
+ hr = IPin_QueryInterface(pin, &IID_IKsPropertySet, (void**)&props);
+ if (FAILED(hr))
+ return S_FALSE;
- TRACE("Match made in heaven\n");
+ hr = IKsPropertySet_Get(props, &ROPSETID_Pin, 0, NULL,
+ 0, &category, sizeof(category), &fetched);
+ IKsPropertySet_Release(props);
+ if (FAILED(hr) || !IsEqualIID(&category, cat))
+ return S_FALSE;
+ }
+
+ if (type)
+ {
+ IEnumMediaTypes *types;
+ AM_MEDIA_TYPE *media_type;
+ ULONG fetched;
+
+ hr = IPin_EnumMediaTypes(pin, &types);
+ if (FAILED(hr))
+ return S_FALSE;
+
+ IEnumMediaTypes_Reset(types);
+ while (1) {
+ if (IEnumMediaTypes_Next(types, 1, &media_type, &fetched) != S_OK || fetched != 1)
+ {
+ IEnumMediaTypes_Release(types);
+ return S_FALSE;
+ }
- return TRUE;
+ if (IsEqualIID(&media_type->majortype, type))
+ {
+ DeleteMediaType(media_type);
+ break;
+ }
+ DeleteMediaType(media_type);
+ }
+ IEnumMediaTypes_Release(types);
+ }
+
+ TRACE("Pin matched\n");
+ return S_OK;
}
static HRESULT WINAPI
@@ -426,7 +468,7 @@ fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface,
if (hr == E_NOINTERFACE)
{
WARN("Input not filter or pin?!\n");
- return E_FAIL;
+ return E_NOINTERFACE;
}
hr = IBaseFilter_EnumPins(filter, &enumpins);
@@ -436,11 +478,11 @@ fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface,
return hr;
}
- IEnumPins_Reset(enumpins);
-
while (1)
{
- hr = IEnumPins_Next(enumpins, 1, &pin, NULL);
+ ULONG fetched;
+
+ hr = IEnumPins_Next(enumpins, 1, &pin, &fetched);
if (hr == VFW_E_ENUM_OUT_OF_SYNC)
{
numcurrent = 0;
@@ -448,14 +490,22 @@ fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface,
pin = NULL;
continue;
}
-
if (hr != S_OK)
break;
+ if (fetched != 1)
+ {
+ hr = E_FAIL;
+ break;
+ }
+
TRACE("Testing match\n");
- if (pin_matches(pin, pindir, pCategory, pType, fUnconnected) && numcurrent++ == num)
+ hr = pin_matches(pin, pindir, pCategory, pType, fUnconnected);
+ if (hr == S_OK && numcurrent++ == num)
break;
IPin_Release(pin);
pin = NULL;
+ if (FAILED(hr))
+ break;
}
IEnumPins_Release(enumpins);
@@ -465,7 +515,7 @@ fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface,
return E_FAIL;
}
}
- else if (!pin_matches(pin, pindir, pCategory, pType, fUnconnected))
+ else if (pin_matches(pin, pindir, pCategory, pType, fUnconnected) != S_OK)
{
IPin_Release(pin);
return E_FAIL;
More information about the wine-cvs
mailing list