简体   繁体   中英

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

I would need to retrieve the serial number from my USB memory, namely the hard disk's serial number that the manufacturer assigns. For this reason I cannot use GetVolumeInformation() as suggested in some other threads. I would need to have the "unique" number

I kindly ask you if you can share an example in C++ and Windows environment (Visual c++)

Thanks!

You can check out this article:- 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;  
}

You get the device number by calling DeviceIOControl() with the handle to your device:

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

Next here is a method to recognize if a volume is removable media (eg like a usb or firewire disk):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM