Initial Revision
This commit is contained in:
commit
5bca4ba6a2
38
SmartPatcher.cfg
Normal file
38
SmartPatcher.cfg
Normal file
@ -0,0 +1,38 @@
|
||||
-$A8
|
||||
-$B-
|
||||
-$C+
|
||||
-$D+
|
||||
-$E-
|
||||
-$F-
|
||||
-$G+
|
||||
-$H+
|
||||
-$I+
|
||||
-$J-
|
||||
-$K-
|
||||
-$L+
|
||||
-$M-
|
||||
-$N+
|
||||
-$O+
|
||||
-$P+
|
||||
-$Q-
|
||||
-$R-
|
||||
-$S-
|
||||
-$T-
|
||||
-$U-
|
||||
-$V+
|
||||
-$W-
|
||||
-$X+
|
||||
-$YD
|
||||
-$Z1
|
||||
-cg
|
||||
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
-H+
|
||||
-W+
|
||||
-M
|
||||
-$M16384,1048576
|
||||
-K$00400000
|
||||
-LE"c:\program files\borland\delphi7\Projects\Bpl"
|
||||
-LN"c:\program files\borland\delphi7\Projects\Bpl"
|
||||
-w-UNSAFE_TYPE
|
||||
-w-UNSAFE_CODE
|
||||
-w-UNSAFE_CAST
|
140
SmartPatcher.dof
Normal file
140
SmartPatcher.dof
Normal file
@ -0,0 +1,140 @@
|
||||
[FileVersion]
|
||||
Version=7.0
|
||||
[Compiler]
|
||||
A=8
|
||||
B=0
|
||||
C=1
|
||||
D=1
|
||||
E=0
|
||||
F=0
|
||||
G=1
|
||||
H=1
|
||||
I=1
|
||||
J=0
|
||||
K=0
|
||||
L=1
|
||||
M=0
|
||||
N=1
|
||||
O=1
|
||||
P=1
|
||||
Q=0
|
||||
R=0
|
||||
S=0
|
||||
T=0
|
||||
U=0
|
||||
V=1
|
||||
W=0
|
||||
X=1
|
||||
Y=1
|
||||
Z=1
|
||||
ShowHints=1
|
||||
ShowWarnings=1
|
||||
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||
NamespacePrefix=
|
||||
SymbolDeprecated=1
|
||||
SymbolLibrary=1
|
||||
SymbolPlatform=1
|
||||
UnitLibrary=1
|
||||
UnitPlatform=1
|
||||
UnitDeprecated=1
|
||||
HResultCompat=1
|
||||
HidingMember=1
|
||||
HiddenVirtual=1
|
||||
Garbage=1
|
||||
BoundsError=1
|
||||
ZeroNilCompat=1
|
||||
StringConstTruncated=1
|
||||
ForLoopVarVarPar=1
|
||||
TypedConstVarPar=1
|
||||
AsgToTypedConst=1
|
||||
CaseLabelRange=1
|
||||
ForVariable=1
|
||||
ConstructingAbstract=1
|
||||
ComparisonFalse=1
|
||||
ComparisonTrue=1
|
||||
ComparingSignedUnsigned=1
|
||||
CombiningSignedUnsigned=1
|
||||
UnsupportedConstruct=1
|
||||
FileOpen=1
|
||||
FileOpenUnitSrc=1
|
||||
BadGlobalSymbol=1
|
||||
DuplicateConstructorDestructor=1
|
||||
InvalidDirective=1
|
||||
PackageNoLink=1
|
||||
PackageThreadVar=1
|
||||
ImplicitImport=1
|
||||
HPPEMITIgnored=1
|
||||
NoRetVal=1
|
||||
UseBeforeDef=1
|
||||
ForLoopVarUndef=1
|
||||
UnitNameMismatch=1
|
||||
NoCFGFileFound=1
|
||||
MessageDirective=1
|
||||
ImplicitVariants=1
|
||||
UnicodeToLocale=1
|
||||
LocaleToUnicode=1
|
||||
ImagebaseMultiple=1
|
||||
SuspiciousTypecast=1
|
||||
PrivatePropAccessor=1
|
||||
UnsafeType=0
|
||||
UnsafeCode=0
|
||||
UnsafeCast=0
|
||||
[Linker]
|
||||
MapFile=0
|
||||
OutputObjs=0
|
||||
ConsoleApp=1
|
||||
DebugInfo=0
|
||||
RemoteSymbols=0
|
||||
MinStackSize=16384
|
||||
MaxStackSize=1048576
|
||||
ImageBase=4194304
|
||||
ExeDescription=SmartPatcher for new versions of cracked software.
|
||||
[Directories]
|
||||
OutputDir=
|
||||
UnitOutputDir=
|
||||
PackageDLLOutputDir=
|
||||
PackageDCPOutputDir=
|
||||
SearchPath=
|
||||
Packages=vcl;dclOfficeXP;vcldb;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;dsnapcon;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL
|
||||
Conditionals=
|
||||
DebugSourceDirs=
|
||||
UsePackages=0
|
||||
[Parameters]
|
||||
RunParams=
|
||||
HostApplication=
|
||||
Launcher=
|
||||
UseLauncher=0
|
||||
DebugCWD=
|
||||
[Language]
|
||||
ActiveLang=
|
||||
ProjectLang=
|
||||
RootDir=
|
||||
[Version Info]
|
||||
IncludeVerInfo=1
|
||||
AutoIncBuild=1
|
||||
MajorVer=1
|
||||
MinorVer=0
|
||||
Release=0
|
||||
Build=5
|
||||
Debug=0
|
||||
PreRelease=0
|
||||
Special=1
|
||||
Private=0
|
||||
DLL=0
|
||||
Locale=1033
|
||||
CodePage=1252
|
||||
[Version Info Keys]
|
||||
CompanyName=riddick
|
||||
FileDescription=SmartPatcher for new versions of cracked software.
|
||||
FileVersion=1.0.0.5
|
||||
InternalName=SmartPatcher
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=SmartPatcher.exe
|
||||
ProductName=SmartPatcher
|
||||
ProductVersion=1.0.0.0
|
||||
Comments=SmartPatcher for new versions of already cracked software.
|
||||
SpecialBuild=
|
||||
[HistoryLists\hlUnitAliases]
|
||||
Count=1
|
||||
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
14
SmartPatcher.dpr
Normal file
14
SmartPatcher.dpr
Normal file
@ -0,0 +1,14 @@
|
||||
program SmartPatcher;
|
||||
|
||||
uses
|
||||
Forms,
|
||||
USmartPatcher in 'USmartPatcher.pas' {FPatcher};
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.Title := 'SmartPatcher';
|
||||
Application.CreateForm(TFPatcher, FPatcher);
|
||||
Application.Run;
|
||||
end.
|
43
SmartPatcher.txt
Normal file
43
SmartPatcher.txt
Normal file
@ -0,0 +1,43 @@
|
||||
SmartPatcher by riddick
|
||||
=======================
|
||||
|
||||
P U R P O S E
|
||||
|
||||
Let's say, you have downloaded a cracked version of CoolApp 1.0. You have the
|
||||
original program file CoolApp.exe and a cracked one CoolApp.cracked.exe . But
|
||||
now there's version 1.2 out and you don't have a crack for it. What do you do?
|
||||
|
||||
SmartPatcher is the solution! It analyzes the changes made by the cracker to
|
||||
the v1.0 files and tries to apply the same changes to the new file. This works
|
||||
with *almost any* application if the versions don't differ too much.
|
||||
|
||||
|
||||
|
||||
U S A G E
|
||||
|
||||
Staying with the previously created example, you would select your original
|
||||
CoolApp.exe of version 1.0 as the "Original file", the cracked one as "Modified
|
||||
file" and the new version 1.2 of CoolApp.exe as "New file". Now click on
|
||||
"SmartPatch!" and take a look at the Messagebox. If you see some error lines
|
||||
about not finding the appropriate location, try to check "Extended Search" on
|
||||
your next try. (Restore the backup first.) Extended Search will do some more
|
||||
searching which could take much longer with huge files.
|
||||
|
||||
|
||||
|
||||
L I M I T A T I O N S
|
||||
|
||||
Although it worked in most cases for me, there can be files where it doesn't.
|
||||
Be warned that you use this software on your own risk. If you damage your
|
||||
files, your computer or whatever - don't blame me.
|
||||
|
||||
|
||||
|
||||
C O N T A C T
|
||||
|
||||
If you want to contact me, do so through the forum at www.p800stuff.com. My
|
||||
username there is "riddick".
|
||||
|
||||
|
||||
|
||||
-riddick
|
1469
USmartPatcher.dfm
Normal file
1469
USmartPatcher.dfm
Normal file
File diff suppressed because it is too large
Load Diff
349
USmartPatcher.pas
Normal file
349
USmartPatcher.pas
Normal file
@ -0,0 +1,349 @@
|
||||
unit USmartPatcher;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, SysUtils, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Classes, Graphics, StrUtils;
|
||||
|
||||
type
|
||||
TFPatcher = class(TForm)
|
||||
Label1: TLabel;
|
||||
Label2: TLabel;
|
||||
GroupOrigFileset: TGroupBox;
|
||||
Label3: TLabel;
|
||||
Label4: TLabel;
|
||||
OpenDialog: TOpenDialog;
|
||||
EditOrigFile: TEdit;
|
||||
EditModFile: TEdit;
|
||||
ButBrowseOrig: TButton;
|
||||
ButBrowseMod: TButton;
|
||||
GroupNewFile: TGroupBox;
|
||||
Label5: TLabel;
|
||||
EditNewFile: TEdit;
|
||||
ButtBrowseNew: TButton;
|
||||
ImgLogoRiddickTop: TImage;
|
||||
ButtSmartPatch: TButton;
|
||||
LogBox: TListBox;
|
||||
Label6: TLabel;
|
||||
CheckBackup: TCheckBox;
|
||||
ButtExit: TButton;
|
||||
ImgLogoRiddickLeft: TImage;
|
||||
CheckExtSearch: TCheckBox;
|
||||
procedure ButBrowseOrigClick(Sender: TObject);
|
||||
procedure ButtExitClick(Sender: TObject);
|
||||
procedure ButBrowseModClick(Sender: TObject);
|
||||
procedure ButtBrowseNewClick(Sender: TObject);
|
||||
procedure ButtSmartPatchClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
FPatcher: TFPatcher;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
const
|
||||
PreAftLen: integer = 10;
|
||||
PreAftSrc: integer = $4000;
|
||||
|
||||
type
|
||||
TModRec = record
|
||||
Offset: longint;
|
||||
Length: longint;
|
||||
Orig: AnsiString;
|
||||
New: AnsiString;
|
||||
Pre: AnsiString;
|
||||
Aft: AnsiString;
|
||||
end;
|
||||
TModRecA = array of TModRec;
|
||||
|
||||
var
|
||||
Mods: TModRecA;
|
||||
|
||||
procedure Log(x: string);
|
||||
var i: integer;
|
||||
begin
|
||||
while (FPatcher.LogBox.Count>500) do begin
|
||||
FPatcher.LogBox.Items.Delete(0);
|
||||
end;
|
||||
i := FPatcher.LogBox.Items.Add(x);
|
||||
FPatcher.LogBox.TopIndex := i;
|
||||
end;
|
||||
|
||||
function Dec2Hex(d: longint): string;
|
||||
const hexset: string[16] = '0123456789abcdef';
|
||||
begin
|
||||
Result := '';
|
||||
while (d>=16) do begin
|
||||
Result := hexset[(d MOD 16)+1] + Result;
|
||||
d := d DIV 16;
|
||||
end;
|
||||
Result := hexset[d+1] + Result;
|
||||
if (Length(Result) MOD 2=1) then Result := '0'+Result;
|
||||
end;
|
||||
|
||||
function FindModsInFiles(g1,g2: string): TModRecA;
|
||||
var f1,f2: file of char;
|
||||
Buf1, Buf2: array[1..64] of char;
|
||||
i, i1, i2: integer;
|
||||
o: longint;
|
||||
lastinequal: boolean;
|
||||
resi: longint;
|
||||
Last10, Next10: AnsiString;
|
||||
begin
|
||||
try
|
||||
AssignFile(f1,g1);
|
||||
AssignFile(f2,g2);
|
||||
FileMode := fmOpenRead;
|
||||
Reset(f1);
|
||||
Reset(f2);
|
||||
repeat
|
||||
if (FilePos(f1)<>FilePos(f2)) then begin
|
||||
Log('ERROR while reading! File positions are different. Aborting.');
|
||||
CloseFile(f1);
|
||||
CloseFile(f2);
|
||||
Exit;
|
||||
end;
|
||||
o := FilePos(f1);
|
||||
BlockRead(f1,Buf1,SizeOf(Buf1),i1);
|
||||
BlockRead(f2,Buf2,SizeOf(Buf2),i2);
|
||||
if (i2<>i1) then begin
|
||||
Log('ERROR while reading! Different sized blocks were read. Aborting.');
|
||||
CloseFile(f1);
|
||||
CloseFile(f2);
|
||||
Exit;
|
||||
end;
|
||||
lastinequal := false;
|
||||
for i:=1 to i1 do begin
|
||||
if (Buf1[i]<>Buf2[i]) then begin
|
||||
if (lastinequal) then begin
|
||||
resi := Length(Result)-1;
|
||||
Inc(Result[resi].Length);
|
||||
Result[resi].Orig := Result[resi].Orig + Buf1[i];
|
||||
Result[resi].New := Result[resi].New + Buf2[i];
|
||||
end else begin
|
||||
resi := Length(Result);
|
||||
SetLength(Result, resi+1);
|
||||
Result[resi].Offset := o+i-1;
|
||||
Result[resi].Length := 1;
|
||||
Result[resi].Orig := Buf1[i];
|
||||
Result[resi].New := Buf2[i];
|
||||
Result[resi].Pre := Last10;
|
||||
// Result[resi].Aft := Next10;
|
||||
end;
|
||||
lastinequal := true;
|
||||
end else begin
|
||||
if (lastinequal) then begin
|
||||
Last10 := '';
|
||||
resi := Length(Result)-1;
|
||||
Log('Found '+IntToStr(Result[resi].Length)+' different Byte(s) at Offset 0x'+UpperCase(Dec2Hex(Result[resi].Offset)));
|
||||
end;
|
||||
lastinequal := false;
|
||||
end;
|
||||
if (Length(Last10)<PreAftLen) then Last10 := Last10 + Buf1[i] else Last10 := RightBStr(Last10, PreAftLen - 1) + Buf1[i];
|
||||
end;
|
||||
until (i1=0) OR (i2=0);
|
||||
CloseFile(f1);
|
||||
CloseFile(f2);
|
||||
Log('>>> Found '+IntToStr(Length(Result))+' different areas.');
|
||||
except
|
||||
on e: Exception do Log('Exception: '+e.Message);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ChangeNewFile(g: string; m: TModRecA): boolean;
|
||||
var f: file of char;
|
||||
i,j: integer;
|
||||
o, lo, mo: longint;
|
||||
Last: AnsiString;
|
||||
Buf: char;
|
||||
foundit, missedany: boolean;
|
||||
label NextTurn;
|
||||
begin
|
||||
try
|
||||
missedany := false;
|
||||
AssignFile(f, g);
|
||||
FileMode := fmOpenReadWrite;
|
||||
Reset(f);
|
||||
Last := '';
|
||||
o := Mods[0].Offset - PreAftSrc;
|
||||
lo := 0;
|
||||
if (o<0) then o := 0;
|
||||
Seek(f,o);
|
||||
for i:=0 to Length(Mods)-1 do begin
|
||||
foundit := false;
|
||||
NextTurn:
|
||||
if (FPatcher.CheckExtSearch.Checked) then mo := FileSize(f) else mo := Mods[i].Offset+2*PreAftSrc;
|
||||
while (FilePos(f)<mo) AND (NOT EOF(f)) do begin
|
||||
BlockRead(f,Buf,1);
|
||||
if (RightBStr(Last, Length(Mods[i].Pre)) = Mods[i].Pre) then begin
|
||||
if (Buf = Mods[i].Orig[1]) then begin
|
||||
Seek(f,FilePos(f)-1);
|
||||
Log('Found pos at Offset 0x'+Dec2Hex(FilePos(f))+' - changing from '+Dec2Hex(Ord(Buf))+' to '+Dec2Hex(Ord(Mods[i].New[1])));
|
||||
for j:=1 to Length(Mods[i].New) do begin
|
||||
Read(f,Buf);
|
||||
if (Buf=Mods[i].Orig[j]) then begin
|
||||
foundit := true;
|
||||
Seek(f,FilePos(f)-1);
|
||||
Write(f,Mods[i].New[j]);
|
||||
lo := FilePos(f);
|
||||
end else Log('Bytes different at Offset 0x'+Dec2Hex(FilePos(f)));
|
||||
end;
|
||||
Break;
|
||||
end else begin
|
||||
foundit := false;
|
||||
Log('Found pos, but different original first byte. Searching further...');
|
||||
end;
|
||||
end;
|
||||
if (Length(Last)<PreAftLen) then Last := Last + Buf else Last := RightBStr(Last, PreAftLen-1) + Buf;
|
||||
end;
|
||||
if (NOT foundit) AND (Length(Mods[i].Pre)>2) then begin
|
||||
Mods[i].Pre := RightBStr(Mods[i].Pre,Length(Mods[i].Pre)-1);
|
||||
Log('Pre not found. Dropping one byte... (now '+IntToStr(Length(Mods[i].Pre))+' bytes)');
|
||||
if (lo>0) then o := lo else o := Mods[i].Offset - PreAftSrc;
|
||||
if (o<0) then o:=0;
|
||||
Seek(f,o);
|
||||
goto NextTurn;
|
||||
end else if (NOT foundit) then begin
|
||||
Log('Couldn''t find this mod. Trying next one...');
|
||||
missedany := true;
|
||||
end;
|
||||
end;
|
||||
CloseFile(f);
|
||||
if (NOT missedany) then Result := true else Result := false;
|
||||
except
|
||||
on e: Exception do begin
|
||||
Log('Exception: '+e.Message);
|
||||
Result := falsE;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CheckFileSizes(g1,g2: string): boolean;
|
||||
var f1,f2: file of char;
|
||||
s1,s2: longint;
|
||||
begin
|
||||
try
|
||||
AssignFile(f1,g1);
|
||||
AssignFile(f2,g2);
|
||||
FileMode := fmOpenRead;
|
||||
Reset(f1);
|
||||
Reset(f2);
|
||||
s1 := FileSize(f1);
|
||||
s2 := FileSize(f2);
|
||||
CloseFile(f1);
|
||||
CloseFile(f2);
|
||||
if (s1=s2) then Result := true else Result := false;
|
||||
except
|
||||
on e: Exception do begin
|
||||
Log('Exception: '+e.Message);
|
||||
Result := false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFPatcher.ButBrowseOrigClick(Sender: TObject);
|
||||
begin
|
||||
if (Length(ExtractFilePath(EditOrigFile.Text))>0) then OpenDialog.InitialDir := ExtractFilePath(EditOrigFile.Text);
|
||||
OpenDialog.Title := 'Select original file from old version';
|
||||
if (OpenDialog.Execute) then begin
|
||||
EditOrigFile.Text := OpenDialog.FileName;
|
||||
Log('Original file: '+ExtractFilename(OpenDialog.FileName));
|
||||
end else Log('Aborted OpenDialog. (Original file)');
|
||||
end;
|
||||
|
||||
procedure TFPatcher.ButtExitClick(Sender: TObject);
|
||||
begin
|
||||
Application.Terminate;
|
||||
end;
|
||||
|
||||
procedure TFPatcher.ButBrowseModClick(Sender: TObject);
|
||||
begin
|
||||
if (Length(ExtractFilePath(EditModFile.Text))>0) then OpenDialog.InitialDir := ExtractFilePath(EditModFile.Text);
|
||||
OpenDialog.Title := 'Select modified file from old version';
|
||||
if (OpenDialog.Execute) then begin
|
||||
EditModFile.Text := OpenDialog.FileName;
|
||||
Log('Original modified file: '+ExtractFilename(OpenDialog.FileName));
|
||||
end else Log('Aborted OpenDialog. (Original mod file)');
|
||||
end;
|
||||
|
||||
procedure TFPatcher.ButtBrowseNewClick(Sender: TObject);
|
||||
begin
|
||||
if (Length(ExtractFilePath(EditNewFile.Text))>0) then OpenDialog.InitialDir := ExtractFilePath(EditNewFile.Text);
|
||||
OpenDialog.Title := 'Select file with new version';
|
||||
if (OpenDialog.Execute) then begin
|
||||
EditNewFile.Text := OpenDialog.FileName;
|
||||
Log('New version file: '+ExtractFilename(OpenDialog.FileName));
|
||||
end else Log('Aborted OpenDialog. (New ver file)');
|
||||
end;
|
||||
|
||||
function Backup(f: string): boolean;
|
||||
var t: string;
|
||||
begin
|
||||
t := ChangeFileExt(f,'.bak');
|
||||
Log('Backup to: '+t);
|
||||
if (FileExists(t)) then begin
|
||||
Log('File exists! Let''s hope that this is an old backup of this file. Skipping backup.');
|
||||
Result := true;
|
||||
end else Result := CopyFile(PChar(f),PChar(t),true);
|
||||
end;
|
||||
|
||||
procedure TFPatcher.ButtSmartPatchClick(Sender: TObject);
|
||||
begin
|
||||
if (ExtractFileName(EditOrigFile.Text)='') then begin
|
||||
Log('ERROR! Please select the original file of the OLD version!');
|
||||
Exit;
|
||||
end;
|
||||
if (ExtractFileName(EditModFile.Text)='') then begin
|
||||
Log('ERROR! Please select the modified file of the OLD version!');
|
||||
Exit;
|
||||
end;
|
||||
if (ExtractFileName(EditNewFile.Text)='') then begin
|
||||
Log('ERROR! Please select the original file of the NEW version!');
|
||||
Exit;
|
||||
end;
|
||||
if (EditOrigFile.Text = EditModFile.Text) then begin
|
||||
Log('ERROR! Please select different original files!');
|
||||
Exit;
|
||||
end;
|
||||
if (EditOrigFile.Text = EditNewFile.Text) OR (EditModFile.Text = EditNewFile.Text) then begin
|
||||
Log('ERROR! New version file can''t be the same as old version file!');
|
||||
Exit;
|
||||
end;
|
||||
if (NOT CheckFileSizes(EditOrigFile.Text, EditModFile.Text)) then begin
|
||||
Log('ERROR! File sizes of original files differ!');
|
||||
Exit;
|
||||
end;
|
||||
Log('No errors until here. Start modification parsing...');
|
||||
Mods := FindModsInFiles(EditOrigFile.Text, EditModFile.Text);
|
||||
Log('Done finding differences in original fileset.');
|
||||
if (CheckBackup.Checked) then begin
|
||||
if (Backup(EditNewFile.Text)) then begin
|
||||
Log('Backup done.');
|
||||
end else begin
|
||||
Log('ERROR! Could not backup file. Aborting...');
|
||||
Exit;
|
||||
end;
|
||||
end else Log('Skipping backup of new file.');
|
||||
if (ChangeNewFile(EditNewFile.Text, Mods)) then begin
|
||||
Log('Done making changes to new file. File should work now!');
|
||||
end else begin
|
||||
Log('ERROR! Could not apply all changes to new file.');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFPatcher.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Log('Welcome to SmartPatcher by riddick');
|
||||
Log('');
|
||||
Log('NOTE: You can damage your files - use this app wisely!');
|
||||
Log(DupeString('-',140));
|
||||
end;
|
||||
|
||||
end.
|
Reference in New Issue
Block a user