Mark Walker wrote: > Tim, yes, you're right I should only be interested in single device. > However, all devices fail in that particular loop, including the one I > want. Shouldn't all devices return a good interface anyway? Anyway, > like I said this is not such a big deal right now, but I'd like to > understand what's going on, though. If you bring up graphedt, does your device appear in the "Audio Renderers" list? Are you able to instantiate it there? If so, then your basic process has to work. Graphedt uses exactly the same code. Here, this code works on my XP machine, and prints out IBaseFilter instances for all of my audio devices. C:\tmp>cl amap.cpp /I..\dshow Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. amap.cpp Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:amap.exe amap.obj C:\tmp>amap NVIDIA(R) nForce(TM) Audio 00000000 0085849C Default DirectSound Device 00000000 0085849C Default WaveOut Device 00000000 0085849C DirectSound: NVIDIA(R) nForce(TM) Audio 00000000 0085849C C:\Dev\Videology\sw\i2c>type amap.cpp #include <streams.h> #include <ks.h> #include <atlbase.h> #pragma comment( lib, "strmiids.lib" ) int main( int argc, char ** argv ) { HRESULT hr; CoInitialize(NULL); CComPtr< IBaseFilter > pFilt; // Create an enumerator. CComPtr< ICreateDevEnum > pCreateDevEnum; pCreateDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum ); if( !pCreateDevEnum ) return E_FAIL; // Enumerate the list of audio renderer devices. CComPtr< IEnumMoniker > pEm; pCreateDevEnum->CreateClassEnumerator( CLSID_AudioRendererCategory, &pEm, 0 ); if( !pEm ) return E_FAIL; pEm->Reset( ); // Enumerate through the list and grab the first video capture device. // TODO We should allow connection to multiple devices. while( 1 ) { ULONG ulFetched = 0; CComPtr< IMoniker > pM; hr = pEm->Next( 1, &pM, &ulFetched ); if( FAILED(hr) || !pM ) break; // Get the property bag interface from the moniker. CComPtr< IPropertyBag > pBag; hr = pM->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag ); if( FAILED(hr) ) continue; // Go read the friendly name from the property bag. CComVariant var; var.vt = VT_BSTR; hr = pBag->Read( L"FriendlyName", &var, NULL ); if( FAILED(hr) ) continue; printf( "%S\n", var.bstrVal ); hr = pM->BindToObject( 0, 0, __uuidof(IBaseFilter), (void**) &pFilt ); printf( "%08x %p\n", hr, pFilt ); pFilt.Release(); pM.Release(); pBag.Release(); } pEm.Release(); pCreateDevEnum.Release(); return 0; } C:\tmp> -- Tim Roberts, timr@xxxxxxxxx Providenza & Boekelheide, Inc.