home *** CD-ROM | disk | FTP | other *** search
- /*
- DPBTEST.C -- uses undocumented INT 21h Function 32h (Get DPB)
- to display bytes per drive; but first walks the DPB chain,
- showing the difference between the two access methods
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <dos.h>
-
- #pragma pack(1)
-
- typedef unsigned char BYTE;
-
- typedef struct dpb {
- BYTE drive;
- BYTE unit;
- unsigned bytes_per_sect;
- BYTE sectors_per_cluster; // plus 1
- BYTE shift; // for sectors per cluster
- unsigned boot_sectors;
- BYTE copies_fat;
- unsigned max_root_dir;
- unsigned first_data_sector;
- unsigned highest_cluster;
- union {
- struct {
- unsigned char sectors_per_fat;
- unsigned first_dir_sector;
- void far *device_driver;
- BYTE media_descriptor;
- BYTE access_flag;
- struct dpb far *next;
- unsigned long reserved;
- } dos3;
- struct {
- unsigned sectors_per_fat; // WORD, not BYTE!
- unsigned first_dir_sector;
- void far *device_driver;
- BYTE media_descriptor;
- BYTE access_flag;
- struct dpb far *next;
- unsigned long reserved;
- } dos4;
- } vers;
- } DPB;
-
- #ifndef MK_FP
- #define MK_FP(seg,ofs) \
- ((void far *)(((unsigned long)(seg) << 16) | (ofs)))
- #endif
-
- void fail(char *s) { puts(s); exit(1); }
-
- void display(DPB far *dpb)
- {
- unsigned long bytes_per_clust =
- dpb->bytes_per_sect * (dpb->sectors_per_cluster + 1);
-
- printf("Drive %c: ", 'A' + dpb->drive);
- printf("%u bytes/sector * ", dpb->bytes_per_sect);
- printf("%u sectors/cluster = \n",
- dpb->sectors_per_cluster + 1);
- printf(" %lu bytes/cluster * ", bytes_per_clust);
- printf("%u clusters = ", dpb->highest_cluster - 1);
- printf("%lu bytes\n\n",
- bytes_per_clust * (dpb->highest_cluster - 1));
- }
-
- main()
- {
- DPB far *dpb;
- union REGS r;
- struct SREGS s;
-
- /* floppy = single disk drive logical drive indicator 0=a 1=b */
- unsigned char far *pfloppy = (BYTE far *) 0x504L;
-
- int i;
-
- #ifdef __TURBOC__
- unsigned lastdrive = setdisk(getdisk());
- #else
- unsigned lastdrive;
- unsigned curdrv;
- _dos_getdrive(&curdrv);
- _dos_setdrive(curdrv, &lastdrive);
- #endif
-
- puts("Using DPB linked list");
-
- s.es = r.x.bx = 0;
- r.h.ah = 0x52;
- intdosx(&r, &r, &s);
- /* pointer to first DPB at offset 0h in List of Lists */
- if (! (dpb = *((void far * far *) MK_FP(s.es, r.x.bx))))
- return 1;
- do {
- /* skip either drive A: or drive B: */
- if (((*pfloppy == 1) && (dpb->drive != 0)) ||
- ((*pfloppy == 0) && (dpb->drive != 1)))
- display(dpb);
- if (_osmajor < 4)
- dpb = dpb->vers.dos3.next;
- else
- dpb = dpb->vers.dos4.next;
- } while (FP_OFF(dpb) != -1);
-
-
- puts("Using INT 21h Function 32h");
-
- segread(&s);
- for (i=1; i<=lastdrive; i++)
- {
- /* skip either drive A: or drive B: */
- if ((*pfloppy == 1) && (i == 1)) continue;
- else if ((*pfloppy == 0) && (i == 2)) continue;
-
- r.h.ah = 0x32;
- r.h.dl = i;
- intdosx(&r, &r, &s);
- if (r.h.al != 0xFF)
- display((DPB far *) MK_FP(s.ds, r.x.bx));
- }
-
- return 0;
- }
-