home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
dtx9203
/
driver
/
drvload.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-06
|
6KB
|
167 lines
/* 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;
}