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

Retrieve serial number from USB memory (Windows environment c++)

本文关键字:Windows 环境 c++ 序列号 USB 存储器 检索      更新时间:2023-10-16

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

我想问你是否可以在C++和Windows环境(Visual C++)中分享一个例子

谢谢!

您可以查看这篇文章:-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或firewire磁盘):

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;
}