Monday, May 16, 2011

An Elementary CHKDSK

With functions to read/write FAT (readwrite( )) and to find number of sectors per FAT (getspft( )) for a given drive under our belt, let us now proceed with reading the two copies of FAT, comparing them and if one has gone bad then overwriting it with the good copy. Here is a program to do so...
# include
# include
# include
main( )
{
unsigned int spft, drive_no, drive ;
printf ( "\nEnter drive No. A=0 B=1 C=2 etc." ) ;
scanf ( "%d", &drive_no ) ;
drive = getdisk( ) ;
setdisk ( drive_no ) ;
spft = getspft ( drive_no ) ;
fat_compare ( drive_no, spft ) ;
setdisk ( drive ) ;
}
fat_compare ( unsigned int drive_no, unsigned int spft )
{
int chk1, chk2 ;
long k ;
char *arr_copy1, *arr_copy2 ;
arr_copy1 = farmalloc ( spft * 512l ) ;
arr_copy2 = farmalloc ( spft * 512l ) ;
if ( arr_copy1 == NULL || arr_copy2 == NULL )
{
puts ( "Insufficient memory" ) ;
return ;
}
chk1 = readwrite ( 'r', drive_no, spft, 1L, arr_copy1 ) ;
chk2 = readwrite ( 'r', drive_no, spft, 1L + spft, arr_copy2 ) ;
if ( chk1 == -1 && chk2 == -1 )
{
printf ( "Both copies of FAT damaged" ) ;
return ;
}
if ( chk1 == 0 && chk2 == 0 )
{
for ( k = 2l ; k < spft * 512l ; k++ )
{
if ( *( arr_copy1 + k ) != *( arr_copy2 + k ) )
{
printf ( "\nFAT copies not matching" ) ;
return ;
}
}
printf ( "\nBoth FAT copies are up to date. " ) ;
}
if ( chk1 == 0 && chk2 == -1 )
fat_fix ( drive_no, spft, 1, arr_copy1 ) ;
if ( chk1 == -1 && chk2 == 0 )
fat_fix ( drive_no, spft, 0, arr_copy2 ) ;
}
fat_fix (int drive_no, int spft, int fat_no, char *arr )
{
char ch, chk ;
printf ( "\nCopy no. %d of FAT is bad. ", fat_no + 1 ) ;
printf ( "\nOverwrite it with the good one? Y/N " ) ;
if ( ( ch = toupper ( getch( ) ) ) == 'Y' )
{
chk = readwrite ( 'w', drive_no, spft, 1L + fat_no * spft, arr ) ;
if ( chk != 0 )
printf ( "\nFAT copy %d could not be recovered", fat_no ) ;
}
}
The program opens with a prompt for the user to enter the drive number. A call to setdisk( ) sets the current drive to the drive number entered by the user. The earlier current drive is safely stored in drive so that at the end it can be restored. With current drive set, getspft( ) is called to find number of sectors occupied by each copy of FAT for this drive. A call to fat_compare( ) follows which reads the two copies of FATs and depending upon the status of the two copies performs the actions shown below.