USB Device Finder

复制代码
http://www.velleman.eu/images/tmp/usbfind.c

#ifdef __cplusplus
extern "C" { #endif #include <windows.h> #include <tchar.h> #include <setupapi.h> #include <initguid.h> #include <stdio.h> // This is the GUID for the USB device class DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); // (A5DCBF10-6530-11D2-901F-00C04FB951ED) int main() { HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DATA DevIntfData; PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData; SP_DEVINFO_DATA DevData; DWORD dwSize, dwType, dwMemberIdx; HKEY hKey; BYTE lpData[1024]; // We will try to get device information set for all USB devices that have a // device interface and are currently present on the system (plugged in). hDevInfo = SetupDiGetClassDevs( &GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (hDevInfo != INVALID_HANDLE_VALUE) { // Prepare to enumerate all device interfaces for the device information // set that we retrieved with SetupDiGetClassDevs(..) DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); dwMemberIdx = 0; // Next, we will keep calling this SetupDiEnumDeviceInterfaces(..) until this // function causes GetLastError() to return ERROR_NO_MORE_ITEMS. With each // call the dwMemberIdx value needs to be incremented to retrieve the next // device interface information. SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, dwMemberIdx, &DevIntfData); while(GetLastError() != ERROR_NO_MORE_ITEMS) { // As a last step we will need to get some more details for each // of device interface information we are able to retrieve. This // device interface detail gives us the information we need to identify // the device (VID/PID), and decide if it's useful to us. It will also // provide a DEVINFO_DATA structure which we can use to know the serial // port name for a virtual com port. DevData.cbSize = sizeof(DevData); // Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with // a NULL DevIntfDetailData pointer, a DevIntfDetailDataSize // of zero, and a valid RequiredSize variable. In response to such a call, // this function returns the required buffer size at dwSize. SetupDiGetDeviceInterfaceDetail( hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL); // Allocate memory for the DeviceInterfaceDetail struct. Don't forget to // deallocate it later! DevIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, DevIntfDetailData, dwSize, &dwSize, &DevData)) { // Finally we can start checking if we've found a useable device, // by inspecting the DevIntfDetailData->DevicePath variable. // The DevicePath looks something like this: // // \\?\usb#vid_04d8&pid_0033#5&19f2438f&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} // // The VID for Velleman Projects is always 10cf. The PID is variable // for each device: // // ------------------- // | Device | PID | // ------------------- // | K8090 | 8090 | // | VMB1USB | 0b1b | // ------------------- // // As you can see it contains the VID/PID for the device, so we can check // for the right VID/PID with string handling routines. if (NULL != _tcsstr((TCHAR*)DevIntfDetailData->DevicePath, _T("vid_10cf&pid_8090"))) { // To find out the serial port for our K8090 device, // we'll need to check the registry: hKey = SetupDiOpenDevRegKey( hDevInfo, &DevData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ ); dwType = REG_SZ; dwSize = sizeof(lpData); RegQueryValueEx(hKey, _T("PortName"), NULL, &dwType, lpData, &dwSize); RegCloseKey(hKey); // Eureka! wprintf(_T("Found a device on port '%s'\n"), lpData); } } HeapFree(GetProcessHeap(), 0, DevIntfDetailData); // Continue looping SetupDiEnumDeviceInterfaces( hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData); } SetupDiDestroyDeviceInfoList(hDevInfo); } return 0; }
复制代码

 

posted @   IAmAProgrammer  阅读(1059)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
历史上的今天:
2013-09-29 [Win32]创建模态窗口
2013-09-29 Process ID, Process handle, Window handle
2013-09-29 PEM DAC note
2013-09-29 创建Windows窗体 : WinMain() 与 WndProc()
点击右上角即可分享
微信分享提示