为什么我的获取硬盘序列号的代码,在有些电脑上没法获取到硬盘序列号,即返回值为空白?
本帖最后由 bcrun 于 2012-12-26 20:13:55 编辑
'取得硬盘信息:型号/物理系列号(唯一)
Function GetHardDiskInfo(Optional ByVal numDisk As eumDiskNo = hdPrimaryMaster, Optional ByVal numType As eumInfoType = hdOnlySN) As String
On Error GoTo Errc
If GetDiskInfo(numDisk) = 1 Then
Dim pSerialNumber As String, pModelNumber As String
pSerialNumber = StrConv(m_DiskInfo.sSerialNumber, vbUnicode)
pModelNumber = StrConv(m_DiskInfo.sModelNumber, vbUnicode)
Select Case numType
Case hdOnlyModel '仅型号
GetHardDiskInfo = Trim(pModelNumber)
Case hdOnlySN '仅系列号
GetHardDiskInfo = Trim(pSerialNumber)
Case Else '型号,系列号
GetHardDiskInfo = Trim(pModelNumber) & "," & Trim(pSerialNumber)
End Select
End If
Dim l#, i#, str As String
str = GetHardDiskInfo
GetHardDiskInfo = Left(str, 20)
l# = Len(GetHardDiskInfo)
For i# = 1 To l#
str = Mid(GetHardDiskInfo, i#, 1)
If 32 < asc(str) And asc(str) < 127 Then
Else
Mid(GetHardDiskInfo, i#, 1) = "0"
End If
Next i#
Exit Function
Errc:
If Err.Description <> "" Then MsgBox Err.Description
End Function
Private Function OpenSMART(ByVal nDrive As Byte) As Long
Dim hSMARTIOCTL As Long
Dim hd As String
Dim VersionInfo As OSVERSIONINFO
hSMARTIOCTL = INVALID_HANDLE_VALUE
VersionInfo.dwOSVersionInfoSize = Len(VersionInfo)
GetVersionEx VersionInfo
Select Case VersionInfo.dwPlatformId
Case VER_PLATFORM_WIN32s
OpenSMART = hSMARTIOCTL
Case VER_PLATFORM_WIN32_WINDOWS
hSMARTIOCTL = CreateFile("\\.\SMARTVSD", 0, 0, 0, CREATE_NEW, 0, 0)
Case VER_PLATFORM_WIN32_NT
If nDrive < MAX_IDE_DRIVES Then
hd = "\\.\PhysicalDrive" & nDrive
hSMARTIOCTL = CreateFile(hd, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
End If
End Select
OpenSMART = hSMARTIOCTL
End Function
Private Function DoIDENTIFY(ByVal hSMARTIOCTL As Long, pSCIP As SENDCMDINPARAMS, pSCOP() As Byte, ByVal bIDCmd As Byte, ByVal bDriveNum As Byte, lpcbBytesReturned As Long) As Boolean
pSCIP.cBufferSize = IDENTIFY_BUFFER_SIZE
pSCIP.irDriveRegs.bFeaturesReg = 0
pSCIP.irDriveRegs.bSectorCountReg = 1
pSCIP.irDriveRegs.bSectorNumberReg = 1
pSCIP.irDriveRegs.bCylLowReg = 0
pSCIP.irDriveRegs.bCylHighReg = 0
pSCIP.irDriveRegs.bDriveHeadReg = &HA0 Or ((bDriveNum And 1) * 2 ^ 4)
'
pSCIP.irDriveRegs.bCommandReg = bIDCmd
pSCIP.bDriveNumber = bDriveNum
pSCIP.cBufferSize = IDENTIFY_BUFFER_SIZE
DoIDENTIFY = CBool(DeviceIoControl(hSMARTIOCTL, DFP_RECEIVE_DRIVE_DATA, _
pSCIP, 32, _
pSCOP(0), 528, _
lpcbBytesReturned, 0))
End Function
Private Sub ChangeByteOrder(szString() As Byte, ByVal uscStrSize As Integer)
Dim i As Integer
Dim bTemp As Byte
For i = 0 To uscStrSize - 1 Step 2
bTemp = szString(i)
szString(i) = szString(i + 1)
szString(i + 1) = bTemp
Next i
End Sub
Private Sub DisplayIdInfo(pids As IDSECTOR, pSCIP As SENDCMDINPARAMS, ByVal bIDCmd As Byte, ByVal bDfpDriveMap As Byte, ByVal bDriveNum As Byte)
ChangeByteOrder pids.sModelNumber, UBound(pids.sModelNumber) + 1
ChangeByteOrder pids.sFirmwareRev, UBound(pids.sFirmwareRev) + 1
ChangeByteOrder pids.sSerialNumber, UBound(pids.sSerialNumber) + 1
End Sub
Public Function GetDiskInfo(ByVal nDrive As Byte) As Long
Dim hSMARTIOCTL As Long
Dim cbBytesReturned As Long
Dim VersionParams As GETVERSIONOUTPARAMS
Dim scip As SENDCMDINPARAMS
Dim scop() As Byte
Dim OutCmd As SENDCMDOUTPARAMS
Dim bDfpDriveMap As Byte
Dim bIDCmd As Byte ' IDE or ATAPI IDENTIFY cmd
Dim uDisk As IDSECTOR
m_DiskInfo = uDisk
'
'
hSMARTIOCTL = OpenSMART(nDrive)
If hSMARTIOCTL <> INVALID_HANDLE_VALUE Then
Call DeviceIoControl(hSMARTIOCTL, DFP_GET_VERSION, ByVal 0, 0, VersionParams, Len(VersionParams), cbBytesReturned, 0)
If Not (VersionParams.bIDEDeviceMap \ 2 ^ nDrive And &H10) Then
If DoEnableSMART(hSMARTIOCTL, scip, OutCmd, nDrive, cbBytesReturned) Then
bDfpDriveMap = bDfpDriveMap Or 2 ^ nDrive
End If
End If
bIDCmd = IIf((VersionParams.bIDEDeviceMap \ 2 ^ nDrive And &H10), IDE_ATAPI_ID, IDE_ID_FUNCTION)
ReDim scop(LenB(OutCmd) + IDENTIFY_BUFFER_SIZE - 1) As Byte
If DoIDENTIFY(hSMARTIOCTL, scip, scop, bIDCmd, nDrive, cbBytesReturned) Then
CopyMemory m_DiskInfo, scop(LenB(OutCmd) - 4), LenB(m_DiskInfo)
Call DisplayIdInfo(m_DiskInfo, scip, bIDCmd, bDfpDriveMap, nDrive)
CloseHandle hSMARTIOCTL
GetDiskInfo = 1
Exit Function '>---> Bottom
End If
CloseHandle hSMARTIOCTL
GetDiskInfo = 0
Else 'NOT HSMARTIOCTL...
GetDiskInfo = -1
End If
End Function
[解决办法]
楼主弄的是物理硬盘出厂时的序列号,还是软件格式化磁盘分区时的那个卷的序列号啊
[解决办法]
的确有这个问题,应该是和硬盘的代次和型号有关
[解决办法]
这是利用SMART接口获取硬盘序列号的代码.
如果不能成功,不一定是代码的问题,运行环境也有很多因素会造成获取失败.
比如,主板驱动不正常,硬盘驱动不正常,或者程序没有相应的权限等.
建议你在不能正常获取的机器上运行一下HDTune这个硬盘检测软件,它好象也是利用SMART接口的,看看在info选项卡里能否得到Serial项的内容.
如果HDTune能获取而你的程序不能获取,那时再找找原因不迟.
[解决办法]
不使用SMART接口的话可能就只有自己写个驱动去直接与硬盘通讯了.
这个我就没办法啦!
[解决办法]
我也一直困扰与此...
[解决办法]
其实可以利用现成的比如Safengine里的那个SESDKDummy.dll,他直接可以返回所有硬件和bios的参数计算出来的一个码,你可以调用他的
[解决办法]
不知道这个的输出有没有你要的SN
Const strComputer As String = "."
Dim strClass As String
Dim wbemServices As Object
Dim wbemObjectSet As Object
Dim wbemObject As Object
Dim p As Object
Set wbemServices = GetObject("winmgmts:\\" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("CIM_DiskDrive")
For Each wbemObject In wbemObjectSet
Debug.Print "-------Properties---"
For Each p In wbemObject.Properties_
Debug.Print p.Name; ":"; ConvPVtoStr(p.Value)
Next
Debug.Print "-------System Properties---"
For Each p In wbemObject.SystemProperties_
Debug.Print p.Name; ":"; ConvPVtoStr(p.Value)
Next
Next
-------Properties---
Availability:
BytesPerSector:512
Capabilities:3,4
CapabilityDescriptions:
Caption:FUJITSU MJA2250BH G2
CompressionMethod:
ConfigManagerErrorCode:0
ConfigManagerUserConfig:False
CreationClassName:Win32_DiskDrive
DefaultBlockSize:
Description:磁盘驱动器
DeviceID:\\.\PHYSICALDRIVE0
ErrorCleared:
ErrorDescription:
ErrorMethodology:
Index:0
InstallDate:
InterfaceType:IDE
LastErrorCode:
Manufacturer:(标准磁盘驱动器)
MaxBlockSize:
MaxMediaSize:
MediaLoaded:True
MediaType:Fixed hard disk media
MinBlockSize:
Model:FUJITSU MJA2250BH G2
Name:\\.\PHYSICALDRIVE0
NeedsCleaning:
NumberOfMediaSupported:
Partitions:4
PNPDeviceID:IDE\DISKFUJITSU_MJA2250BH_G2____________________0084001C\5&4AEFDA8&0&0.0.0
PowerManagementCapabilities:
PowerManagementSupported:
SCSIBus:0
SCSILogicalUnit:0
SCSIPort:0
SCSITargetId:0
SectorsPerTrack:63
Signature:1064714101
Size:250056737280
Status:OK
StatusInfo:
SystemCreationClassName:Win32_ComputerSystem
SystemName:BJZJ-YANGWEI
TotalCylinders:30401
TotalHeads:255
TotalSectors:488392065
TotalTracks:7752255
TracksPerCylinder:255
-------System Properties---
__PATH:\\BJZJ-YANGWEI\root\cimv2:Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"
__NAMESPACE:root\cimv2
__SERVER:BJZJ-YANGWEI
__DERIVATION:CIM_DiskDrive,CIM_MediaAccessDevice,CIM_LogicalDevice,CIM_LogicalElement,CIM_ManagedSystemElement
__PROPERTY_COUNT:49
__RELPATH:Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"
__DYNASTY:CIM_ManagedSystemElement
__SUPERCLASS:CIM_DiskDrive
__CLASS:Win32_DiskDrive
__GENUS:2
[解决办法]
CBool(DeviceIoControl(这个是向驱动层读取信息的,如果读取失败,估计很难。。。
[解决办法]
目前网上流行的程序只能取得IDE硬盘物理序列号,SATA硬盘物理序列号不好获取,跟SATA驱动程序有关。
------解决方案--------------------
你说错了,网上N多程序都可以返回SATA硬盘的,我硬盘就是SATA一样返回得到序列号