STER Cluster1 REG CLUSTER Cluster2struct buffer FAR bpunsigned idxunsigned secdivunsigned char wasfree 0CLUSTER clussec Cluster1/这么多簇有多少扇区/CLUSTER max_cluster dpbp-gtdpb_size/最大簇号/ifdef WITHFAT32if ISFAT32dpbp max_cluster dpbp-gtdpb_xsizeendif/当前索引的簇值肯定是要在当前盘的空间内的,如果超过了(包括两边),就返回,并报错/if clussec lt 1 clussec gt max_cluster put_stringquotrun CHKDSK: trying to
access invalid cluster 0xquotifdef WITHFAT32 put_unsignedunsignedclussec gtgt 16 16 4endif/put_unsigned函数是将一个十进制的字符串数转化成为2进制或者是16进制的表示方法,非常巧妙/ put_unsignedunsignedclussec amp 0xffffu 16 4 put_console/n return 1/dpb-gtdpb_secsize是当前驱动盘的扇区大小为什么要用secdiv做变量我还不是很清楚可能是secctor divide因为下面做除法了 /secdiv dpbp-gtdpb_secsizeif ISFAT12dpbp/这好像要看官方文档,看 fat12的簇大小是多少的一个簇=一个扇区=512字节,// 这里一个2,一个3,注意的是1.5=3/2,就是一个fat要占用的字节数, 我突然想到baidu知道上不知道是谁说fat12的簇含有4个扇区 / clussec unsignedclussec 3 secdiv 2/暂且只讨论fat12/else / FAT16 or FAT32 / secdiv / 2ifdef WITHFAT32 if ISFAT32dpbp secdiv / 2endif/ idx is a pointer to an index which is the nibble offset of the FAT entry within the sector for FAT12 or word offset for FAT16 or dword offset for FAT32 //我认为下面的代码就是计算偏移,化整为零/idx unsignedclussec secdiv/没有构成一个扇区/clussec / secdiv/还有多少个整数扇区//曾经做过一个计算题,好像fat表项可以是很大的,可以有几兆的/clussec dpbp-gtdpb_fatstrt/绝对扇区地址/ifdef WITHFAT32if ISFAT32dpbp ampamp dpbp-gtdpb_xflags amp FAT_NO_MIRRORING / we must modify the active fat its number is in the 0-3 bits of dpb_xflags / clussec dpbp-gtdpb_xflags amp 0xf dpbp-gtdpb_xfatsizeendif/ Get the block that this cluster is in //读一个block到一个缓冲区,返回的是缓冲区的首地址但是比较特殊的是/ / 它返回的是一个512字节长度的fat表项 /bp getFATblockdpbp clussec/没有读成功,自然要返回也就是读fat表项没有成功,可能是别的错误之类的/if bp NULL return 1 / the only error code possible here (他是说这是这个函数里面唯一的错误信息不过好像确实是的//针对fat12特别处理,可以看到下面每种文件系统都做了处理,我在想,如果我要加入ntfs怎么办?/if ISFAT12dpbp REG UBYTE FAR fbp0 FAR fbp1 struct buffer FAR bp1 unsigned cluster cluster2 / form an index so that we can read the block as a / / byte array //idx上面操作得到的在簇里面的第几个扇区 fat12文件系统一个簇=一个扇区 第n个fat目录项: n为偶数:低四位3n/2,高四位3n/21 n为奇数:低四位 一个簇=??? 一个扇区=512字节 一个fat表项=12位=1.5位 idx是在原有的簇的基础上还要移动几个扇区的索引 一个buffer的大小就是一个扇区的大小 / idx / 2 / Test to see if the cluster straddles the block. If / / it does get the next block and use both to form the / / the FAT word. Otherwise just point to the next / / block.测试这个簇是否跨越了这个块,如果是这样的话,得到下个块, 用这两个簇形成一个fat字 //sizeofb_buffer512BPRIampgtPRI-gt/ fbp0 ampbp-gtb_bufferidx / pointer to next byte will be overwritten if not valid //如果是跨越的话,就是越界的访问了吧我的意思没有意思的访问/ fbp1 fbp0 1/如果这时候是跨越了的话,那么就要读下一个块,那么fbp1是无效的,而是需要重新赋值//因为是必须要读2个字节的,idx只是开始字节地址/ if idx gt unsigneddpbp-gtdpb_secsize - 1 / blockio.c LRU logic ensures that bp bp1 这话我还没懂,希望懂的人能解释下/ bp1 getFATblockdpbp unsignedclussec 1 if bp1 0 return 1 / the only error code possible here //我看到现在只要看过READ_CLUSTER/ if unsignedCluster2 READ_CLUSTER bp1-gtb_flag BFR_DIRTY BFR_VALID /fbp1指向下个byte/ fbp1 ampbp1-gtb_buffer0 /fbp1只是unsigned char阿?总共也就8位的,左移8位还有吗??//高高低低原则/ cluster fbp0 fbp1 ltlt 8 unsigned res cluster / Now to unpack the contents of the FAT entry. Odd and / / even bytes are packed differently. //如果要寻找的idx是奇数的话,则要/ if Cluster1 amp 0x01 cluster gtgt 4 cluster amp 0x0fff/因为我只要看获取一个空闲fat,所以我就看到了这里 当fat项是0时候,说明是空闲的 / if unsignedCluster2 READ_CLUSTER if cluster gt MASK12 return LONG_LAST_CLUSTER if cluster BAD12 return LONG_BAD return cluster /如果不是在寻找空闲的fat那么可以计算空闲的fat/ if cluster FREE wasfree cluster res / Cluster2 may be set to LONG_LAST_CLUSTER 0x0FFFFFFFUL or 0xFFFF / / -- please dont remove this mask / cluster2 unsignedCluster2 amp 0x0fff / Now pack the value in / if Cluster1 amp 0x01 cluster amp 0x000f cluster2 ltlt 4 else cluster amp 0xf000 cluster cluster2 fbp0 UBYTEcluster fbp1 UBYTEcluster gtgt 8else .