//Возвращает информацию о фильтре 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; }