似水无痕

http://www.fushunboy.com, http://www.kunet.cn, http://www.gotdotnet.cn
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C#读硬盘序列号的原代码

Posted on 2006-01-27 00:09  似水无痕  阅读(498)  评论(0编辑  收藏  举报
public class IDE 

[StructLayout(LayoutKind.Sequential, CharSet
=CharSet.Ansi)] 
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.ByValTStr, SizeConst
=20)] 
public string sSerialNumber; 
public ushort wBufferType; 
public ushort wBufferSize; 
public ushort wECCSize; 
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst
=8)] 
public string sFirmwareRev; 
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst
=40)] 
public string 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; 
}
 

[StructLayout(LayoutKind.Sequential)] 
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)] 
internal struct SENDCMDOUTPARAMS 

public uint cBufferSize; 
public DRIVERSTATUS DriverStatus; 
[ MarshalAs( UnmanagedType.ByValArray, SizeConst
=513 )] 
public byte [] bBuffer; 
}
 

[StructLayout(LayoutKind.Sequential, CharSet
=CharSet.Ansi)] 
internal struct SRB_IO_CONTROL 

public uint HeaderLength; 
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst
=8 )] 
public string Signature; 
public uint Timeout; 
public uint ControlCode; 
public uint ReturnCode; 
public uint Length; 
}
 

[StructLayout(LayoutKind.Sequential)] 
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)] 
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)] 
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. 
}
 

[DllImport(
"kernel32.dll")] 
private static extern int CloseHandle(uint hObject); 

[DllImport(
"kernel32.dll")] 
private static extern int DeviceIoControl(uint hDevice, 
uint dwIoControlCode, 
ref SENDCMDINPARAMS lpInBuffer, 
int nInBufferSize, 
ref SENDCMDOUTPARAMS lpOutBuffer, 
int nOutBufferSize, 
ref uint lpbytesReturned, 
int lpOverlapped); 

[DllImport(
"kernel32.dll")] 
private static extern int DeviceIoControl(uint hDevice, 
uint dwIoControlCode, 
int lpInBuffer, 
int nInBufferSize, 
ref GETVERSIONOUTPARAMS lpOutBuffer, 
int nOutBufferSize, 
ref uint lpbytesReturned, 
int lpOverlapped); 

[DllImport(
"kernel32.dll")] 
private static extern uint CreateFile(string lpFileName, 
uint dwDesiredAccess, 
uint dwShareMode, 
int lpSecurityAttributes, 
uint dwCreationDisposition, 
uint dwFlagsAndAttributes, 
int hTemplateFile); 

private const uint GENERIC_READ = 0x80000000
private const uint GENERIC_WRITE = 0x40000000
private const uint FILE_SHARE_READ = 0x00000001
private const uint FILE_SHARE_WRITE = 0x00000002
private const uint OPEN_EXISTING = 3
private const uint INVALID_HANDLE_VALUE = 0xffffffff
private const uint DFP_GET_VERSION = 0x00074080
private const int IDE_ATAPI_IDENTIFY = 0xA1// Returns ID sector for ATAPI. 
private const int IDE_ATA_IDENTIFY = 0xEC// Returns ID sector for ATA. 
private const int IDENTIFY_BUFFER_SIZE = 512
private const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088

public static string Read(byte drive) 

OperatingSystem os 
= Environment.OSVersion; 
if (os.Platform != PlatformID.Win32NT) throw new NotSupportedException("仅支持WindowsNT/2000/XP"); 
//我没有NT4,请哪位大大测试一下NT4下能不能用 
//if (os.Version.Major < 5) throw new NotSupportedException("仅支持WindowsNT/2000/XP"); 

string driveName = "\\\\.\\PhysicalDrive" + drive.ToString(); 
uint device = CreateFile(driveName, 
GENERIC_READ 
| GENERIC_WRITE, 
FILE_SHARE_READ 
| FILE_SHARE_WRITE, 
0, OPEN_EXISTING, 00); 
if (device == INVALID_HANDLE_VALUE) return ""
GETVERSIONOUTPARAMS verPara 
= new GETVERSIONOUTPARAMS(); 
uint bytRv = 0

if (0 != DeviceIoControl(device, DFP_GET_VERSION, 
00ref verPara, Marshal.SizeOf(verPara), 
ref bytRv, 0)) 

if (verPara.bIDEDeviceMap > 0

byte bIDCmd = (byte)(((verPara.bIDEDeviceMap >> drive & 0x10!= 0? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY); 
SENDCMDINPARAMS scip 
= new SENDCMDINPARAMS(); 
SENDCMDOUTPARAMS scop 
= new SENDCMDOUTPARAMS(); 

scip.cBufferSize 
= IDENTIFY_BUFFER_SIZE; 
scip.irDriveRegs.bFeaturesReg 
= 0
scip.irDriveRegs.bSectorCountReg 
= 1
scip.irDriveRegs.bCylLowReg 
= 0
scip.irDriveRegs.bCylHighReg 
= 0
scip.irDriveRegs.bDriveHeadReg 
= (byte)(0xA0 | ((drive & 1<< 4)); 
scip.irDriveRegs.bCommandReg 
= bIDCmd; 
scip.bDriveNumber 
= drive; 

if (0 != DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA, 
ref scip, Marshal.SizeOf(scip), ref scop, 
Marshal.SizeOf(scop), 
ref bytRv, 0)) 

StringBuilder s 
= new StringBuilder(); 
for (int i = 20; i < 40; i += 2

s.Append((
char)(scop.bBuffer[i+1])); 
s.Append((
char)scop.bBuffer[i]); 
}
 
CloseHandle(device); 
return s.ToString().Trim(); 
}
 
}
 
}
 
CloseHandle(device); 
return ""
}
 
}