Index: sbin/fsck_msdosfs/fat.c =================================================================== --- sbin/fsck_msdosfs/fat.c +++ sbin/fsck_msdosfs/fat.c @@ -33,6 +33,8 @@ "$FreeBSD$"; #endif /* not lint */ +#include + #include #include #include @@ -623,30 +625,54 @@ case CLUST32_MASK: if (fat[cl].next == CLUST_FREE) boot->NumFree++; - *p++ = (u_char)fat[cl].next; - *p++ = (u_char)(fat[cl].next >> 8); - *p++ = (u_char)(fat[cl].next >> 16); - *p &= 0xf0; - *p++ |= (fat[cl].next >> 24)&0x0f; + le32enc(p, fat[cl].next | 0xF0000000); + p += 4; break; case CLUST16_MASK: if (fat[cl].next == CLUST_FREE) boot->NumFree++; - *p++ = (u_char)fat[cl].next; - *p++ = (u_char)(fat[cl].next >> 8); + le16enc(p, fat[cl].next); + p += 2; break; default: if (fat[cl].next == CLUST_FREE) boot->NumFree++; - *p++ = (u_char)fat[cl].next; - *p = (u_char)((fat[cl].next >> 8) & 0xf); + le16enc(p, fat[cl].next & 0xfff); + p++; cl++; if (cl >= boot->NumClusters) break; if (fat[cl].next == CLUST_FREE) boot->NumFree++; - *p++ |= (u_char)(fat[cl + 1].next << 4); - *p++ = (u_char)(fat[cl + 1].next >> 4); + /* + * Pack the 2nd 12-bit cluster, if there is one. + * + * Currently: + * [ cl-1:next ][ zeros ] + * Bits: mmmmmmmm mmmm0000 00000000 + * ^ ^ ^ + * | | (p+1) + * | p; high 4b of cl-1:next + * (p-1); low 8b of cl-1:next + * + * We want to store the 12 bit cl:next at p + half a + * byte. But we can only point to bytes in C. + * + * Instead, create a full 16 bit value to store at p. + * It is composed of the 12 bit cl:next pointer, + * appended with the existing upper 4 bits from the + * cl-1:next pointer at *p. Store it over p. + */ + le16enc(p, ((fat[cl].next & 0xfff) << 4) | *p); + p += 2; + /* + * The result is: + * + * [ cl-1:next ][ cl:next ] + * Bits: mmmmmmmm mmmmCCCC CCCCCCCC + * ^ + * p + */ break; } }