从 USB 存储器中检索序列号(Windows 环境 c++)

Posted

技术标签:

【中文标题】从 USB 存储器中检索序列号(Windows 环境 c++)【英文标题】:Retrieve serial number from USB memory (Windows environment c++) 【发布时间】:2013-08-12 20:25:50 【问题描述】:

我需要从我的 USB 存储器中检索序列号,即制造商分配的硬盘序列号。出于这个原因,我不能像其他一些线程中建议的那样使用 GetVolumeInformation() 。我需要有“唯一”号码

请问您能否分享一个在 C++ 和 Windows 环境(Visual c++)中的示例

谢谢!

【问题讨论】:

错误的假设。 USB 序列号与磁盘序列号无关。即使是 USB 鼠标也可以有序列号(实际上它们没有,因为鼠标没有身份,它们都是平等的) Get USB serial number c++的可能重复 感谢您对我的帖子的澄清。尽管如此,我还是需要提取 USB 存储器的序列号,因为如果我错了,请纠正我,它应该是一个唯一的 ID。我已经检查了您建议的帖子,确实有一个用于 Windows 环境的 c++ 示例,但是尽管我使用了 windows 平台 sdk,但我无法编译它 应该是。便宜的中国东西违反了大约一半的 USB 规范,只有微软的宽大处理才能让他们侥幸逃脱。特别是不要指望 USB 序列号。但退后一步:你认为你为什么需要这些? (可能是另一个问题的主题) 这不是真正的为什么。我发现唯一 ID 用于唯一标识。这就是缩写的含义。问题是 USB 存储设备的身份更多地由其上的内容(即文件)定义,而不是载体本身。 【参考方案1】:

你可以看看这篇文章:-http://oroboro.com/usb-serial-number/

#include <WinIOCtl.h>
#include <api/usbioctl.h>
#include <Setupapi.h>

DEFINE_GUID( GUID_DEVINTERFACE_USB_DISK,   
             0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 
             0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b );

void getDeviceInfo( int vol )

   UsbDeviceInfo info;

   // get the device handle
   char devicePath[7] = "\\\\.\\@:";
   devicePath[4] = (char)( vol + 'A' );

   HANDLE deviceHandle = CreateFile( devicePath, 0, 
                                     FILE_SHARE_READ | 
                                     FILE_SHARE_WRITE, NULL, 
                                     OPEN_EXISTING, 0, NULL );
   if ( deviceHandle == INVALID_HANDLE_VALUE )
      return;

   // to get the device number
   DWORD volumeDeviceNumber = getDeviceNumber( deviceHandle );
   CloseHandle( deviceHandle );

   // Get device interface info set handle
   // for all devices attached to the system
   HDEVINFO hDevInfo = SetupDiGetClassDevs( 
      &amp;GUID_DEVINTERFACE_USB_DISK, NULL, NULL,
      DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );

   if ( hDevInfo == INVALID_HANDLE_VALUE )  
        return;

   // 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, 
                                          &amp;GUID_DEVINTERFACE_USB_DISK, 
                                          dwIndex, &amp;spdid ))
         break;

      DWORD dwSize = 0;
      SetupDiGetDeviceInterfaceDetail( hDevInfo, &amp;spdid, NULL, 
                                       0, &amp;dwSize, NULL );

      if (( dwSize != 0 ) &amp;&amp; ( dwSize &lt;= sizeof( Buf )))
      
         pspdidd->cbSize = sizeof( *pspdidd ); // 5 Bytes!

         ZeroMemory((PVOID)&amp;spdd, sizeof(spdd));
         spdd.cbSize = sizeof(spdd);

         long res = SetupDiGetDeviceInterfaceDetail( 
            hDevInfo, &amp;spdid, pspdidd,
            dwSize, &amp;dwSize, &amp;spdd );
         if ( res ) 
         
            HANDLE hDrive = CreateFile( pspdidd-&gt;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-&gt;DevicePath );
               
            
            CloseHandle( hDrive );
         
      
      dwIndex++;
    

   SetupDiDestroyDeviceInfoList(hDevInfo);
   return;  

您可以通过使用设备句柄调用DeviceIOControl() 来获取设备号:

DWORD getDeviceNumber( HANDLE deviceHandle )

   STORAGE_DEVICE_NUMBER sdn;
   sdn.DeviceNumber = -1;
   DWORD dwBytesReturned = 0;
   if ( !DeviceIoControl( deviceHandle,
                          IOCTL_STORAGE_GET_DEVICE_NUMBER,
                          NULL, 0, &sdn, sizeof( sdn ),
                          &dwBytesReturned, NULL ) )
   
      // handle error - like a bad handle.
      return U32_MAX;
   
   return sdn.DeviceNumber;

接下来是一种识别卷是否为可移动媒体(例如 USB 或火线磁盘)的方法:

bool isRemovableMedia( s32 vol )

   char rootPath[5] = "@:\\";
   rootPath[0] = (char)( vol + 'A' );

   char szDosDeviceName[MAX_PATH];
   char dosDevicePath[3] = "@:";

   // get the drive type
   UINT DriveType = GetDriveType( rootPath );

   if ( DriveType != DRIVE_REMOVABLE )
      return false;

   dosDevicePath[0] = (char)( vol + 'A' );
   QueryDosDevice( dosDevicePath, szDosDeviceName, MAX_PATH );

   if ( strstr( szDosDeviceName,"\\Floppy") != NULL )
   
      // its a floppy
      return false;
   

   return true;

【讨论】:

确实需要在答案中包含足够的内容,以便在该链接失效时它仍然有用...... 谢谢。事实上,我尝试使用我可以使用oroboro.com/usb-serial-number 找到的示例,但我无法编译它,尽管我使用了正确的库。

以上是关于从 USB 存储器中检索序列号(Windows 环境 c++)的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core 2.1中获取USB存储设备的序列号

linux C++下的U盘序列号

无法从密钥环文件 secring.gpg 中检索密钥,因为它不存在

如何获取 USB 闪存驱动器的制造商序列号?

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

在 Windows Phone 中存储和检索 mp3 文件?