パス名で何日か脱線していたが、
改めてボリュームマウントポイントに戻ろう。

ボリュームマウントポイントは、
ファイルシステムのディレクトリに対して、
リパースポイント機能を使うことで実現していた。

リパースポイント属性を持つディレクトリには、
リパースデータバッファという追加情報が保存されている。

リパースデータバッファには種類があるが、
ボリュームマウントポイントは、
IO_REPARSE_TAG_MOUNT_POINT という種類であり、
データとしてリンク先を表すデバイスパスが記録されていた。

改めてその内容を引用しておこう。

\??\Volume{f08e7d20-64f1-11db-b10d-001125868411}\

上記は ?? 名前空間にあるボリューム識別子を参照している。
最後に \ がついているのは重要なことである。

もし、\ がついていなければ、
デバイスとしてのボリューム自体を示すことになるが、
\ がついていると、ボリュームのルートディレクトリを指す。

つまり、上記パスは、Volume{~} が示すボリュームの
ルートディレクトリを示すデバイスパスなのである。

ここでちょっとした疑問(興味)が浮かんでくる。

ボリュームマウントポイント機能は、
ディレクトリに、ボリュームを関連付ける方法であった。
その場合、わざわざデバイスパスを使わなくとも、
ボリューム識別子だけを記録しておけばいいのではないか。
それならば、データ長は固定なので、
わざわざ扱いにくい可変長文字列を扱わなくとも良いはずだ。

デバイスパスを文字列で指定しているということは、
その気になれば、任意のデバイスを指定できることになる。

もし、これを下位のディレクトリや、
別のデバイスパスが指すディレクトリにすると、
いったいどうなるのであろうか。

実は、その手法は正式に NTFS でサポートされている。
リパースポイントはディレクトリを指すことが可能なのだ。

ボリュームではなく、任意のディレクトリを指定した場合、
そのディレクトリに対してリンクを張ることになり、
UNIX のディレクトリへのシンボリックリンクと
ほぼ同じようなことが実現できることになる。

この機能を、「ディレクトリジャンクション」と呼ぶ。

リパースデータバッファのタグは、
ボリュームマウントポイント同様であり、
指し示すデバイスパスが異なるだけである。

つまり、IO_REPARSE_TAG_MOUNT_POINT と言うタグは、
「マウントポイント」という機能を実現するためのもので、
その指す先がボリューム(のルートディレクトリ)であれば、
「ボリュームマウントポイント」と呼ばれ、
その他のディレクトリをさすのであれば、
「ディレクトリジャンクション」と呼ばれるのである。

Windows が提供しているリパースポイントの API は、
ボリュームを操作するものしか存在しないため、
ディレクトリジャンクションを作成するためには、
直接リパースポイントバッファを用意して、
DeviceIOControl 等で設定してやる必要がある。