C#读硬盘序列号(转载)

using  System;
using  System.Runtime.InteropServices;
using  System.Text;

namespace  Sunmast.Hardware
{
    [Serializable]
    
public   struct  HardDiskInfo
    {
        
///  
        
///  型号
        
///  
         public   string  ModuleNumber;
        
///  
        
///  固件版本
        
///  
         public   string  Firmware;
        
///  
        
///  序列号
        
///  
         public   string  SerialNumber;
        
///  
        
///  容量,以M为单位
        
///  
         public   uint  Capacity;
    }

    
#region  Internal Structs

    [StructLayout(LayoutKind.Sequential, Pack
= 1 )]
    
internal   struct  GetVersionOutParams
    {
        
public   byte  bVersion;
        
public   byte  bRevision;
        
public   byte  bReserved;
        
public   byte  bIDEDeviceMap;
        
public   uint  fCapabilities;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 4 )]
        
public   uint [] dwReserved;  //  For future use.
    }

    [StructLayout(LayoutKind.Sequential, Pack
= 1 )]
    
internal   struct  IdeRegs
    {
        
public   byte  bFeaturesReg;
        
public   byte  bSectorCountReg;
        
public   byte  bSectorNumberReg;
        
public   byte  bCylLowReg;
        
public   byte  bCylHighReg;
        
public   byte  bDriveHeadReg;
        
public   byte  bCommandReg;
        
public   byte  bReserved;
    }

    [StructLayout(LayoutKind.Sequential, Pack
= 1 )]
    
internal   struct  SendCmdInParams
    {
        
public   uint  cBufferSize;
        
public  IdeRegs irDriveRegs;
        
public   byte  bDriveNumber;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 3 )]
        
public   byte [] bReserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 4 )]
        
public   uint [] dwReserved;
        
public   byte  bBuffer;
    }

    [StructLayout(LayoutKind.Sequential, Pack
= 1 )]
    
internal   struct  DriverStatus
    {
        
public   byte  bDriverError;
        
public   byte  bIDEStatus;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 2 )]
        
public   byte [] bReserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 2 )]
        
public   uint [] dwReserved;
    }

    [StructLayout(LayoutKind.Sequential, Pack
= 1 )]
    
internal   struct  SendCmdOutParams
    {
        
public   uint  cBufferSize;
        
public  DriverStatus DriverStatus;
        
public  IdSector bBuffer;
    }

    [StructLayout(LayoutKind.Sequential, Pack
= 1 , Size = 512 )]
    
internal   struct  IdSector
    {
        
public   ushort  wGenConfig;
        
public   ushort  wNumCyls;
        
public   ushort  wReserved;
        
public   ushort  wNumHeads;
        
public   ushort  wBytesPerTrack;
        
public   ushort  wBytesPerSector;
        
public   ushort  wSectorsPerTrack;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 3 )]
        
public   ushort [] wVendorUnique;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 20 )]
        
public   byte [] sSerialNumber;
        
public   ushort  wBufferType;
        
public   ushort  wBufferSize;
        
public   ushort  wECCSize;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 8 )]
        
public   byte [] sFirmwareRev;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 40 )]
        
public   byte [] sModelNumber;
        
public   ushort  wMoreVendorUnique;
        
public   ushort  wDoubleWordIO;
        
public   ushort  wCapabilities;
        
public   ushort  wReserved1;
        
public   ushort  wPIOTiming;
        
public   ushort  wDMATiming;
        
public   ushort  wBS;
        
public   ushort  wNumCurrentCyls;
        
public   ushort  wNumCurrentHeads;
        
public   ushort  wNumCurrentSectorsPerTrack;
        
public   uint  ulCurrentSectorCapacity;
        
public   ushort  wMultSectorStuff;
        
public   uint  ulTotalAddressableSectors;
        
public   ushort  wSingleWordDMA;
        
public   ushort  wMultiWordDMA;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst
= 128 )]
        
public   byte [] bReserved;
    }

    
#endregion

    
///  
    
///  ATAPI驱动器相关
    
///  
     public   class  AtapiDevice
    {

        
#region  DllImport

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern   int  CloseHandle(IntPtr hObject);

        [DllImport(
" kernel32.dll " , SetLastError = true )]
        
static   extern  IntPtr CreateFile(
            
string  lpFileName,
            
uint  dwDesiredAccess,
            
uint  dwShareMode,
            IntPtr lpSecurityAttributes,
            
uint  dwCreationDisposition,
            
uint  dwFlagsAndAttributes,
            IntPtr hTemplateFile);

        [DllImport(
" kernel32.dll " )]
        
static   extern   int  DeviceIoControl(
            IntPtr hDevice,
            
uint  dwIoControlCode,
            IntPtr lpInBuffer,
            
uint  nInBufferSize,
            
ref  GetVersionOutParams lpOutBuffer,
            
uint  nOutBufferSize,
            
ref   uint  lpBytesReturned,
            [Out] IntPtr lpOverlapped);

        [DllImport(
" kernel32.dll " )]
        
static   extern   int  DeviceIoControl(
            IntPtr hDevice,
            
uint  dwIoControlCode,
            
ref  SendCmdInParams lpInBuffer,
            
uint  nInBufferSize,
            
ref  SendCmdOutParams lpOutBuffer,
            
uint  nOutBufferSize,
            
ref   uint  lpBytesReturned,
            [Out] IntPtr lpOverlapped);

        
const   uint  DFP_GET_VERSION  =   0x00074080 ;
        
const   uint  DFP_SEND_DRIVE_COMMAND  =   0x0007c084 ;
        
const   uint  DFP_RECEIVE_DRIVE_DATA  =   0x0007c088 ;

        
const   uint  GENERIC_READ  =   0x80000000 ;
        
const   uint  GENERIC_WRITE  =   0x40000000 ;
        
const   uint  FILE_SHARE_READ  =   0x00000001 ;
        
const   uint  FILE_SHARE_WRITE  =   0x00000002 ;
        
const   uint  Create_NEW  =   1 ;
        
const   uint  OPEN_EXISTING  =   3 ;

        
#endregion

        
#region  GetHddInfo

        
///  
        
///  获得硬盘信息
        
///  
        
///  硬盘序号
        
///  硬盘信息
        
///  
        
///  参考lu0的文章: http://lu0s1.3322.org/App/2k1103.html
        
///  by sunmast for everyone
        
///  thanks lu0 for his great works
        
///  在Windows 98/ME中,S.M.A.R.T并不缺省安装,请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下。
        
///  在Windows 2000/2003下,需要Administrators组的权限。
        
///  
        
///  
        
///  AtapiDevice.GetHddInfo()
        
///  
         public   static  HardDiskInfo GetHddInfo( byte  driveIndex)
        {
            
switch (Environment.OSVersion.Platform)
            {
                
case  PlatformID.Win32Windows:
                    
return  GetHddInfo9x(driveIndex);
                
case  PlatformID.Win32NT:
                    
return  GetHddInfoNT(driveIndex);
                
case  PlatformID.Win32S:
                    
throw   new  NotSupportedException( " Win32s is not supported. " );
                
case  PlatformID.WinCE:
                    
throw   new  NotSupportedException( " WinCE is not supported. " );
                
default :
                    
throw   new  NotSupportedException( " Unknown Platform. " );
            }
        }

        
#region  GetHddInfo9x

        
private   static  HardDiskInfo GetHddInfo9x( byte  driveIndex)
        {
            GetVersionOutParams vers 
=   new  GetVersionOutParams();
            SendCmdInParams inParam 
=   new  SendCmdInParams();
            SendCmdOutParams outParam 
=   new  SendCmdOutParams();
            
uint  bytesReturned  =   0 ;

            IntPtr hDevice 
=  CreateFile(
                
@" \\.\Smartvsd " ,
                
0 ,
                
0 ,
                IntPtr.Zero,
                Create_NEW,
                
0 ,
                IntPtr.Zero);
            
if  (hDevice  ==  IntPtr.Zero)
            {
                
throw   new  Exception( " Open smartvsd.vxd failed. " );
            }
            
if  ( 0   ==  DeviceIoControl(
                hDevice,
                DFP_GET_VERSION,
                IntPtr.Zero,
                
0 ,
                
ref  vers,
                (
uint )Marshal.SizeOf(vers),
                
ref  bytesReturned,
                IntPtr.Zero))
            {
                CloseHandle(hDevice);
                
throw   new  Exception( " DeviceIoControl failed:DFP_GET_VERSION " );
            }
            
//  If IDE identify command not supported, fails
             if  ( 0   ==  (vers.fCapabilities  &   1 ))
            {
                CloseHandle(hDevice);
                
throw   new  Exception( " Error: IDE identify command not supported. " );
            }
            
if  ( 0   !=  (driveIndex  &   1 ))
            {
                inParam.irDriveRegs.bDriveHeadReg 
=   0xb0 ;
            }
            
else
            {
                inParam.irDriveRegs.bDriveHeadReg 
=   0xa0 ;
            }
            
if  ( 0   !=  (vers.fCapabilities  &  ( 16   >>  driveIndex)))
            {
                
//  We don't detect a ATAPI device.
                CloseHandle(hDevice);
                
throw   new  Exception( string .Format( " Drive {0} is a ATAPI device, we don't detect it " ,driveIndex  +   1 ));
            }
            
else
            {
                inParam.irDriveRegs.bCommandReg 
=   0xec ;
            }
            inParam.bDriveNumber 
=  driveIndex;
            inParam.irDriveRegs.bSectorCountReg 
=   1 ;
            inParam.irDriveRegs.bSectorNumberReg 
=   1 ;
            inParam.cBufferSize 
=   512 ;
            
if  ( 0   ==  DeviceIoControl(
                hDevice,
                DFP_RECEIVE_DRIVE_DATA,
                
ref  inParam,
                (
uint )Marshal.SizeOf(inParam),
                
ref  outParam,
                (
uint )Marshal.SizeOf(outParam),
                
ref  bytesReturned,
                IntPtr.Zero))
            {
                CloseHandle(hDevice);
                
throw   new  Exception( " DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA " );
            }
            CloseHandle(hDevice);

            
return  GetHardDiskInfo(outParam.bBuffer);
        }

        
#endregion

        
#region  GetHddInfoNT

        
private   static  HardDiskInfo GetHddInfoNT( byte  driveIndex)
        {
            GetVersionOutParams vers 
=   new  GetVersionOutParams();
            SendCmdInParams inParam 
=   new  SendCmdInParams();
            SendCmdOutParams outParam 
=   new  SendCmdOutParams();
            
uint  bytesReturned  =   0 ;

            
//  We start in NT/Win2000
            IntPtr hDevice  =  CreateFile(
                
string .Format( @" \\.\PhysicalDrive{0} " ,driveIndex),
                GENERIC_READ 
|  GENERIC_WRITE,
                FILE_SHARE_READ 
|  FILE_SHARE_WRITE,
                IntPtr.Zero,
                OPEN_EXISTING,
                
0 ,
                IntPtr.Zero);
            
if  (hDevice  ==  IntPtr.Zero)
            {
                
throw   new  Exception( " CreateFile faild. " );
            }
            
if  ( 0   ==  DeviceIoControl(
                hDevice,
                DFP_GET_VERSION,
                IntPtr.Zero,
                
0 ,
                
ref  vers,
                (
uint )Marshal.SizeOf(vers),
                
ref  bytesReturned,
                IntPtr.Zero))
            {
                CloseHandle(hDevice);
                
throw   new  Exception( string .Format( " Drive {0} may not exists. " ,driveIndex  +   1 ));
            }
            
//  If IDE identify command not supported, fails
             if  ( 0   ==  (vers.fCapabilities  &   1 ))
            {
                CloseHandle(hDevice);
                
throw   new  Exception( " Error: IDE identify command not supported. " );
            }
            
//  Identify the IDE drives
             if  ( 0   !=  (driveIndex  &   1 ))
            {
                inParam.irDriveRegs.bDriveHeadReg 
=   0xb0 ;
            }
            
else
            {
                inParam.irDriveRegs.bDriveHeadReg
= 0xa0 ;
            }
            
if  ( 0   !=  (vers.fCapabilities  &  ( 16   >>  driveIndex)))
            {
                
//  We don't detect a ATAPI device.
                CloseHandle(hDevice);
                
throw   new  Exception( string .Format( " Drive {0} is a ATAPI device, we don't detect it. " ,driveIndex  +   1 ));
            }
            
else
            {
                inParam.irDriveRegs.bCommandReg 
=   0xec ;
            }
            inParam.bDriveNumber 
=  driveIndex;
            inParam.irDriveRegs.bSectorCountReg 
=   1 ;
            inParam.irDriveRegs.bSectorNumberReg 
=   1 ;
            inParam.cBufferSize 
=   512 ;

            
if  ( 0   ==  DeviceIoControl(
                hDevice,
                DFP_RECEIVE_DRIVE_DATA,
                
ref  inParam,
                (
uint )Marshal.SizeOf(inParam),
                
ref  outParam,
                (
uint )Marshal.SizeOf(outParam),
                
ref  bytesReturned,
                IntPtr.Zero))
            {
                CloseHandle(hDevice);
                
throw   new  Exception( " DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA " );
            }
            CloseHandle(hDevice);

            
return  GetHardDiskInfo(outParam.bBuffer);
        }

        
#endregion

        
private   static  HardDiskInfo GetHardDiskInfo(IdSector phdinfo)
        {
            HardDiskInfo hddInfo 
=   new  HardDiskInfo();

            ChangeByteOrder(phdinfo.sModelNumber);
            hddInfo.ModuleNumber 
=  Encoding.ASCII.GetString(phdinfo.sModelNumber).Trim();

            ChangeByteOrder(phdinfo.sFirmwareRev);
            hddInfo.Firmware 
=  Encoding.ASCII.GetString(phdinfo.sFirmwareRev).Trim();

            ChangeByteOrder(phdinfo.sSerialNumber);
            hddInfo.SerialNumber 
=  Encoding.ASCII.GetString(phdinfo.sSerialNumber).Trim();

            hddInfo.Capacity 
=  phdinfo.ulTotalAddressableSectors  /   2   /   1024 ;

            
return  hddInfo;
        }

        
private   static   void  ChangeByteOrder( byte [] charArray)
        {
            
byte  temp;
            
for ( int  i  =   0 ; i  <  charArray.Length; i  +=   2 )
            {
                temp 
=  charArray[i];
                charArray[i] 
=  charArray[i + 1 ];
                charArray[i
+ 1 =  temp;
            }
        }

        
#endregion
    }
}

转载于:https://www.cnblogs.com/XingfuStar/archive/2006/04/20/380369.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值