当前位置: 代码迷 >> 综合 >> NTFS 之 LCN,VCN
  详细解决方案

NTFS 之 LCN,VCN

热度:11   发布时间:2023-12-13 08:31:52.0
NTFS 之 LCN,VCN
2010-03-26 14:02

NTFS,是随着WIN NT的第一个版本于1993年推出的文件系统;相对于传统的FAT文件系统,有很多的优越性。NTFS是一种“日志性”的文件系统,可以把改变文件的操作全部记录下来,因此也成为一种可恢复的文件系统;NTFS又是一种基于安全性的文件系统,同时在设计上节省存储资源,减少磁盘占用量。

下面具体而微,看一下ntfs中对逻辑簇号和数据长度的处理技术。
LCN表示在整个文件卷的相对位置;VCN表示文件内部的相对位置。假如一个文件占用m个簇,那么这些簇的VCN就是从0到(m-1)。
简单的来说,NTFS用MFT的文件记录块来记录文件,一个文件记录块是固定大小的1K;如果文件的数据域比较大,那么文件记录块的相应字段会记录数据域有几块簇链组成,并且记录每块簇链的{LCN,DataLen},NTFS里将这样的簇链称为run,即片段。

为了节省空间,run片段的描述项采用如下的结构

{首字节,LCN长度,DataLen长度}

简单的来说,描述项的第一个字节分前后两部分,每部分占4位,4位也就可以描述16位的长度了。那么,前4位记录LCN的长度所占用的字节数,后4位描述DataLen的长度所占用的字节数。用这种方法来节省存储空间。

举个例子:
42 (是一个run片段第一个字节)
那么,42表示的含义是:4表示LCN的长度占用4个字节数;2表示DataLen的长度占用2个字节
然后,用一定的位移运算就能求出LCN以及DataLen了。

ReactOS,相关代码说明:

static ULONG RunLength(PUCHAR run)
//返回run片段的长度 = 首字节长度+LCN的长度+DataLen的长度
{
return(*run & 0x0f) + ((*run >> 4) & 0x0f) + 1;
}


static LONGLONG RunLCN(PUCHAR run)
//获取run片段的LCN
{
UCHAR n1 = *run & 0x0f;
UCHAR n2 = (*run >> 4) & 0x0f;
LONGLONG lcn = (n2 == 0) ? 0 : (CHAR)(run[n1 + n2]);
LONG i = 0;

for (i = n1 +n2 - 1; i > n1; i--)
   lcn = (lcn << 8) + run[i];
return lcn;
}

 

static ULONGLONG RunCount(PUCHAR run)
//获取run片段的DataLen长度
{
UCHAR n = *run & 0xf;
ULONGLONG count = 0;
ULONG i = 0;
// n表示长度占几个字节,每个字节的内容加起来就是总长度
for (i = n; i > 0; i--)
   count = (count << 8) + run[i];
return count;
}