home *** CD-ROM | disk | FTP | other *** search
/ For Beginners & Professional Hackers / cd.iso / docum / dos-ref.doc / examples / chap4.arj / FILES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-25  |  6.1 KB  |  221 lines

  1. /* 
  2. FILES.C -- list all files in system file table
  3.  
  4. cl files.c
  5. cl -DFREEUP -Fefreeup.exe files.c
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <dos.h>
  11.  
  12. #ifdef __TURBOC__
  13. #define ASM asm
  14. #else
  15. #define ASM _asm
  16. #endif
  17.  
  18. typedef unsigned char BYTE;
  19. typedef unsigned USHORT;
  20. typedef unsigned long ULONG;
  21. typedef BYTE far *FP;
  22.  
  23. #pragma pack(1)
  24.  
  25. typedef struct file {   
  26.     USHORT num_handles, open_mode;
  27.     BYTE fattr;
  28.     USHORT dev_info;    // includes drive number
  29.     FP ptr;
  30.     USHORT start_cluster, time, date;
  31.     ULONG fsize, offset;
  32.     USHORT rel_cluster, abs_cluster, dir_sector;
  33.     BYTE dir_entry;
  34.     BYTE filename[11];
  35.     ULONG share_prev_sft;
  36.     USHORT share_net_machine;
  37.     USHORT owner_psp;
  38.     // ...
  39.     } file; // for DOS 3.x, 4.x
  40.     
  41. typedef struct sysftab {
  42.     struct sysftab far *next;
  43.     USHORT num_files;
  44.     file f[1];
  45.     } SYS_FTAB;
  46.     
  47. typedef struct {
  48.     BYTE type;      
  49.     USHORT owner;    /* PSP of the owner */
  50.     USHORT size;
  51.     BYTE unused[3];
  52.     BYTE dos4[8];
  53.     } MCB;
  54.  
  55. void fail(char *s) { puts(s); exit(1); }    
  56.  
  57. #ifdef __TURBOC__
  58. #define GETVECT(intno)  getvect(intno)
  59. #define ASM             asm
  60. #else
  61. #define GETVECT(intno)  _dos_getvect(intno)
  62. #define ASM             _asm
  63. #endif
  64.  
  65. #ifndef MK_FP
  66. #define MK_FP(seg,ofs)  ((FP)(((ULONG)(seg) << 16) | (ofs)))
  67. #endif
  68.  
  69. #define NEXT(mcb)       (MK_FP(FP_SEG(mcb) + (mcb)->size + 1, 0))
  70.  
  71. int belongs(FP vec, USHORT start, USHORT size)
  72. {
  73.     USHORT seg = FP_SEG(vec);
  74.     return (seg >= start) && (seg <= (start + size));
  75. }
  76.  
  77. int is_psp(USHORT seg)
  78. {
  79.     return ((((MCB far *) MK_FP(seg-1,0))->owner == seg) &&
  80.             (*((USHORT far *) MK_FP(seg,0)) == 0x20CD));
  81. }
  82.                 
  83. /*
  84.     Look for "orphaned" file handles: e.g., TSR>FOO.BAR or TSR>NUL
  85.     will leave FOO.BAR or NUL entry in SFT, consuming file handle. If
  86.     the PSP of the file's owner is COMMAND.COM, and if there's only
  87.     one owner, then we decide it's an orphaned handle.
  88. */
  89. int orphan(file far *ff)
  90. {
  91.     static command_com_psp = 0;
  92.     if (! ff->num_handles)
  93.         return 0;
  94.     if (! command_com_psp)  /* do just one time */
  95.     {
  96.         FP int2e = (FP) GETVECT(0x2E);
  97.         MCB far *mcb;
  98.         ASM mov ah, 52h
  99.         ASM int 21h
  100.         ASM mov ax, es:[bx-2]
  101.         ASM mov word ptr mcb+2, ax
  102.         ASM mov word ptr mcb, 0
  103.         while (mcb->type != 'Z')
  104.             if (belongs(int2e, FP_SEG(mcb), mcb->size))
  105.             {
  106.                 command_com_psp = mcb->owner;
  107.                 break;
  108.             }
  109.             else
  110.                 mcb = (MCB far *) NEXT(mcb);
  111.     }
  112.     return ((ff->owner_psp == command_com_psp) &&
  113.             (ff->num_handles == 1));
  114. }
  115.  
  116. #define IS_AUX(s)   ((s[0]=='A') && (s[1]=='U') && (s[2]=='X'))
  117. #define IS_CON(s)   ((s[0]=='C') && (s[1]=='O') && (s[2]=='N'))
  118. #define IS_PRN(s)   ((s[0]=='P') && (s[1]=='R') && (s[2]=='N'))
  119.  
  120. main(void)
  121. {
  122.     SYS_FTAB far *sys_filetab;
  123.     file far *ff;
  124.     int size;
  125.     int i;
  126.  
  127.     ASM mov ah, 52h
  128.     ASM int 21h
  129.     ASM les bx, dword ptr es:[bx+4] /* ptr to list of DOS file tables */
  130.     ASM mov word ptr sys_filetab, bx
  131.     ASM mov word ptr sys_filetab+2, es
  132.  
  133.     /* DOS box of OS/2 1.x doesn't provide system file tbl */
  134.     if (sys_filetab == (SYS_FTAB far *) -1L)
  135.         fail("system file table not supported");
  136.  
  137.     switch (_osmajor)
  138.     {
  139.         case 2:             size = 0x28; break;
  140.         case 3:             size = 0x35; break;
  141.         default:            size = 0x3b; break;
  142.     }
  143.  
  144.     /* Perform sanity check: determine size of file structure
  145.        empirically from difference between strings "CON" and
  146.        "AUX." If this equals size computed via _osmajor, everything
  147.        is fine. Otherwise, we reset size. */
  148.     {
  149.         FP p, q;
  150.         int i;
  151.         /* i=1000: set upper limit on string search in memory */
  152.         for (p=(FP)sys_filetab->f, i=1000; i--, p++; )
  153.             if (IS_AUX(p))
  154.                 break;
  155.         if (! i) return 1;
  156.         for (q=p, i=1000; i--, q++; )
  157.             if (IS_CON(q))
  158.                 break;
  159.         if (! i) return 1;
  160.         /* size of file structure must equal span from AUX to CON */
  161.         if (size != (q - p))
  162.         {
  163.             puts("size based on _osmajor looks wrong");
  164.             size = q - p;
  165.         }
  166.     }
  167.  
  168.     printf("Filename              Size      Attr Handles    Owner\n");
  169.     printf("--------              ----      ---- -------    -----\n");
  170.  
  171.     do { /* FOR EACH SFT */
  172.         
  173.         /* FOR EACH ENTRY IN THIS SFT */
  174.         for (i=sys_filetab->num_files, ff=sys_filetab->f; 
  175.              i--; 
  176.              ((FP) ff) += size)
  177.         if (ff->num_handles)
  178.         {
  179.             if (_osmajor == 2)
  180.             {
  181.                 // didn't bother with struct for DOS2
  182.                 FP ff2 = (FP) ff;
  183.                 printf("%.8Fs.",   ff2 + 0x04);
  184.                 printf("%.3Fs\t",  ff2 + 0x0c);
  185.                 printf("%10lu\t",  *((ULONG far *) (ff2 + 0x13)));
  186.                 printf("%04X\t",   ff2[0x02]);
  187.             }
  188.             else
  189.             {
  190.                 printf("%.8Fs.",   ff->filename);
  191.                 printf("%.3Fs\t",  ff->filename + 8);
  192.                 printf("%10lu\t",  ff->fsize);
  193.                 printf("%04X\t",   ff->fattr);
  194.                 printf("%d\t",     ff->num_handles);
  195.                 printf("%04X\t",   ff->owner_psp);
  196.                 if (! is_psp(ff->owner_psp))
  197.                     printf("[NOT PSP]");
  198.                 if (orphan(ff))
  199.                     printf("[ORPHAN]");
  200.             }
  201. #ifdef FREEUP
  202.             // only DOS 3+
  203.             if (! IS_AUX(ff->filename)) 
  204.             if (! IS_CON(ff->filename))
  205.             if (! IS_PRN(ff->filename))
  206.             if (orphan(ff) || (! is_psp(ff->owner_psp)))
  207.             {
  208.                 if (! (-- ff->num_handles))  // decrement owners
  209.                     printf(" [FREED]");
  210.                 else
  211.                     printf(" [NOW %d]", ff->num_handles);
  212.             }
  213. #endif
  214.             printf("\n");
  215.         }
  216.         sys_filetab = sys_filetab->next; /* FOLLOWED LINKED LIST... */
  217.     } while (FP_SEG(sys_filetab) && 
  218.              FP_OFF(sys_filetab) != (unsigned) -1); /* ...UNTIL END */
  219.     return 0;
  220. }
  221.