home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_PAS / TVTOYS.ZIP / EXESTRM.PAS < prev    next >
Pascal/Delphi Source File  |  1994-01-20  |  6KB  |  188 lines

  1. (***************************************************************************
  2.   ExeStream unit
  3.   Stream that makes adding resources to your .EXE a piece of cake
  4.   PJB November 13, 1993, CompuServe mail to INTERNET:d91-pbr@nada.kth.se
  5.   Copyright PJB 1993, All Rights Reserved. Portions copyright Borland.
  6.   Free source, use at your own risk.
  7.   If modified, please state so if you pass this around.
  8.  
  9.   All seeks are relative to the first header byte.
  10.  
  11.   Don't use this to write to your EXE file, since
  12.   1) You can't insert new data, only overwrite
  13.   2) You'll probably get virus warnings
  14.  
  15.   To add your own resource types, follow the THeader format.
  16.   This should be the first 8 bytes in your resource:
  17.  
  18.      Signature : Word;    { Use $4246 }
  19.      InfoType  : Word;    { Any unused, not $4648 or $5250 }
  20.      InfoSize  : Longint  { Length in bytes of resource, not counting this }
  21.                           { header itself }
  22.  
  23.   If you want to use your resource with DPMI apps, you have to add a
  24.   "back link". At the end of your resource, append $4C424246 and then
  25.   the size of your resource + the 8 bytes of the back link. The InfoSize
  26.   value in the starting header should count the back link as part of the
  27.   resource.
  28.  
  29.   See THelpFile.Done in the TVToys HELPFILE or TResourceFile.Flush in
  30.   OBJECTS.PAS
  31.  
  32. ***************************************************************************)
  33. unit ExeStrm;
  34.  
  35. {$B-}
  36.  
  37. interface
  38.  
  39.   uses
  40.     Objects;
  41.  
  42.   type
  43.     PExeScanningStream = ^TExeScanningStream;
  44.     TExeScanningStream =
  45.       object (TDosStream)
  46.         BasePos : Longint;
  47.         constructor Init(FileName:FNameStr; Mode:Word; InfoType:Word);
  48.         procedure Seek(Pos:Longint); virtual;
  49.       end;
  50.  
  51.   const
  52.     magicHelpFile     = $4648;
  53.     magicResourceFile = $5250;
  54.  
  55.  
  56. (***************************************************************************
  57. ***************************************************************************)
  58. implementation
  59.  
  60.   {$IFDEF DPMI}
  61.     {$DEFINE NewExeFormat}
  62.   {$ENDIF}
  63.   {$IFDEF WINDOWS}
  64.     {$DEFINE NewExeFormat}
  65.   {$ENDIF}
  66.  
  67.  
  68.   (*******************************************************************
  69.     Find the beginning of the EXE appendix
  70.   *******************************************************************)
  71.   constructor TExeScanningStream.Init(FileName:FNameStr; Mode:Word; InfoType:Word);
  72.     type
  73.      {$IFDEF NewExeFormat}
  74.       TExeHeader = record
  75.         eHdrSize:   Word;
  76.         eMinAbove:  Word;
  77.         eMaxAbove:  Word;
  78.         eInitSS:    Word;
  79.         eInitSP:    Word;
  80.         eCheckSum:  Word;
  81.         eInitPC:    Word;
  82.         eInitCS:    Word;
  83.         eRelocOfs:  Word;
  84.         eOvlyNum:   Word;
  85.         eRelocTab:  Word;
  86.         eSpace:     array [1..30] of Byte;
  87.         eNewHeader: Word;
  88.       end;
  89.      {$ENDIF}
  90.  
  91.       THeader =
  92.         record
  93.           Signature: Word;
  94.           case Integer of
  95.             0: (
  96.               LastCount: Word;
  97.               PageCount: Word;
  98.               ReloCount: Word);
  99.             1: (
  100.               InfoType: Word;
  101.               InfoSize: Longint);
  102.         end;
  103.  
  104.     var
  105.       Found  : Boolean;
  106.       Header : THeader;
  107.      {$IFDEF NewExeFormat}
  108.       ExeHeader: TExeHeader;
  109.      {$ENDIF}
  110.  
  111.   begin
  112.     inherited Init(FileName, Mode);
  113.  
  114.     BasePos:=0;
  115.     Found:=False;
  116.  
  117.     while (Status=stOK) and (BasePos<=GetSize-SizeOf(THeader)) do
  118.     begin
  119.       Seek(0);                                        (* Seek to BasePos *)
  120.       Read(Header, SizeOf(THeader));
  121.       case Header.Signature of
  122.  
  123.        {$IFDEF NewExeFormat}
  124.         $5A4D:
  125.           begin
  126.             Read(ExeHeader, SizeOf(TExeHeader));
  127.             BasePos:=ExeHeader.eNewHeader;
  128.           end;
  129.         $454E:  BasePos:=GetSize-SizeOf(THeader);
  130.         $4246:                                        (* Borland header *)
  131.           if Header.InfoType=InfoType then
  132.           begin
  133.             Found:=True;
  134.             Break;
  135.           end
  136.           else
  137.             case Header.Infotype of
  138.               $4C42: Dec(BasePos, Header.InfoSize-8); { Found BackLink }
  139.               else                       { Found TV HelpFile, Resource etc }
  140.                 Inc(BasePos, Header.InfoSize+8);
  141.                 { Dec(BasePos, SizeOf(THeader)*2); (* Windows helpfile? *)}
  142.             end;
  143.         $424E:
  144.           if Header.InfoType=$3230 then               { Found Debug Info }
  145.             Dec(BasePos, Header.InfoSize);
  146.         else
  147.           Break;
  148.  
  149.        {$ELSE}
  150.  
  151.         $5A4D: Inc(BasePos, LongMul(Header.PageCount, 512) -
  152.                  (-Header.LastCount and 511));
  153.         $4246:                                         (* Borland header *)
  154.           if Header.InfoType=InfoType then
  155.           begin
  156.             Found:=True;
  157.             Break;
  158.           end
  159.           else
  160.             Inc(BasePos, Header.InfoSize+8);
  161.         else
  162.           Break;
  163.        {$ENDIF}
  164.  
  165.       end;
  166.     end;
  167.  
  168.     if not Found then
  169.       Error(stInitError, 0);
  170.   end;
  171.  
  172.  
  173.   (*******************************************************************
  174.     Overridden seek does relative seeks
  175.   *******************************************************************)
  176.   procedure TExeScanningStream.Seek(Pos:Longint);
  177.   begin
  178.     inherited Seek(BasePos+Pos);
  179.   end;
  180.  
  181.  
  182.     (*******************************************************************
  183.     *******************************************************************)
  184.  
  185. end.
  186.  
  187.  
  188.