home *** CD-ROM | disk | FTP | other *** search
- Program DrvLoad; { DRVLOAD.PAS, 20-JUN-91 as }
- {$M $1000,0,0}
- uses Dos, DosUtils,DrvLib;
-
- { Lädt Zeichentreiber im Format .SYS bzw. .COM zu beliebigen Zeitpunkten.
-
- Aufruf: DRVLOAD [HI] <Treiber-Datei> [Treiber-Parameter...]
- }
-
-
- Function UpString(s: String): String;
- var x: Integer;
- begin
- for x := 1 to Length(s) do UpString[x] := Upcase(s[x]);
- UpString[0] := s[0];
- end;
-
- var
- OrgStrat: Byte; OrgLink: Boolean;
- Procedure ErrOut(Msg: String);
- begin
- Writeln(Msg);
- SetUMBLink(OrgLink); SetAllocStrat(OrgStrat);
- Halt;
- end;
-
- var
- DrvInitBlock: Record { Parameterblock für "Init" }
- DSize: Byte; { Größe des gesamten Blocks }
- DUnit: Byte; { Geräte-Kennziffer (relativ) }
- DFunc: Byte; { Funktionsnummer ($00) }
- DStatus: Word; { Status als Ergebnis }
- DResvd: Array[0..7] of Byte;
- { --- Funktionsabhängige Felder --- }
- DUnits: Byte; { Anzahl Laufwerke (nur für Block) }
- DEndAddr: Pointer; { Endadresse, vom Treiber gesetzt }
- DCmdLine: Pointer; { Adresse der "Kommandozeile" }
- DFirstDrv: Byte; { Kennziffer erstes Laufwerk (nur Block) }
- DMsgFlag: Word; { für Fehlermeldungen des Treibers }
- end;
-
- DriverCmd: String; { Kommandozeile für den Treiber }
- DriverName, HiCmd: String;
- F: File;
- FSize: Word; { Größe der Datei in Bytes }
- x, ParmStart: Integer;
- DriverSeg,DriverSize: Word;
- DriverHead, NULDev,NextDev: DriverPointer;
- DriverMCB : MCBPtr;
- FileHead : Record { nur für DR-DOS }
- ID,Remainder,Pages,RelocItems,HdSize: Word;
- end;
- begin
- Writeln('DRVLOAD (c) 6/91 as');
- if (ParamCount = 0) or (ParamStr(1) = '/?') or
- (ParamStr(1) = '/H') then
- begin
- Writeln('Aufruf: DRVLOAD [HI] <Zeichentreiber-Datei> ',
- '[Treiber-Parameter...]');
- Writeln('Lädt Zeichentreiber ohne Neustart des Systems.');
- Halt;
- end;
-
- { Speicherverteilungskonzept festhalten und Prüfung auf
- Kommandozeilen-Parameter 'HI' }
- OrgStrat := GetAllocStrat; OrgLink := GetUMBLink;
- DriverName := UpString(ParamStr(1));
- SetAllocStrat(2); { Treiber auf jeden Fall ans Ende }
- if DriverName = 'HI' then
- begin { UMB mit einbinden, soweit möglich }
- SetUMBLink(TRUE); DriverName := UpString(ParamStr(2));
- ParmStart := 3;
- end else ParmStart := 2;
-
- { Haben wir es mit einer .EXE-Datei zu tun? }
- if Pos('.EXE',DriverName) <> 0
- then ErrOut('Geht leider nicht für .EXE-Dateien!');
-
- { Datei öffnen und erst einmal prüfen }
- Assign(F,DriverName); {$I-} Reset(F,1); {$I+}
- if IOResult <> 0
- then ErrOut('Datei '+DriverName+' nicht gefunden.');
- FSize := FileSize(F);
- { Die ersten 10 Bytes lesen }
- BlockRead(F,FileHead,Sizeof(FileHead));
- if FileHead.ID <> $FFFF then { Treiberkopf? }
- begin
- if (Swap(DosVersion) = $0329) or (Swap(DosVersion) = $0332) then
- with FileHead do
- begin { DR-DOS 3.41 oder 5.0 }
- if (ID <> $5A4D) or (RelocItems <> 0) { .EXE-Signatur,RelocTbl }
- then ErrOut('DR-DOS: als .SYS getarnte .EXE-Datei');
- Dec(FSize,HdSize*16); { Dateigröße minus Kopf }
- Seek(F,HdSize*16); { Position hinter Dateikopf }
- BlockRead(F,FileHead,Sizeof(FileHead)); { die ersten 10 Bytes }
- end
- else ErrOut('MS-DOS: Treiber ist .EXE-Datei!');
- end;
-
- DriverSeg := GetMemBlock(FSize); DriverHead := Ptr(DriverSeg,0);
- if DosError <> 0 { haben wir genug Platz? }
- then ErrOut('Nicht genug Platz im Hauptspeicher!');
-
- Move(FileHead,DriverHead^,Sizeof(FileHead)); { 10 Bytes kopieren }
- BlockRead(F,Ptr(DriverSeg,Sizeof(FileHead))^,
- FSize-Sizeof(FileHead)); { Datei einlesen }
- if (DriverHead^.DAttr and $8000) = 0 then
- begin
- FreeMemBlock(DriverSeg);
- ErrOut(DriverName + ' ist kein Zeichentreiber!');
- end;
-
- { Treiber in die Kette einbauen }
- NULDev := GetFirstHeader; NextDev := NulDev^.DNext;
- DriverHead^.DNext := NextDev; NULDev^.DNext := DriverHead;
-
- { Kommandozeile zusammensetzen und Parameterblock erstellen }
- DriverCmd := DriverName;
- for x := ParmStart to ParamCount
- do DriverCmd := DriverCmd + ' ' + ParamStr(x);
- DriverCmd := DriverCmd + #13#10; { CR/LF anhängen }
-
- FillChar(DrvInitBlock,Sizeof(DrvInitBlock),0);
- with DrvInitBlock do
- begin
- DSize := Sizeof(DrvInitBlock);
- DFunc := 0; { eigentlich unnötig }
- DCmdLine := Addr(DriverCmd[1]); { hinter dem Längenbyte }
- DEndAddr := Ptr(DriverSeg+FSize div 16,0); { verfügbarer Platz }
-
- CallStrategy(DriverHead,@DrvInitBlock); { Übergabe }
- CallInterrupt(DriverHead); { und Ausführung }
-
- if ((DStatus and $8000) <> 0) { or (DStatus and $0100 = 0)} then
- begin { Fehler! }
- NULDev^.DNext := NextDev; { Treiber aus der Kette raus }
- FreeMemBlock(DriverSeg);
- ErrOut('Fehler bei der Initialisierung!');
- end;
- DriverSize := (LongInt((Seg(DEndAddr^) - DriverSeg))*16
- + Ofs(DEndAddr^)+$0F) div 16;
- SetMemBlock(DriverSeg,DriverSize);
- DriverMCB := Ptr(DriverSeg-1,0);
- DriverMCB^.OwnerPSP := DriverSeg;
- for x:= 1 to 8 do DriverMCB^.OwnerID[x] := DriverHead^.Name[x];
-
- Write('Treiber ',DriverName, ' (Gerätename ');
- for x:= 1 to 8 do Write(DriverHead^.Name[x]);
- Writeln(') geladen.');
- end;
- SetAllocStrat(OrgStrat); SetUMBLink(OrgLink);
- end.
-