2006 年 10 月 29 日 23 時 55 分

リパースデータバッファの構造


このアーカイブは同期化されません。 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 が指す文字列は、
何かしらの説明文らしいが、
現在では利用されていないようである。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.