有的软件通过简单的输入用户名,决定注册码;而又有的软件是通过机器码、EMAIL、用户名这三个条件决定注册码,那个机器码是怎么得出的?这一种算法是否会因为更换硬件(如CPU,换大容量硬盘)而引起用户必须重新取注册码的问题?
能否给几个示范代码吧。

解决方案 »

  1.   

    一般都是硬盘id
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Label1: TLabel;
        Edit1: TEdit;
        Label2: TLabel;
        Edit2: TEdit;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}
    function encrypt(serial:string):string;
    var
      i:dword;
      len:dword;
      r:dword;
    begin
      r:=0;
      len:=length(serial);
      for i:=1 to len do
      begin
        r:=r+dword(serial[i]);
        r:=r*10;
      end;
      result:=inttostr(r);
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      edit2.text:=encrypt(edit1.text);
    end;end.
      

  2.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, registry;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
      IDENTIFY_BUFFER_SIZE = 512;
      DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
      IOCTL_SCSI_MINIPORT = $0004d008;
      IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;
      IDE_ID_FUNCTION = $EC;
      BufferSize=1280;type
      TForm1 = class(TForm)
        Label1: TLabel;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      serial:string;
      inputserial:string;implementation
    uses
      unit2;
    {$R *.DFM}
    function encrypt(serial:string):string;
    var
      i:dword;
      len:dword;
      r:dword;
    begin
      r:=0;
      len:=length(serial);
      for i:=1 to len do
      begin
        r:=r+dword(serial[i]);
        r:=r*10;
      end;
      result:=inttostr(r);
    end;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 readhdserial: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);  //通过MS的S.M.A.R.T.接口,直接从RING3调用
      //API DeviceIoControl()来获取硬盘信息
      // 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;
        with PIdSector(PChar(pOutData)+16)^ do
        begin
          ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
          SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
        end;
      finally
        CloseHandle(hDevice);
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      reg:tregistry;
      s:string;
    begin
      serial:=readhdserial();
      inputserial:=encrypt(serial);
      reg:=tregistry.create;
      reg.RootKey:=HKEY_CLASSES_ROOT;
      if not reg.openKey('\Licenses\'+serial,false) then
      //打开注册表项,没有该项,则是第一次启动
      begin
        Application.CreateForm(TOKBottomDlg, OKBottomDlg);
        OKBottomDlg.showmodal;
        OKBottomDlg.Destroy;
        //输入序列号正确,则
        //将已安装信息写入注册表
        reg.createkey('\Licenses\'+serial);
        reg.openkey('\Licenses\'+serial,false);
        reg.writestring('installed','true');
        //将序列号写入注册表
        reg.Createkey('\Licenses\'+inputserial);
        reg.OpenKey('\Licenses\'+inputserial,false);
        reg.WriteString('1',inputserial);
        reg.closekey;
      end
      else
      begin//是今后的启动
        reg.CloseKey;
        //检查序列号
        reg.openkey('\Licenses\'+inputserial,false);
        s:=reg.readstring('1');
        reg.closekey;
        if inputserial<>s then
        begin
          Application.CreateForm(TOKBottomDlg, OKBottomDlg);
          OKBottomDlg.showmodal;
        end;
      end;
    end;end.
      

  3.   

    to grail_(grail_) 
    你的代码是不是在所有系统下都能获得硬盘 id??