From: Martin Str|mberg Message-Id: <199909121935.VAA25065@father.ludd.luth.se> Subject: FAT32 detection To: djgpp-workers AT delorie DOT com (DJGPP-WORKERS) Date: Sun, 12 Sep 1999 21:35:42 +0200 (MET DST) X-Mailer: ELM [version 2.4ME+ PL15 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com 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 . * * This software may be used freely so long as this copyright notice is * left intact. There is no warranty on this software. * */ #include #include #include #include #include /* 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. -----