home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l440 / 2.ddi / CHAP4 / DPBTEST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-25  |  3.4 KB  |  128 lines

  1. /*
  2. DPBTEST.C -- uses undocumented INT 21h Function 32h (Get DPB)
  3.     to display bytes per drive; but first walks the DPB chain, 
  4.     showing the difference between the two access methods
  5. */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <dos.h>
  10.  
  11. #pragma pack(1)
  12.  
  13. typedef unsigned char BYTE;
  14.  
  15. typedef struct dpb {
  16.     BYTE drive;
  17.     BYTE unit;
  18.     unsigned bytes_per_sect;
  19.     BYTE sectors_per_cluster;       // plus 1
  20.     BYTE shift;                     // for sectors per cluster
  21.     unsigned boot_sectors;          
  22.     BYTE copies_fat;
  23.     unsigned max_root_dir;
  24.     unsigned first_data_sector;
  25.     unsigned highest_cluster;
  26.     union {
  27.         struct {
  28.             unsigned char sectors_per_fat;
  29.             unsigned first_dir_sector;
  30.             void far *device_driver;
  31.             BYTE media_descriptor;
  32.             BYTE access_flag;
  33.             struct dpb far *next;
  34.             unsigned long reserved;
  35.             } dos3;
  36.         struct {
  37.             unsigned sectors_per_fat;       // WORD, not BYTE!
  38.             unsigned first_dir_sector;
  39.             void far *device_driver;
  40.             BYTE media_descriptor;
  41.             BYTE access_flag;
  42.             struct dpb far *next;
  43.             unsigned long reserved;
  44.             } dos4;
  45.         } vers;
  46.     } DPB;
  47.  
  48. #ifndef MK_FP
  49. #define MK_FP(seg,ofs) \
  50.     ((void far *)(((unsigned long)(seg) << 16) | (ofs)))
  51. #endif
  52.  
  53. void fail(char *s) { puts(s); exit(1); }
  54.  
  55. void display(DPB far *dpb)
  56. {
  57.     unsigned long bytes_per_clust = 
  58.         dpb->bytes_per_sect * (dpb->sectors_per_cluster + 1);
  59.  
  60.     printf("Drive %c: ", 'A' + dpb->drive);
  61.     printf("%u bytes/sector * ", dpb->bytes_per_sect);
  62.     printf("%u sectors/cluster = \n", 
  63.         dpb->sectors_per_cluster + 1);
  64.     printf("         %lu bytes/cluster * ", bytes_per_clust);
  65.     printf("%u clusters = ", dpb->highest_cluster - 1);
  66.     printf("%lu bytes\n\n",
  67.         bytes_per_clust * (dpb->highest_cluster - 1));
  68. }
  69.  
  70. main()
  71. {
  72.     DPB far *dpb;
  73.     union REGS r;
  74.     struct SREGS s;
  75.     
  76.     /* floppy = single disk drive logical drive indicator 0=a 1=b */
  77.     unsigned char far *pfloppy = (BYTE far *) 0x504L;
  78.     
  79.     int i;
  80.     
  81. #ifdef __TURBOC__
  82.     unsigned lastdrive = setdisk(getdisk());
  83. #else
  84.     unsigned lastdrive;
  85.     unsigned curdrv;
  86.     _dos_getdrive(&curdrv);
  87.     _dos_setdrive(curdrv, &lastdrive);
  88. #endif
  89.  
  90.     puts("Using DPB linked list");
  91.     
  92.     s.es = r.x.bx = 0;
  93.     r.h.ah = 0x52;
  94.     intdosx(&r, &r, &s);
  95.     /* pointer to first DPB at offset 0h in List of Lists */
  96.     if (! (dpb = *((void far * far *) MK_FP(s.es, r.x.bx))))
  97.         return 1;
  98.     do {
  99.         /* skip either drive A: or drive B: */
  100.         if (((*pfloppy == 1) && (dpb->drive != 0)) ||
  101.             ((*pfloppy == 0) && (dpb->drive != 1)))
  102.                 display(dpb);
  103.         if (_osmajor < 4) 
  104.             dpb = dpb->vers.dos3.next;
  105.         else
  106.             dpb = dpb->vers.dos4.next;
  107.     } while (FP_OFF(dpb) != -1);
  108.  
  109.     
  110.     puts("Using INT 21h Function 32h");
  111.     
  112.     segread(&s);
  113.     for (i=1; i<=lastdrive; i++)
  114.     {
  115.         /* skip either drive A: or drive B: */
  116.         if ((*pfloppy == 1) && (i == 1)) continue;
  117.         else if ((*pfloppy == 0) && (i == 2)) continue;
  118.  
  119.         r.h.ah = 0x32;
  120.         r.h.dl = i;
  121.         intdosx(&r, &r, &s);
  122.         if (r.h.al != 0xFF)
  123.             display((DPB far *) MK_FP(s.ds, r.x.bx));
  124.     }
  125.  
  126.     return 0;
  127. }
  128.