(******************************************************************* Make sure we're working with an *.EXE file extension. *******************************************************************) procedure SetExeExt ( VAR S : string ) ; begin S := Upper ( S ) ; if pos ( '.EXE' , S ) = 0 then S := S + '.EXE' ; end ; (******************************************************************* Global OPEN and CLOSE, with error checking. *******************************************************************) function OpenFile ( VAR F : file ; S : string ) : boolean ; begin OpenFile := FALSE ; SetExeExt ( S ) ; {$I-} assign ( F , S ) ; reset ( F , 1 ) ; {$I+} (******************************************************************* Restoring FileMode to the our default AFTER the Reset allows the calling procedure to set the FileMode if need be. *******************************************************************) FileMode := DefaultFileMode ; if IOresult <> 0 then EXIT ; OpenFile := TRUE ; end ; procedure CloseFile ( VAR F : file ) ; begin {$I-} Close ( F ) ; {$I+} if IOresult <> 0 then Abort ( 'Error closing file' ) ; end ; (******************************************************************* File size function - from DOS. *******************************************************************) function FileBytes ( S : string ) : longint ; var F : file ; begin FileBytes := 0 ; if not OpenFile ( F , S ) then EXIT ; FileBytes := FileSize ( F ) ; CloseFile ( F ) ; end ; (******************************************************************* File size function - from EXE header. *******************************************************************) function ExeFileSize ( S : string ) : longint ; var F : file ; ExeHeader : ExeHeaderRec ; W : word ; begin ExeFileSize := 0 ; if not OpenFile ( F , S ) then EXIT ; BlockRead ( F , ExeHeader , SizeOf ( ExeHeader ) , W ) ; CloseFile ( F ) ; if W <> SizeOf ( ExeHeader ) then EXIT ; with ExeHeader do begin if Signature <> $5A4D then EXIT ; (* Not EXE format *) if LengthRem = 0 then ExeFileSize := LongInt ( LengthPages ) shl 9 else ExeFileSize := ( LongInt ( Pred ( LengthPages ) ) shl 9 ) + LongInt ( LengthRem ) ; end ; end ; (******************************************************************* Seek with error checking. *******************************************************************) procedure SeekFile ( VAR F : file ; L : longint ) ; begin {$I-} Seek ( F , L ) ; {$I+} if IOresult <> 0 then Abort ( 'Error during file SEEK' ) ; end ; (******************************************************************* Append user-specific data to the end of the EXE file. *******************************************************************) procedure ExeInstallData ( S : string ; VAR V ; NumBytes : longint ) ; var F : file ; BytesInExeHeader : longint ; begin BytesInExeHeader := ExeFileSize ( S ) ; FileMode := DefaultWriteMode ; if not OpenFile ( F , S ) then Abort ( 'Unable to open file ' + S ) ; SeekFile ( F , BytesInExeHeader + 1 ) ; (* 1 byte past EXE size *) {$I-} BlockWrite ( F , V , NumBytes ) ; {$I+} if IOresult <> 0 then Abort ( 'Error writing to original file!' ) ; CloseFile ( F ) ; end ; (******************************************************************* Read user-specific data from the end of the EXE file, as reported by the EXE header, NOT the actual DOS file size. *******************************************************************) procedure ExeReadData ( S : string ; VAR V ; NumBytes : longint ) ; var F : file ; BytesInExeHeader : longint ; begin FillChar ( V , NumBytes , #0 ) ; BytesInExeHeader := ExeFileSize ( S ) ; if not OpenFile ( F , S ) then Abort ( 'Unable to open file ' + S ) ; SeekFile ( F , BytesInExeHeader + 1 ) ; {$I-} BlockRead ( F , V , NumBytes ) ; {$I+} if IOresult <> 0 then Abort ( 'Error reading file!' ) ; CloseFile ( F ) ; end ; (******************************************************************* A check to see if the EXE has already been "stamped". *******************************************************************) function IsExePersonalized ( S : string ) : boolean ; begin IsExePersonalized := ExeFileSize ( S ) <> FileBytes ( S ) ; end ;