home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9203 / driver / drvload.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-04-05  |  5.3 KB  |  153 lines

  1. Program DrvLoad;  { DRVLOAD.PAS, 20-JUN-91 as }
  2. {$M $1000,0,0}
  3. uses Dos, DosUtils,DrvLib;
  4.  
  5. { Lädt Zeichentreiber im Format .SYS bzw. .COM zu beliebigen Zeitpunkten.
  6.  
  7.   Aufruf: DRVLOAD [HI] <Treiber-Datei> [Treiber-Parameter...]
  8. }
  9.  
  10.  
  11. Function UpString(s: String): String;
  12. var x: Integer;
  13. begin
  14.   for x := 1 to Length(s) do UpString[x] := Upcase(s[x]);
  15.   UpString[0] := s[0];
  16. end;
  17.  
  18. var
  19.   OrgStrat: Byte; OrgLink: Boolean;
  20. Procedure ErrOut(Msg: String);
  21. begin
  22.   Writeln(Msg);
  23.   SetUMBLink(OrgLink); SetAllocStrat(OrgStrat);
  24.   Halt;
  25. end;
  26.  
  27. var
  28.   DrvInitBlock: Record  { Parameterblock für "Init" }
  29.     DSize:      Byte;    { Größe des gesamten Blocks }
  30.     DUnit:      Byte;    { Geräte-Kennziffer (relativ) }
  31.     DFunc:      Byte;    { Funktionsnummer ($00) }
  32.     DStatus:    Word;    { Status als Ergebnis }
  33.     DResvd:     Array[0..7] of Byte;
  34.     { --- Funktionsabhängige Felder --- }
  35.     DUnits:     Byte;    { Anzahl Laufwerke (nur für Block) }
  36.     DEndAddr:   Pointer; { Endadresse, vom Treiber gesetzt }
  37.     DCmdLine:   Pointer; { Adresse der "Kommandozeile" }
  38.     DFirstDrv:  Byte;    { Kennziffer erstes Laufwerk (nur Block) }
  39.     DMsgFlag:   Word;    { für Fehlermeldungen des Treibers }
  40.   end;
  41.  
  42.   DriverCmd: String;  { Kommandozeile für den Treiber }
  43.   DriverName, HiCmd: String;
  44.   F: File;
  45.   FSize: Word;        { Größe der Datei in Bytes }
  46.   x, ParmStart: Integer;
  47.   DriverSeg,DriverSize: Word;
  48.   DriverHead, NULDev,NextDev: DriverPointer;
  49.   DriverMCB : MCBPtr;
  50.   FileHead : Record  { nur für DR-DOS }
  51.     ID,Remainder,Pages,RelocItems,HdSize: Word;
  52.   end;
  53. begin
  54.   Writeln('DRVLOAD (c) 6/91 as');
  55.   if (ParamCount = 0) or (ParamStr(1) = '/?') or
  56.     (ParamStr(1) = '/H') then
  57.   begin
  58.     Writeln('Aufruf: DRVLOAD [HI] <Zeichentreiber-Datei> ',
  59.             '[Treiber-Parameter...]');
  60.     Writeln('Lädt Zeichentreiber ohne Neustart des Systems.');
  61.     Halt;
  62.   end;
  63.  
  64.   { Speicherverteilungskonzept festhalten und Prüfung auf
  65.     Kommandozeilen-Parameter 'HI' }
  66.   OrgStrat := GetAllocStrat; OrgLink := GetUMBLink;
  67.   DriverName := UpString(ParamStr(1));
  68.   SetAllocStrat(2);  { Treiber auf jeden Fall ans Ende }
  69.   if DriverName = 'HI' then
  70.   begin   { UMB mit einbinden, soweit möglich }
  71.     SetUMBLink(TRUE); DriverName := UpString(ParamStr(2));
  72.     ParmStart := 3;
  73.   end else ParmStart := 2;
  74.  
  75.   { Haben wir es mit einer .EXE-Datei zu tun? }
  76.   if Pos('.EXE',DriverName) <> 0
  77.     then ErrOut('Geht leider nicht für .EXE-Dateien!');
  78.  
  79.   { Datei öffnen und erst einmal prüfen }
  80.   Assign(F,DriverName); {$I-} Reset(F,1); {$I+}
  81.   if IOResult <> 0
  82.     then ErrOut('Datei '+DriverName+' nicht gefunden.');
  83.   FSize := FileSize(F);
  84.   { Die ersten 10 Bytes lesen }
  85.   BlockRead(F,FileHead,Sizeof(FileHead));
  86.   if FileHead.ID <> $FFFF then { Treiberkopf? }
  87.   begin
  88.     if (Swap(DosVersion) = $0329) or (Swap(DosVersion) = $0332) then
  89.     with FileHead do
  90.     begin           { DR-DOS 3.41 oder 5.0 }
  91.       if (ID <> $5A4D) or (RelocItems <> 0) { .EXE-Signatur,RelocTbl }
  92.          then ErrOut('DR-DOS: als .SYS getarnte .EXE-Datei');
  93.       Dec(FSize,HdSize*16);  { Dateigröße minus Kopf }
  94.       Seek(F,HdSize*16); { Position hinter Dateikopf }
  95.       BlockRead(F,FileHead,Sizeof(FileHead)); { die ersten 10 Bytes }
  96.     end
  97.      else ErrOut('MS-DOS: Treiber ist .EXE-Datei!');
  98.   end;
  99.  
  100.   DriverSeg := GetMemBlock(FSize); DriverHead := Ptr(DriverSeg,0);
  101.   if DosError <> 0  { haben wir genug Platz? }
  102.     then ErrOut('Nicht genug Platz im Hauptspeicher!');
  103.  
  104.   Move(FileHead,DriverHead^,Sizeof(FileHead)); { 10 Bytes kopieren }
  105.   BlockRead(F,Ptr(DriverSeg,Sizeof(FileHead))^,
  106.              FSize-Sizeof(FileHead)); { Datei einlesen }
  107.   if (DriverHead^.DAttr and $8000) = 0 then
  108.   begin
  109.     FreeMemBlock(DriverSeg);
  110.     ErrOut(DriverName + ' ist kein Zeichentreiber!');
  111.   end;
  112.  
  113.   { Treiber in die Kette einbauen }
  114.   NULDev := GetFirstHeader; NextDev := NulDev^.DNext;
  115.   DriverHead^.DNext := NextDev; NULDev^.DNext := DriverHead;
  116.  
  117.   { Kommandozeile zusammensetzen und Parameterblock erstellen }
  118.   DriverCmd := DriverName;
  119.   for x := ParmStart to ParamCount
  120.     do DriverCmd := DriverCmd + ' ' + ParamStr(x);
  121.   DriverCmd := DriverCmd + #13#10;  { CR/LF anhängen }
  122.  
  123.   FillChar(DrvInitBlock,Sizeof(DrvInitBlock),0);
  124.   with DrvInitBlock do
  125.   begin
  126.     DSize := Sizeof(DrvInitBlock);
  127.     DFunc := 0;  { eigentlich unnötig }
  128.     DCmdLine := Addr(DriverCmd[1]);  { hinter dem Längenbyte }
  129.     DEndAddr := Ptr(DriverSeg+FSize div 16,0); { verfügbarer Platz }
  130.  
  131.     CallStrategy(DriverHead,@DrvInitBlock);  { Übergabe }
  132.     CallInterrupt(DriverHead);  { und Ausführung }
  133.  
  134.     if ((DStatus and $8000) <> 0) { or (DStatus and $0100 = 0)} then
  135.     begin   { Fehler! }
  136.       NULDev^.DNext := NextDev;  { Treiber aus der Kette raus }
  137.       FreeMemBlock(DriverSeg);
  138.       ErrOut('Fehler bei der Initialisierung!');
  139.     end;
  140.     DriverSize := (LongInt((Seg(DEndAddr^) - DriverSeg))*16
  141.                  + Ofs(DEndAddr^)+$0F) div 16;
  142.     SetMemBlock(DriverSeg,DriverSize);
  143.     DriverMCB := Ptr(DriverSeg-1,0);
  144.     DriverMCB^.OwnerPSP := DriverSeg;
  145.     for x:= 1 to 8 do DriverMCB^.OwnerID[x] := DriverHead^.Name[x];
  146.  
  147.     Write('Treiber ',DriverName, ' (Gerätename ');
  148.     for x:= 1 to 8 do Write(DriverHead^.Name[x]);
  149.     Writeln(') geladen.');
  150.   end;
  151.   SetAllocStrat(OrgStrat); SetUMBLink(OrgLink);
  152. end.
  153.