📄 mkdrv.c
字号:
/*
mkdrv driver_file [ [(-|/)flags] service ]*
Make driver_file from the given services.
Valid service file extensions are:
.kbd
.csd
.gsd
.prd
.gpd
.syd
.scd
Valid flags are: L[fsrp] (default is Lfs).
f => fixed
s => standard, dual mode (real+protect)
r => standard service, real mode only
p => standard service, protect mode only
ex. mkdrv dos3.drv -Lfs std3.kbd -Lf std3.prd
See "Installable Drivers Interface (1.00.01)" and "API Guide
Installable Drivers (2.20.02)" for more details.
Revision history:
88.03.24 mikedon original
88-04-22 scottra add real/protect, general extensions, ...
88-07-12 johng add SCD (indtSerialComm)
*/
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <fcntl.h>
#include <memory.h>
#include <cow.h>
#include <indrv.h>
#define floadDefault (floadFixed | floadStandard | floadAnyMode)
#define lcbCodeMax ((long)(65535 - sizeof(INSH)))
#define iindsMax 20
#define cbBuffMax (8 * 1024)
char rgb[cbBuffMax];
unsigned cbBuff = 0;
int fload;
char szMagic[5] = szMagicDRV;
typedef struct
{
char * sz;
WORD indt;
} SVI; /* service info */
SVI rgsvi[] =
{
{ ".kbd", indtKeyboard },
{ ".csd", indtCharacterScreen },
{ ".gsd", indtGraphicScreen },
{ ".prd", indtCharacterPrinter },
{ ".gpd", indtGraphicPrinter },
{ ".syd", indtSystem },
{ ".scd", indtSerialComm },
{ NULL, indtNil }
};
void main(int, char *([]));
char IndtFromSzFile(char *);
void SetFlagsSz(char *);
void SetFlagsDefaults();
void OutputFlush(int);
void OutputHFile(int, int, unsigned long);
void OutputB(int, void *, unsigned);
void OutputTableHead(int, unsigned);
void OutputPinds(int, INDS *);
void OutputTail(int, unsigned long);
#define block /* block */
void
main(csz, rgsz)
int csz;
char *rgsz[];
{
char **hsz, **hszMax;
INDS rginds[iindsMax], *pinds, *pindsMax;
long lfaMac = 0;
int hFileOut;
unsigned cinds;
#ifdef DEBUG
block
{
/* display commandline parameters */
int i;
for (i = 0; i < csz; i++)
{
printf("%s\n", rgsz[i]);
}
}
#endif
/* check usage */
if (csz <= 1)
{
printf("\nUsage: mkdrv output_file [[-Lfds] service]*\n");
exit(1);
}
/* open output file */
hFileOut = open(rgsz[1], O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IWRITE);
if (hFileOut == -1)
{
printf("cannot write %s\n", rgsz[1]);
exit(5);
}
/* process given parameters */
hszMax = &(rgsz[csz]);
pindsMax = &(rginds[iindsMax]);
SetFlagsDefaults();
for ( hsz = &(rgsz[2]), pinds = rginds;
hsz < hszMax && pinds < pindsMax;
hsz++)
{
char ch;
if ((ch = **hsz) == '-' || ch == '/')
{
/* process flags */
SetFlagsSz(*hsz + 1);
}
else
{
/* assume we have a file name of a service, process it */
int hFile;
long lcbCode;
hFile = open(*hsz, O_BINARY | O_RDONLY);
if (hFile == -1)
{
printf("cannot read %s\n", *hsz);
exit(2);
}
lcbCode = filelength(hFile);
if (lcbCode > lcbCodeMax)
{
printf("%s is too big (%l > %l)\n", *hsz, lcbCode, lcbCodeMax);
exit(3);
}
/* build INDS record for this service */
if ((pinds->indt = IndtFromSzFile(*hsz)) == indtNil)
{
printf("warning: %s is an unknown service\n", *hsz);
}
pinds->fload = (fload == 0) ? floadDefault : fload;
pinds->cbCode = (int)lcbCode;
pinds++;
/* transfer service to output file */
OutputHFile(hFileOut, hFile, lcbCode);
lfaMac += lcbCode;
SetFlagsDefaults();
}
}
/* check for too many services */
if (hsz < hszMax)
{
printf("too many services (%d max)\n", iindsMax);
exit(4);
}
/* output master table */
pindsMax = pinds;
cinds = pindsMax - rginds;
OutputTableHead(hFileOut, cinds);
block
{
/* output INDS records */
long dlfa = 0;
while (pinds-- > rginds)
{
dlfa += pinds->cbCode;
pinds->dlfaCode = dlfa;
OutputPinds(hFileOut, pinds);
}
}
/* output file end header (INDH) */
OutputTail(hFileOut, (unsigned long)(sizeof(INDT) + (cinds - 1) * sizeof(INDS) + sizeof(INDH)));
/* cinds - 1: 1 INDS already in INDT */
OutputFlush(hFileOut);
close(hFileOut);
exit(0);
}
void
SetFlagsDefaults()
{
fload = 0;
}
void
SetFlagsSz(pch)
char *pch;
{
/* set flag values accordingly */
char ch = *pch;
if (ch == 'L')
{
++pch;
while ((ch = *pch++) != '\0')
{
if (ch == 'f')
fload |= floadFixed;
else if (ch == 's')
fload |= floadStandard | floadAnyMode;
else if (ch == 'r')
fload |= floadStandard | floadRealMode;
else if (ch == 'p')
fload |= floadStandard | floadProtMode;
else
printf("bad load flag: %c\n", ch);
}
}
else
{
printf("unknown flag: %c\n", ch);
}
}
char
IndtFromSzFile(szFile)
char *szFile;
{
/* return service type based on extension of service name
(valid service names are assumed to be .xxx)
*/
unsigned cch = strlen(szFile);
char *pchExt;
char szExt[5];
SVI * psvi;
if (cch < 4)
{
return(indtNil);
}
block
{
/* lower the file extension */
char *pch = szExt;
char *pchExtMax = szFile + cch;
for (pchExt = pchExtMax - 4; pchExt < pchExtMax;)
{
*pch++ = tolower(*pchExt);
pchExt++;
}
szExt[4] = '\0';
pchExt = szExt;
}
/* determine service type */
for (psvi = rgsvi; psvi->sz != NULL; psvi++)
if (strcmp(pchExt, psvi->sz) == 0)
return(psvi->indt);
return(indtNil);
}
/* Output Routines:
Nothing is flushed from the buffer until it is filled. Only
OutputFlush does a write. OutputHFile and OutputB transfer
data to the buffer and flush accordingly.
*/
void
OutputFlush(hFile)
int hFile;
{
if (cbBuff > 0 && cbBuff != write(hFile, rgb, cbBuff))
{
printf("...write error\n");
exit(10);
}
#ifdef DEBUG
printf("wrote %u bytes\n", cbBuff);
#endif
cbBuff = 0;
}
void
OutputHFile(hFileOut, hFile, lcb)
int hFileOut;
int hFile;
unsigned long lcb;
{
unsigned cbRead;
#ifdef DEBUG
printf("process %lu bytes\n", lcb);
#endif
while (lcb > 0)
{
if (cbBuff >= cbBuffMax)
{
OutputFlush(hFileOut);
}
cbRead = cbBuffMax - cbBuff;
if ((unsigned long )cbRead > lcb)
{
cbRead = (int)lcb;
}
if (cbRead != read(hFile, &(rgb[cbBuff]), cbRead))
{
printf("...read error\n");
exit(20);
}
#ifdef DEBUG
printf("read %u bytes\n", cbRead);
#endif
cbBuff += cbRead;
lcb -= cbRead;
}
}
void
OutputB(hFile, pb, cb)
int hFile;
void *pb;
unsigned cb;
{
unsigned cbMove;
#ifdef DEBUG
printf("transfer %u bytes\n", cb);
#endif
while (cb > 0)
{
if (cbBuff >= cbBuffMax)
{
OutputFlush(hFile);
}
cbMove = cbBuffMax - cbBuff;
if (cbMove > cb)
{
cbMove = cb;
}
memcpy(&(rgb[cbBuff]), pb, cbMove);
cbBuff += cbMove;
cb -= cbMove;
}
}
void
OutputTableHead(hFileOut, cinds)
int hFileOut;
unsigned cinds;
{
INDT indt;
memcpy(indt.rgchMagic, szMagic, 4);
indt.cinds = cinds;
#ifdef DEBUG
printf("INDT: magic:%c%c%c%c, cinds:%u\n", indt.rgchMagic[0],
indt.rgchMagic[1],
indt.rgchMagic[2],
indt.rgchMagic[3],
indt.cinds);
#endif
OutputB(hFileOut, &indt, sizeof(INDT) - sizeof(INDS));
/* do not include the INDS in INDT */
}
void
OutputPinds(hFileOut, pinds)
int hFileOut;
INDS *pinds;
{
#ifdef DEBUG
printf("INDS: indt:%u, fload:%u, cbCode:%u, dlfaCode:%lu\n", pinds->indt, pinds->fload,
pinds->cbCode, pinds->dlfaCode);
#endif
OutputB(hFileOut, pinds, sizeof(INDS));
}
void
OutputTail(hFileOut, dlfa)
int hFileOut;
unsigned long dlfa;
{
INDH indh;
memcpy(indh.rgchMagic, szMagic, 4);
indh.dlfaTable = dlfa;
#ifdef DEBUG
printf("INDH: magic:%c%c%c%c, dlfaTable:%lu\n", indh.rgchMagic[0],
indh.rgchMagic[1],
indh.rgchMagic[2],
indh.rgchMagic[3],
indh.dlfaTable);
#endif
OutputB(hFileOut, &indh, sizeof(indh));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -