[wdmaudiodev] Re: Device Enumeration again ...

  • From: "Jerry Evans" <jerry@xxxxxxxxxx>
  • To: <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Mon, 7 Apr 2003 18:02:45 +0100

Thanks Mitch.

I'll do that.

----- Original Message -----
From: "Mitchell Rundle" <mitchr@xxxxxxxxxxxxx>
To: <wdmaudiodev@xxxxxxxxxxxxx>
Sent: Monday, April 07, 2003 5:28 PM
Subject: [wdmaudiodev] Re: Device Enumeration again ...


>
> Most "wave" and USB audio filters register under KSCATEGORY_AUDIO,
> .._RENDER, and .._CAPTURE.  i.e. you don't normally see separate render
> and capture filters for a given device.
>
> To make this crystal clear, run ksstudio and set it to enumerate
> KSCATEGORY_AUDIO.  You can expand the enumerated filters in the left
> pane see see what categories they are aliased under.
>
> Mitch Rundle
> Microsoft
>
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
> -----Original Message-----
> From: Jerry Evans [mailto:jerry@xxxxxxxxxx]=20
> Sent: Sunday, April 06, 2003 8:15 AM
> To: wdmaudiodev@xxxxxxxxxxxxx
> Subject: [wdmaudiodev] Device Enumeration again ...
>
>
> Hi all.
>
> I'm now getting much more detail about the various devices installed in
> the system.  However my enumerator has (I think) got a problem with
> distinguishing between KSCATEGORY_RENDER and KSCATEGORY_CAPTURE
> categories. It would appear to be getting _all_ entries for the
> KSCATEGORY_AUDIO hive.
>
> It is worth noting I have also tried querying the registry using this:
>
> SetupDiGetDeviceRegistryProperty(hDevInfo,&DevInfoData,SPDRP_DEVTYPE,NUL
> L,(P
> BYTE)&dw,sizeof(dw),&reqSize);
>
> The theory here being that the enumerations indicate unambiguously what
> type of device we have. The MSDN link is
> http://msdn.microsoft.com/library/default.asp?url=3D/library/en-us/kmarch=
> /
> hh/k
> march/devobjts_5hnr.asp Howver this fails with GetLastError() returning
> an 'invalid data' message.
>
> I have taken the liberty of attaching the relevant C++ class which is
> reasonably well commented. If anyone would care to comment on why the
> enumeration returns both Capture AND Render devices I would be
> delighted. It should only require a #include to an existing project with
> a call as shown in the header comments.
>
>
> TVMIA
>
> Jerry
>
>
> -- Attached file included as plaintext by Ecartis --
> -- File: DEVENUM2.H
>
> /*
>
> KS device enumerator
> =09
> Sample usage:
> =09
> Chordia::CDeviceEnumerator enumerator;
> std::vector<Chordia::CDeviceDescriptor> ipnames;
> std::vector<Chordia::CDeviceDescriptor> opnames;
> // do the enumeration for AUDIO + CAPTURE devices only
> if
> (enumerator.enumerate(KSCATEGORY_AUDIO,KSCATEGORY_CAPTURE,ipnames) > 0)
> {
> for (std::vector<Chordia::CDeviceDescriptor>::iterator
> it =3D ipnames.begin();
> it !=3D ipnames.end();
> ++it)
> {
> // stuff ....
> }
> }
>
> STATIC_KSCATEGORY_AUDIO
> STATIC_KSCATEGORY_RENDER
> STATIC_KSCATEGORY_CAPTURE
>
> (C) Jerry Evans 2003
> =09
> jerry_ks@xxxxxxxxxxxxx
> =09
> Permisssion to redistribute granted for source and binary
> formats.
> Please do not modify any of this comment block
> =09
> */
>
>
> //----------------------------------------------------------------------
> -------
> // auto-include relevant libraries
> //----------------------------------------------------------------------
> -------
>
> #include <Setupapi.h>
>
> #pragma comment( lib, "setupapi.lib")
>
> //----------------------------------------------------------------------
> -------
> //----------------------------------------------------------------------
> -------
>
> namespace Chordia
> {
>
> class CDeviceDescriptor
> {
> public:
> =09
> std::string m_handle;
> std::string m_description;
> std::string m_name;
> std::string m_manufacturer;
> UINT m_id;
> =09
> CDeviceDescriptor() { m_id =3D 0;}
> =09
> CDeviceDescriptor(const CDeviceDescriptor& arg)
> {
> m_id =3D arg.m_id;
> m_handle =3D arg.m_handle;
> m_description =3D arg.m_description;
> m_name =3D arg.m_name;
> m_manufacturer =3D arg.m_manufacturer;
> }
> =09
> CDeviceDescriptor& operator=3D(const CDeviceDescriptor& arg)
> {
> m_id =3D arg.m_id;
> m_handle =3D arg.m_handle;
> m_description =3D arg.m_description;
> m_name =3D arg.m_name;
> m_manufacturer =3D arg.m_manufacturer;
> return (*this);=09
> }
> };
>
> //----------------------------------------------------------------------
> -------
> // Enumerate kernel devices and return internal handle name and
> descriptions
> //----------------------------------------------------------------------
> -------
>
> class CDeviceEnumerator
> {
> public:
> =09
> CDeviceEnumerator() {}
> =09
> // enumerate names of devices matching GUIDS
> // size_t enumerate(IN const GUID category, IN const
> std::vector<GUID>& guids, OUT std::vector<CDeviceDescriptor>& descs)
> //=20
> size_t enumerate(IN const GUID category, IN const GUID& mode,
> OUT std::vector<CDeviceDescriptor>& descs)
> {
> std::map<std::string,UINT> id_map;
> // Get a handle to the device set specified by the guid
> HDEVINFO hDevInfo =3D SetupDiGetClassDevs(&category,=20
> =09
> NULL,=20
> =09
> NULL,=20
> =09
> DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
> // failure ?
>
> if (hDevInfo =3D=3D INVALID_HANDLE_VALUE)
> {
> return 0;
> }
> //
> DWORD index =3D 0;
> // Loop through members of the set and get details for
> each
> while (true)
> {
> SP_DEVICE_INTERFACE_DATA            DID;
> SP_DEVICE_INTERFACE_DATA            DIDAlias;
> SP_DEVINFO_DATA                     DevInfoData;
>
> DID.cbSize =3D sizeof(DID);
> DID.Reserved =3D 0;
> DIDAlias.cbSize =3D sizeof(DIDAlias);
> DIDAlias.Reserved =3D 0;
>
> ZeroMemory(&DevInfoData,sizeof(DevInfoData));
> DevInfoData.cbSize =3D sizeof(DevInfoData);
> DevInfoData.Reserved =3D 0;
>
> // enumerate all KS_CATEGORY_AUDIO ?
> if (SetupDiEnumDeviceInterfaces(hDevInfo,=20
> =09
> NULL,=20
> =09
> &category,=20
> =09
> index++,
> =09
> &DID) =3D=3D FALSE)
> {
> // This just means that we've enumerate
> all the devices - it's not a real error
> break;
> }
>
> // new scope so buffer will come & go
> {
> // Get details for the device registered
> in this class
> DWORD size =3D
> sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR);
> // use vector so it will clean up
> afterwards
> std::vector<BYTE> buffer(size,0);
> //=20
> SP_DEVICE_INTERFACE_DETAIL_DATA*
> pDevInterfaceDetails =3D
> reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA*>(&buffer[0]);
> //
> pDevInterfaceDetails->cbSize =3D
> sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
> //
> if
> (!SetupDiGetDeviceInterfaceDetail(hDevInfo,=20
> =09
> &DID,=20
> =09
> pDevInterfaceDetails,=20
> =09
> size,
> =09
> NULL,=20
> =09
> &DevInfoData))
> {
> continue;
> }
>
> // check additional category guids which
> may (or may not) have been supplied
> if
> (!SetupDiGetDeviceInterfaceAlias(hDevInfo,
> =09
> &DID,
> =09
> &mode,
> =09
> &DIDAlias))
> {
> continue;
> }
>
>
> // Check if the this interface alias is
> enabled.
> if (!DIDAlias.Flags || (DIDAlias.Flags &
> SPINT_REMOVED))
> {
> continue;
> }
> //=20
> CDeviceDescriptor desc;
> desc.m_handle =3D
> pDevInterfaceDetails->DevicePath;
>
> // this is how I test device 'type' at
> the moment !!!!
> /*
> CKsAudFilter filter;
> if
> (filter.Instantiate(pDevInterfaceDetails->DevicePath) =3D=3D S_OK)
> {
> if (mode =3D=3D KSCATEGORY_RENDER)
> {
> if
> (filter.CountRenderPins() =3D=3D 0)
> {
> continue;
> }
> }
> if (mode =3D=3D KSCATEGORY_CAPTURE)
> {
> if
> (filter.CountCapturePins() =3D=3D 0)
> {
> continue;
> }
> }
> }
> */ =09
> //
> DWORD reqSize =3D 0;
> BYTE name[64];
> DWORD dw =3D 0;
> BOOL b =3D
> SetupDiGetDeviceRegistryProperty(hDevInfo,
> =09
> &DevInfoData,
> =09
> SPDRP_DEVTYPE,
> =09
> NULL,
> =09
> (PBYTE)&dw,
> =09
> sizeof(dw),
> =09
> &reqSize);
>
> // get friendly name=20
> if
> (SetupDiGetDeviceRegistryProperty(hDevInfo,
> =09
> &DevInfoData,
> =09
> SPDRP_LOCATION_INFORMATION,
> =09
> NULL, // don't need the reg type
> =09
> &name[0],
> =09
> sizeof(name),
> =09
> &reqSize) =3D=3D TRUE)
> {
>
> desc.m_name =3D
> reinterpret_cast<TCHAR*>(name);
> name[reqSize] =3D '\0';
> }
> // get device description
> if
> (SetupDiGetDeviceRegistryProperty(hDevInfo,
> =09
> &DevInfoData,
> =09
> SPDRP_DEVICEDESC,
> =09
> NULL, // don't need the reg type
> =09
> &name[0],
> =09
> sizeof(name),
> =09
> &reqSize) =3D=3D TRUE)
> {
>
> desc.m_description =3D
> reinterpret_cast<TCHAR*>(name);
> name[reqSize] =3D '\0';
> }
> // get the manufacturers name
> if
> (SetupDiGetDeviceRegistryProperty(hDevInfo,
> =09
> &DevInfoData,
> =09
> SPDRP_MFG,
> =09
> NULL, // don't need the reg type
> =09
> &name[0],
> =09
> sizeof(name),
> =09
> &reqSize) =3D=3D TRUE)
> {
>
> desc.m_manufacturer =3D
> reinterpret_cast<TCHAR*>(name);
> name[reqSize] =3D '\0';
> }
> // this gives us device numbering if we
> have multiple (say) USB devices
> std::string strDesc =3D
> desc.m_description;
> UINT id =3D 1;
> // find the name
> std::map<std::string,UINT>::iterator imi
> =3D id_map.find(strDesc);
> if (imi !=3D id_map.end())
> {
> // increment the count
> id =3D ++imi->second;
> }
> else
> {
> // insert as <Name> <1>
> =09
> id_map.insert(std::make_pair(strDesc,1));
> }
> //
> desc.m_id =3D id; =09
> descs.push_back(desc);
> }
> }
> // clean up and go home
> SetupDiDestroyDeviceInfoList(hDevInfo);
> //
> return descs.size();
> }
> };
>
> //----------------------------------------------------------------------
> -------
> // end namespace
> //----------------------------------------------------------------------
> -------
>
> };
>
> //----------------------------------------------------------------------
> -------
> // end file
> //----------------------------------------------------------------------
> -------
>
> ******************
>
> WDMAUDIODEV addresses:
> Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
> Subscribe:    =
> mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=3Dsubscribe
> Unsubscribe:
> mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=3Dunsubscribe
> Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx
>
> URL to WDMAUDIODEV page:
> http://www.wdmaudiodev.de/
>
> ******************
>
> WDMAUDIODEV addresses:
> Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
> Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
> Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
> Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx
>
> URL to WDMAUDIODEV page:
> http://www.wdmaudiodev.de/
>
>


******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.de/

Other related posts: