Mouse和Keyboard这类HID类设备是被系统独占的,若想用CreateFile得到句柄需把第二个参数为0;
CString strShow;
int flag=0;
int vid = 0x046D;
int pid = 0xC040;
//获得GUID
GUID guidHID;
HidD_GetHidGuid(&guidHID);
strShow=_T("HID类的GUID标识为:/r/n");
ShowMessage(strShow);
strShow.Format(_T(" %08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x/r/n"),
guidHID.Data1,guidHID.Data2,guidHID.Data3,guidHID.Data4[0],
guidHID.Data4[1],guidHID.Data4[2],guidHID.Data4[3],guidHID.Data4[4],
guidHID.Data4[5],guidHID.Data4[6],guidHID.Data4[7]);
ShowMessage(strShow);
//获得HID的结构数组调用函数SetupDiGetClassDevs,获得HID的结构数组
HDEVINFO hDevInfo = SetupDiGetClassDevs(
&guidHID,
NULL,
0,
DIGCF_PRESENT|DIGCF_DEVICEINTERFACE );
//根据此数组逐项查找指定的HID
SP_DEVICE_INTERFACE_DATA strtInterfaceData;
strtInterfaceData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
BOOL usbSuccess,pathSuccess;
DWORD index=0;
CString temp;
for(int i=0;flag==0 && i<10;i++)//一个USB接口理论上可以支持127个装置,但是目前还无法达到这个数字。其实,对于一台计算机,所接的周边外设很少有超过10个的,因此这个数字是足够我们使用的。
{
strShow.Format(_T("/r/n第%d次查找开始:/r/n"),i);
ShowMessage(strShow);
//识别HID接口调用函数SetupDiEnumDeviceInterfaces,识别当前HID接口
usbSuccess= SetupDiEnumDeviceInterfaces(
hDevInfo,//SetupDiGetClassDevs的返回值
NULL,
&guidHID,//通过HidD_GetHidGuid函数获得的GUID
index,//第一次调用设置为0
&strtInterfaceData);
index++;
if(usbSuccess)//识别当前HID接口成功
{
ShowMessage(_T("当前HID接口信息:/r/n"));
strShow.Format(_T(" cbsize:%d/r/n"),strtInterfaceData.cbSize);
ShowMessage(strShow);
strShow.Format(_T(" Flags:%d/r/n"),strtInterfaceData.Flags);
ShowMessage(strShow);
// 若找到了设备,则读取设备路径名
ULONG predictedLength = 0;
ULONG requiredLength = 0;
BOOL pathSuccess;
SP_DEVICE_INTERFACE_DETAIL_DATA * strtDetailData;
ShowMessage(_T("连续两次调用函数SetupDiGetDeviceInterfaceDetail,获得当前HID设备路径.../r/n"));
pathSuccess=SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,NULL,0,&requiredLength,NULL);//第一次调用返回pathSuccess=0
ShowMessage(_T(" 第一次调用成功.../r/n"));
strShow.Format(_T(" 获得需要数据区域大小为:%d/r/n"),requiredLength);
predictedLength=requiredLength;
strtDetailData= (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);
ShowMessage(_T(" 按需要重新分配内存成功/r/n"));
strtDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
strShow.Format(_T(" 获取cbSize:%d/r/n"),strtDetailData->cbSize);
pathSuccess=SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,strtDetailData,predictedLength,&requiredLength,NULL);
ShowMessage(_T(" 第二次调用成功.../r/n"));
m_strPath = strtDetailData->DevicePath;
strShow.Format(_T(" 返回路径DevicePath:%s/r/n"),m_strPath);
m_strLog += strShow;
SetDlgItemText(IDC_EDIT_REPORT,m_strLog);
//获得设备句柄
hCom = CreateFile(m_strPath,0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, // no SECURITY_ATTRIBUTES structure
OPEN_EXISTING, // No special create flags
0,
NULL);
if(hCom == INVALID_HANDLE_VALUE)
{
ShowMessage(_T("调用函数CreateFile,获得句柄失败!/r/n"));
}
else
{
ShowMessage(_T("调用函数CreateFile,获得句柄成功!/r/n"));
}
strShow.Format(_T(" 返回句柄:%p/r/n"),&hCom);
ShowMessage(strShow);
//获得设备的厂商ID、产品ID和产品序列号
ShowMessage(_T("调用函数HidD_GetAttributes,获取设备的厂商ID、产品ID和产品序列号.../r/n"));
HIDD_ATTRIBUTES strtAttrib;
BOOL Result;
Result=HidD_GetAttributes(hCom,&strtAttrib);
if(Result)
{
strShow.Format(_T(" 返回厂商ID值(十进制):%X/r/n 返回产品ID值(十进制):%X/r/n 返回产品序列号值(十进制):%X/r/n"),
strtAttrib.VendorID,strtAttrib.ProductID,strtAttrib.VersionNumber);
}
else
{
strShow = _T("HidD_GetAttributes Error!/r/n");
}
ShowMessage(strShow);
// 将查到的匹配的设备的标识显示出来
if(strtAttrib.VendorID== vid &&strtAttrib.ProductID==pid)
{
strShow.Format(_T("找到符合条件的HID设备,停止查找。/r/n"),i);
ShowMessage(strShow);
ShowMessage(_T("显示设备信息如下:/r/n"));
//显示厂商标识
strShow.Format(_T(" 厂商标识:0x%x/r/n"),strtAttrib.VendorID);
m_strLog += strShow;
SetDlgItemText(IDC_EDIT_REPORT,m_strLog);
//显示产品标识
strShow.Format(_T(" 产品标识:0x%x/r/n"),strtAttrib.ProductID);
m_strLog += strShow;
SetDlgItemText(IDC_EDIT_REPORT,m_strLog);
//显示产品版本号
strShow.Format(_T(" 产品序列号:%d/r/n"),strtAttrib.VersionNumber);
m_strLog += strShow;
SetDlgItemText(IDC_EDIT_REPORT,m_strLog);
ShowMessage(_T("此时可以在通信区进行收发报表操作!/r/n"));
AfxMessageBox(_T("FIND HID!"));
//找到则跳出循环
flag=1;
}
else
{
strShow.Format(_T("匹配设备的厂商标识和产品标识不成功,结束此次查找!/r/n"),i);
ShowMessage(strShow);
}
}
else//识别当前HID接口操作不成功
{
ShowMessage(_T("识别当前HID接口操作不成功,结束此次查找!/r/n"));
}
}//for循环结束
if(flag==0)//10次查找完成,找不到符合条件的HID设备
{
ShowMessage(_T("已完成N次查找,找不到符合条件的HID设备!/r/n"));
}
参照USBPort源码修改,功能查找某个PID,VID的HID设备