Andrew Nguyen : dxdiagn: Add code that populates the DxDiag_DirectShowFilters container.
Alexandre Julliard
julliard at winehq.org
Tue Feb 15 11:29:26 CST 2011
Module: wine
Branch: master
Commit: 5ae57265c59a35931cf055876ec44e87ab11dcfd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5ae57265c59a35931cf055876ec44e87ab11dcfd
Author: Andrew Nguyen <anguyen at codeweavers.com>
Date: Tue Feb 15 01:14:53 2011 -0600
dxdiagn: Add code that populates the DxDiag_DirectShowFilters container.
---
dlls/dxdiagn/provider.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 270 insertions(+), 1 deletions(-)
diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c
index c61555e..5eafefd 100644
--- a/dlls/dxdiagn/provider.c
+++ b/dlls/dxdiagn/provider.c
@@ -1417,11 +1417,280 @@ static HRESULT build_directxfiles_tree(IDxDiagContainerImpl_Container *node)
return S_OK;
}
-static HRESULT build_directshowfilters_tree(IDxDiagContainerImpl_Container *node)
+static HRESULT read_property_names(IPropertyBag *pPropBag, VARIANT *friendly_name, VARIANT *clsid_name)
{
+ static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
+ static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
+
+ HRESULT hr;
+
+ VariantInit(friendly_name);
+ VariantInit(clsid_name);
+
+ hr = IPropertyBag_Read(pPropBag, wszFriendlyName, friendly_name, 0);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IPropertyBag_Read(pPropBag, wszClsidName, clsid_name, 0);
+ if (FAILED(hr))
+ {
+ VariantClear(friendly_name);
+ return hr;
+ }
+
return S_OK;
}
+static HRESULT fill_filter_data_information(IDxDiagContainerImpl_Container *subcont, BYTE *pData, ULONG cb)
+{
+ static const WCHAR szVersionW[] = {'s','z','V','e','r','s','i','o','n',0};
+ static const WCHAR dwInputs[] = {'d','w','I','n','p','u','t','s',0};
+ static const WCHAR dwOutputs[] = {'d','w','O','u','t','p','u','t','s',0};
+ static const WCHAR dwMeritW[] = {'d','w','M','e','r','i','t',0};
+ static const WCHAR szVersionFormat[] = {'v','%','d',0};
+
+ HRESULT hr;
+ IFilterMapper2 *pFileMapper = NULL;
+ IAMFilterData *pFilterData = NULL;
+ REGFILTER2 *pRF = NULL;
+ WCHAR bufferW[10];
+ ULONG j;
+ DWORD dwNOutputs = 0;
+ DWORD dwNInputs = 0;
+
+ hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper2,
+ (void **)&pFileMapper);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IFilterMapper2_QueryInterface(pFileMapper, &IID_IAMFilterData, (void **)&pFilterData);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = IAMFilterData_ParseFilterData(pFilterData, pData, cb, (BYTE **)&pRF);
+ if (FAILED(hr))
+ goto cleanup;
+
+ snprintfW(bufferW, sizeof(bufferW)/sizeof(bufferW[0]), szVersionFormat, pRF->dwVersion);
+ hr = add_bstr_property(subcont, szVersionW, bufferW);
+ if (FAILED(hr))
+ goto cleanup;
+
+ if (pRF->dwVersion == 1)
+ {
+ for (j = 0; j < pRF->u.s.cPins; j++)
+ if (pRF->u.s.rgPins[j].bOutput)
+ dwNOutputs++;
+ else
+ dwNInputs++;
+ }
+ else if (pRF->dwVersion == 2)
+ {
+ for (j = 0; j < pRF->u.s1.cPins2; j++)
+ if (pRF->u.s1.rgPins2[j].dwFlags & REG_PINFLAG_B_OUTPUT)
+ dwNOutputs++;
+ else
+ dwNInputs++;
+ }
+
+ hr = add_ui4_property(subcont, dwInputs, dwNInputs);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = add_ui4_property(subcont, dwOutputs, dwNOutputs);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = add_ui4_property(subcont, dwMeritW, pRF->dwMerit);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = S_OK;
+cleanup:
+ CoTaskMemFree(pRF);
+ if (pFilterData) IAMFilterData_Release(pFilterData);
+ if (pFileMapper) IFilterMapper2_Release(pFileMapper);
+
+ return hr;
+}
+
+static HRESULT fill_filter_container(IDxDiagContainerImpl_Container *subcont, IMoniker *pMoniker)
+{
+ static const WCHAR szName[] = {'s','z','N','a','m','e',0};
+ static const WCHAR ClsidFilterW[] = {'C','l','s','i','d','F','i','l','t','e','r',0};
+ static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
+
+ HRESULT hr;
+ IPropertyBag *pPropFilterBag = NULL;
+ BYTE *pData;
+ VARIANT friendly_name;
+ VARIANT clsid_name;
+ VARIANT v;
+
+ VariantInit(&friendly_name);
+ VariantInit(&clsid_name);
+ VariantInit(&v);
+
+ hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (void **)&pPropFilterBag);
+ if (FAILED(hr))
+ return hr;
+
+ hr = read_property_names(pPropFilterBag, &friendly_name, &clsid_name);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = add_bstr_property(subcont, szName, V_BSTR(&friendly_name));
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = add_bstr_property(subcont, ClsidFilterW, V_BSTR(&clsid_name));
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = IPropertyBag_Read(pPropFilterBag, wszFilterDataName, &v, NULL);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = SafeArrayAccessData(V_ARRAY(&v), (void **)&pData);
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = fill_filter_data_information(subcont, pData, V_ARRAY(&v)->rgsabound->cElements);
+ SafeArrayUnaccessData(V_ARRAY(&v));
+ if (FAILED(hr))
+ goto cleanup;
+
+ hr = S_OK;
+cleanup:
+ VariantClear(&v);
+ VariantClear(&clsid_name);
+ VariantClear(&friendly_name);
+ if (pPropFilterBag) IPropertyBag_Release(pPropFilterBag);
+
+ return hr;
+}
+
+static HRESULT build_directshowfilters_tree(IDxDiagContainerImpl_Container *node)
+{
+ static const WCHAR szCatName[] = {'s','z','C','a','t','N','a','m','e',0};
+ static const WCHAR ClsidCatW[] = {'C','l','s','i','d','C','a','t',0};
+ static const WCHAR szIdFormat[] = {'%','d',0};
+
+ HRESULT hr;
+ int i = 0;
+ ICreateDevEnum *pCreateDevEnum;
+ IEnumMoniker *pEmCat = NULL;
+ IMoniker *pMCat = NULL;
+ IEnumMoniker *pEnum = NULL;
+
+ hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ICreateDevEnum, (void **)&pCreateDevEnum);
+ if (FAILED(hr))
+ return hr;
+
+ hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEmCat, 0);
+ if (FAILED(hr))
+ goto cleanup;
+
+ while (IEnumMoniker_Next(pEmCat, 1, &pMCat, NULL) == S_OK)
+ {
+ VARIANT vCatName;
+ VARIANT vCatClsid;
+ IPropertyBag *pPropBag;
+ CLSID clsidCat;
+ IMoniker *pMoniker = NULL;
+
+ hr = IMoniker_BindToStorage(pMCat, NULL, NULL, &IID_IPropertyBag, (void **)&pPropBag);
+ if (FAILED(hr))
+ {
+ IMoniker_Release(pMCat);
+ break;
+ }
+
+ hr = read_property_names(pPropBag, &vCatName, &vCatClsid);
+ IPropertyBag_Release(pPropBag);
+ if (FAILED(hr))
+ {
+ IMoniker_Release(pMCat);
+ break;
+ }
+
+ hr = CLSIDFromString(V_BSTR(&vCatClsid), &clsidCat);
+ if (FAILED(hr))
+ {
+ IMoniker_Release(pMCat);
+ VariantClear(&vCatClsid);
+ VariantClear(&vCatName);
+ break;
+ }
+
+ hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0);
+ if (hr != S_OK)
+ {
+ IMoniker_Release(pMCat);
+ VariantClear(&vCatClsid);
+ VariantClear(&vCatName);
+ continue;
+ }
+
+ while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK)
+ {
+ WCHAR bufferW[10];
+ IDxDiagContainerImpl_Container *subcont;
+
+ snprintfW(bufferW, sizeof(bufferW)/sizeof(bufferW[0]), szIdFormat, i);
+ subcont = allocate_information_node(bufferW);
+ if (!subcont)
+ {
+ hr = E_OUTOFMEMORY;
+ IMoniker_Release(pMoniker);
+ break;
+ }
+
+ hr = add_bstr_property(subcont, szCatName, V_BSTR(&vCatName));
+ if (FAILED(hr))
+ {
+ free_information_tree(subcont);
+ IMoniker_Release(pMoniker);
+ break;
+ }
+
+ hr = add_bstr_property(subcont, ClsidCatW, V_BSTR(&vCatClsid));
+ if (FAILED(hr))
+ {
+ free_information_tree(subcont);
+ IMoniker_Release(pMoniker);
+ break;
+ }
+
+ hr = fill_filter_container(subcont, pMoniker);
+ if (FAILED(hr))
+ {
+ free_information_tree(subcont);
+ IMoniker_Release(pMoniker);
+ break;
+ }
+
+ add_subcontainer(node, subcont);
+ i++;
+ IMoniker_Release(pMoniker);
+ }
+
+ IEnumMoniker_Release(pEnum);
+ IMoniker_Release(pMCat);
+ VariantClear(&vCatClsid);
+ VariantClear(&vCatName);
+
+ if (FAILED(hr))
+ break;
+ }
+
+cleanup:
+ if (pEmCat) IEnumMoniker_Release(pEmCat);
+ ICreateDevEnum_Release(pCreateDevEnum);
+ return hr;
+}
+
static HRESULT build_logicaldisks_tree(IDxDiagContainerImpl_Container *node)
{
return S_OK;
More information about the wine-cvs
mailing list