System Device Enumerator
Wether you locating for a particular filter or want to enumerate all the filters on a system. The System Device Enumerator is a big help. Enumeration of DirectShow filters can be achieved with the help of System Device Enumerator. It is COM object. which expose ICreateDevEnum interface. It means first you have to create the System Device Enumerator object, then you will grab its interface ICreateDevEnum , this interface exposes just one method CreateClassEnumerator this method actually creates enumerator, which can be used to enumerate the filters in a specific Filter Category, or can be used to enumerate all the Filter Categories on a users system.
Filter Categories
Filter in DirectShow are divided in the categories . Every category has its own class identifier called a CLSID. With the help of this CLSID it is easy to enumerate the filters of that specific class.
But first of all how to enumerate those categories, for this purpose there is a CLSID_ActiveMovieCategories CLSID. With it one can easily enumerate the categories which has filters in them.
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum,
NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr))
{
return hr;
}
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(
(GUID)CLSID_ActiveMovieCategories, &pEnumCat, 0);
if (hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker = NULL;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if (SUCCEEDED(hr))
{
VARIANT varName, varCLSID;
VariantInit(&varName);
VariantInit(&varCLSID);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
hr = pPropBag->Read(L"CLSID", &varCLSID, 0);
if (SUCCEEDED(hr))
{
GUID clsid;
if (SUCCEEDED(CLSIDFromString(varCLSID.bstrVal,
&clsid)))
{
EnumFilters(clsid, hparent);
this snippet of code shows how to enumerate all the filter categories. Now you have all the filter categories it is time to enumerate the filters in those filter categories.
bool CEnumFiltersDlg::EnumFilters(GUID clsid, HTREEITEM hparent) { // Create the System Device Enumerator. HRESULT hr; ICreateDevEnum *pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum,
NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr))
{
return hr;
}
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator((GUID)clsid, &pEnumCat, 0);
if (hr == S_OK)
{
IMoniker *pMoniker = NULL;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if (SUCCEEDED(hr))
{
// To retrieve the filter's friendly name, do the following:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
// Display the name in your UI somehow.
TVINSERTSTRUCT tvInsert;
tvInsert.hParent = hparent;
tvInsert.hInsertAfter = NULL;
tvInsert.item.mask = TVIF_TEXT;
CString str(varName.bstrVal);
tvInsert.item.pszText = str.GetBuffer();
str.ReleaseBuffer();
mFiltersTree.InsertItem(&tvInsert);
}
VariantClear(&varName);
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
mFiltersTree.SortChildren(hparent);
return true;
}
Here clsid parameter passed is the CLSID of the filter category whom to enumerate.
NOTE
this sample don’t enumerate the DMOs on a system as the Graph Edit utility enumerates in its insert filter function. I will try to add it later.