物理序列号才是唯一的!<br><br>附代码一段:<br>得到硬盘物理序号 <br>unit hdid;<br>interface<br>uses<br> windows, controls,sysutils,forms;<br> //, graphics, dialogs, classes, messages,stdctrls;<br>type<br> tsrbiocontrol = packed record<br> headerlength : ulong;<br> signature : array[0..7] of char;<br> timeout : ulong;<br> controlcode : ulong;<br> returncode : ulong;<br> length : ulong;<br> end;<br> srb_io_control = tsrbiocontrol;<br> psrbiocontrol = ^tsrbiocontrol;<br><br> tideregs = packed record<br> bfeaturesreg : byte; // used for specifying smart "commands".<br> bsectorcountreg : byte; // ide sector count register<br> bsectornumberreg : byte; // ide sector number register<br> bcyllowreg : byte; // ide low order cylinder value<br> bcylhighreg : byte; // ide high order cylinder value<br> bdriveheadreg : byte; // ide drive/head register<br> bcommandreg : byte; // actual ide command.<br> breserved : byte; // reserved. must be zero.<br> end;<br> ideregs = tideregs;<br> pideregs = ^tideregs;<br><br> tsendcmdinparams = packed record<br> cbuffersize : dword;<br> irdriveregs : tideregs;<br> bdrivenumber : byte;<br> breserved : array[0..2] of byte;<br> dwreserved : array[0..3] of dword;<br> bbuffer : array[0..0] of byte;<br> end;<br> sendcmdinparams = tsendcmdinparams;<br> psendcmdinparams = ^tsendcmdinparams;<br><br> tidsector = packed record<br> wgenconfig : word;<br> wnumcyls : word;<br> wreserved : word;<br> wnumheads : word;<br> wbytespertrack : word;<br> wbytespersector : word;<br> wsectorspertrack : word;<br> wvendorunique : array[0..2] of word;<br> sserialnumber : array[0..19] of char;<br> wbuffertype : word;<br> wbuffersize : word;<br> weccsize : word;<br> sfirmwarerev : array[0..7] of char;<br> smodelnumber : array[0..39] of char;<br> wmorevendorunique : word;<br> wdoublewordio : word;<br> wcapabilities : word;<br> wreserved1 : word;<br> wpiotiming : word;<br> wdmatiming : word;<br> wbs : word;<br> wnumcurrentcyls : word;<br> wnumcurrentheads : word;<br> wnumcurrentsectorspertrack : word;<br> ulcurrentsectorcapacity : ulong;<br> wmultsectorstuff : word;<br> ultotaladdressablesectors : ulong;<br> wsingleworddma : word;<br> wmultiworddma : word;<br> breserved : array[0..127] of byte;<br> end;<br> pidsector = ^tidsector;<br><br>const<br> ide_id_function = $ec;<br> identify_buffer_size = 512;<br> dfp_receive_drive_data = $0007c088;<br> ioctl_scsi_miniport = $0004d008;<br> ioctl_scsi_miniport_identify = $001b0501;<br> datasize = sizeof(tsendcmdinparams)-1+identify_buffer_size;<br> buffersize = sizeof(srb_io_control)+datasize;<br> w9xbuffersize = identify_buffer_size+16;<br>type<br> thdidform = class(tform)<br> private<br> { private declarations }<br> public<br><br> { public declarations }<br> end;<br><br>var<br> hdidform: thdidform;<br> function getidediskserialnumber : string;<br><br>implementation<br><br>{$r *.dfm}<br>procedure changebyteorder( var data; size : integer );<br> var ptr : pchar;<br> i : integer;<br> c : char;<br> begin<br> ptr := @data;<br> for i := 0 to (size shr 1)-1 do<br> begin<br> c := ptr^;<br> ptr^ := (ptr+1)^;<br> (ptr+1)^ := c;<br> inc(ptr,2);<br> end;<br> end;<br><br>function getidediskserialnumber : string;<br><br>var <br> hdevice : thandle; <br> cbbytesreturned : dword; <br> pindata : psendcmdinparams; <br> poutdata : pointer; // psendcmdoutparams <br> buffer : array[0..buffersize-1] of byte;<br> srbcontrol : tsrbiocontrol absolute buffer;<br>begin<br> result := '';<br> fillchar(buffer,buffersize,#0);<br> if win32platform=ver_platform_win32_nt then<br> begin // windows nt, windows 2000<br> // get scsi port handle<br> hdevice := createfile( '//./scsi0:',<br> generic_read or generic_write,<br> file_share_read or file_share_write,<br> nil, open_existing, 0, 0 );<br> if hdevice=invalid_handle_value then exit;<br> try<br> srbcontrol.headerlength := sizeof(srb_io_control);<br> system.move('scsidisk',srbcontrol.signature,8);<br> srbcontrol.timeout := 2;<br> srbcontrol.length := datasize;<br> srbcontrol.controlcode := ioctl_scsi_miniport_identify;<br> pindata := psendcmdinparams(pchar(@buffer)<br> +sizeof(srb_io_control));<br> poutdata := pindata;<br> with pindata^ do<br> begin<br> cbuffersize := identify_buffer_size;<br> bdrivenumber := 0;<br> with irdriveregs do<br> begin<br> bfeaturesreg := 0;<br> bsectorcountreg := 1;<br> bsectornumberreg := 1;<br> bcyllowreg := 0;<br> bcylhighreg := 0;<br> bdriveheadreg := $a0;<br> bcommandreg := ide_id_function;<br> end;<br> end;<br> if not deviceiocontrol( hdevice, ioctl_scsi_miniport,<br> @buffer, buffersize, @buffer, buffersize,<br> cbbytesreturned, nil ) then exit;<br> finally<br> closehandle(hdevice);<br> end;<br> end<br> else<br> begin // windows 95 osr2, windows 98<br> hdevice := createfile( '//./smartvsd', 0, 0, nil,<br> create_new, 0, 0 );<br> if hdevice=invalid_handle_value then exit;<br> try<br> pindata := psendcmdinparams(@buffer);<br> poutdata := @pindata^.bbuffer;<br> with pindata^ do<br> begin<br> cbuffersize := identify_buffer_size;<br> bdrivenumber := 0;<br> with irdriveregs do<br> begin<br> bfeaturesreg := 0;<br> bsectorcountreg := 1;<br> bsectornumberreg := 1;<br> bcyllowreg := 0;<br> bcylhighreg := 0;<br> bdriveheadreg := $a0;<br> bcommandreg := ide_id_function;<br> end;<br> end;<br> if not deviceiocontrol( hdevice, dfp_receive_drive_data,<br> pindata, sizeof(tsendcmdinparams)-1, poutdata,<br> w9xbuffersize, cbbytesreturned, nil ) then exit;<br> finally<br> closehandle(hdevice);<br> end;<br> end;<br> with pidsector(pchar(poutdata)+16)^ do<br> begin<br> changebyteorder(sserialnumber,sizeof(sserialnumber));<br> setstring(result,sserialnumber,sizeof(sserialnumber));<br> end;<br>end;<br><br>end.<br><br>//win98要 c:/windows/system/的smartvsd.vxd拷贝到 c:/windows/system/iosubsys 然后重启生效 <br>//2000 and nt do not need<br>得到硬盘物理序号:<br>hdsn:=trim(getidediskserialnumber);