2011-09-29 50 views
3

有沒有一種方法可以在窗口中找到具有指定VID和PID的USB設備,而無需調用WDK功能?list沒有使用Windows驅動程序的指定VID和PID的USB設備套件

+0

使用SetupAPI:http://msdn.microsoft.com/en-us/library/ff550897%28v=VS.85%29.aspx –

+0

可能的重複[如何在Visual中列出所有連接的USB設備C++](http://stackoverflow.com/questions/2735920/how-to-list-all-attached-usb-devices-in-visual-c) –

回答

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 
    } 
} 
相關問題