⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 DELPHI编写的获取电脑CPU和硬盘序列号的测试程序,可以用于共享软件编写注册码用.我写的共享软件就是用这方法编写.
💻 PAS
字号:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
type
  TCID= array[1..4] of Longint;

function TargetID : TCID; assembler; register;     //得到CPU序列号
asm
  PUSH    EBX         {Save affected register}
  PUSH    EDI
  MOV     EDI,EAX     {@Resukt}
  MOV     EAX,1
  DW      $A20F       {CPUID Command}
  STOSD                {CID[1]}
  MOV     EAX,EBX
  STOSD               {CID[2]}
  MOV     EAX,ECX
  STOSD               {CID[3]}
  MOV     EAX,EDX
  STOSD               {CID[4]}
  POP     EDI          {Restore registers}
  POP     EBX
end;

//获得硬盘序列号
function PlanID : 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 // Windows NT, Windows 2000
  begin
    // 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 // Windows 95 OSR2, Windows 98
  begin
    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;

procedure TForm1.Button1Click(Sender: TObject);
var
  CID: TCID;
begin
  CID:=TargetID; //获得CPU序列号
  Edit1.text:=inttostr(CID[1])+inttostr(CID[2])+inttostr(CID[3])+inttostr(CID[4]);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Edit2.Text:=PlanID;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -