TIP: Click on subject to list as thread! ANSI
echo: aust_c_here
to: Paul Edwards
from: Frank Adam
date: 1996-10-15 11:33:00
subject: Fat

Hi Paul, why not write your own ??

I've had this floating around for some time, and couldn't get it 
working at that stage. I tried again now, must be improving :).
If i get the time i'll finish and add the restore and boot read to it, 
unless you want to beat me to it. ;-)
Writing it back should be as easy if not easier, and the boot is a snap.

/* 
** Fat saver.. PD by me to you or anyone who cares to use it.
** This will NOT work on an older compiler if you have a modern
** large drive because they (EG. TC2) seem to use the old INT25 absread()
** function, which can not read LBA drives. Compiled in BC4, but
** should port with little pain.
** Only one truely non portable part in this, absread(), there are 
** replacements for that out there, but i didn't really want to bother.
** Could replace it with INT25 AX=ffffh, i think.
*/
                                                 
#include 
#include   /* for memcpy */
#include    /* for toupper */
#include 
#include 

#define BYTE char
#define WORD unsigned int
#define DWORD unsigned long

struct DriveParamBlock  /* from Ralph Brown's excellent Interrupt List */
{
 BYTE Driveno;  /*  drive number (00h = A:, 01h = B:, etc) */
 BYTE DevUnit;  /*  unit number within device driver */
 WORD Bpersec;  /*  bytes per sector */
 BYTE Hysect ;  /*  highest sector number within a cluster */
 BYTE Shft   ;  /*  shift count to convert clusters into sectors */
 WORD ResSecs;  /*  number of reserved sectors at beginning of drive */
 BYTE NumFats;  /*  number of FATs */
 WORD NumRoot;  /*  number of root directory entries */
 WORD UserFsc;  /*  number of first sector containing user data */
 WORD MaxClust; /*  highest cluster number (number of data clusters + 1) */
         /*  16-bit FAT if greater than 0FF6h, else 12-bit FAT */
 WORD SecPerFat;/*  number of sectors per FAT */
 WORD DirStart; /*  sector number of first directory sector */
 DWORD DevHead; /* address of device driver header */
 BYTE  MediaId; /*  media ID byte (see #0669) */
 BYTE  AccessB; /*  00h if disk accessed, FFh if not */
 DWORD NextDbp; /*  pointer to next DPB */
 WORD  NextClus; /* cluster at which to start search for free space */ 
                 /*  when writing, usually the last cluster allocated */
 WORD  FreeClus; /* number of free clusters on drive, FFFFh = unknown */
};

struct BackupData  /* this could hold the "where to put it back" info */
{
 int drive;
 short fss; /* fat start sector. Always 1(i think) */
 int bps; /* bytes per sector 512 on my drives */
 int spf; /* sectors per fat 251-2 on my drives */
 short fats;  /* number of fats  (normally 2, 0 here is not good at all:))*/
              /* the two fats are contigous and the same, so one is enough 
              /* to save, image.exe does the same. 
              */
 }bupdat;     /* not yet in use */

char fname[80];
struct DriveParamBlock dpb;

int GetDpb(int drive)
{
 union REGS inregs,outregs;struct SREGS sregs;
 char far* p;
 inregs.h.ah = 0x32;
 inregs.h.dl = drive; /* 0 default drv,1 = A, 2 = B, etc.. */
 intdosx(&inregs,&outregs,&sregs);
 if(outregs.x.cflag) return 0;
 if(outregs.h.al) return 0;
 p = (char far*) MK_FP((unsigned)sregs.ds,(unsigned)outregs.x.bx);
 printf("\nDBP Address = %p\n",p);
 memcpy(&dpb,p,sizeof(struct DriveParamBlock));
 return 1;
};


int GetFat(int drive)
{
 char *fat;
 int startsector = 1, j , p = 0;
 FILE *out;
 sprintf(fname,"testfat%c.dat\0",(dpb.Driveno + 'A'));

 fat = (char*)calloc(dpb.Bpersec,sizeof(unsigned char));
  if(NULL == fat) {printf("\nNot enough memory");return 0;}

 out = fopen(fname,"wb");
  if(out == NULL) {perror("\nError opening file");return 0;}

printf("\n\n");  
 for(int i = 0;i < (dpb.SecPerFat);i++)
 {
  if (absread(drive, 1, i + startsector, fat) != 0)
  {perror("Disk read error"); return 0;}
  printf("\rSector %02d Read OK....",i);
  for(j = 0; j < dpb.Bpersec;j++)
      p += fwrite(&fat[j],1,1,out);
  printf("Written %03d items OK",i,p);
  p = 0;
 }
 free(fat);
 fclose(out);
 return 1; /* phew */
 };

void ShowMedia() /* just a bit of show off :o) */
{
 printf("\n Drive %c media type = ",toupper(dpb.Driveno + 'A'));
 switch((int)dpb.MediaId)
 {
  case 0xfff0 : if(dpb.SecPerFat > 4 && dpb.SecPerFat < 10)
                   printf("Probably 1.44M 3.5 floppy");
                 else printf("Unrecognized device or CD-ROM drive.");
                   break;
  case 0xfff8 : printf("Hard drive");break;
  case 0xfff9 : printf("DS 1.2M 5.25 floppy");break;
  case 0xfffa : printf("HP ROM device");break;
  case 0xfffc : printf("SS 9S/T 180K floppy");break;
  case 0xfffd : printf("DS 9S/T 360K floppy");break;
  case 0xfffe : printf("SS 8S/T 160K floppy");break;
  case 0xffff : printf("DS 8S/T 320K floppy");break;
  default   : printf("Unrecognized device");break;
  }
 printf("\nSectors per fat  = %d",dpb.SecPerFat);
 printf("\nBytes per sector = %d",dpb.Bpersec);
 printf("\nNumber of fats   = %d",dpb.NumFats);
 };
/* Note: i found, a 1.4M can return 0xfff9 if disk/x-copied from a 1.2M */


int main ( void )
{
 int drive = 1; /*
                **   try 'A' first, but works fine here on all my drives 
                **   except the CD-ROM
                */
 if(GetDpb(drive)) printf("DBP Operation OK..");
  else {
        printf("DBP Operation Failed ! ");
        return 0;
        }

  ShowMedia(); /* looking good if we got here */
  printf("\n\nProceed with reading FAT ?");
  if(toupper(fgetc(stdin)) == 'N') return 0;
  if(GetFat(drive - 1) != 0) printf("\nFat saved OK to %s.",fname);
 return 0;
 }

  L8r Frank(fadam{at}ozemail.com.au)
___ Blue Wave/DOS v2.21

--- Gash
* Origin: The Software Parlour (3:635/544)
SEEN-BY: 50/99 620/243 623/630 632/349 635/503 544 727 711/409 410 413 430
SEEN-BY: 711/808 809 932 934 712/515 713/888 714/906 800/1
@PATH: 635/544 50/99 711/808 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.