获取硬盘物理序列号

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices


Public Class PhysicalDrive
    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure DRIVERSTATUS
        Public bDriverError As Byte
        Public bIDEStatus As Byte
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
        Public bReserved() As Byte
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _
        Public dwReserved() As Int32
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure SENDCMDOUTPARAMS
        Public cBufferSize As Int32
        Public DriverStatus As DRIVERSTATUS
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=513)> _
        Public bBuffer() As Byte
    End Structure
    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure IDEREGS
        Public bFeaturesReg As Byte
        Public bSectorCountReg As Byte
        Public bSectorNumberReg As Byte
        Public bCylLowReg As Byte
        Public bCylHighReg As Byte
        Public bDriveHeadReg As Byte
        Public bCommandReg As Byte
        Public bReserved As Byte
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure SENDCMDINPARAMS
        Public cBufferSize As Int32
        Public irDriveRegs As IDEREGS
        Public bDriveNumber As Byte
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> _
        Public bReserved() As Byte
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
        Public dwReserved() As Int32
        Public bBuffer As Byte
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Friend Structure GETVERSIONOUTPARAMS
        Public bVersion As Byte
        Public bRevision As Byte
        Public bReserved As Byte
        Public bIDEDeviceMap As Byte
        Public fCapabilities As Int32
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
        Public dwReserved() As Int32
    End Structure

    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Shared Function CloseHandle( _
        ByVal hObject As Int32 _
    ) As Integer
    End Function

    <DllImport("kernel32.dll")> _
    Private Overloads Shared Function DeviceIoControl( _
        ByVal hDevice As Int32, _
        ByVal dwIoControlCode As Int32, _
        ByRef lpInBuffer As SENDCMDINPARAMS, _
        ByVal nInBufferSize As Integer, _
        ByRef lpOutBuffer As SENDCMDOUTPARAMS, _
        ByVal nOutBufferSize As Integer, _
        ByRef lpbytesReturned As Int32, _
        ByVal lpOverlapped As Integer _
    ) As Integer
    End Function

    <DllImport("kernel32.dll")> _
    Private Overloads Shared Function DeviceIoControl( _
        ByVal hDevice As Int32, _
        ByVal dwIoControlCode As Int32, _
        ByVal lpInBuffer As Integer, _
        ByVal nInBufferSize As Integer, _
        ByRef lpOutBuffer As GETVERSIONOUTPARAMS, _
        ByVal nOutBufferSize As Integer, _
        ByRef lpbytesReturned As Int32, _
        ByVal lpOverlapped As Integer _
    ) As Integer
    End Function

    <DllImport("kernel32.dll")> _
    Private Shared Function CreateFile( _
        ByVal lpFileName As String, _
        ByVal dwDesiredAccess As Int32, _
        ByVal dwShareMode As Int32, _
        ByVal lpSecurityAttributes As Integer, _
        ByVal dwCreationDisposition As Int32, _
        ByVal dwFlagsAndAttributes As Int32, _
        ByVal hTemplateFile As Integer _
    ) As Int32
    End Function

    Private Const GENERIC_READ As Int32 = &H80000000
    Private Const GENERIC_WRITE As Int32 = &H40000000
    Private Const FILE_SHARE_READ As Int32 = &H1
    Private Const FILE_SHARE_WRITE As Int32 = &H2
    Private Const OPEN_EXISTING As Int32 = 3
    Private Const INVALID_HANDLE_VALUE As Int32 = &HFFFFFFFF
    Private Const DFP_GET_VERSION As Int32 = &H74080
    Private Const IDE_ATAPI_IDENTIFY As Integer = &HA1
    Private Const IDE_ATA_IDENTIFY As Integer = &HEC
    Private Const IDENTIFY_BUFFER_SIZE As Integer = 512
    Private Const DFP_RECEIVE_DRIVE_DATA As Int32 = &H7C088

    ''' <summary>
    ''' 获取物理序列号
    ''' </summary>
    ''' <param name="id">系统硬盘序号,0-255</param>
    Public Shared Function GetSerialNumber(ByVal id As Byte) As String
        Dim os As OperatingSystem = Environment.OSVersion
        If os.Platform <> PlatformID.Win32NT Then
            Throw New NotSupportedException("仅支持2000/XP/2003")
        End If
        If os.Version.Major < 5 Then
            Throw New NotSupportedException("仅支持2000/XP/2003")
        End If

        Return Read(id)
    End Function

 

 

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.Text = PhysicalDrive.GetSerialNumber(0) 

    End Sub

 

 

    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

End Class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值