exFAT 文件系统格式

时间:2021-02-17 16:06:36
前言:
         SD卡 3.0 标准推出后,SD卡往高容量发展,这个时候 FAT,FAT32 已经不符合SDHD的需求了,
这时引进了新的文件系统 ---> exFAT。


如果哪里有翻译不正确的地方,希望大家指出来,谢谢!

原版内容在这里:
http://www.ntfs.com/exfat-overview.htm





一、exFAT 和 FAT32 比较

支持                                                    Fat32                                exFat
============================================
磁盘最大卷                                          8TB *                               128PB
最大文件大小                                     4GB                                     16EB
最大簇大小                                       32KB**                                 32M
最大簇数                                           2^28                                    2^32
最大文件名长度                                 255                                      255
时间日期分辨率                                 2S                                        10ms
MBR分区类型定义                            0x0B,0x0C                            0x07

注释:
* windows 无法格式化大于等于32G的Fat32的卷,虽然第三方可以可以格式化最大容支持到 16TB,以64KB每簇大小。
** 微软补丁 KB184006 设置每簇大小不超过 32kB,某些第三方格式化簇可以支持 64KB

参考:
KB184006 FAT32 文件系统的限制:
http://support.microsoft.com/kb/184006

二、卷结构分析

offset,sectors                size, sectors                          block                          注释
===================================================
                                                   主引导区域
------------------------------------------------------------------------------------------------------
0                                     1                                    引导扇区
1                                     8                                    扩展引导扇区
9                                     1                                    OEM 信息记录
10                                   1                                    保留
11                                   1                                    引导校验扇区
------------------------------------------------------------------------------------------------------
                                              主引导记录备份区域
------------------------------------------------------------------------------------------------------
12                                   1                                    引导扇区
13                                   8                                    扩展引导扇区
9                                     1                                    OEM 信息记录
10                                   1                                    保留
11                                   1                                    引导校验扇区
------------------------------------------------------------------------------------------------------
                                              FAT 记录区域
------------------------------------------------------------------------------------------------------
24                           fatoffset - 24                           FAT队列                      引导扇区记录了 fatoffset
fatoffset                  fatLength                                 First Fat                      引导扇区记录了 fatoffset  fatLength
FatOffset +
    FatLength           FatLength                                Second FAT                 For TexFAT only
------------------------------------------------------------------------------------------------------
                                            数据记录区域
------------------------------------------------------------------------------------------------------
offset,sectors :   FatOffset + FatLength * NumberOfFats
Size, sectors   :   ClusterHeapOffset – (FatOffset + FatLength * NumberOfFats)
Block              :  Cluster Heap Alignment

offset,sectors :   ClusterHeapOffset
Size, sectors   :   ClusterCount * 2^SectorsPerClusterShift
Block              :  Cluster Heap

offset,sectors : ClusterHeapOffset + ClusterCount * 2^SectorsPerClusterShift
Size, sectors   : VolumeLength – (ClusterHeapOffset + ClusterCount * 2^SectorsPerClusterShift)
Block              : Excess Space

2.1.1 引导扇区:

偏移量                            大小                           目标                                         注释
============================================================
0                                      3                               Boot 跳转指令                         0xEB7690
3                                      8                               文件系统名称                          “EXFAT”
11                                    53                             必须为 0
64                                    8                               分区偏移位置                           单位扇区,假如0则忽略
72                                    8                               卷长度                                      exFAT卷大小,单位扇区
80                                    4                               FAT Offset                                 单位扇区
84                                    4                               Fat Length                                单位扇区
                                                                         May exceed the required space in order to align the second FAT
88                                    4                               ClusterHeapOffset                     单位扇区
92                                    4                               ClusterCount                            最大簇为 2^32-11
96                                    4                               RootDirectoryCluster
100                                  4                               卷序号
104                                  2                               文件系统版本                           高位主版本号,低位次版本号,如 01.00
106                                  2                               卷标志              
                                                                         bit0     size 1     0 第一FAT 1 第二FAT                 
                                                                         bit1     size 1     0 空          1 有内容
                                                                         bit2     size 1     0 不支持或被记录坏簇   1 某些读写操作失败
                                                                         bit3     size 1     清空为零
                                                                         bit4     size12    保留
108                                  1                               BytesPerSectorShift                 最小 9   (512字节每扇区)
                                                                                                                        最大 12 (4096字节每扇区)
109                                  1                               SectorsPerCluster Shift            最小  0   (每簇一扇区)
                                                                                                                        最大 25- SectorsPerCluster Shift
110                                  1                               NumberOfFats                         TexFAT 为 2
111                                  1                               DriveSelect                              0x80
112                                  1                               PercentInUse                           0..100, 0xFF- PercentInUse 代表不可用
113                                  7                               保留
120                                  390                           引导代码
510                                  2                               引导标记                                 0xAA55
512                    2^BytesPerSectorShift - 512   扩展空间

2.1.2  扩展引导扇区

偏移量                                     大小                                        目标                                           注释
================================================================
0                                            2^BytesPerSectorShift - 4        扩展引导代码
2^BytesPerSectorShift - 4     4                                              扩展引导标记                            0xAA550000

2.1.3  OEM 信息记录

偏移量            大小                       目标                                           注释
================================================================
0                     16                         参数类型                                    OEM_FLASH_PARAMETER_GUID
                                                                                                      空代表不使用

16                   32                         参数值                                        OEM 定义

具体结构如下:

[cpp] view plain copy print?
  1. #define OEM_FLASH_PARAMETER_GUID 0A0C7E46-3399-4021-90C8-FA6D389C4BA2  
  2.     struct  
  3.     {  
  4.     GUID OemParameterType;     //Value is OEM_FLASH_PARAMETER_GUID  
  5.     UINT32 EraseBlockSize;     //Erase block size in bytes  
  6.     UNIT32 PageSize;       
  7.     UNIT32 NumberOfSpareBlocks;  
  8.     UNIT32 tRandomAccess;     //Random Access Time in nanoseconds  
  9.     UNIT32 tProgram;     //Program time in nanoseconds  
  10.     UNIT32 tReadCycle;     //Serial read circle time in nanoseconds  
  11.     UNIT32 tWriteCycle;     //Write Cycle time in nanoseconds  
  12.     UCHAR Reserved[4];  
  13.     }  
  14.     FlashParameters;  

2.1.4  引导校验扇区

校验扇区包含前面11个扇区做32位校验,其中不包含引导扇区的 106、107、112字节。
具体算法代码如下:

[cpp] view plain copy print?
  1. UNIT32 BootChecksum(constunsignedchardata[], intbytes)  
  2.     {  
  3.     UINT32 checksum   =   0;  
  4.     for (inti = 0; i < bytes; i++)  
  5.     {  
  6.     if (i == 106 || i == 107 || i == 112)  
  7.     continue;  
  8.     checksum = (checksum<< 31) | (checksum>> 1) + data[i];  
  9.     }  
  10.     returnchecksum;  
  11.     }  

2.2.1 文件分配表 (FAT)

文件分配表可能有1个或2个FAT组成,它定义在 NumberOfFats  项中,
ActiveFat 单元在引导扇区的 VolumeFlags 中,已确定 FAT是否活动。

第一个簇是 cluster 2开始,像 FAT32 一样, 每个 FatEntry代表一个簇。

在 exFAT 中 ,FAT 表不用于追踪是否分配,用Allocation Bitmap来替代它,
FAT用来维护碎片文件簇的交叉链,假如文件没有碎片,FAT表则不需要更新。
一个 Directory Entry 扩展流将被用于确定FAT交叉链是否有效,假如不需要则为空


偏移量                                     大小                    目标                                           注释
================================================================
0                                             4                          FatEntry[0]                               媒体类型(0xFFFFFFF8)
4                                             4                          FatEntry[1]                               0xFFFFFFFF
8                                             4                          FatEntry[2]                               第一个簇
.............
(ClusterCount + 1) * 4            4                          FatEntry[ClusterCount +1]        最后一个簇
(ClusterCount + 2) * 4            剩余扇区              剩余空间

FatEntry 内容如下:

[cpp] view plain copy print?
  1. •0x00000002 – ClusterCount +1 (max 0xFFFFFFF6) – next cluster in the chain  
  2. •0xFFFFFFF7 – bad cluster  
  3. •0xFFFFFFF8 – media descriptor  
  4. •0xFFFFFFFF – end of file (EOF mark)  

值 0x00000000 不代表簇没有被使用,它是一个没有被定义的值。
第二个文件分区表(只有TexFat时使用),排在第一个文件分配表之后,而且和第一个文件分配表大小相同。


2.2.2  簇堆(Cluster Heap)
簇堆是exFAT文件系统设置簇是否保存数据的地方,其构造如下

[cpp] view plain copy print?
  1. •Root Directory  
  2. •Files  
  3. •Directories  
  4. •Bitmap Allocation Table  
  5. •UP-Case Table  

簇的分配状态由簇堆自己的 Bitmap Allocation Table 追踪。

2.2.2.1  Allocation Bitmap
Allocation Bitmap 记录簇的分配状他. FAT的使用目的不像 FAT16/FAT32文件系统.
Allocation Bitmap 有8位字节组成,每一位代表一个数据记录簇。
假如它有一位为1代表该簇已被使用,0则为没有被使用。最低位代表第一个簇

偏移量                                     大小                    目标                                           注释
================================================================
0x00                                       1                         1st byte                                     Clusters 2-9
0x01                                       1                         2nd byte                                    Clusters 10-17
0x02                                       1                         3rd byte                                     Clusters 18-25
...................

Bitmap allocation table 在簇堆中和  Bitmap Directory entry在Root Directory中。
在 TexFAT中有2个 Bitmap allocation table ,其他则是1个Bitmap allocation table 。
在引导扇区的NumberOfFats项中记录 root directory 和 Allocation Bitmaps条目是否有效。

2.2.2.2  Up-case Table
Up-case table 数据构造使用 forconversion  字符小写转大写,文件名目录入口使用 Unicode 字符存储长文件名。
exFAT本身不区分大小写,所以它搜索文件名时比较文件名需要转大写,通常位于Bitmap Allocation table 之后,
但可以放在簇堆的任何地方,它有个关键directory entry在root directory中。
Up-case Table 是一个 Unicode 字符的数组,索引需要Unicode字符的大写,Up-case Table 强制包含 128 Unicode 映射值。
如果强制支持  128 字符,Up-case Table剩余部分可以被忽略,当文件名大写是大写字符只来之强制 128字符大写结构,
其它字符不变,非强制集合字符比较文件名,这些文件名应该认为相等。

序号             值                    注释
===============================================================
0x0000        0x0000
0x0001        0x0001
0x0002        0x0002
.........
0x0041        0x0041            "A"自我映射(identity 映射)
0x0042        0x0042            "B"自我映射
.........
0x0061        0x041               ‘a’映射到“A”(non-identity 映射)
0x0062        0x042               ‘b’映射到“B”
.........
Up-case Table 可以写入压缩格式,identity 映射用0xFFFF表示

Mandatory First 128 Up-case Table Entries
序号             表项
===============================================================
0000           0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
0010           0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F
0020           0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F
0030           0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F
0040           0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F
0050           0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F
0060           0060 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F
0070            0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 007B 007C 007D 007E 007F
Non-identity 映射高亮背景表示

Mandatory First 128 Up-case Table Entries in compressed format
序号             表项
===============================================================
0000          FFFF 0061 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F
0010          0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A   FFFF  0005

高亮背景第一个 0x0061 代表 (0x0000-0x0060)字符,然后 0x0061映射到 0x0041 直到 下一个压缩组。


2.2.2 目录结构
exFAT 使用树状结构来描述文件和目录之间的关系。根目录树定义目录在 RootDirectoryCluster 之中。
子目录单向连接到它,(.)和(..)目录指向自己本身和父目录这像 FAT16/FAT32一样。
每个 directory 包括一系列的目录条目,目录条目的优先等级如下:

[cpp] view plain copy print?
  1. •Primary Directory Entries   
  2.       1.Critical Primary Entries  
  3.       2.Benign Primary Entries  
  4.    
  5. •Secondary Directory Entries   
  6.       1.Critical Primary Entries  
  7.       2.Benign Primary Entries  

Critical entries 是必须项,benign entries是可选的,Primary directory entries对应文件系统中的条目,
Secondary directory entries 是 primary directory entry 数据扩展和关联。
一组 primary/secondary entries 组成 directory entry 设置文件或目录,
设置第一个 directory entry 为 primary directory entry,所有子条目必须是 Secondary directory entries 。

每个目录项都是从通用目录项中派生出来的,目录项的大小为 32个字节:

Generic Directory Entry Template  
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型
                                           bit            size             Description        Comments
                                           -------------------------------------------------------------
                                           0~4          5                code                 
                                           5              1                Importance       0 – Critical entry, 1 – Benign entry
                                           6              1                Category           0 – Primary entry, 1 – Secondary entry
                                           7              1               In use status       0 – Not in use, 1 – In use
1                19                     自定义
20              4                       第一簇                                                0 – 没有使用 2..ClusterCount+1 – cluster index   
24              8                       数据长度                                             单位字节

条目类型值如下:

[cpp] view plain copy print?
  1. •0x00 – End Of Directory marker. All other fields in directory entry are invalid.   
  2.              All subsequent directory entries are also End Of Directory markers  
  3. •0x01-0x7F (InUse = 0). All other fields in this entry are not defined  
  4. •0x81-0xFF (InUse = 1). Regular record with all fields defined.  


Generic Primary Directory Entry Template
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型
1                 1                      secondary entries 计数                        主目录项的次项的数目  0~255
2                 2                      SetChecksum                                      所有 directory entries 的校验和除了此项
                                                                                                      参考 EntrySetCheckSum ().
4                 2                      通用主项标志
                                            bit          size            Description                  Comments
                                           -------------------------------------------------------------------------------------
                                            0            1                AllocationPossible         0-not possible
                                                                                                                  (FirstCluster and DataLength 没定义)
                                                                                                               1-possible     
                                            1            1                NoFatChain                  0-FAT cluster chain is valid
                                                                                                                1-FAT cluster chain is not used (contiguous data)
                                            2            14              CustomDefined
6                14                      自定义
20              4                       第一簇  
24              8                       数据长度
所有 critical primary directory 位于根目录中(除了文件目录条目)
Benign primary directory 为可选项,假如一个 benign primary entry 不正确,所有目录条目将被忽略。

Generic Secondary Directory Entry Template
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                     条目类型
1                 1                     通用次项标志
                                            bit          size            Description                  Comments
                                           -------------------------------------------------------------------------------------
                                            0            1               AllocationPossible
                                            1            1               NoFatChain
                                            2            14             CustomDefined
2                18                     自定义
20              4                       第一簇  
24              8                       数据长度

Defined Directory Entries
EntryType            Primary               Critical                 Code                      Directory Entry
===============================================================
0x81                    •                         •                          1                            Allocation Bitmap
0x82                    •                         •                          2                            Up-case Table
0x83                    •                         •                          3                            Volume Label
0x85                    •                                                     5                            File
0xA0                    •                                                     0                           Volume GUID
0xA1                    •                                                     1                           TexFAT Padding
0xA2                    •                                                     2                           Windows CE Access Control Table
0xC0                                             •                            0                           Stream Extension
0xC1                                             •                            1                           File Name


Allocation Bitmap Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                     条目类型                                              0x81
1                 1                     BitmapFlags                                          Indicates which Allocation Bitmap the given entry describes
                                          bits    size     Description                       Comments
                                          --------------------------------------------------------------------------------------------
                                          0       1        Bitmapidentifier                 0 – 1st bitmap, 1 -2nd bitmap
                                          1       7        Reserved
2                 18                   保留字段
20              4                      第一簇  
24              8                      数据长度

bitmaps 数目 和 Bitmap Allocation entries 数等于FATs数,例如TexFAT中2个FATs,bit0 表示哪一个bitmap和FAT。
第一个Allocation Bitmap应该被第一个FAT使用,第二个Allocation Bitmap应该被第二个FAT使用
引导扇区 ActiveFat 定义哪个为活动的 bitmap和FAT。
Bitmap 的字节大小必须在卷中的一个簇整除以8和向上进位。

Up-Case Table Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                1                       条目类型                                               0x82
1                3                       保留字段1
4                4                        TableChecksum                                     Up-case 表校验和
8                12                     保留字段2
20              4                       第一簇  
24              8                       数据长度
校验和的计算方法代码如下:

[cpp] view plain copy print?
  1. UNIT32 UpCaseTableChecksum(constunsignedchardata[], intbytes)  
  2.  {  
  3. UINT32 checksum   =   0;   
  4. for (inti = 0; i < bytes; i++)  
  5.  checksum = (checksum<< 31) | (checksum>> 1) + data[i];  
  6. returnchecksum;  
  7.  }  

Volume Label Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                1                       条目类型                                               0x83
1                1                       字符数                                                  Unicode 字符长度 (最大 11)
2                22                     卷标                                                      Unicode 字符串
24              8                       保留字段
假如卷格式化后没有标识,Volume Label Directory Entry的条目类型应该设为 0x03 (不被使用)

File Directory Entry
File Directory Entry描述文件和目录内容,
It is a primary critical directory entry and must be immediately followed by 1 Stream Extension directory entry
and from 1 to 17 File Name directory entries .
Those 3-19 directory entries comprise a directory entry set describing a single file or a directory.
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型                                              0x85
1                 1                      SecondaryCount                                  必须设为 2 到 18
2                 2                      SetChecksum
4                 2                      文件属性
                                           bits    size     Attribute                      Comments
                                          --------------------------------------------------------------------------------------------  
                                           0       1         只读
                                           1       1         隐藏
                                           2       1         系统
                                           3       1         保留1
                                           4       1         目录
                                           5       1         存档
                                           6       10       保留2
6                2                       保留字段1
8                4                       创建时间
12              4                       最后修改时间
16              4                       最后访问时间
20              1                       创建 10ms 增量                                        0 .. 199
21              1                       最后修改 10ms 增量                                 0 .. 199
22              1                       创建时区偏移量                                        偏移量为UTC 15分钟递增
23              1                       最后修改时区偏移量                                 偏移量为UTC 15分钟递增     
24              1                       最后访问时区偏移量                                 偏移量为UTC 15分钟递增
25              7                       保留字段2

Timestamp Format
Bits            Size                    Description                                               Comments
---------------------------------------------------------------------------------------------------------------------------------
0-4             5                       秒(2秒计数单位)                                  0..29 (29 代表 58秒)
5-10           6                       分                                                             0..59
11-15         5                       小时                                                         0..23
16-20         5                       天                                                             0..31
21-24         4                       月                                                             1..12
25-31         7                       年(1980年起始)                                        0 代表 1980
Timestamp format  秒数是2秒计数,所以需要 10ms 增量来修正 2秒时间的精度,有效值是0..199。
Timestamp 记录本地时间时,时区偏移量为15分钟递增。

Time Zone Offset Table
TimezoneOffset field             TZ Offset                Time Zone                                       Comments
---------------------------------------------------------------------------------------------------------------------------------
128 (0x80)                          UTC                        Greenwich Standard Time
132 (0x84)                          UTC+01:00            Central Europe Time
136 (0x88)                          UTC+02:00            Eastern Europe Standard Time
140 (0x8C)                          UTC+03:00            Moscow Standard Time
144 (0x90)                          UTC+04:00            Ar* Standard Time
148 (0x94)                          UTC+05:00            WestAsiaStandardTime
152 (0x98)                          UTC+06:00            CentralAsiaStandardTime
156 (0x9C)                          UTC+07:00            NorthAsiaStandardTime
160 (0xA0)                          UTC+08:00            NorthAsiaEastStandardTime
164 (0xA4)                          UTC+09:00            TokyoStandardTime
168 (0xA8)                          UTC+10:00            WestPacificStandardTime
172 (0xAC)                          UTC+11:00            CentralPacificStandardTime
176 (0xB0)                          UTC+12:00            NewZealandStandardTime
180 (0xB4)                          UTC+13:00            TongaStandardTime
208 (0xD0)                          UTC-12:00             DatelineStandardTime
212 (0xD4)                          UTC-11:00             SamoaStandardTime
216 (0xD8)                          UTC-10:00             HawaiiStandardTime
220 (0xDC)                          UTC-09:00             AlaskaStandardTime
224 (0xE0)                           UTC-08:00             PacificStandardTime
228 (0xE4)                           UTC-07:00             MountainStandardTime
232 (0xE8)                           UTC-06:00             CentralStandardTime
236 (0xEC)                           UTC-05:00             EasternStandardTime
240 (0xF0)                           UTC-04:00              AtlanticStandardtime
242 (0xF2)                           UTC-03:00              NewfoundlandStandardTime
244 (0xF4)                           UTC-03:00              GreenlandStandardTime
248 (0xF8)                           UTC-02:00              Mid-AtlanticStandardTime         
252 (0xFC)                           UTC-01:00              AzoresStandardTime

Volume GUID Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型                                             0xA0
1                 1                      SecondaryCount                                 必须设 0
2                 2                      SetChecksum
4                 2                      GeneralPrimaryFlags
                                           bits    Size         Attribute                      Comments
                                           --------------------------------------------------------------------------------------------
                                            0        1           AllocationPossible         必须设 0
                                            1        1           NoFatChain                  必须设 0
                                            2        14         CustomDefined
6                 16                     VolumeGuid                                         所有值都有效,除了空的
                                                                                                       GUID{00000000-0000-0000-0000-000000000000}
22               10                     保留字段
这是一个benign primary directory entry 并可能在文件系统中不存在

TexFAT Padding Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型                                             0xA1
1                 31                    保留字段
exFat 1.00 没有定义  TexFAT Padding Directory Entry,TexFAT Padding Directory Entry只在目录第一个簇时有效
TexFAT Padding Directory Entry不能被移动。

Windows CE Access Control Table Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型                                             0xA2
1                 31                    保留字段
exFat 1.00 没有定义 Windows CE Access Control Table Directory Entry。

Stream Extension Directory Entry  
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型                                              0xC0
1                 1                      GeneralSecondaryFlags
                                           bits         size         Description              Comments
                                           --------------------------------------------------------------------------------------------
                                            0            1            AllocationPossible      必须设 1
                                            1            1            NoFatChain
                                            2            14          CustomDefined
2                 1                       保留字段1
3                 1                       NameLength                                        子文件目录项中的 Unicode 名字的长度
4                 2                       NameHash                                            大写文件名的 Hash 值
6                 2                       保留字段2
8                 8                       有效数据长度                                       必须设为0到数据长度之间
16               4                       保留字段3                                    
20               4                       第一簇  
24               8                       数据长度                                              目录最大 256 M

Stream Extension directory entry 必须跟在 File directory entry 设置项后,
它有可能只有1个Stream Extension directory entry
如果 NoFatChain 标志设置,所有的簇是连续的。

NameHash 字段用于文件名的快速比较和优化大写文件名,
NameHash 验证对不匹配,但是匹配哈希值,不能保证平等 offile 名称。
如果名称的哈希值匹配,必须执行后续的完整名称比较。

NameHash  算法代码如下:

[cpp] view plain copy print?
  1. // fileName points to up-cased file name  
  2. UNIT16 NameHash(WCHAR *file Name, intnameLength)  
  3.  {  
  4. UNIT16 hash = 0;  
  5. unsignedchar *data = ( unsignedchar*) fileName;  
  6.   
  7. for ( inti = 0; i<nameLenght*2; i++)  
  8.  hash = (hash << 15) | (hash >> 1) + data[i];  
  9. returnhash;  
  10.  }  

ValidDataLength  确定多少实际的数据写入到文件中。实施须更新此字段,如在写入数据。
有效的数据长度超出数据未定义和实施须返回零。

File Name Directory Entry
偏移量        大小                 目标                                                     注释
===============================================================
0                 1                      条目类型                                             0xC1
1                 1                      GeneralSecondaryFlags
                                           bits         size         Description              Comments
                                           --------------------------------------------------------------------------------------------
                                            0             1           AllocationPossible     必须设 0
                                            1             1           NoFatChain              必须设 0
                                            2             14         CustomDefined
2                30                     文件名

File Name directory entries 必须跟在 Steam Extension directory entry 后,数目 NameLength/15 向上舍入。
文件名称条目的最大数量是 17,每个可容纳最多 15 个 Unicode 字符和最大文件名称的长度是 255。未用的部分的文件名字段必须设置为 0x0000。

Invalid File Name Characters
Character Code                    Character                             Description
===============================================================
0x0000 – 0x001F                                                             Control codes
0x0022                                 “                                          Quotation mark
0x002A                                 ∗                                         Asterisk
0x002F                                  /                                          Forward slash
0x003A                                 :                                           Colon
0x003C                                 <                                         Less than
0x003E                                 >                                         Greater than
0x003F                                  ?                                         Question mark
0x005C                                 \                                          Back slash
0x007C                                 |                                          Vertical bar