示例#1
0
//Возвращает информацию о фильтре DirectShow
//Перед вызовом этой функции необходимо вызвать UpdateDSFiltersArray(...) (если она не вызывалась)
//В случае ошибки функция вернет значение меньше нуля
int CDirectShow::GetDSFilterInfo(LPCWSTR lpwDSFilName, DSFILTERINFO *pDSFI)
{
	if (!m_pGraphBuilder) return -1;
	if (!m_lDSFilCount) return -1;
	IPropertyBag *pPropBag = NULL;
	VARIANT varDSFName = { 0 }, varDSFCLSID = { 0 }, varDSFData = { 0 };
	varDSFName.vt = VT_BSTR;
	varDSFCLSID.vt = VT_BSTR;
	varDSFData.vt = (VT_UI1 | VT_ARRAY);
	for (m_lCounter = 0; m_lCounter < m_lDSFilCount; m_lCounter++)
	{
		m_pDSFMoniker[m_lCounter]->BindToStorage(NULL, NULL, IID_IPropertyBag, (LPVOID *)&pPropBag);
		if (FAILED(pPropBag->Read(L"FriendlyName", &varDSFName, NULL)))
		{
			if (m_lCounter >= (m_lDSFilCount - 1))
			{
				pPropBag->Release();
				return -1;
			} else continue;
		}
		if (_wcsicmp(lpwDSFilName, varDSFName.bstrVal) == 0)
		{
			if(SUCCEEDED(pPropBag->Read(L"CLSID", &varDSFCLSID, NULL)))
			{
				CLSIDFromString(varDSFCLSID.bstrVal, &pDSFI->cCLSID);
				SysFreeString(varDSFCLSID.bstrVal);
			}
			else
			{
				ZeroMemory(&pDSFI->cCLSID, sizeof(pDSFI->cCLSID));
			}
			if(SUCCEEDED(pPropBag->Read(L"FilterData", &varDSFData, NULL)))
			{
				BSTR *bstrData = NULL;
				LPBYTE pData = NULL;
				IAMFilterData *pFilterData = NULL;
				SafeArrayAccessData(varDSFData.parray, (LPVOID *)&bstrData);
				CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC, __uuidof(IAMFilterData),
					(LPVOID *)&pFilterData);
				if (SUCCEEDED(pFilterData->ParseFilterData((LPBYTE)bstrData,
					varDSFData.parray->cbElements * varDSFData.parray->rgsabound[0].cElements, &pData)))
				{
					REGFILTER2 *pRF2 = (REGFILTER2 *)*((DWORD *)pData);
					pDSFI->dwMerit = pRF2->dwMerit;
					CoTaskMemFree(pRF2);
				}
				SR(pFilterData);
			}
			else
			{
				pDSFI->dwMerit = 0;
				//Обнуление остальных членов структуры
			}
			SysFreeString(varDSFName.bstrVal);
			pPropBag->Release();
			break;
		}
		else
		{
			if (m_lCounter >= (m_lDSFilCount - 1))
			{
				SysFreeString(varDSFName.bstrVal);
				pPropBag->Release();
				return -1;
			}
		}
		SysFreeString(varDSFName.bstrVal);
		pPropBag->Release();
	}
	return 0;
}
// Read merit and version information
HRESULT MainDialog::GetMerit(IPropertyBag *pPropBag, DWORD *pdwMerit)
{
    HRESULT hr;
    IAMFilterData *pData = NULL;

    VARIANT varFilData={0};
    varFilData.vt = VT_UI1 | VT_ARRAY;
    varFilData.parray = 0;     // docs say to zero this

    BYTE *pbFilterData = 0;    // 0 if not read
    DWORD dwcbFilterDAta = 0;  // 0 if not read

    // Read compressed filter data from the property bag with a variant
    hr = pPropBag->Read(L"FilterData", &varFilData, 0);
    if (SUCCEEDED(hr))
    {
        assert(varFilData.vt == (VT_UI1 | VT_ARRAY));
        dwcbFilterDAta = varFilData.parray->rgsabound[0].cElements;

        // Access the filter data
        hr = SafeArrayAccessData(varFilData.parray, (void **)&pbFilterData);
    }

    // Get the IAMFilterData interface for parsing the filter data
	if (SUCCEEDED(hr))
	{
	    hr = m_pMapper->QueryInterface(__uuidof(IAMFilterData), (void **)&pData);
	}

    if (SUCCEEDED(hr))
    {
        BYTE *pb=0;

        // Use a helper method to parse the binary filter data.  Pass in
        // the pointer to the filter data, its size, and a buffer to fill with
        // the resulting data.  The "pb" buffer is allocated with CoTaskMemAlloc,
        // so it must be correspondingly freed by the caller.
        hr = pData->ParseFilterData(pbFilterData, dwcbFilterDAta, &pb);
        if(SUCCEEDED(hr))
        {
            REGFILTER2 *pFil = ((REGFILTER2 **)pb)[0];


            // Assign the merit value from the REGFILTER2 structure
            if (pFil)
			{
                *pdwMerit = pFil->dwMerit;

                 // Free the memory allocated by ParseFilterData
                 CoTaskMemFree(pFil);
			}
        }
    }

	if (pbFilterData)
	{
		SafeArrayUnaccessData(varFilData.parray);
		VariantClear(&varFilData);
	}

	// Release the IAMFilterData interface
	SAFE_RELEASE(pData);

    return hr;
}