Das Patchen einer Datei ist eigentlich nichts anderes als die Datei so zu verändern, sodass sie im Nachhinein weiter funktionstüchtig ist. Es können Strings entfernt oder ersetzt werden.
Um einen String aus einer Datei zu entfernen oder zu ersetzen, muss der String erstmal gesucht werden.
Mit dieser Funktion lassen sich Dateien patchen, doch sie ist sensibel. Bei EXE-Dateien sollte man den Inhalt einigermaßen kennen, damit die EXE danach auch weiter funktioniert.
uses Math
type
TReplaceFlags = set of (rfReplaceAll, rfIgnoreCase);
//
function PatchFile(const AFilename: string; AOldText, ANewText: string;
Flags: TReplaceFlags): boolean;
const
cMaxBuffer = 128*1024;
var
f: TFileStream;
i: integer;
Buf: array[0..cMaxBuffer-1] of Char;
OldStr: string;
StrBuf: string;
begin
result := false;
if Length(AOldText) <> Length(ANewText) then exit;
ZeroMemory(@Buf, cMaxBuffer);
if rfIgnoreCase in Flags then
OldStr := AnsiLowerCase(AOldText)
else
OldStr := AOldText;
f := TFileStream.Create(AFilename, fmOpenReadWrite or fmShareDenyWrite);
try
while f.Read(Buf, cMaxBuffer) > Length(AOldText) do
begin
StrBuf := Buf;
f.Seek(-Length(AOldText), soFromCurrent);
if rfIgnoreCase in Flags then
StrBuf := AnsiLowerCase(StrBuf);
repeat
i := Pos(OldStr, StrBuf);
if i > 0 then
begin
result := true;
Delete(StrBuf, i, length(AOldText));
Insert(ANewText, StrBuf, i);
if not (rfReplaceAll in Flags) then
break;
end;
until i = 0;
f.Position := Max(f.Position + Length(AOldText) - cMaxBuffer, 0);
f.Write(Pointer(StrBuf)^, Length(StrBuf));
if result and not (rfReplaceAll in Flags) then exit;
end;
finally
f.Free;
end;
end;
Beispiel :
procedure TForm1.Button1Click(Sender: TObject);
begin
if PatchFile('c:\temp.txt', // Pfad der Datei
'AltText', // Der String der gesucht werden muss
'NeuText', // Der String der den alten ersetzten soll (Patchen)
[rfIgnoreCase, rfReplaceAll]) then
ShowMessage('Found and Patch done')
else
ShowMessage('Not found Patch missmatch.');
end;
Keine Kommentare:
Kommentar veröffentlichen