📄 dpbtest.c
字号:
/*
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -