Windows provided some API to get the device's detail information, include USB STORAGE HID PCI etc
#include <windows.h>
#include <devguid.h> // for GUID_DEVCLASS_CDROM etc
#include <setupapi.h>
#include <cfgmgr32.h> // for MAX_DEVICE_ID_LEN, CM_Get_Parent and CM_Get_Device_ID
#define INITGUID
#include <tchar.h>
#include <stdio.h>
//#include "c:\WinDDK\7600.16385.1\inc\api\devpkey.h"
// include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpropdef.h
#ifdef DEFINE_DEVPROPKEY
#undef DEFINE_DEVPROPKEY
#endif
#ifdef INITGUID
#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
#else
#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY name
#endif // INITGUID
// include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpkey.h
DEFINE_DEVPROPKEY(DEVPKEY_Device_BusReportedDeviceDesc, 0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 4); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_Device_ContainerId, 0x8c7ed206, 0x3f8a, 0x4827, 0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c, 2); // DEVPROP_TYPE_GUID
DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_DeviceDisplay_Category, 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x5a); // DEVPROP_TYPE_STRING_LIST
DEFINE_DEVPROPKEY(DEVPKEY_Device_LocationInfo, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 15); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_Device_SecuritySDS, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 26); // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
#pragma comment (lib, "setupapi.lib")
typedef BOOL (WINAPI *FN_SetupDiGetDevicePropertyW)(
__in HDEVINFO DeviceInfoSet,
__in PSP_DEVINFO_DATA DeviceInfoData,
__in const DEVPROPKEY *PropertyKey,
__out DEVPROPTYPE *PropertyType,
__out_opt PBYTE PropertyBuffer,
__in DWORD PropertyBufferSize,
__out_opt PDWORD RequiredSize,
__in DWORD Flags
// List all USB devices with some additional information
void ListDevices (CONST GUID *pClassGuid, LPCTSTR pszEnumerator)
unsigned i, j;
DWORD dwSize, dwPropertyRegDataType;
DEVPROPTYPE ulPropertyType;
CONFIGRET status;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
const static LPCTSTR arPrefix[3] = {TEXT("VID_"), TEXT("PID_"), TEXT("MI_")};
TCHAR szDeviceInstanceID [MAX_DEVICE_ID_LEN];
TCHAR szDesc[1024], szHardwareIDs[4096];
WCHAR szBuffer[4096];
LPTSTR pszToken, pszNextToken;
TCHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
FN_SetupDiGetDevicePropertyW fn_SetupDiGetDevicePropertyW = (FN_SetupDiGetDevicePropertyW)
GetProcAddress (GetModuleHandle (TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyW");
// List all connected USB devices
hDevInfo = SetupDiGetClassDevs (pClassGuid, pszEnumerator, NULL,
pClassGuid != NULL ? DIGCF_PRESENT: DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
return;
// Find the ones that are driverless
for (i = 0; ; i++) {
DeviceInfoData.cbSize = sizeof (DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
break;
status = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
if (status != CR_SUCCESS)
continue;
// Display device instance ID
_tprintf (TEXT("%s\n"), szDeviceInstanceID );
if (SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
&dwPropertyRegDataType, (BYTE*)szDesc,
sizeof(szDesc), // The size, in bytes
&dwSize))
_tprintf (TEXT(" Device Description: \"%s\"\n"), szDesc);
if (SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID,
&dwPropertyRegDataType, (BYTE*)szHardwareIDs,
sizeof(szHardwareIDs), // The size, in bytes
&dwSize)) {
LPCTSTR pszId;
_tprintf (TEXT(" Hardware IDs:\n"));
for (pszId=szHardwareIDs;
*pszId != TEXT('\0') && pszId + dwSize/sizeof(TCHAR) <= szHardwareIDs + ARRAYSIZE(szHardwareIDs);
pszId += lstrlen(pszId)+1) {
_tprintf (TEXT(" \"%s\"\n"), pszId);
// Retreive the device description as reported by the device itself
// On Vista and earlier, we can use only SPDRP_DEVICEDESC
// On Windows 7, the information we want ("Bus reported device description") is
// accessed through DEVPKEY_Device_BusReportedDeviceDesc
if (fn_SetupDiGetDevicePropertyW && fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0))
_tprintf (TEXT(" Bus Reported Device Description: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_Manufacturer,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
_tprintf (TEXT(" Device Manufacturer: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_FriendlyName,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
_tprintf (TEXT(" Device Friendly Name: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_LocationInfo,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
_tprintf (TEXT(" Device Location Info: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_SecuritySDS,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
// See Security Descriptor Definition Language on MSDN
// (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379567(v=vs.85).aspx)
_tprintf (TEXT(" Device Security Descriptor String: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_ContainerId,
&ulPropertyType, (BYTE*)szDesc, sizeof(szDesc), &dwSize, 0)) {
StringFromGUID2((REFGUID)szDesc, szBuffer, ARRAY_SIZE(szBuffer));
_tprintf (TEXT(" ContainerId: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_DeviceDisplay_Category,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0))
_tprintf (TEXT(" Device Display Category: \"%ls\"\n"), szBuffer);
pszToken = _tcstok_s (szDeviceInstanceID , TEXT("\\#&"), &pszNextToken);
while(pszToken != NULL) {
szVid[0] = TEXT('\0');
szPid[0] = TEXT('\0');
szMi[0] = TEXT('\0');
for (j = 0; j < 3; j++) {
if (_tcsncmp(pszToken, arPrefix[j], lstrlen(arPrefix[j])) == 0) {
switch(j) {
case 0:
_tcscpy_s(szVid, ARRAY_SIZE(szVid), pszToken);
break;
case 1:
_tcscpy_s(szPid, ARRAY_SIZE(szPid), pszToken);
break;
case 2:
_tcscpy_s(szMi, ARRAY_SIZE(szMi), pszToken);
break;
default:
break;
if (szVid[0] != TEXT('\0'))
_tprintf (TEXT(" vid: \"%s\"\n"), szVid);
if (szPid[0] != TEXT('\0'))
_tprintf (TEXT(" pid: \"%s\"\n"), szPid);
if (szMi[0] != TEXT('\0'))
_tprintf (TEXT(" mi: \"%s\"\n"), szMi);
pszToken = _tcstok_s (NULL, TEXT("\\#&"), &pszNextToken);
return;
int _tmain()
// List all connected USB devices
_tprintf (TEXT("---------------\n"));
_tprintf (TEXT("- USB devices -\n"));
_tprintf (TEXT("---------------\n"));
ListDevices(NULL, TEXT("USB"));
_tprintf (TEXT("\n"));
_tprintf (TEXT("-------------------\n"));
_tprintf (TEXT("- USBSTOR devices -\n"));
_tprintf (TEXT("-------------------\n"));
ListDevices(NULL, TEXT("USBSTOR"));
_tprintf (TEXT("\n"));
_tprintf (TEXT("--------------\n"));
_tprintf (TEXT("- SD devices -\n"));
_tprintf (TEXT("--------------\n"));
ListDevices(NULL, TEXT("SD"));
//_tprintf (TEXT("\n"));
//ListDevices(&GUID_DEVCLASS_USB, NULL);
//_tprintf (TEXT("\n"));
_tprintf (TEXT("\n"));
_tprintf (TEXT("-----------\n"));
_tprintf (TEXT("- Volumes -\n"));
_tprintf (TEXT("-----------\n"));
//ListDevices(NULL, TEXT("STORAGE\\VOLUME"));
//_tprintf (TEXT("\n"));
ListDevices(&GUID_DEVCLASS_VOLUME, NULL);
_tprintf (TEXT("\n"));
_tprintf (TEXT("----------------------------\n"));
_tprintf (TEXT("- devices with disk drives -\n"));
_tprintf (TEXT("----------------------------\n"));
ListDevices(&GUID_DEVCLASS_DISKDRIVE, NULL);
return 0;
Windows provided some API to get the device's detail information, include USB STORAGE HID PCI etc#include #include // for GUID_DEVCLASS_CDROM etc#include #include // for MAX_DEVICE_ID_
USB_HID_DEVICE
如果目标是STM32F429I-disco板,则必须在“define.h”中取消注释“#define USE_USB_OTG_HS”
这个例子是作为键盘的 HID 设备
如果您按下 USER_BUTTON,它将向 PC(windows) 发送 WIN+R
if (GetDriveType(szRootPathName) != DRIVE_REMOVABLE)
m_csErrorMsg.Format(_T("该磁盘不是可移动磁盘"));
csLogicDisk.Format(_T("\\\\.\\%c:"), csDiskSymbol[0]);
1 用途概述
DEVICE ID可唯一标识一个存储设备,这对于多盘掉电等功能非常重要,因为无论是判定一个盘是否已掉盘还是已上盘都必须知道是哪一个盘。利用这个唯一标识,可以做的事情就很多,包括定位。
一个典型的USB设备的DEVICE ID格式如下:
百度搜了下,
https://blog.csdn.net/kingston110/article/details/112060113?spm=1001.2014.3001.5506
这位老哥给的方案最靠谱,但是这老哥貌似有点保留,根据他的代码是没办法对相同摄像头by不同的USB口进行区分。
最后小研究了下找到解决方案。
1.OPENCV中打开摄像头都是打开摄像头的Index,这个Index是通过COM来遍历“CLSID_VideoInp
IoInvalidateDeviceRelations 之间经过的时间和
IRP_MN_QUERY_DEVICE_RELATIONS
完成的 IRP_MN_QUERY_DEVICE_RELATIONS 之间经过的时间
和 IRP_MN_START_DEVICE
IRP 计时开始
软件启动设备恢复计时
硬件初始化设备恢复计时
集线器简历从选择性暂停计时
ETW USB 和电源管理
Delphi可以使用Windows API函数来判断USB设备。首先要使用SetupDiGetClassDevs函数获取设备信息,然后使用SetupDiEnumDeviceInterfaces函数枚举设备接口,使用SetupDiGetDeviceInterfaceDetail函数获取接口详细信息。可以根据接口信息判断设备是否为USB设备。
以下是一个简单的示例代码:
1.声明函数
声明Windows API函数,包括 SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces, SetupDiGetDeviceInterfaceDetail等函数。
2. 获取设备信息
使用SetupDiGetClassDevs函数获取设备信息。需要传递两个参数,第一个参数是GUID,表示要查找的设备类型;第二个参数为NULL,表示查找所有可用的设备。返回值为设备信息的句柄。
3. 枚举设备接口
使用SetupDiEnumDeviceInterfaces函数枚举设备接口,需要传递三个参数,第一个参数是设备信息的句柄,第二个参数是设备描述符,第三个参数是接口GUID。
4. 获取接口信息
使用SetupDiGetDeviceInterfaceDetail函数获取接口详细信息,需要传递三个参数,第一个参数是设备信息的句柄,第二个参数是接口描述符,第三个参数是接口详细信息结构体。
5. 判断是否为USB设备
根据接口详细信息结构体来判断设备是否为USB设备。
示例代码:
//获取设备信息
hDevInfo := SetupDiGetClassDevs(@GUID_DEVCLASS_USB, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
if hDevInfo = INVALID_HANDLE_VALUE then
begin
ShowMessage('SetupDiGetClassDevs failed.');
Exit;
//枚举设备接口
devInterfaceData.cbSize := SizeOf(devInterfaceData);
index := 0;
while SetupDiEnumDeviceInterfaces(hDevInfo, nil, GUID_DEVINTERFACE_USB_DEVICE, index, devInterfaceData) do
begin
//获取接口详细信息
if not SetupDiGetDeviceInterfaceDetail(hDevInfo, @devInterfaceData, nil, 0, @requiredSize, nil) then
begin
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
begin
mem := AllocMem(requiredSize);
devInterfaceDetailData.cbSize := SizeOf(devInterfaceDetailData);
if not SetupDiGetDeviceInterfaceDetail(hDevInfo, @devInterfaceData, mem, requiredSize, @requiredSize, @devInfoData) then
begin
ShowMessage('SetupDiGetDeviceInterfaceDetail failed.');
begin
//判断是否为USB设备
if devInterfaceDetailData.DevicePath.IndexOf('USB') >= 0 then
begin
//是USB设备
FreeMem(mem);
Inc(index);
//释放设备信息句柄
SetupDiDestroyDeviceInfoList(hDevInfo);
以上就是使用Delphi判断USB设备的简单方法。