Вступление

Один из механизмов защиты от пиратства в области компьютерных программ предполагает привязку программы к железу, на котором оно установлено. Для этого необходимо определить параметры этого самого железа, например серийный номер жёсткого диска, на который устанавливается ПО. Он не является на 100% уникальным (лично сталкивался с тем, что у целой партии HDD был один серийник), но в совокупности с другими сведениями это поможет.

Задача 1

Определить серийный номер жёсткого диска.

Решение

procedure TForm1.Button1Click(Sender: TObject);
var
  VolumeName, FileSystemName: array [0 .. MAX_PATH - 1] of Char;
  VolumeSerialNo: DWord;
  MaxComponentLength, FileSystemFlags: DWord;
begin
  GetVolumeInformation('C:\', VolumeName, MAX_PATH, @VolumeSerialNo,
    MaxComponentLength, FileSystemFlags, FileSystemName, MAX_PATH);
  Memo1.Lines.Add('VName = ' + VolumeName);
  Memo1.Lines.Add('SerialNo = $' + IntToHex(VolumeSerialNo, 8));
  Memo1.Lines.Add('CompLen = ' + IntToStr(MaxComponentLength));
  Memo1.Lines.Add('Flags = $' + IntToHex(FileSystemFlags, 4));
  Memo1.Lines.Add('FSName = ' + FileSystemName);
end;Code language: Delphi (delphi)

Комментарий

Функция GetVolumeInformation позволяет получить нужную информацию:

Задача 2

Определить частоту процессора

Решение

function GetCPUSpeed: Double;
const
  DelayTime = 500;
var
  TimerHi: DWORD;
  TimerLo: DWORD;
  PriorityClass: Integer;
  Priority: Integer;
begin
  // Рок-н-ролл!
  PriorityClass := GetPriorityClass(GetCurrentProcess);
  Priority := GetThreadPriority(GetCurrentThread);
  SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
  SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
  Sleep(10);
  asm
    DW 310Fh // rdtsc
    MOV TimerLo, EAX
    MOV TimerHi, EDX
  end;
  Sleep(DelayTime);
  asm
    DW 310Fh // rdtsc
    SUB EAX, TimerLo
    SBB EDX, TimerHi
    MOV TimerLo, EAX
    MOV TimerHi, EDX
  end;
  // Вернём на место
  SetThreadPriority(GetCurrentThread, Priority);
  SetPriorityClass(GetCurrentProcess, PriorityClass);
  Result := TimerLo / (1000.0 * DelayTime);
end;Code language: Delphi (delphi)

Комментарий

Эта процедура производит реальный замер частоты процессора, что для идентификации не совсем подходит: частота некоторых процессоров зависит от температуры ядра. Однако сам метод заслуживает внимания.

Вариант использования:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.Caption := Format('CPU speed: %f MHz', [GetCPUSpeed]);
end;Code language: Delphi (delphi)

Верификация

Delphi XE5, Win7

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *