windows平台下获取USB设备“身份证”

  当我们将U盘插入windows主机时,会提示安装驱动,那么windows是如何判断应该安装哪个版本的驱动的呢?在这里将用到设备的身份信息,包括厂商、型号、序列号等。大概半年前做了一个关于设备检测的小工程,看了很多资料和帖子,将获取设备身份信息的方法在此记录,方便以后使用。

0x01 USB设备有哪些身份信息

  根据USB规范中的说明USB规范官方文档,供应商ID(VID)/产品识别码(PID)唯一标识一个设备,VID和PID都是两个字节长,其中,供应商ID(VID)由供应商向USB执行论坛申请,每个供应商的VID是唯一的,PID由供应商自行决定,理论上来说,不同的产品、相同产品的不同型号、相同型号的不同设计的产品最好采用不同的PID,以便区别相同厂家的不同设备。
  在windows系统中,我们可以通过设备管理器->要查看的设备->属性->详细信息->硬件ID来查看VID/PID,如下图



0x02 获取USB设备VID/PID

  下面将介绍枚举USB设备VID/PID的方法,后面会抽时间写一篇介绍如何通过U盘盘符获取U盘VID、PID的文章。
  首先需要USB设备类GUID,设备管理器->通用串行总线控制器->随便选择一个设备->右键->属性->详细信息->设备类GUID,通用串行总线控制器的设备类GUID{36fc9e60-c465-11cf-8056-444553540000}。构造GUID,用SetupDiGetClassDevs获取设备信息结构的句柄,该结构包含了所有已安装USB设备。再调用SetupDiEnumDeviceInfo枚举设备实例,之后再调用SetupDiGetDeviceRegistryProperty即能获取硬件ID。核心代码如下:

      
       1
      
      
       2
      
      
       3
      
      
       4
      
      
       5
      
      
       6
      
      
       7
      
      
       8
      
      
       9
      
      
       10
      
      
       11
      
      
       12
      
      
       13
      
      
       14
      
      
       15
      
      
       16
      
      
       17
      
      
       18
      
      
       19
      
      
       20
      
      
       21
      
      
       22
      
      
       23
      
      
       24
      
      
       25
      
      
       26
      
      
       27
      
      
       28
      
      
       29
      
      
       30
      
      
       31
      
      
       32
      
      
       33
      
      
       34
      
      
       35
      
      
       36
      
      
       37
      
      
       38
      
      
       39
      
      
       40
      
      
       41
      
      
       42
      
      
       GUID USBGuid = { 
       0x36fc9e60, 
       0xc465, 
       0x11cf, { 
       0x80, 
       0x56, 
       0x44, 
       0x45, 
       0x53, 
       0x54, 
       0x00, 
       0x00} }
      
      
       HDEVINFO hDevInfo = SetupDiGetClassDevs(&USBGuid, NULL, NULL, 
       DIGCF_PRESENT);
      
      
       ...
      
      
       for (int Device_Index = 
       0
       ;; Device_Index++)
      
      
       {
      
      
       	...
      
          
       BOOL 
       bResualt = SetupDiEnumDeviceInfo(hDevInfo, Device_Index, &tDevData)
      
      
           ...
      
          
       bResualt = SetupDiGetDeviceRegistryProperty(hDevInfo,
      
      
       			&tDevData,
      
      
       			SPDRP_HARDWAREID,
      
      
       			NULL,
      
      
       			NULL,
      
      			
       0,
      
      
       			&RequiredSize)
      
      
       	if (!
       bResualt)
      
      
        {
      
      
       		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      
      
       		{
      
      			
       BYTE *PropertBuffer = (
       BYTE*)malloc(RequiredSize);
      
      
        		
       bResualt = SetupDiGetDeviceRegistryProperty(hDevInfo,
      
      
       				&tDevData,
      
      
       				SPDRP_HARDWAREID,
      
      
       				NULL,
      
      
       				PropertBuffer,
      
      
       				RequiredSize,
      
      
       				NULL)
      
      
       			if (
       bResualt)
      
      
        		{
      
      
       				TCHAR *HID = (TCHAR*)PropertBuffer
      
      
       				wprintf(L
       "%s n", HID)
      
      
           		}
      
      
       			else
      
      
       			{
      
      
       					free(PropertBuffer)
      
      
       					return FALSE
      
      
       			}
      
      
       		}
      
      
       	}
      
      
       	...
      
      
      
       }
      

程序运行效果


完整工程下载

原文:大专栏  windows平台下获取USB设备“身份证”