G
grj1
Unregistered / Unconfirmed
GUEST, unregistred user!
如何获取硬盘的ID ? 我这有源码,但是读不出来。<br><br>原码如下:<br>unit Unit1;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> StdCtrls, registry;<br><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><br>const<br> IDENTIFY_BUFFER_SIZE = 512;<br> DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;<br> IOCTL_SCSI_MINIPORT = $0004d008;<br> IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;<br> IDE_ID_FUNCTION = $EC;<br> BufferSize=1280;<br><br>type<br> TForm1 = class(TForm)<br> Label1: TLabel;<br> procedure FormCreate(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> Form1: TForm1;<br> serial:string;<br> inputserial:string;<br><br>implementation<br>uses<br> unit2;<br>{$R *.DFM}<br>function encrypt(serial:string):string;<br>var<br> i:dword;<br> len:dword;<br> r:dword;<br>begin<br> r:=0;<br> len:=length(serial);<br> for i:=1 to len do<br> begin<br> r:=r+dword(serial);<br> r:=r*10;<br> end;<br> result:=inttostr(r);<br>end;<br><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 readhdserial:string;<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><br> //通过MS的S.M.A.R.T.接口,直接从RING3调用<br> //API DeviceIoControl()来获取硬盘信息<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<br> Exit;<br> with PIdSector(PChar(pOutData)+16)^ do<br> begin<br> ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));<br> SetString(Result,sSerialNumber,SizeOf(sSerialNumber));<br> end;<br> finally<br> CloseHandle(hDevice);<br> end;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br> reg:tregistry;<br> s:string;<br>begin<br> serial:=readhdserial();<br> inputserial:=encrypt(serial);<br> reg:=tregistry.create;<br> reg.RootKey:=HKEY_CLASSES_ROOT;<br> if not reg.openKey('/License/'+serial,false) then<br> //打开注册表项,没有该项,则是第一次启动<br> begin<br> Application.CreateForm(TOKBottomDlg, OKBottomDlg);<br> OKBottomDlg.showmodal;<br> OKBottomDlg.Destroy;<br> //输入序列号正确,则<br> //将已安装信息写入注册表<br> reg.createkey('/License/'+serial);<br> reg.openkey('/License/'+serial,false);<br> reg.writestring('installed','true');<br> //将序列号写入注册表<br> reg.Createkey('/License/'+inputserial);<br> reg.OpenKey('/License/'+inputserial,false);<br> reg.WriteString('1',inputserial);<br> reg.closekey;<br> end<br> else<br> begin//是今后的启动<br> reg.CloseKey;<br> //检查序列号<br> reg.openkey('/License/'+inputserial,false);<br> s:=reg.readstring('1');<br> reg.closekey;<br> if inputserial<>s then<br> begin<br> Application.CreateForm(TOKBottomDlg, OKBottomDlg);<br> OKBottomDlg.showmodal;<br> end;<br> end;<br>end;<br><br>end.<br><br>通过跟踪发现:下面的两行执行,跳出了程序,不知为何,请高手指点。<br> if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT,<br> @Buffer, BufferSize, @Buffer, BufferSize,<br> cbBytesReturned, nil ) then<br> Exit;<br><br>