home *** CD-ROM | disk | FTP | other *** search
- /* DRVLOAD.C */
- /* HINWEIS: Benötigt das Modul DOSLIB.OBJ, das zuvor mit TASM /MX DOSLIB
- übersetzt worden sein muß.
- */
- #include <stdio.h>
- #include <dos.h>
- #include <io.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include "drvlib.inc"
- #include "doslib.h"
-
- /* Lädt Zeichentreiber im Format .SYS bzw. .COM zu
- beliebigen Zeitpunkten und muß mit einer .PRJ-Datei
- bzw. dem folgenden Befehl erstellt werden:
-
- TCC -mc drvload doslib.lib
-
- Aufruf: DRVLOAD [HI] <Treiber-Datei> [Treiber-Parameter...]
- */
-
- /* Umsetzen eines Strings in Großbuchstaben, für Vergleiche */
- char *UpString(char *s)
- { char *p;
-
- for (p = s; *p; p++)
- *p = toupper(*p);
- return s;
- }
-
- /* Ermittelt die Größe der Treiberdatei */
- long FileSize(int Handle)
- { long Res;
- long CurrPos = tell(Handle);
-
- Res = lseek(Handle,0L,SEEK_END); /* Dateiende */
- lseek(Handle,CurrPos,SEEK_SET); /* Position zurück */
- return Res;
- }
-
- unsigned char OrgStrat, OrgLink; /* Speicherkonzept */
-
- /* Bricht das Programm mit Ausgabe einer Fehlermeldung ab */
- void ErrOut(char *Fmt, char *Msg)
- {
- printf(Fmt, Msg);
- SetUMBLink(OrgLink); SetAllocStrat(OrgStrat);
- exit(1);
- }
-
- struct /* Parameterblock für die Treiberfunktion 0x00 (Init) */
- { unsigned char DSize; /* Größe des Parameterblocks */
- unsigned char DUnit; /* Laufwerk (Treiber-relativ) */
- unsigned char DFunc; /* Funktionsnummer (0x00) */
- unsigned DStatus; /* Ergebnis */
- char DResvd[8]; /* "reserviert", nicht benutzt */
- unsigned char DUnits; /* Anzahl Laufwerke (nur Block) */
- void far *DEndAddr; /* Endadresse, vom Treiber gesetzt */
- void far *DCmdLine; /* Adresse der "Kommandozeile" */
- unsigned char DFirstDrv; /* erstes Laufwerk (nur Block) */
- unsigned DMsgFlag; /* für Fehlermeldungen des Treibers */
- } DrvInitBlock;
-
- int main(int argc, char *argv[])
- { char DriverCmd[127]; /* Kommandozeile für den Treiber */
- char DriverName[127]; /* Treiber-Dateiname */
- int FHandle; /* zum Lesen der Treiberdatei */
- int x, ParmStart;
- unsigned DriverSeg, DriverSize; /* Segment, Größe des Treibers */
- DriverPointer DriverHead, NULDev, NextDev; /* Treiber-Kette */
- MCBPtr DriverMCB; /* MCB des neu geladenen Treibers */
- unsigned FSize; /* Dateigröße */
- struct
- { unsigned ID, Remainder, Pages, RelocItems,HDSize;
- } FileHead; /* nur für DR-DOS */
-
- printf("DRVLOAD (c) JUL-91 as\n");
- if (argc < 2 || !strcmp(argv[1],"/?") || !strcmp(argv[1],"/H"))
- { printf("Aufruf: DRVLOAD [HI] <Zeichentreiber-Datei> "
- "[Parameter...]\n"
- "Lädt Zeichentreiber ohne Neustart des Systems.\n");
- return 0;
- }
-
- /* Speicherverteilungskonzept festhalten und Prüfung auf HI */
- OrgStrat = GetAllocStrat(); OrgLink = GetUMBLink();
- if (!strcmp(UpString(strcpy(DriverName,argv[1])),"HI"))
- { SetUMBLink(1);
- UpString(strcpy(DriverName,argv[2]));
- ParmStart = 3;
- } else ParmStart = 2;
- SetAllocStrat(2); /* von oben nach unten */
-
- /* Haben wir es mit einer .EXE-Datei zu tun? */
- if (strstr(DriverName,".EXE"))
- ErrOut("%s\n", "Geht leider nicht für .EXE-Dateien!");
-
- /* Datei öffnen, Platz im Hauptspeicher belegen und einlesen */
- if ((FHandle = open(DriverName,O_RDONLY)) == -1)
- ErrOut("%s - Datei nicht gefunden.\n", DriverName);
- FSize = FileSize(FHandle); /* Größe der Datei */
- /* Die ersten 10 Bytes lesen */
- _read(FHandle,&FileHead,sizeof(FileHead));
- if (FileHead.ID != 0xFFFF)
- if (DosVersion() == 0x2903 || DosVersion() == 0x3203)
- { /* DR-DOS 3.41 oder DR-DOS 5.0 */
- if (FileHead.ID != 0x5A4D || FileHead.RelocItems) /* .EXE-Signatur */
- ErrOut("DR-DOS: als .SYS getarnte .EXE-Datei!\n","");
- FSize -= FileHead.HDSize * 16; /* Dateigröße minus Kopf */
- lseek(FHandle,FileHead.HDSize*16,SEEK_SET); /* hinter den Kopf */
- _read(FHandle,&FileHead,sizeof(FileHead)); /* erste echte 10 Bytes */
- }
- else ErrOut("MS-DOS: keine einfache Treiber-Datei!\n", "");
- allocmem((FSize + 0x0F) / 16, &DriverSeg);
- if (_doserrno) ErrOut("%s\n", "Nicht genug Platz im Hauptspeicher!");
- DriverHead = MK_FP(DriverSeg,0);
- memmove(DriverHead,&FileHead,sizeof(FileHead)); /* 10 Bytes kopieren */
- _read(FHandle,MK_FP(DriverSeg,sizeof(FileHead)),FSize-sizeof(FileHead));
-
- if (!(DriverHead->DAttr & 0x8000))
- { freemem(DriverSeg);
- ErrOut("%s ist kein Zeichentreiber!\n", DriverName);
- }
-
- /* Treiber in die Kette einbauen */
- DriverHead->DNext = NextDev
- = (NULDev = GetFirstHeader())->DNext;
- NULDev->DNext = DriverHead;
-
- /* Kommandozeile zusammensetzen und Parameterblock erstellen */
- strcpy(DriverCmd, DriverName);
- for (x = ParmStart; x < argc; x++)
- strcat(strcat(DriverCmd," "),argv[x]);
- strcat(DriverCmd,"\r\n"); /* CR/LF hintendran */
-
- memset(&DrvInitBlock,0,sizeof(DrvInitBlock));
- DrvInitBlock.DSize = sizeof(DrvInitBlock);
- DrvInitBlock.DFunc = 0; /* eigentlich unnötig */
- DrvInitBlock.DCmdLine = DriverCmd; /* Kommandozeile */
- DrvInitBlock.DEndAddr = MK_FP(DriverSeg,FSize);
-
- CallStrategy(DriverHead,&DrvInitBlock); /* Übergabe */
- CallInterrupt(DriverHead); /* und Ausführung */
-
- if (DrvInitBlock.DStatus & 0x8000 || !(DrvInitBlock.DStatus & 0x0100))
- { NULDev->DNext = NextDev; /* Treiber aus der Kette entfernen */
- freemem(DriverSeg); /* Freigabe des Speicherbereichs */
- ErrOut("Status: 0x%04X - Fehler bei der Initialisierung!\n",
- (char *)DrvInitBlock.DStatus);
- }
-
- /* Speicherblock auf die tatsächlich benötigte Größe setzen */
- DriverSize = (((long)FP_SEG(DrvInitBlock.DEndAddr)-DriverSeg)*16 +
- FP_OFF(DrvInitBlock.DEndAddr)+0x0F) / 16;
- setblock(DriverSeg,DriverSize);
- DriverMCB = MK_FP(DriverSeg-1,0); /* und MCB "fälschen" */
- DriverMCB->OwnerPSP = DriverSeg;
- printf("Treiber %s (Gerätename ", DriverName);
- for (x = 0; x < 8; x++) /* Eintrag des Namens (Optik) */
- putchar(DriverMCB->OwnerID[x] = DriverHead->NameOrUnits[x]);
- printf(") geladen.\n");
-
- SetAllocStrat(OrgStrat); SetUMBLink(OrgLink);
- return 0;
- }
-