如何获取M.2硬盘的序列号

smarteyeexit 2017-10-26 10:49:05
之前获取IDE和Scsi硬盘时候,用的是DeviceIoControl方式来获取硬盘序列号,但是M.2硬盘就获取不到了,请高手给指点指点应该怎么获取M.2硬盘的序列号呢,没分了不好意思
...全文
2416 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
窝米逗佛~ 2019-06-06
  • 打赏
  • 举报
回复
引用 16 楼 qq_41506221 的回复:
[quote=引用 15 楼 潇潇-易水 的回复:] [quote=引用 14 楼 qq_41506221 的回复:] [quote=引用 13 楼 潇潇-易水的回复:]

hPhysicalDriveIOCTL = CreateFile( "\\\\.\\PhysicalDrive%d", 0,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, 0, NULL );
			STORAGE_PROPERTY_QUERY query;
			DWORD cbBytesReturned = 0;
			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( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
				&query,
				sizeof( query ),
				&local_buffer[ 0 ],
				sizeof( local_buffer ),
				&cbBytesReturned, NULL ) )


这样也不行么?
老大,可以帮忙转成c#或者vb的吗,C的不会啊 [/quote] c# 用的很少啊 对应的转译有点麻烦呢 简单解释下代码,然后你找对应的函数去实现一遍就是了 首先是打开 物理驱动号 即 PhysicalDrive0 这样的 c#应该也是一样的函数吧createfile 然后就是STORAGE_PROPERTY_QUERY 这个结构体 你需要专门找一下c#的封装 vc 里面是在ntddstor.h中 最后c#里面也是deviceiocontrol 吧 https://blog.csdn.net/zhangxizhicn/article/details/6754233 这里有个例子 [/quote] 我这样的方式应该跟你那种没什么区别,代码如下: Private Shared Function Read(ByVal drive As Byte) As String Dim driveName As String = String.Concat("\\.\PhysicalDrive", drive.ToString()) Dim device As Int32 = CreateFile( _ driveName, _ GENERIC_READ Or GENERIC_WRITE, _ FILE_SHARE_READ Or FILE_SHARE_WRITE, _ 0, _ OPEN_EXISTING, _ 0, _ 0) If device = INVALID_HANDLE_VALUE Then Return "" End If Dim verPara As New GETVERSIONOUTPARAMS() Dim bytRv As Int32 = 0 If DeviceIoControl( _ device, _ DFP_GET_VERSION, _ 0, _ 0, _ verPara, _ Marshal.SizeOf(verPara), _ bytRv, _ 0 _ ) <> 0 Then If verPara.bIDEDeviceMap > 0 Then Dim bIDCmd As Byte = CByte(IIf((verPara.bIDEDeviceMap >> drive And &H10) <> 0, IDE_ATAPI_IDENTIFY, IDE_ATA_IDENTIFY)) Dim scip As New SENDCMDINPARAMS() Dim scop As New SENDCMDOUTPARAMS() With scip .cBufferSize = IDENTIFY_BUFFER_SIZE .bDriveNumber = drive With .irDriveRegs .bFeaturesReg = 0 .bSectorCountReg = 1 .bCylLowReg = 0 .bCylHighReg = 0 .bDriveHeadReg = CByte((&HA0 Or ((drive And 1) << 4))) .bCommandReg = bIDCmd End With End With If DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA, scip, Marshal.SizeOf(scip), scop, Marshal.SizeOf(scop), bytRv, 0) <> 0 Then Dim s As New StringBuilder() Dim i As Integer For i = 20 To 40 - 2 Step 2 s.Append(ChrW(scop.bBuffer((i + 1)))) s.Append(ChrW(scop.bBuffer(i))) Next i CloseHandle(device) Return s.ToString().Trim() End If End If End If CloseHandle(device) Return "" End Function 这种方式需要管理员权限,但还是读不到序列号,我的硬盘是PCI接口的固态 [/quote] verPara 是STORAGE_DEVICE_DESCRIPTOR https://docs.microsoft.com/zh-cn/windows/desktop/api/winioctl/ns-winioctl-_storage_device_descriptor 然后取SerialNumberOffset ,, 就是序列号在verPara 内存中的起始位置,然后一直取到'\0'就是你要的序列号啊
qq_41506221 2019-06-06
  • 打赏
  • 举报
回复
把你的方式编译个exe或者dll,我试下看可以不
窝米逗佛~ 2019-06-05
  • 打赏
  • 举报
回复
引用 14 楼 qq_41506221 的回复:
[quote=引用 13 楼 潇潇-易水的回复:]

hPhysicalDriveIOCTL = CreateFile( "\\\\.\\PhysicalDrive%d", 0,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, 0, NULL );
			STORAGE_PROPERTY_QUERY query;
			DWORD cbBytesReturned = 0;
			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( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
				&query,
				sizeof( query ),
				&local_buffer[ 0 ],
				sizeof( local_buffer ),
				&cbBytesReturned, NULL ) )


这样也不行么?
老大,可以帮忙转成c#或者vb的吗,C的不会啊 [/quote] c# 用的很少啊 对应的转译有点麻烦呢 简单解释下代码,然后你找对应的函数去实现一遍就是了 首先是打开 物理驱动号 即 PhysicalDrive0 这样的 c#应该也是一样的函数吧createfile 然后就是STORAGE_PROPERTY_QUERY 这个结构体 你需要专门找一下c#的封装 vc 里面是在ntddstor.h中 最后c#里面也是deviceiocontrol 吧 https://blog.csdn.net/zhangxizhicn/article/details/6754233 这里有个例子
qq_41506221 2019-06-05
  • 打赏
  • 举报
回复
引用 15 楼 潇潇-易水 的回复:
[quote=引用 14 楼 qq_41506221 的回复:]
[quote=引用 13 楼 潇潇-易水的回复:]

hPhysicalDriveIOCTL = CreateFile( "\\\\.\\PhysicalDrive%d", 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL );
STORAGE_PROPERTY_QUERY query;
DWORD cbBytesReturned = 0;
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( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
&query,
sizeof( query ),
&local_buffer[ 0 ],
sizeof( local_buffer ),
&cbBytesReturned, NULL ) )



这样也不行么?

老大,可以帮忙转成c#或者vb的吗,C的不会啊
[/quote]
c# 用的很少啊 对应的转译有点麻烦呢
简单解释下代码,然后你找对应的函数去实现一遍就是了
首先是打开 物理驱动号 即 PhysicalDrive0 这样的 c#应该也是一样的函数吧createfile
然后就是STORAGE_PROPERTY_QUERY 这个结构体 你需要专门找一下c#的封装 vc 里面是在ntddstor.h中
最后c#里面也是deviceiocontrol 吧
https://blog.csdn.net/zhangxizhicn/article/details/6754233
这里有个例子
[/quote]

我这样的方式应该跟你那种没什么区别,代码如下:
Private Shared Function Read(ByVal drive As Byte) As String
Dim driveName As String = String.Concat("\\.\PhysicalDrive", drive.ToString())

Dim device As Int32 = CreateFile( _
driveName, _
GENERIC_READ Or GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
0, _
OPEN_EXISTING, _
0, _
0)

If device = INVALID_HANDLE_VALUE Then
Return ""
End If

Dim verPara As New GETVERSIONOUTPARAMS()
Dim bytRv As Int32 = 0


If DeviceIoControl( _
device, _
DFP_GET_VERSION, _
0, _
0, _
verPara, _
Marshal.SizeOf(verPara), _
bytRv, _
0 _
) <> 0 Then

If verPara.bIDEDeviceMap > 0 Then
Dim bIDCmd As Byte = CByte(IIf((verPara.bIDEDeviceMap >> drive And &H10) <> 0, IDE_ATAPI_IDENTIFY, IDE_ATA_IDENTIFY))

Dim scip As New SENDCMDINPARAMS()
Dim scop As New SENDCMDOUTPARAMS()

With scip
.cBufferSize = IDENTIFY_BUFFER_SIZE
.bDriveNumber = drive
With .irDriveRegs
.bFeaturesReg = 0
.bSectorCountReg = 1
.bCylLowReg = 0
.bCylHighReg = 0
.bDriveHeadReg = CByte((&HA0 Or ((drive And 1) << 4)))
.bCommandReg = bIDCmd
End With
End With

If DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA, scip, Marshal.SizeOf(scip), scop, Marshal.SizeOf(scop), bytRv, 0) <> 0 Then
Dim s As New StringBuilder()
Dim i As Integer
For i = 20 To 40 - 2 Step 2
s.Append(ChrW(scop.bBuffer((i + 1))))
s.Append(ChrW(scop.bBuffer(i)))
Next i

CloseHandle(device)

Return s.ToString().Trim()
End If
End If
End If

CloseHandle(device)

Return ""
End Function

这种方式需要管理员权限,但还是读不到序列号,我的硬盘是PCI接口的固态
qq_41506221 2019-06-04
  • 打赏
  • 举报
回复
引用 13 楼 潇潇-易水的回复:

hPhysicalDriveIOCTL = CreateFile( "\\\\.\\PhysicalDrive%d", 0,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, 0, NULL );
			STORAGE_PROPERTY_QUERY query;
			DWORD cbBytesReturned = 0;
			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( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
				&query,
				sizeof( query ),
				&local_buffer[ 0 ],
				sizeof( local_buffer ),
				&cbBytesReturned, NULL ) )


这样也不行么?
老大,可以帮忙转成c#或者vb的吗,C的不会啊
窝米逗佛~ 2019-06-04
  • 打赏
  • 举报
回复

hPhysicalDriveIOCTL = CreateFile( "\\\\.\\PhysicalDrive%d", 0,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, 0, NULL );
			STORAGE_PROPERTY_QUERY query;
			DWORD cbBytesReturned = 0;
			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( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
				&query,
				sizeof( query ),
				&local_buffer[ 0 ],
				sizeof( local_buffer ),
				&cbBytesReturned, NULL ) )


这样也不行么?
liups 2019-05-16
  • 打赏
  • 举报
回复
引用 9 楼 weixin_39282170 的回复:
[quote=引用 8 楼 weixin_39282170的回复:]我的HP SSD ex900固体硬盘是nvme接口的,装在pci卡槽,用什么方式才能读取到序列号呢 我用crystaldiskinfo工具是可以读取到的
系统是win10,目前用什么方式都读不到序列号[/quote] 你按这个试一下先:https://blog.csdn.net/liups/article/details/90261294
liups 2019-05-16
  • 打赏
  • 举报
回复
引用 9 楼 weixin_39282170 的回复:
[quote=引用 8 楼 weixin_39282170的回复:]我的HP SSD ex900固体硬盘是nvme接口的,装在pci卡槽,用什么方式才能读取到序列号呢 我用crystaldiskinfo工具是可以读取到的
系统是win10,目前用什么方式都读不到序列号[/quote] 如果是wmi方式建议直接使用wmi工具先手工查一下,看问题出在哪里,工具可以参考这里: https://blog.csdn.net/cosmoslife/article/details/8226500
weixin_39282170 2019-05-16
  • 打赏
  • 举报
回复
引用 8 楼 weixin_39282170的回复:
我的HP SSD ex900固体硬盘是nvme接口的,装在pci卡槽,用什么方式才能读取到序列号呢 我用crystaldiskinfo工具是可以读取到的
系统是win10,目前用什么方式都读不到序列号
weixin_39282170 2019-05-16
  • 打赏
  • 举报
回复
我的HP SSD ex900固体硬盘是nvme接口的,装在pci卡槽,用什么方式才能读取到序列号呢 我用crystaldiskinfo工具是可以读取到的
weixin_39282170 2019-05-16
  • 打赏
  • 举报
回复
引用 11 楼 liups的回复:
[quote=引用 9 楼 weixin_39282170 的回复:] [quote=引用 8 楼 weixin_39282170的回复:]我的HP SSD ex900固体硬盘是nvme接口的,装在pci卡槽,用什么方式才能读取到序列号呢 我用crystaldiskinfo工具是可以读取到的
系统是win10,目前用什么方式都读不到序列号[/quote] 你按这个试一下先:https://blog.csdn.net/liups/article/details/90261294[/quote] 我试了这个,也是读不到
liups 2019-05-16
  • 打赏
  • 举报
回复
关于空格的问题我已经记不清原始的那个硬盘了,这里有其他的相关资料: https://blog.csdn.net/qq61394323/article/details/25052711
liups 2019-05-15
  • 打赏
  • 举报
回复
以前有一个联想本本,加了一个M.2 2242,当时测试是能通过WMI读取的。另外,碰到过一种不能读取的,其实是因为序列号前面有空格,有些程序没有考虑这种情况,所以结果为空(我碰到的实际上是ATA硬盘)。最后一种就是没有序列号的,这种情况确实存在。
weixin_39282170 2019-05-15
  • 打赏
  • 举报
回复
引用 4 楼 liups的回复:
[quote=引用 3 楼 qq_41506221 的回复:] 怎么读取的啊,老大,能分享下吗
WMI 硬盘序列号 实际上不管什么接口,基本都模拟成ATA接口的,所以才序列号的,因为本来就是ATA标准[/quote] 目前固态硬盘的序列号读取不到啊,好恼火
liups 2019-05-15
  • 打赏
  • 举报
回复
引用 3 楼 qq_41506221 的回复:
怎么读取的啊,老大,能分享下吗
WMI 硬盘序列号 实际上不管什么接口,基本都模拟成ATA接口的,所以才序列号的,因为本来就是ATA标准
qq_41506221 2019-05-15
  • 打赏
  • 举报
回复
怎么读取的啊,老大,能分享下吗
smarteyeexit 2017-10-26
  • 打赏
  • 举报
回复
@赵4老师 谢谢,提取出序列号了
赵4老师 2017-10-26
  • 打赏
  • 举报
回复
奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中! 搜“WMI 硬盘序列号”

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧