有沒有一種方法可以在窗口中找到具有指定VID和PID的USB設備,而無需調用WDK功能?list沒有使用Windows驅動程序的指定VID和PID的USB設備套件
3
A
回答
3
下面的代碼就可以了:
static const char dongleVid[] = {'1', '2', '3', '4', '\0'};
static const char donglePid[] = {'5', '6', '7', '8', '\0'};
static const LPCTSTR arPrefix[3] = {TEXT("VID_"), TEXT("PID_"), TEXT("MI_")};
const std::string requiredVid = boost::to_upper_copy(std::string(arPrefix[0]) + std::string(dongleVid));
const std::string requiredPid = boost::to_upper_copy(std::string(arPrefix[1]) + std::string(donglePid));
unsigned i, j;
DWORD dwSize, dwPropertyRegDataType;
OSVERSIONINFO osvi;
CONFIGRET r;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
TCHAR szDesc[1024];
LPTSTR pszToken, pszNextToken;
TCHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
#ifdef UNICODE
FN_SetupDiGetDeviceProperty fn_SetupDiGetDeviceProperty = (FN_SetupDiGetDeviceProperty)
GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyW");
#else
FN_SetupDiGetDeviceProperty fn_SetupDiGetDeviceProperty = (FN_SetupDiGetDeviceProperty)
GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyA");
#endif
// List all connected USB devices
hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
return false;
}
// Find the ones that are driverless
for (i = 0; ; i++)
{
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
{
break;
}
r = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
if (r != CR_SUCCESS)
{
continue;
}
SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
&dwPropertyRegDataType, (BYTE*)szDesc,
sizeof(szDesc), // The size, in bytes
&dwSize);
// Retreive the device description as reported by the device itself
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
pszToken = _tcstok_s(szDeviceInstanceID , TEXT("\\#&"), &pszNextToken);
szVid[0] = TEXT('\0');
szPid[0] = TEXT('\0');
szMi[0] = TEXT('\0');
while (pszToken != NULL)
{
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;
}
}
}
pszToken = _tcstok_s(NULL, TEXT("\\#&"), &pszNextToken);
}
std::string foundVid = boost::to_upper_copy(std::string(szVid));
std::string foundPid = boost::to_upper_copy(std::string(szPid));
if (requiredVid == foundVid && requiredPid == foundPid)
{
return true;
}
}
+0
你從來沒有真正使用你聲明的OSVERSIONINFO變量。 –
+0
混淆代碼,不清楚。 –
1
是的,你可以在user32.dll和setuapi.dll的Win32 API中擁有所有必要的功能。這是一個小C#示例:
internal static bool FindUsbDevice(string vendorId, string productId,
ref string deviceDesc, ref string deviceInstanceId, ref Guid classId)
{
bool returnValue = false;
string enumeratorClass = "USB";
IntPtr szClass = Marshal.StringToHGlobalAuto(enumeratorClass);
Guid classGuid = Guid.Empty;
IntPtr deviceInfoSet = new System.IntPtr();
try
{
deviceInfoSet = DeviceManagement.SetupDiGetClassDevs(ref classGuid, szClass, IntPtr.Zero,
DeviceManagement.DIGCF_ALLCLASSES | DeviceManagement.DIGCF_PRESENT);
DeviceManagement.SP_DEVINFO_DATA spDevInfoData = new DeviceManagement.SP_DEVINFO_DATA();
spDevInfoData.cbSize = Marshal.SizeOf(spDevInfoData);
for (int i = 0; DeviceManagement.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref spDevInfoData); i++)
{
int nSize = 0;
string DeviceInstanceId = new string('0', 259);
IntPtr ptrDeviceInstanceId = Marshal.StringToHGlobalAuto(DeviceInstanceId);
if (!DeviceManagement.SetupDiGetDeviceInstanceId(deviceInfoSet, ref spDevInfoData, ptrDeviceInstanceId,
DeviceInstanceId.Length, ref nSize))
{
Console.WriteLine("SetupDiGetDeviceInstanceId() error");
continue;
}
DeviceInstanceId = Marshal.PtrToStringAnsi(ptrDeviceInstanceId);
if (!DeviceInstanceId.Contains(string.Format("USB\\VID_{0}&PID_{1}", vendorId, productId)))
continue;
returnValue = true;
deviceInstanceId = DeviceInstanceId;
classId = spDevInfoData.ClassGuid;
int DataT = 0;
string buffer = new string('0', 259);
IntPtr pBuffer = Marshal.StringToHGlobalAuto(buffer);
int bufferSize = 259;
if (!DeviceManagement.SetupDiGetDeviceRegistryProperty(
deviceInfoSet, ref spDevInfoData, DeviceManagement.SPDRP_DEVICEDESC,
ref DataT, pBuffer, bufferSize, ref bufferSize))
{
if (Marshal.GetLastWin32Error() == DeviceManagement.ERROR_INVALID_DATA)
Debug.WriteLine("Error invalid data");
else
Debug.WriteLine("error");
}
else
{
buffer = Marshal.PtrToStringAnsi(pBuffer, bufferSize);
deviceDesc = buffer;
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
DeviceManagement.SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
return returnValue;
}
而包裝器代碼:
public sealed partial class DeviceManagement
{
///<summary >
// API declarations relating to device management (SetupDixxx and
// RegisterDeviceNotification functions).
/// </summary>
// from dbt.h
internal const Int32 DBT_DEVICEARRIVAL = 0X8000;
internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004;
internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5;
internal const Int32 DBT_DEVTYP_HANDLE = 6;
internal const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
internal const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 1;
internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0;
internal const Int32 WM_DEVICECHANGE = 0X219;
// from setupapi.h
internal const Int32 DIGCF_PRESENT = 2;
internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;
internal const Int32 DIGCF_ALLCLASSES = 0x4;
internal const Int32 SPDRP_FRIENDLYNAME = 0xC;
internal const Int32 SPDRP_DEVICEDESC = 0x0;
internal const Int32 SPDRP_CLASSGUID = 0x8;
// from WinError.h
internal const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
internal const Int32 ERROR_INVALID_DATA = 13;
// Two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure.
// Use this one in the call to RegisterDeviceNotification() and
// in checking dbch_devicetype in a DEV_BROADCAST_HDR structure:
[StructLayout(LayoutKind.Sequential)]
internal class DEV_BROADCAST_DEVICEINTERFACE
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
internal Guid dbcc_classguid;
internal Int16 dbcc_name;
}
// Use this to read the dbcc_name String and classguid:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class DEV_BROADCAST_DEVICEINTERFACE_1
{
internal Int32 dbcc_size;
internal Int32 dbcc_devicetype;
internal Int32 dbcc_reserved;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
internal Byte[] dbcc_classguid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
internal Char[] dbcc_name;
}
[StructLayout(LayoutKind.Sequential)]
internal class DEV_BROADCAST_HDR
{
internal Int32 dbch_size;
internal Int32 dbch_devicetype;
internal Int32 dbch_reserved;
}
internal struct SP_DEVICE_INTERFACE_DATA
{
internal Int32 cbSize;
internal System.Guid InterfaceClassGuid;
internal Int32 Flags;
internal IntPtr Reserved;
}
internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
internal Int32 cbSize;
internal String DevicePath;
}
internal struct SP_DEVINFO_DATA
{
internal Int32 cbSize;
internal System.Guid ClassGuid;
internal Int32 DevInst;
internal Int32 Reserved;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, int MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern bool SetupDiGetDeviceInstanceId(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, IntPtr DeviceInstanceId, int DeviceInstanceIdSize, ref int RequiredSize);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, int Property, ref int PropertyRegDataType, IntPtr PropertyBuffer, int PropertyBufferSize, ref int RequiredSize);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll", SetLastError = true)]
internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
[DllImport("user32.dll", SetLastError = true)]
internal static extern Boolean UnregisterDeviceNotification(IntPtr Handle);
}
希望它能幫助,你應該趕快把它翻譯成的Visual C++
3
這裏是郭驗鈔的代碼的簡化版本:
unsigned index;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
TCHAR HardwareID[1024];
// List all connected USB devices
hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
for (index = 0; ; index++) {
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) {
return false; // no match
}
SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID, NULL, (BYTE*)HardwareID, sizeof(HardwareID), NULL);
if (_tcsstr(HardwareID, _T("VID_1234&PID_5678"))) {
return true; // match
}
}
相關問題
- 1. 如何從Python中的USB設備VID和PID確定sysfs devpath?
- 2. 如何設置嵌入式Linux中USB設備的VID和PID
- 3. 如何根據其VID和PID識別USB設備
- 4. 直接在Delphi中使用VID和PID的USB設備進行數據交換
- 5. 在VC++中使用PID和VID函數檢測USB設備的問題
- 6. 如何從C#中的USB閃存驅動器獲取VID/PID?
- 7. USb驅動程序Windows移動設備的文檔掃描儀
- 8. 自定義USB設備驅動程序,Windows
- 9. 設備VID和PID傳遞到功能
- 10. 使用pyserial標識USB給串口給出USB VID和PID
- 11. 如何實現Windows的USB設備驅動程序?
- 12. usb cdc設備驅動程序
- 13. 從任何USB設備獲取PID/VID nunbers
- 14. 根據其VID/PID查找並彈出USB設備
- 15. 我們可以從USB閃存驅動器獲取VID和PID嗎?
- 16. 沒有設備的設備驅動程序?
- 17. 設備和應用程序驅動程序之間的Hack USB通信?
- 18. 學習資源的USB設備和設備驅動程序開發
- 19. 用於USB AVR JTAG-ISP設備的驅動程序
- 20. 如果我正在使用類驅動程序,爲什麼還需要USB VID/PID?
- 21. 如何將驅動程序與USB設備綁定?
- 22. 如何區分兩個usb觸摸屏設備與Linux中相同的pid/vid
- 23. 驅動程序綁定使用驅動程序中沒有兼容字符串的設備樹
- 24. GT-I7500的Android銀河三星設備的USB驅動程序
- 25. Linux的USB驅動程序:探測已經插入的設備
- 26. 用自定義驅動程序替換Windows USB類驅動程序?
- 27. 在Windows中測量設備驅動程序的內存使用
- 28. 如何獲取在.net中連接到我的系統的所有USB設備的VID和PID?
- 29. 控制一個無驅動程序的USB音頻設備
- 30. 的Windows硬件/設備驅動程序報告/庫存
使用SetupAPI:http://msdn.microsoft.com/en-us/library/ff550897%28v=VS.85%29.aspx –
可能的重複[如何在Visual中列出所有連接的USB設備C++](http://stackoverflow.com/questions/2735920/how-to-list-all-attached-usb-devices-in-visual-c) –