MFC如何获取USB的VID、PID和协议版本呢?

lwei2 2020-08-11 02:26:06
各位大佬,请问Win API有哪个接口可以获取指定的USB协议版本和VID、PID,在网上查看,很多都是把所有的USB的VID和PID找出来,这样不是会把键盘和鼠标的也找出来吗?我自己试过,它就连鼠标和键盘的都找出来了,要怎么做,才能找出只有自己插入的USB的VID和PID呢?代码如下:

//#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <string>
#include <setupapi.h>

#include <initguid.h>
using namespace std;

#pragma comment(lib,"setupapi.lib")

DEFINE_GUID(UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);

//获取USB设备VID和PID

string GetUsbInfo()

{

HDEVINFO hDevInfo;

SP_DEVICE_INTERFACE_DATA spDevData;

PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;

BOOL bRes = TRUE;

int nCount = 0;
string csResult;
hDevInfo = ::SetupDiGetClassDevs((LPGUID)&UsbClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);



if (hDevInfo != INVALID_HANDLE_VALUE)

{

pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, 1024);

pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

while (bRes)

{

spDevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

bRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID)&UsbClassGuid, nCount, &spDevData);

if (bRes)

{

bRes = ::SetupDiGetInterfaceDeviceDetail(hDevInfo, &spDevData, pDetail, 1024, NULL, NULL);

if (bRes)

{

string szStr = pDetail->DevicePath;
csResult += szStr + "\n";

//break;
nCount++;

}

}

}

::GlobalFree(pDetail);

::SetupDiDestroyDeviceInfoList(hDevInfo);

}

return csResult;

}

int main(void)

{

string csStr = GetUsbInfo();

cout << csStr << endl;
cout << "End...";


return 0;

}
恳请懂的大佬指点一下,不胜感激!!
...全文
659 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
lwei2 2020-09-24
  • 打赏
  • 举报
回复
引用 12 楼 worldy 的回复:
USB设备插入后,操作系统会自动读取设备描述符,从而获得VID及PID,然后根据VID和PID加载驱动,如果找不到驱动,会提示安装驱动,加载驱动后,才能访问USB设备; 上位机访问USB设备,一般都是在驱动加载完成之后。
哦哦,目前我是获取不出它的协议
引用 13 楼 飞鹤0755 的回复:
DWORD GetDriveTypeByBus(const CHAR *drive, WORD *type) { HANDLE hDevice; // handle to the drive to be examined BOOL result; // results flag DWORD readed; // discard results STORAGE_DESCRIPTOR_HEADER *pDevDescHeader; STORAGE_DEVICE_DESCRIPTOR *pDevDesc; DWORD devDescLength; STORAGE_PROPERTY_QUERY query; hDevice = CreateFile( drive, // drive to open GENERIC_READ | GENERIC_WRITE, // access to the drive FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL // do not copy file attribute ); if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive { fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError()); return DWORD(-1); } query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; int nSize = sizeof(STORAGE_DESCRIPTOR_HEADER); pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER)); if (NULL == pDevDescHeader) { return (DWORD)-1; } result = DeviceIoControl( hDevice, // device to be queried IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform &query, sizeof query, // no input buffer pDevDescHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), // output buffer &readed, // # bytes returned NULL); // synchronous I/O if (!result) //fail { fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError()); free(pDevDescHeader); (void)CloseHandle(hDevice); return DWORD(-1); } devDescLength = pDevDescHeader->Size; pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(devDescLength+512); if (NULL == pDevDesc) { free(pDevDescHeader); return (DWORD)-1; } result = DeviceIoControl( hDevice, // device to be queried IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform &query, sizeof query, // no input buffer pDevDesc, devDescLength, // output buffer &readed, // # bytes returned NULL); // synchronous I/O if (!result) //fail { fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError()); free(pDevDescHeader); free(pDevDesc); (void)CloseHandle(hDevice); return DWORD(-1); } //printf("%d\n", pDevDesc->BusType); *type = (WORD)pDevDesc->BusType; free(pDevDescHeader); free(pDevDesc); (void)CloseHandle(hDevice); return 0; }
大佬,你这个好像不能获取VID、PID、或协议版本吧……
lwei2 2020-09-22
  • 打赏
  • 举报
回复
引用 13 楼 飞鹤0755 的回复:
DWORD GetDriveTypeByBus(const CHAR *drive, WORD *type) { HANDLE hDevice; // handle to the drive to be examined BOOL result; // results flag DWORD readed; // discard results STORAGE_DESCRIPTOR_HEADER *pDevDescHeader; STORAGE_DEVICE_DESCRIPTOR *pDevDesc; DWORD devDescLength; STORAGE_PROPERTY_QUERY query; hDevice = CreateFile( drive, // drive to open GENERIC_READ | GENERIC_WRITE, // access to the drive FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL // do not copy file attribute ); if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive { fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError()); return DWORD(-1); } query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; int nSize = sizeof(STORAGE_DESCRIPTOR_HEADER); pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER)); if (NULL == pDevDescHeader) { return (DWORD)-1; } result = DeviceIoControl( hDevice, // device to be queried IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform &query, sizeof query, // no input buffer pDevDescHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), // output buffer &readed, // # bytes returned NULL); // synchronous I/O if (!result) //fail { fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError()); free(pDevDescHeader); (void)CloseHandle(hDevice); return DWORD(-1); } devDescLength = pDevDescHeader->Size; pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(devDescLength+512); if (NULL == pDevDesc) { free(pDevDescHeader); return (DWORD)-1; } result = DeviceIoControl( hDevice, // device to be queried IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform &query, sizeof query, // no input buffer pDevDesc, devDescLength, // output buffer &readed, // # bytes returned NULL); // synchronous I/O if (!result) //fail { fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError()); free(pDevDescHeader); free(pDevDesc); (void)CloseHandle(hDevice); return DWORD(-1); } //printf("%d\n", pDevDesc->BusType); *type = (WORD)pDevDesc->BusType; free(pDevDescHeader); free(pDevDesc); (void)CloseHandle(hDevice); return 0; }
多谢大佬指点!!!
-飞鹤- 2020-09-22
  • 打赏
  • 举报
回复
DWORD GetDriveTypeByBus(const CHAR *drive, WORD *type) { HANDLE hDevice; // handle to the drive to be examined BOOL result; // results flag DWORD readed; // discard results STORAGE_DESCRIPTOR_HEADER *pDevDescHeader; STORAGE_DEVICE_DESCRIPTOR *pDevDesc; DWORD devDescLength; STORAGE_PROPERTY_QUERY query; hDevice = CreateFile( drive, // drive to open GENERIC_READ | GENERIC_WRITE, // access to the drive FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL // do not copy file attribute ); if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive { fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError()); return DWORD(-1); } query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; int nSize = sizeof(STORAGE_DESCRIPTOR_HEADER); pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER)); if (NULL == pDevDescHeader) { return (DWORD)-1; } result = DeviceIoControl( hDevice, // device to be queried IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform &query, sizeof query, // no input buffer pDevDescHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), // output buffer &readed, // # bytes returned NULL); // synchronous I/O if (!result) //fail { fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError()); free(pDevDescHeader); (void)CloseHandle(hDevice); return DWORD(-1); } devDescLength = pDevDescHeader->Size; pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(devDescLength+512); if (NULL == pDevDesc) { free(pDevDescHeader); return (DWORD)-1; } result = DeviceIoControl( hDevice, // device to be queried IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform &query, sizeof query, // no input buffer pDevDesc, devDescLength, // output buffer &readed, // # bytes returned NULL); // synchronous I/O if (!result) //fail { fprintf(stderr, "IOCTL_STORAGE_QUERY_PROPERTY Error: %ld\n", GetLastError()); free(pDevDescHeader); free(pDevDesc); (void)CloseHandle(hDevice); return DWORD(-1); } //printf("%d\n", pDevDesc->BusType); *type = (WORD)pDevDesc->BusType; free(pDevDescHeader); free(pDevDesc); (void)CloseHandle(hDevice); return 0; }
worldy 2020-09-08
  • 打赏
  • 举报
回复
USB设备插入后,操作系统会自动读取设备描述符,从而获得VID及PID,然后根据VID和PID加载驱动,如果找不到驱动,会提示安装驱动,加载驱动后,才能访问USB设备; 上位机访问USB设备,一般都是在驱动加载完成之后。
worldy 2020-09-07
  • 打赏
  • 举报
回复
引用 8 楼 lwei2 的回复:
[quote=引用 5 楼 worldy 的回复:]DeviceDscr: db DSCR_DEVICE_LEN ;; Descriptor length db DSCR_DEVICE ;; Decriptor type dw 0002H ;; Specification Version (BCD) db 00H ;; Device class db 00H ;; Device sub-class db 00H ;; Device sub-sub-class db 64 ;; Maximum packet size dw 0B404H ;; Vendor ID dw 0510H ;; Product ID (Sample Device) dw 0000H ;; Product version ID db 1 ;; Manufacturer string index db 2 ;; Product string index db 0 ;; Serial number string index db 1 ;; Number of configurations 红色那个字段
大佬,请问怎么获取设备描述符呢?我找到usbview那个例子,但是它总是去主机控制器那里循环获取处理,有什么办法可以获取插入的硬盘的对应的USB设备描述符吗?[/quote] 有没有使用库?或者使用了如LibUSB之类的驱动库或厂家提供的驱动库?使用LibUSB或厂家提供的驱动库,按说明操作即可
lwei2 2020-09-07
  • 打赏
  • 举报
回复
引用 10 楼 worldy 的回复:
[quote=引用 8 楼 lwei2 的回复:][quote=引用 5 楼 worldy 的回复:]DeviceDscr: db DSCR_DEVICE_LEN ;; Descriptor length db DSCR_DEVICE ;; Decriptor type dw 0002H ;; Specification Version (BCD) db 00H ;; Device class db 00H ;; Device sub-class db 00H ;; Device sub-sub-class db 64 ;; Maximum packet size dw 0B404H ;; Vendor ID dw 0510H ;; Product ID (Sample Device) dw 0000H ;; Product version ID db 1 ;; Manufacturer string index db 2 ;; Product string index db 0 ;; Serial number string index db 1 ;; Number of configurations 红色那个字段
大佬,请问怎么获取设备描述符呢?我找到usbview那个例子,但是它总是去主机控制器那里循环获取处理,有什么办法可以获取插入的硬盘的对应的USB设备描述符吗?[/quote] 有没有使用库?或者使用了如LibUSB之类的驱动库或厂家提供的驱动库?使用LibUSB或厂家提供的驱动库,按说明操作即可[/quote]用了,不过那个库好像要求安装对应的USB驱动,才能去访问并打开这个USB设备。。。
lwei2 2020-09-04
  • 打赏
  • 举报
回复
引用 7 楼 dd_zhouqian 的回复:
https://blog.csdn.net/chenyujing1234/article/details/7577320
这个例子太难了,它循环去主机控制器里面获取,难道就没有其他办法获取硬盘的USB设备描述符了吗?那个usbview会把一些不需要的设备描述符也获取出来……
lwei2 2020-09-04
  • 打赏
  • 举报
回复
引用 5 楼 worldy 的回复:
DeviceDscr: db DSCR_DEVICE_LEN ;; Descriptor length db DSCR_DEVICE ;; Decriptor type dw 0002H ;; Specification Version (BCD) db 00H ;; Device class db 00H ;; Device sub-class db 00H ;; Device sub-sub-class db 64 ;; Maximum packet size dw 0B404H ;; Vendor ID dw 0510H ;; Product ID (Sample Device) dw 0000H ;; Product version ID db 1 ;; Manufacturer string index db 2 ;; Product string index db 0 ;; Serial number string index db 1 ;; Number of configurations 红色那个字段
大佬,请问怎么获取设备描述符呢?我找到usbview那个例子,但是它总是去主机控制器那里循环获取处理,有什么办法可以获取插入的硬盘的对应的USB设备描述符吗?
dd_zhouqian 2020-08-21
  • 打赏
  • 举报
回复
https://blog.csdn.net/chenyujing1234/article/details/7577320
lwei2 2020-08-12
  • 打赏
  • 举报
回复
引用 3 楼 lwei2 的回复:
引用 1 楼 worldy 的回复:
读取设备描述符
读取了,但不知道那些字段是表示协议版本的,像VID和PID还好找…
为啥不用STORAGE_DEVICE_DESCRIPTOR这个结构体呢,即如下: typedef struct _STORAGE_DEVICE_DESCRIPTOR { ULONG Version; // 版本 ULONG Size; // 结构大小 UCHAR DeviceType; // 设备类型 UCHAR DeviceTypeModifier; // SCSI-2额外的设备类型 BOOLEAN RemovableMedia; // 是否可移动 BOOLEAN CommandQueueing; // 是否支持命令队列 ULONG VendorIdOffset; // 厂家设定值的偏移 ULONG ProductIdOffset; // 产品ID的偏移 ULONG ProductRevisionOffset; // 产品版本的偏移 ULONG SerialNumberOffset; // 序列号的偏移 STORAGE_BUS_TYPE BusType; // 总线类型 ULONG RawPropertiesLength; // 额外的属性数据长度 UCHAR RawDeviceProperties[1]; // 额外的属性数据(仅定义了象征性的1个字节) } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; 你说的是要自定义的它的属性吗?
worldy 2020-08-12
  • 打赏
  • 举报
回复
DeviceDscr: db DSCR_DEVICE_LEN ;; Descriptor length db DSCR_DEVICE ;; Decriptor type dw 0002H ;; Specification Version (BCD) db 00H ;; Device class db 00H ;; Device sub-class db 00H ;; Device sub-sub-class db 64 ;; Maximum packet size dw 0B404H ;; Vendor ID dw 0510H ;; Product ID (Sample Device) dw 0000H ;; Product version ID db 1 ;; Manufacturer string index db 2 ;; Product string index db 0 ;; Serial number string index db 1 ;; Number of configurations 红色那个字段
lwei2 2020-08-12
  • 打赏
  • 举报
回复
引用 2 楼 zgl7903 的回复:
WDK 中有 USBView 的源码,可以参考研究下
很感谢,正在研究中……
lwei2 2020-08-12
  • 打赏
  • 举报
回复
引用 1 楼 worldy 的回复:
读取设备描述符
读取了,但不知道那些字段是表示协议版本的,像VID和PID还好找…
worldy 2020-08-11
  • 打赏
  • 举报
回复
读取设备描述符

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧