开机自检程序在FAT32上做的检查与修复工作

来源:互联网 发布:360软件助手不见了 编辑:程序博客网 时间:2024/06/05 03:31

      文章前提是建立在读者对FAT32文件系统了解的情况下。什么时候Windows开机会磁盘自检?Dirty BIT 标志,那么这个DirtyBit在哪呢?当前分区偏移0x41(只针对FAT32,NTFS就不是了),由于FAT32文件系统驱动是开源的,从FASTFAT工程里可以得到:

typedef struct _PACKED_BOOT_SECTOR_EX {    UCHAR Jump[3];                                  // offset = 0x000   0    UCHAR Oem[8];                                   // offset = 0x003   3    PACKED_BIOS_PARAMETER_BLOCK_EX PackedBpb;       // offset = 0x00B  11    UCHAR PhysicalDriveNumber;                      // offset = 0x040  64    UCHAR CurrentHead;                              // offset = 0x041  65    UCHAR Signature;                                // offset = 0x042  66    UCHAR Id[4];                                    // offset = 0x043  67    UCHAR VolumeLabel[11];                          // offset = 0x047  71    UCHAR SystemId[8];                              // offset = 0x058  88} PACKED_BOOT_SECTOR_EX;                            // sizeof = 0x060  96

具体步骤如下:

1.       校验FAT表项的数目不能小于boot所在序号

2.       校验media_byte发现问题并根据实际情况修正,这个字节是用来标示磁盘大类的比如:软盘,光盘,U盘,还是硬盘

3.       遍历FAT表找到有问题的表项并把它指向表尾,有问题的表项是指,指针在FAT表以外,不是空闲项,不是坏簇,不是文件结尾,不是保留项。

4.       校验FAT表第一项的值一定要与mediabyte相同,不相同的话,修正回去

5.       遍历查找EA文件

6.       校验EA文件

7.       遍历整个目录树把目录项

a)       把最后一个目录项继续向后遍历把后面的目录项设成目录终结。(有点没道理,不过他这么做的原因应该是把系统截断残留的可能导致错误的痕迹抹掉)。

b)       遍历出来的中间每一个被删除过的目录项,如果有长文件名的话清除他们的长文件名项

c)       针对有长文件名的项做短文件名与长文件名记录中校验和的比较,长文件名项中的文件起始簇判断是否一定为0(因为文件起始是记在短文件名那里),校验长文件名,顺序号

d)       长文件名是否是有效的C字符串

e)       以上如都发现有问题就把该项删掉

8.       针对目录项所指向的文件数据信息进行校验:

a)       指向的文件如果是目录的话,目录项里文件大小就一定为0

b)       从文件起始簇位置开始遍历,如果发现途中的簇是空闲的或不在FAT表内的,就认识有问题,把整个目录项和这个文件删掉。

c)       如果指向文件是目录的话,遍历这个目录的FAT表,看有没有表项是空闲或指向FAT表之外的

d)       不管是不是目录都遍历FAT表,是否有坏簇,用的是读方法底层实现看不到(有待于研究,可能是IOCTL_DISK_VERTIFY),有的话会找其它表项替换(如果替换失败就把它删了,这个地方可能有出入)

e)       校验文件大小,如果不在所占的簇的大小以及其减一的区间内,认为有问题,把文件大小设置成所占磁盘空间的大小。

9.       目录项中判断是目录但起始簇为0,是目录但不是”..”的话,认为是错误,删了它

10.   对交叉链接的检查:遍历FAT表,用一BITMAP打点,发现交叉链接切断它。

11.   整理EA文件

12.   清除“孤立文件”,就是把上面遍历打点以外的有效项(不是空闲的),他们在文件系统中没有用到,把它们找出来,有两种归宿1. 变成空闲 2. 找出来放到FoundXXX.XXX文件中。

13.   如果严格的话,检查所有空闲的簇有没有坏的,有的话标记。

14.   把DIRTY_BIT清掉,自检完成。


有几点需要说明的是:

EA文件,FAT32文件系统不支持权限控制,但在WINDOWS初期为了兼容OS/2硬加上去的一个特性,后来都不用了,从FASTFAT里的代码都能看到,不支持了。那为什么autochk还要做呢,其实这些代码已经写了20年了,为了保证稳定和兼容基本没怎么动过。

怎么检查磁盘上的坏扇区呢?有两个方法,1.标准方法利用ZwDeviceIoControlFile +IOCTL_DISK_VERIFY发给磁盘设备对象的,应该是由小端口驱动来实现对坏扇区的检测,速度比较快。2.读的方法,读取每个扇区的数据,看是否有失败或超时发生。