このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
昨日、マウントポイントのバッファの内容を直接取り出したが、
そのリンク先のパスは、以下のようになっていた。
\??\Volume{f08e7d20-64f1-11db-b10d-001125868411}\
だが、これを GetVolumeNameForVolumeMountPoint で
取り出すと以下のようになる。
\\?\Volume{f08e7d20-64f1-11db-b10d-001125868411}\
一見同じに見えるが、接頭辞が異なっている。
これらはどう違い、どんな意味をもっているのだろうか。
今日は、前者について考えよう。
これはリパースポイントから取得した生のパス文字列であり、
デバイスを示す絶対パス表現である。
デバイスパスは、Windows のデバイスオブジェクトの
名前空間上のパスを示している。
デバイスは階層化されているため、
ファイルシステムと同じように \ で区切って階層を示す。
例えば、\Device\Harddisk0\Partition1 は、
最初のハードディスクの最初のパーティションのデバイスを表し、
\FileSystem\Ntfs は、NTFS ドライバを表している。
これは、UNIX 系の /dev ファイルシステムに似ている。
上記の Device や FileSystem はルート直下の名前空間で、
これはディレクトリのような位置づけである。
これらデバイスパスは、通常はあまり使わないが、
デバイスドライバなど、低水準のコードを書く際には、
デバイスを示す際に必要になる。
さて、ルートには「??」という仮想的な名前空間が存在する。
?? は、DOS 名前空間(DOS デバイス名前空間)と呼ばれ、
主に MS-DOS との互換性を色濃く残す部分である。
これは通常のファイルシステムパスや、
高水準のファイルアクセス API への橋渡しをしている。
?? の中には、NUL, COM1, AUX, C:, D: などが存在する。
そう、この空間にあるデバイス名は、
MS-DOS デバイスと呼ばれる特別なデバイスなのだ。
Windows のデバイス名は階層化されているが、
MS-DOS デバイス名は階層化できない。
そのため、?? 名前空間の中には、
その他の名前空間に存在するデバイスへの
リンクが格納されている。
例えば、NUL のデバイスパスは、\??\NUL であるが、
これは、\Device\Null へのリンクとなっている。
UNIX では /dev/null なので非常に良く似ている。
また、俺の環境では、\??\C: は、
\Device\HarddiskVolume1 へのリンクであり、
\??\Q: は、\Device\CdRom0 へのリンクとなっている。
冒頭で示したパスが指しているのも、この名前空間だ。
Volume{f08e7d20-64f1-11db-b10d-001125868411} は、
俺の環境では、\Device\CdRom3 へのリンクとなっている。
昨日取得したリパースポイントのデータは、
ファイルシステムに存在する低水準のデータであるため、
示すリンク先が、デバイスパスで格納されていた訳だ。
これらデバイスパスを調べるのは大変だが、
Sysinternals が無料で公開している、
winobj というツールを使うと、
オブジェクトの階層構造を視覚的に見ることができる。
■ Sysinternals Freeware - WinObj
http://www.sysinternals.com/Utilities/WinObj.html
今日解説した ?? 名前空間にあるリンクを写真に示す。
写真で開いているのは ?? ではなく GLOBAL?? だが、
?? 空間には、GLOBAL?? の内容が含まれているので、
ほとんど同じと考えて構わない。