-----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx]On Behalf Of Jerry Evans Sent: Monday, April 07, 2003 1:03 PM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Device Enumeration again ... 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/ ****************** 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/