Hi,
I have build a application which enumerates all the audio devices installed in the system and searches for a particular PnP audio output device. To provide this feature I make use of 'DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA' data structure. I populate this data structure and register it with dsound.dll.
As a result of it a callback registered by me is invoked depending upon the number of audio devices present in the system.
This approach is working perfectly find in Window's XP and 2K. But on Windows Vista (32 bit) I am facing some unique problems. Though there are 2 audio devices present in my system but sometimes the callback registered is invoked just once. Hence I loss the other device.
What may be the reason for this
Following are the details of my development environment:
* Operating System: Microsoft Vista Ultimate 32 bit
* OS Version: 6.06.6000 Build 6000 (Ready to Market build)
* Microsoft Visual Studio 8 2005
* Microsoft DirectX SDK (October 2006)
The following is the code snippet being used:
/* Function Name - pollAudioDevices
*
* In
* - none.
*
* Out - none
*
* Return Value - none
*
* Purpose - To poll the system audio devices and update
* the data structures for the changes.
*/
void pollAudioDevices()
{
HMODULE hDS;
IKsPropertySet *pIKSPS;
IClassFactory *pICF;
LPFNGETCLASSOBJECT pFNGCO;
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA dsdsded;
// gain access to DirectSound
if (!(hDS = LoadLibrary(_T("dsound.dll"))))
{
LOGDUMP(_T(" DSOUND.DLL loading failed "));
return;
}
// get the DllGetClassObject function pointer
if (!(pFNGCO = (LPFNGETCLASSOBJECT)(GetProcAddress(hDS,"DllGetClassObject"))))
{
LOGDUMP(_T(" DllGetClassObject operation failed "));
return;
}
// now use it to get the DirectSoundPrivate class factory interface
pFNGCO(CLSID_DirectSoundPrivate, IID_IClassFactory, (void **) (&pICF));
if (!pICF)
{
LOGDUMP(_T(" DirectSoundPrivate operation failed "));
return;
}
// use the class factory to create a property set
pICF->CreateInstance(0, IID_IKsPropertySet, (void **) (&pIKSPS));
if (!pIKSPS)
{
LOGDUMP(_T(" class factory to create a property set operation failed "));
return;
}
// now we can use that interface to enumerate
dsdsded.Callback = AudioDevDataCallback; // Callback
dsdsded.Context = NULL;
DWORD dwLen = 0;
IKsPropertySet_Get(pIKSPS, DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE, 0, 0, (void *) (&dsdsded), sizeof(dsdsded), &dwLen);
// Clean up
pIKSPS->Release();
pICF->Release();
FreeLibrary(hDS);
}
/* Function Name - AudioDevDataCallback
*
* In
* pdsdd - Pointer to structure containing description of the Audio device.
* pv - Context pointer.
*
* Out - none
*
* Return Value - next device info needed or not.
*
* Purpose - This function is called back by the system for each Audio device available.
*/
BOOL CALLBACK AudioDevDataCallback(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA *pdsdd, void *pv)
{
if((pdsdd->Type == DIRECTSOUNDDEVICE_TYPE_VXD)
||(pdsdd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE))
return TRUE;
if(pdsdd->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED)
{
return TRUE;
}
_TCHAR str_xp[] =_T("Vid_046d&Pid_0a08");
_TCHAR str_vista[] =_T("VID_046D&PID_0A08");
// Vista related change
// check for our Plug n Play Audio Output Device.
if(((_tcsstr (pdsdd->Interface,str_xp))!=NULL)||((_tcsstr (pdsdd->Interface,str_vista))!=NULL))
{
g_AudioDeviceName = pdsdd->Description;
}
return TRUE;
}

Audio Device Enumeration inconsistent in Vista
ITsAlive