[SOLVED]Problems following cluster chains
Posted: Sat Dec 03, 2011 1:59 pm
I've been following the tutorials at http://www.brokenthorn.com/Resources/OSDev22.html to implement FAT12 filesystem support in my OS. Unfortunately, I've run into a problem. The code that follows the FAT cluster chain doesn't seem to work on files that have been resized. Specifically, the file that it is trying to read was originally 1KB, then it was increased to 9KB, then lowered to 2KB. I put in some code that made it display the clusters it was reading, and this is what it displayed:
Here's the code that I'm using:
I viewed the floppy disk with a hex editor and found that the correct cluster should be 704 instead of 1058. I also found that that cluster 1058 has not yet been used by the file system to store data. Is this a bug somewhere in the code, or is it something else?Reading cluster 513
Reading cluster 514
Reading cluster 1058
Here's the code that I'm using:
Code: Select all
void fread (FILE *file, unsigned char* Buffer, unsigned int Length)
{
int i;
for (i = 0; i <= (Length / 512); i++)
{
printf ("Reading cluster %d\n", file->currentCluster);
fread_sector(file, Buffer + (i * 512), 512);
if (file->eof)
return;
}
}
void fread_sector(FILE *file, unsigned char* Buffer, unsigned int Length)
{
if (file)
{
unsigned int physSector = 32 + (file->currentCluster - 1);
unsigned char* sector = (unsigned char*) flpydsk_read_sector ( physSector );
memcpy (Buffer, sector, 512);
unsigned int FAT_Offset = file->currentCluster + (file->currentCluster / 2); //multiply by 1.5
unsigned int FAT_Sector = 1 + (FAT_Offset / SECTOR_SIZE);
unsigned int entryOffset = FAT_Offset % SECTOR_SIZE;
sector = (unsigned char*) flpydsk_read_sector ( FAT_Sector );
memcpy (FAT, sector, 512);
sector = (unsigned char*) flpydsk_read_sector ( FAT_Sector + 1 );
memcpy (FAT + SECTOR_SIZE, sector, 512);
unsigned short nextCluster = *(unsigned short *)&FAT[entryOffset];
if (entryOffset & 0x1)
nextCluster >>= 4; //grab high 12 bits
else
nextCluster &= 0x0FFF; //grab low 12 bits
if ( nextCluster >= 0xff8)
{
file->eof = 1;
return;
}
if ( nextCluster == 0 )
{
file->eof = 1;
return;
}
file->currentCluster = nextCluster;
}
}