Microsoft Extensible Firmware Initiative fat32 File System Specification


If(BPB_FATSz16 != 0) FATSz = BPB_FATSz16



Yüklə 225,69 Kb.
səhifə4/9
tarix11.10.2017
ölçüsü225,69 Kb.
#4468
1   2   3   4   5   6   7   8   9

If(BPB_FATSz16 != 0)

FATSz = BPB_FATSz16;

Else

FATSz = BPB_FATSz32;


If(FATType == FAT16)

FATOffset = N * 2;

Else if (FATType == FAT32)

FATOffset = N * 4;


ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);

ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);

REM(…) is the remainder operator. That means the remainder after division of FATOffset by BPB_BytsPerSec. ThisFATSecNum is the sector number of the FAT sector that contains the entry for cluster N in the first FAT. If you want the sector number in the second FAT, you add FATSz to ThisFATSecNum; for the third FAT, you add 2*FATSz, and so on.


You now read sector number ThisFATSecNum (remember this is a sector number relative to sector 0 of the FAT volume). 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;

}



Note how the FAT32 code above works. A FAT32 FAT entry is actually only a 28-bit entry. The high 4 bits of a FAT32 FAT entry are reserved. The only time that the high 4 bits of FAT32 FAT entries should ever be changed is when the volume is formatted, at which time the whole 32-bit FAT entry should be zeroed, including the high 4 bits.
A bit more explanation is in order here, because this point about FAT32 FAT entries seems to cause a great deal of confusion. Basically 32-bit FAT entries are not really 32-bit values; they are only 28-bit values. For example, all of these 32-bit cluster entry values: 0x10000000, 0xF0000000, and 0x00000000 all indicate that the cluster is FREE, because you ignore the high 4 bits when you read the cluster entry value. If the 32-bit free cluster value is currently 0x30000000 and you want to mark this cluster as bad by storing the value 0x0FFFFFF7 in it. Then the 32-bit entry will contain the value 0x3FFFFFF7 when you are done, because you must preserve the high 4 bits when you write in the 0x0FFFFFF7 bad cluster mark.
Take note that because the BPB_BytsPerSec value is always divisible by 2 and 4, you never have to worry about a FAT16 or FAT32 FAT entry spanning over a sector boundary (this is not true of FAT12).
The code for FAT12 is more complicated because there are 1.5 bytes (12-bits) per FAT entry.

if (FATType == FAT12)

FATOffset = N + (N / 2);

/* Multiply by 1.5 without using floating point, the divide by 2 rounds DOWN */

ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);

ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);

We now have to check for the sector boundary case:



If(ThisFATEntOffset == (BPB_BytsPerSec – 1)) {

/* This cluster access spans a sector boundary in the FAT */

/* There are a number of strategies to handling this. The */

/* easiest is to always load FAT sectors into memory */

/* in pairs if the volume is FAT12 (if you want to load */

/* FAT sector N, you also load FAT sector N+1 immediately */

/* following it in memory unless sector N is the last FAT */

/* sector). It is assumed that this is the strategy used here */

/* which makes this if test for a sector boundary span */

/* unnecessary. */

}

We now access the FAT entry as a WORD just as we do for FAT16, but if the cluster number is EVEN, we only want the low 12-bits of the 16-bits we fetch; and if the cluster number is ODD, we only want the high 12-bits of the 16-bits we fetch.



FAT12ClusEntryVal = *((WORD *) &SecBuff[ThisFATEntOffset]);

If(N & 0x0001)

FAT12ClusEntryVal = FAT12ClusEntryVal >> 4; /* Cluster number is ODD */

Else

FAT12ClusEntryVal = FAT12ClusEntryVal & 0x0FFF; /* Cluster number is EVEN */



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

If(N & 0x0001) {

FAT12ClusEntryVal = FAT12ClusEntryVal << 4; /* Cluster number is ODD */

*((WORD *) &SecBuff[ThisFATEntOffset]) =

(*((WORD *) &SecBuff[ThisFATEntOffset])) & 0x000F;

} Else {

FAT12ClusEntryVal = FAT12ClusEntryVal & 0x0FFF; /* Cluster number is EVEN */

*((WORD *) &SecBuff[ThisFATEntOffset]) =

(*((WORD *) &SecBuff[ThisFATEntOffset])) & 0xF000;

}

*((WORD *) &SecBuff[ThisFATEntOffset]) =

(*((WORD *) &SecBuff[ThisFATEntOffset])) | FAT12ClusEntryVal;



NOTE: It is assumed that the >> operator shifts a bit value of 0 into the high 4 bits and that the << operator shifts a bit value of 0 into the low 4 bits.
The way the data of a file is associated with the file is as follows. In the directory entry, the cluster number of the first cluster of the file is recorded. The first cluster (extent) of the file is the data associated with this first cluster number, and the location of that data on the volume is computed from the cluster number as described earlier (computation of FirstSectorofCluster).
Note that a zero-length file—a file that has no data allocated to it—has a first cluster number of 0 placed in its directory entry. This cluster location in the FAT (see earlier computation of ThisFATSecNum and ThisFATEntOffset) contains either an EOC mark (End Of Clusterchain) or the cluster number of the next cluster of the file. The EOC value is FAT type dependant (assume FATContent is the contents of the cluster entry in the FAT being checked to see whether it is an EOC mark):


Yüklə 225,69 Kb.

Dostları ilə paylaş:
1   2   3   4   5   6   7   8   9




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©www.genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə