我最近在做一个操作USB设备的程序,但在打开设备时遇到了问题.步骤如下,
1.调用SetupDiGetClassDevs.这一部正常获得句柄
2.调用SetupDiEnumDeviceInterfaces,枚举设备.3.两次调用SetupDiGetDeviceInterfaceDetail,获取设备详细信息,设备名.
代码例子:
#define MAX_SLOT_NUM 64
static char TotalSlotName[MAX_SLOT_NUM][MAX_PATH];
static PSTR strSCRName[MAX_SLOT_NUM];
static DWORD TotalSlotNum;
static DWORD checkTokenID;
static GUID usb_guid = CdRomClassGuid;
DWORD CP11Dlg::USBcheck( )
{
HDEVINFO info;
SP_DEVICE_INTERFACE_DATA xifdata;
DWORD devindex;
DWORD needed;
PSP_INTERFACE_DEVICE_DETAIL_DATA detail;
SP_DEVINFO_DATA did;
BOOL reflag = true;
DWORD checkTotalNum = 0;
DWORD dwDataLen=0;
info = SetupDiGetClassDevs(&usb_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); // All devices present on system
if(info==INVALID_HANDLE_VALUE)
{
return FALSE;
}
xifdata.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for(devindex = 0; SetupDiEnumDeviceInterfaces(info, NULL, &usb_guid, devindex, &xifdata);devindex++)
{
SetupDiGetDeviceInterfaceDetail(info, &xifdata, NULL, 0, &needed, NULL);
detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(needed);
detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
did.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiGetDeviceInterfaceDetail(info, &xifdata, detail, needed, NULL, &did);
if(_tcsstr(detail->DevicePath, _T("zteic")))
{
if(checkTotalNum>MAX_SLOT_NUM)
{
break;
reflag=false;
}
checkTotalNum++;
strcpy(TotalSlotName[checkTotalNum-1], detail->DevicePath);
}
}
writelog(LOG_INFO,"目前KEY总数为:%d\n",checkTotalNum);
for( int i = 0;i < (int)checkTotalNum; i++)
{
writelog(LOG_INFO,"id:%s\n",TotalSlotName[i]);
}
free((void *) detail);
SetupDiDestroyDeviceInfoList(info);
return reflag;
}
关于其他函数
SetupDiGetClassDevs
HDEVINFO
SetupDiGetClassDevs(
IN PGUID ClassGuid, /* optional */
IN PCTSTR Enumerator, /* optional */
IN HWND hwndParent, /* optional */
IN DWORD Flags
);
SetupDiGetClassDevs returns a device information set that contains all installed devices of a specified class.
获取一个指定类别或全部类别的所有已安装设备的信息
Parameters
ClassGuid
Supplies a pointer to the class GUID to use when creating the list of devices. If the DIGCF_ALLCLASSES flag is set, this parameter is ignored and the resulting list contains all installed classes.
一个特定类别GUID(需要查询注册表)的指针,如果设置了DIGCF_ALLCLASSES标记,该参数备忽略,将返回所有类别的设备信息表
Enumerator
Supplies the name of the key under the Enum registry branch that contains device instances for which information is to be retrieved. If this parameter is not specified, device information is retrieved for all device instances in the entire Enum tree.
过滤梅举的内容:如:PCI则只显示PCI设备,
hwndParent
Supplies the handle of the top-level window to be used for any user interface relating to the members of this set.
用于关联到集合成员中的用户接口的顶层窗口句柄
Flags
Supplies control options used in building the device information set. Can be one of the following values:
建立设备信息表的控制选项,可以是下列值
DIGCF_PRESENT
Return only devices that are currently present.(只列出当前存在的设备信息)
DIGCF_ALLCLASSES
Return a list of installed devices for all classes. If this flag is set, the ClassGuid parameter is ignored.(列出所有类别的一安装的设备表,如果设置了此值,则指定的类别将备忽略)
DIGCF_PROFILE
Return only devices that are a part of the current hardware profile.(只返回当前硬件概况部分)
Return Value
If the function succeeds, it returns a handle to a device information set containing all installed devices matching the specified parameters.
如成功,返回包含所有与指定参数匹配的已经安装设备信息句柄
If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
如失败则返回INVALID_HANDLE_VALUE
SetupDiEnumDeviceInfo
(
m_hDevInfo, //设备句柄,如果熟悉注册表可以从注册表中指定,VC++也支持默认设备:
//如GUID_DEVCLASS_SMARTCARDREADER表示读卡器GUID
i, //当前设备连接端口号
&m_DeviceInfoData//第i端口连接设备的详细硬件信息
)
通过USB设备的详细信息可以控制连接设备的相关操作,包括
DICS_DISABLE(驱动卸载),
DICS_ENABLE(驱动重装),
DICS_STOP(设备停用),
DICS_START(设备重启),
当然,如果需要与USB设备进行通信,只需要该USB设备的驱动以及他的LIB、DLL、.H文件就可以通过头文件中的驱动函数访问该设备。