| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| 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™.