Mail Archives: djgpp-workers/1999/09/12/15:51:05
Please try the following program (particularly those of you that have
access to NTFS and other possible file system used from DJGPP)
It reports correct FAT sizes for FAT12 (floppy), FAT16 and FAT32 file
systems. And it fails on RAMDISK, CDROM and network file systems.
It is right according to official documentation from Microsnoft.
As I'll replace my first FAT32 detection routine with this, it would
be nice to know if anything bad happens when you try this
program. Thanks!
Right,
MartinS
----- Program starts. -----
/*
* File getfatsz.c.
*
* Copyright (C) 1999 Martin Str<94>mberg <ams AT ludd DOT luth DOT se>.
*
* This software may be used freely so long as this copyright notice
is
* left intact. There is no warranty on this software.
*
*/
#include <dpmi.h>
#include <go32.h>
#include <errno.h>
#include <sys/farptr.h>
#include <stdio.h>
/* Returns number of bits in FAT; 0 == FAT of unknown size; -1 ==
error. */
int
_get_fat_size( const int drive /* drive number (1=A:). */
)
{
__dpmi_regs r = {{0}};
int size;
unsigned long bytes_per_sector, sectors_per_cluster,
reserved_sectors;
unsigned long number_of_fats, root_entries, fat16_size, fat32_size;
unsigned long total16_sectors, total32_sectors;
unsigned long root_sectors, fat_size, total_sectors, data_sectors;
unsigned long number_of_clusters;
r.x.ax = 0x440d;
r.h.bl = drive;
r.h.ch = 0x48;
r.h.cl = 0x60;
r.x.ds = /*r.x.si = */ __tb >>4;
r.x.dx = /*r.x.di = */ __tb & 0x0f;
__dpmi_int(0x21, &r);
if( r.x.flags & 0x01 )
{
fprintf(stderr, "INT21/0x440d failed (ax = %d).\n", r.x.ax);
errno = ENOSYS;
return(-1);
}
bytes_per_sector = _farpeekw(_dos_ds, __tb+7+11-11);
sectors_per_cluster = _farpeekb(_dos_ds, __tb+7+13-11);
reserved_sectors = _farpeekw(_dos_ds, __tb+7+14-11);
number_of_fats = _farpeekb(_dos_ds, __tb+7+16-11);
root_entries = _farpeekw(_dos_ds, __tb+7+17-11);
fat16_size = _farpeekw(_dos_ds, __tb+7+22-11);
fat32_size = _farpeekl(_dos_ds, __tb+7+36-11);
total16_sectors = _farpeekw(_dos_ds, __tb+7+19-11);
total32_sectors = _farpeekl(_dos_ds, __tb+7+32-11);
root_sectors = ( (root_entries * 32)
+ (bytes_per_sector - 1)
) / bytes_per_sector;
fat_size = fat16_size ? fat16_size : fat32_size;
total_sectors = total16_sectors ? total16_sectors : total32_sectors;
data_sectors = total_sectors - reserved_sectors -
number_of_fats*fat_size
- root_sectors;
number_of_clusters = data_sectors / sectors_per_cluster;
if( number_of_clusters < 4085 )
{
size = 12;
}
else if( number_of_clusters < 65525 )
{
size = 16;
}
else
{
size = 32;
}
#if 0
fprintf(stderr, "bytes_per_sector = %ld.\n", bytes_per_sector);
fprintf(stderr, "sectors_per_cluster = %ld.\n",
sectors_per_cluster);
fprintf(stderr, "reserved_sectors = %ld.\n", reserved_sectors);
fprintf(stderr, "number_of_fats = %ld.\n", number_of_fats);
fprintf(stderr, "root_entries = %ld.\n", root_entries);
fprintf(stderr, "fat16_size = %ld.\n", fat16_size);
fprintf(stderr, "fat32_size = %ld.\n", fat32_size);
fprintf(stderr, "total16_sectors = %ld.\n", total16_sectors);
fprintf(stderr, "total32_sectors = %ld.\n", total32_sectors);
fprintf(stderr, "root_sectors = %ld.\n", root_sectors);
fprintf(stderr, "data_sectors = %ld.\n", data_sectors);
fprintf(stderr, "number_of_clusters = %ld.\n", number_of_clusters);
#endif
return( size );
}
#if 1
int main(int argc, char *argv[])
{
int ret;
if( argc == 2
&& 'A' <= argv[1][0]
&& argv[1][0] <= 'Z' )
{
ret = _get_fat_size(argv[1][0] - 'A' + 1);
fprintf(stderr, "_get_fat_size returned %d.\n", ret);
return(0);
}
else
{
fprintf(stderr, "%s: run like this '%s C'.\n", argv[0], argv[0]);
return(1);
}
}
#endif
----- Program ends. -----
- Raw text -