mklink 创建的这个重解析点是怎么回事?

mklink 创建的这个重解析点是怎么回事?

以下是我遇到的mklink自 Vista 以来 Windows 中出现的一些奇怪行为。我怀疑这可能是mklinkNTFS 文件系统驱动程序的缺陷,甚至可能与它一样严重,但这种行为可能需要一些解释。这种行为分别在 Windows 7 和 10 上出现过。

假设我们在 NTFS 卷上有一个目录(不是尝试在除了为此目的而创建的卷之外的任何卷上执行此操作!)以及bar.txt其中命名的文件。

md F:\1
echo foo > F:\1\bar.txt

现在发出以下命令(通过特权提示):

mklink F:\1:bar F:\1\bar.txt

...这将给你:

symbolic link created for F:\1:bar <<===>> F:\1\bar.txt

别担心,我知道这是愚蠢的。但这是测试备用数据流 (ADS) 是否可以成为重新解析点的结果。我认为它不能,因为备用数据流只有名称、大小以及其中的数据。与文件或目录不同,它没有文件属性或自己的时间戳,因此没有属性可以将 ADS 指定为重新解析点(否则可以通过文件属性来实现)。或者换句话说:重新解析点只能引用目录条目(通过$Extend\$Reparse),而 ADS 则与目录条目绑定。

上述命令的结果是这样的:

F:\>dir /r
 Volume in drive F is TEST
 Volume Serial Number is 24F3-8A7D

 Directory of F:\

2018-04-03  20:47    <SYMLINKD>     1 [F:\1\bar.txt]
                                  0 1:bar:$DATA
               0 File(s)              0 bytes
               1 Dir(s)   4,244,283,392 bytes free

毫不奇怪,尝试更改到此目录不起作用,并且产生The directory name is invalid.

junction -d同样,尝试使用(来自 Sysinternals Suite)或使用删除重新解析点fsutil reparsepoint delete都会失败,并出现相同的错误。只有检查重新解析点数据才能让我找到一些线索:

 F:\>fsutil reparsepoint query F:\1
Reparse Tag Value : 0xa000000c
Tag value: Microsoft
Tag value: Name Surrogate
Tag value: Symbolic Link

Reparse Data Length: 0x00000044
Reparse Data:
0000:  18 00 20 00 00 00 18 00  00 00 00 00 46 00 3a 00  .. .........F.:.
0010:  5c 00 31 00 5c 00 62 00  61 00 72 00 2e 00 74 00  \.1.\.b.a.r...t.
0020:  78 00 74 00 5c 00 3f 00  3f 00 5c 00 46 00 3a 00  x.t.\.?.?.\.F.:.
0030:  5c 00 31 00 5c 00 62 00  61 00 72 00 2e 00 74 00  \.1.\.b.a.r...t.
0040:  78 00 74 00                                       x.t.

现在我的问题是这里发生了什么,以及如何使用板载 Windows 工具(或者,如果失败,使用外部工具)再次摆脱这样的重新解析点?如果您能够回答文件夹内的文件发生了什么情况1并披露您的方法,则可以获得加分。

到目前为止,我的工作理论如下:

  1. mklink创建“文件”F:\1:bar并成功(大概通过CreateFile())。
  2. mklink在创建的“文件”上设置REPARSE_DATA_BUFFER,但由于它是目录上的 ADS,因此无法工作。因此,内部发生的事情是文件系统驱动程序在目录上设置重新解析数据缓冲区。

结果就是我们看到的。这里让我困扰的是,通常情况下,如果不指定特定标志,您就无法获取目录的句柄。因此,我们不仅导致mklink创建符号链接在目录上对于文件,我们还避免了指定的必要性FILE_FLAG_BACKUP_SEMANTICS

FILE_FLAG_BACKUP_SEMANTICS下的文档CreateFile内容如下:

必须设置此标志才能获取目录句柄。目录句柄可以代替文件句柄传递给某些函数。有关更多信息,请参阅备注部分。


为了重现,我强烈建议你不是不要在现有的 NTFS 驱动器上尝试此操作,而是使用磁盘管理RAM 磁盘驱动程序和附带的imdisk命令行工具(通过特权提示):

imdisk -a -t vm -p "/fs:ntfs /q /y /v:TEST" -s 4G -m F:

(根据需要更改参数。-m表示驱动器号和-sRAM 磁盘的大小。)

相关内容