home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
info
/
fstat.arc
/
FSTAT.C
next >
Wrap
Text File
|
1989-12-12
|
7KB
|
219 lines
/*
* FSTAT - a utility to list the all open files known to the system
* along with miscellaneous information such as length, offset, handle
* count, access modes, device information or drive information, and
* the program which opened the file
* R. Brittain July 4, 1989
*
* This program released to the public domain
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
extern unsigned char _osmajor;
char *localcopy(char far *);
char *progname(unsigned int);
_setargv() {}
_setenvp() {}
main(int argc, char *argv[] )
{
union REGS regs;
struct SREGS segregs;
char far *pfiletab, far *pnext, far *fp;
char far *name, file[13], far *plist, far *entry;
char ownername[9], ownerext[5];
int nfiles, i, j, numhandles, entrylen;
unsigned int access, devinfo, progpsp;
long length, offset;
regs.h.ah = 0x52; /* DOS list of lists */
intdosx(®s,®s,&segregs);
/* make a pointer to start of master list */
plist = (char far *)MK_FP(segregs.es,regs.x.bx);
/* pointer to start of file table */
pfiletab = (char far *)MK_FP(*(int far *)(plist+6), *(int far *)(plist+4));
switch (_osmajor) {
case 2:
entrylen = 40; /* DOS 2.x */
break;
case 3:
entrylen = 53; /* DOS 3.x */
break;
case 4:
entrylen = 59; /* DOS 4.x - I do not know what is in the extra 6 bytes */
break;
default:
printf("Sorry, cannot handle this version of MS-DOS");
exit(1);
}
printf ("Name length offset hnd acc PSP device type/owner\n");
printf ("---- ------ ------ --- --- --- -----------------\n");
for (;;) {
/* pointer to next file table */
pnext = (char far *)MK_FP(*(int far *)(pfiletab+2), *(int far *)(pfiletab+0));
nfiles = *(int far *)(pfiletab+4);
#ifdef DEBUG
printf ("\nFile table at %Fp entries for %d files\n",pfiletab,nfiles);
#endif
for (i=0; i<nfiles; i++) {
/* cycle through all files, quit when we reach an unused entry */
entry = pfiletab + 6 + (i * entrylen);
if (_osmajor >= 3) {
name = entry + 32 ;
strncpy(file, localcopy(name), 11);
file[11] = '\0';
numhandles = *(int far *)(entry + 0) ;
access = (int) *(char far *)(entry + 2) ;
length = *(long far *)(entry + 17) ;
offset = *(long far *)(entry + 21) ;
devinfo = *(int far *)(entry + 5) ;
progpsp = *(int far *)(entry + 49);
} else {
name = entry + 4 ;
strncpy(file, localcopy(name), 11);
file[11] = '\0';
numhandles = (int) *(char far *)(entry + 0) ;
access = (int) *(char far *)(entry + 1) ;
length = *(long far *)(entry + 19) ;
offset = *(long far *)(entry + 36) ;
devinfo = (int) *(char far *)(entry + 27) ;
}
if ((strlen(file) > 0) && (numhandles > 0)) {
printf("%11.11s %8ld %8ld %2d ",
file,length,offset,numhandles);
switch (access) {
case 0:
printf("r ");
break;
case 1:
printf("w ");
break;
case 2:
printf("rw ");
break;
default:
printf(" ");
}
if (_osmajor >= 3)
printf("%04X ",progpsp);
else
printf("---- ");
if ((devinfo & 0x80) > 0) {
printf("dev: ");
if (devinfo & 0x01) printf("stdin ");
if (devinfo & 0x02) printf("stdout ");
if (devinfo & 0x04) printf("NUL ");
if (devinfo & 0x08) printf("CLOCK$ ");
if (devinfo & 0x10) printf("fast-tty ");
if (devinfo & 0x20) printf("binary ");
if (devinfo & 0x1000) printf("network ");
printf("\n");
} else {
printf("drive %c: ",'A'+(devinfo&0x1F));
if (devinfo & 0x8000) printf("(network) ");
if (_osmajor >= 3) {
/* only DOS 3+ can find out the name of the program */
fnsplit(progname(progpsp),NULL,NULL,ownername,ownerext);
printf(" [%s%s]\n",strlwr(ownername),strlwr(ownerext));
} else {
printf("\n");
}
}
}
if (strlen(file) == 0) exit(0);
}
pfiletab = pnext;
}
}
char *localcopy(char far *s)
/* Make a copy of a string pointed to by a far pointer */
{
char far *p, *l, *r ;
int i=0 ;
p = s;
while (*p++ != NULL) { i++; }
r = l = (char *)malloc(i+1);
p = s;
i = 0;
while (*p != NULL) { *l++ = *p++; i++;}
*l = '\0';
return(r);
}
char *progname(pid)
unsigned int pid;
/*
* Return a near pointer to a character string with the full path name
* of the program whose PSP is given in the argument. If the argument is
* invalid, this may return gibberish but I don't know how to tell
* Offset 0x2C in the PSP in the segment address of the environment of a
* program. Beyond the last environment string is a null marker, a word
* count (usually 1), then the full pathname of the owner of the environment
* This only works for DOS 3+
*/
{
unsigned far *envsegptr; /* Pointer to seg address of environment */
char far *envptr; /* Pointer to pid's environment */
unsigned far *envsizeptr; /* Pointer to environment size */
unsigned envsize; /* Size of pid's environment */
unsigned ppid; /* Parent psp address */
/* find the parent process psp at offset 0x16 of the psp */
ppid = *(unsigned far *)MK_FP(pid, 0x16);
/* find the environment at offset 2Ch of the psp */
envsegptr = (unsigned far *) MK_FP (pid,0x2C);
envptr = (char far *) MK_FP (*envsegptr,0);
/*
* Make a pointer that contains the size of the environment
* block. Must point back one paragraph (to the environments
* MCB plus three bytes forward (to the MCB block size field).
*/
envsizeptr = (unsigned far *) MK_FP(*envsegptr-1,0x3);
envsize = *envsizeptr*16; /* x 16 turns it into bytes */
while (envsize > 0) {
/* search for end of environment block, or NULL */
while (--envsize && *envptr++);
/*
* Now check for another NULL immediately following the first one
* located and a word count of 0001 following that.
*/
if (!*envptr && *(unsigned far *) (envptr+1) == 0x1) {
envptr +=3;
break;
}
}
if (envsize > 0) {
/* Owner name found - return it */
return(localcopy(envptr));
} else {
if (pid == ppid) {
/*
* command.com doesn't leave it's name around, but if pid = ppid
* then we know we have a shell
*/
return("-shell-");
} else {
return("unknown");
}
}
}