Question

I am trying to write a program in C that allows me to move through a FAT32 file system image. However, I am having difficulty understanding and applying the equations to gather the correct data. I am using a debian distribution of linux so little-endian form is maintained. Below is pseudocode from the Microsoft website about FAT32, calculating the next cluster to access of a directory or file:

    ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
    ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);

    FAT32ClusEntryVal = FAT32ClusEntryVal & 0x0FFFFFFF;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) =
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0xF0000000;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) = 
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) | FAT32ClusEntryVal;

I do not fully understand what the SecBuff character array is doing or what it's accessing. DWORD is supposed to be a unsigned int and I'm not sure I understand the subsequent casts either. Any light shed is much appreciated.

If someone could also explain how we are supposed to move through the FAT32 filesystem based on clusters it would be greatly appreciated, it seems to me that going by reference of sectors is more effective even though cluster allocation ensures spatial locality. I don't fully understand how to do the byte reading to find the next cluster for files/folders.

Was it helpful?

Solution

That pseudo code is for reading and writing a cluster number from/into the file allocation table. The doc says it right between two pieces of pseudo code. It's the only possibility here, unless you don't have a slightest idea of how FAT12/16/32 works.

------8<------

Assume this is read into an 8-bit byte array named SecBuff. Also assume that the type WORD is a 16-bit unsigned and that the type DWORD is a 32-bit unsigned.

If(FATType == FAT16)
    FAT16ClusEntryVal = *((WORD *) &SecBuff[ThisFATEntOffset]);
Else
    FAT32ClusEntryVal = (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0x0FFFFFFF;

Fetches the contents of that cluster. To set the contents of this same cluster you do the following:

If(FATType == FAT16)
    *((WORD *) &SecBuff[ThisFATEntOffset]) = FAT16ClusEntryVal;
Else {
     FAT32ClusEntryVal = FAT32ClusEntryVal & 0x0FFFFFFF;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) =
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0xF0000000;
    *((DWORD *) &SecBuff[ThisFATEntOffset]) = 
        (*((DWORD *) &SecBuff[ThisFATEntOffset])) | FAT32ClusEntryVal;
}

------8<------

It is these cluster numbers in the cells the above pseudo code manipulates with:

enter image description here

They say where the next file part is (if any), in what cluster. Every file or directory is a chain of clusters.

SecBuff is an array containing a 512-bytes-long sector of the file allocation table. The *((DWORD *) casts are there to avoid reading/writing 32-bit values in separate 8-bit pieces.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top