admin管理员组

文章数量:1532656

2024年2月17日发(作者:)

获取硬盘序列号的代码

网上有很多获取硬盘序列号的代码,但大部分都只能取得逻辑分区的序列号,而不能取得硬盘的物理序列号。我们知道,逻辑分区的序列号是FORMAT时产生的,重新FORMAT将会改变。这对于要求唯一识别码的程式来说是致命的。这段代码利用API可以取得物理硬盘的很多特性,包括硬盘出厂时的唯一编号。这段代码我是从CSDN论坛获得,原作者不详。我将其稍做修改和增添,独立出两个常用的函数:GetDiskVolume 、GetHardDiskInfo ......

'============================================

'模块功能: 取得硬盘的信息

'编 程:来自互联网,阿勇修改

'更新日期:2005/7/8

'调用方法:

' GetDiskVolume() 取得逻辑盘的序列号

' GetHardDiskInfo() 取得物理盘的型号或序列号

'============================================

Private Const MAX_IDE_DRIVES As Long = 4 ' Max number

of drives assuming primary/secondary, master/slave topology

Private Const READ_ATTRIBUTE_BUFFER_SIZE As Long = 512

Private Const IDENTIFY_BUFFER_SIZE As Long = 512

Private Const READ_THRESHOLD_BUFFER_SIZE As Long =

512

Private Const DFP_GET_VERSION As Long = &H74080

Private Const DFP_SEND_DRIVE_COMMAND As Long =

&H7C084

Private Const DFP_RECEIVE_DRIVE_DATA As Long =

&H7C088

Private Type GETVERSIONOUTPARAMS

bVersion As Byte ' Binary driver version.

bRevision As Byte ' Binary driver revision.

bReserved As Byte ' Not used.

bIDEDeviceMap As Byte ' Bit map of IDE devices.

fCapabilities As Long ' Bit mask of driver capabilities.

dwReserved(3) As Long ' For future use.

End Type

Private Const CAP_IDE_ID_FUNCTION As Long = 1 ' ATA ID

command supported

Private Const CAP_IDE_ATAPI_ID As Long = 2 ' ATAPI ID

command supported

Private Const CAP_IDE_EXECUTE_SMART_FUNCTION As

Long = 4 ' SMART commannds supported

Private Type IDEREGS

bFeaturesReg As Byte ' Used for specifying SMART

"commands".

bSectorCountReg As Byte ' IDE sector count register

bSectorNumberReg As Byte ' IDE sector number register

bCylLowReg As Byte ' IDE low order cylinder value

bCylHighReg As Byte ' IDE high order cylinder value

bDriveHeadReg As Byte ' IDE drive/head register

bCommandReg As Byte ' Actual IDE command.

bReserved As Byte ' reserved for future use. Must be zero.

End Type

Private Type SENDCMDINPARAMS

cBufferSize As Long ' Buffer size in bytes

irDriveRegs As IDEREGS ' Structure with drive register values.

bDriveNumber As Byte ' Physical drive number to send

' command to (0,1,2,3).

bReserved(2) As Byte ' Reserved for future expansion.

dwReserved(3) As Long ' For future use.

bBuffer(0) As Byte ' Input buffer.

End Type

Private Const IDE_ATAPI_ID As Long = &HA1 ' Returns ID

sector for ATAPI.

Private Const IDE_ID_FUNCTION As Long = &HEC ' Returns

ID sector for ATA.

Private Const IDE_EXECUTE_SMART_FUNCTION As Long =

&HB0 ' Performs SMART cmd.

Private Const SMART_CYL_LOW As Long = &H4F

Private Const SMART_CYL_HI As Long = &HC2

Private Type DRIVERSTATUS

bDriverError As Byte ' Error code from driver,

bIDEStatus As Byte ' Contents of IDE Error register.

bReserved(1) As Byte ' Reserved for future expansion.

dwReserved(1) As Long ' Reserved for future expansion.

End Type

Private Const SMART_NO_ERROR As Long = 0 ' No error

Private Const SMART_IDE_ERROR As Long = 1 ' Error from

IDE controller

Private Const SMART_INVALID_FLAG As Long = 2 ' Invalid

command flag

Private Const SMART_INVALID_COMMAND As Long = 3 '

Invalid command byte

Private Const SMART_INVALID_BUFFER As Long = 4 ' Bad

buffer (null, invalid addr..)

Private Const SMART_INVALID_DRIVE As Long = 5 ' Drive

number not valid

Private Const SMART_INVALID_IOCTL As Long = 6 ' Invalid

IOCTL

Private Const SMART_ERROR_NO_MEM As Long = 7 ' Could

not lock user's buffer

Private Const SMART_INVALID_REGISTER As Long = 8 ' Some

IDE Register not valid

Private Const SMART_NOT_SUPPORTED As Long = 9 ' Invalid

cmd flag set

Private Const SMART_NO_IDE_DEVICE As Long = 10 ' Cmd

issued to device not present

Private Type SENDCMDOUTPARAMS

cBufferSize As Long ' Size of bBuffer in bytes

drvStatus As DRIVERSTATUS ' Driver status structure.

bBuffer(0) As Byte ' Buffer of arbitrary length in which to

store the data read from the ' drive.

End Type

Private Const SMART_READ_ATTRIBUTE_VALUES As Long =

&HD0 ' ATA4: Renamed

Private Const SMART_READ_ATTRIBUTE_THRESHOLDS As

Long = &HD1 ' Obsoleted in ATA4!

Private

&HD2

Private Const SMART_SAVE_ATTRIBUTE_VALUES As Long =

&HD3

Private Const SMART_EXECUTE_OFFLINE_IMMEDIATE As

Long = &HD4 ' ATA4

Private Const SMART_ENABLE_SMART_OPERATIONS As

Long = &HD8

Private Const SMART_DISABLE_SMART_OPERATIONS As

Long = &HD9

Private Const SMART_RETURN_SMART_STATUS As Long =

&HDA

Private Type DRIVEATTRIBUTE

bAttrID As Byte ' Identifies which attribute

wStatusFlags As Integer ' see bit definitions below

bAttrValue As Byte ' Current normalized value

bWorstValue As Byte ' How bad has it ever been?

bRawValue(5) As Byte ' Un-normalized value

bReserved As Byte ' ...

End Type

Private Type ATTRTHRESHOLD

bAttrID As Byte ' Identifies which attribute

bWarrantyThreshold As Byte ' Triggering value

bReserved(9) As Byte ' ...

End Type

Const

SMART_ENABLE_DISABLE_ATTRIBUTE_AUTOSAVE As Long =

Private Type IDSECTOR

wGenConfig As Integer

wNumCyls As Integer

wReserved As Integer

wNumHeads As Integer

wBytesPerTrack As Integer

wBytesPerSector As Integer

wSectorsPerTrack As Integer

wVendorUnique(2) As Integer

sSerialNumber(19) As Byte

wBufferType As Integer

wBufferSize As Integer

wECCSize As Integer

sFirmwareRev(7) As Byte

sModelNumber(39) As Byte

wMoreVendorUnique As Integer

wDoubleWordIO As Integer

wCapabilities As Integer

wReserved1 As Integer

wPIOTiming As Integer

wDMATiming As Integer

wBS As Integer

wNumCurrentCyls As Integer

wNumCurrentHeads As Integer

wNumCurrentSectorsPerTrack As Integer

ulCurrentSectorCapacity(3) As Byte '这里只能用byte,因为VB没有无符号的LONG型变量

wMultSectorStuff As Integer

ulTotalAddressableSectors(3) As Byte '这里只能用byte,因为

VB没有无符号的LONG型变量

wSingleWordDMA As Integer

wMultiWordDMA As Integer

bReserved(127) As Byte

End Type

Private Const ATTR_INVALID As Long = 0

Private Const ATTR_READ_ERROR_RATE As Long = 1

Private Const ATTR_THROUGHPUT_PERF As Long = 2

Private Const ATTR_SPIN_UP_TIME As Long = 3

Private Const ATTR_START_STOP_COUNT As Long = 4

Private Const ATTR_REALLOC_SECTOR_COUNT As Long = 5

Private Const ATTR_READ_CHANNEL_MARGIN As Long = 6

Private Const ATTR_SEEK_ERROR_RATE As Long = 7

Private Const ATTR_SEEK_TIME_PERF As Long = 8

Private Const ATTR_POWER_ON_HRS_COUNT As Long = 9

Private Const ATTR_SPIN_RETRY_COUNT As Long = 10

Private Const ATTR_CALIBRATION_RETRY_COUNT As Long =

11

Private Const ATTR_POWER_CYCLE_COUNT As Long = 12

Private Const PRE_FAILURE_WARRANTY As Long = &H1

Private Const ON_LINE_COLLECTION As Long = &H2

Private Const PERFORMANCE_ATTRIBUTE As Long = &H4

Private Const ERROR_RATE_ATTRIBUTE As Long = &H8

Private Const EVENT_COUNT_ATTRIBUTE As Long = &H10

Private Const SELF_PRESERVING_ATTRIBUTE As Long =

&H20

Private Const NUM_ATTRIBUTE_STRUCTS As Long = 30

Private Const INVALID_HANDLE_VALUE As Long = -1

Private Const VER_PLATFORM_WIN32s As Long = 0

Private Const VER_PLATFORM_WIN32_WINDOWS As Long =

1

Private Const VER_PLATFORM_WIN32_NT As Long = 2

Private Type OSVERSIONINFO

dwOSVersionInfoSize As Long

dwMajorVersion As Long

dwMinorVersion As Long

dwBuildNumber As Long

dwPlatformId As Long

szCSDVersion As String * 128 ' Maintenance string for PSS

usage

End Type

Private Const CREATE_NEW As Long = 1

Private Const GENERIC_READ As Long = &H80000000

Private Const GENERIC_WRITE As Long = &H40000000

Private Const FILE_SHARE_READ As Long = &H1

Private Const FILE_SHARE_WRITE As Long = &H2

Private Const OPEN_EXISTING As Long = 3

Private m_DiskInfo As IDSECTOR

Private Declare Function GetVersionEx Lib "kernel32" Alias

"GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As

Long

Private Declare Function CreateFile Lib "kernel32" Alias

"CreateFileA" (ByVal lpFileName As String, ByVal

dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal

lpSecurityAttributes As Long, ByVal dwCreationDisposition As

Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile

As

Long) As Long

Private Declare Function DeviceIoControl Lib "kernel32"

(ByVal hDevice As Long, ByVal dwIoControlCode As Long,

lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As

Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long,

ByVal lpOverlapped As Long) As Long

Private Declare Function CloseHandle Lib "kernel32" (ByVal

hObject As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias

"RtlMoveMemory" (Destination As Any, Source As Any, ByVal

Length As Long)

Private

"kernel32"

Declare

Alias

Function GetVolumeInformation Lib

"GetVolumeInformationA" (ByVal

lpRootPathName As String, ByVal lpVolumeNameBuffer As String,

ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As

Long, lpMaximumComponentLength As Long, lpFileSystemFlags

As Long, ByVal lpFileSystemNameBuffer As String, ByVal

nFileSystemNameSize As Long) As Long

'信息类型枚举

Enum eumInfoType

hdmodelsn = 0

hdOnlyModel = 1

hdOnlySN = 2

End Enum

'磁盘通道枚举

Enum eumDiskNo

hdPrimaryMaster = 0

hdPrimarySlave = 1

hdSecondaryMaster = 2

hdSecondarySlave = 3

End Enum

'取得逻辑盘序列号 (非唯一)

Function GetDiskVolume(Optional ByVal strDiskName = "C")

As String

Dim TempStr1 As String * 256, TempStr2 As String * 256

Dim TempLon1 As Long, TempLon2 As Long, GetVal As Long

Dim tmpVol As String

Call GetVolumeInformation(strDiskName & ":", TempStr1,

256, GetVal, TempLon1, TempLon2, TempStr2, 256)

If GetVal = 0 Then

tmpVol = ""

Else

tmpVol = Hex(GetVal)

tmpVol = String(8 - Len(tmpVol), "0") & tmpVol

tmpVol = Left(tmpVol, 4) & "-" & Right(tmpVol, 4)

End If

GetDiskVolume = tmpVol

End Function

'取得硬盘信息:型号/物理系列号(唯一)

Function GetHardDiskInfo(Optional ByVal numDisk As

eumDiskNo = hdPrimaryMaster, Optional ByVal numType As

eumInfoType = hdOnlySN) As String

If GetDiskInfo(numDisk) = 1 Then

Dim pSerialNumber As String, pModelNumber As String

pSerialNumber

vbUnicode)

pModelNumber

vbUnicode)

Select Case numType

Case hdOnlyModel '仅型号

GetHardDiskInfo = Trim(pModelNumber)

Case hdOnlySN '仅系列号

GetHardDiskInfo = Trim(pSerialNumber)

Case Else '型号,系列号

GetHardDiskInfo

Trim(pSerialNumber)

End Select

End If

End Function

Private Function OpenSMART(ByVal nDrive As Byte) As Long

Dim hSMARTIOCTL As Long

Dim hd As String

Dim VersionInfo As OSVERSIONINFO

= Trim(pModelNumber) & "," &

= StrConv(m_Number,

= StrConv(m_lNumber,

hSMARTIOCTL = INVALID_HANDLE_VALUE

rsionInfoSize = Len(VersionInfo)

GetVersionEx VersionInfo

Select Case formId

Case VER_PLATFORM_WIN32s

OpenSMART = hSMARTIOCTL

Case VER_PLAT

FORM_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

rSize = IDENTIFY_BUFFER_SIZE

resReg = 0

rCountReg = 1

rNumberReg = 1

wReg = 0

ghReg = 0

HeadReg = &HA0 Or ((bDriveNum

And 1) * 2 ^ 4)

'

ndReg = bIDCmd

Number = bDriveNum

rSize = IDENTIFY_BUFFER_SIZE

DoIDENTIFY

pSCIP, 32, _

pSCOP(0), 528, _

lpcbBytesReturned, 0))

End Function

Private Function DoEnableSMART(ByVal hSMARTIOCTL As

Long, pSCIP As SENDCMDINPARAMS,

ByVal bDriveNum

pSCOP

As

As

Byte, SENDCMDOUTPARAMS,

rSize = 0

resReg

SMART_ENABLE_SMART_OPERATIONS

rCountReg = 1

rNumberReg = 1

wReg = SMART_CYL_LOW

ghReg = SMART_CYL_HI

=

= CBool(DeviceIoControl(hSMARTIOCTL,

DFP_RECEIVE_DRIVE_DATA, _

lpcbBytesReturned As Long) As Boolean

HeadReg = &HA0 Or ((bDriveNum

And 1) * 2 ^ 4)

ndReg

IDE_EXECUTE_SMART_FUNCTION

Number = bDriveNum

DoEnableSMART = CBool(DeviceIoControl(hSMARTIOCTL,

DFP_SEND_DRIVE_COMMAND, _

pSCIP, LenB(pSCIP) - 1, _

pSCOP, LenB(pSCOP) - 1, _

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,

ChangeByteOrder

UBound(Number) + 1

ChangeByteOrder

UBound(areRev) + 1

ChangeByteOrder

UBound(lNumber) + 1

End Sub

Public Function GetDiskInfo(ByVal n

Drive 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

lNumber,

areRev,

Number,

ByVal bIDCmd As Byte, ByVal

bDfpDriveMap As Byte, ByVal bDriveNum As Byte)

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 (viceMap 2 ^ nDrive And

&H10) Then

If DoEnableSMART(hSMARTIOCTL, scip, OutCmd, nDrive,

cbBytesReturned) Then

bDfpDriveMap = bDfpDriveMap Or 2 ^ nDrive

End If

End If

bIDCmd = IIf((viceMap 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

LenB(m_DiskInfo)

Call DisplayIdInfo(m_DiskInfo, scip, bIDCmd, bDfpDriveMap,

nDrive)

CloseHandle hSMARTIOCTL

GetDiskInfo = 1

m_DiskInfo, scop(LenB(OutCmd) - 4),

Exit Function '>---> Bottom

End If

CloseHandle hSMARTIOCTL

GetDiskInfo = 0

Else '

GetDiskInfo = -1

End If

End Function

本文标签: 序列号硬盘取得代码修改