Category : Pascal Source Code
Archive   : TP5PATCH.ZIP
Filename : TP5PATCH.PAS

 
Output of file : TP5PATCH.PAS contained in archive : TP5PATCH.ZIP
{
TP5Patch Version 1.0 3/16/89
by Richard S. Sadowsky
donated to the public domain with no restrictions on use
}

{$S-,R-,I-,V-}

program TP5Patch;

{
This program alters the File Mode byte associated with the opening of
Overlay files and text files opened for reading (with Reset). For some
reason, Turbo Pascal 5 ignores the global FileMode variable when opening
overlay and text files for reading. The program does not correct this
oversight, but does allow you to customize the Mode byte which is used to
open these files. If you look at the assembly snippets extracted from the
Overlay.TPU and System.TPU files, you'll note the problem (and see the
solution). The problem is that the file mode associated with these files is
hardcoded in the statement

MOV AX,3D00

Luckily, this also means that solving the problem is as simple as replacing
the 00 in AL with a more appropriate value. By default, this program will
change the low byte to 40h (deny-none). This should result in these files
being shareable over a network without any bad side effects when running
single user. It is not appropriate here to enter a lengthy discussion of
other possible modes. Suffice to say that 40h should solve the main
problem--the inability to share Overlay and text files by more than one
program over a LAN.

To explicitly set the file mode to a value other the default of 40h, use the
command line option -mxx, where xx is the hex value of the new mode. The mode
is always interpreted as a hex number, so a leading '$' or trailing 'h' is
not necessary (or permitted). The option -? shows a help message. Specifying
a file name on the command line will instruct TP5Patch to patch the
appropriate bytes in an already compiled TP5 EXE file.

Example command lines:

TP5Patch
Will look for SYSTEM.TPU, OVERLAY.TPU, and TURBO.TPL. It will patch those
found with the default file mode of 40h.

TP5Patch -m42
Will look for SYSTEM.TPU, OVERLAY.TPU, and TURBO.TPL. It will patch those
found with the specified file mode of 42h.

TP5Patch NETDEMO.EXE -m42
Will patch the TP5 program NETDEMO.EXE with the specified file mode of 42h.

This program DOES NOT MAKE A BACKUP of files before patching them. Please do
so before running this program.


Thee patching process boils down to searching for the following pieces of
code and patching the AL argument of the DOS function 3Dh call with the new
file mode.

For overlay file mode look for the following code:
16 PUSH SS
1F POP DS
B8003D MOV AX,3D00
CD21 INT 21
C3 RET

For text file mode look for the following code:
B8003D MOV AX,3D00
817D02B1D7 CMP WORD PTR [DI+02],D7B1
740D JZ 1EF0
B002 MOV AL,02
}
const
OverlayMatchPattern : Array[1..8] of Byte =
($16,$1F,$B8,$00,$3D,$CD,$21,$C3);

SystemMatchPattern : Array[1..14] of Byte =
($B8,$00,$3D,$81,$7D,$02,$B1,$D7,
$74,$0D,$B0,$02,$FF,$05);
NewMode : Byte = $40;
JustReport : Boolean = FALSE;
PatchingExe : Boolean = FALSE;

BufferSize = $FF00;

OverlayUnit = 'OVERLAY.TPU';
SystemUnit = 'SYSTEM.TPU';
TurboTPL = 'TURBO.TPL';

type
BufferType = Array[1..BufferSize] of Byte;

var
Posit,Temp,Code,OvrFileSize : Word;
F : File;
Buffer : ^BufferType;
FileToPatch : String;

function Search(var BufToSearch; BufSize : Word;
var BufToFind; FindSize : Word) : Word;
{-A quick and dirty memory search routine}
const
MaxWord = $FFFF;

type
SearchBuffer = Array[1..MaxWord] of Byte;

var
I,II : Word;
Buf : SearchBuffer absolute BufToSearch;
Find : SearchBuffer absolute BufToFind;
Found,StillMatches : Boolean;
begin
Search := 0;
if (BufSize = 0) or (FindSize = 0) or (FindSize > BufSize) then
Exit;
I := 1;
Found := FALSE;
while (not Found) and (I <= (BufSize-FindSize+1)) do begin
if Buf[I] = Find[1] then begin
II := 1;
StillMatches := TRUE;
while (II < FindSize) and StillMatches do begin
if Buf[I+II] <> Find[Succ(II)] then
StillMatches := FALSE;
Inc(II);
end;
if (II = FindSize) and StillMatches then
Found := TRUE;
end;
if not Found then
Inc(I);
end;
if Found then
Search := I;
end;

procedure ShowHelp;

begin
WriteLn('TP5Patch [-?] [-m00] [filename.exe]'^M^J);
WriteLn(' -? displays this help message');
WriteLn(' -m sets file mode, may be specified in hex (default is 40h)');
WriteLn(' filename.exe refers to a Turbo Pascal EXE file to patch directly');

Halt;
end;

procedure GetOptions;

var
I : Byte;
Opt : String;
begin
for I := 1 to ParamCount do begin
Opt := ParamStr(I);
if Opt[1] in ['-','/'] then
case Opt[2] of
'M' : begin end;
'?','H' : ShowHelp;
else begin
WriteLn('Invalid option ',Opt);
end;
end
else begin
FileToPatch := Opt;
PatchingEXE := TRUE;
end;
end;
end;

procedure PatchMode(FName : String; var MatchPattern;
MatchSize,OffsetInMatch : Word);


var
F : File;
Posit,FSize : Word;

begin
Assign(F,FName);
Reset(F,1);
if IOResult <> 0 then begin
WriteLn(FName,' not found');
Exit;
end;

BlockRead(F,Buffer^,SizeOf(BufferType),FSize);
if IOResult <> 0 then begin
WriteLn('Error reading ',FName);
Close(F);
if IOResult <> 0 then ;
Exit;
end;
WriteLn(FSize,' bytes read from ',FName);
Posit := Search(Buffer^,FSize,MatchPattern,MatchSize);
if Posit = 0 then begin
WriteLn('Patch point not found');
Close(F);
if IOResult <> 0 then ;
Exit;
end;
Seek(F,Posit+(OffsetInMatch-2));
if IOResult <> 0 then begin
WriteLn('Seek error in ',FName);
Close(F);
if IOResult <> 0 then ;
Exit;
end;
BlockWrite(F,NewMode,SizeOf(Byte));
if IOResult <> 0 then begin
WriteLn('Error writing ',FName);
Close(F);
if IOResult <> 0 then ;
Exit;
end;
Close(F);
if IOResult = 0 then
WriteLn(FName,' patched')
else
WriteLn('I/O error saving ',FName);
end;

procedure LookForPatchPoints(Size : Word; var TxtPosit,OvrPosit : Word);

begin
OvrPosit := Search(Buffer^,Size,OverlayMatchPattern,
SizeOf(OverlayMatchPattern));
TxtPosit := Search(Buffer^,Size,SystemMatchPattern,
SizeOf(SystemMatchPattern));
end;

procedure IOCheck(S : String);

var
E : Word;
begin
E := IOResult;
if E <> 0 then begin
WriteLn('IOResult = ',E);
WriteLn(S);
Halt;
end;
end;

procedure PatchByte(var F : File; Offs : Longint; var Bite : Byte);

var
B : Byte;
begin
Seek(F,Offs);
IOCheck('Error seeking '+FileToPatch);
BlockRead(F,B,SizeOf(B));
IOCheck('Error reading '+FileToPatch);
WriteLn('B = ',B);
Seek(F,Offs);
IOCheck('Error seeking '+FileToPatch);
BlockWrite(F,Bite,SizeOf(Bite));
IOCheck('Error writing '+FileToPatch);
end;

procedure PatchDiskFile;

var
Overlap1,Overlap2 : ^BufferType;
Size,Posit : LongInt;
NumRead,TxtPosit,OvrPosit : Word;
FoundOvr,FoundText : Boolean;

begin
Assign(F,FileToPatch);
Reset(F,1);
IOCheck(FileToPatch + ' not found');
Size := FileSize(F);
FoundOvr := False;
FoundText := False;
Posit := 0;
while (Posit < Size) and (not (FoundOvr and FoundText)) do begin
Seek(F,Posit);
IOCheck('Error seeking '+FileToPatch);
BlockRead(F,Buffer^,SizeOf(Buffer^),NumRead);

LookForPatchPoints(NumRead,TxtPosit,OvrPosit);
if TxtPosit > 0 then begin
FoundText := True;
PatchByte(F,Posit+TxtPosit,NewMode);
end;
if OvrPosit > 0 then begin
FoundOvr := True;
PatchByte(F,Posit+OvrPosit+2,NewMode);
end;

Inc(Posit,NumRead);
if Posit < Size then
Dec(Posit,SizeOf(SystemMatchPattern));
end;
if FoundOvr then
WriteLn('Overlay file open patched in ',FileToPatch)
else
WriteLn(FileToPatch,' does not use TP5 Overlays (or already patched).');
if FoundText then
WriteLn('Text file open (reset) patched in ',FileToPatch)
else begin
WriteLn('Patch point not found for SYSTEM.TPU code in ',FileToPatch);
WriteLn('Either already patched or not a Turbo Pascal 5 program.');
end;
end;

procedure PatchTPLandTPUs;

begin
PatchMode(OverlayUnit,OverlayMatchPattern,SizeOf(OverlayMatchPattern),4);
PatchMode(SystemUnit,SystemMatchPattern,SizeOf(SystemMatchPattern),2);
PatchMode(TurboTPL,OverlayMatchPattern,SizeOf(OverlayMatchPattern),4);
PatchMode(TurboTPL,SystemMatchPattern,SizeOf(SystemMatchPattern),2);
end;

var
I : Byte;

begin
WriteLn('TP5Patch version 1.0 - Patches Overlay and Text File Modes'^M^J);
FileToPatch := '';
GetOptions;
New(Buffer);

if PatchingEXE then
PatchDiskFile
else
PatchTPLandTPUs;

Dispose(Buffer);
end.


  3 Responses to “Category : Pascal Source Code
Archive   : TP5PATCH.ZIP
Filename : TP5PATCH.PAS

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/