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

📄 unit1.pas

📁 Delphi实效编程百例的随书源代码 这是其中的程序发布部分
💻 PAS
字号:
unit Unit1;

interface

uses
  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.

⌨️ 快捷键说明

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