libusb枚举设备的过程

1 调用libusb_get_device_descriptor获取USB设备的设备描述符,然后调用libusb_get_config_descriptor获取配置描述符、接口描述符、端点描述符信息。
2 根据上面获取的设备信息匹配设备,通常可以通过设备的PID\VID匹配,设备的class 、subclass 、protocol 来进行匹配,如果是复合设备,则根据interface的class 、subclass、protocol来为每一个interface匹配。
3 调用libusb_claim_interface申请一个设备接口
4 读写设备
示例代码:
typedef struct
{
         
        u_int8_t  bInterfaceNumber;
        u_int8_t  bInEndpointAddress;
        u_int8_t  bOutEndpointAddress;
        u_int16_t idVendor;
        u_int16_t idProduct;
         
        
}stUsbCtrl;
stUsbCtrl usbctrl;
static int FindEndpoint( u_int8_t * bInAddress , u_int8_t * bOutAddress,const struct libusb_interface_descriptor * interface)
{
        int i;
        int ret=0;
        for(i=0;i<interface->bNumEndpoints;i++)
        {
                if((interface->endpoint[i].bmAttributes&0x03)==0x02)
                {
                        if(interface->endpoint[i].bEndpointAddress&0x80)
                        {
                                ret|=1;
                                *bInAddress=interface->endpoint[i].bEndpointAddress;
                        }
                        else
                        {
                                ret|=2;
                                *bOutAddress=interface->endpoint[i].bEndpointAddress;
                        }
                }
                                         
        }
        if(ret==3)
        {
                return 1;
        }
        else
        {
                return 0;
        }
}
int FindInterface(struct libusb_device_descriptor * desc,libusb_device *dev )
{
        struct libusb_config_descriptor *conf_desc;
        int i,j,k;
        int isFind = 0; 
        
        u_int8_t  bInterfaceNumber;
        u_int8_t  bInEndpointAddress;
        u_int8_t  bOutEndpointAddress; 
    
    for (i=0; i< desc->bNumConfigurations; i++) 
    {
                libusb_get_config_descriptor(dev, i, &conf_desc);
                 
                                
                for (j=0; j< conf_desc->bNumInterfaces; j++)
                {
                                 
                        for (k=0; k< conf_desc->interface[j].num_altsetting; k++) 
                        {
                                if(conf_desc->interface[j].altsetting[k].bInterfaceClass==0xff&&conf_desc->interface[j].altsetting[k].bInterfaceSubClass==0xff)
                                {
                                        if(FindEndpoint( &bInEndpointAddress , &bOutEndpointAddress ,  &(conf_desc->interface[j].altsetting[k] ) ))
                                        {
                                                bInterfaceNumber = conf_desc->interface[j].altsetting[k].bInterfaceNumber;
                                                libusb_free_config_descriptor(conf_desc);
                                                isFind=1;
                                                goto DINFINTERFACE;
                                        }
                                }
                                         
                        }
                }
                libusb_free_config_descriptor(conf_desc);
        }
DINFINTERFACE :
        if(isFind)
        {
                usbctrl.bInEndpointAddress=bInEndpointAddress;
                usbctrl.bOutEndpointAddress=bOutEndpointAddress;
                usbctrl.bInterfaceNumber=bInterfaceNumber;
                usbctrl.idVendor=desc->idVendor ;
                usbctrl.idProduct=desc->idProduct;
                return 1;
        }
        else
        {
                return 0;
        }
        
}
int CheckUsbDevice(libusb_device *dev)
{
        struct libusb_device_descriptor desc;




         
        int ret = libusb_get_device_descriptor(dev, &desc);
        
        if (LIBUSB_SUCCESS != ret) 
        {
                printf("Error getting device descriptor %s\n", libusb_error_name(ret));
                return -1;
        }
        if((desc.idVendor==USB_MATCH_VID)&&(desc.idProduct==USB_MATCH_PID))
        {
                if(FindInterface(&desc,dev))
                {
                        return 1;
                }
                else
                {
                        return -1;
                }
        }
        else
        {
                return -1;
        }
         
}
int  listalldevice( void )
{
        libusb_device **devs;
        ssize_t cnt;
        int i;
        int ret; 
        cnt = libusb_get_device_list(NULL, &devs);
        for(i=0;i<cnt;i++)
        {
                ret =CheckUsbDevice(devs[i]);
                if(ret==1)
                {
                        break;
                }
        }
        libusb_free_device_list(devs, 1);
        return ret;
}
int main(int argc, char **argv)
{
        unsigned char buf[10];
        int iRealLen;
        int ret;
        libusb_init (NULL);
        if(listalldevice()==1)
        {
                libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, usbctrl.idVendor, usbctrl.idProduct);
                if(handle==NULL)
                {
                        goto DONE;
                }
                libusb_set_auto_detach_kernel_driver(handle, 1);
                ret=libusb_claim_interface(handle, usbctrl.bInterfaceNumber);  
                if(ret != LIBUSB_SUCCESS)
                {
                        libusb_reset_device( handle );
                        ret=libusb_claim_interface(handle, usbctrl.bInterfaceNumber);  
                }
                if(ret != LIBUSB_SUCCESS)
                {
                        libusb_close(handle);
                        goto DONE;
                }
                ret = libusb_bulk_transfer(handle,usbctrl.bOutEndpointAddress,buf,10,&iRealLen,0);//发送数据
                if(ret!=LIBUSB_SUCCESS)
                {
                        if(ret==LIBUSB_ERROR_PIPE)
                        {
                                libusb_clear_halt(handle,usbctrl.bInEndpointAddress);
                        }
                }
                ret = libusb_bulk_transfer(handle,usbctrl.bInEndpointAddress,buf,10,&iRealLen,0);//接收数据
                if(ret!=LIBUSB_SUCCESS)
                {
                        if(ret==LIBUSB_ERROR_PIPE)
                        {
                                libusb_clear_halt(handle,usbctrl.bInEndpointAddress);
                        }
                }
                libusb_release_interface(handle, usbctrl.bInterfaceNumber);
                libusb_close(handle); 
        }
DONE:
        libusb_exit(NULL);
        return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要启用一个隐藏设备,你需要使用 Windows API 中的 SetupDiXXX 系列函数来枚举设备和获取设备信息。这个过程可以用 C++ 实现,不过你需要先了解一些 Windows API 的知识。以下是一个简单的示例代码,它使用 libusb 库和 Windows API 来枚举 USB 设备并启用一个隐藏设备: ```c++ #include <windows.h> #include <setupapi.h> #include <devguid.h> #include <regstr.h> #include <iostream> #include <libusb.h> int main() { // 枚举 USB 设备 HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_USB, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { std::cerr << "Failed to enumerate USB devices." << std::endl; return -1; } // 遍历设备信息 SP_DEVINFO_DATA devInfo; ZeroMemory(&devInfo, sizeof(devInfo)); devInfo.cbSize = sizeof(devInfo); for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfo); ++i) { // 获取设备描述符 char desc[256]; if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfo, SPDRP_DEVICEDESC, NULL, (BYTE*)desc, sizeof(desc), NULL)) { continue; } // 判断是否为隐藏设备 DWORD status; DWORD problem; if (!CM_Get_DevNode_Status(&status, &problem, devInfo.DevInst, 0)) { if (status & DN_HAS_PROBLEM && problem == CM_PROB_DEVICE_NOT_THERE) { // 打开设备 libusb_device_handle* handle = libusb_open_device_with_vid_pid(NULL, VendorID, ProductID); if (handle != NULL) { // 启用设备 libusb_detach_kernel_driver(handle, 0); libusb_attach_kernel_driver(handle, 0); libusb_close(handle); } } } } // 释放资源 SetupDiDestroyDeviceInfoList(hDevInfo); return 0; } ``` 需要注意的是,这个示例代码只能启用 VendorID 和 ProductID 对应的设备,如果需要启用其他设备,你需要修改代码中的 VendorID 和 ProductID。此外,还需要确保你的应用程序具有管理员权限才能启用隐藏设备
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值