File Archive

 
Output of file : CVTTRC.C contained in archive : CVTTRC.ZIP

/* cvttrc.c - MSC V4.0 version
* Copyright 1987 Jim Kyle - All Rights Reserved
* 16 June 1987
*
* This program gathers all pertinent data from the CVT kept by
* MSDOS in the low portion of the DOS kernel, and reports it via
* the STDOUT stream so that the report may be captured or sent
* to a printer. Its major value, however, is to document the
* structure of the CVT, the information it contains, and a method
* for accessing it that is as version-independent as possible.
*
* The program, and the information it contains, may be freely
* distributed and used so long as this entire comment section
* is not altered.
*/

#include
#include
#include

union REGS b; /* defined in DOS.H for intdosx() use */
struct SREGS s;

struct farp { /* Far-Pointer detail */
unsigned o; /* offset */
unsigned s; /* segment */
};

union fpu { /* Pointers for tracing the chain */
struct CVT far * base;
struct bcb far * bcbp;
struct mcb far * mcbp;
struct pdt far * pdtp;
struct chn far * chnp;
struct ldt far * ldtp;
char far * cfp;
int far * ifp;
struct farp fp;
} u;

/* The CVT is located at the very front of the DOS kernel in both 2.x
* and 3.x, but varies between the two versions. The listing below is
* for the 3.x version.
*/

struct CVT { /* Configuration Variable Table */
struct bcb far * curbfr;
struct mcb far * memchn;
struct pdt far * pdrvs;
struct chn far * dcbchn;
char far * clkdev;
char far * condev;
int secsiz;
struct bcb far * bfrchn;
struct ldt far * ldrvs;
struct chn far * fcbchn;
int filler;
char npdrvs;
char nldrvs;
} far * cvtbase;

struct bcb { /* Buffer Control Block format */
union fpu nxcb; /* +00 next one in chain */
char ldrv; /* +04 logical drive code */
char action; /* +05 action code */
unsigned lsect; /* +06 logical sector # */
char nf; /* +08 nbr FATs or 01 */
char secf; /* +09 sectors/FAT or 00 */
char far * pdrv; /* +0A phys drv tbl ptr */
int fill; /* +0E unknown */
unsigned char buf[512]; /* +10 the buffer itself */
} far * curbuf;

struct mcb { /* Mem Alloc Block header format */
char flag; /* +00 must be M or Z */
unsigned owner; /* +01 PSP seg or 0000 */
unsigned siz; /* +03 Number paragraphs */
} far * curmcb;

struct pdt { /* Physical Drive Table format */
char drvc; /* +00 drive code */
char unit; /* +01 unit number */
int bps; /* +02 bytes per sector */
char spc; /* +04 sec per cluster -1 */
char pwr2; /* +05 power of 2 */
int rsrvs; /* +06 reserved sectors */
char nfats; /* +08 number of FATs */
unsigned dirsiz; /* +09 root dir size */
unsigned fus; /* +0B first usable sectr */
unsigned tcc; /* +0D total clstr ct +1 */
char spf; /* +0F sec per FAT */
unsigned fds; /* +10 first dir sector */
char far * drvr; /* +12 driver pointer */
unsigned char mcode; /* +16 media code */
char accflg; /* +17 access flag */
union fpu nxt; /* +18 next table ptr */
unsigned lastused; /* +1C last used cluster */
unsigned filler; /* +1E usually FFFF */
} far * curpdt;

struct chn { /* Chain links for DCB, FCB chains */
union fpu nxtlnk; /* +00 next link or FFFF */
int nmbr; /* +04 number blocks here */
} far * curchn;

struct dcb { /* Device Control Block format */
int nusers; /* +00 users for this */
int mode; /* +02 0,1,2 per OPEN */
char datrb; /* +04 disk attrib byte */
char dvatr; /* +05 device attrib */
char atrb2; /* +06 2nd device attrib */
char far * pdrvr; /* +07 points to driver */
unsigned frstc; /* +0B first cluster nbr */
unsigned modtm; /* +0D file time word */
unsigned moddt; /* +0F file date word */
long totsiz; /* +11 total file size */
long curpos; /* +15 current byte pos */
unsigned clsctr; /* +19 total cluster ctr */
unsigned curcls; /* +1B current cluster */
unsigned dirsec; /* +1D directoryy sector */
char dirndx; /* +1F dir entry index */
char name[8]; /* +20 dev/file name */
char ext[3]; /* +28 file extension */
unsigned fill2; /* +2B unknown */
unsigned fill3; /* +2D unknown */
unsigned fill4; /* +2F unknown */
unsigned owner; /* +31 PSP of owner */
unsigned fill5; /* +33 unknown */
} far * curdcb, far * curfcb;

struct ldt { /* Logical Drive Table format */
char name[68]; /* +00 drive and path */
char code; /* +44 is 40 or 50... */
struct pdt far * mypdt; /* +45 PDT for this drive */
unsigned curdir; /* +49 directory sector */
unsigned filler2; /* +4B FFFF */
unsigned filler3; /* +4D FFFF */
unsigned filler4; /* +4F 0002 or 0008 */
} far * curldt;

int bcbctr, dcbctr; /* counters */

/* prototype declarations
*/
void bcbtrc(struct bcb far * );
void bcbrpt(struct bcb far * );
void dmp(unsigned char far * );
void pdttrc(struct pdt far * );
void pdtrpt(void);
void dcbtrc(char *, struct chn far * );
void dcbrpt(char *, int);
char * f_tm(unsigned);
char * f_dt(unsigned);
void memtrc(struct mcb far * );
void memrpt(unsigned,unsigned,unsigned);
char * memu(unsigned);

void main()
{ b.h.ah = 0x52; /* Get CVT pointer set up */
intdosx(&b,&b,&s); /* (using undocumented function) */
u.fp.o = b.x.bx - 8; /* offset of CVT base in DOS kernel */
u.fp.s = s.es; /* segment for DOS kernel */
cvtbase = u.base; /* hold pointer to CVT */

printf("\nCVT is located at %p\n----\n", cvtbase);
printf("No. of Phys Drives (at %p): %2d\n",
&cvtbase->npdrvs, cvtbase->npdrvs);
printf("No. of Log. Drives (at %p): %2d\n",
&cvtbase->nldrvs, cvtbase->nldrvs);
printf(" Clock Device (ptr at %p): %p\n",
&cvtbase->clkdev, cvtbase->clkdev);
printf(" CON Device (ptr at %p): %p\n",
&cvtbase->condev, cvtbase->condev);
printf(" Sector Size(?) (at %p): %04X\n",
&cvtbase->secsiz, cvtbase->secsiz);
printf(" Unknown word (at %p): %04X\n\n",
&cvtbase->filler, cvtbase->filler);
printf("1. Memory Chain (ptr at %p): %p\n",
&cvtbase->memchn, cvtbase->memchn);
printf("2. DCB Chain (ptr at %p): %p\n",
&cvtbase->dcbchn, cvtbase->dcbchn);
printf("3. PDT Chain (ptr at %p): %p\n",

&cvtbase->pdrvs, cvtbase->pdrvs);
printf("4. FCB Chain (ptr at %p): %p\n",
&cvtbase->fcbchn, cvtbase->fcbchn);
printf("5. LDT Chain (ptr at %p): %p\n",
&cvtbase->ldrvs, cvtbase->ldrvs);
printf("6. Current Buffer (ptr at %p): %p\n",
&cvtbase->curbfr, cvtbase->curbfr);
printf("7. Buffer Chain (ptr at %p): %p\n",
&cvtbase->bfrchn, cvtbase->bfrchn);

printf("\nTRACING MCB Chain===\n");
memtrc(cvtbase->memchn);

printf("\nTRACING DCB Chain===\n");
dcbtrc("DCB", cvtbase->dcbchn);

printf("\nTRACING PDT Chain===\n");
pdttrc(cvtbase->pdrvs);

printf("\nTRACING FCB Chain===\n");
dcbtrc("FCB", cvtbase->fcbchn);

printf("\nTRACING Current Buffer===\n");
bcbtrc(cvtbase->curbfr);

printf("\nTRACING Buffer Chain===\n");
bcbtrc(cvtbase->bfrchn);

exit(0);
}

void pdttrc(a) struct pdt far * a;
{ unsigned ofs;
curpdt = a;
ofs = 0;
printf ("\nPHYSICAL DRIVE DATA--\n");
while (ofs != (unsigned) 0xFFFF)
{ ofs = curpdt->nxt.fp.o;
pdtrpt ();
curpdt = curpdt->nxt.pdtp;
}
putchar(12);
}

void pdtrpt()
{ printf("\nDrive %c: (unit %d of driver at %p) media code = %02X\n",
curpdt->drvc+'A', curpdt->unit, curpdt->drvr, curpdt->mcode);
printf(" %3d bytes per sector,", curpdt->bps);
printf(" %d sectors per cluster,", curpdt->spc+1);
printf(" %5d total cluster count\n", curpdt->tcc-1);
printf(" Res sectors: %d ", curpdt->rsrvs);
printf(" %d FAT's, %d sec ea ", curpdt->nfats, curpdt->spf);
printf(" FAT entry: %d bits ", (curpdt->tcc)>0xFFC ? 16 : 12 );
printf(" Root: %d entries\n", curpdt->dirsiz);
printf(" First root sector: %04X", curpdt->fds );
printf(" First data sector: %04X", curpdt->fus );
printf(" Last cluster used: %04X.\n", curpdt->lastused);
}

void bcbtrc(a) struct bcb far * a;
{ unsigned ofs;
bcbctr = ofs = 0;
while (ofs != (unsigned) 0xFFFF)
{ ofs = a->nxcb.fp.o;
bcbrpt (a);
a = a->nxcb.bcbp;
}
putchar(12);
}

void bcbrpt(a) struct bcb far * a;
{ int i;
unsigned char far * x;
printf("\nBuffer Control Block %2d at %p\n", ++bcbctr, a);
printf(" Logical \'%c:\', Sector %04X Action code: %02X\n",
'A'+a->ldrv, a->lsect, a->action);
printf(" NFATS: %02X SPF: %02X PDT: %p FILL: %04X\n",
a->nf, a->secf, a->pdrv, a->fill);
x = &(a->buf[0]);
for (i=0; i<512; i+=16)
dmp(x+i);
}

void dmp(f) unsigned char far *f;
{ unsigned char far *x;
int i;
x = f;
printf("%p> ", f);
for (i=0; i<16; ++i)
printf("%02X%c",*x++,i==7 ? '-' : ' ');
printf(" ");
for (i=0; i<16; ++i)
printf("%c",((*(f+i))&'\x7F')>=' ' ? *(f+i) : '.');
putchar('\n');
}

void dcbtrc(t, a) char *t; struct chn far * a;
{ unsigned ofs;
curchn = a;
dcbctr = ofs = 0;
while (ofs != (unsigned) 0xFFFF)
{ ofs = curchn->nxtlnk.fp.o;
curdcb = (struct dcb far *)(&curchn[1]);
printf("\nLink at %p contains %d %ss--\n",
curchn, curchn->nmbr, t);
dcbrpt (t, curchn->nmbr);
curchn = curchn->nxtlnk.chnp;
}
putchar(12);
}

void dcbrpt(t, n) char *t; int n;
{ static char * actyp[] = {"READ", "WRITE", "R/W", "unknown"};
while (n)
{ if (curdcb->name[0])
{ printf("\n%s %2d, for %s \'",
t, dcbctr++, (curdcb->dvatr)&128 ? "device" : "file" );
printf("%c%c%c",
curdcb->name[0], curdcb->name[1], curdcb->name[2]);
printf("%c%c%c",
curdcb->name[3], curdcb->name[4], curdcb->name[5]);
printf("%c%c",
curdcb->name[6], curdcb->name[7]);
if (!((curdcb->dvatr)&128))
printf(".%c%c%c",
curdcb->ext[0], curdcb->ext[1], curdcb->ext[2]);
printf("\' at %p shows %2d OPENs\n", curdcb, curdcb->nusers);
printf(" Opened for %s access", actyp[3&(curdcb->mode)]);
if (0xFFFC & (curdcb->mode))
printf(" (%04X)", curdcb->mode);
printf(" by process %04X\n", curdcb->owner);
if((curdcb->dvatr)&128) /* Device */
{ printf(" Device driver at %p", curdcb->pdrvr);
printf(" is in %s mode",
(curdcb->dvatr)&32 ? "Raw" : "Cooked" );
printf(" and is%sready\n",
(curdcb->dvatr)&64 ? " " : " not " );
}
else /* File */
{ printf(" File is on drive %c:",
'A'+((curdcb->dvatr)&31) );
printf(" (driver at %p) and", curdcb->pdrvr);
printf(" has%sbeen written to.\n",
(curdcb->dvatr)&64 ? " not " : " " );
printf(" File's attribute byte = %02X\n", curdcb->datrb);
}
printf(" Mod Time/date: %s, %s\n",
f_tm(curdcb->modtm), f_dt(curdcb->moddt));
printf(" Dir Sector: %04X ", curdcb->dirsec);
printf(" Dir Index: %4d\n", curdcb->dirndx);
printf(" First Cluster: %04X ", curdcb->frstc);
printf(" Prev Clusters: %4d ", curdcb->clsctr);
printf(" Current Cluster: %04X\n", curdcb->curcls);
printf(" Directory size:%6ld ", curdcb->totsiz);
printf(" Curr byte count:%6ld\n", curdcb->curpos);
printf(" Fill2=%04X ", curdcb->fill2);
printf(" Fill3=%04X ", curdcb->fill3);
printf(" Fill4=%04X ", curdcb->fill4);
printf(" Fill5=%04X\n", curdcb->fill5);
}
else
printf("\n%s %2d at %p not used since bootup\n",
t, dcbctr++, curdcb);
++curdcb;
--n;
}
}

char * f_tm(n) unsigned n;
{ static char buf[16];
sprintf(buf, "%02d:%02d:%02d", (n>>11)&31, (n>>5)&63, (n<<1)&63);
return(buf);
}

char * f_dt(n) unsigned n;
{ static char buf[16];
sprintf(buf, "%02d/%02d/%4d", (n>>5)&15, n&31, 1980+((n>>9)&15));
return(buf);
}

void memtrc(a) struct mcb far * a;
{ curmcb = a;
printf ("\nMEMORY ALLOCATION CHAIN\n");
while (curmcb->flag == 'M')
{ memrpt( curmcb->siz, curmcb->owner, FP_SEG(curmcb)+1);
FP_SEG(curmcb) += (curmcb->siz + 1);
}
if (curmcb->flag != 'Z')
{ printf ("\nMEMORY ALLOCATION ERROR at %p\n", curmcb );
exit(255);
}
memrpt( curmcb->siz, curmcb->owner, FP_SEG(curmcb)+1);
}

void memrpt(s,o,a) unsigned s,o,a;
{ unsigned long z;
z = 16L * (unsigned long)s;
if (o)
printf("%8lu bytes USED by proc %04X, at %04X:0000, for %s\n",
z, o, a, memu(a));
else
printf("%8lu bytes FREE at %04X:0000\n", z, a);
}

char * memu(a) unsigned a;
{ union fpu y;
char x;
y.fp.s = a;
y.fp.o = 0;
x = *(y.cfp);
return (x=='C' ? "Environment" : (x=='\xCD' ? "Program" : "Data" ));
}