このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
リパースタグなどの特殊なデータにアクセスする場合、
デバイスドライバに対して制御コードを送り、
データ構造を直接扱う必要がある。
Windows には、DeviceIoControl という API があり、
これを使うことで、デバイスドライバの制御が可能である。
リパースポイントの情報を得るためには、
対象のディレクトリハンドルに対して、
FSCTL_GET_REPARSE_POINT という制御コードを送る。
そうすれば、その結果としてリパースポイントの情報が、
リパースデータバッファと呼ばれる構造で返却される。
低水準な機能を利用するためには、
このリパースデータバッファと呼ばれるデータ構造を、
独力で解析して情報を取り出す必要がある。
昨日も書いた通り、リパースポイントは、
拡張して色々と利用できるように作成されているため、
データバッファも汎用的に作られている。
リパースデータバッファの先頭には、
リパースポイントの機能を表す 8 バイトのヘッダがある。
これは、どの種類のリパースポイントでも同じである。
unsigned long tag;
unsigned short dataLength;
unsigned short reserved;
tag は、リパースタグ(種類を表す ID 番号)である。
tag の値によって、ヘッダの後に続くデータの構造は異なり、
dataLength には、続くデータのバイト数が格納されている。
reserved は未使用で、通常 0 である。
これら数値はリトルエンディアンで格納されている。
さて、ボリュームマウントポイントの場合は、
タグとして IO_REPARSE_TAG_MOUNT_POINT が入っており、
ヘッダに続いて、8 バイトのリンク先の情報が続き、
残りは全て Unicode 文字データとなっている。
unsigned short targetOffset;
unsigned short targetByteLength;
unsigned short descriptionOffset;
unsigned short descriptionByteLength;
unsigned char buffer[<残り全部>];
リンク先の情報には、2 つの文字列が定義されている。
リンク先のパスと、説明文である。
これら文字列は可変長であるので、
文字自体は後ろにある buffer に格納され、
最初の 4 メンバは、文字列が格納されている、
buffer 上のバイト位置を示しているのである。
target が指す文字列は、リンク先デバイスパスであり、
例えばこのような値を持っている。
\??\Volume{2c4c2620-c203-11d9-a821-806d6172696f}\
そして、description が指す文字列は、
何かしらの説明文らしいが、
現在では利用されていないようである。