tideregs = packed record
bfeaturesreg : byte; // used for specifying smart "commands".
bsectorcountreg : byte; // ide sector count register
bsectornumberreg : byte; // ide sector number register
bcyllowreg : byte; // ide low order cylinder value
bcylhighreg : byte; // ide high order cylinder value
bdriveheadreg : byte; // ide drive/head register
bcommandreg : byte; // actual ide command.
breserved : byte; // reserved. must be zero.
end;
ideregs = tideregs;
pideregs = ^tideregs;
tsendcmdinparams = packed record
cbuffersize : dword;
irdriveregs : tideregs;
bdrivenumber : byte;
breserved : array[0..2] of byte;
dwreserved : array[0..3] of dword;
bbuffer : array[0..0] of byte;
end;
sendcmdinparams = tsendcmdinparams;
psendcmdinparams = ^tsendcmdinparams;
var
hdidform: thdidform;
function getidediskserialnumber : string;
implementation
{$r *.dfm}
procedure changebyteorder( var data; size : integer );
var ptr : pchar;
i : integer;
c : char;
begin
ptr := @data;
for i := 0 to (size shr 1)-1 do
begin
c := ptr^;
ptr^ := (ptr+1)^;
(ptr+1)^ := c;
inc(ptr,2);
end;
end;
function getidediskserialnumber : string;
var
hdevice : thandle;
cbbytesreturned : dword;
pindata : psendcmdinparams;
poutdata : pointer; // psendcmdoutparams
buffer : array[0..buffersize-1] of byte;
srbcontrol : tsrbiocontrol absolute buffer;
begin
result := '';
fillchar(buffer,buffersize,#0);
if win32platform=ver_platform_win32_nt then
begin // windows nt, windows 2000
// get scsi port handle
hdevice := createfile( '\\.\scsi0:',
generic_read or generic_write,
file_share_read or file_share_write,
nil, open_existing, 0, 0 );
if hdevice=invalid_handle_value then exit;
try
srbcontrol.headerlength := sizeof(srb_io_control);
system.move('scsidisk',srbcontrol.signature,8);
srbcontrol.timeout := 2;
srbcontrol.length := datasize;
srbcontrol.controlcode := ioctl_scsi_miniport_identify;
pindata := psendcmdinparams(pchar(@buffer)
+sizeof(srb_io_control));
poutdata := pindata;
with pindata^ do
begin
cbuffersize := identify_buffer_size;
bdrivenumber := 0;
with irdriveregs do
begin
bfeaturesreg := 0;
bsectorcountreg := 1;
bsectornumberreg := 1;
bcyllowreg := 0;
bcylhighreg := 0;
bdriveheadreg := $a0;
bcommandreg := ide_id_function;
end;
end;
if not deviceiocontrol( hdevice, ioctl_scsi_miniport,
@buffer, buffersize, @buffer, buffersize,
cbbytesreturned, nil ) then exit;
finally
closehandle(hdevice);
end;
end
else
begin // windows 95 osr2, windows 98
hdevice := createfile( '\\.\smartvsd', 0, 0, nil,
create_new, 0, 0 );
if hdevice=invalid_handle_value then exit;
try
pindata := psendcmdinparams(@buffer);
poutdata := @pindata^.bbuffer;
with pindata^ do
begin
cbuffersize := identify_buffer_size;
bdrivenumber := 0;
with irdriveregs do
begin
bfeaturesreg := 0;
bsectorcountreg := 1;
bsectornumberreg := 1;
bcyllowreg := 0;
bcylhighreg := 0;
bdriveheadreg := $a0;
bcommandreg := ide_id_function;
end;
end;
if not deviceiocontrol( hdevice, dfp_receive_drive_data,
pindata, sizeof(tsendcmdinparams)-1, poutdata,
w9xbuffersize, cbbytesreturned, nil ) then exit;
finally
closehandle(hdevice);
end;
end;
with pidsector(pchar(poutdata)+16)^ do
begin
changebyteorder(sserialnumber,sizeof(sserialnumber));
setstring(result,sserialnumber,sizeof(sserialnumber));
end;
end;
end.
//win98要 c:\windows\system\的smartvsd.vxd
//copy to c:\windows\system\iosubsys
//reboot your computer and ok
//2000 and nt do not need
得到硬盘物理序号: