home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9101 / tricks / pascal / turpatch / tpwpatch.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1991-09-30  |  6.7 KB  |  243 lines

  1. (* ------------------------------------------------------ *)
  2. (*                     TPWPATCH.PAS                       *)
  3. (*        Ändern der Meldung in TPW-EXE-Dateien.          *)
  4. (*        (c) 1991 Mario Westphal & DMV-Verlag            *)
  5. (* ------------------------------------------------------ *)
  6.  
  7. {$DEFINE PRG_FERTIG}                 { Checks aus          }
  8. {$DEFINE DEBUG}                      { Zum Debuggen setzen }
  9. {$DEFINE IDE}      { WICHTIG: innerhalb der IDE definieren }
  10.  
  11. PROGRAM TPW_WinExePatch;
  12. {$M 4096,0,655360}
  13.  
  14. {$IFDEF PRG_FERTIG} 
  15.   {$A+,B-,D-,E+,F-,G-,I+,L-,N-,O-,R-,S-,V+,X-}
  16. {$ENDIF}
  17. {$IFDEF DEBUG}
  18.   {$D+,L+}
  19. {$ENDIF}
  20.  
  21. USES Crt, Dos;
  22.  
  23. CONST
  24.   cHSize   = $08;         { Offset: Größe des Headers      }
  25.   cWhAddr  = $3C;         { Offset: Adresse Windows-Header }
  26.   cWinID   = $454E;             { Kennung im W-Header "EN" }
  27.   cTpWid   = $E0010BA;          { MOV DX,0010 PUSH CS      }
  28.   cMStart  = $90;               { Offset: Meldung          }
  29.   cMLen    = $100-cMStart;      { Länge der Meldung        }
  30.   CR      = '\N';               { Steuerzeichen            }
  31.   cDefName = 'TPWPATCH.DEF';    { Name der Default-Datei   }
  32.  
  33. VAR
  34.   PaStr   : STRING;
  35.   DefMess : STRING [cMLen-3];   { -3 wg. CRLF+"$" am Ende  }
  36.   NewMess : STRING [cMLen-3];
  37.   b       : BYTE;
  38.  
  39.  
  40.   FUNCTION ParseStr(s : STRING) : STRING;
  41.     (* Ersetzt das Steuerzeichen \N durch CRLF, füllt bis
  42.        zur maximalen Länge mit Blanks auf und fügt CRLF+"$"
  43.        an das Stringende an.                              *)
  44.   VAR
  45.     i : BYTE;
  46.     t : STRING;
  47.   BEGIN
  48.     FillChar(t[1], cMLen, ' ');
  49.     i := Pos(CR, s);              { Steuerzeichen ersetzen }
  50.     WHILE i <> 0 DO BEGIN
  51.       Insert(#13#10, s, i);
  52.       Delete(s, i+2, 2);
  53.       i := Pos(CR, s);
  54.     END;
  55.     t := s+#13#10+'$';       
  56.     t[0] := CHR(cMLen);
  57.     ParseStr := t;
  58.   END;
  59.  
  60.  
  61.   FUNCTION LoadDefMess : BOOLEAN;
  62.     (* Öffnet TPWPATCH.DEF und liest die erste Zeile in die
  63.        Variable "DefMess". Liefert FALSE bei I/O-Fehler.  *)
  64.   VAR
  65.     FName : STRING;
  66.     d     : DirStr;
  67.     n     : NameStr;
  68.     e     : ExtStr;
  69.     TFile : TEXT;
  70.   BEGIN
  71.     LoadDefMess := FALSE;
  72.     FSplit(ParamStr(0), d, n, e);
  73.   {$IFDEF IDE}                    { nur innerhalb der IDE }
  74.     d := 'C:\TP\';                { evtl. anpassen !      }
  75.   {$ENDIF}
  76.     FName := d + cDefName;
  77.     Assign(TFile, FName);
  78.   {$I-}
  79.     Reset(TFile);
  80.   {$I+}
  81.     IF IOResult <> 0 THEN Exit;
  82.     ReadLn(TFile, DefMess);
  83.     Close(TFile);
  84.     LoadDefMess := (IOResult = 0);
  85.   END;
  86.  
  87.  
  88.   FUNCTION IsWinEXE(FName : STRING) : BYTE;
  89.     (* Prüft, ob die Datei "FName" eine TPW EXE-Datei ist.
  90.        Ergebnis  = 0 : Kein Fehler und gültige Datei
  91.                  = 1 : Keine TPW EXE-Datei
  92.                  = 2 : Keine Windows EXE-Datei
  93.                  = 3 : I/O-Fehler                        *)
  94.   TYPE
  95.     LType = RECORD
  96.               CASE Typ : INTEGER OF
  97.                 0 : (L  : LONGINT);
  98.                 1 : (LW : WORD;
  99.                      HW : WORD);
  100.             END;
  101.   VAR
  102.     f : FILE;
  103.     w : WORD;
  104.     L : LType;
  105.  
  106.     FUNCTION ReadWord(VAR w : WORD) : BOOLEAN;
  107.       (* Liest ein Word. Schließt bei Fehler die Datei
  108.          und liefert FALSE.                               *)
  109.     VAR
  110.       r : WORD;
  111.       e : INTEGER;
  112.     BEGIN
  113.     {$I-}
  114.       BlockRead(f, w, SizeOf(w), r);
  115.       e := IOResult;
  116.       IF (e <> 0) OR (r <> SizeOf(w)) THEN Close(f);
  117.     {$I+}
  118.       ReadWord := (e = 0) AND (r = SizeOf(w));
  119.     END;
  120.  
  121.   BEGIN
  122.     IsWinEXE := 3;
  123.     Assign(f, FName);
  124.   {$I-}
  125.     Reset(f, 1);
  126.     IF IOResult <> 0 THEN Exit;
  127.  
  128.     Seek(f, cWhAddr);        { Windows-Header Offset lesen }
  129.  
  130.     IF NOT ReadWord(L.LW) THEN Exit;
  131.     IF NOT ReadWord(L.HW) THEN Exit;
  132.  
  133.     Seek(f, L.L);
  134.     IF NOT ReadWord(w) THEN Exit;          { Kennung lesen }
  135.     IF w <> cWinID THEN BEGIN
  136.       IsWinEXE := 2;
  137.       Close(f);
  138.       Exit;
  139.     END;
  140.  
  141.     Seek(f, cHSize);             { Größe des Headers lesen }
  142.     IF NOT ReadWord(w) THEN Exit;
  143.     w := w SHL 4;                   { Paragraphen -> Bytes }
  144.     Seek(f, w);                        { Die ersten 4 Byte }
  145.     IF NOT ReadWord(L.LW) THEN Exit;   { des Code-Segments }
  146.     IF NOT ReadWord(L.HW) THEN Exit;   { vergleichen       }
  147.     Close(f);
  148.   {$I+}
  149.  
  150.     IF IOResult <> 0 THEN Exit;
  151.     IF L.L <> cTpWid THEN IsWinEXE := 1
  152.                      ELSE IsWinEXE := 0
  153.   END;
  154.  
  155.  
  156.   FUNCTION Patch(FName : STRING; Mess : STRING) : BOOLEAN;
  157.     (* Überschreibt den alten Text in der EXE-Datei mit dem
  158.        Inhalt von "DefMess". Liefert FALSE bei I/O-Fehler *)
  159.   VAR
  160.     f : FILE;
  161.     r : WORD;
  162.   BEGIN
  163.   {$I-}
  164.     Patch := FALSE;
  165.     Assign(f, FName);
  166.     Reset(f, 1);
  167.     IF IOResult <> 0 THEN Exit;
  168.     Seek(f, cMStart);
  169.     IF IOResult <> 0 THEN
  170.     BEGIN Close(f); Exit;
  171.     END;
  172.     BlockWrite(f, Mess[1], cMLen, r);
  173.     Close(f);
  174.     Patch := (IOResult = 0) AND(r = cMLen);
  175.   {$I+}
  176.   END;
  177.  
  178. BEGIN
  179.   WriteLn('TPWPatch - ',
  180.           '(c) 1991 Mario M. Westphal & DMV-Verlag');
  181.  
  182.   IF Lo(DosVersion) < 3 THEN BEGIN     { wegen ParamStr(0) }
  183.     WriteLn;
  184.     WriteLn('Dieses Programm benötigt DOS-Version 3.x!');
  185.     Halt(1);
  186.   END;
  187.  
  188.   IF NOT LoadDefMess THEN BEGIN  { Default-String einlesen }
  189.     WriteLn;
  190.     WriteLn(#7, 'Kann Message-Datei nicht lesen!');
  191.     Halt(1);
  192.   END;
  193.  
  194.   PaStr := ParamStr(1);           { Dateinamen aufbereiten }
  195.   IF PaStr = '' THEN BEGIN
  196.     WriteLn;
  197.     WriteLn('AUFRUF: tpwpatch <Dateiname>');
  198.     Halt(1);
  199.   END ELSE
  200.     PaStr := FExpand(PaStr);
  201.   b := Pos('.', PaStr);
  202.   IF b = 0 THEN
  203.     PaStr := PaStr + '.EXE'
  204.   ELSE IF Copy(PaStr, b, 4) <> '.EXE' THEN BEGIN
  205.     WriteLn;
  206.     WriteLn(#7, 'Ungültiger Dateiname!');
  207.     Halt(1);
  208.   END;
  209.   WriteLn('Datei: ', PaStr);
  210.  
  211.   b := IsWinEXE(PaStr);               { Dateiformat prüfen }
  212.   IF b <> 0 THEN BEGIN
  213.     CASE b OF
  214.       1 : WriteLn(#7, 'Keine TPW EXE-Datei!');
  215.       2 : WriteLn(#7, 'Kein Windows-Programm!');
  216.       3 : WriteLn(#7, 'Fehler beim Zugriff auf Datei!');
  217.     END;
  218.     Halt(1);
  219.   END;
  220.  
  221.   WriteLn('Vorgabe:');            { Neue Meldung einlesen }
  222.   DefMess := ParseStr(DefMess);
  223.   HighVideo;
  224.   WriteLn(DefMess);
  225.   NormVideo;
  226.   WriteLn;
  227.   WriteLn('Neue Meldung (<─┘ = Vorgabe):');
  228.   HighVideo;
  229.   ReadLn(NewMess);
  230.   NormVideo;
  231.   WriteLn;
  232.   IF NewMess = '' THEN NewMess := DefMess
  233.                   ELSE NewMess := ParseStr(NewMess);
  234.  
  235.   IF NOT Patch(PaStr, NewMess) THEN BEGIN        { Patchen }
  236.     WriteLn(#7, 'Fehler beim Ändern der Meldung!');
  237.     Halt(1);
  238.   END ELSE
  239.     WriteLn('Meldung wurde geändert.');
  240. END.
  241. (* ------------------------------------------------------ *)
  242. (*               Ende von TPWPATCH.PAS                    *)
  243.