结合设备安装类GUID和设备接口类GUID获取设备VIDPID

http://blog.csdn.net/jhqin/article/details/6766311

 

前言:

VID和PID常被用于厂家的软件加密,只有在系统中检测到某VID和PID的设备时,软件才能运行。因此获取某一类型设备或者全部设备的VID和PID集合至关重要。获取设备VID和PID的一般流程是通过设备接口类GUID创建设备信息集,然后从设备接口详细信息中获取设备路径,再调用HidD_GetAttributes从属性中读取VID和PID。该方法的缺点是需要事先知道设备接口类GUID,且每次只能获取一个设备接口类的VID和PID集合。本方法既可以指定设备安装类GUID和/或设备接口类GUID,也可以两者都不指定而直接创建设备信息集,然后通过设备信息数据获取设备实例ID,并直接从设备实例ID中提取出VID和PID,巧妙地避开了对设备IO的读写。

下载:

WDK_VidPidQuery.zip

源代码:

WDK_VidPidQuery.h

[cpp] view plain copy print ?
  1. /* ---------------------------------------------------------- 
  2. 文件名称:WDK_VidPidQuery.h 
  3.  
  4. 作者:秦建辉 
  5.  
  6. MSN:[email protected] 
  7. QQ:36748897 
  8.  
  9. 开发环境: 
  10.     Visual Studio V2010  
  11.     WinDDK 7600.16385.1 
  12.  
  13. 版本历史: 
  14.     V1.0    2011年09月10日 
  15.             结合设备安装类GUID和设备接口类GUID获取设备VIDPID 
  16.  
  17. 接口函数: 
  18.     WDK_WhoAllVidPid 
  19.     WDK_isExistVidPid 
  20. ------------------------------------------------------------ */  
  21. #pragma once  
  22.   
  23. #include <windows.h>  
  24.   
  25. #ifndef MACRO_HIDD_VIDPID  
  26.     #define MACRO_HIDD_VIDPID  
  27.     typedef struct _HIDD_VIDPID  
  28.     {  
  29.         USHORT  VendorID;  
  30.         USHORT  ProductID;  
  31.     } HIDD_VIDPID;  
  32. #endif  
  33.   
  34. #ifdef __cplusplus  
  35. extern "C"  
  36. {  
  37. #endif  
  38.   
  39. /* 
  40. 功能:获取系统所有设备的VIDPID 
  41. 入口参数: 
  42.     [out] pVidPid:存储返回的VIDPID,会自动过滤掉重复的VIDPID 
  43.     [in] iCapacity:存储单元的容量,建议为32 
  44.     [in] SetupClassGuid:设备安装类GUID,默认为NULL 
  45.     [in] InterfaceClassGuid:设备接口类GUID,默认为NULL 
  46. 返回值: 
  47.     获取到的VID和PID数目 
  48. 优点: 
  49.     直接通过设备实例ID提取VIDPID,从而无需获取设备路径来读写IO。 
  50. */  
  51. INT WINAPI WDK_WhoAllVidPid( HIDD_VIDPID* pVidPid, INT iCapacity, const GUID* SetupClassGuid = NULL, const GUID* InterfaceClassGuid = NULL );  
  52.   
  53. /* 
  54. 功能:判断指定的VIDPID是否存在于列表中 
  55. 入口参数: 
  56.     [in] VendorID:要查找的VID 
  57.     [in] ProductID:要查找的PID 
  58.     [in] pVidPid:用来检索的VIDPID库 
  59.     [in] iSize:VIDPID库大小 
  60. 返回值: 
  61.     TRUE:存在 
  62.     FALSE:不存在 
  63. */  
  64. BOOL WINAPI WDK_isExistVidPid( USHORT VendorID, USHORT ProductID, const HIDD_VIDPID* pVidPid, INT iSize );  
  65.   
  66. #ifdef __cplusplus  
  67. }  
  68. #endif  

 

WDK_VidPidQuery.cpp

[cpp] view plain copy print ?
  1. #include "WDK_VidPidQuery.h"  
  2. #include <tchar.h>  
  3. #include <setupapi.h>  
  4.   
  5. #pragma comment (lib, "Setupapi.lib")  
  6.   
  7. #define DeviceInstanceIdSize 256    // 设备实例ID最大长度  
  8.   
  9. // 获取系统的VID和PID集合  
  10. INT WINAPI WDK_WhoAllVidPid( HIDD_VIDPID* pVidPid, INT iCapacity, const GUID* SetupClassGuid, const GUID* InterfaceClassGuid )  
  11. {  
  12.     // 检测入口参数  
  13.     if (pVidPid == NULL || iCapacity <= 0) return 0;   
  14.   
  15.     // 根据设备安装类GUID创建空的设备信息集合  
  16.     HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList( SetupClassGuid, NULL );  
  17.     if (DeviceInfoSet == INVALID_HANDLE_VALUE) return -1;  
  18.       
  19.     // 根据设备安装类GUID获取设备信息集合  
  20.     HDEVINFO hDevInfo;  
  21.     if(InterfaceClassGuid == NULL)  
  22.         hDevInfo = SetupDiGetClassDevsEx( NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, DeviceInfoSet, NULL, NULL );  
  23.     else  
  24.         hDevInfo = SetupDiGetClassDevsEx( InterfaceClassGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, DeviceInfoSet, NULL, NULL );  
  25.   
  26.     if (hDevInfo == INVALID_HANDLE_VALUE) return -1;  
  27.   
  28.     // 存储得到的VID和PID数目  
  29.     INT iTotal = 0;  
  30.   
  31.     // 存储设备实例ID   
  32.     TCHAR DeviceInstanceId[DeviceInstanceIdSize];     
  33.   
  34.     // 存储设备信息数据  
  35.     SP_DEVINFO_DATA DeviceInfoData;                   
  36.     DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);  
  37.   
  38.     // 获取设备信息数据  
  39.     DWORD DeviceIndex = 0;  
  40.     while (SetupDiEnumDeviceInfo( hDevInfo, DeviceIndex++, &DeviceInfoData))  
  41.     {  
  42.         // 获取设备实例ID  
  43.         if (SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, DeviceInstanceId, DeviceInstanceIdSize, NULL))  
  44.         {  
  45.             // 从设备实例ID中提取VID和PID  
  46.             TCHAR* pVidIndex = _tcsstr(DeviceInstanceId, TEXT("VID_"));  
  47.             if (pVidIndex == NULL) continue;  
  48.   
  49.             TCHAR* pPidIndex = _tcsstr(pVidIndex + 4, TEXT("PID_"));  
  50.             if (pPidIndex == NULL) continue;  
  51.   
  52.             USHORT VendorID = _tcstoul(pVidIndex + 4, NULL, 16);  
  53.             USHORT ProductID = _tcstoul(pPidIndex + 4, NULL, 16);  
  54.   
  55.             // 剔除重复的VID和PID  
  56.             if (!WDK_isExistVidPid( VendorID, ProductID, pVidPid, iTotal ))  
  57.             {  
  58.                 pVidPid[iTotal].VendorID = VendorID;  
  59.                 pVidPid[iTotal].ProductID = ProductID;  
  60.                 if (++iTotal >= iCapacity) break;  
  61.             }  
  62.         }  
  63.     }  
  64.   
  65.     return iTotal;  
  66. }  
  67.   
  68. // 判断VID和PID是否已经存在  
  69. BOOL WINAPI WDK_isExistVidPid( USHORT VendorID, USHORT ProductID, const HIDD_VIDPID* pVidPid, INT iSize )  
  70. {  
  71.     if (pVidPid != NULL)  
  72.     {  
  73.         for (INT i = 0; i < iSize; i++)  
  74.         {  
  75.             if (pVidPid[i].VendorID == VendorID && pVidPid[i].ProductID == ProductID)  
  76.                 return TRUE;  
  77.         }  
  78.     }  
  79.   
  80.     return FALSE;  
  81. }  

 

你可能感兴趣的:(结合设备安装类GUID和设备接口类GUID获取设备VIDPID)