有人可以看看我这样做是否正确:
//DeviceManager.h
#include <windows.h>
//#include <hidsdi.h>
#include <setupapi.h>
#include <iostream>
#include <cfgmgr32.h>
#include <tchar.h>
#include <devpkey.h>
extern "C"{
#include <hidsdi.h>
}
//#pragma comment (lib, "setupapi.lib")
class DeviceManager
{
public:
DeviceManager();
~DeviceManager();
void ListAllDevices();
void GetDevice(std::string vid, std::string pid);
HANDLE PSMove;
byte reportBuffer;
private:
HDEVINFO deviceInfoSet; //A list of all the devices
SP_DEVINFO_DATA deviceInfoData; //A device from deviceInfoSet
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;
};
//DeviceManager.cpp
#include"DeviceManager.h"
DeviceManager::DeviceManager()
{
deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); //Gets all Devices
}
DeviceManager::~DeviceManager()
{
}
void DeviceManager::ListAllDevices()
{
DWORD deviceIndex = 0;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
deviceInfoData.cbSize = sizeof(deviceInfoData);
ULONG tcharSize;
CM_Get_Device_ID_Size(&tcharSize, deviceInfoData.DevInst, 0);
TCHAR* deviceIDBuffer = new TCHAR[tcharSize]; //the device ID will be stored in this array, so the tcharSize needs to be big enough to hold all the info.
//Or we can use MAX_DEVICE_ID_LEN, which is 200
CM_Get_Device_ID(deviceInfoData.DevInst, deviceIDBuffer, MAX_PATH, 0); //gets the devices ID - a long string that looks like a file path.
/*
//SetupDiGetDevicePropertyKeys(deviceInfoSet, &deviceInfoData, &devicePropertyKey, NULL, 0, 0);
if( deviceIDBuffer[8]=='8' && deviceIDBuffer[9]=='8' && deviceIDBuffer[10]=='8' && deviceIDBuffer[11]=='8' && //VID
deviceIDBuffer[17]=='0' && deviceIDBuffer[18]=='3' && deviceIDBuffer[19]=='0' && deviceIDBuffer[20]=='8') //PID
{
std::cout << deviceIDBuffer << "\t<-- Playstation Move" << std::endl;
}
else
{
std::cout << deviceIDBuffer << std::endl;
}*/
std::cout << deviceIDBuffer << std::endl;
deviceIndex++;
}
}
void DeviceManager::GetDevice(std::string vid, std::string pid)
{
DWORD deviceIndex = 0;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
deviceInfoData.cbSize = sizeof(deviceInfoData);
ULONG IDSize;
CM_Get_Device_ID_Size(&IDSize, deviceInfoData.DevInst, 0);
TCHAR* deviceID = new TCHAR[IDSize];
CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_PATH, 0);
if( deviceID[8]==vid.at(0) && deviceID[9]==vid.at(1) && deviceID[10]==vid.at(2) && deviceID[11]==vid.at(3) && //VID
deviceID[17]==pid.at(0) && deviceID[18]==pid.at(1) && deviceID[19]==pid.at(2) && deviceID[20]==pid.at(3)) //PID
{
//DWORD requiredBufferSize;
//SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &requiredBufferSize,
HDEVINFO deviceInterfaceSet = SetupDiGetClassDevs(&deviceInfoData.ClassGuid, NULL, NULL, DIGCF_ALLCLASSES);
DWORD deviceInterfaceIndex = 0;
deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
while(SetupDiEnumDeviceInterfaces(deviceInterfaceSet, NULL, &deviceInterfaceData.InterfaceClassGuid, deviceInterfaceIndex, &deviceInterfaceData))
{
deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
std::cout << deviceInterfaceIndex << std::endl;
deviceInterfaceIndex++;
}
//std::cout << deviceInterfaceData.cbSize << std::endl;
break;
}
deviceIndex++;
}
}
我的SetupDiEnumDeviceInterfaces(在GetDevice()函数中)没有做任何事情。它甚至没有进入while循环......有人可以试着指出我做错了什么吗?
由于
编辑/更多信息:我刚刚调用了GetLastError()函数,它返回了一个259 - ERROR_NO_MORE_ITEMS。设备甚至可能不包含接口吗?
答案 0 :(得分:8)
顺便说一句。
我试图尽可能少地破解你的原始代码;以下代码(至少对我来说)通过内部while(SetupDiEnumDeviceInterfaces..)
:
void DeviceManager::GetDeviceUSB(std::string vid, std::string pid)
{
DWORD deviceIndex = 0;
deviceInfoData.cbSize = sizeof(deviceInfoData);
//buried somewhere deep in the ddk
static GUID GUID_DEVINTERFACE_USB_HUB={ 0xf18a0e88, 0xc30c, 0x11d0, {0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8} };
static GUID GUID_DEVINTERFACE_USB_DEVICE ={ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
static GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER={ 0x3abf6f2d, 0x71c4, 0x462a, {0x8a, 0x92, 0x1e, 0x68, 0x61, 0xe6, 0xaf, 0x27}};
//get usb device interfaces
HDEVINFO deviceInterfaceSet=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE);
while(SetupDiEnumDeviceInfo(deviceInterfaceSet, deviceIndex, &deviceInfoData))
{
deviceInfoData.cbSize = sizeof(deviceInfoData);
ULONG IDSize;
CM_Get_Device_ID_Size(&IDSize, deviceInfoData.DevInst, 0);
TCHAR* deviceID = new TCHAR[IDSize];
CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_PATH, 0);
if( deviceID[8]==vid.at(0) && deviceID[9]==vid.at(1) && deviceID[10]==vid.at(2) && deviceID[11]==vid.at(3) && //VID
deviceID[17]==pid.at(0) && deviceID[18]==pid.at(1) && deviceID[19]==pid.at(2) && deviceID[20]==pid.at(3)) //PID
{
DWORD deviceInterfaceIndex = 0;
deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
while(SetupDiEnumDeviceInterfaces(deviceInterfaceSet, &deviceInfoData, &GUID_DEVINTERFACE_USB_DEVICE, deviceInterfaceIndex, &deviceInterfaceData))
{
deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
std::cout << deviceInterfaceIndex << std::endl;
//get some more details etc
//DWORD requiredBufferSize;
//SetupDiGetDeviceInterfaceDetail(deviceInterfaceSet, &deviceInterfaceData, NULL, 0, &requiredBufferSize,
deviceInterfaceIndex++;
}
}
deviceIndex++;
}
}
afaik,此方法选择与OP构造函数调用相同的设备:
(注意:我包括了一些其他有用的界面指南)
deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); //Gets all Devices
但我这样做是为了获取设备接口:
// /coughs/ you might want to put back the DIGCF_PRESENT flag i removed for testing
HDEVINFO deviceInterfaceSet=SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_DEVICEINTERFACE);
我也根据文档将deviceInfoData
传递给SetupDiEnumDeviceInterfaces
:
的 的
指向指定设备的SP_DEVINFO_DATA结构的指针 DeviceInfoSet中的信息元素。此参数是可选的 可以是NULL。如果指定了此参数, SetupDiEnumDeviceInterfaces将枚举限制为 指定设备支持的接口。如果这 参数为NULL,重复调用SetupDiEnumDeviceInterfaces 返回有关与all关联的接口的信息 DeviceInfoSet中的设备信息元素。这个指针是 通常由SetupDiEnumDeviceInfo返回。 的
来自device setup classes documentation:
设备设置类定义了安装设备所涉及的类安装程序和类共同安装程序
来自device interface classes documentation:
设备接口类是一种将设备和驱动程序功能导出到其他系统组件(包括其他驱动程序)的方法 以及用户模式应用程序
Also, see this handy comparison
Also, this related doc is useful
所以:
deviceInfoSet = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL,DIGCF_PRESENT|DIGCF_ALLCLASSES);
这是检索所有 setup 类信息集并过滤“USB”
你可以这样做:
deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES|DIGCF_DEVICEINTERFACE);`
这将检索支持任何类的设备接口的设备的类信息集。 (应用一个emumerator ID s / a“USB”似乎没有影响)
然而,最重要的是: The function adds to the device information set a device information element that represents such a device and then adds to the device information element a device interface list that contains all the device interfaces that the device supports.
( 并注意: SP_DEVINFO_DATA.ClassGuid
总是设备的设置的GUID class)
Afaik:
但是,在调用InterfaceClassGuid
时,您仍然需要提供 SetupDiEnumDeviceInterfaces()
〜tbh,我真的不明白为什么如果调用者提供可选的 DeviceInfoData
,这是必要的
但由于它都是封闭源,我怎么知道! :)
&amp;这是info regarding GUID_DEVINTERFACE_USB_DEVICE
<子>
(;免责声明:我不会为M $工作;请怀疑地对待上述信息:)&amp;&amp;当然是dyoRs;)
希望这有帮助,祝你好运!
答案 1 :(得分:3)
问题始于如何调用SetupDiGetClassDevs。
如果您想获取设备路径,请使用 SetupDiGetClassDevs(&amp; GUID_DEVINTERFACE_USB_DEVICE ,,,)
SetupDiEnumDeviceInterfaces失败,错误259如果SetupDiGetClassDevs被赋予了错误的GUID MS帮助说的ClassGuid是 指向设备设置类或设备接口类的GUID的指针。
包含文件devguid.h包含一组GUID_DEVCLASS值。这些 NOT 与您需要的GUID_DEVINTERFACE_ *值相同。
使用#include&lt; uuids.h&gt;其中包括ksuuids.h,您可以在其中找到GUID_DEVINTERFACE_ *值。
我的网站上有更详细的解释,其中一些源代码可以帮助您正确枚举USB设备。