我写的检测硬盘程序记录了我的硬盘的ID,本来是想当真正的用户第一次运行后,就记录他的ID,如果有人非法复制使用,就不能使用程序了,但是去到另外一台机子,也可以运行,并且也改了那个ID,为什么会这样的呢,而且在WINME那里真的检测不了ID的,请教是我那里错了,或者是我做错了那一步呢?麻烦请各位帮忙检测一下,谢谢unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,inifiles;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}
var
 SoftIniFile:Tinifile;
 CheckFirstRun:Boolean;
 IsFirstRun,Diskid:string;function GetId : String;
type 
TSrbIoControl = packed record 
HeaderLength : ULONG; 
Signature : Array[0..7] of Char; 
Timeout : ULONG; 
ControlCode : ULONG;
ReturnCode : ULONG; 
Length : ULONG; 
end; 
SRB_IO_CONTROL = TSrbIoControl; 
PSrbIoControl = ^TSrbIoControl; 
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; 
TIdSector = packed record 
wGenConfig : Word; 
wNumCyls : Word; 
wReserved : Word; 
wNumHeads : Word; 
wBytesPerTrack : Word; 
wBytesPerSector : Word; 
wSectorsPerTrack : Word; 
wVendorUnique : Array[0..2] of Word; 
sSerialNumber : Array[0..19] of Char; 
wBufferType : Word; 
wBufferSize : Word; 
wECCSize : Word; 
sFirmwareRev : Array[0..7] of Char; 
sModelNumber : Array[0..39] of Char; 
wMoreVendorUnique : Word; 
wDoubleWordIO : Word; 
wCapabilities : Word; 
wReserved1 : Word; 
wPIOTiming : Word; 
wDMATiming : Word; 
wBS : Word; 
wNumCurrentCyls : Word; 
wNumCurrentHeads : Word; 
wNumCurrentSectorsPerTrack : Word; 
ulCurrentSectorCapacity : ULONG; 
wMultSectorStuff : Word; 
ulTotalAddressableSectors : ULONG; 
wSingleWordDMA : Word; 
wMultiWordDMA : Word; 
bReserved : Array[0..127] of Byte; 
end; 
PIdSector = ^TIdSector; 
const 
IDE_ID_FUNCTION = $EC; 
IDENTIFY_BUFFER_SIZE = 512; 
DFP_RECEIVE_DRIVE_DATA = $0007c088; 
IOCTL_SCSI_MINIPORT = $0004d008; 
IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501; 
DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE; 
BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize; 
W9xBufferSize = IDENTIFY_BUFFER_SIZE+16; 
var 
hDevice : THandle; 
cbBytesReturned : DWORD; 
pInData : PSendCmdInParams; 
pOutData : Pointer; // PSendCmdOutParams 
Buffer : Array[0..BufferSize-1] of Byte; 
srbControl : TSrbIoControl absolute Buffer; 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; 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; Function CheckFirstRunTrue:boolean;
Var IsFirstRun:String;
Begin
  SoftIniFile:=TIniFile.Create(GetCurrentDir+'\soft.ini');
  IsFirstRun:=SoftIniFile.ReadString('option','IsFirstRun','False');
  SoftIniFile.Free;
  If IsFirstRun='true' then CheckFirstRunTrue:=True Else CheckFirstRun:=False;
End;//检查是否DiskID和本机硬盘ID相同
Function CheckDiskID:Boolean;
Var DiskID,Temp,LocalID:String;
    I:Integer;
Begin
  SoftIniFile:=TIniFile.Create(GetCurrentDir+'\soft.ini');
  DiskID:=SoftIniFile.ReadString('option','DiskID','');
  SoftIniFile.Free;
  Temp:=GetID;
  While Not (Temp[i]=' ') do
    Begin
      LocalID:=LocalID+Temp[i];
      i:=i+1;
    End;
  If LocalID = DiskID then CheckDiskID:=True Else CheckDiskID:=False;
End;//写入INI文件,调用时将会得到本机硬盘
//DiskID并且写入INI文件中,因此只能在
//CheckFir
//stRunTrue为true时调用
Procedure WriteIniFile;
Begin
  SoftIniFile:=TiniFile.Create(GetCurrentDir+'\soft.ini');
  IsFirstRun:='False';
  SoftIniFile.WriteString('option','IsFirstRun',IsFirstRun);
  DiskID:=GetID;
  SoftIniFile.WriteString('option','DiskID',DiskID);
  SoftIniFile.Free;
End;procedure TForm1.FormCreate(Sender: TObject);
Begin
  If FileExists(GetCurrentDir+'\soft.ini') then  //这里是如果ini文件不存在则处理
  If CheckFirstRunTrue then WriteIniFile //如果确定是第一次运行,就会得到本机Dis
//kID并写入文件
     Else If CheckDiskID then
             Begin //INI文件中的DiskID和本机DiskID相同时候执行
             SHowmessage('yes');
             exit;
             End
                         Else
             Begin //ini文件中的DiskID和本机DiskID不同时候执行
             SHowmessage('no');
             exit;
             End;
End;end.