首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

为什么小弟我的获取硬盘序列号的代码,在有些电脑下没法获取到硬盘序列号,即返回值为空白

2013-01-19 
为什么我的获取硬盘序列号的代码,在有些电脑上没法获取到硬盘序列号,即返回值为空白?本帖最后由 bcrun 于

为什么我的获取硬盘序列号的代码,在有些电脑上没法获取到硬盘序列号,即返回值为空白?
本帖最后由 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驱动程序有关。
------解决方案--------------------


引用:
目前网上流行的程序只能取得IDE硬盘物理序列号,SATA硬盘物理序列号不好获取,跟SATA驱动程序有关。


你说错了,网上N多程序都可以返回SATA硬盘的,我硬盘就是SATA一样返回得到序列号

热点排行