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