从 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(
&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,
&GUID_DEVINTERFACE_USB_DISK,
dwIndex, &spdid ))
break;
DWORD dwSize = 0;
SetupDiGetDeviceInterfaceDetail( hDevInfo, &spdid, NULL,
0, &dwSize, NULL );
if (( dwSize != 0 ) && ( dwSize <= sizeof( Buf )))
pspdidd->cbSize = sizeof( *pspdidd ); // 5 Bytes!
ZeroMemory((PVOID)&spdd, sizeof(spdd));
spdd.cbSize = sizeof(spdd);
long res = SetupDiGetDeviceInterfaceDetail(
hDevInfo, &spdid, pspdidd,
dwSize, &dwSize, &spdd );
if ( res )
HANDLE hDrive = CreateFile( pspdidd->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->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++)的主要内容,如果未能解决你的问题,请参考以下文章