exfat文件系统相关数据结构以及数据恢复方法

exFAT(扩展FAT)是Microsoft在Windows Embeded 6.0中引入的一种适合于闪存的文件系统。对于闪存,NTFS文件系统过于复杂,exFAT更为适用。

  相对FAT文件系统,exFAT有如下好处:

  •增强了台式电脑与移动设备的互操作能力

  •没有文件大小4G的限制(具体多大MS没有给出,wiki上的介绍有误)

  •簇大小可高达32MB

  •采用了剩余空间分配表,剩余空间分配性能改进

  •同一目录下最大文件数超过1000个

  •支持访问控制

  •支持TFAT

  采用该文件系统的闪存盘不支持Windows Vista ReadyBoost。Windows Vista SP1支持该文件系统。
XP系统(SP3)下不能认识exFAT格式的U盘!

2 exfat文件系统相关的数据结构

#define EXFAT_FIRST_DATA_CLUSTER 2
#define EXFAT_CLUSTER_FREE 0 /* free cluster */
#define EXFAT_CLUSTER_BAD 0xfffffff7 /* cluster contains bad block */
#define EXFAT_CLUSTER_END 0xffffffff /* final cluster of file or directory */

struct exfat_super_block
{
uint8_t jump[3]; /* 0x00 jmp and nop instructions */
uint8_t oem_name[8]; /* 0x03 "EXFAT " */
uint8_t __unknown1[53]; /* 0x0B ? always 0 */
le64_t block_start; /* 0x40 partition first block */
le64_t block_count; /* 0x48 partition blocks count */
le32_t fat_block_start; /* 0x50 FAT first block */
le32_t fat_block_count; /* 0x54 FAT blocks count */
le32_t cluster_block_start; /* 0x58 first cluster block */
le32_t cluster_count; /* 0x5C total clusters count */
le32_t rootdir_cluster; /* 0x60 first cluster of the root dir */
le32_t volume_serial; /* 0x64 */
le16_t __unknown2; /* 0x68 version? always 0x00 0x01 */
le16_t volume_state; /* 0x6A */
uint8_t block_bits; /* 0x6C block size as (1 << n) */
uint8_t bpc_bits; /* 0x6D blocks per cluster as (1 << n) */
uint8_t __unknown3; /* 0x6E ? always 1 */
uint8_t __unknown4; /* 0x6F drive number? always 0x80 */
uint8_t allocated_percent; /* 0x70 percentage of allocated space */
uint8_t __unknown5[397]; /* 0x71 padding? all zero */
le16_t boot_signature; /* the value of 0xAA55 */
};

#define EXFAT_ENTRY_VALID 0x80
#define EXFAT_ENTRY_CONTINUED 0x40

#define EXFAT_ENTRY_EOD (0x00)
#define EXFAT_ENTRY_BITMAP (0x01 | EXFAT_ENTRY_VALID)
#define EXFAT_ENTRY_UPCASE (0x02 | EXFAT_ENTRY_VALID)
#define EXFAT_ENTRY_LABEL (0x03 | EXFAT_ENTRY_VALID)
#define EXFAT_ENTRY_FILE (0x05 | EXFAT_ENTRY_VALID)
#define EXFAT_ENTRY_FILE_INFO (0x00 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED)
#define EXFAT_ENTRY_FILE_NAME (0x01 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED)

struct exfat_entry /* common container for all entries */
{
uint8_t type; /* any of EXFAT_ENTRY_xxx */
uint8_t data[31];
};

#define EXFAT_ENAME_MAX 15

struct exfat_entry_bitmap /* allocated clusters bitmap */
{
uint8_t type; /* EXFAT_ENTRY_BITMAP */
uint8_t __unknown1[19];
le32_t start_cluster;
le64_t size; /* in bytes */
};

struct exfat_entry_upcase /* upper case translation table */
{
uint8_t type; /* EXFAT_ENTRY_UPCASE */
uint8_t __unknown1[3];
le32_t checksum;
uint8_t __unknown2[12];
le32_t start_cluster;
le64_t size; /* in bytes */
};

struct exfat_entry_label /* volume label */
{
uint8_t type; /* EXFAT_ENTRY_LABEL */
uint8_t length; /* number of characters */
le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
};

#define EXFAT_ATTRIB_RO 0x01
#define EXFAT_ATTRIB_HIDDEN 0x02
#define EXFAT_ATTRIB_SYSTEM 0x04
#define EXFAT_ATTRIB_VOLUME 0x08
#define EXFAT_ATTRIB_DIR 0x10
#define EXFAT_ATTRIB_ARCH 0x20

struct exfat_entry_meta1 /* file or directory info (part 1) */
{
uint8_t type; /* EXFAT_ENTRY_FILE */
uint8_t continuations;
le16_t checksum;
le16_t attrib; /* combination of EXFAT_ATTRIB_xxx */
le16_t __unknown1;
le16_t crtime, crdate; /* creation date and time */
le16_t mtime, mdate; /* latest modification date and time */
le16_t atime, adate; /* latest access date and time */
uint8_t crtime_cs; /* creation time in cs (centiseconds) */
uint8_t mtime_cs; /* latest modification time in cs */
uint8_t __unknown2[10];
};

#define EXFAT_FLAG_FRAGMENTED 1
#define EXFAT_FLAG_CONTIGUOUS 3

struct exfat_entry_meta2 /* file or directory info (part 2) */
{
uint8_t type; /* EXFAT_ENTRY_FILE_INFO */
uint8_t flag; /* fragmented or contiguous */
uint8_t __unknown1;
uint8_t name_length;
le16_t name_hash;
le16_t __unknown2;
le64_t real_size; /* in bytes, equals to size */
uint8_t __unknown3[4];
le32_t start_cluster;
le64_t size; /* in bytes, equals to real_size */
};

struct exfat_entry_name /* file or directory name */
{
uint8_t type; /* EXFAT_ENTRY_FILE_NAME */
uint8_t __unknown;
le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
};

你可能感兴趣的:(文件系统)