nieyangjie

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

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, 0, 0);
if (device == invalid_handle_value) return "";
getversionoutparams verpara = new getversionoutparams();
uint bytrv = 0;

if (0 != deviceiocontrol(device, dfp_get_version,
0, 0, ref 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 "";
}
}



posted on 2012-05-01 20:25  nieyangjie  阅读(174)  评论(0编辑  收藏

My Links

Blog Stats