VPatch 2.1:
* Added argument checking and error handling to GenPat. Now returns exit codes as well to indicate success/failure (and the reason for failure). Only GenPat has changed in this version compared to 2.0 final. * Bug Fix: GenPat no longer gives an Access Violation when attempting to patch a file smaller than 64 bytes into a file larger than 64 bytes. git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3318 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
14f2e625e4
commit
b7c7a31b3e
5 changed files with 314 additions and 108 deletions
Binary file not shown.
|
@ -98,87 +98,161 @@ a:hover
|
||||||
<body>
|
<body>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<table width="750" class="maintable" cellspacing="0" cellpadding="0">
|
<table width="750" class="maintable" cellspacing="0" cellpadding="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<h1>VPatch 2</h1>
|
<h1>VPatch 2</h1>
|
||||||
<div>
|
<div>
|
||||||
<h2>Introduction</h2>
|
<h2>Introduction</h2>
|
||||||
<p>VPatch allows to create a patch file to update previous versions of your software. The GenPat
|
<p>VPatch allows to create a patch file to update previous versions
|
||||||
utitily generates the patch file. The plug-in can use the patch to update a file. Using a patch,
|
of your software. The GenPat utitily generates the patch file. The
|
||||||
you can reduce the download size of your updates, because only the differences between the files
|
plug-in can use the patch to update a file. Using a patch, you can
|
||||||
are included in the patch file.</p>
|
reduce the download size of your updates, because only the differences
|
||||||
<h2>How to use</h2>
|
between the files are included in the patch file.</p>
|
||||||
<h3>Generate the patch file</h3>
|
<h2>How to use</h2>
|
||||||
<p>Make sure you have the source file (original version) and the target file (version to update
|
<h3>Generate the patch file</h3>
|
||||||
to). For example, DATA.DTA (currently on user system) and DATA_20.DTA (version 2.0 of this data
|
<p>Make sure you have the source file (original version) and the target
|
||||||
file). Now call the command line tool GenPat.exe:</p>
|
file (version to update to). For example, DATA.DTA (currently on user
|
||||||
<pre>
|
system) and DATA_20.DTA (version 2.0 of this data file). Now call
|
||||||
|
the command line tool GenPat.exe:</p>
|
||||||
|
<pre>
|
||||||
GENPAT data.dta data_20.dta data.pat
|
GENPAT data.dta data_20.dta data.pat
|
||||||
</pre>
|
</pre>
|
||||||
<p>Now, the patch will be generated, this will take some time.</p>
|
<p>Now, the patch will be generated, this will take some time.</p>
|
||||||
<p>Using the /B=(BlockSize) parameter of the GenPat utility (put it after the filenames), you can
|
<p>Using the /B=(BlockSize) parameter of the GenPat utility (put it
|
||||||
use a different block size. A smaller block size may result in a smaller patch, but the generation
|
after the filenames), you can use a different block size. A smaller
|
||||||
will take more time (the default blocksize is 64).</p>
|
block size may result in a smaller patch, but the generation will
|
||||||
<h3>Update the file during installation</h3>
|
take more time (the default blocksize is 64).</p>
|
||||||
<p>Use the VPatch plug-in to update a file using a patch file:</p>
|
<h3>Update the file during installation</h3>
|
||||||
<pre>
|
<p>Use the VPatch plug-in to update a file using a patch file:</p>
|
||||||
|
<pre>
|
||||||
vpatch::vpatchfile "pathfile.pat" "source.file" "new.file"
|
vpatch::vpatchfile "pathfile.pat" "source.file" "new.file"
|
||||||
</pre>
|
</pre>
|
||||||
<p>The result of the patch operating will be added to the stack and can be one of the following
|
<p>The result of the patch operating will be added to the stack and
|
||||||
texts:</p>
|
can be one of the following texts:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>OK</li>
|
<li>OK</li>
|
||||||
<li>OK, new version already installed</li>
|
<li>OK, new version already installed</li>
|
||||||
<li>An error occured while patching</li>
|
<li>An error occured while patching</li>
|
||||||
<li>Patch data is invalid or corrupt</li>
|
<li>Patch data is invalid or corrupt</li>
|
||||||
<li>No suitable patches were found</li>
|
<li>No suitable patches were found</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Check <a href="example.nsi">example.nsi</a> for an example.</p>
|
<p>Check <a href="example.nsi">example.nsi</a> for an example.</p>
|
||||||
<h3>Multiple patches in one file</h3>
|
<h3>Multiple patches in one file</h3>
|
||||||
<p>GenPat appends a patch to the file you specified. If there is already a patch for the same
|
<p>GenPat appends a patch to the file you specified. If there is already
|
||||||
orginal file in the patch file, the patch will be replaced. For example, if you want to be able to
|
a patch for the same orginal file in the patch file, the patch will
|
||||||
upgrade version 1 and 2 to version 3, you can put a 1 > 3 and 2 > 3 patch in one file.</p>
|
be replaced. For example, if you want to be able to upgrade version
|
||||||
<p>You can also put patches for different files in one patch file, for example, a patch from file A
|
1 and 2 to version 3, you can put a 1 > 3 and 2 > 3 patch in
|
||||||
version 1 to file A version 2 and a patch from file B version 1 to file B version 2. Just call the
|
one file.</p>
|
||||||
plug-in multiple times with the same patch file. It will automatically select the right patch
|
<p>You can also put patches for different files in one patch file, for
|
||||||
(based on the file CRC).</p>
|
example, a patch from file A version 1 to file A version 2 and a patch
|
||||||
<h2>Source code</h2>
|
from file B version 1 to file B version 2. Just call the plug-in multiple
|
||||||
<h3>NSIS plug-in (C++)</h3>
|
times with the same patch file. It will automatically select the right
|
||||||
<p>The source of the NSIS plug-in that applies patches can be found in the Source\Plugin
|
patch (based on the file CRC).</p>
|
||||||
folder.</p>
|
<h3>GenPat exit codes</h3>
|
||||||
<h3>Patch Generator (Delphi)</h3>
|
<p>In version 2.1 support was added for exit codes (known as error levels
|
||||||
<p>The most interesting part of VPatch, the actual patch generation algoritm, can be found in
|
in the DOS period) to GenPat. GenPat will return an exit code based
|
||||||
Source\GenPat\PatchGenerator.pas. The header of that file contains a brief explanation of the
|
on succes of the patch generation. Here is a list of the possible
|
||||||
algoritm as well.</p>
|
exit codes:</p>
|
||||||
<h3>User interface (Delphi)</h3>
|
<table width="547" border="0" cellspacing="0" cellpadding="0">
|
||||||
<p>A user interface is included as well, which you will have to build yourself because the GUI
|
<tr>
|
||||||
executable was too large to include. Besides Borland Delphi 6 or higher (you can use the freely
|
<td><b>Exit code</b></td>
|
||||||
available Personal edition), you will also need to install the <a href=
|
<td><b>Description</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>0</td>
|
||||||
|
<td>Success</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>1</td>
|
||||||
|
<td>Arguments missing</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>2</td>
|
||||||
|
<td>Source file not found</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>3</td>
|
||||||
|
<td>Target file not found</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>4</td>
|
||||||
|
<td>Unknown error while reading existing patch file</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>5</td>
|
||||||
|
<td>Unknown error while generating patch</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>6</td>
|
||||||
|
<td>Unknown error while writing patch file to disk</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>10</td>
|
||||||
|
<td>CRC of source and target file are equal</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>11</td>
|
||||||
|
<td>Not enough memory for source file</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>12</td>
|
||||||
|
<td>Not enough memory for target file</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p>These exit codes can be useful when you generate patch files through
|
||||||
|
a script.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Source code</h2>
|
||||||
|
<h3>NSIS plug-in (C++)</h3>
|
||||||
|
<p>The source of the NSIS plug-in that applies patches can be found
|
||||||
|
in the Source\Plugin folder.</p>
|
||||||
|
<h3>Patch Generator (Delphi)</h3>
|
||||||
|
<p>The most interesting part of VPatch, the actual patch generation
|
||||||
|
algoritm, can be found in Source\GenPat\PatchGenerator.pas. The header
|
||||||
|
of that file contains a brief explanation of the algoritm as well.</p>
|
||||||
|
<h3>User interface (Delphi)</h3>
|
||||||
|
<p>A user interface is included as well, which you will have to build
|
||||||
|
yourself because the GUI executable was too large to include. Besides
|
||||||
|
Borland Delphi 6 or higher (you can use the freely available Personal
|
||||||
|
edition), you will also need to install the <a href=
|
||||||
"http://www.delphi-gems.com">VirtualTreeView</a> component by Mike Lischke.</p>
|
"http://www.delphi-gems.com">VirtualTreeView</a> component by Mike Lischke.</p>
|
||||||
<h2>Version history</h2>
|
<h2>Version history</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>2.0 final
|
<li>2.1
|
||||||
<ul>
|
<ul>
|
||||||
<li>Cleaned up source code for the patch generator, which is now included (this code is written in
|
<li>Added argument checking and error handling to GenPat. Now
|
||||||
Borland Delphi 6 and compiles with the freely available Personal edition).</li>
|
returns exit codes as well to indicate success/failure (and
|
||||||
</ul>
|
the reason for failure). Only GenPat has changed in this version
|
||||||
</li>
|
compared to 2.0 final.</li>
|
||||||
<li>2.0 beta 2
|
<li>Bug Fix: GenPat no longer gives an Access Violation when attempting
|
||||||
<ul>
|
to patch a file smaller than 64 bytes into a file larger than
|
||||||
<li>All new algorithm used in the patch generator: much faster (up to 90%) while using smaller
|
64 bytes.</li>
|
||||||
block sizes (higher compression)</li>
|
</ul>
|
||||||
<li>Created a NSIS 2 plugin</li>
|
</li>
|
||||||
<li>Works with small files</li>
|
<li>2.0 final
|
||||||
<li>Replaces existing patch in file if original file CRC is identical</li>
|
<ul>
|
||||||
</ul>
|
<li>Cleaned up source code for the patch generator, which is now
|
||||||
</li>
|
included (this code is written in Borland Delphi 6 and compiles
|
||||||
</ul>
|
with the freely available Personal edition).</li>
|
||||||
<h2>Credits</h2>
|
</ul>
|
||||||
<p>Written by Koen van de Sande<br />
|
</li>
|
||||||
C plug-in by Edgewize<br />
|
<li>2.0 beta 2
|
||||||
New documentation and example by Joost Verburg</p>
|
<ul>
|
||||||
<h2>License</h2>
|
<li>All new algorithm used in the patch generator: much faster
|
||||||
<pre>
|
(up to 90%) while using smaller block sizes (higher compression)</li>
|
||||||
|
<li>Created a NSIS 2 plugin</li>
|
||||||
|
<li>Works with small files</li>
|
||||||
|
<li>Replaces existing patch in file if original file CRC is identical</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Credits</h2>
|
||||||
|
<p>Written by Koen van de Sande<br />
|
||||||
|
C plug-in by Edgewize<br />
|
||||||
|
New documentation and example by Joost Verburg</p>
|
||||||
|
<h2>License</h2>
|
||||||
|
<pre>
|
||||||
Copyright (C) 2001-2003 Koen van de Sande
|
Copyright (C) 2001-2003 Koen van de Sande
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
|
@ -196,8 +270,9 @@ it freely, subject to the following restrictions:
|
||||||
2. Altered versions must be plainly marked as such,
|
2. Altered versions must be plainly marked as such,
|
||||||
and must not be misrepresented as being the original software.
|
and must not be misrepresented as being the original software.
|
||||||
3. This notice may not be removed or altered from any distribution.
|
3. This notice may not be removed or altered from any distribution.
|
||||||
</pre></div>
|
</pre>
|
||||||
</td>
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,6 +11,9 @@ program GenPat2;
|
||||||
|
|
||||||
What's new
|
What's new
|
||||||
----------
|
----------
|
||||||
|
2.1 20031219 Koen Added error checking, handling, shouldn't
|
||||||
|
crash when invalid arguments, returns
|
||||||
|
exit codes now.
|
||||||
2.0 20030811 Koen Initial documentation
|
2.0 20030811 Koen Initial documentation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,18 +41,20 @@ type
|
||||||
var
|
var
|
||||||
Config: TextFile;
|
Config: TextFile;
|
||||||
T1,T2: TDateTime;
|
T1,T2: TDateTime;
|
||||||
d: Integer;
|
d, i: Integer;
|
||||||
S,Key: String;
|
S,Key: String;
|
||||||
ShowDebug: Boolean;
|
SourceFile, TargetFile, PatchFile: String;
|
||||||
|
ShowDebug, ShowHelp: Boolean;
|
||||||
PG: TPatchGenerator;
|
PG: TPatchGenerator;
|
||||||
EV: TEventHandler;
|
EV: TEventHandler;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
EV:=TEventHandler.Create;
|
EV:=TEventHandler.Create;
|
||||||
PG:=TPatchGenerator.Create;
|
PG:=TPatchGenerator.Create;
|
||||||
PG.StartBlockSize:=64;
|
PG.StartBlockSize:=64;
|
||||||
|
|
||||||
WriteLn('GenPat v2.0 final');
|
WriteLn('GenPat v2.1');
|
||||||
WriteLn('=================');
|
WriteLn('===========');
|
||||||
WriteLn;
|
WriteLn;
|
||||||
WriteLn('(c) 2001-2003 Van de Sande Productions');
|
WriteLn('(c) 2001-2003 Van de Sande Productions');
|
||||||
WriteLn('Website: http://www.tibed.net/vpatch');
|
WriteLn('Website: http://www.tibed.net/vpatch');
|
||||||
|
@ -75,13 +80,35 @@ begin
|
||||||
CloseFile(Config);
|
CloseFile(Config);
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
i:=0;
|
||||||
for d:=1 to ParamCount do begin
|
for d:=1 to ParamCount do begin
|
||||||
if CompareStr(LowerCase(Copy(ParamStr(d),1,3)),'/b=')=0 then begin
|
if CompareStr(LowerCase(Copy(ParamStr(d),1,3)),'/b=')=0 then begin
|
||||||
PG.StartBlockSize:=StrToInt(Copy(ParamStr(d),4,10));
|
PG.StartBlockSize:=StrToInt(Copy(ParamStr(d),4,10));
|
||||||
|
end else begin
|
||||||
|
// not a parameter?
|
||||||
|
if not (ParamStr(d)[1] = '/') then begin
|
||||||
|
if i = 2 then begin
|
||||||
|
PatchFile:=ParamStr(d);
|
||||||
|
Inc(i);
|
||||||
|
end;
|
||||||
|
if i = 1 then begin
|
||||||
|
TargetFile:=ParamStr(d);
|
||||||
|
Inc(i);
|
||||||
|
end;
|
||||||
|
if i = 0 then begin
|
||||||
|
SourceFile:=ParamStr(d);
|
||||||
|
Inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (CompareStr(ParamStr(1),'')=0) or (CompareStr(ParamStr(2),'')=0) or (CompareStr(ParamStr(3),'')=0) then begin
|
ShowHelp:=False;
|
||||||
|
if(CompareStr(PatchFile,'')=0) then ShowHelp:=True;
|
||||||
|
if SourceFile = '' then ShowHelp:=True;
|
||||||
|
if TargetFile = '' then ShowHelp:=True;
|
||||||
|
|
||||||
|
if ShowHelp then begin
|
||||||
WriteLn('This program will take (sourcefile) as input and create a (patchfile).');
|
WriteLn('This program will take (sourcefile) as input and create a (patchfile).');
|
||||||
WriteLn('With this patchfile, you can convert a (sourcefile) into (targetfile).');
|
WriteLn('With this patchfile, you can convert a (sourcefile) into (targetfile).');
|
||||||
WriteLn;
|
WriteLn;
|
||||||
|
@ -90,36 +117,110 @@ begin
|
||||||
WriteLn;
|
WriteLn;
|
||||||
WriteLn('Command line options (you do not need them):');
|
WriteLn('Command line options (you do not need them):');
|
||||||
WriteLn('/B=(BlockSize) Set blocksize (def=64), multiple of 2');
|
WriteLn('/B=(BlockSize) Set blocksize (def=64), multiple of 2');
|
||||||
WriteLn('/WAIT Wait for a keypress after program complete');
|
WriteLn('/NOEQUALERROR Exit code becomes 0 instead of 10 when');
|
||||||
|
WriteLn(' two files with equal CRC are encountered');
|
||||||
|
WriteLn(' (patch file will remain unchanged)');
|
||||||
WriteLn('/DEBUG Show runtime debug information');
|
WriteLn('/DEBUG Show runtime debug information');
|
||||||
WriteLn('Note: all these parameters must be *after* the filenames!');
|
|
||||||
WriteLn;
|
WriteLn;
|
||||||
Write('Press a enter to exit ');
|
WriteLn('Note: filenames should never start with / character!');
|
||||||
ReadLn(S);
|
WriteLn;
|
||||||
|
WriteLn('Possible exit codes:');
|
||||||
|
WriteLn(' 0 Success');
|
||||||
|
WriteLn(' 1 Arguments missing');
|
||||||
|
WriteLn(' 2 Source file not found');
|
||||||
|
WriteLn(' 3 Target file not found');
|
||||||
|
WriteLn(' 4 Unknown error while reading existing patch file');
|
||||||
|
WriteLn(' 5 Unknown error while generating patch');
|
||||||
|
WriteLn(' 6 Unknown error while writing patch file to disk');
|
||||||
|
WriteLn(' 10 CRC of source and target file are equal (impossible with /NOEQUALERROR)');
|
||||||
|
WriteLn(' 11 Not enough memory for source file');
|
||||||
|
WriteLn(' 12 Not enough memory for target file');
|
||||||
|
PG.Free;
|
||||||
|
ExitCode:=1;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FileExists(ParamStr(3)) then begin
|
// stop if file error, result shown above
|
||||||
WriteLn('Using existing file to include patches in: '+ParamStr(3));
|
if not FileExists(SourceFile) then begin
|
||||||
PG.LoadFromFile(ParamStr(3));
|
WriteLn('Error: Source file not found');
|
||||||
|
PG.Free;
|
||||||
|
ExitCode:=2;
|
||||||
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
if not FileExists(TargetFile) then begin
|
||||||
|
WriteLn('Error: Target file not found');
|
||||||
|
PG.Free;
|
||||||
|
ExitCode:=3;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if FileExists(PatchFile) then begin
|
||||||
|
WriteLn('Using existing file to include patches in: '+PatchFile);
|
||||||
|
try
|
||||||
|
PG.LoadFromFile(PatchFile);
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
WriteLn('Error: Reading existing patch file failed');
|
||||||
|
WriteLn('Error message: ', E.ClassName, ': ', E.Message);
|
||||||
|
PG.Free;
|
||||||
|
ExitCode:=4;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
WriteLn('Source (original) file: ', SourceFile);
|
||||||
|
WriteLn('Target (newer) file: ', TargetFile);
|
||||||
|
|
||||||
T1:=Now;
|
T1:=Now;
|
||||||
WriteLn('Patch body size: '+IntToStr(PG.CreatePatch(ParamStr(1),ParamStr(2))));
|
|
||||||
PG.WriteToFile(ParamStr(3));
|
|
||||||
|
|
||||||
T2:=Now;
|
// create patch file, with error handling
|
||||||
Write('GenPat.exe finished execution in: ');
|
try
|
||||||
WriteLn(FloatToStr((T2-T1)*24*60*60),'s');
|
i:=PG.CreatePatch(SourceFile,TargetFile);
|
||||||
WriteLn;
|
except
|
||||||
{$IFNDEF AUTOWAIT}
|
on E: Exception do begin
|
||||||
if FindCmdLineSwitch('wait',['/'],True) then begin
|
WriteLn('Error: Generating patch failed');
|
||||||
{$ENDIF}
|
WriteLn('Error message: ', E.ClassName, ': ', E.Message);
|
||||||
WriteLn;
|
PG.Free;
|
||||||
WriteLn('Press a key');
|
ExitCode:=5;
|
||||||
ReadLn(S);
|
Exit;
|
||||||
{$IFNDEF AUTOWAIT}
|
end;
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
|
||||||
|
if(i < 0) then begin
|
||||||
|
if(i = -1) then begin
|
||||||
|
if not FindCmdLineSwitch('noequalerror',['/'],True) then
|
||||||
|
WriteLn('Error: CRC of source and target file are equal');
|
||||||
|
end;
|
||||||
|
if(i = -2) then WriteLn('Error: Not enough memory for source file');
|
||||||
|
if(i = -3) then WriteLn('Error: Not enough memory for target file');
|
||||||
|
ExitCode:=9 - i;
|
||||||
|
|
||||||
|
if(i = -1) and (FindCmdLineSwitch('noequalerror',['/'],True)) then begin
|
||||||
|
WriteLn('Equal CRCs ignored (no patch will be written and exit code is 0)');
|
||||||
|
ExitCode:=0;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
WriteLn('Patch body size: '+IntToStr(i));
|
||||||
|
try
|
||||||
|
PG.WriteToFile(PatchFile);
|
||||||
|
except
|
||||||
|
on E: Exception do begin
|
||||||
|
WriteLn('Error: Writing patch to file ' + PatchFile + ' failed');
|
||||||
|
WriteLn('Error message: ', E.ClassName, ': ', E.Message);
|
||||||
|
PG.Free;
|
||||||
|
ExitCode:=6;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
T2:=Now;
|
||||||
|
Write('Time taken for generation: ');
|
||||||
|
WriteLn(FloatToStr((T2-T1)*24*60*60),'s');
|
||||||
|
WriteLn;
|
||||||
|
|
||||||
|
ExitCode:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
PG.Free;
|
PG.Free;
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -32,6 +32,8 @@ unit PatchGenerator;
|
||||||
|
|
||||||
What's new
|
What's new
|
||||||
----------
|
----------
|
||||||
|
2.1 20031219 Koen Added error checking to CreatePatch, returns
|
||||||
|
negative numbers when there are errors.
|
||||||
2.0 20030811 Koen Initial documentation
|
2.0 20030811 Koen Initial documentation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,8 +143,8 @@ var
|
||||||
retTO: Integer;
|
retTO: Integer;
|
||||||
noN: Integer;
|
noN: Integer;
|
||||||
begin
|
begin
|
||||||
fsSource:=TFileStream.Create(SourceFileName,fmOpenRead);
|
fsSource:=TFileStream.Create(SourceFileName,fmOpenRead+fmShareDenyNone);
|
||||||
fsTarget:=TFileStream.Create(TargetFileName,fmOpenRead);
|
fsTarget:=TFileStream.Create(TargetFileName,fmOpenRead+fmShareDenyNone);
|
||||||
fm:=TMemoryStream.Create;
|
fm:=TMemoryStream.Create;
|
||||||
|
|
||||||
SetLength(PRay,INIT_BLOCK_COUNT);
|
SetLength(PRay,INIT_BLOCK_COUNT);
|
||||||
|
@ -150,7 +152,14 @@ begin
|
||||||
|
|
||||||
//Load those files into memory!
|
//Load those files into memory!
|
||||||
SourceSize:=fsSource.Size;
|
SourceSize:=fsSource.Size;
|
||||||
GetMem(Source,SourceSize);
|
try
|
||||||
|
GetMem(Source,SourceSize);
|
||||||
|
except
|
||||||
|
on EOutOfMemory do begin
|
||||||
|
Result:=-2; // not enough memory for source file
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
fm.CopyFrom(fsSource,SourceSize);
|
fm.CopyFrom(fsSource,SourceSize);
|
||||||
Move(fm.Memory^,Source^,SourceSize);
|
Move(fm.Memory^,Source^,SourceSize);
|
||||||
SourceCRC:=FileCRC(fsSource);
|
SourceCRC:=FileCRC(fsSource);
|
||||||
|
@ -158,13 +167,28 @@ begin
|
||||||
|
|
||||||
fm.Clear;
|
fm.Clear;
|
||||||
TargetSize:=fsTarget.Size;
|
TargetSize:=fsTarget.Size;
|
||||||
GetMem(Target,TargetSize);
|
try
|
||||||
|
GetMem(Target,TargetSize);
|
||||||
|
except
|
||||||
|
on EOutOfMemory do begin
|
||||||
|
FreeMem(Source,SourceSize);
|
||||||
|
Result:=-3; // not enough memory for target file
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
fm.CopyFrom(fsTarget,TargetSize);
|
fm.CopyFrom(fsTarget,TargetSize);
|
||||||
Move(fm.Memory^,Target^,TargetSize);
|
Move(fm.Memory^,Target^,TargetSize);
|
||||||
TargetCRC:=FileCRC(fsTarget);
|
TargetCRC:=FileCRC(fsTarget);
|
||||||
fsTarget.Free;
|
fsTarget.Free;
|
||||||
fm.Free;
|
fm.Free;
|
||||||
|
|
||||||
|
if(SourceCRC = TargetCRC) then begin
|
||||||
|
FreeMem(Source,SourceSize);
|
||||||
|
FreeMem(Target,TargetSize);
|
||||||
|
Result:=-1;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
PRay[0].TargetOffset:=0;
|
PRay[0].TargetOffset:=0;
|
||||||
PRay[0].SourceOffset:=0;
|
PRay[0].SourceOffset:=0;
|
||||||
PRay[0].Size:=0;
|
PRay[0].Size:=0;
|
||||||
|
|
|
@ -15,6 +15,8 @@ unit TreeCode;
|
||||||
|
|
||||||
What's new
|
What's new
|
||||||
----------
|
----------
|
||||||
|
2.1 20031219 Koen Fixed bug in TreeFind: when tree was a nil
|
||||||
|
pointer, now returns instead of AVing
|
||||||
2.0 20030811 Koen Initial documentation
|
2.0 20030811 Koen Initial documentation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +181,10 @@ var
|
||||||
lo,mid,hi,m: Integer;
|
lo,mid,hi,m: Integer;
|
||||||
tmp: Cardinal;
|
tmp: Cardinal;
|
||||||
begin
|
begin
|
||||||
|
if not Assigned(ABlockTree) then begin
|
||||||
|
FoundCount:=0; Result:=nil;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
lo:=0;
|
lo:=0;
|
||||||
hi:=ABlockTreeNodeCount-1;
|
hi:=ABlockTreeNodeCount-1;
|
||||||
while true do begin
|
while true do begin
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue