查询硬盘序号总结
查询硬盘序号总结
问题描述
刚开始获取硬件信息的时候找了很多方法,但最终效果并不是特别好,直到现在找到了可靠的方法,现在总结下来,希望你能在这里得到一些思路。
查询硬盘序号的方法
正确的序列号,使用软件CrystalDiskInfo
或者AIDA64
可以查询到。
一、WMI
这两种方式应该没有太大区分
WMI
命令行
wmic diskdrive get serialnumber
效果:
WQL工具
二、DeviceIoControl
参考链接,以下是部分代码,不完全。
/************************************************************************
GetHDSerial:用于获取指定编号的硬盘序列号,无需任何权限提升
参数:
PCHAR pszIDBuff:传入的字符串缓冲区,用于接收硬盘序列号
int nBuffLen:传入的字符串缓冲区大小,当硬盘序列号大于该值时,只复制nBuffLen长度
int nDriveID:要获取的驱动器编号,从0开始,到15为止
返回值:
成功获取到的硬盘序列号长度,为0表示获取失败
作者:
famous214(blog.csdn.net/LPWSTR)
源码参考了diskid32(https://www.winsim.com/diskid32/diskid32.html)
版本历史:
20171226 第一版,从diskid32源码中提取
20171226 第二版,兼容Unicode编译方式
20171230 重构后发布第三版
************************************************************************/
ULONG GetHDSerial(PCHAR pszIDBuff, int nBuffLen, int nDriveID)
{
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
ULONG ulSerialLen = 0;
__try
{
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
TCHAR szDriveName[32];
wsprintf(szDriveName, TEXT("\\\\.\\PhysicalDrive%d"), nDriveID);
// Windows NT, Windows 2000, Windows XP - admin rights not required
hPhysicalDrive = CreateFile(szDriveName, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hPhysicalDrive == INVALID_HANDLE_VALUE)
{
__leave;
}
STORAGE_PROPERTY_QUERY query;
DWORD cbBytesReturned = 0;
static char local_buffer[10000];
memset((void*)&query, 0, sizeof(query));
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
memset(local_buffer, 0, sizeof(local_buffer));
if (DeviceIoControl(hPhysicalDrive, IOCTL_STORAGE_QUERY_PROPERTY,
&query,
sizeof(query),
&local_buffer[0],
sizeof(local_buffer),
&cbBytesReturned, NULL))
{
STORAGE_DEVICE_DESCRIPTOR* descrip = (STORAGE_DEVICE_DESCRIPTOR*)&local_buffer;
char serialNumber[1000];
flipAndCodeBytes(local_buffer,
descrip->SerialNumberOffset,
1, serialNumber);
if (isalnum(serialNumber[0]))
{
ULONG ulSerialLenTemp = strnlen(serialNumber, nBuffLen - 1);
memcpy(pszIDBuff, serialNumber, ulSerialLenTemp);
pszIDBuff[ulSerialLenTemp] = NULL;
ulSerialLen = ulSerialLenTemp;
__leave;
}
}
}
__finally
{
if (hPhysicalDrive != INVALID_HANDLE_VALUE)
{
CloseHandle(hPhysicalDrive);
}
return ulSerialLen;
}
}
void GetAllHDSerial(void)
{
const int MAX_IDE_DRIVES = 16;
static char szBuff[0x100];
for (int nDriveNum = 0; nDriveNum < MAX_IDE_DRIVES; nDriveNum++)
{
ULONG ulLen = GetHDSerial(szBuff, sizeof(szBuff), nDriveNum);
if (ulLen > 0)
{
std::cout << nDriveNum + 1 << "," << szBuff << endl;
// _tprintf(TEXT("第%d块硬盘的序列号为:%hs\n"), nDriveNum + 1, szBuff);
}
}
}
效果:
三、Smartmontools
这个工具是监控硬盘用的,里面包含了硬件信息我顺便拿过来测试了下,开源有代码,以命令行的形式还是可能用在程序里面的,主页。
四、CrystalDiskInfo
没想到这个软件也是可以下到源代码的,主页。
查看了内部实现的代码,本质上也就是DeviceIoControl
+WQL
的方式再把硬盘的序列号提取再拼凑起来的,这时才明白过来看似简单的得到硬盘序号并没有想象的那么简单。
相关代码已上传,
下载地址:https://www.123pan.com/s/R0XNjv-QwxGd.html提取码:6666
最后
感谢各位大佬的无私奉献。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?