获取硬盘物理序列号(VB.NET)

 

Public   Class  PhysicalDriveDemo
    
Public   Shared   Sub  Run()
        Console.WriteLine(PhysicalDrive.GetSerialNumber(
0 ))
    
End Sub
End Class

 

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

Public   Class  PhysicalDrive

    
' <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
     '   Friend Structure IDSECTOR
     '     Public wGenConfig As Int16
     '     Public wNumCyls As Int16
     '     Public wReserved As Int16
     '     Public wNumHeads As Int16
     '     Public wBytesPerTrack As Int16
     '     Public wBytesPerSector As Int16
     '     Public wSectorsPerTrack As Int16
     '     <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> _
     '      Public wVendorUnique() As Int16
     '     <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=20)> _
     '     Public sSerialNumber As String
     '     Public wBufferType As Int16
     '     Public wBufferSize As Int16
     '     Public wECCSize As Int16
     '     <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _
     '      Public sFirmwareRev As String
     '     <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=40)> _
     '     Public sModelNumber As String
     '     Public wMoreVendorUnique As Int16
     '     Public wDoubleWordIO As Int16
     '     Public wCapabilities As Int16
     '     Public wReserved1 As Int16
     '     Public wPIOTiming As Int16
     '     Public wDMATiming As Int16
     '     Public wBS As Int16
     '     Public wNumCurrentCyls As Int16
     '     Public wNumCurrentHeads As Int16
     '     Public wNumCurrentSectorsPerTrack As Int16
     '     Public ulCurrentSectorCapacity As Int32
     '     Public wMultSectorStuff As Int16
     '     Public ulTotalAddressableSectors As Int32
     '     Public wSingleWordDMA As Int16
     '     Public wMultiWordDMA As Int16
     '     <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> _
     '     Public bReserved() As Byte
     ' End Structure

    
< 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, CharSet:=CharSet.Ansi)> _
     '   Friend Structure SRB_IO_CONTROL
     '     Public HeaderLength As Int32
     '     <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _
     '     Public Signature As String
     '     Public Timeout As Int32
     '     Public ControlCode As Int32
     '     Public ReturnCode As Int32
     '     Public Length As Int32
     ' 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   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

你可能感兴趣的:(VB.NET)