home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
progjorn
/
pj_7_1.arc
/
TCUNIT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-12-15
|
6KB
|
214 lines
(*
* PROGRAM : For editing typed constants in EXE files
* SYSTEM : PC/MS-DOS / Turbo Pascal 4.0 or 5.0
* AUTHOR : (C) 1988 by Tom Swan
*)
UNIT TCUnit;
INTERFACE
USES Crt; { Standard Borland display unit }
PROCEDURE GetWord( prompt : String; VAR v : Word;
low, high : Word );
PROCEDURE GetStr( prompt : String; VAR s : String;
maxLen : Word );
FUNCTION ChangesSaved( fileName, searchStr : String;
cbase, ebase : Word ) : Boolean;
IMPLEMENTATION
TYPE ExeFile = File OF Char; { Reads EXE files as file of char }
PROCEDURE GetWord( prompt : String; VAR v : Word; low, high : Word );
{ Prompt for word value, displaying prompt string and limiting
response in v to the range low..high. }
VAR response : String[8]; { Holds response to prompt }
newValue : Word; { Possible new value for v }
e : Integer; { Error code for Val() }
BEGIN
ClrScr;
Writeln;
Writeln( prompt, ' = ', v );
Writeln;
Writeln( 'Enter new value from ', low, ' to ', high );
Write( 'or press Enter for no change: ' );
Readln( response );
IF Length( response ) > 0 THEN
BEGIN
Val( response, newValue, e );
IF ( e = 0 ) AND ( low <= newValue ) AND ( newValue <= high )
THEN
v := newValue
ELSE
BEGIN
Writeln;
Write( 'Entry error. Press Enter...' );
Readln
END { else }
END { if }
END; { GetWord }
PROCEDURE GetStr( prompt : String; VAR s : String; maxLen : Word );
{ Prompt for string, displaying prompt string and limiting response
in s to string length 0..maxLen. }
VAR response : String; { Holds response to prompt }
BEGIN
ClrScr;
Writeln;
Writeln( prompt, ' = ', s );
Writeln;
Writeln( 'Enter new string with up to ', maxLen, ' characters' );
Write( 'or press Enter for no change: ' );
Readln( response );
IF Length( response ) > 0 THEN
BEGIN
IF Length( response ) <= maxLen
THEN
s := response
ELSE
BEGIN
Writeln;
Write( 'Entry error. Press Enter...' );
Readln
END { else }
END { if }
END; { GetStr }
PROCEDURE ShowError( e : Integer );
{ Display an error message. e>0 = I/O error; e<0 = other error }
BEGIN
IF e > 0
THEN Writeln( 'I/O Error #', e )
ELSE Writeln( 'Error in EXE file format' );
Writeln;
Writeln( 'WARNING: EXE file may be damaged!' );
Writeln;
Write( 'Press Enter...' );
Readln
END; { ShowError }
{$i-} { Shut off I/O error checks }
FUNCTION FoundCBase( VAR f : ExeFile; VAR searchStr : String;
VAR offset : LongInt ) : Boolean;
{ Return True if searchString (CBase) is found in file f. If found,
then return byte offset to string in file. }
VAR position : LongInt; { Possible position of match }
ch : Char; { Holds candidate bytes from file }
FUNCTION FoundMatch : Boolean;
{ True if current position = search string }
VAR i : Integer; { searchStr index }
BEGIN
FOR i := 2 TO Length( searchStr ) DO
BEGIN
Read( f, ch );
IF ch <> searchStr[i] THEN
BEGIN
FoundMatch := False;
Exit
END { if }
END; { for }
FoundMatch := True
END; { FoundMatch }
BEGIN
Reset( f ); { Start search at beginning of file }
WHILE NOT Eof( f ) DO
BEGIN
Read( f, ch );
IF ch = searchStr[1] THEN { Test one char }
BEGIN
position := FilePos( f ); { Remember position }
IF FoundMatch THEN { Check for match }
BEGIN
offset := position - 2; { Found: return offset }
(* Writeln; Writeln( 'Offset = ', offset ); *)
FoundCBase := True; { Set function result }
Exit { Stop searching }
END ELSE
Seek( f, position ) { Continue search }
END { if }
END; { while }
FoundCBase := False { searchStr isn't there }
END; { FoundCBase }
PROCEDURE SaveData( VAR f : ExeFile; offset, cbase, len : LongInt;
VAR e : Integer );
{ Write len bytes to file f, beginning at byte #offset in the file
and transferring from memory len bytes starting at DS:cbase. Return
any errors in e. This copies the in-memory typed constants to the
EXE file image on disk. }
VAR i : Word; { Mem[] array index }
BEGIN
Seek( f, offset );
FOR i := 0 TO ( len - 1 ) DO
BEGIN
Write( f, Char( Mem[ DSeg:( cbase + i ) ] ) );
e := IoResult;
IF e <> 0 THEN Exit
END { for }
END; { SaveData }
FUNCTION ChangesSaved( fileName, searchStr : String; cbase,
ebase : Word ) : Boolean;
{ Return True if typed constants in memory are written to disk.
fileName must be a Turbo Pascal compiled EXE file. searchStr
should equal the CBase marker string at the start of the typed
constants area. cbase should be the in-memory offset to the CBase
typed constant. ebase should be the in-memory offset to the EBase
typed constant. }
VAR f : ExeFile; { Read .EXE as a char file }
offset : LongInt; { Byte offset to CBase in .EXE file }
err : Integer; { Error code }
BEGIN
GotoXY( 1, 25 );
ClrEol;
Write( 'Saving changes to ', fileName, '. Please wait...' );
Assign( f, fileName );
Reset( f );
err := IoResult;
IF err = 0 THEN
IF FoundCBase( f, searchStr, offset )
THEN SaveData( f, offset, cbase, ( ebase - cbase ), err );
ChangesSaved := ( err = 0 ); { i.e. True if no error }
Writeln;
IF err = 0
THEN Writeln( 'Changes saved' )
ELSE ShowError( err );
Close( f )
END; { ChangesSaved }
END. { TCUnit }