[wdmaudiodev] Re: Device Enumeration again ...

  • From: "Mitchell Rundle" <mitchr@xxxxxxxxxxxxx>
  • To: <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Mon, 7 Apr 2003 09:28:10 -0700

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/

Other related posts: