به نظر من یکی از بهترین روش ها استفاده تواما از چندین روش قفل گذاری می باشد .

یکی از روش هایی که مدت هاست که مرسوم است استفاده از ریجستری است. البته این روش به تنهایی قادر به تامین امنیت برنامه نمی باشد.
در این روش اطلاعات کاربر و رمز ورود و سایر مشخصات مورد نیاز در قسمتی از ریجستری که دور از ذهن باشد به صورت کد شده نوشته می شود. لازم به ذکر است که یکی از ضعف های این روش این است که با استفاده از یک برنامه مانیتورینگ پی به محل ذخیره سازی اطلاعات برد.

یکی دیگر از روش ها نوشتن اطلاعات و مشخصات به صورت کد شده و به صورت یک رکورد در آخر یک فایل.
این فایل می تواند یک فایل DLL باشد یا هر فایلی ولی فایل DLL ترجیه داده می شود. این روش نسبت به استفاده از ریجستری از امنیت بیشتری برخوردار است ولی باز هم کافی نیست.

اما... یکی از بهترین روش ها استفاده از دو روش مذکور به طور همزمان است.

اطلاعات کاربر و اطلاعات برنامه در یک رکورد قرار گرفته و این رکورد می تواند در درون ریجستری و در آخر یک یا چندین فایل مختلف قرار گیرد.

البته به علت طولانی شدن مبحث (و... ) فقط روش نوشتن رکورد های ثبت در آخر فایل در زیر توضیح داده شده!

برای مثال رکوردی مانند این:

  TProgTrial=Packed Record
    fWinVer:integer      ;
    fProgVer:integer   ;
    fRemindTime:TDateTime;
    fLastUse:TDateTime;
    fTrial:Boolean;
    fUserName:string[30];
    fUsedDays:cardinal;
  end;
  TProgAccess=Packed Record
    fWinVer:integer      ;
    fProgVer:integer   ;
    fUserName:string[30];
    fRegistered:Boolean;
    fRegTime:TDateTime;
  end;

رکورد اولی یعنی TProgTrial زمانی توسط برنامه نوشته می شه که برنامه زمان دار یا همان Trial است. بعد از هر روز یک عدد به مقدار fUsedDays افزوده می شود و مقدار fTrial هم true است.علت استفاده از fTrial هم در پایین توضیح داده شده است.

رکورد دومی یعنی TProgAccess هم زمانی نوشته می شود که برنامه توسط کاربر به ثبت رسیده باشد. یعنی کاربر کد ثبت را به درستی وارد کرده و برنامه به طور کامل در اختیار او قرار می گیرد.

نکته ای که در اینجا مهم است نحوه خواندن رکورد های فوق از آخر فایل است. برای تعیین محل خواندن اطلاعات باید اندازه فایل را منهای اندازه رکورد کرد تا محل خواندن اطلاعات مشخص شود.
مثال زیر این نکته را در خط 18 نشان می دهد. البته مثال زیر مربوط به رکورد TProgTrial است:

Function GetFileTrial(fName:String):TProgTrial;
var
  fFileStream:TFileStream;
begin
try
  If not FileExists(fName) then begin
    Result.fWinVer:=0;
    Result.fProgVer:=0;
    Result.fRemindTime:=0;
    Result.fTrial:=false;
    Result.fUserName:='';
    Result.fUsedDays:=999999;
    Result.fLastUse:=0;
    exit;
  end;
  fFileStream:=TFileStream.Create(fName,fmOpenRead or fmShareDenyWrite);
  try
    fFileStream.Seek(fFileStream.Size-SizeOf(TProgTrial),soBeginning);
    fFileStream.ReadBuffer(result,sizeOf(TProgTrial));
  finally
    fFileStream.Free;
  end;
  Result.fWinVer:=(Result.fWinVer);
  Result.fprogVer:=((Result.fProgVer));
  Result.fUserName:=((Result.fUserName));
except
end;
end;

و این مثال TProgAccess :

Function GetFileAccess(fName:String):TProgAccess;
var
  fFileStream:TFileStream;
begin
try
  If not FileExists(fName) then begin
    Result.fWinVer:=0;
    Result.fprogVer:=0;
    Result.fRegTime:=0;
    Result.fRegistered:=false;
    Result.fUserName:='';
    exit;
  end;
  fFileStream:=TFileStream.Create(fName,fmOpenRead or fmShareDenyWrite);
  try
    fFileStream.Seek(-sizeOf(TProgAccess),soEnd);
    fFileStream.ReadBuffer(result,sizeOf(TProgAccess));
  finally
    fFileStream.free;
  end;
  Result.fWinVer:=((Result.fWinVer));
  Result.fprogVer:=((Result.fprogVer));
  Result.fUserName:=TrimRight((Result.fUserName));

except
end;
end;

و نکته دیگر اینکه باید صحت رکوردها مورد بررسی قرار گیرد. یعنی با اطلاعات برنامه تطابق داده شود. کد های زیر این مطلب را نشان می دهند:

const
  sVersion=1;
  sRemindUserName='SalarSoftwares';

function AccessFile(fName: String): Boolean;
var
  fProgReg:TProgAccess;
  Major,Minor:Cardinal;
begin
try
  result:=false;
  Major :=  (DWORD(LOBYTE(LOWORD(GetVersion))));
  Minor :=  (DWORD(HIBYTE(LOWORD(GetVersion))));
  fProgReg:=GetFileAccess(fName);
  If fProgReg.fRegistered then
    result:=true;
  If (fProgReg.fWinVer)<>(Major+Minor) then
    Result:=false;
  If fProgReg.fprogVer<>sVersion then
    result:=false;
Except
  Result:=false;
end;
end;

function TimedFile(fName: String): Boolean;
var
  fprogRemind:TProgTrial;
  Major,Minor:Cardinal;
begin
Result:=false;
try
  Major :=  (DWORD(LOBYTE(LOWORD(GetVersion))));
  Minor :=  (DWORD(HIBYTE(LOWORD(GetVersion))));
  fprogRemind:=GetFileTrial(fName);
  If fprogRemind.fTrial then
    result:=true;
  If fprogRemind.fUserName=sRemindUserName then
    result:=true;
  If (fprogRemind.fWinVer)<>(Major+Minor) then
    Result:=false;
  If fprogRemind.fprogVer<>sVersion then
    result:=false;
Except
  Result:=false;
end;
end;


و نکته دیگر اینکه حتما باید در هنگام خواندن رکوردها هر دوی این رکوردها خوانده شود. علت کار این است که برای تشخیص اینکه برنامه به ثبت رسیده یا Trial است لازم می باشد.
کدهای زیر این مطلب را نشان می دهند:

type
  TAccessMode=(amNone,amTimed,amFullAccess,amError);
function GetAccessMode(filename:Tfilename): TAccessMode;
var
  fret1,fret2:Boolean;
begin
try
  Result:=amError;
  fret1:=AccessFile(filename) ;
  fret2:=TrialFile(filename) ;
  //fret3:=AccessReg(sRegAddr); //Define with self
  //fret4:=TrialReg(sRegAddr); //Define with self
  If fret2 then
    Result:=amTimed;
  If fret1 then
    Result:=amFullAccess;
  If (fret1 and fret2)then //error when fret1=fret2=true
    Result:=amError;
  If not (fret1 or fret2) then
    Result:=amNone;
except
  Result:=amError;
end;
end;

در این کد GetAccessMode نوع دسترسی شما به فایل را نشان می دهد:
amNone: یعنی هیچ کاری بر روی فایل انجام نگرفته است و نه به ثبت رسیده و نه Trial است.
amTimed: یعنی فایل trial است.
amFullAccess: یعنی فایل به طور کامل و درست به ثبت رسیده است.
amError: یعنی اشکالی در ثبت فایل وجود دارد و برنامه نباید به کار خود ادامه دهد.

وآخرین نکته در این مبحث نحوه نوشتن رکورد ها در فایل است. به کد های زیر دقت فرمایید.

کدهای زیر این مطلب را نشان می دهند:

function SetAccessFile(fName:String;fUser: String): Boolean;
var
  Hfile:file;
  fBReg:TprogAccess;
  Major,Minor:Cardinal;
begin
try
  AssignFile(Hfile,fname);
  reset(Hfile,1);
  try
    seek(Hfile,Filesize(Hfile)-SizeOf(TprogAccess));
    blockread(Hfile,fBReg,sizeOf(fBReg));
    If fBReg.fprogVer<>sVersion then
      seek(Hfile,Filesize(Hfile){-SizeOf(TprogAccess)});
    Major :=  (DWORD(LOBYTE(LOWORD(GetVersion))));
    Minor :=  (DWORD(HIBYTE(LOWORD(GetVersion))));
    //GetVersionEx(OsVer);
    fBReg.fWinVer:=(Major)+(Minor);
    fBReg.fprogVer:=(sVersion);
    fBReg.fRegTime:=now;
    fBReg.fRegistered:=True;
    fBReg.fUserName:=(fUser);
    blockwrite(Hfile,fBReg,sizeOf(fBReg));
  finally
    closeFile(Hfile);
    Result:=true;
  end;
except
  Result:=false;
end;
end;

Function GetShortFilename(Const FileName:TFileName):TFilename;
var
  Buffer:Array[0..Max_Path-1] of char;
begin
SetString(Result,Buffer,GetShortPathName(Pchar(Filename),Buffer,Max_Path-1));
Result:=lowerCase(Result);
end;

function SetTimedFile(fName: String;fRemindTime,fLastUse:TDateTime;UsedDays:Cardinal): Boolean;
var
  hfile:file;
  fBRemind:TProgTrial;
  Major,Minor:Cardinal;
begin
try
  Result:=true;
  fname:=GetShortFilename(fname);
  If not fileexists(fname) then exit;
  AssignFile(hfile,(fname));
  reset(hfile,1);
  try
    seek(hfile,Filesize(hfile)-SizeOf(TProgTrial));
    blockread(hfile,fBRemind,sizeOf(fBRemind));
    If fBRemind.fprogVer<>sVersion then
    begin
      seek(hfile,Filesize(hfile){-SizeOf(TprogTimed)});
    end
    else
    begin
      seek(hfile,Filesize(hfile)-SizeOf(TProgTrial));
    end;
    Major :=  (DWORD(LOBYTE(LOWORD(GetVersion))));
    Minor :=  (DWORD(HIBYTE(LOWORD(GetVersion))));
    //GetVersionEx(OsVer);
    fBRemind.fLastUse:=fLastUse;
    fBRemind.fRemindTime:=fRemindTime;
    fBRemind.fWinVer:=(Major)+(Minor);
    fBRemind.fprogVer:=(sVersion);
    fBRemind.fTrial:=true;
    fBRemind.fUserName:=(sRemindUserName);
    fBRemind.fUsedDays:=UsedDays;
    blockwrite(hfile,fBRemind,sizeOf(fBRemind));
    Result:=true;
  finally
    closeFile(hfile);
  end;
except
  Result:=false;
end;
end;
مطالب برگرفته از سایت آقای سالار خلیل زاده هستش ...  آدرس ایشون : www.salarsoft.somee.com