mklink によって作成されたこの再解析ポイントでは何が起こっているのでしょうか?

mklink によって作成されたこの再解析ポイントでは何が起こっているのでしょうか?

これは、Vista 以降の Windows に同梱されている機能で私が遭遇した奇妙な動作ですmklink。これは NTFS ファイル システム ドライバーの欠陥か、あるいはそれと同じくらい深刻な問題であると思われますmklinkが、この動作には何らかの説明が必要です。この動作は、それぞれ 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 ディスクのサイズを示します。)

関連情報