从连接的 USB 设备检索'Device Instance Path'
Retrieve 'Device Instance Path' from attached USB device
我关注了一些资源,包括这个资源,我可以检索USB设备的pid、vid等属性,但我也需要检索"设备实例路径",因为它包含序列号(最后4位),这最终是我想要的。
我试着使用这里的代码来检索序列号,但它对USB存储设备是这样做的,我的设备是一个独立的设备,有点像相机的USB连接。
QString USBDevices::findDevice()
{
GUID*pClassGuid = NULL;
LPCTSTR pszEnumerator = TEXT("USB");
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);
//hDevInfo = SetupDiGetClassDevs(NULL,0,0, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
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
qDebug() << QString::fromWCharArray(szDeviceInstanceID);
if (SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
&dwPropertyRegDataType, (BYTE*)szDesc,
sizeof(szDesc), // The size, in bytes
&dwSize))
qDebug() << " Device Description: " << QString::fromWCharArray(szDesc);
if (SetupDiGetDeviceRegistryProperty (hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID,
&dwPropertyRegDataType, (BYTE*)szHardwareIDs,
sizeof(szHardwareIDs), // The size, in bytes
&dwSize)) {
LPCTSTR pszId;
qDebug() << " Hardware IDs:n";
for (pszId=szHardwareIDs;
*pszId != TEXT(' ') && pszId + dwSize/sizeof(TCHAR) <= szHardwareIDs + ARRAYSIZE(szHardwareIDs);
pszId += lstrlen(pszId)+1) {
qDebug() << QString::fromWCharArray(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))
{
QString busReportedDeviceDescription = QString::fromWCharArray(szBuffer);
qDebug() << " Bus Reported Device Description: " << QString::fromWCharArray(szBuffer);
if ( busReportedDeviceDescription == MY_DEVICE )
{
qDebug() << getSerialNum( hDevInfo );
return busReportedDeviceDescription;
}
}
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_Manufacturer,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
qDebug() << " Device Manufacturer: " << QString::fromWCharArray(szBuffer);
}
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_FriendlyName,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
qDebug() << " Device Friendly Name: " << QString::fromWCharArray(szBuffer);
}
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_LocationInfo,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
qDebug() << " Device Location Info: " << QString::fromWCharArray(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)
qDebug() << " Device Security Descriptor String: " << QString::fromWCharArray(szBuffer);
}
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_ContainerId,
&ulPropertyType, (BYTE*)szDesc, sizeof(szDesc), &dwSize, 0)) {
StringFromGUID2((REFGUID)szDesc, szBuffer, ARRAY_SIZE(szBuffer));
qDebug() << " ContainerId: " << QString::fromWCharArray(szBuffer);
}
if (fn_SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_DeviceDisplay_Category,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0))
qDebug() << " Device Display Category: " << QString::fromWCharArray(szBuffer);
}
QString deviceInstanceID( QString::fromWCharArray( szDeviceInstanceID ) );
QRegExp splitBy("(\\|\&|\#)");
QStringList deviceInstanceIDItems = deviceInstanceID.split(splitBy);
QString vid;
QString pid;
QString mi;
if (deviceInstanceIDItems.count() > 1)
vid = deviceInstanceIDItems[1].contains("VID_") ? deviceInstanceIDItems[1] : "";
if (deviceInstanceIDItems.count() > 2)
pid = deviceInstanceIDItems[2].contains("PID_") ? deviceInstanceIDItems[2] : "";
if (deviceInstanceIDItems.count() > 3)
mi = deviceInstanceIDItems[3].contains("MI_") ? deviceInstanceIDItems[3] : "";
if (!vid.isEmpty())
qDebug() << " vid: " << vid;
if (!pid.isEmpty())
qDebug() << " pid: " << pid;
if (!mi.isEmpty())
qDebug() << " mi: " << mi;
}
return "";
}
QString USBDevices::getSerialNum(HDEVINFO hDevInfo)
{
// Get a context structure for the device interface
// of a device information set.
BYTE Buf[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd =
(PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
spdid.cbSize = sizeof( spdid );
DWORD dwIndex = 0;
while ( true )
{
if ( ! SetupDiEnumDeviceInterfaces( hDevInfo, NULL,
//&GUID_DEVINTERFACE_USB_DISK,
&my_guid,
dwIndex, &spdid ))
{
qDebug() << "GetLastError code" << GetLastError();
break;
}
DWORD dwSize = 0;
SetupDiGetDeviceInterfaceDetail( hDevInfo, &spdid, NULL,
0, &dwSize, NULL );
if (( dwSize != 0 ) && ( dwSize <= sizeof( Buf )))
{
pspdidd->cbSize = sizeof( *pspdidd ); // 5 Bytes!
ZeroMemory((PVOID)&spdd, sizeof(spdd));
spdd.cbSize = sizeof(spdd);
long res = SetupDiGetDeviceInterfaceDetail(
hDevInfo, &spdid, pspdidd,
dwSize, &dwSize, &spdd );
// if ( res )
// {
// HANDLE hDrive = CreateFile( pspdidd->DevicePath,0,
// FILE_SHARE_READ | FILE_SHARE_WRITE,
// NULL, OPEN_EXISTING, 0, NULL );
// if ( hDrive != INVALID_HANDLE_VALUE )
// {
// DWORD usbDeviceNumber = getDeviceNumber( hDrive );
// if ( usbDeviceNumber == volumeDeviceNumber )
// {
// fprintf( "%s", pspdidd->DevicePath );
// }
// }
// CloseHandle( hDrive );
// }
qDebug() << "Device Path" << pspdidd->DevicePath;
QString devicePath = QString::fromWCharArray( pspdidd->DevicePath );
return devicePath;
}
dwIndex++;
}
return "";
}
问题是这部分代码:
if ( ! SetupDiEnumDeviceInterfaces( hDevInfo, NULL,
//&GUID_DEVINTERFACE_USB_DISK,
&my_guid,
dwIndex, &spdid ))
{
qDebug() << "GetLastError code" << GetLastError();
break;
}
返回错误代码269,因此它不检索任何信息。我试着提供了几个不同的GUID,我认为这会解决问题,但没有,而且我不确定我应该提供什么GUID,因为我的GUID不是存储设备。
您应该使用启用的标志DIGCF_DEVICEINTERFACE
和一些接口类GUID来调用SetupDiGetClassDevs
。然后,使用相同的GUID调用SetupDiEnumDeviceInterfaces
。在你的情况下,我认为GUID_DEVINTERFACE_USB_DEVICE
会胜任这项工作。
您可以在此处找到符合条件的GUID。
相关文章:
- C++ Singleton - Prevent ::instance() to variable
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- DrawIndexedInstanced 具有不同的 Index Count per Instance (Directx
- 我可以将QCoreApplication::instance()用于孤儿QObjects吗?
- 如何强制嵌入式python使用与命令行相同的sys.path?
- "terminate called after throwing an instance of std::invalid_argument' what(): stoi ?"
- [LLVM-9 clang-9 OSX]: std::filesystem::path unrecognized
- cin.get() 导致"no instance of overloaded function"错误
- 我可以对"int 文件 = open(path, flag);"做点什么吗?
- 方括号在"map <string, int> instance[numberFeatures];"中是什么意思
- "#include <path/to/header>"指令的含义(如"#include <loki/Functor.h>")
- Cppcheck 静态代码分析器实际上可以检测到不太常见的警告(如 "Relative Path Traversal (CWE-23)" 或"Buffer Under-read(CWE-127)")吗
- 如何处理异步函数中的异常UWP应用程序getFileFrompathAsync(path);
- 尝试在虚幻引擎中通过C++添加视口时出错"No instance of overloaded function CreateWidget"
- 使用std :: filesystem :: path中的double
- 使用谷歌测试编译程序时"g++ is not a full path"
- c++ std::bad_alloc on std::filesystem::path append
- CodeLite opencv path
- 安装 gRPC : ld: 警告: 找不到选项 '-L/<path>/grpc/libs/opt/c-ares' 的目录
- 从连接的 USB 设备检索'Device Instance Path'