Device setup classes provide a mechanism for grouping devices that are installed and configured in the same way. A setup class identifies the class installer and class co-installers that are involved in installing the devices that belong to the class. For example, all CD-ROM drives belong to the CDROM setup class and will use the same co-installer when installed.
Device interface classes provide a mechanism for grouping devices according to shared characteristics. Rather than tracking the presence in the system of an individual device, drivers and user applications can register to be notified of the arrival or removal of any device that belongs to a particular interface class.
使用函数SetupDiEnumDeviceInfo枚举可用设备时只有存在可用的设备时,系统才会枚举出那个设备;其它端口PORT虽然在注册表中存在设备接口但该端口并没有可用的具体设备,因此也不会被枚举出来。所以SetupDiEnumDeviceInfo只会枚举出可用的具体设备。
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
/*
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE表示当前存在的接口实例,因此必须使用接口GUID才能正确获取;它是细化到接口中去查找可用的实例。
DIGCF_ALLCLASSES表示枚举所有的设备类,因此必须使用设备GUID才能正确获取(以GUID_DEVCLASS_*的形式表示);要再继续获取接口实例必须循环每个
具体设备类,并像下面的代码重复获取。
*/
hDevInfo = SetupDiGetClassDevs((LPGUID) &GUID_DEVINTERFACE_CDROM, 0, 0,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
// Insert error handling here.
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
// Enumerate through all devices in Set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (int i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);i++)
{
DWORD DataT;
char *pBuffer = new char[2048];
DWORD buffersize =sizeof(pBuffer);
while (!SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_FRIENDLYNAME,&DataT,(PBYTE)pBuffer,buffersize,&buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
}
else
{
delete []pBuffer;
pBuffer = NULL;
break;
}
}
//
DWORD iInterfaceIndex = 0;
SP_DEVICE_INTERFACE_DATA devInterfaceData;
memset(&devInterfaceData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD dwError;
while(!SetupDiEnumDeviceInterfaces(hDevInfo, (PSP_DEVINFO_DATA)&DeviceInfoData, &GUID_DEVINTERFACE_CDROM, iInterfaceIndex, &devInterfaceData))
{
delete []pBuffer;
pBuffer = NULL;
dwError = GetLastError();
break;
}
/*
Using SetupDiGetDeviceInterfaceDetail to get details about an interface is typically a two-step process:
1.Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a NULL DeviceInterfaceDetailData pointer,
a DeviceInterfaceDetailDataSize of zero, and a valid RequiredSize variable.
In response to such a call, this function returns the required buffer size at RequiredSize and fails with GetLastError
returning ERROR_INSUFFICIENT_BUFFER.
2.Allocate an appropriately sized buffer and call the function again to get the interface details.
*/
DWORD dwRequiredSize;
SP_DEVINFO_DATA DevInterfaceInfoData;
DevInterfaceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, NULL, 0, &dwRequiredSize, &DevInterfaceInfoData);
BYTE Buf[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA pDevInterDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;//遵循第二条的规则
pDevInterDetailData->cbSize = sizeof(*pDevInterDetailData);
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, pDevInterDetailData,
dwRequiredSize, &dwRequiredSize, &DevInterfaceInfoData);