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

  1. /* DRVLOAD.C */
  2. /* HINWEIS: Benötigt das Modul DOSLIB.OBJ, das zuvor mit TASM /MX DOSLIB
  3.    übersetzt worden sein muß.
  4. */
  5. #include <stdio.h>
  6. #include <dos.h>
  7. #include <io.h>
  8. #include <fcntl.h>
  9. #include <ctype.h>
  10. #include <stdlib.h>
  11. #include "drvlib.inc"
  12. #include "doslib.h"
  13.  
  14. /* Lädt Zeichentreiber im Format .SYS bzw. .COM zu
  15.    beliebigen Zeitpunkten und muß mit einer .PRJ-Datei
  16.    bzw. dem folgenden Befehl erstellt werden:
  17.  
  18.    TCC -mc drvload doslib.lib
  19.  
  20.    Aufruf: DRVLOAD [HI] <Treiber-Datei> [Treiber-Parameter...]
  21. */
  22.  
  23. /* Umsetzen eines Strings in Großbuchstaben, für Vergleiche */
  24. char *UpString(char *s)
  25. { char *p;
  26.  
  27.   for (p = s; *p; p++)
  28.     *p = toupper(*p);
  29.   return s;
  30. }
  31.  
  32. /* Ermittelt die Größe der Treiberdatei */
  33. long FileSize(int Handle)
  34. { long Res;
  35.   long CurrPos = tell(Handle);
  36.  
  37.   Res = lseek(Handle,0L,SEEK_END);  /* Dateiende */
  38.   lseek(Handle,CurrPos,SEEK_SET);   /* Position zurück */
  39.   return Res;
  40. }
  41.  
  42. unsigned char OrgStrat, OrgLink;  /* Speicherkonzept */
  43.  
  44. /* Bricht das Programm mit Ausgabe einer Fehlermeldung ab */
  45. void ErrOut(char *Fmt, char *Msg)
  46. {
  47.   printf(Fmt, Msg);
  48.   SetUMBLink(OrgLink); SetAllocStrat(OrgStrat);
  49.   exit(1);
  50. }
  51.  
  52. struct   /* Parameterblock für die Treiberfunktion 0x00 (Init) */
  53.  { unsigned char DSize;    /* Größe des Parameterblocks */
  54.    unsigned char DUnit;    /* Laufwerk (Treiber-relativ) */
  55.    unsigned char DFunc;    /* Funktionsnummer (0x00) */
  56.    unsigned DStatus;       /* Ergebnis */
  57.    char DResvd[8];         /* "reserviert", nicht benutzt */
  58.    unsigned char DUnits;   /* Anzahl Laufwerke (nur Block) */
  59.    void far *DEndAddr;     /* Endadresse, vom Treiber gesetzt */
  60.    void far *DCmdLine;     /* Adresse der "Kommandozeile" */
  61.    unsigned char DFirstDrv; /* erstes Laufwerk (nur Block) */
  62.    unsigned DMsgFlag;     /* für Fehlermeldungen des Treibers */
  63.  } DrvInitBlock;
  64.  
  65. int main(int argc, char *argv[])
  66. { char DriverCmd[127];   /* Kommandozeile für den Treiber */
  67.   char DriverName[127];  /* Treiber-Dateiname */
  68.   int FHandle;          /* zum Lesen der Treiberdatei */
  69.   int x, ParmStart;
  70.   unsigned DriverSeg, DriverSize;  /* Segment, Größe des Treibers */
  71.   DriverPointer DriverHead, NULDev, NextDev; /* Treiber-Kette */
  72.   MCBPtr DriverMCB;   /* MCB des neu geladenen Treibers */
  73.   unsigned FSize;     /* Dateigröße */
  74.   struct
  75.    { unsigned ID, Remainder, Pages, RelocItems,HDSize;
  76.    } FileHead;   /* nur für DR-DOS */
  77.  
  78.   printf("DRVLOAD (c) JUL-91 as\n");
  79.   if (argc < 2 || !strcmp(argv[1],"/?") || !strcmp(argv[1],"/H"))
  80.    { printf("Aufruf: DRVLOAD [HI] <Zeichentreiber-Datei> "
  81.             "[Parameter...]\n"
  82.             "Lädt Zeichentreiber ohne Neustart des Systems.\n");
  83.      return 0;
  84.    }
  85.  
  86.   /* Speicherverteilungskonzept festhalten und Prüfung auf HI */
  87.   OrgStrat = GetAllocStrat(); OrgLink = GetUMBLink();
  88.   if (!strcmp(UpString(strcpy(DriverName,argv[1])),"HI"))
  89.    { SetUMBLink(1);
  90.      UpString(strcpy(DriverName,argv[2]));
  91.      ParmStart = 3;
  92.    } else ParmStart = 2;
  93.   SetAllocStrat(2);  /* von oben nach unten */
  94.  
  95.   /* Haben wir es mit einer .EXE-Datei zu tun? */
  96.   if (strstr(DriverName,".EXE"))
  97.    ErrOut("%s\n", "Geht leider nicht für .EXE-Dateien!");
  98.  
  99.   /* Datei öffnen, Platz im Hauptspeicher belegen und einlesen */
  100.   if ((FHandle = open(DriverName,O_RDONLY)) == -1)
  101.     ErrOut("%s - Datei nicht gefunden.\n", DriverName);
  102.   FSize = FileSize(FHandle);  /* Größe der Datei */
  103.   /* Die ersten 10 Bytes lesen */
  104.   _read(FHandle,&FileHead,sizeof(FileHead));
  105.   if (FileHead.ID != 0xFFFF)
  106.     if (DosVersion() == 0x2903 || DosVersion() == 0x3203)
  107.       {  /* DR-DOS 3.41 oder DR-DOS 5.0 */
  108.      if (FileHead.ID != 0x5A4D || FileHead.RelocItems) /* .EXE-Signatur */
  109.        ErrOut("DR-DOS: als .SYS getarnte .EXE-Datei!\n","");
  110.      FSize -= FileHead.HDSize * 16;  /* Dateigröße minus Kopf */
  111.      lseek(FHandle,FileHead.HDSize*16,SEEK_SET); /* hinter den Kopf */
  112.      _read(FHandle,&FileHead,sizeof(FileHead)); /* erste echte 10 Bytes */
  113.       }
  114.      else ErrOut("MS-DOS: keine einfache Treiber-Datei!\n", "");
  115.   allocmem((FSize + 0x0F) / 16, &DriverSeg);
  116.   if (_doserrno) ErrOut("%s\n", "Nicht genug Platz im Hauptspeicher!");
  117.   DriverHead = MK_FP(DriverSeg,0);
  118.   memmove(DriverHead,&FileHead,sizeof(FileHead)); /* 10 Bytes kopieren */
  119.   _read(FHandle,MK_FP(DriverSeg,sizeof(FileHead)),FSize-sizeof(FileHead));
  120.  
  121.   if (!(DriverHead->DAttr & 0x8000))
  122.    { freemem(DriverSeg);
  123.      ErrOut("%s ist kein Zeichentreiber!\n", DriverName);
  124.    }
  125.  
  126.   /* Treiber in die Kette einbauen */
  127.   DriverHead->DNext = NextDev
  128.     = (NULDev = GetFirstHeader())->DNext;
  129.   NULDev->DNext = DriverHead;
  130.  
  131.   /* Kommandozeile zusammensetzen und Parameterblock erstellen */
  132.   strcpy(DriverCmd, DriverName);
  133.   for (x = ParmStart; x < argc; x++)
  134.    strcat(strcat(DriverCmd," "),argv[x]);
  135.   strcat(DriverCmd,"\r\n");   /* CR/LF hintendran */
  136.  
  137.   memset(&DrvInitBlock,0,sizeof(DrvInitBlock));
  138.   DrvInitBlock.DSize = sizeof(DrvInitBlock);
  139.   DrvInitBlock.DFunc = 0;  /* eigentlich unnötig */
  140.   DrvInitBlock.DCmdLine = DriverCmd; /* Kommandozeile */
  141.   DrvInitBlock.DEndAddr = MK_FP(DriverSeg,FSize);
  142.  
  143.   CallStrategy(DriverHead,&DrvInitBlock);  /* Übergabe */
  144.   CallInterrupt(DriverHead);  /* und Ausführung */
  145.  
  146.   if (DrvInitBlock.DStatus & 0x8000 || !(DrvInitBlock.DStatus & 0x0100))
  147.    { NULDev->DNext = NextDev;  /* Treiber aus der Kette entfernen */
  148.      freemem(DriverSeg);  /* Freigabe des Speicherbereichs */
  149.      ErrOut("Status: 0x%04X - Fehler bei der Initialisierung!\n",
  150.              (char *)DrvInitBlock.DStatus);
  151.    }
  152.  
  153.   /* Speicherblock auf die tatsächlich benötigte Größe setzen */
  154.   DriverSize = (((long)FP_SEG(DrvInitBlock.DEndAddr)-DriverSeg)*16 +
  155.                  FP_OFF(DrvInitBlock.DEndAddr)+0x0F) / 16;
  156.   setblock(DriverSeg,DriverSize);
  157.   DriverMCB = MK_FP(DriverSeg-1,0);  /* und MCB "fälschen" */
  158.   DriverMCB->OwnerPSP = DriverSeg;
  159.   printf("Treiber %s (Gerätename ", DriverName);
  160.   for (x = 0; x < 8; x++)   /* Eintrag des Namens (Optik) */
  161.     putchar(DriverMCB->OwnerID[x] = DriverHead->NameOrUnits[x]);
  162.   printf(") geladen.\n");
  163.  
  164.   SetAllocStrat(OrgStrat); SetUMBLink(OrgLink);
  165.   return 0;
  166. }
  167.