|
很久很久以前网上摘的,好用.
调用方式我做了一个小封装:- msgbox GetHDDID(1) '取第一个硬盘的序列号
复制代码
ModGetHID.bas
(17.6 KB, 下载次数: 3186)
以下是代码:- '****************************************************************
- '原作: Bardo
- '出处: 《东方热讯》网站
- '网址: www.easthot.net
- '****************************************************************
- '(如需转载,请不在删除以上信息,否则视为侵权!)
- '****************************************************************
- '要这个有什么用?可以生成与硬件相关的注册码。控制软件不重复使用!那么,很多多人认为VB实现不了。自然没有找到方法,一定是实现不了。然而,感谢WWW,我们能在上面找到VC的源码,DELPHI的源码。但是VB的就是见不到。为此,我决定将VC的源码改成VB的,以下即是:
- 'VC原作说明部分(再发行时,请注意采用注解的方式,请不要删除的方式侵权,谢谢!)
- '*************************************************************************
- '通常情况下,我们通过=&HEC命令对IDE端口进行监测.获取硬盘信息.
- '一般情况下,我们就写个VXD或者DRIVER来完成.但是现在,通过MS的S.M.A.R.T.接口,
- '我们可以直接从RING3调用API DeviceIoControl()来获取硬盘信息.下面乃是我的例程:
- '另外,也有编译好的版本供大家平时使用.欢迎下载.
- '/*+++
- 'HDID.CPP
- 'Written by Lu Lin
- 'http://lu0.126.com
- '2000.11.3
- '---*/
- '*************************************************************************
- 'VB程序编制: BARDO
- '本来我想写一个只取盘动物理序列号的。但是考虑到大家学习的方便。还是将原来的代码
- '全部翻译了出来。如果你需要单一的只查一个主硬盘的序列号的程序,欢迎到本站下载。
- '
- '网站:东方热讯:http://www.easthot.net
- '邮件:sales@easthot.net
- '2003.01.23
- '*************************************************************************
- Option Explicit
- '以下这一行是必须的,困为要做结构复制。而结构中有数组。所以,没有它则会错位
- Option Base 0
- 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
- '#pragma pack(1)
- Private Type TGETVERSIONOUTPARAMS '{
- 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(4) As Long 'For future use.
- End Type
- Private Type TIDEREGS
- 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 TSENDCMDINPARAMS
- cBufferSize As Long 'Buffer size in bytes
- irDriveRegs As TIDEREGS '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.
- ''BYTE bBuffer(1) 'Input buffer.
- End Type
- Private Type TDRIVERSTATUS
- bDriverError As Byte 'Error code from driver, 'or 0 if no error.
- bIDEStatus As Byte 'Contents of IDE Error register.
- 'Only valid when bDriverError 'is SMART_IDE_ERROR.
- bReserved(1) As Byte 'Reserved for future expansion.
- dwReserved(1) As Long 'Reserved for future expansion.
- End Type
- Private Type TSENDCMDOUTPARAMS
- cBufferSize As Long 'Size of bBuffer in bytes
- DRIVERSTATUS As TDRIVERSTATUS 'Driver status structure.
- bBuffer(511) As Byte 'Buffer of arbitrary length
- 'in which to store the data read from the drive.
- End Type
- '下面的结构是要从另一结构复制数据过来的,所以,必须是字节数与VC的完全一致
- '而不能用兼容变量,但这里的我们还是用了兼容变量,Integer,因为此结构中这一
- '类型的的变量程序中没有用到,如果要用到,建议改为Byte类型。因为VB没有USHORT
- Private Type TIDSECTOR
- 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
- '/*+++
- 'Global vars
- '---*/
- Private vers As TGETVERSIONOUTPARAMS
- Private in_data As TSENDCMDINPARAMS
- Private out_data As TSENDCMDOUTPARAMS
- Private h As Long
- Private I As Long
- Private J As Byte
- Private Type OSVERSIONINFO
- dwOSVersionInfoSize As Long
- dwMajorVersion As Long
- dwMinorVersion As Long
- dwBuildNumber As Long
- dwPlatformId As Long
- szCSDVersion As String * 128
- End Type
- Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
- (LpVersionInformation As OSVERSIONINFO) As Long
- Private Const VER_PLATFORM_WIN32S = 0
- Private Const VER_PLATFORM_WIN32_WINDOWS = 1
- Private Const VER_PLATFORM_WIN32_NT = 2
- 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 Const CREATE_NEW = 1
- Private Const GENERIC_READ = &H80000000
- Private Const GENERIC_WRITE = &H40000000
- Private Const OPEN_EXISTING = 3
- Private Const FILE_SHARE_READ = &H1
- Private Const FILE_SHARE_WRITE = &H2
- Private Type OVERLAPPED
- Internal As Long
- InternalHigh As Long
- offset As Long
- OffsetHigh As Long
- hEvent As Long
- End Type
- 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, lpOverlapped As OVERLAPPED) As Long
- Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
- Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
- hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
- Private Sub CopyRight()
- 'VC原版权代码(再发行时,请注意采用注解的方式,请不要删除的方式侵权,谢谢!)
- '****************************************************************************
- ' cerr<<endl<<"HDD identifier v1.0 for WIN95/98/Me/NT/2000. written by Lu Lin"<<endl
- ' cerr<<"For more information, please visit Inside Programming: http:'lu0.126.com"<<endl
- ' cerr<<"2000.11.3"<<endl<<endl
- '****************************************************************************
- Dim StrMsg As String
- StrMsg = StrMsg & "直接从RING3调用API DeviceIoControl()来获取硬盘信息的VB程序 "
- StrMsg = StrMsg & vbCrLf & "VC源作板权信息如下:"
- StrMsg = StrMsg & vbCrLf & "***********************************************************"
- StrMsg = StrMsg & vbCrLf & "HDD identifier v1.0 for WIN95/98/Me/NT/2000. written by Lu Lin"
- StrMsg = StrMsg & vbCrLf & "For more information, please visit Inside Programming: http://lu0.126.com"
- StrMsg = StrMsg & vbCrLf & "2000.11.3"
- StrMsg = StrMsg & vbCrLf & "***********************************************************"
- StrMsg = StrMsg & vbCrLf & "VB程序编制:BARDO"
- StrMsg = StrMsg & vbCrLf & "网站:东方热讯:http://www.easthot.net"
- StrMsg = StrMsg & vbCrLf & "邮件:sales@easthot.net"
- StrMsg = StrMsg & vbCrLf & "2003.01.23"
- MsgBox StrMsg
- End Sub
- Sub ChangeByteOrder(szString() As Byte, uscStrSize As Long)
- Dim I As Long
- Dim Temp As String
- For I = 0 To uscStrSize - 1 Step 2
- Temp = szString(I)
- szString(I) = szString(I + 1)
- szString(I + 1) = Temp
- Next I
- End Sub
- Private Function hdid9x() As String
- 'We start in 95/98/Me
- h = CreateFile("\\.\Smartvsd", 0, 0, 0, CREATE_NEW, 0, 0)
- If h = 0 Then
- hdid9x = "open smartvsd.vxd failed"
- Exit Function
- End If
- Dim olp As OVERLAPPED
- Dim lRet As Long
- lRet = DeviceIoControl(h, DFP_GET_VERSION, ByVal 0&, 0, vers, Len(vers), ByVal I, olp)
- If lRet = 0 Then
- hdid9x = "DeviceIoControl failed:DFP_GET_VERSION"
- CloseHandle (h)
- Exit Function
- End If
- 'If IDE identify command not supported, fails
- If (vers.fCapabilities And 1) <> 1 Then
- hdid9x = "Error: IDE identify command not supported."
- CloseHandle (h)
- Exit Function
- End If
- 'Display IDE drive number detected
- Dim sPreOutStr As String
- sPreOutStr = DetectIDE(vers.bIDEDeviceMap)
- hdid9x = sPreOutStr
- 'Identify the IDE drives
- For J = 0 To 3
- Dim phdinfo As TIDSECTOR
- Dim S(40) As Byte
-
- If (J And 1) = 1 Then
- in_data.irDriveRegs.bDriveHeadReg = &HB0
- Else
- in_data.irDriveRegs.bDriveHeadReg = &HA0
- End If
- If (vers.fCapabilities And (16 \ (2 ^ J))) = (16 \ (2 ^ J)) Then
- 'We don't detect a ATAPI device.
- hdid9x = "Drive " & CStr(J + 1) & " is a ATAPI device, we don't detect it"
- Else
- in_data.irDriveRegs.bCommandReg = &HEC
- in_data.bDriveNumber = J
- in_data.irDriveRegs.bSectorCountReg = 1
- in_data.irDriveRegs.bSectorNumberReg = 1
- in_data.cBufferSize = 512
-
- lRet = DeviceIoControl(h, DFP_RECEIVE_DRIVE_DATA, in_data, Len(in_data), out_data, Len(out_data), ByVal I, olp)
-
- If lRet = 0 Then
- hdid9x = "DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"
- CloseHandle (h)
- Exit Function
- End If
-
- Dim StrOut As String
-
- CopyMemory phdinfo, out_data.bBuffer(0), Len(phdinfo)
-
- CopyMemory S(0), phdinfo.sModelNumber(0), 40
- S(40) = 0
- ChangeByteOrder S, 40
-
- StrOut = ByteArrToString(S, 40)
-
- hdid9x = hdid9x & vbCrLf & "Module Number:" & StrOut
- CopyMemory S(0), phdinfo.sFirmwareRev(0), 8
- S(8) = 0
- ChangeByteOrder S, 8
-
- StrOut = ByteArrToString(S, 8)
-
- hdid9x = hdid9x & vbCrLf & "Firmware rev:" & StrOut
- CopyMemory S(0), phdinfo.sSerialNumber(0), 20
- S(20) = 0
- ChangeByteOrder S, 20
-
- StrOut = ByteArrToString(S, 20)
-
- hdid9x = hdid9x & vbCrLf & "Serial Number:" & StrOut
-
- CopyMemory S(0), phdinfo.ulTotalAddressableSectors(0), 4
-
- S(5) = 0
- Dim dblStrOut As Double
- dblStrOut = ByteArrToLong(S)
- hdid9x = hdid9x & vbCrLf & "Capacity:" & dblStrOut / 2 / 1024 & "M"
- End If
- Next J
- 'Close handle before quit
- CloseHandle (h)
- CopyRight
- End Function
- Private Function hdidnt(ByRef outHDDID() As String) As String
- Dim hd As String * 80
- Dim phdinfo As TIDSECTOR
- Dim S(40) As Byte
- Dim StrOut As String
- ReDim outHDDID(3)
- hdidnt = ""
- 'We start in NT/Win2000
- For J = 0 To 3 '这里取四个硬盘的信息,因为正常PC不超过四个硬盘
- hd = "\\.\PhysicalDrive" & CStr(J)
- hdidnt = hdidnt & vbCrLf & hd
- h = CreateFile(hd, GENERIC_READ Or GENERIC_WRITE, _
- FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
-
- Dim olpv As OVERLAPPED
-
- Dim lRet As Long
- lRet = DeviceIoControl(h, DFP_GET_VERSION, ByVal 0&, 0, vers, Len(vers), ByVal I, olpv)
-
- If lRet = 0 Then
- CloseHandle (h)
- Else
- 'If IDE identify command not supported, fails
- If (vers.fCapabilities And 1) <> 1 Then
- hdidnt = "Error: IDE identify command not supported."
- CloseHandle (h)
- Exit Function
- End If
- 'Identify the IDE drives
- If (J And 1) = 1 Then
- in_data.irDriveRegs.bDriveHeadReg = &HB0
- Else
- in_data.irDriveRegs.bDriveHeadReg = &HA0
- End If
- If (vers.fCapabilities And (16 \ (2 ^ J))) <> 0 Then
- 'We don't detect a ATAPI device.
- hdidnt = hdidnt & vbCrLf & "Drive " & CStr(J + 1) & " is a ATAPI device, we don't detect it"
- Else
-
- in_data.irDriveRegs.bCommandReg = &HEC
- in_data.bDriveNumber = J
- in_data.irDriveRegs.bSectorCountReg = 1
- in_data.irDriveRegs.bSectorNumberReg = 1
- in_data.cBufferSize = 512
-
- Dim olpr As OVERLAPPED
-
- lRet = DeviceIoControl(h, DFP_RECEIVE_DRIVE_DATA, in_data, Len(in_data), out_data, Len(out_data), ByVal I, olpr)
- If lRet <= 0 Then
- hdidnt = hdidnt & vbCrLf & "DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"
- CloseHandle (h)
-
- Else
-
- CopyMemory phdinfo, out_data.bBuffer(0), Len(phdinfo)
-
- CopyMemory S(0), phdinfo.sModelNumber(0), 40
- S(40) = 0
- ChangeByteOrder S, 40
-
- StrOut = ByteArrToString(S, 40)
-
- hdidnt = hdidnt & vbCrLf & "Module Number:" & StrOut
- CopyMemory S(0), phdinfo.sFirmwareRev(0), 8
- S(8) = 0
- ChangeByteOrder S, 8
-
- StrOut = ByteArrToString(S, 8)
-
- hdidnt = hdidnt & vbCrLf & "Firmware rev:" & StrOut
- CopyMemory S(0), phdinfo.sSerialNumber(0), 20
- S(20) = 0
- ChangeByteOrder S, 20
-
- StrOut = ByteArrToString(S, 20)
-
- hdidnt = hdidnt & vbCrLf & "Serial Number:" & StrOut
- outHDDID(J + 1) = Trim(StrOut)
-
- CopyMemory S(0), phdinfo.ulTotalAddressableSectors(0), 4
- S(5) = 0
- Dim dblStrOut As Double
- dblStrOut = ByteArrToLong(S)
-
- hdidnt = hdidnt & vbCrLf & "Capacity:" & dblStrOut / 2 / 1024 & "M"
- CloseHandle (h)
- End If
- End If
- End If
- Next J
- 'CopyRight
- End Function
- Private Function DetectIDE(bIDEDeviceMap As Byte) As String
- If (bIDEDeviceMap And 1) Then
- If (bIDEDeviceMap And 16) Then
- DetectIDE = DetectIDE & "ATAPI device is attached to primary controller, drive 0."
- Else
- DetectIDE = DetectIDE & "IDE device is attached to primary controller, drive 0."
- End If
- End If
- If (bIDEDeviceMap And 2) Then
- If (bIDEDeviceMap And 32) Then
- DetectIDE = DetectIDE & "ATAPI device is attached to primary controller, drive 1."
- Else
- DetectIDE = DetectIDE & "IDE device is attached to primary controller, drive 1."
- End If
- End If
- If (bIDEDeviceMap And 4) Then
- If (bIDEDeviceMap And 64) Then
- DetectIDE = DetectIDE & "ATAPI device is attached to secondary controller, drive 0."
- Else
- DetectIDE = DetectIDE & "IDE device is attached to secondary controller, drive 0."
- End If
- End If
- If (bIDEDeviceMap And 8) Then
- If (bIDEDeviceMap And 128) Then
- DetectIDE = DetectIDE & "ATAPI device is attached to secondary controller, drive 1."
- Else
- DetectIDE = DetectIDE & "IDE device is attached to secondary controller, drive 1."
- End If
- End If
- End Function
- Private Function ByteArrToString(inByte() As Byte, ByVal strlen As Integer) As String
- Dim I As Integer
- For I = 0 To strlen
- If inByte(I) = 0 Then
- Exit For
- End If
- ByteArrToString = ByteArrToString & Chr(inByte(I))
- Next I
- End Function
- Private Function ByteArrToLong(inByte() As Byte) As Double
- Dim I As Integer
- For I = 0 To 3
- ByteArrToLong = ByteArrToLong + CDbl(inByte(I)) * (256 ^ I)
- Next I
- End Function
- Public Function GetHDDID(ByVal HDDIndex As Long, Optional ByRef outFullInfo As String = "-1") As String
- '取硬盘ID
- 'HDDIndex - 硬盘号(1 - 4)
- 'outFullInfo - 可选,输出;用于输出完整的硬盘信息
- '返回值:
- ' 指定硬盘的ID
- '嗷嗷叫的老马 添加
- '
- Dim VerInfo As OSVERSIONINFO
- Dim Ret As Long, I As Long, J As Long, K As Long
- Dim strInfo As String, strInfoArr() As String
-
- VerInfo.dwOSVersionInfoSize = Len(VerInfo)
- Ret = GetVersionEx(VerInfo)
-
- Select Case VerInfo.dwPlatformId
- Case VER_PLATFORM_WIN32S
- strInfo = "Win32s is not supported by this programm."
- Case VER_PLATFORM_WIN32_WINDOWS
- strInfo = hdid9x
- Case VER_PLATFORM_WIN32_NT
- strInfo = hdidnt(strInfoArr)
- End Select
- If outFullInfo <> "-1" Then outFullInfo = strInfo
- GetHDDID = strInfoArr(HDDIndex)
- End Function
复制代码 |
|