www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/09/12/15:51:05

From: Martin Str|mberg <ams AT ludd DOT luth DOT se>
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
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019