参考资料:
1.Microsoft Extensible Firmware Initiative FAT32 File System Specification
FAT文件的规格说明书,有人译成了中文版。
2.http://www.codeproject.com/Articles/138888/Getting-the-File-System-Image-and-Deleted-Data-Rec
This article describes the process of recovering of deleted data from the flash drive
3. 一个工具 HxD可以用来看磁盘的扇区。http://mh-nexus.de
几个难点问题:
1.FAT12,FAT16,FAT32
FAT12是用来格式化小于4.1M的软盘的。
FAT16最大支持2G的盘。
FAT32,如果空间大于512M, Microsoft会用FAT32格式化此硬盘。>32.5时才有可能格式化成FAT32.
2.FAT文件系统的4个区域以及这四个区域开始扇区和大小的计算:
0 – Reserved Region
1 – FAT Region
2 – Root Directory Region (doesn’t exist on FAT32 volumes)
3 – File and Directory Data Region
第一个扇区也就是前512个字节需要根据FAT32和FAT的不同,用不同的结构来进行设置。FAT文件的规格说明书中有详细说明。
BPB_RsvdSecCnt:如果是FAT12/16,设置成1, 如果是FAT32,一般是设置成32.
BPB_RootEntCnt:如果是FAT12/16,设置成512, 如果是FAT32,一般是设置成0.
BPB_HiddSec:如果是FAT12/16,设置成0, 如果是FAT32,一般是设置成1.
FAT32所独有的数据:
BPB_RootClus:Thisis set to the cluster number of the first cluster of the root directory,usually 2 but not required to be 2.
BPB_FSInfo: Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.当为1时,就在第一个512字节后面。
BPB_BkBootSec:,indicates the sector number in the reserved area of the volume of a copy of theboot record. Usually 6.
3.FAT表大小的计算和初始化
FAT表所占的扇区数计算:
RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
TmpVal1 = DskSize – (BPB_ResvdSecCnt + RootDirSectors);
TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs;
If(FATType == FAT32)
TmpVal2 = TmpVal2 / 2;
FATSz = (TMPVal1 + (TmpVal2 – 1)) / TmpVal2;
If(FATType == FAT32) {
BPB_FATSz16 = 0;
BPB_FATSz32 = FATSz;
} else {
BPB_FATSz16 = LOWORD(FATSz);
/* there is no BPB_FATSz32 in a FAT16 BPB */
}
FAT表开始扇区计算:
如果是FAT12/16: 第二个扇区, 紧跟在0扇区后面。
如果是FAT32:BPB_RsvdSecCnt
4.BPB_FSInfo数据的设置
BPB_FSInfo所在的扇区一般设置为1,这样可以直接根据设置值得到扇区位置。
5.root directory的初始化
所在扇区的计算:如果是FAT12/16: FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16); 如果是FAT32:FirstRootDirSecNum =BPB_RootClus*BPB_SecPerClus
6.BPB_SecPerClus的设置
struct DSKSZTOSECPERCLUS {
DWORD DiskSize;
BYTE SecPerClusVal;
};
/*
*This is the table for FAT16 drives. NOTE that this table includes
* entries for disk sizes larger than 512 MB even though typically
* only the entries for disks < 512 MB in size are used.
* The way this table is accessed is to look for the first entry
* in the table for which the disk size is less than or equal
* to the DiskSize field in that table entry. For this table to
* work properly BPB_RsvdSecCnt must be 1, BPB_NumFATs
* must be 2, and BPB_RootEntCnt must be 512. Any of these values
* being different may require the first table entries DiskSize value
* to be changed otherwise the cluster count may be to low for FAT16.
*/
DSKSZTOSECPERCLUS DskTableFAT16 [] = {
{ 8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */
{ 32680, 2}, /* disks up to 16 MB, 1k cluster */
{ 262144, 4}, /* disks up to 128 MB, 2k cluster */
{ 524288, 8}, /* disks up to 256 MB, 4k cluster */
{ 1048576, 16}, /* disks up to 512 MB, 8k cluster */
/* The entries after this point are not used unless FAT16 is forced */
{ 2097152, 32}, /* disks up to 1 GB, 16k cluster */
{ 4194304, 64}, /* disks up to 2 GB, 32k cluster */
{ 0xFFFFFFFF, 0} /* any disk greater than 2GB, 0 value for SecPerClusVal trips an error */
};
/*
* This is the table for FAT32 drives. NOTE that this table includes
* entries for disk sizes smaller than 512 MB even though typically
* only the entries for disks >= 512 MB in size are used.
* The way this table is accessed is to look for the first entry
* in the table for which the disk size is less than or equal
* to the DiskSize field in that table entry. For this table to
* work properly BPB_RsvdSecCnt must be 32, and BPB_NumFATs
* must be 2. Any of these values being different may require the first
* table entries DiskSize value to be changed otherwise the cluster count
* may be to low for FAT32.
*/
DSKSZTOSECPERCLUS DskTableFAT32 [] = {
{ 66600, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */
{ 532480, 1}, /* disks up to 260 MB, .5k cluster */
{ 16777216, 8}, /* disks up to 8 GB, 4k cluster */
{ 33554432, 16}, /* disks up to 16 GB, 8k cluster */
{ 67108864, 32}, /* disks up to 32 GB, 16k cluster */
{ 0xFFFFFFFF, 64}/* disks greater than 32GB, 32k cluster */
};
由磁盘的大小可以根据上面的表来设置BPB_SecPerClus, 设置好后可以计算得到数据区的clusters,下面是Windows对数据区clusters的规定.
以下的代码并不用包含在RamDisk的驱动中。
RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
If(BPB_FATSz16 != 0)
FATSz = BPB_FATSz16;
Else
FATSz = BPB_FATSz32;
If(BPB_TotSec16 != 0)
TotSec = BPB_TotSec16;
Else
TotSec = BPB_TotSec32;
DataSec = TotSec – (BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors);
CountofClusters = DataSec / BPB_SecPerClus;
If(CountofClusters < 4085) {
/* Volume is FAT12 */
} else if(CountofClusters < 65525) {
/* Volume is FAT16 */
} else {
/* Volume is FAT32 */
}
This is the one and only way that FAT type is determined. There is no such thing as a FAT12 volume that has more than 4084 clusters. There is no such thing as a FAT16 volume that has less than 4085 clusters or more than 65,524 clusters. There is no such thing as a FAT32 volume that has less than 65,525 clusters. If you try to make a FAT volume that violates this rule, Microsoft operating systems will not handle them correctly because they will think the volume has a different type of FAT than what you think it does.